1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */ 2 3 #ifndef COLLISION_VOLUME_H 4 #define COLLISION_VOLUME_H 5 6 #include "System/float3.h" 7 #include "System/creg/creg_cond.h" 8 #include "System/Util.h" 9 10 // the positive x-axis points to the "left" in object-space and to the "right" in world-space 11 // converting between them means flipping the sign of x-components of positions and directions 12 const float3 WORLD_TO_OBJECT_SPACE = float3(-1.0f, 1.0f, 1.0f); 13 const float COLLISION_VOLUME_EPS = 0.0000000001f; 14 15 struct LocalModelPiece; 16 class CMatrix44f; 17 class CSolidObject; 18 class CUnit; 19 class CFeature; 20 21 struct CollisionVolume 22 { 23 CR_DECLARE_STRUCT(CollisionVolume) 24 25 public: 26 enum { 27 COLVOL_TYPE_ELLIPSOID = 0, // dummy, these become spheres or boxes 28 COLVOL_TYPE_CYLINDER = 1, 29 COLVOL_TYPE_BOX = 2, 30 COLVOL_TYPE_SPHERE = 3, 31 }; 32 enum { 33 COLVOL_AXIS_X = 0, 34 COLVOL_AXIS_Y = 1, 35 COLVOL_AXIS_Z = 2, 36 }; 37 enum { 38 COLVOL_HITTEST_DISC = 0, 39 COLVOL_HITTEST_CONT = 1, 40 }; 41 42 public: 43 CollisionVolume(); CollisionVolumeCollisionVolume44 CollisionVolume(const CollisionVolume* v) { *this = *v; } 45 CollisionVolume( 46 const std::string& cvTypeStr, 47 const float3& cvScales, 48 const float3& cvOffsets 49 ); 50 51 CollisionVolume& operator = (const CollisionVolume&); 52 53 /** 54 * Called if a unit or feature does not define a custom volume. 55 * @param radius the object's default radius 56 */ 57 void InitSphere(float radius); 58 void InitBox(const float3& scales); 59 void InitShape( 60 const float3& scales, 61 const float3& offsets, 62 const int vType, 63 const int tType, 64 const int pAxis 65 ); 66 67 void RescaleAxes(const float3& scales); 68 void SetAxisScales(const float3& scales); 69 void FixTypeAndScale(float3& scales); 70 void SetBoundingRadius(); 71 GetVolumeTypeCollisionVolume72 int GetVolumeType() const { return volumeType; } SetVolumeTypeCollisionVolume73 void SetVolumeType(int type) { volumeType = type; } 74 SetIgnoreHitsCollisionVolume75 void SetIgnoreHits(bool b) { ignoreHits = b; } SetUseContHitTestCollisionVolume76 void SetUseContHitTest(bool b) { useContHitTest = b; } SetDefaultToPieceTreeCollisionVolume77 void SetDefaultToPieceTree(bool b) { defaultToPieceTree = b; } SetDefaultToFootPrintCollisionVolume78 void SetDefaultToFootPrint(bool b) { defaultToFootPrint = b; } 79 GetPrimaryAxisCollisionVolume80 int GetPrimaryAxis() const { return volumeAxes[0]; } GetSecondaryAxisCollisionVolume81 int GetSecondaryAxis(int axis) const { return volumeAxes[axis + 1]; } 82 GetBoundingRadiusCollisionVolume83 float GetBoundingRadius() const { return volumeBoundingRadius; } GetBoundingRadiusSqCollisionVolume84 float GetBoundingRadiusSq() const { return volumeBoundingRadiusSq; } 85 GetOffsetCollisionVolume86 float GetOffset(int axis) const { return axisOffsets[axis]; } GetOffsetsCollisionVolume87 const float3& GetOffsets() const { return axisOffsets; } 88 GetScaleCollisionVolume89 float GetScale(int axis) const { return fAxisScales[axis]; } GetHScaleCollisionVolume90 float GetHScale(int axis) const { return hAxisScales[axis]; } GetHScaleSqCollisionVolume91 float GetHScaleSq(int axis) const { return hsqAxisScales[axis]; } GetScalesCollisionVolume92 const float3& GetScales() const { return fAxisScales; } GetHScalesCollisionVolume93 const float3& GetHScales() const { return hAxisScales; } GetHSqScalesCollisionVolume94 const float3& GetHSqScales() const { return hsqAxisScales; } GetHIScalesCollisionVolume95 const float3& GetHIScales() const { return hiAxisScales; } 96 IgnoreHitsCollisionVolume97 bool IgnoreHits() const { return ignoreHits; } UseContHitTestCollisionVolume98 bool UseContHitTest() const { return useContHitTest; } DefaultToSphereCollisionVolume99 bool DefaultToSphere() const { return (fAxisScales.x == 1.0f && fAxisScales.y == 1.0f && fAxisScales.z == 1.0f); } DefaultToFootPrintCollisionVolume100 bool DefaultToFootPrint() const { return defaultToFootPrint; } DefaultToPieceTreeCollisionVolume101 bool DefaultToPieceTree() const { return defaultToPieceTree; } 102 103 float3 GetWorldSpacePos(const CSolidObject* o, const float3& extOffsets = ZeroVector) const; 104 105 float GetPointSurfaceDistance(const CUnit* u, const LocalModelPiece* lmp, const float3& p) const; 106 float GetPointSurfaceDistance(const CFeature* u, const LocalModelPiece* lmp, const float3& p) const; 107 108 private: 109 float GetPointSurfaceDistance(const CMatrix44f& m, const float3& p) const; 110 111 float3 fAxisScales; ///< full-length axis scales 112 float3 hAxisScales; ///< half-length axis scales 113 float3 hsqAxisScales; ///< half-length axis scales (squared) 114 float3 hiAxisScales; ///< half-length axis scales (inverted) 115 float3 axisOffsets; ///< offsets wrt. the model's mid-position (world-space) 116 117 float volumeBoundingRadius; ///< radius of minimally-bounding sphere around volume 118 float volumeBoundingRadiusSq; ///< squared radius of minimally-bounding sphere 119 120 int volumeType; ///< which COLVOL_TYPE_* shape we have 121 int volumeAxes[3]; ///< [0] is prim. axis, [1] and [2] are sec. axes (all COLVOL_AXIS_*) 122 123 bool ignoreHits; /// if true, CollisionHandler does not check for hits against us 124 bool useContHitTest; /// if true, CollisionHandler does continuous instead of discrete hit-testing 125 bool defaultToFootPrint; /// if true, volume becomes a box with dimensions equal to a SolidObject's {x,z}size 126 bool defaultToPieceTree; /// if true, volume is owned by a unit but defaults to piece-volume tree for hit-testing 127 }; 128 129 #endif 130 131