File: PathEstimator.h

package info (click to toggle)
spring 0.81.2.1%2Bdfsg1-6
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 28,496 kB
  • ctags: 37,096
  • sloc: cpp: 238,659; ansic: 13,784; java: 12,175; awk: 3,428; python: 1,159; xml: 738; perl: 405; sh: 297; makefile: 267; pascal: 228; objc: 192
file content (205 lines) | stat: -rw-r--r-- 6,635 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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#ifndef PATHESTIMATOR_H
#define PATHESTIMATOR_H

#include "IPath.h"
#include "PathFinder.h"
#include "float3.h"
#include "Sim/MoveTypes/MoveInfo.h"
#include <string>
#include <list>
#include "PathCache.h"

#include <boost/thread/thread.hpp>
#include <boost/detail/atomic_count.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/barrier.hpp>
#include <boost/cstdint.hpp>

class CPathEstimatorDef;
class CPathFinderDef;


class CPathEstimator: public IPath {
	public:
		/*
		 * Creates a new estimator based on a couple of parameters
		 *	<pathFinder>
		 *		The pathfinder to be used for exact cost-calculation of vertices.
		 *
		 *	<BLOCK_SIZE>
		 *		The resolution of the estimator, given in mapsquares.
		 *
		 *	<moveMathOpt>
		 *		What level of blocking the estimator should care of. Based on the
		 *		available options given in CMoveMath.
		 *
		 *	<name>
		 *		Name of the file on disk where pre-calculated data is stored.
		 *		The name given are added to the end of the filename, after the
		 *		name of the corresponding map.
		 *		Ex. PE-name "pe" + Mapname "Desert" => "Desert.pe"
		 */
		CPathEstimator(CPathFinder* pathFinder, unsigned int BLOCK_SIZE, unsigned int moveMathOpt, std::string name);
		~CPathEstimator();

#if !defined(USE_MMGR)
		// note: thread-safety (see PathFinder.cpp)?
		void* operator new(size_t size) { return pfAlloc(size); }
		inline void operator delete(void* p, size_t size) { pfDealloc(p, size); }
#endif

		void Draw(void);


		/*
		 * Returns a estimate low-resolution path from starting location to the goal defined in
		 * CPathEstimatorDef, whenever any such are available.
		 * If no complete path are found, then a path leading as "close" as possible to the goal
		 * is returned instead, together with SearchResult::OutOfRange.
		 * Only if no position closer to the goal than the starting location itself could be found
		 * no path and SearchResult::CantGetCloser is returned.
		 * Param:
		 *	moveData
		 *		Defining the footprint of the unit to use the path.
		 *
		 *	start
		 *		The starting location of the search.
		 *
		 *	peDef
		 *		Object defining the goal of the search.
		 *		Could also be used to add constraints to the search.
		 *
		 * 	path
		 *		If a path could be found, it's generated and put into this structure.
		 *
		 *	maxSearchedBlocks
		 *		The maximum number of nodes/blocks the search are allowed to analyze.
		 *		This restriction could be used in cases where CPU-consumption are critical.
		 */
		SearchResult GetPath(const MoveData& moveData, float3 start, const CPathFinderDef& peDef, Path& path, unsigned int maxSearchedBlocks = 10000);


		/*
		 * Whenever the ground structure of the map changes (ex. at explosions and new buildings)
		 * this function shall be called, with (x1, z1)-(x2, z2) defining the rectangular area
		 * affected. The estimator will itself decided when update of the area is needed.
		 */
		void MapChanged(unsigned int x1, unsigned int z1, unsigned int x2, unsigned int z2);


		/*
		 * called every frame
		 */
		void Update();

		// find the best block to use for this pos
		float3 FindBestBlockCenter(const MoveData* moveData, float3 pos);

		/// Return a checksum that can be used to check if every player has the same path data
		boost::uint32_t GetPathChecksum();

