263 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			263 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								#ifndef DETOURTILECACHE_H
							 | 
						||
| 
								 | 
							
								#define DETOURTILECACHE_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "DetourStatus.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef unsigned int dtObstacleRef;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef unsigned int dtCompressedTileRef;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// Flags for addTile
							 | 
						||
| 
								 | 
							
								enum dtCompressedTileFlags
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DT_COMPRESSEDTILE_FREE_DATA = 0x01,					///< Navmesh owns the tile memory and should free it.
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct dtCompressedTile
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									unsigned int salt;						///< Counter describing modifications to the tile.
							 | 
						||
| 
								 | 
							
									struct dtTileCacheLayerHeader* header;
							 | 
						||
| 
								 | 
							
									unsigned char* compressed;
							 | 
						||
| 
								 | 
							
									int compressedSize;
							 | 
						||
| 
								 | 
							
									unsigned char* data;
							 | 
						||
| 
								 | 
							
									int dataSize;
							 | 
						||
| 
								 | 
							
									unsigned int flags;
							 | 
						||
| 
								 | 
							
									dtCompressedTile* next;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								enum ObstacleState
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DT_OBSTACLE_EMPTY,
							 | 
						||
| 
								 | 
							
									DT_OBSTACLE_PROCESSING,
							 | 
						||
| 
								 | 
							
									DT_OBSTACLE_PROCESSED,
							 | 
						||
| 
								 | 
							
									DT_OBSTACLE_REMOVING,
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								enum ObstacleType
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DT_OBSTACLE_CYLINDER,
							 | 
						||
| 
								 | 
							
									DT_OBSTACLE_BOX, // AABB
							 | 
						||
| 
								 | 
							
									DT_OBSTACLE_ORIENTED_BOX, // OBB
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct dtObstacleCylinder
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									float pos[ 3 ];
							 | 
						||
| 
								 | 
							
									float radius;
							 | 
						||
| 
								 | 
							
									float height;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct dtObstacleBox
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									float bmin[ 3 ];
							 | 
						||
| 
								 | 
							
									float bmax[ 3 ];
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct dtObstacleOrientedBox
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									float center[ 3 ];
							 | 
						||
| 
								 | 
							
									float halfExtents[ 3 ];
							 | 
						||
| 
								 | 
							
									float rotAux[ 2 ]; //{ cos(0.5f*angle)*sin(-0.5f*angle); cos(0.5f*angle)*cos(0.5f*angle) - 0.5 }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static const int DT_MAX_TOUCHED_TILES = 8;
							 | 
						||
| 
								 | 
							
								struct dtTileCacheObstacle
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									union
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										dtObstacleCylinder cylinder;
							 | 
						||
| 
								 | 
							
										dtObstacleBox box;
							 | 
						||
| 
								 | 
							
										dtObstacleOrientedBox orientedBox;
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									dtCompressedTileRef touched[DT_MAX_TOUCHED_TILES];
							 | 
						||
| 
								 | 
							
									dtCompressedTileRef pending[DT_MAX_TOUCHED_TILES];
							 | 
						||
| 
								 | 
							
									unsigned short salt;
							 | 
						||
| 
								 | 
							
									unsigned char type;
							 | 
						||
| 
								 | 
							
									unsigned char state;
							 | 
						||
| 
								 | 
							
									unsigned char ntouched;
							 | 
						||
| 
								 | 
							
									unsigned char npending;
							 | 
						||
| 
								 | 
							
									dtTileCacheObstacle* next;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct dtTileCacheParams
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									float orig[3];
							 | 
						||
| 
								 | 
							
									float cs, ch;
							 | 
						||
| 
								 | 
							
									int width, height;
							 | 
						||
| 
								 | 
							
									float walkableHeight;
							 | 
						||
| 
								 | 
							
									float walkableRadius;
							 | 
						||
| 
								 | 
							
									float walkableClimb;
							 | 
						||
| 
								 | 
							
									float maxSimplificationError;
							 | 
						||
| 
								 | 
							
									int maxTiles;
							 | 
						||
| 
								 | 
							
									int maxObstacles;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct dtTileCacheMeshProcess
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									virtual ~dtTileCacheMeshProcess() { }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									virtual void process(struct dtNavMeshCreateParams* params,
							 | 
						||
| 
								 | 
							
														 unsigned char* polyAreas, unsigned short* polyFlags) = 0;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class dtTileCache
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
									dtTileCache();
							 | 
						||
