Explorar o código

Add configuration of maximum layers in DynamicNavigationMesh

- Valid range of 3 - 255
- Angelscript + Lua bindings
- Layer maximum changes only effects nav mesh build and does not trigger
a build
JSandusky %!s(int64=10) %!d(string=hai) anos
pai
achega
003aedb298

+ 2 - 0
Source/Urho3D/AngelScript/NavigationAPI.cpp

@@ -174,6 +174,8 @@ void RegisterDynamicNavigationMesh(asIScriptEngine* engine)
     engine->RegisterObjectMethod("DynamicNavigationMesh", "Array<Vector3>@ FindPath(const Vector3&in, const Vector3&in, const Vector3&in extents = Vector3(1.0, 1.0, 1.0))", asFUNCTION(DynamicNavigationMeshFindPath), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("DynamicNavigationMesh", "Array<Vector3>@ FindPath(const Vector3&in, const Vector3&in, const Vector3&in extents = Vector3(1.0, 1.0, 1.0))", asFUNCTION(DynamicNavigationMeshFindPath), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("DynamicNavigationMesh", "void set_drawObstacles(bool)", asMETHOD(DynamicNavigationMesh, SetDrawObstacles), asCALL_THISCALL);
     engine->RegisterObjectMethod("DynamicNavigationMesh", "void set_drawObstacles(bool)", asMETHOD(DynamicNavigationMesh, SetDrawObstacles), asCALL_THISCALL);
     engine->RegisterObjectMethod("DynamicNavigationMesh", "bool get_drawObstacles() const", asMETHOD(DynamicNavigationMesh, GetDrawObstacles), asCALL_THISCALL);
     engine->RegisterObjectMethod("DynamicNavigationMesh", "bool get_drawObstacles() const", asMETHOD(DynamicNavigationMesh, GetDrawObstacles), asCALL_THISCALL);
+    engine->RegisterObjectMethod("DynamicNavigationMesh", "void set_maxLayers(uint)", asMETHOD(DynamicNavigationMesh, SetMaxLayers), asCALL_THISCALL);
+    engine->RegisterObjectMethod("DynamicNavigationMesh", "bool get_maxLayers() const", asMETHOD(DynamicNavigationMesh, GetMaxLayers), asCALL_THISCALL);
     engine->RegisterObjectMethod("DynamicNavigationMesh", "void set_maxObstacles(uint)", asMETHOD(DynamicNavigationMesh, SetMaxObstacles), asCALL_THISCALL);
     engine->RegisterObjectMethod("DynamicNavigationMesh", "void set_maxObstacles(uint)", asMETHOD(DynamicNavigationMesh, SetMaxObstacles), asCALL_THISCALL);
     engine->RegisterObjectMethod("DynamicNavigationMesh", "uint get_maxObstacles() const", asMETHOD(DynamicNavigationMesh, GetMaxObstacles), asCALL_THISCALL);
     engine->RegisterObjectMethod("DynamicNavigationMesh", "uint get_maxObstacles() const", asMETHOD(DynamicNavigationMesh, GetMaxObstacles), asCALL_THISCALL);
 }
 }

+ 3 - 0
Source/Urho3D/LuaScript/pkgs/Navigation/DynamicNavigationMesh.pkg

@@ -3,11 +3,14 @@ $#include "Navigation/DynamicNavigationMesh.h"
 class DynamicNavigationMesh : public NavigationMesh
 class DynamicNavigationMesh : public NavigationMesh
 {
 {
     void SetDrawObstacles(bool enable);
     void SetDrawObstacles(bool enable);
+    void SetMaxLayers(unsigned maxLayers);
     void SetMaxObstacles(unsigned maxObstacles);
     void SetMaxObstacles(unsigned maxObstacles);
 
 
     bool GetDrawObstacles() const;
     bool GetDrawObstacles() const;
+    unsigned GetMaxLayers() const;
     unsigned GetMaxObstacles() const;
     unsigned GetMaxObstacles() const;
 
 
     tolua_property__get_set bool drawObstacles;
     tolua_property__get_set bool drawObstacles;
     tolua_property__get_set int maxObstacles;
     tolua_property__get_set int maxObstacles;
+    tolua_property__get_set unsigned maxLayers;
 };
 };

+ 15 - 5
Source/Urho3D/Navigation/DynamicNavigationMesh.cpp

@@ -49,7 +49,7 @@
 // DebugNew is deliberately not used because the macro 'free' conflicts with DetourTileCache's LinearAllocator interface
 // DebugNew is deliberately not used because the macro 'free' conflicts with DetourTileCache's LinearAllocator interface
 //#include "../DebugNew.h"
 //#include "../DebugNew.h"
 
 
