File: CollisionVolume.h

package info (click to toggle)
spring 98.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 41,928 kB
  • ctags: 60,665
  • sloc: cpp: 356,167; ansic: 39,434; python: 12,228; java: 12,203; awk: 5,856; sh: 1,719; xml: 997; perl: 405; php: 253; objc: 194; makefile: 72; sed: 2
file content (130 lines) | stat: -rw-r--r-- 4,828 bytes parent folder | download
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