| 
								 | 
							
									~dtTileCache();
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									struct dtTileCacheAlloc* getAlloc() { return m_talloc; }
							 | 
						||
| 
								 | 
							
									struct dtTileCacheCompressor* getCompressor() { return m_tcomp; }
							 | 
						||
| 
								 | 
							
									const dtTileCacheParams* getParams() const { return &m_params; }
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									inline int getTileCount() const { return m_params.maxTiles; }
							 | 
						||
| 
								 | 
							
									inline const dtCompressedTile* getTile(const int i) const { return &m_tiles[i]; }
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									inline int getObstacleCount() const { return m_params.maxObstacles; }
							 | 
						||
| 
								 | 
							
									inline const dtTileCacheObstacle* getObstacle(const int i) const { return &m_obstacles[i]; }
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									const dtTileCacheObstacle* getObstacleByRef(dtObstacleRef ref);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtObstacleRef getObstacleRef(const dtTileCacheObstacle* obmin) const;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtStatus init(const dtTileCacheParams* params,
							 | 
						||
| 
								 | 
							
												  struct dtTileCacheAlloc* talloc,
							 | 
						||
| 
								 | 
							
												  struct dtTileCacheCompressor* tcomp,
							 | 
						||
| 
								 | 
							
												  struct dtTileCacheMeshProcess* tmproc);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									int getTilesAt(const int tx, const int ty, dtCompressedTileRef* tiles, const int maxTiles) const ;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtCompressedTile* getTileAt(const int tx, const int ty, const int tlayer);
							 | 
						||
| 
								 | 
							
									dtCompressedTileRef getTileRef(const dtCompressedTile* tile) const;
							 | 
						||
| 
								 | 
							
									const dtCompressedTile* getTileByRef(dtCompressedTileRef ref) const;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtStatus addTile(unsigned char* data, const int dataSize, unsigned char flags, dtCompressedTileRef* result);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtStatus removeTile(dtCompressedTileRef ref, unsigned char** data, int* dataSize);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									// Cylinder obstacle.
							 | 
						||
| 
								 | 
							
									dtStatus addObstacle(const float* pos, const float radius, const float height, dtObstacleRef* result);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Aabb obstacle.
							 | 
						||
| 
								 | 
							
									dtStatus addBoxObstacle(const float* bmin, const float* bmax, dtObstacleRef* result);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Box obstacle: can be rotated in Y.
							 | 
						||
| 
								 | 
							
									dtStatus addBoxObstacle(const float* center, const float* halfExtents, const float yRadians, dtObstacleRef* result);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtStatus removeObstacle(const dtObstacleRef ref);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtStatus queryTiles(const float* bmin, const float* bmax,
							 | 
						||
| 
								 | 
							
														dtCompressedTileRef* results, int* resultCount, const int maxResults) const;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// Updates the tile cache by rebuilding tiles touched by unfinished obstacle requests.
							 | 
						||
| 
								 | 
							
									///  @param[in]		dt			The time step size. Currently not used.
							 | 
						||
| 
								 | 
							
									///  @param[in]		navmesh		The mesh to affect when rebuilding tiles.
							 | 
						||
| 
								 | 
							
									///  @param[out]	upToDate	Whether the tile cache is fully up to date with obstacle requests and tile rebuilds.
							 | 
						||
| 
								 | 
							
									///  							If the tile cache is up to date another (immediate) call to update will have no effect;
							 | 
						||
| 
								 | 
							
									///  							otherwise another call will continue processing obstacle requests and tile rebuilds.
							 | 
						||
| 
								 | 
							
									dtStatus update(const float dt, class dtNavMesh* navmesh, bool* upToDate = 0);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtStatus buildNavMeshTilesAt(const int tx, const int ty, class dtNavMesh* navmesh);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtStatus buildNavMeshTile(const dtCompressedTileRef ref, class dtNavMesh* navmesh);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									void calcTightTileBounds(const struct dtTileCacheLayerHeader* header, float* bmin, float* bmax) const;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									void getObstacleBounds(const struct dtTileCacheObstacle* ob, float* bmin, float* bmax) const;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Encodes a tile id.
							 | 
						||
