Planeshift
|
00001 // 00002 // Copyright (c) 2009-2010 Mikko Mononen [email protected] 00003 // 00004 // This software is provided 'as-is', without any express or implied 00005 // warranty. In no event will the authors be held liable for any damages 00006 // arising from the use of this software. 00007 // Permission is granted to anyone to use this software for any purpose, 00008 // including commercial applications, and to alter it and redistribute it 00009 // freely, subject to the following restrictions: 00010 // 1. The origin of this software must not be misrepresented; you must not 00011 // claim that you wrote the original software. If you use this software 00012 // in a product, an acknowledgment in the product documentation would be 00013 // appreciated but is not required. 00014 // 2. Altered source versions must be plainly marked as such, and must not be 00015 // misrepresented as being the original software. 00016 // 3. This notice may not be removed or altered from any source distribution. 00017 // 00018 00019 #ifndef DETOURNAVMESH_H 00020 #define DETOURNAVMESH_H 00021 00022 #include "DetourAlloc.h" 00023 #include "DetourStatus.h" 00024 00025 // Note: If you want to use 64-bit refs, change the types of both dtPolyRef & dtTileRef. 00026 // It is also recommended that you change dtHashRef() to a proper 64-bit hash. 00027 00030 typedef unsigned int dtPolyRef; 00031 00034 typedef unsigned int dtTileRef; 00035 00038 static const int DT_VERTS_PER_POLYGON = 6; 00039 00045 00047 static const int DT_NAVMESH_MAGIC = 'D'<<24 | 'N'<<16 | 'A'<<8 | 'V'; 00048 00050 static const int DT_NAVMESH_VERSION = 7; 00051 00053 static const int DT_NAVMESH_STATE_MAGIC = 'D'<<24 | 'N'<<16 | 'M'<<8 | 'S'; 00054 00056 static const int DT_NAVMESH_STATE_VERSION = 1; 00057 00059 00062 static const unsigned short DT_EXT_LINK = 0x8000; 00063 00065 static const unsigned int DT_NULL_LINK = 0xffffffff; 00066 00068 static const unsigned int DT_OFFMESH_CON_BIDIR = 1; 00069 00072 static const int DT_MAX_AREAS = 64; 00073 00076 enum dtTileFlags 00077 { 00079 DT_TILE_FREE_DATA = 0x01, 00080 }; 00081 00083 enum dtStraightPathFlags 00084 { 00085 DT_STRAIGHTPATH_START = 0x01, 00086 DT_STRAIGHTPATH_END = 0x02, 00087 DT_STRAIGHTPATH_OFFMESH_CONNECTION = 0x04, 00088 }; 00089 00091 enum dtPolyTypes 00092 { 00094 DT_POLYTYPE_GROUND = 0, 00096 DT_POLYTYPE_OFFMESH_CONNECTION = 1, 00097 }; 00098 00099 00102 struct dtPoly 00103 { 00105 unsigned int firstLink; 00106 00109 unsigned short verts[DT_VERTS_PER_POLYGON]; 00110 00112 unsigned short neis[DT_VERTS_PER_POLYGON]; 00113 00115 unsigned short flags; 00116 00118 unsigned char vertCount; 00119 00122 unsigned char areaAndtype; 00123 00125 inline void setArea(unsigned char a) { areaAndtype = (areaAndtype & 0xc0) | (a & 0x3f); } 00126 00128 inline void setType(unsigned char t) { areaAndtype = (areaAndtype & 0x3f) | (t << 6); } 00129 00131 inline unsigned char getArea() const { return areaAndtype & 0x3f; } 00132 00134 inline unsigned char getType() const { return areaAndtype >> 6; } 00135 }; 00136 00138 struct dtPolyDetail 00139 { 00140 unsigned int vertBase; 00141 unsigned int triBase; 00142 unsigned char vertCount; 00143 unsigned char triCount; 00144 }; 00145 00149 struct dtLink 00150 { 00151 dtPolyRef ref; 00152 unsigned int next; 00153 unsigned char edge; 00154 unsigned char side; 00155 unsigned char bmin; 00156 unsigned char bmax; 00157 }; 00158 00162 struct dtBVNode 00163 { 00164 unsigned short bmin[3]; 00165 unsigned short bmax[3]; 00166 int i; 00167 }; 00168 00171 struct dtOffMeshConnection 00172 { 00174 float pos[6]; 00175 00177 float rad; 00178 00180 unsigned short poly; 00181 00185 unsigned char flags; 00186 00188 unsigned char side; 00189 00191 unsigned int userId; 00192 }; 00193 00196 struct dtMeshHeader 00197 { 00198 int magic; 00199 int version; 00200 int x; 00201 int y; 00202 int layer; 00203 unsigned int userId; 00204 int polyCount; 00205 int vertCount; 00206 int maxLinkCount; 00207 int detailMeshCount; 00208 00210 int detailVertCount; 00211 00212 int detailTriCount; 00213 int bvNodeCount; 00214 int offMeshConCount; 00215 int offMeshBase; 00216 float walkableHeight; 00217 float walkableRadius; 00218 float walkableClimb; 00219 float bmin[3]; 00220 float bmax[3]; 00221 00223 float bvQuantFactor; 00224 }; 00225 00228 struct dtMeshTile 00229 { 00230 unsigned int salt; 00231 00232 unsigned int linksFreeList; 00233 dtMeshHeader* header; 00234 dtPoly* polys; 00235 float* verts; 00236 dtLink* links; 00237 dtPolyDetail* detailMeshes; 00238 00240 float* detailVerts; 00241 00243 unsigned char* detailTris; 00244 00247 dtBVNode* bvTree; 00248 00249 dtOffMeshConnection* offMeshCons; 00250 00251 unsigned char* data; 00252 int dataSize; 00253 int flags; 00254 dtMeshTile* next; 00255 }; 00256 00261 struct dtNavMeshParams 00262 { 00263 float orig[3]; 00264 float tileWidth; 00265 float tileHeight; 00266 int maxTiles; 00267 int maxPolys; 00268 }; 00269 00272 class dtNavMesh 00273 { 00274 public: 00275 dtNavMesh(); 00276 ~dtNavMesh(); 00277 00280 00284 dtStatus init(const dtNavMeshParams* params); 00285 00292 dtStatus init(unsigned char* data, const int dataSize, const int flags); 00293 00295 const dtNavMeshParams* getParams() const; 00296 00304 dtStatus addTile(unsigned char* data, int dataSize, int flags, dtTileRef lastRef, dtTileRef* result); 00305 00311 dtStatus removeTile(dtTileRef ref, unsigned char** data, int* dataSize); 00312 00314 00317 00322 void calcTileLoc(const float* pos, int* tx, int* ty) const; 00323 00329 const dtMeshTile* getTileAt(const int x, const int y, const int layer) const; 00330 00337 int getTilesAt(const int x, const int y, 00338 dtMeshTile const** tiles, const int maxTiles) const; 00339 00345 dtTileRef getTileRefAt(int x, int y, int layer) const; 00346 00350 dtTileRef getTileRef(const dtMeshTile* tile) const; 00351 00356 const dtMeshTile* getTileByRef(dtTileRef ref) const; 00357 00360 int getMaxTiles() const; 00361 00365 const dtMeshTile* getTile(int i) const; 00366 00372 dtStatus getTileAndPolyByRef(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const; 00373 00378 void getTileAndPolyByRefUnsafe(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const; 00379 00383 bool isValidPolyRef(dtPolyRef ref) const; 00384 00388 dtPolyRef getPolyRefBase(const dtMeshTile* tile) const; 00389 00396 dtStatus getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const; 00397 00401 const dtOffMeshConnection* getOffMeshConnectionByRef(dtPolyRef ref) const; 00402 00404 00408 00413 dtStatus setPolyFlags(dtPolyRef ref, unsigned short flags); 00414 00419 dtStatus getPolyFlags(dtPolyRef ref, unsigned short* resultFlags) const; 00420 00425 dtStatus setPolyArea(dtPolyRef ref, unsigned char area); 00426 00431 dtStatus getPolyArea(dtPolyRef ref, unsigned char* resultArea) const; 00432 00436 int getTileStateSize(const dtMeshTile* tile) const; 00437 00443 dtStatus storeTileState(const dtMeshTile* tile, unsigned char* data, const int maxDataSize) const; 00444 00450 dtStatus restoreTileState(dtMeshTile* tile, const unsigned char* data, const int maxDataSize); 00451 00453 00457 00463 inline dtPolyRef encodePolyId(unsigned int salt, unsigned int it, unsigned int ip) const 00464 { 00465 return ((dtPolyRef)salt << (m_polyBits+m_tileBits)) | ((dtPolyRef)it << m_polyBits) | (dtPolyRef)ip; 00466 } 00467 00475 inline void decodePolyId(dtPolyRef ref, unsigned int& salt, unsigned int& it, unsigned int& ip) const 00476 { 00477 const dtPolyRef saltMask = ((dtPolyRef)1<<m_saltBits)-1; 00478 const dtPolyRef tileMask = ((dtPolyRef)1<<m_tileBits)-1; 00479 const dtPolyRef polyMask = ((dtPolyRef)1<<m_polyBits)-1; 00480 salt = (unsigned int)((ref >> (m_polyBits+m_tileBits)) & saltMask); 00481 it = (unsigned int)((ref >> m_polyBits) & tileMask); 00482 ip = (unsigned int)(ref & polyMask); 00483 } 00484 00489 inline unsigned int decodePolyIdSalt(dtPolyRef ref) const 00490 { 00491 const dtPolyRef saltMask = ((dtPolyRef)1<<m_saltBits)-1; 00492 return (unsigned int)((ref >> (m_polyBits+m_tileBits)) & saltMask); 00493 } 00494 00499 inline unsigned int decodePolyIdTile(dtPolyRef ref) const 00500 { 00501 const dtPolyRef tileMask = ((dtPolyRef)1<<m_tileBits)-1; 00502 return (unsigned int)((ref >> m_polyBits) & tileMask); 00503 } 00504 00509 inline unsigned int decodePolyIdPoly(dtPolyRef ref) const 00510 { 00511 const dtPolyRef polyMask = ((dtPolyRef)1<<m_polyBits)-1; 00512 return (unsigned int)(ref & polyMask); 00513 } 00514 00516 00518 dtMeshTile* getTile(int i); 00519 00520 private: 00521 00523 int getTilesAt(const int x, const int y, 00524 dtMeshTile** tiles, const int maxTiles) const; 00525 00527 int getNeighbourTilesAt(const int x, const int y, const int side, 00528 dtMeshTile** tiles, const int maxTiles) const; 00529 00531 int findConnectingPolys(const float* va, const float* vb, 00532 const dtMeshTile* tile, int side, 00533 dtPolyRef* con, float* conarea, int maxcon) const; 00534 00536 void connectIntLinks(dtMeshTile* tile); 00538 void baseOffMeshLinks(dtMeshTile* tile); 00539 00541 void connectExtLinks(dtMeshTile* tile, dtMeshTile* target, int side); 00543 void connectExtOffMeshLinks(dtMeshTile* tile, dtMeshTile* target, int side); 00544 00546 void unconnectExtLinks(dtMeshTile* tile, dtMeshTile* target); 00547 00548 00549 // TODO: These methods are duplicates from dtNavMeshQuery, but are needed for off-mesh connection finding. 00550 00552 int queryPolygonsInTile(const dtMeshTile* tile, const float* qmin, const float* qmax, 00553 dtPolyRef* polys, const int maxPolys) const; 00555 dtPolyRef findNearestPolyInTile(const dtMeshTile* tile, const float* center, 00556 const float* extents, float* nearestPt) const; 00558 void closestPointOnPolyInTile(const dtMeshTile* tile, unsigned int ip, 00559 const float* pos, float* closest) const; 00560 00561 dtNavMeshParams m_params; 00562 float m_orig[3]; 00563 float m_tileWidth, m_tileHeight; 00564 int m_maxTiles; 00565 int m_tileLutSize; 00566 int m_tileLutMask; 00567 00568 dtMeshTile** m_posLookup; 00569 dtMeshTile* m_nextFree; 00570 dtMeshTile* m_tiles; 00571 00572 unsigned int m_saltBits; 00573 unsigned int m_tileBits; 00574 unsigned int m_polyBits; 00575 }; 00576 00580 dtNavMesh* dtAllocNavMesh(); 00581 00585 void dtFreeNavMesh(dtNavMesh* navmesh); 00586 00587 #endif // DETOURNAVMESH_H 00588 00590 00591 // This section contains detailed documentation for members that don't have 00592 // a source file. It reduces clutter in the main section of the header. 00593