Planeshift

DetourNavMesh.h

Go to the documentation of this file.
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