Planeshift
|
00001 /* 00002 Crystal Space Entity Layer 00003 Copyright (C) 2010 by Leonardo Rodrigo Domingues 00004 Copyright (C) 2011 by Matthieu Kraus 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public 00017 License along with this library; if not, write to the Free 00018 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00019 */ 00020 00021 #ifndef __CEL_NAVMESH__ 00022 #define __CEL_NAVMESH__ 00023 00024 #include <cssysdef.h> 00025 #include <csgeom/obb.h> 00026 #include <csgeom/plane3.h> 00027 #include <csgeom/tri.h> 00028 #include <csgeom/vector3.h> 00029 #include <csqsqrt.h> 00030 #include <cstool/csapplicationframework.h> 00031 #include <csutil/list.h> 00032 #include <csutil/ref.h> 00033 #include <csutil/scf_implementation.h> 00034 #include <csutil/threadmanager.h> 00035 #include <iengine/mesh.h> 00036 #include <iengine/movable.h> 00037 #include <iengine/portal.h> 00038 #include <iengine/portalcontainer.h> 00039 #include <iengine/sector.h> 00040 #include <igeom/trimesh.h> 00041 #include <imesh/objmodel.h> 00042 #include <imesh/terrain2.h> 00043 #include <iutil/comp.h> 00044 #include <iutil/document.h> 00045 #include <iutil/objreg.h> 00046 #include <iutil/vfs.h> 00047 #include <tools/celnavmesh.h> 00048 #include "recastnavigation/ChunkyTriMesh.h" 00049 #include "recastnavigation/DebugDraw.h" 00050 #include "recastnavigation/DetourCommon.h" 00051 #include "recastnavigation/DetourDebugDraw.h" 00052 #include "recastnavigation/DetourNavMesh.h" 00053 #include "recastnavigation/DetourNavMeshBuilder.h" 00054 #include "recastnavigation/Recast.h" 00055 00056 CS_PLUGIN_NAMESPACE_BEGIN(celNavMesh) 00057 { 00058 00059 00060 00061 /* 00062 * Recast structures 00063 */ 00064 static const int MAX_CONVEXVOL_PTS = 12; 00065 struct ConvexVolume 00066 { 00067 float verts[MAX_CONVEXVOL_PTS * 3]; 00068 float hmin, hmax; 00069 int nverts; 00070 int area; 00071 }; 00072 00073 // These are just sample areas to use consistent values across the samples. 00074 // The use should specify these base on his needs. 00075 enum SamplePolyAreas 00076 { 00077 SAMPLE_POLYAREA_GROUND, 00078 SAMPLE_POLYAREA_WATER, 00079 SAMPLE_POLYAREA_ROAD, 00080 SAMPLE_POLYAREA_DOOR, 00081 SAMPLE_POLYAREA_GRASS, 00082 SAMPLE_POLYAREA_JUMP, 00083 }; 00084 enum SamplePolyFlags 00085 { 00086 SAMPLE_POLYFLAGS_WALK = 0x01, // Ability to walk (ground, grass, road) 00087 SAMPLE_POLYFLAGS_SWIM = 0x02, // Ability to swim (water). 00088 SAMPLE_POLYFLAGS_DOOR = 0x04, // Ability to move through doors. 00089 SAMPLE_POLYFLAGS_JUMP = 0x08, // Ability to jump. 00090 SAMPLE_POLYFLAGS_ALL = 0xffff // All abilities. 00091 }; 00092 00101 class DebugDrawCS : public duDebugDraw 00102 { 00103 private: 00104 csSimpleRenderMesh* currentMesh; 00105 csZBufMode currentZBufMode; 00106 csArray<csSimpleRenderMesh*>* meshes; 00107 csArray<csVector3> vertices; 00108 csArray<csVector4> colors; 00109 int nVertices; 00110 00111 public: 00112 DebugDrawCS (); 00113 virtual ~DebugDrawCS (); 00114 csArray<csSimpleRenderMesh*>* GetMeshes (); 00115 00116 // duDebugDraw 00117 virtual void depthMask (bool state); 00118 virtual void texture(bool state); 00119 virtual void begin (duDebugDrawPrimitives prim, float size = 1.0f); 00120 virtual void vertex (const float* pos, unsigned int color); 00121 virtual void vertex (const float x, const float y, const float z, unsigned int color); 00122 virtual void vertex (const float* pos, unsigned int color, const float* uv); 00123 virtual void vertex (const float x, const float y, const float z, unsigned int color, const float u, const float v); 00124 virtual void end (); 00125 }; 00126 00127 00128 00132 class celNavMeshParams : public scfImplementation1<celNavMeshParams, iCelNavMeshParams> 00133 { 00134 private: 00135 float agentHeight; 00136 float agentRadius; 00137 float agentMaxSlopeAngle; 00138 float agentMaxClimb; 00139 float cellSize; 00140 float cellHeight; 00141 float maxSimplificationError; 00142 float detailSampleDist; 00143 float detailSampleMaxError; 00144 float distanceThreshold; 00145 int maxEdgeLength; 00146 int minRegionArea; 00147 int mergeRegionArea; 00148 int maxVertsPerPoly; 00149 int tileSize; 00150 int borderSize; 00151 csVector3 polygonSearchBox; 00152 00153 public: 00154 celNavMeshParams (); 00155 celNavMeshParams (const iCelNavMeshParams* parameters); 00156 virtual ~celNavMeshParams (); 00157 00158 iCelNavMeshParams* Clone () const; 00159 virtual void SetSuggestedValues (float agentHeight, float agentRadius, float agentMaxSlopeAngle); 00160 00161 virtual float GetAgentHeight () const; 00162 virtual void SetAgentHeight (const float height); 00163 virtual float GetAgentRadius () const; 00164 virtual void SetAgentRadius (const float radius); 00165 virtual float GetAgentMaxSlopeAngle () const; 00166 virtual void SetAgentMaxSlopeAngle (const float angle); 00167 virtual float GetAgentMaxClimb () const; 00168 virtual void SetAgentMaxClimb (const float maxClimb); 00169 virtual float GetCellSize () const; 00170 virtual void SetCellSize (const float size); 00171 virtual float GetCellHeight () const; 00172 virtual void SetCellHeight (const float height); 00173 virtual float GetMaxSimplificationError () const; 00174 virtual void SetMaxSimplificationError (const float error); 00175 virtual float GetDetailSampleDist () const; 00176 virtual void SetDetailSampleDist (const float dist); 00177 virtual float GetDetailSampleMaxError () const; 00178 virtual void SetDetailSampleMaxError (const float error); 00179 virtual int GetMaxEdgeLength () const; 00180 virtual void SetMaxEdgeLength (const int length); 00181 virtual int GetMinRegionArea () const; 00182 virtual void SetMinRegionArea (const int area); 00183 virtual int GetMergeRegionArea () const; 00184 virtual void SetMergeRegionArea (const int area); 00185 virtual int GetMaxVertsPerPoly () const; 00186 virtual void SetMaxVertsPerPoly (const int maxVerts); 00187 virtual int GetTileSize () const; 00188 virtual void SetTileSize (const int size); 00189 virtual int GetBorderSize () const; 00190 virtual void SetBorderSize (const int size); 00191 virtual csVector3 GetPolygonSearchBox () const; 00192 virtual void SetPolygonSearchBox (const csVector3 box); 00193 }; 00194 00195 00196 00200 // Based on Recast NavMeshTesterTool 00201 class celNavMeshPath : public scfImplementation1<celNavMeshPath, iCelNavMeshPath> 00202 { 00203 private: 00204 float* path; 00205 int pathSize; // In nodes 00206 int maxPathSize; 00207 int currentPosition; // Path array position, not point index 00208 int increasePosition; // Value to be added to currentPosition to get next element 00209 static const int INCREASE_PATH_BY; // Increase path vector by this amount when the it gets full 00210 csRef<iSector> sector; 00211 csArray<csSimpleRenderMesh*>* debugMeshes; 00212 00213 public: 00214 celNavMeshPath (float* path, int pathSize, int maxPathSize, iSector* sector); 00215 virtual ~celNavMeshPath (); 00216 00217 // API 00218 virtual iSector* GetSector () const; 00219 virtual void Current (csVector3& vector) const; 00220 virtual void Next (csVector3& vector); 00221 virtual void Previous (csVector3& vector); 00222 virtual void GetFirst (csVector3& vector) const; 00223 virtual void GetLast (csVector3& vector) const; 00224 virtual bool HasNext () const; 00225 virtual bool HasPrevious () const; 00226 virtual void Invert (); 00227 virtual void Restart (); 00228 virtual void AddNode (csVector3 node); 00229 virtual void InsertNode (int pos, csVector3 node); 00230 virtual float Length () const; 00231 virtual int GetNodeCount () const; 00232 virtual csArray<csSimpleRenderMesh*>* GetDebugMeshes (); 00233 }; 00234 00235 00236 00240 class celNavMesh : public scfImplementation1<celNavMesh, iCelNavMesh> 00241 { 00242 private: 00243 struct NavMeshSetHeader 00244 { 00245 int magic; 00246 int version; 00247 int numTiles; 00248 dtNavMeshParams params; 00249 }; 00250 00251 struct NavMeshTileHeader 00252 { 00253 dtTileRef tileRef; 00254 int dataSize; 00255 }; 00256 00257 csRef<iSector> sector; 00258 iObjectRegistry* objectRegistry; 00259 csRef<iCelNavMeshPath> path; 00260 dtQueryFilter filter; 00261 dtNavMesh* detourNavMesh; 00262 dtNavMeshQuery* detourNavMeshQuery; 00263 csRef<iCelNavMeshParams> parameters; 00264 csArray<csSimpleRenderMesh*>* debugMeshes; 00265 csArray<csSimpleRenderMesh*>* agentDebugMeshes; 00266 float boundingMin[3]; 00267 float boundingMax[3]; 00268 unsigned char navMeshDrawFlags; 00269 static const int MAX_NODES; 00270 static const int NAVMESHSET_MAGIC; 00271 static const int NAVMESHSET_VERSION; 00272 00273 bool LoadCelNavMeshParams (iDocumentNode* mainNode); 00274 bool LoadDtNavMeshParams (iDocumentNode* paramsNode, dtNavMeshParams& params); 00275 bool LoadNavMeshLegacy (iFile* file); 00276 public: 00277 celNavMesh (iObjectRegistry* objectRegistry); 00278 virtual ~celNavMesh (); 00279 00280 bool Initialize (const iCelNavMeshParams* parameters, iSector* sector, const float* boundingMin, 00281 const float* boundingMax); 00282 bool AddTile (unsigned char* data, int dataSize); 00283 bool RemoveTile (int x, int y); 00284 bool LoadNavMesh (iFile* file); 00285 00286 // API 00287 virtual iCelNavMeshPath* ShortestPath (const csVector3& from, const csVector3& goal, int maxPathSize = 32); 00288 virtual bool Update (const csBox3& boundingBox); 00289 virtual bool Update (const csOBB& boundingBox); 00290 virtual iSector* GetSector () const; 00291 virtual void SetSector (iSector* sector); 00292 virtual iCelNavMeshParams* GetParameters () const; 00293 virtual csBox3 GetBoundingBox() const; 00294 virtual csArray<csPoly3D> QueryPolygons(const csBox3& box) const; 00295 virtual bool SaveToFile (iFile* file) const; 00296 virtual csArray<csSimpleRenderMesh*>* GetDebugMeshes (); 00297 virtual csArray<csSimpleRenderMesh*>* GetAgentDebugMeshes (const csVector3& pos); 00298 virtual csArray<csSimpleRenderMesh*>* GetAgentDebugMeshes (const csVector3& pos, int red, int green, 00299 int blue, int alpha); 00300 virtual void ResetAgentDebugMeshes (); 00301 }; 00302 00303 00304 00308 class celNavMeshBuilder : public ThreadedCallable<celNavMeshBuilder>, 00309 public scfImplementation2<celNavMeshBuilder, iCelNavMeshBuilder, iComponent> 00310 { 00311 private: 00312 // Crystal space & CEL 00313 iObjectRegistry* objectRegistry; 00314 csRef<iSector> currentSector; 00315 csRef<iStringSet> strings; 00316 00317 // Recast & Detour 00318 rcChunkyTriMesh* chunkyTriMesh; 00319 00320 // Tile specific 00321 unsigned char* triangleAreas; 00322 rcContext dummy; 00323 rcHeightfield* solid; 00324 rcCompactHeightfield* chf; 00325 rcContourSet* cSet; 00326 rcPolyMesh* pMesh; 00327 rcPolyMeshDetail* dMesh; 00328 00329 // Off-Mesh connections. 00330 static const int MAX_OFFMESH_CONNECTIONS = 256; 00331 float offMeshConVerts[MAX_OFFMESH_CONNECTIONS * 3 * 2]; 00332 float offMeshConRads[MAX_OFFMESH_CONNECTIONS]; 00333 unsigned char offMeshConDirs[MAX_OFFMESH_CONNECTIONS]; 00334 unsigned char offMeshConAreas[MAX_OFFMESH_CONNECTIONS]; 00335 unsigned short offMeshConFlags[MAX_OFFMESH_CONNECTIONS]; 00336 int numberOfOffMeshCon; 00337 00338 // Convex Volumes 00339 static const int MAX_VOLUMES = 256; 00340 ConvexVolume volumes[MAX_VOLUMES]; 00341 int numberOfVolumes; 00342 00343 csRef<iCelNavMeshParams> parameters; 00344 csRef<celNavMesh> navMesh; 00345 00346 // Others 00347 int numberOfVertices; 00348 float* triangleVertices; 00349 int numberOfTriangles; 00350 int* triangleIndices; 00351 float boundingMin[3]; 00352 float boundingMax[3]; 00353 00354 void CleanUpSectorData (); 00355 void CleanUpTileData (); 00356 bool GetSectorData (); 00357 unsigned char* BuildTile(const int tx, const int ty, const float* bmin, const float* bmax, 00358 const rcConfig& tileConfig, int& dataSize); 00359 iObjectRegistry* GetObjectRegistry() const { return objectRegistry; } 00360 00361 // helper function to check whether an object has to be clipped 00362 // stores whether the object has to be clipped in result and returns true if it's visible 00363 bool CheckClipping(const csPlane3& clipPlane, const csBox3& bbox, bool& result); 00364 00365 // helper function to clip a convex polygon to a plane and triangulate it apllying an object to world transform 00366 void SplitPolygon(int indexOffset, int numVerts, csVector3* poly, csArray<csVector3>& vertices, csArray<csTriangle>& triangles, 00367 const csReversibleTransform& t, csPlane3& clipPlane, bool clipPolygon); 00368 00369 // helper function to add a bul of triangles to the sector data 00370 00371 public: 00372 celNavMeshBuilder (iBase* parent); 00373 virtual ~celNavMeshBuilder (); 00374 virtual bool Initialize (iObjectRegistry*); 00375 bool UpdateNavMesh (celNavMesh* navMesh, const csBox3& boundingBox); 00376 00377 // API 00378 virtual bool SetSector (iSector* sector); 00379 THREADED_CALLABLE_DECL(celNavMeshBuilder,BuildNavMesh,csThreadReturn,THREADEDL,false,false); 00380 virtual iCelNavMesh* LoadNavMesh (iFile* file); 00381 virtual const iCelNavMeshParams* GetNavMeshParams () const; 00382 virtual void SetNavMeshParams (const iCelNavMeshParams* parameters); 00383 virtual iSector* GetSector () const; 00384 00385 }; 00386 00387 } 00388 CS_PLUGIN_NAMESPACE_END(celNavMesh) 00389 00390 #endif // __CEL_NAVMESH__