	private:
		void InitEstimator(const std::string&);
		void InitVertices();
		void InitBlocks();
		void CalcOffsetsAndPathCosts(int thread);
		void CalculateBlockOffsets(int, int);
		void EstimatePathCosts(int, int);

		boost::mutex loadMsgMutex;
		std::vector<CPathFinder*> pathFinders;
		std::vector<boost::thread*> threads;



		enum {MAX_SEARCHED_BLOCKS = 10000};
		const unsigned int BLOCK_SIZE;
		const unsigned int BLOCK_PIXEL_SIZE;
		const unsigned int BLOCKS_TO_UPDATE;


		class OpenBlock {
			public:
				float cost;
				float currentCost;
				int2 block;
				int blocknr;
				inline bool operator< (const OpenBlock& ob) { return cost < ob.cost; }
				inline bool operator> (const OpenBlock& ob) { return cost > ob.cost; }
				inline bool operator==(const OpenBlock& ob) { return blocknr == ob.blocknr; }
		};

		struct lessCost: public std::binary_function<OpenBlock*, OpenBlock*, bool> {
			inline bool operator() (const OpenBlock* x, const OpenBlock* y) const {
				return (x->cost > y->cost);
			}
		};

		struct BlockInfo {
			int2* sqrCenter;
			float cost;
			int2 parentBlock;
			unsigned int options;
		};

		struct SingleBlock {
			int2 block;
			MoveData* moveData;
		};


		void FindOffset(const MoveData&, int, int);
		void CalculateVertices(const MoveData&, int, int, int thread = 0);
		void CalculateVertex(const MoveData&, int, int, unsigned int, int thread = 0);

		SearchResult InitSearch(const MoveData& moveData, const CPathFinderDef& peDef);
		SearchResult StartSearch(const MoveData& moveData, const CPathFinderDef& peDef);
		SearchResult DoSearch(const MoveData& moveData, const CPathFinderDef& peDef);
		void TestBlock(const MoveData& moveData, const CPathFinderDef& peDef, OpenBlock& parentOpenBlock, unsigned int direction);
		void FinishSearch(const MoveData& moveData, Path& path);
		void ResetSearch();

		bool ReadFile(std::string name);
		void WriteFile(std::string name);
		unsigned int Hash();

		CPathFinder* pathFinder;

		int nbrOfBlocksX, nbrOfBlocksZ, nbrOfBlocks;									// Number of blocks on map.
		BlockInfo* blockState;															// Map over all blocks and there states.
		OpenBlock openBlockBuffer[MAX_SEARCHED_BLOCKS];									// The buffer to be used in the priority-queue.
		OpenBlock *openBlockBufferPointer;												// Pointer to the current position in the buffer.
		std::priority_queue<OpenBlock*, std::vector<OpenBlock*>, lessCost> openBlocks;	// The priority-queue used to select next block to be searched.
		std::list<int> dirtyBlocks;														// List of blocks changed in last search.
		std::list<SingleBlock> needUpdate;												// Blocks that may need an update due to map changes.

		static const int PATH_DIRECTIONS = 8;
		static const int PATH_DIRECTION_VERTICES = PATH_DIRECTIONS / 2;
		int2 directionVector[PATH_DIRECTIONS];
		int directionVertex[PATH_DIRECTIONS];

		unsigned int nbrOfVertices;
		float* vertex;

		unsigned int maxBlocksToBeSearched;
		unsigned int moveMathOptions;
		float3 start;
		int2 startBlock, goalBlock;
		int startBlocknr;
		float goalHeuristic;
		int2 goalSqrOffset;

		int testedBlocks;

		CPathCache* pathCache;

		boost::uint32_t pathChecksum; ///< currently crc from the zip

		boost::barrier *pathBarrier;

		boost::detail::atomic_count offsetBlockNum, costBlockNum;

		int lastOffsetMessage, lastCostMessage;
};

#endif