-#define TILECACHE_MAXLAYERS 128
+#define TILECACHE_MAXLAYERS 255
 
 
 namespace Urho3D
 namespace Urho3D
 {
 {
@@ -57,6 +57,7 @@ namespace Urho3D
 extern const char* NAVIGATION_CATEGORY;
 extern const char* NAVIGATION_CATEGORY;
 
 
 static const int DEFAULT_MAX_OBSTACLES = 1024;
 static const int DEFAULT_MAX_OBSTACLES = 1024;
+static const int DEFAULT_MAX_LAYERS = 16;
 
 
 struct DynamicNavigationMesh::TileCacheData
 struct DynamicNavigationMesh::TileCacheData
 {
 {
@@ -211,6 +212,7 @@ DynamicNavigationMesh::DynamicNavigationMesh(Context* context) :
     NavigationMesh(context),
     NavigationMesh(context),
     tileCache_(0),
     tileCache_(0),
     maxObstacles_(1024),
     maxObstacles_(1024),
+    maxLayers_(DEFAULT_MAX_LAYERS),
     drawObstacles_(false)
     drawObstacles_(false)
 {
 {
     //64 is the largest tile-size that DetourTileCache will tolerate without silently failing
     //64 is the largest tile-size that DetourTileCache will tolerate without silently failing
@@ -238,6 +240,7 @@ void DynamicNavigationMesh::RegisterObject(Context* context)
 
 
     URHO3D_COPY_BASE_ATTRIBUTES(NavigationMesh);
     URHO3D_COPY_BASE_ATTRIBUTES(NavigationMesh);
     URHO3D_ACCESSOR_ATTRIBUTE("Max Obstacles", GetMaxObstacles, SetMaxObstacles, unsigned, DEFAULT_MAX_OBSTACLES, AM_DEFAULT);
     URHO3D_ACCESSOR_ATTRIBUTE("Max Obstacles", GetMaxObstacles, SetMaxObstacles, unsigned, DEFAULT_MAX_OBSTACLES, AM_DEFAULT);
+    URHO3D_ACCESSOR_ATTRIBUTE("Max Layers", GetMaxLayers, SetMaxLayers, unsigned, DEFAULT_MAX_LAYERS, AM_DEFAULT);
     URHO3D_ACCESSOR_ATTRIBUTE("Draw Obstacles", GetDrawObstacles, SetDrawObstacles, bool, false, AM_DEFAULT);
     URHO3D_ACCESSOR_ATTRIBUTE("Draw Obstacles", GetDrawObstacles, SetDrawObstacles, bool, false, AM_DEFAULT);
 }
 }
 
 
@@ -278,7 +281,7 @@ bool DynamicNavigationMesh::Build()
         numTilesZ_ = (gridH + tileSize_ - 1) / tileSize_;
         numTilesZ_ = (gridH + tileSize_ - 1) / tileSize_;
 
 
         // Calculate max. number of tiles and polygons, 22 bits available to identify both tile & polygon within tile
         // Calculate max. number of tiles and polygons, 22 bits available to identify both tile & polygon within tile
-        unsigned maxTiles = NextPowerOfTwo((unsigned)(numTilesX_ * numTilesZ_)) * TILECACHE_MAXLAYERS;
+        unsigned maxTiles = NextPowerOfTwo((unsigned)(numTilesX_ * numTilesZ_)) * maxLayers_;
         unsigned tileBits = 0;
         unsigned tileBits = 0;
         unsigned temp = maxTiles;
         unsigned temp = maxTiles;
         while (temp > 1)
         while (temp > 1)
@@ -318,7 +321,7 @@ bool DynamicNavigationMesh::Build()
         tileCacheParams.width = tileSize_;
         tileCacheParams.width = tileSize_;
         tileCacheParams.height = tileSize_;
         tileCacheParams.height = tileSize_;
         tileCacheParams.maxSimplificationError = edgeMaxError_;
         tileCacheParams.maxSimplificationError = edgeMaxError_;
-        tileCacheParams.maxTiles = numTilesX_ * numTilesZ_ * TILECACHE_MAXLAYERS;
+        tileCacheParams.maxTiles = numTilesX_ * numTilesZ_ * maxLayers_;
         tileCacheParams.maxObstacles = maxObstacles_;
         tileCacheParams.maxObstacles = maxObstacles_;
         // Settings from NavigationMesh
         // Settings from NavigationMesh
         tileCacheParams.walkableClimb = agentMaxClimb_;
         tileCacheParams.walkableClimb = agentMaxClimb_;
@@ -429,7 +432,7 @@ bool DynamicNavigationMesh::Build(const BoundingBox& boundingBox)
         for (int x = sx; x <= ex; ++x)
         for (int x = sx; x <= ex; ++x)
         {
         {
             dtCompressedTileRef existing[TILECACHE_MAXLAYERS];
             dtCompressedTileRef existing[TILECACHE_MAXLAYERS];
-            const int existingCt = tileCache_->getTilesAt(x, z, existing, TILECACHE_MAXLAYERS);
+            const int existingCt = tileCache_->getTilesAt(x, z, existing, maxLayers_);
             for (int i = 0; i < existingCt; ++i)
             for (int i = 0; i < existingCt; ++i)
             {
             {
                 unsigned char* data = 0x0;
                 unsigned char* data = 0x0;
@@ -644,7 +647,7 @@ PODVector<unsigned char> DynamicNavigationMesh::GetNavigationDataAttr() const
             for (int x = 0; x < numTilesX_; ++x)
             for (int x = 0; x < numTilesX_; ++x)
             {
             {
                 dtCompressedTileRef tiles[TILECACHE_MAXLAYERS];
                 dtCompressedTileRef tiles[TILECACHE_MAXLAYERS];
-                const int ct = tileCache_->getTilesAt(x, z, tiles, TILECACHE_MAXLAYERS);
+                const int ct = tileCache_->getTilesAt(x, z, tiles, maxLayers_);
                 for (int i = 0; i < ct; ++i)
                 for (int i = 0; i < ct; ++i)
                 {
                 {
                     const dtCompressedTile* tile = tileCache_->getTileByRef(tiles[i]);
                     const dtCompressedTile* tile = tileCache_->getTileByRef(tiles[i]);
@@ -661,6 +664,13 @@ PODVector<unsigned char> DynamicNavigationMesh::GetNavigationDataAttr() const
     return ret.GetBuffer();
     return ret.GetBuffer();
 }
 }
 
 
+void DynamicNavigationMesh::SetMaxLayers(unsigned maxLayers)
+{
+    // Set 3 as a minimum due to the tendency of layers to be constructed inside the hollow space of stacked objects
+    // That behavior is unlikely to be expected by the end user
+    maxLayers_ = Max(3, Min(maxLayers, TILECACHE_MAXLAYERS));
+}
+
 int DynamicNavigationMesh::BuildTile(Vector<NavigationGeometryInfo>& geometryList, int x, int z, TileCacheData* tiles)
 int DynamicNavigationMesh::BuildTile(Vector<NavigationGeometryInfo>& geometryList, int x, int z, TileCacheData* tiles)
 {
 {
     URHO3D_PROFILE(BuildNavigationMeshTile);
     URHO3D_PROFILE(BuildNavigationMeshTile);

+ 6 - 0
Source/Urho3D/Navigation/DynamicNavigationMesh.h

@@ -70,9 +70,13 @@ public:
 
 
     /// Set the maximum number of obstacles allowed.
     /// Set the maximum number of obstacles allowed.
     void SetMaxObstacles(unsigned maxObstacles) { maxObstacles_ = maxObstacles; }
     void SetMaxObstacles(unsigned maxObstacles) { maxObstacles_ = maxObstacles; }
+    /// Set the maximum number of layers that navigation construction can create.
+    void SetMaxLayers(unsigned maxLayers);
 
 
     /// Return the maximum number of obstacles allowed.
     /// Return the maximum number of obstacles allowed.
     unsigned GetMaxObstacles() const { return maxObstacles_; }
     unsigned GetMaxObstacles() const { return maxObstacles_; }
+    /// Return the maximum number of layers permitted to build.
+    unsigned GetMaxLayers() const { return maxLayers_; }
 
 
     /// Draw debug geometry for Obstacles.
     /// Draw debug geometry for Obstacles.
     void SetDrawObstacles(bool enable) { drawObstacles_ = enable; }
     void SetDrawObstacles(bool enable) { drawObstacles_ = enable; }
@@ -116,6 +120,8 @@ private:
     dtTileCacheMeshProcess* meshProcessor_;
     dtTileCacheMeshProcess* meshProcessor_;
     /// Maximum number of obstacle objects allowed.
     /// Maximum number of obstacle objects allowed.
     unsigned maxObstacles_;
     unsigned maxObstacles_;
+    /// Maximum number of layers that are allowed to be constructed.
+    unsigned maxLayers_;
     /// Debug draw Obstacles.
     /// Debug draw Obstacles.
     bool drawObstacles_;
     bool drawObstacles_;
 };
 };