Planeshift

celnavmesh.h

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