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