1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2 
3 #ifndef QUAD_FIELD_H
4 #define QUAD_FIELD_H
5 
6 #include <set>
7 #include <vector>
8 #include <list>
9 #include <boost/noncopyable.hpp>
10 
11 #include "System/creg/creg_cond.h"
12 #include "System/float3.h"
13 
14 class CUnit;
15 class CFeature;
16 class CProjectile;
17 class CSolidObject;
18 
19 class CQuadField : boost::noncopyable
20 {
21 	CR_DECLARE_STRUCT(CQuadField)
22 	CR_DECLARE_SUB(Quad)
23 
24 public:
25 	static void Resize(unsigned int nqx, unsigned int nqz);
26 
27 	CQuadField(unsigned int nqx, unsigned int nqz);
28 	~CQuadField();
29 
30 	std::vector<int> GetQuads(float3 pos, float radius) const;
31 	std::vector<int> GetQuadsRectangle(const float3& pos1, const float3& pos2) const;
32 
33 	// optimized functions, somewhat less userfriendly
34 	//
35 	// when calling these, <begQuad> and <endQuad> are both expected
36 	// to point to the *start* of an array of int's of size at least
37 	// numQuadsX * numQuadsZ (eg. tempQuads) -- GetQuadsOnRay ensures
38 	// this by itself, for GetQuads the callers take care of it
39 	//
40 	unsigned int GetQuads(float3 pos, float radius, int*& begQuad, int*& endQuad) const;
41 	unsigned int GetQuadsOnRay(float3 start, float3 dir, float length, int*& begQuad, int*& endQuad);
42 
43 	void GetUnitsAndFeaturesColVol(
44 		const float3& pos,
45 		const float radius,
46 		std::vector<CUnit*>& units,
47 		std::vector<CFeature*>& features,
48 		unsigned int* numUnitsPtr = NULL,
49 		unsigned int* numFeaturesPtr = NULL
50 	);
51 
52 	/**
53 	 * Returns all units within @c radius of @c pos,
54 	 * and treats each unit as a 3D point object
55 	 */
56 	std::vector<CUnit*> GetUnits(const float3& pos, float radius);
57 	/**
58 	 * Returns all units within @c radius of @c pos,
59 	 * takes the 3D model radius of each unit into account,
60  	 * and performs the search within a sphere or cylinder depending on @c spherical
61 	 */
62 	std::vector<CUnit*> GetUnitsExact(const float3& pos, float radius, bool spherical = true);
63 	/**
64 	 * Returns all units within the rectangle defined by
65 	 * mins and maxs, which extends infinitely along the y-axis
66 	 */
67 	std::vector<CUnit*> GetUnitsExact(const float3& mins, const float3& maxs);
68 
69 	/**
70 	 * Returns all features within @c radius of @c pos,
71 	 * and takes the 3D model radius of each feature into account
72 	 */
73 	std::vector<CFeature*> GetFeaturesExact(const float3& pos, float radius);
74 	/**
75 	 * Returns all features within @c radius of @c pos,
76 	 * and performs the search within a sphere or cylinder depending on @c spherical
77 	 */
78 	std::vector<CFeature*> GetFeaturesExact(const float3& pos, float radius, bool spherical);
79 	/**
80 	 * Returns all features within the rectangle defined by
81 	 * mins and maxs, which extends infinitely along the y-axis
82 	 */
83 	std::vector<CFeature*> GetFeaturesExact(const float3& mins, const float3& maxs);
84 
85 	std::vector<CProjectile*> GetProjectilesExact(const float3& pos, float radius);
86 	std::vector<CProjectile*> GetProjectilesExact(const float3& mins, const float3& maxs);
87 
88 	std::vector<CSolidObject*> GetSolidsExact(
89 		const float3& pos,
90 		const float radius,
91 		const unsigned int physicalStateBits = 0xFFFFFFFF,
92 		const unsigned int collisionStateBits = 0xFFFFFFFF
93 	);
94 
95 	void MovedUnit(CUnit* unit);
96 	void RemoveUnit(CUnit* unit);
97 
98 	void AddFeature(CFeature* feature);
99 	void RemoveFeature(CFeature* feature);
100 
101 	void MovedProjectile(CProjectile* projectile);
102 	void AddProjectile(CProjectile* projectile);
103 	void RemoveProjectile(CProjectile* projectile);
104 
105 	struct Quad {
106 		CR_DECLARE_STRUCT(Quad)
107 		Quad();
108 		std::list<CUnit*> units;
109 		std::vector< std::list<CUnit*> > teamUnits;
110 		std::list<CFeature*> features;
111 		std::list<CProjectile*> projectiles;
112 	};
113 
GetQuad(int i)114 	const Quad& GetQuad(int i) const {
115 		assert(i >= 0);
116 		assert(i < baseQuads.size());
117 		return baseQuads[i];
118 	}
GetQuadAt(int x,int z)119 	const Quad& GetQuadAt(int x, int z) const {
120 		return baseQuads[numQuadsX * z + x];
121 	}
122 
GetNumQuadsX()123 	int GetNumQuadsX() const { return numQuadsX; }
GetNumQuadsZ()124 	int GetNumQuadsZ() const { return numQuadsZ; }
125 
GetQuadSizeX()126 	int GetQuadSizeX() const { return quadSizeX; }
GetQuadSizeZ()127 	int GetQuadSizeZ() const { return quadSizeZ; }
128 
129 	const static unsigned int BASE_QUAD_SIZE =  128;
130 	const static unsigned int NUM_TEMP_QUADS = 1024;
131 
132 private:
133 	std::vector<Quad> baseQuads;
134 	std::vector<int> tempQuads;
135 
136 	int numQuadsX;
137 	int numQuadsZ;
138 
139 	int quadSizeX;
140 	int quadSizeZ;
141 };
142 
143 extern CQuadField* quadField;
144 
145 #endif /* QUAD_FIELD_H */
146