forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			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
 |