| 
								 | 
							
									inline dtCompressedTileRef encodeTileId(unsigned int salt, unsigned int it) const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return ((dtCompressedTileRef)salt << m_tileBits) | (dtCompressedTileRef)it;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// Decodes a tile salt.
							 | 
						||
| 
								 | 
							
									inline unsigned int decodeTileIdSalt(dtCompressedTileRef ref) const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										const dtCompressedTileRef saltMask = ((dtCompressedTileRef)1<<m_saltBits)-1;
							 | 
						||
| 
								 | 
							
										return (unsigned int)((ref >> m_tileBits) & saltMask);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// Decodes a tile id.
							 | 
						||
| 
								 | 
							
									inline unsigned int decodeTileIdTile(dtCompressedTileRef ref) const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										const dtCompressedTileRef tileMask = ((dtCompressedTileRef)1<<m_tileBits)-1;
							 | 
						||
| 
								 | 
							
										return (unsigned int)(ref & tileMask);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Encodes an obstacle id.
							 | 
						||
| 
								 | 
							
									inline dtObstacleRef encodeObstacleId(unsigned int salt, unsigned int it) const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return ((dtObstacleRef)salt << 16) | (dtObstacleRef)it;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// Decodes an obstacle salt.
							 | 
						||
| 
								 | 
							
									inline unsigned int decodeObstacleIdSalt(dtObstacleRef ref) const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										const dtObstacleRef saltMask = ((dtObstacleRef)1<<16)-1;
							 | 
						||
| 
								 | 
							
										return (unsigned int)((ref >> 16) & saltMask);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// Decodes an obstacle id.
							 | 
						||
| 
								 | 
							
									inline unsigned int decodeObstacleIdObstacle(dtObstacleRef ref) const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										const dtObstacleRef tileMask = ((dtObstacleRef)1<<16)-1;
							 | 
						||
| 
								 | 
							
										return (unsigned int)(ref & tileMask);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
									// Explicitly disabled copy constructor and copy assignment operator.
							 | 
						||
| 
								 | 
							
									dtTileCache(const dtTileCache&);
							 | 
						||
| 
								 | 
							
									dtTileCache& operator=(const dtTileCache&);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									enum ObstacleRequestAction
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										REQUEST_ADD,
							 | 
						||
| 
								 | 
							
										REQUEST_REMOVE,
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									struct ObstacleRequest
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										int action;
							 | 
						||
| 
								 | 
							
										dtObstacleRef ref;
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									int m_tileLutSize;						///< Tile hash lookup size (must be pot).
							 | 
						||
| 
								 | 
							
									int m_tileLutMask;						///< Tile hash lookup mask.
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtCompressedTile** m_posLookup;			///< Tile hash lookup.
							 | 
						||
| 
								 | 
							
									dtCompressedTile* m_nextFreeTile;		///< Freelist of tiles.
							 | 
						||
| 
								 | 
							
									dtCompressedTile* m_tiles;				///< List of tiles.
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									unsigned int m_saltBits;				///< Number of salt bits in the tile ID.
							 | 
						||
| 
								 | 
							
									unsigned int m_tileBits;				///< Number of tile bits in the tile ID.
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtTileCacheParams m_params;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtTileCacheAlloc* m_talloc;
							 | 
						||
| 
								 | 
							
									dtTileCacheCompressor* m_tcomp;
							 | 
						||
| 
								 | 
							
									dtTileCacheMeshProcess* m_tmproc;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtTileCacheObstacle* m_obstacles;
							 | 
						||
| 
								 | 
							
									dtTileCacheObstacle* m_nextFreeObstacle;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									static const int MAX_REQUESTS = 64;
							 | 
						||
| 
								 | 
							
									ObstacleRequest m_reqs[MAX_REQUESTS];
							 | 
						||
| 
								 | 
							
									int m_nreqs;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									static const int MAX_UPDATE = 64;
							 | 
						||
| 
								 | 
							
									dtCompressedTileRef m_update[MAX_UPDATE];
							 | 
						||
| 
								 | 
							
									int m_nupdate;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								dtTileCache* dtAllocTileCache();
							 | 
						||
| 
								 | 
							
								void dtFreeTileCache(dtTileCache* tc);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 |