198 lines
5.3 KiB
C++
198 lines
5.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
|
|
{
|
|
OBS_EMPTY,
|
|
OBS_NEW,
|
|
OBS_PROCESSED,
|
|
};
|
|
|
|
static const int DT_MAX_TOUCHED_TILES = 8;
|
|
struct dtTileCacheObstacle
|
|
{
|
|
float pos[3], radius, height;
|
|
dtCompressedTileRef touched[DT_MAX_TOUCHED_TILES];
|
|
unsigned short salt;
|
|
unsigned char state;
|
|
unsigned char ntouched;
|
|
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;
|
|
};
|
|
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
dtStatus addObstacle(const float* pos, const float radius, const float height, dtObstacleRef* result);
|
|
dtStatus removeObstacle(const dtObstacleRef ref);
|
|
|
|
dtStatus queryTiles(const float* bmin, const float* bmax,
|
|
dtCompressedTileRef* results, int* resultCount, const int maxResults) const;
|
|
|
|
dtStatus update(const float /*dt*/, class dtNavMesh* navmesh);
|
|
|
|
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:
|
|
|
|
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;
|
|
|
|
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
|