Browse Source

Reformat and reorganize include for Navigation sub-library.

Yao Wei Tjong 姚伟忠 10 years ago
parent
commit
69dd312d54

+ 27 - 27
Source/Urho3D/Navigation/CrowdAgent.cpp

@@ -22,19 +22,15 @@
 
 
 #include "../Precompiled.h"
 #include "../Precompiled.h"
 
 
-#include "../Scene/Component.h"
 #include "../Core/Context.h"
 #include "../Core/Context.h"
-#include "../Navigation/CrowdAgent.h"
-#include "../Navigation/CrowdManager.h"
+#include "../Core/Profiler.h"
 #include "../Graphics/DebugRenderer.h"
 #include "../Graphics/DebugRenderer.h"
 #include "../IO/Log.h"
 #include "../IO/Log.h"
 #include "../IO/MemoryBuffer.h"
 #include "../IO/MemoryBuffer.h"
 #include "../Navigation/NavigationEvents.h"
 #include "../Navigation/NavigationEvents.h"
+#include "../Navigation/CrowdAgent.h"
 #include "../Scene/Node.h"
 #include "../Scene/Node.h"
-#include "../Core/Profiler.h"
 #include "../Scene/Scene.h"
 #include "../Scene/Scene.h"
-#include "../Scene/Serializable.h"
-#include "../Core/Variant.h"
 
 
 #include <Detour/DetourCommon.h>
 #include <Detour/DetourCommon.h>
 #include <DetourCrowd/DetourCrowd.h>
 #include <DetourCrowd/DetourCrowd.h>
@@ -109,7 +105,8 @@ void CrowdAgent::RegisterObject(Context* context)
 
 
     ATTRIBUTE("Target Position", Vector3, targetPosition_, Vector3::ZERO, AM_DEFAULT);
     ATTRIBUTE("Target Position", Vector3, targetPosition_, Vector3::ZERO, AM_DEFAULT);
     ATTRIBUTE("Target Velocity", Vector3, targetVelocity_, Vector3::ZERO, AM_DEFAULT);
     ATTRIBUTE("Target Velocity", Vector3, targetVelocity_, Vector3::ZERO, AM_DEFAULT);
-    ENUM_ATTRIBUTE("Requested Target Type", requestedTargetType_, crowdAgentRequestedTargetTypeNames, DEFAULT_AGENT_REQUEST_TARGET_TYPE, AM_DEFAULT);
+    ENUM_ATTRIBUTE("Requested Target Type", requestedTargetType_, crowdAgentRequestedTargetTypeNames,
+        DEFAULT_AGENT_REQUEST_TARGET_TYPE, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Update Node Position", GetUpdateNodePosition, SetUpdateNodePosition, bool, true, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Update Node Position", GetUpdateNodePosition, SetUpdateNodePosition, bool, true, AM_DEFAULT);
     ATTRIBUTE("Max Accel", float, maxAccel_, DEFAULT_AGENT_MAX_ACCEL, AM_DEFAULT);
     ATTRIBUTE("Max Accel", float, maxAccel_, DEFAULT_AGENT_MAX_ACCEL, AM_DEFAULT);
     ATTRIBUTE("Max Speed", float, maxSpeed_, DEFAULT_AGENT_MAX_SPEED, AM_DEFAULT);
     ATTRIBUTE("Max Speed", float, maxSpeed_, DEFAULT_AGENT_MAX_SPEED, AM_DEFAULT);
@@ -137,7 +134,8 @@ void CrowdAgent::ApplyAttributes()
     CrowdAgentRequestedTarget requestedTargetType = requestedTargetType_;
     CrowdAgentRequestedTarget requestedTargetType = requestedTargetType_;
     if (CA_REQUESTEDTARGET_NONE != requestedTargetType_)
     if (CA_REQUESTEDTARGET_NONE != requestedTargetType_)
     {
     {
-        requestedTargetType_ = CA_REQUESTEDTARGET_NONE;     // Assign a dummy value such that the value check in the setter method passes
+        // Assign a dummy value such that the value check in the setter method passes
+        requestedTargetType_ = CA_REQUESTEDTARGET_NONE;
         if (requestedTargetType == CA_REQUESTEDTARGET_POSITION)
         if (requestedTargetType == CA_REQUESTEDTARGET_POSITION)
             SetTargetPosition(targetPosition_);
             SetTargetPosition(targetPosition_);
         else
         else
@@ -199,28 +197,28 @@ void CrowdAgent::UpdateParameters(unsigned scope)
             {
             {
             case NAVIGATIONQUALITY_LOW:
             case NAVIGATIONQUALITY_LOW:
                 params.updateFlags = 0
                 params.updateFlags = 0
-                    | DT_CROWD_OPTIMIZE_VIS
-                    | DT_CROWD_ANTICIPATE_TURNS;
+                                     | DT_CROWD_OPTIMIZE_VIS
+                                     | DT_CROWD_ANTICIPATE_TURNS;
                 break;
                 break;
 
 
             case NAVIGATIONQUALITY_MEDIUM:
             case NAVIGATIONQUALITY_MEDIUM:
                 params.updateFlags = 0
                 params.updateFlags = 0
-                    | DT_CROWD_OPTIMIZE_TOPO
-                    | DT_CROWD_OPTIMIZE_VIS
-                    | DT_CROWD_ANTICIPATE_TURNS
-                    | DT_CROWD_SEPARATION;
+                                     | DT_CROWD_OPTIMIZE_TOPO
+                                     | DT_CROWD_OPTIMIZE_VIS
+                                     | DT_CROWD_ANTICIPATE_TURNS
+                                     | DT_CROWD_SEPARATION;
                 break;
                 break;
 
 
             case NAVIGATIONQUALITY_HIGH:
             case NAVIGATIONQUALITY_HIGH:
                 params.updateFlags = 0
                 params.updateFlags = 0
-                    // Path finding
-                    | DT_CROWD_OPTIMIZE_TOPO
-                    | DT_CROWD_OPTIMIZE_VIS
-                    // Steering
-                    | DT_CROWD_ANTICIPATE_TURNS
-                    | DT_CROWD_SEPARATION
-                    // Velocity planning
-                    | DT_CROWD_OBSTACLE_AVOIDANCE;
+                                     // Path finding
+                                     | DT_CROWD_OPTIMIZE_TOPO
+                                     | DT_CROWD_OPTIMIZE_VIS
+                                     // Steering
+                                     | DT_CROWD_ANTICIPATE_TURNS
+                                     | DT_CROWD_SEPARATION
+                                     // Velocity planning
+                                     | DT_CROWD_OBSTACLE_AVOIDANCE;
                 break;
                 break;
             }
             }
         }
         }
@@ -413,7 +411,8 @@ void CrowdAgent::SetQueryFilterType(unsigned queryFilterType)
     {
     {
         if (queryFilterType >= DT_CROWD_MAX_QUERY_FILTER_TYPE)
         if (queryFilterType >= DT_CROWD_MAX_QUERY_FILTER_TYPE)
         {
         {
-            LOGERRORF("The specified filter type index (%d) exceeds the maximum allowed value (%d)", queryFilterType, DT_CROWD_MAX_QUERY_FILTER_TYPE);
+            LOGERRORF("The specified filter type index (%d) exceeds the maximum allowed value (%d)", queryFilterType,
+                DT_CROWD_MAX_QUERY_FILTER_TYPE);
             return;
             return;
         }
         }
 
 
@@ -429,7 +428,8 @@ void CrowdAgent::SetObstacleAvoidanceType(unsigned obstacleAvoidanceType)
     {
     {
         if (obstacleAvoidanceType >= DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS)
         if (obstacleAvoidanceType >= DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS)
         {
         {
-            LOGERRORF("The specified obstacle avoidance type index (%d) exceeds the maximum allowed value (%d)", obstacleAvoidanceType, DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS);
+            LOGERRORF("The specified obstacle avoidance type index (%d) exceeds the maximum allowed value (%d)",
+                obstacleAvoidanceType, DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS);
             return;
             return;
         }
         }
 
 
@@ -493,9 +493,9 @@ bool CrowdAgent::HasArrived() const
 {
 {
     // Is the agent at or near the end of its path and within its own radius of the goal?
     // Is the agent at or near the end of its path and within its own radius of the goal?
     const dtCrowdAgent* agent = GetDetourCrowdAgent();
     const dtCrowdAgent* agent = GetDetourCrowdAgent();
-    return agent && (!agent->ncorners ||
-        (agent->cornerFlags[agent->ncorners - 1] & DT_STRAIGHTPATH_END &&
-            dtVdist2D(agent->npos, &agent->cornerVerts[(agent->ncorners - 1) * 3]) <= agent->params.radius));
+    return agent && (!agent->ncorners || (agent->cornerFlags[agent->ncorners - 1] & DT_STRAIGHTPATH_END &&
+                                          dtVdist2D(agent->npos, &agent->cornerVerts[(agent->ncorners - 1) * 3]) <=
+                                          agent->params.radius));
 }
 }
 
 
 bool CrowdAgent::IsInCrowd() const
 bool CrowdAgent::IsInCrowd() const

+ 19 - 10
Source/Urho3D/Navigation/CrowdAgent.h

@@ -22,8 +22,8 @@
 
 
 #pragma once
 #pragma once
 
 
-#include "../Scene/Component.h"
 #include "../Navigation/CrowdManager.h"
 #include "../Navigation/CrowdManager.h"
+#include "../Scene/Component.h"
 
 
 namespace Urho3D
 namespace Urho3D
 {
 {
@@ -123,48 +123,59 @@ public:
     Vector3 GetDesiredVelocity() const;
     Vector3 GetDesiredVelocity() const;
     /// Return the agent's actual velocity.
     /// Return the agent's actual velocity.
     Vector3 GetActualVelocity() const;
     Vector3 GetActualVelocity() const;
+
     /// Return the agent's requested target position.
     /// Return the agent's requested target position.
     const Vector3& GetTargetPosition() const { return targetPosition_; }
     const Vector3& GetTargetPosition() const { return targetPosition_; }
+
     /// Return the agent's requested target velocity.
     /// Return the agent's requested target velocity.
     const Vector3& GetTargetVelocity() const { return targetVelocity_; }
     const Vector3& GetTargetVelocity() const { return targetVelocity_; }
+
     /// Return the agent's requested target type, if any.
     /// Return the agent's requested target type, if any.
     CrowdAgentRequestedTarget GetRequestedTargetType() const { return requestedTargetType_; }
     CrowdAgentRequestedTarget GetRequestedTargetType() const { return requestedTargetType_; }
+
     /// Return the agent's  state.
     /// Return the agent's  state.
     CrowdAgentState GetAgentState() const;
     CrowdAgentState GetAgentState() const;
     /// Return the agent's target state.
     /// Return the agent's target state.
     CrowdAgentTargetState GetTargetState() const;
     CrowdAgentTargetState GetTargetState() const;
+
     /// Return true when the node's position should be updated by the CrowdManager.
     /// Return true when the node's position should be updated by the CrowdManager.
     bool GetUpdateNodePosition() const { return updateNodePosition_; }
     bool GetUpdateNodePosition() const { return updateNodePosition_; }
+
     /// Return the agent id.
     /// Return the agent id.
     int GetAgentCrowdId() const { return agentCrowdId_; }
     int GetAgentCrowdId() const { return agentCrowdId_; }
+
     /// Get the agent's max acceleration.
     /// Get the agent's max acceleration.
     float GetMaxAccel() const { return maxAccel_; }
     float GetMaxAccel() const { return maxAccel_; }
+
     /// Get the agent's max velocity.
     /// Get the agent's max velocity.
     float GetMaxSpeed() const { return maxSpeed_; }
     float GetMaxSpeed() const { return maxSpeed_; }
+
     /// Get the agent's radius.
     /// Get the agent's radius.
     float GetRadius() const { return radius_; }
     float GetRadius() const { return radius_; }
+
     /// Get the agent's height.
     /// Get the agent's height.
     float GetHeight() const { return height_; }
     float GetHeight() const { return height_; }
+
     /// Get the agent's query filter type.
     /// Get the agent's query filter type.
     unsigned GetQueryFilterType() const { return queryFilterType_; }
     unsigned GetQueryFilterType() const { return queryFilterType_; }
+
     /// Get the agent's obstacle avoidance type.
     /// Get the agent's obstacle avoidance type.
     unsigned GetObstacleAvoidanceType() const { return obstacleAvoidanceType_; }
     unsigned GetObstacleAvoidanceType() const { return obstacleAvoidanceType_; }
+
     /// Get the agent's navigation quality.
     /// Get the agent's navigation quality.
-    NavigationQuality GetNavigationQuality() const {return navQuality_; }
+    NavigationQuality GetNavigationQuality() const { return navQuality_; }
+
     /// Get the agent's navigation pushiness.
     /// Get the agent's navigation pushiness.
-    NavigationPushiness GetNavigationPushiness() const {return navPushiness_; }
+    NavigationPushiness GetNavigationPushiness() const { return navPushiness_; }
+
     /// Return true when the agent has a target.
     /// Return true when the agent has a target.
     bool HasRequestedTarget() const { return requestedTargetType_ != CA_REQUESTEDTARGET_NONE; }
     bool HasRequestedTarget() const { return requestedTargetType_ != CA_REQUESTEDTARGET_NONE; }
+
     /// Return true when the agent has arrived at its target.
     /// Return true when the agent has arrived at its target.
     bool HasArrived() const;
     bool HasArrived() const;
     /// Return true when the agent is in crowd (being managed by a crowd manager).
     /// Return true when the agent is in crowd (being managed by a crowd manager).
     bool IsInCrowd() const;
     bool IsInCrowd() const;
 
 
-    /// Get serialized data of internal state.
-    PODVector<unsigned char> GetAgentDataAttr() const;
-    /// Set serialized data of internal state.
-    void SetAgentDataAttr(const PODVector<unsigned char>& value);
-
 protected:
 protected:
     /// Handle crowd agent being updated. It is called by CrowdManager::Update() via callback.
     /// Handle crowd agent being updated. It is called by CrowdManager::Update() via callback.
     virtual void OnCrowdUpdate(dtCrowdAgent* ag, float dt);
     virtual void OnCrowdUpdate(dtCrowdAgent* ag, float dt);
@@ -188,8 +199,6 @@ private:
     WeakPtr<CrowdManager> crowdManager_;
     WeakPtr<CrowdManager> crowdManager_;
     /// Crowd manager reference to this agent.
     /// Crowd manager reference to this agent.
     int agentCrowdId_;
     int agentCrowdId_;
-    /// Reference to poly closest to requested target position.
-    unsigned targetRef_;
     /// Requested target position.
     /// Requested target position.
     Vector3 targetPosition_;
     Vector3 targetPosition_;
     /// Requested target velocity.
     /// Requested target velocity.

+ 34 - 22
Source/Urho3D/Navigation/CrowdManager.cpp

@@ -22,23 +22,19 @@
 
 
 #include "../Precompiled.h"
 #include "../Precompiled.h"
 
 
-#include "../Scene/Component.h"
 #include "../Core/Context.h"
 #include "../Core/Context.h"
+#include "../Core/Profiler.h"
+#include "../Graphics/DebugRenderer.h"
+#include "../IO/Log.h"
 #include "../Navigation/CrowdAgent.h"
 #include "../Navigation/CrowdAgent.h"
 #include "../Navigation/CrowdManager.h"
 #include "../Navigation/CrowdManager.h"
-#include "../Graphics/DebugRenderer.h"
 #include "../Navigation/DynamicNavigationMesh.h"
 #include "../Navigation/DynamicNavigationMesh.h"
-#include "../IO/Log.h"
 #include "../Navigation/NavigationEvents.h"
 #include "../Navigation/NavigationEvents.h"
-#include "../Navigation/NavigationMesh.h"
 #include "../Scene/Node.h"
 #include "../Scene/Node.h"
-#include "../Core/Profiler.h"
 #include "../Scene/Scene.h"
 #include "../Scene/Scene.h"
 #include "../Scene/SceneEvents.h"
 #include "../Scene/SceneEvents.h"
-#include "../Container/Vector.h"
 
 
 #include <DetourCrowd/DetourCrowd.h>
 #include <DetourCrowd/DetourCrowd.h>
-#include <Recast/Recast.h>
 
 
 #include "../DebugNew.h"
 #include "../DebugNew.h"
 
 
@@ -84,14 +80,16 @@ void CrowdManager::RegisterObject(Context* context)
     ATTRIBUTE("Max Agents", unsigned, maxAgents_, DEFAULT_MAX_AGENTS, AM_DEFAULT);
     ATTRIBUTE("Max Agents", unsigned, maxAgents_, DEFAULT_MAX_AGENTS, AM_DEFAULT);
     ATTRIBUTE("Max Agent Radius", float, maxAgentRadius_, DEFAULT_MAX_AGENT_RADIUS, AM_DEFAULT);
     ATTRIBUTE("Max Agent Radius", float, maxAgentRadius_, DEFAULT_MAX_AGENT_RADIUS, AM_DEFAULT);
     ATTRIBUTE("Navigation Mesh", unsigned, navigationMeshId_, 0, AM_DEFAULT | AM_COMPONENTID);
     ATTRIBUTE("Navigation Mesh", unsigned, navigationMeshId_, 0, AM_DEFAULT | AM_COMPONENTID);
-    MIXED_ACCESSOR_ATTRIBUTE("Filter Types", GetQueryFilterTypesAttr, SetQueryFilterTypesAttr, VariantVector, Variant::emptyVariantVector, AM_DEFAULT);
-    MIXED_ACCESSOR_ATTRIBUTE("Obstacle Avoidance Types", GetObstacleAvoidanceTypesAttr, SetObstacleAvoidanceTypesAttr, VariantVector, Variant::emptyVariantVector, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Filter Types", GetQueryFilterTypesAttr, SetQueryFilterTypesAttr, VariantVector,
+        Variant::emptyVariantVector, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Obstacle Avoidance Types", GetObstacleAvoidanceTypesAttr, SetObstacleAvoidanceTypesAttr,
+        VariantVector, Variant::emptyVariantVector, AM_DEFAULT);
 }
 }
 
 
 void CrowdManager::ApplyAttributes()
 void CrowdManager::ApplyAttributes()
 {
 {
     // Values from Editor, saved-file, or network must be checked before applying
     // Values from Editor, saved-file, or network must be checked before applying
-    maxAgents_ = Max(1, maxAgents_);
+    maxAgents_ = (unsigned)Max(1, maxAgents_);
     maxAgentRadius_ = Max(0.f, maxAgentRadius_);
     maxAgentRadius_ = Max(0.f, maxAgentRadius_);
 
 
     bool navMeshChange = false;
     bool navMeshChange = false;
@@ -105,7 +103,8 @@ void CrowdManager::ApplyAttributes()
             navigationMesh_ = navMesh;
             navigationMesh_ = navMesh;
         }
         }
     }
     }
-    navigationMeshId_ = navigationMesh_ ? navigationMesh_->GetID() : 0;     // In case of receiving an invalid component id, revert it back to the existing navmesh component id (if any)
+    // In case of receiving an invalid component id, revert it back to the existing navmesh component id (if any)
+    navigationMeshId_ = navigationMesh_ ? navigationMesh_->GetID() : 0;
 
 
     // If the Detour crowd initialization parameters have changed then recreate it
     // If the Detour crowd initialization parameters have changed then recreate it
     if (crowd_ && (navMeshChange || crowd_->getAgentCount() != maxAgents_ || crowd_->getMaxAgentRadius() != maxAgentRadius_))
     if (crowd_ && (navMeshChange || crowd_->getAgentCount() != maxAgents_ || crowd_->getMaxAgentRadius() != maxAgentRadius_))
@@ -359,12 +358,15 @@ Vector3 CrowdManager::FindNearestPoint(const Vector3& point, int queryFilterType
 {
 {
     if (nearestRef)
     if (nearestRef)
         *nearestRef = 0;
         *nearestRef = 0;
-    return crowd_ && navigationMesh_ ? navigationMesh_->FindNearestPoint(point, crowd_->getQueryExtents(), crowd_->getFilter(queryFilterType), nearestRef) : point;
+    return crowd_ && navigationMesh_ ?
+        navigationMesh_->FindNearestPoint(point, crowd_->getQueryExtents(), crowd_->getFilter(queryFilterType), nearestRef) : point;
 }
 }
 
 
 Vector3 CrowdManager::MoveAlongSurface(const Vector3& start, const Vector3& end, int queryFilterType, int maxVisited)
 Vector3 CrowdManager::MoveAlongSurface(const Vector3& start, const Vector3& end, int queryFilterType, int maxVisited)
 {
 {
-    return crowd_ && navigationMesh_ ? navigationMesh_->MoveAlongSurface(start, end, crowd_->getQueryExtents(), maxVisited, crowd_->getFilter(queryFilterType)) : end;
+    return crowd_ && navigationMesh_ ?
+        navigationMesh_->MoveAlongSurface(start, end, crowd_->getQueryExtents(), maxVisited, crowd_->getFilter(queryFilterType)) :
+        end;
 }
 }
 
 
 void CrowdManager::FindPath(PODVector<Vector3>& dest, const Vector3& start, const Vector3& end, int queryFilterType)
 void CrowdManager::FindPath(PODVector<Vector3>& dest, const Vector3& start, const Vector3& end, int queryFilterType)
@@ -377,14 +379,17 @@ Vector3 CrowdManager::GetRandomPoint(int queryFilterType, dtPolyRef* randomRef)
 {
 {
     if (randomRef)
     if (randomRef)
         *randomRef = 0;
         *randomRef = 0;
-    return crowd_ && navigationMesh_ ? navigationMesh_->GetRandomPoint(crowd_->getFilter(queryFilterType), randomRef) : Vector3::ZERO;
+    return crowd_ && navigationMesh_ ? navigationMesh_->GetRandomPoint(crowd_->getFilter(queryFilterType), randomRef) :
+        Vector3::ZERO;
 }
 }
 
 
 Vector3 CrowdManager::GetRandomPointInCircle(const Vector3& center, float radius, int queryFilterType, dtPolyRef* randomRef)
 Vector3 CrowdManager::GetRandomPointInCircle(const Vector3& center, float radius, int queryFilterType, dtPolyRef* randomRef)
 {
 {
     if (randomRef)
     if (randomRef)
         *randomRef = 0;
         *randomRef = 0;
-    return crowd_ && navigationMesh_ ? navigationMesh_->GetRandomPointInCircle(center, radius, crowd_->getQueryExtents(), crowd_->getFilter(queryFilterType), randomRef) : center;
+    return crowd_ && navigationMesh_ ?
+        navigationMesh_->GetRandomPointInCircle(center, radius, crowd_->getQueryExtents(), crowd_->getFilter(queryFilterType),
+            randomRef) : center;
 }
 }
 
 
 float CrowdManager::GetDistanceToWall(const Vector3& point, float radius, int queryFilterType, Vector3* hitPos, Vector3* hitNormal)
 float CrowdManager::GetDistanceToWall(const Vector3& point, float radius, int queryFilterType, Vector3* hitPos, Vector3* hitNormal)
@@ -393,14 +398,17 @@ float CrowdManager::GetDistanceToWall(const Vector3& point, float radius, int qu
         *hitPos = Vector3::ZERO;
         *hitPos = Vector3::ZERO;
     if (hitNormal)
     if (hitNormal)
         *hitNormal = Vector3::DOWN;
         *hitNormal = Vector3::DOWN;
-    return crowd_ && navigationMesh_ ? navigationMesh_->GetDistanceToWall(point, radius, crowd_->getQueryExtents(), crowd_->getFilter(queryFilterType), hitPos, hitNormal) : radius;
+    return crowd_ && navigationMesh_ ?
+        navigationMesh_->GetDistanceToWall(point, radius, crowd_->getQueryExtents(), crowd_->getFilter(queryFilterType), hitPos,
+            hitNormal) : radius;
 }
 }
 
 
 Vector3 CrowdManager::Raycast(const Vector3& start, const Vector3& end, int queryFilterType, Vector3* hitNormal)
 Vector3 CrowdManager::Raycast(const Vector3& start, const Vector3& end, int queryFilterType, Vector3* hitNormal)
 {
 {
     if (hitNormal)
     if (hitNormal)
         *hitNormal = Vector3::DOWN;
         *hitNormal = Vector3::DOWN;
-    return crowd_ && navigationMesh_ ? navigationMesh_->Raycast(start, end, crowd_->getQueryExtents(), crowd_->getFilter(queryFilterType), hitNormal) : end;
+    return crowd_ && navigationMesh_ ?
+        navigationMesh_->Raycast(start, end, crowd_->getQueryExtents(), crowd_->getFilter(queryFilterType), hitNormal) : end;
 }
 }
 
 
 unsigned CrowdManager::GetNumAreas(unsigned queryFilterType) const
 unsigned CrowdManager::GetNumAreas(unsigned queryFilterType) const
@@ -441,23 +449,27 @@ VariantVector CrowdManager::GetQueryFilterTypesAttr() const
 unsigned short CrowdManager::GetIncludeFlags(unsigned queryFilterType) const
 unsigned short CrowdManager::GetIncludeFlags(unsigned queryFilterType) const
 {
 {
     if (queryFilterType >= numQueryFilterTypes_)
     if (queryFilterType >= numQueryFilterTypes_)
-        LOGWARNINGF("Query filter type %d is not configured yet, returning the default include flags initialized by dtCrowd", queryFilterType);
+        LOGWARNINGF("Query filter type %d is not configured yet, returning the default include flags initialized by dtCrowd",
+            queryFilterType);
     const dtQueryFilter* filter = GetDetourQueryFilter(queryFilterType);
     const dtQueryFilter* filter = GetDetourQueryFilter(queryFilterType);
-    return filter ? filter->getIncludeFlags() : 0xffff;
+    return (unsigned short)(filter ? filter->getIncludeFlags() : 0xffff);
 }
 }
 
 
 unsigned short CrowdManager::GetExcludeFlags(unsigned queryFilterType) const
 unsigned short CrowdManager::GetExcludeFlags(unsigned queryFilterType) const
 {
 {
     if (queryFilterType >= numQueryFilterTypes_)
     if (queryFilterType >= numQueryFilterTypes_)
-        LOGWARNINGF("Query filter type %d is not configured yet, returning the default exclude flags initialized by dtCrowd", queryFilterType);
+        LOGWARNINGF("Query filter type %d is not configured yet, returning the default exclude flags initialized by dtCrowd",
+            queryFilterType);
     const dtQueryFilter* filter = GetDetourQueryFilter(queryFilterType);
     const dtQueryFilter* filter = GetDetourQueryFilter(queryFilterType);
-    return filter ? filter->getExcludeFlags() : 0;
+    return (unsigned short)(filter ? filter->getExcludeFlags() : 0);
 }
 }
 
 
 float CrowdManager::GetAreaCost(unsigned queryFilterType, unsigned areaID) const
 float CrowdManager::GetAreaCost(unsigned queryFilterType, unsigned areaID) const
 {
 {
     if (queryFilterType >= numQueryFilterTypes_ || areaID >= numAreas_[queryFilterType])
     if (queryFilterType >= numQueryFilterTypes_ || areaID >= numAreas_[queryFilterType])
-        LOGWARNINGF("Query filter type %d and/or area id %d are not configured yet, returning the default area cost initialized by dtCrowd", queryFilterType, areaID);
+        LOGWARNINGF(
+            "Query filter type %d and/or area id %d are not configured yet, returning the default area cost initialized by dtCrowd",
+            queryFilterType, areaID);
     const dtQueryFilter* filter = GetDetourQueryFilter(queryFilterType);
     const dtQueryFilter* filter = GetDetourQueryFilter(queryFilterType);
     return filter ? filter->getAreaCost((int)areaID) : 1.f;
     return filter ? filter->getAreaCost((int)areaID) : 1.f;
 }
 }

+ 8 - 0
Source/Urho3D/Navigation/CrowdManager.h

@@ -118,14 +118,19 @@ public:
     float GetDistanceToWall(const Vector3& point, float radius, int queryFilterType, Vector3* hitPos = 0, Vector3* hitNormal = 0);
     float GetDistanceToWall(const Vector3& point, float radius, int queryFilterType, Vector3* hitPos = 0, Vector3* hitNormal = 0);
     /// Perform a walkability raycast on the navigation mesh between start and end using the crowd initialized query extent (based on maxAgentRadius) and the specified query filter type. Return the point where a wall was hit, or the end point if no walls.
     /// Perform a walkability raycast on the navigation mesh between start and end using the crowd initialized query extent (based on maxAgentRadius) and the specified query filter type. Return the point where a wall was hit, or the end point if no walls.
     Vector3 Raycast(const Vector3& start, const Vector3& end, int queryFilterType, Vector3* hitNormal = 0);
     Vector3 Raycast(const Vector3& start, const Vector3& end, int queryFilterType, Vector3* hitNormal = 0);
+
     /// Get the maximum number of agents.
     /// Get the maximum number of agents.
     unsigned GetMaxAgents() const { return maxAgents_; }
     unsigned GetMaxAgents() const { return maxAgents_; }
+
     /// Get the maximum radius of any agent.
     /// Get the maximum radius of any agent.
     float GetMaxAgentRadius() const { return maxAgentRadius_; }
     float GetMaxAgentRadius() const { return maxAgentRadius_; }
+
     /// Get the Navigation mesh assigned to the crowd.
     /// Get the Navigation mesh assigned to the crowd.
     NavigationMesh* GetNavigationMesh() const { return navigationMesh_; }
     NavigationMesh* GetNavigationMesh() const { return navigationMesh_; }
+
     /// Get the number of configured query filter types.
     /// Get the number of configured query filter types.
     unsigned GetNumQueryFilterTypes() const { return numQueryFilterTypes_; }
     unsigned GetNumQueryFilterTypes() const { return numQueryFilterTypes_; }
+
     /// Get the number of configured area in the specified query filter type.
     /// Get the number of configured area in the specified query filter type.
     unsigned GetNumAreas(unsigned queryFilterType) const;
     unsigned GetNumAreas(unsigned queryFilterType) const;
     /// Return all the filter types configured in the crowd as attribute.
     /// Return all the filter types configured in the crowd as attribute.
@@ -136,8 +141,10 @@ public:
     unsigned short GetExcludeFlags(unsigned queryFilterType) const;
     unsigned short GetExcludeFlags(unsigned queryFilterType) const;
     /// Get the cost of an area for the specified query filter type.
     /// Get the cost of an area for the specified query filter type.
     float GetAreaCost(unsigned queryFilterType, unsigned areaID) const;
     float GetAreaCost(unsigned queryFilterType, unsigned areaID) const;
+
     /// Get the number of configured obstacle avoidance types.
     /// Get the number of configured obstacle avoidance types.
     unsigned GetNumObstacleAvoidanceTypes() const { return numObstacleAvoidanceTypes_; }
     unsigned GetNumObstacleAvoidanceTypes() const { return numObstacleAvoidanceTypes_; }
+
     /// Return all the obstacle avoidance types configured in the crowd as attribute.
     /// Return all the obstacle avoidance types configured in the crowd as attribute.
     VariantVector GetObstacleAvoidanceTypesAttr() const;
     VariantVector GetObstacleAvoidanceTypesAttr() const;
     /// Get the params for the specified obstacle avoidance type.
     /// Get the params for the specified obstacle avoidance type.
@@ -160,6 +167,7 @@ protected:
     const dtCrowdAgent* GetDetourCrowdAgent(int agent) const;
     const dtCrowdAgent* GetDetourCrowdAgent(int agent) const;
     /// Get the detour query filter.
     /// Get the detour query filter.
     const dtQueryFilter* GetDetourQueryFilter(unsigned queryFilterType) const;
     const dtQueryFilter* GetDetourQueryFilter(unsigned queryFilterType) const;
+
     /// Get the internal detour crowd component.
     /// Get the internal detour crowd component.
     dtCrowd* GetCrowd() const { return crowd_; }
     dtCrowd* GetCrowd() const { return crowd_; }
 
 

+ 31 - 35
Source/Urho3D/Navigation/DynamicNavigationMesh.cpp

@@ -22,35 +22,31 @@
 
 
 #include "../Precompiled.h"
 #include "../Precompiled.h"
 
 
-#include "../Navigation/DynamicNavigationMesh.h"
 
 
-#include "../Math/BoundingBox.h"
 #include "../Core/Context.h"
 #include "../Core/Context.h"
-#include "../Navigation/CrowdAgent.h"
+#include "../Core/Profiler.h"
 #include "../Graphics/DebugRenderer.h"
 #include "../Graphics/DebugRenderer.h"
 #include "../IO/Log.h"
 #include "../IO/Log.h"
 #include "../IO/MemoryBuffer.h"
 #include "../IO/MemoryBuffer.h"
+#include "../Navigation/CrowdAgent.h"
+#include "../Navigation/DynamicNavigationMesh.h"
 #include "../Navigation/NavArea.h"
 #include "../Navigation/NavArea.h"
 #include "../Navigation/NavBuildData.h"
 #include "../Navigation/NavBuildData.h"
 #include "../Navigation/NavigationEvents.h"
 #include "../Navigation/NavigationEvents.h"
-#include "../Scene/Node.h"
 #include "../Navigation/Obstacle.h"
 #include "../Navigation/Obstacle.h"
 #include "../Navigation/OffMeshConnection.h"
 #include "../Navigation/OffMeshConnection.h"
-#include "../Core/Profiler.h"
+#include "../Scene/Node.h"
 #include "../Scene/Scene.h"
 #include "../Scene/Scene.h"
 #include "../Scene/SceneEvents.h"
 #include "../Scene/SceneEvents.h"
 
 
 #include <LZ4/lz4.h>
 #include <LZ4/lz4.h>
-#include <cfloat>
 #include <Detour/DetourNavMesh.h>
 #include <Detour/DetourNavMesh.h>
 #include <Detour/DetourNavMeshBuilder.h>
 #include <Detour/DetourNavMeshBuilder.h>
-#include <Detour/DetourNavMeshQuery.h>
 #include <DetourTileCache/DetourTileCache.h>
 #include <DetourTileCache/DetourTileCache.h>
 #include <DetourTileCache/DetourTileCacheBuilder.h>
 #include <DetourTileCache/DetourTileCacheBuilder.h>
 #include <Recast/Recast.h>
 #include <Recast/Recast.h>
-#include <Recast/RecastAlloc.h>
 
 
-//DebugNew is deliberately not used because the macro 'free' conflicts 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 128
@@ -72,7 +68,7 @@ struct TileCompressor : public dtTileCacheCompressor
 {
 {
     virtual int maxCompressedSize(const int bufferSize)
     virtual int maxCompressedSize(const int bufferSize)
     {
     {
-        return (int)(bufferSize* 1.05f);
+        return (int)(bufferSize * 1.05f);
     }
     }
 
 
     virtual dtStatus compress(const unsigned char* buffer, const int bufferSize,
     virtual dtStatus compress(const unsigned char* buffer, const int bufferSize,
@@ -136,9 +132,9 @@ struct MeshProcess : public dtTileCacheMeshProcess
                     offMeshVertices_.Push(start);
                     offMeshVertices_.Push(start);
                     offMeshVertices_.Push(end);
                     offMeshVertices_.Push(end);
                     offMeshRadii_.Push(connection->GetRadius());
                     offMeshRadii_.Push(connection->GetRadius());
-                    offMeshFlags_.Push(connection->GetMask());
+                    offMeshFlags_.Push((unsigned short)connection->GetMask());
                     offMeshAreas_.Push((unsigned char)connection->GetAreaID());
                     offMeshAreas_.Push((unsigned char)connection->GetAreaID());
-                    offMeshDir_.Push(connection->IsBidirectional() ? DT_OFFMESH_CON_BIDIR : 0);
+                    offMeshDir_.Push((unsigned char)(connection->IsBidirectional() ? DT_OFFMESH_CON_BIDIR : 0));
                 }
                 }
             }
             }
             params->offMeshConCount = offMeshRadii_.Size();
             params->offMeshConCount = offMeshRadii_.Size();
@@ -169,7 +165,8 @@ struct LinearAllocator : public dtTileCacheAlloc
     int top;
     int top;
     int high;
     int high;
 
 
-    LinearAllocator(const int cap) : buffer(0), capacity(0), top(0), high(0)
+    LinearAllocator(const int cap) :
+        buffer(0), capacity(0), top(0), high(0)
     {
     {
         resize(cap);
         resize(cap);
     }
     }
@@ -281,7 +278,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(numTilesX_ * numTilesZ_) * TILECACHE_MAXLAYERS;
+        unsigned maxTiles = NextPowerOfTwo((unsigned)(numTilesX_ * numTilesZ_)) * TILECACHE_MAXLAYERS;
         unsigned tileBits = 0;
         unsigned tileBits = 0;
         unsigned temp = maxTiles;
         unsigned temp = maxTiles;
         while (temp > 1)
         while (temp > 1)
@@ -290,7 +287,7 @@ bool DynamicNavigationMesh::Build()
             ++tileBits;
             ++tileBits;
         }
         }
 
 
-        unsigned maxPolys = 1 << (22 - tileBits);
+        unsigned maxPolys = (unsigned)(1 << (22 - tileBits));
 
 
         dtNavMeshParams params;
         dtNavMeshParams params;
         rcVcopy(params.orig, &boundingBox_.min_.x_);
         rcVcopy(params.orig, &boundingBox_.min_.x_);
@@ -356,7 +353,7 @@ bool DynamicNavigationMesh::Build()
                 {
                 {
                     dtCompressedTileRef tileRef;
                     dtCompressedTileRef tileRef;
                     int status = tileCache_->addTile(tiles[i].data, tiles[i].dataSize, DT_COMPRESSEDTILE_FREE_DATA, &tileRef);
                     int status = tileCache_->addTile(tiles[i].data, tiles[i].dataSize, DT_COMPRESSEDTILE_FREE_DATA, &tileRef);
-                    if (dtStatusFailed(status))
+                    if (dtStatusFailed((dtStatus)status))
                     {
                     {
                         dtFree(tiles[i].data);
                         dtFree(tiles[i].data);
                         tiles[i].data = 0x0;
                         tiles[i].data = 0x0;
@@ -446,7 +443,7 @@ bool DynamicNavigationMesh::Build(const BoundingBox& boundingBox)
             {
             {
                 dtCompressedTileRef tileRef;
                 dtCompressedTileRef tileRef;
                 int status = tileCache_->addTile(tiles[i].data, tiles[i].dataSize, DT_COMPRESSEDTILE_FREE_DATA, &tileRef);
                 int status = tileCache_->addTile(tiles[i].data, tiles[i].dataSize, DT_COMPRESSEDTILE_FREE_DATA, &tileRef);
-                if (dtStatusFailed(status))
+                if (dtStatusFailed((dtStatus)status))
                 {
                 {
                     dtFree(tiles[i].data);
                     dtFree(tiles[i].data);
                     tiles[i].data = 0x0;
                     tiles[i].data = 0x0;
@@ -492,12 +489,9 @@ void DynamicNavigationMesh::DrawDebugGeometry(DebugRenderer* debug, bool depthTe
                     dtPoly* poly = tile->polys + i;
                     dtPoly* poly = tile->polys + i;
                     for (unsigned j = 0; j < poly->vertCount; ++j)
                     for (unsigned j = 0; j < poly->vertCount; ++j)
                     {
                     {
-                        debug->AddLine(
-                            worldTransform * *reinterpret_cast<const Vector3*>(&tile->verts[poly->verts[j] * 3]),
+                        debug->AddLine(worldTransform * *reinterpret_cast<const Vector3*>(&tile->verts[poly->verts[j] * 3]),
                             worldTransform * *reinterpret_cast<const Vector3*>(&tile->verts[poly->verts[(j + 1) % poly->vertCount] * 3]),
                             worldTransform * *reinterpret_cast<const Vector3*>(&tile->verts[poly->verts[(j + 1) % poly->vertCount] * 3]),
-                            Color::YELLOW,
-                            depthTest
-                            );
+                            Color::YELLOW, depthTest);
                     }
                     }
                 }
                 }
             }
             }
@@ -611,7 +605,7 @@ void DynamicNavigationMesh::SetNavigationDataAttr(const PODVector<unsigned char>
         buffer.Read(&header, sizeof(dtTileCacheLayerHeader));
         buffer.Read(&header, sizeof(dtTileCacheLayerHeader));
         const int dataSize = buffer.ReadInt();
         const int dataSize = buffer.ReadInt();
         unsigned char* data = (unsigned char*)dtAlloc(dataSize, DT_ALLOC_PERM);
         unsigned char* data = (unsigned char*)dtAlloc(dataSize, DT_ALLOC_PERM);
-        buffer.Read(data, dataSize);
+        buffer.Read(data, (unsigned)dataSize);
 
 
         if (dtStatusFailed(tileCache_->addTile(data, dataSize, DT_TILE_FREE_DATA, 0)))
         if (dtStatusFailed(tileCache_->addTile(data, dataSize, DT_TILE_FREE_DATA, 0)))
         {
         {
@@ -659,7 +653,7 @@ PODVector<unsigned char> DynamicNavigationMesh::GetNavigationDataAttr() const
                     // The header conveniently has the majority of the information required
                     // The header conveniently has the majority of the information required
                     ret.Write(tile->header, sizeof(dtTileCacheLayerHeader));
                     ret.Write(tile->header, sizeof(dtTileCacheLayerHeader));
                     ret.WriteInt(tile->dataSize);
                     ret.WriteInt(tile->dataSize);
-                    ret.Write(tile->data, tile->dataSize);
+                    ret.Write(tile->data, (unsigned)tile->dataSize);
                 }
                 }
             }
             }
         }
         }
@@ -676,15 +670,13 @@ int DynamicNavigationMesh::BuildTile(Vector<NavigationGeometryInfo>& geometryLis
     float tileEdgeLength = (float)tileSize_ * cellSize_;
     float tileEdgeLength = (float)tileSize_ * cellSize_;
 
 
     BoundingBox tileBoundingBox(Vector3(
     BoundingBox tileBoundingBox(Vector3(
-        boundingBox_.min_.x_ + tileEdgeLength * (float)x,
-        boundingBox_.min_.y_,
-        boundingBox_.min_.z_ + tileEdgeLength * (float)z
-        ),
+            boundingBox_.min_.x_ + tileEdgeLength * (float)x,
+            boundingBox_.min_.y_,
+            boundingBox_.min_.z_ + tileEdgeLength * (float)z),
         Vector3(
         Vector3(
-        boundingBox_.min_.x_ + tileEdgeLength * (float)(x + 1),
-        boundingBox_.max_.y_,
-        boundingBox_.min_.z_ + tileEdgeLength * (float)(z + 1)
-        ));
+            boundingBox_.min_.x_ + tileEdgeLength * (float)(x + 1),
+            boundingBox_.max_.y_,
+            boundingBox_.min_.z_ + tileEdgeLength * (float)(z + 1)));
 
 
     DynamicNavBuildData build(allocator_);
     DynamicNavBuildData build(allocator_);
 
 
@@ -768,7 +760,8 @@ int DynamicNavigationMesh::BuildTile(Vector<NavigationGeometryInfo>& geometryLis
 
 
     // area volumes
     // area volumes
     for (unsigned i = 0; i < build.navAreas_.Size(); ++i)
     for (unsigned i = 0; i < build.navAreas_.Size(); ++i)
-        rcMarkBoxArea(build.ctx_, &build.navAreas_[i].bounds_.min_.x_, &build.navAreas_[i].bounds_.max_.x_, build.navAreas_[i].areaID_, *build.compactHeightField_);
+        rcMarkBoxArea(build.ctx_, &build.navAreas_[i].bounds_.min_.x_, &build.navAreas_[i].bounds_.max_.x_,
+            build.navAreas_[i].areaID_, *build.compactHeightField_);
 
 
     if (this->partitionType_ == NAVMESH_PARTITION_WATERSHED)
     if (this->partitionType_ == NAVMESH_PARTITION_WATERSHED)
     {
     {
@@ -800,7 +793,8 @@ int DynamicNavigationMesh::BuildTile(Vector<NavigationGeometryInfo>& geometryLis
         return 0;
         return 0;
     }
     }
 
 
-    if (!rcBuildHeightfieldLayers(build.ctx_, *build.compactHeightField_, cfg.borderSize, cfg.walkableHeight, *build.heightFieldLayers_))
+    if (!rcBuildHeightfieldLayers(build.ctx_, *build.compactHeightField_, cfg.borderSize, cfg.walkableHeight,
+        *build.heightFieldLayers_))
     {
     {
         LOGERROR("Could not build height field layers");
         LOGERROR("Could not build height field layers");
         return 0;
         return 0;
@@ -830,7 +824,9 @@ int DynamicNavigationMesh::BuildTile(Vector<NavigationGeometryInfo>& geometryLis
         header.hmin = (unsigned short)layer->hmin;
         header.hmin = (unsigned short)layer->hmin;
         header.hmax = (unsigned short)layer->hmax;
         header.hmax = (unsigned short)layer->hmax;
 
 
-        if (dtStatusFailed(dtBuildTileCacheLayer(compressor_/*compressor*/, &header, layer->heights, layer->areas/*areas*/, layer->cons, &(tiles[retCt].data), &tiles[retCt].dataSize)))
+        if (dtStatusFailed(
+            dtBuildTileCacheLayer(compressor_/*compressor*/, &header, layer->heights, layer->areas/*areas*/, layer->cons,
+                &(tiles[retCt].data), &tiles[retCt].dataSize)))
         {
         {
             LOGERROR("Failed to build tile cache layers");
             LOGERROR("Failed to build tile cache layers");
             return 0;
             return 0;

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

@@ -41,6 +41,7 @@ class Obstacle;
 class URHO3D_API DynamicNavigationMesh : public NavigationMesh
 class URHO3D_API DynamicNavigationMesh : public NavigationMesh
 {
 {
     OBJECT(DynamicNavigationMesh)
     OBJECT(DynamicNavigationMesh)
+
     friend class Obstacle;
     friend class Obstacle;
     friend struct MeshProcess;
     friend struct MeshProcess;
 
 
@@ -69,11 +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; }
+
     /// Return the maximum number of obstacles allowed.
     /// Return the maximum number of obstacles allowed.
     unsigned GetMaxObstacles() const { return maxObstacles_; }
     unsigned GetMaxObstacles() const { return maxObstacles_; }
 
 
     /// Draw debug geometry for Obstacles.
     /// Draw debug geometry for Obstacles.
     void SetDrawObstacles(bool enable) { drawObstacles_ = enable; }
     void SetDrawObstacles(bool enable) { drawObstacles_ = enable; }
+
     /// Return whether to draw Obstacles.
     /// Return whether to draw Obstacles.
     bool GetDrawObstacles() const { return drawObstacles_; }
     bool GetDrawObstacles() const { return drawObstacles_; }
 
 

+ 43 - 44
Source/Urho3D/Navigation/NavArea.cpp

@@ -22,67 +22,66 @@
 
 
 #include "../Precompiled.h"
 #include "../Precompiled.h"
 
 
-#include "../Scene/Component.h"
 #include "../Core/Context.h"
 #include "../Core/Context.h"
 #include "../Graphics/DebugRenderer.h"
 #include "../Graphics/DebugRenderer.h"
 #include "../IO/Log.h"
 #include "../IO/Log.h"
 #include "../Navigation/NavArea.h"
 #include "../Navigation/NavArea.h"
 #include "../Scene/Node.h"
 #include "../Scene/Node.h"
-#include "../Container/Str.h"
 
 
 namespace Urho3D
 namespace Urho3D
 {
 {
-    static const unsigned MAX_NAV_AREA_ID = 255;
-    static const Vector3 DEFAULT_BOUNDING_BOX_MIN(-10.0f, -10.0f, -10.0f);
-    static const Vector3 DEFAULT_BOUNDING_BOX_MAX(10.0f, 10.0f, 10.0f);
-    static const unsigned DEFAULT_MASK_FLAG = 0;
-    static const unsigned DEFAULT_AREA_ID = 0;
 
 
-    extern const char* NAVIGATION_CATEGORY;
+static const unsigned MAX_NAV_AREA_ID = 255;
+static const Vector3 DEFAULT_BOUNDING_BOX_MIN(-10.0f, -10.0f, -10.0f);
+static const Vector3 DEFAULT_BOUNDING_BOX_MAX(10.0f, 10.0f, 10.0f);
+static const unsigned DEFAULT_AREA_ID = 0;
 
 
-    NavArea::NavArea(Context* context) :
-        Component(context),
-        areaID_(DEFAULT_AREA_ID),
-        boundingBox_(DEFAULT_BOUNDING_BOX_MIN, DEFAULT_BOUNDING_BOX_MAX)
-    {
-    }
+extern const char* NAVIGATION_CATEGORY;
 
 
-    NavArea::~NavArea()
-    {
-    }
-    
-    void NavArea::RegisterObject(Context* context)
-    {
-        context->RegisterFactory<NavArea>(NAVIGATION_CATEGORY);
+NavArea::NavArea(Context* context) :
+    Component(context),
+    areaID_(DEFAULT_AREA_ID),
+    boundingBox_(DEFAULT_BOUNDING_BOX_MIN, DEFAULT_BOUNDING_BOX_MAX)
+{
+}
 
 
-        COPY_BASE_ATTRIBUTES(Component);
-        ATTRIBUTE("Bounding Box Min", Vector3, boundingBox_.min_, DEFAULT_BOUNDING_BOX_MIN, AM_DEFAULT);
-        ATTRIBUTE("Bounding Box Max", Vector3, boundingBox_.max_, DEFAULT_BOUNDING_BOX_MAX, AM_DEFAULT);
-        ACCESSOR_ATTRIBUTE("Area ID", GetAreaID, SetAreaID, unsigned, DEFAULT_AREA_ID, AM_DEFAULT);
-    }
+NavArea::~NavArea()
+{
+}
 
 
-    void NavArea::SetAreaID(unsigned newID)
-    {
-        if (newID > MAX_NAV_AREA_ID)
-            LOGERRORF("NavArea Area ID %u exceeds maximum value of %u", newID, MAX_NAV_AREA_ID);
-        areaID_ = (unsigned char)newID;
-        MarkNetworkUpdate();
-    }
+void NavArea::RegisterObject(Context* context)
+{
+    context->RegisterFactory<NavArea>(NAVIGATION_CATEGORY);
 
 
-    BoundingBox NavArea::GetWorldBoundingBox() const
+    COPY_BASE_ATTRIBUTES(Component);
+    ATTRIBUTE("Bounding Box Min", Vector3, boundingBox_.min_, DEFAULT_BOUNDING_BOX_MIN, AM_DEFAULT);
+    ATTRIBUTE("Bounding Box Max", Vector3, boundingBox_.max_, DEFAULT_BOUNDING_BOX_MAX, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Area ID", GetAreaID, SetAreaID, unsigned, DEFAULT_AREA_ID, AM_DEFAULT);
+}
+
+void NavArea::SetAreaID(unsigned newID)
+{
+    if (newID > MAX_NAV_AREA_ID)
+        LOGERRORF("NavArea Area ID %u exceeds maximum value of %u", newID, MAX_NAV_AREA_ID);
+    areaID_ = (unsigned char)newID;
+    MarkNetworkUpdate();
+}
+
+BoundingBox NavArea::GetWorldBoundingBox() const
+{
+    Matrix3x4 mat;
+    mat.SetTranslation(node_->GetWorldPosition());
+    return boundingBox_.Transformed(mat);
+}
+
+void NavArea::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
+{
+    if (debug && IsEnabledEffective())
     {
     {
         Matrix3x4 mat;
         Matrix3x4 mat;
         mat.SetTranslation(node_->GetWorldPosition());
         mat.SetTranslation(node_->GetWorldPosition());
-        return boundingBox_.Transformed(mat);
+        debug->AddBoundingBox(boundingBox_, mat, Color::GREEN, depthTest);
     }
     }
+}
 
 
-    void NavArea::DrawDebugGeometry(DebugRenderer* debug, bool depthTest) 
-    {
-        if (debug && IsEnabledEffective())
-        {
-            Matrix3x4 mat;
-            mat.SetTranslation(node_->GetWorldPosition());
-            debug->AddBoundingBox(boundingBox_, mat, Color::GREEN, depthTest);
-        }
-    }
 }
 }

+ 33 - 31
Source/Urho3D/Navigation/NavArea.h

@@ -22,45 +22,47 @@
 
 
 #pragma once
 #pragma once
 
 
-#include "../Scene/Component.h"
 #include "../Math/BoundingBox.h"
 #include "../Math/BoundingBox.h"
+#include "../Scene/Component.h"
 
 
 namespace Urho3D
 namespace Urho3D
 {
 {
-    class URHO3D_API NavArea : public Component
-    {
-        OBJECT(NavArea);
 
 
-    public:
-        /// Construct.
-        NavArea(Context*);
-        /// Destruct.
-        virtual ~NavArea();
-        /// Register object factory and attributes.
-        static void RegisterObject(Context*);
+class URHO3D_API NavArea : public Component
+{
+    OBJECT(NavArea);
+
+public:
+    /// Construct.
+    NavArea(Context*);
+    /// Destruct.
+    virtual ~NavArea();
+    /// Register object factory and attributes.
+    static void RegisterObject(Context*);
+
+    /// Render debug geometry for the bounds.
+    virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
+
+    /// Get the area id for this volume.
+    unsigned GetAreaID() const { return (unsigned)areaID_; }
+
+    /// Set the area id for this volume.
+    void SetAreaID(unsigned newID);
 
 
-        /// Render debug geometry for the bounds.
-        virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
+    /// Get the bounding box of this navigation area, in local space.
+    BoundingBox GetBoundingBox() const { return boundingBox_; }
 
 
-        /// Get the area id for this volume.
-        unsigned GetAreaID() const { return (unsigned)areaID_; }
-        /// Set the area id for this volume.
-        void SetAreaID(unsigned newID);
+    /// Set the bounding box of this area, in local space.
+    void SetBoundingBox(const BoundingBox& bnds) { boundingBox_ = bnds; }
 
 
-        /// Get the bounding box of this navigation area, in local space.
-        BoundingBox GetBoundingBox() const { return boundingBox_; }
-        /// Set the bounding box of this area, in local space.
-        void SetBoundingBox(const BoundingBox& bnds) { boundingBox_ = bnds; }
+    /// Get the bounds of this navigation area in world space.
+    BoundingBox GetWorldBoundingBox() const;
 
 
-        /// Get the bounds of this navigation area in world space.
-        BoundingBox GetWorldBoundingBox() const;
+private:
+    /// Bounds of area to mark.
+    BoundingBox boundingBox_;
+    /// Area id to assign to the marked area.
+    unsigned char areaID_;
+};
 
 
-    private:
-        /// Bounds of area to mark.
-        BoundingBox boundingBox_;
-        /// Flags to assign to the marked area of the navigation map.
-        unsigned flags_;
-        /// Area id to assign to the marked area.
-        unsigned char areaID_;
-    };
 }
 }

+ 0 - 4
Source/Urho3D/Navigation/NavBuildData.cpp

@@ -24,10 +24,6 @@
 
 
 #include "../Navigation/NavBuildData.h"
 #include "../Navigation/NavBuildData.h"
 
 
-#include <Detour/DetourNavMesh.h>
-#include <Detour/DetourNavMeshBuilder.h>
-#include <Detour/DetourNavMeshQuery.h>
-#include <DetourTileCache/DetourTileCache.h>
 #include <DetourTileCache/DetourTileCacheBuilder.h>
 #include <DetourTileCache/DetourTileCacheBuilder.h>
 #include <Recast/Recast.h>
 #include <Recast/Recast.h>
 
 

+ 1 - 0
Source/Urho3D/Navigation/Navigable.h

@@ -42,6 +42,7 @@ public:
 
 
     /// Set whether geometry is automatically collected from child nodes. Default true.
     /// Set whether geometry is automatically collected from child nodes. Default true.
     void SetRecursive(bool enable);
     void SetRecursive(bool enable);
+
     /// Return whether geometry is automatically collected from child nodes.
     /// Return whether geometry is automatically collected from child nodes.
     bool IsRecursive() const { return recursive_; }
     bool IsRecursive() const { return recursive_; }
 
 

+ 54 - 44
Source/Urho3D/Navigation/NavigationMesh.cpp

@@ -22,17 +22,18 @@
 
 
 #include "../Precompiled.h"
 #include "../Precompiled.h"
 
 
-#ifdef URHO3D_PHYSICS
-#include "../Physics/CollisionShape.h"
-#endif
 #include "../Core/Context.h"
 #include "../Core/Context.h"
+#include "../Core/Profiler.h"
 #include "../Graphics/DebugRenderer.h"
 #include "../Graphics/DebugRenderer.h"
 #include "../Graphics/Drawable.h"
 #include "../Graphics/Drawable.h"
-#include "../Navigation/DynamicNavigationMesh.h"
 #include "../Graphics/Geometry.h"
 #include "../Graphics/Geometry.h"
+#include "../Graphics/Model.h"
+#include "../Graphics/StaticModel.h"
+#include "../Graphics/TerrainPatch.h"
 #include "../IO/Log.h"
 #include "../IO/Log.h"
 #include "../IO/MemoryBuffer.h"
 #include "../IO/MemoryBuffer.h"
-#include "../Graphics/Model.h"
+#include "../Navigation/CrowdAgent.h"
+#include "../Navigation/DynamicNavigationMesh.h"
 #include "../Navigation/NavArea.h"
 #include "../Navigation/NavArea.h"
 #include "../Navigation/NavBuildData.h"
 #include "../Navigation/NavBuildData.h"
 #include "../Navigation/Navigable.h"
 #include "../Navigation/Navigable.h"
@@ -40,11 +41,10 @@
 #include "../Navigation/NavigationMesh.h"
 #include "../Navigation/NavigationMesh.h"
 #include "../Navigation/Obstacle.h"
 #include "../Navigation/Obstacle.h"
 #include "../Navigation/OffMeshConnection.h"
 #include "../Navigation/OffMeshConnection.h"
-#include "../Core/Profiler.h"
+#ifdef URHO3D_PHYSICS
+#include "../Physics/CollisionShape.h"
+#endif
 #include "../Scene/Scene.h"
 #include "../Scene/Scene.h"
-#include "../Graphics/StaticModel.h"
-#include "../Graphics/TerrainPatch.h"
-#include "../IO/VectorBuffer.h"
 
 
 #include <cfloat>
 #include <cfloat>
 #include <Detour/DetourNavMesh.h>
 #include <Detour/DetourNavMesh.h>
@@ -52,9 +52,6 @@
 #include <Detour/DetourNavMeshQuery.h>
 #include <Detour/DetourNavMeshQuery.h>
 #include <Recast/Recast.h>
 #include <Recast/Recast.h>
 
 
-#include "../Navigation/CrowdAgent.h"
-#include "../Navigation/CrowdManager.h"
-
 #include "../DebugNew.h"
 #include "../DebugNew.h"
 
 
 namespace Urho3D
 namespace Urho3D
@@ -156,11 +153,15 @@ void NavigationMesh::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE("Region Merge Size", GetRegionMergeSize, SetRegionMergeSize, float, DEFAULT_REGION_MERGE_SIZE, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Region Merge Size", GetRegionMergeSize, SetRegionMergeSize, float, DEFAULT_REGION_MERGE_SIZE, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Edge Max Length", GetEdgeMaxLength, SetEdgeMaxLength, float, DEFAULT_EDGE_MAX_LENGTH, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Edge Max Length", GetEdgeMaxLength, SetEdgeMaxLength, float, DEFAULT_EDGE_MAX_LENGTH, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Edge Max Error", GetEdgeMaxError, SetEdgeMaxError, float, DEFAULT_EDGE_MAX_ERROR, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Edge Max Error", GetEdgeMaxError, SetEdgeMaxError, float, DEFAULT_EDGE_MAX_ERROR, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE("Detail Sample Distance", GetDetailSampleDistance, SetDetailSampleDistance, float, DEFAULT_DETAIL_SAMPLE_DISTANCE, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE("Detail Sample Max Error", GetDetailSampleMaxError, SetDetailSampleMaxError, float, DEFAULT_DETAIL_SAMPLE_MAX_ERROR, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Detail Sample Distance", GetDetailSampleDistance, SetDetailSampleDistance, float,
+        DEFAULT_DETAIL_SAMPLE_DISTANCE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Detail Sample Max Error", GetDetailSampleMaxError, SetDetailSampleMaxError, float,
+        DEFAULT_DETAIL_SAMPLE_MAX_ERROR, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Bounding Box Padding", GetPadding, SetPadding, Vector3, Vector3::ONE, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Bounding Box Padding", GetPadding, SetPadding, Vector3, Vector3::ONE, AM_DEFAULT);
-    MIXED_ACCESSOR_ATTRIBUTE("Navigation Data", GetNavigationDataAttr, SetNavigationDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE | AM_NOEDIT);
-    ENUM_ACCESSOR_ATTRIBUTE("Partition Type", GetPartitionType, SetPartitionType, NavmeshPartitionType, navmeshPartitionTypeNames, NAVMESH_PARTITION_WATERSHED, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Navigation Data", GetNavigationDataAttr, SetNavigationDataAttr, PODVector<unsigned char>,
+        Variant::emptyBuffer, AM_FILE | AM_NOEDIT);
+    ENUM_ACCESSOR_ATTRIBUTE("Partition Type", GetPartitionType, SetPartitionType, NavmeshPartitionType, navmeshPartitionTypeNames,
+        NAVMESH_PARTITION_WATERSHED, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Draw OffMeshConnections", GetDrawOffMeshConnections, SetDrawOffMeshConnections, bool, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Draw OffMeshConnections", GetDrawOffMeshConnections, SetDrawOffMeshConnections, bool, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Draw NavAreas", GetDrawNavAreas, SetDrawNavAreas, bool, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Draw NavAreas", GetDrawNavAreas, SetDrawNavAreas, bool, false, AM_DEFAULT);
 }
 }
@@ -194,7 +195,7 @@ void NavigationMesh::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
                             worldTransform * *reinterpret_cast<const Vector3*>(&tile->verts[poly->verts[(j + 1) % poly->vertCount] * 3]),
                             worldTransform * *reinterpret_cast<const Vector3*>(&tile->verts[poly->verts[(j + 1) % poly->vertCount] * 3]),
                             Color::YELLOW,
                             Color::YELLOW,
                             depthTest
                             depthTest
-                            );
+                        );
                     }
                     }
                 }
                 }
             }
             }
@@ -373,7 +374,7 @@ bool NavigationMesh::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(numTilesX_ * numTilesZ_);
+        unsigned maxTiles = NextPowerOfTwo((unsigned)(numTilesX_ * numTilesZ_));
         unsigned tileBits = 0;
         unsigned tileBits = 0;
         unsigned temp = maxTiles;
         unsigned temp = maxTiles;
         while (temp > 1)
         while (temp > 1)
@@ -382,7 +383,7 @@ bool NavigationMesh::Build()
             ++tileBits;
             ++tileBits;
         }
         }
 
 
-        unsigned maxPolys = 1 << (22 - tileBits);
+        unsigned maxPolys = (unsigned)(1 << (22 - tileBits));
 
 
         dtNavMeshParams params;
         dtNavMeshParams params;
         rcVcopy(params.orig, &boundingBox_.min_.x_);
         rcVcopy(params.orig, &boundingBox_.min_.x_);
@@ -475,9 +476,10 @@ bool NavigationMesh::Build(const BoundingBox& boundingBox)
     return true;
     return true;
 }
 }
 
 
-Vector3 NavigationMesh::FindNearestPoint(const Vector3& point, const Vector3& extents, const dtQueryFilter* filter, dtPolyRef* nearestRef)
+Vector3 NavigationMesh::FindNearestPoint(const Vector3& point, const Vector3& extents, const dtQueryFilter* filter,
+    dtPolyRef* nearestRef)
 {
 {
-    if(!InitializeQuery())
+    if (!InitializeQuery())
         return point;
         return point;
 
 
     const Matrix3x4& transform = node_->GetWorldTransform();
     const Matrix3x4& transform = node_->GetWorldTransform();
@@ -493,7 +495,8 @@ Vector3 NavigationMesh::FindNearestPoint(const Vector3& point, const Vector3& ex
     return *nearestRef ? transform * nearestPoint : point;
     return *nearestRef ? transform * nearestPoint : point;
 }
 }
 
 
-Vector3 NavigationMesh::MoveAlongSurface(const Vector3& start, const Vector3& end, const Vector3& extents, int maxVisited, const dtQueryFilter* filter)
+Vector3 NavigationMesh::MoveAlongSurface(const Vector3& start, const Vector3& end, const Vector3& extents, int maxVisited,
+    const dtQueryFilter* filter)
 {
 {
     if (!InitializeQuery())
     if (!InitializeQuery())
         return end;
         return end;
@@ -513,13 +516,14 @@ Vector3 NavigationMesh::MoveAlongSurface(const Vector3& start, const Vector3& en
     Vector3 resultPos;
     Vector3 resultPos;
     int visitedCount = 0;
     int visitedCount = 0;
     maxVisited = Max(maxVisited, 0);
     maxVisited = Max(maxVisited, 0);
-    PODVector<dtPolyRef> visited(maxVisited);
+    PODVector<dtPolyRef> visited((unsigned)maxVisited);
     navMeshQuery_->moveAlongSurface(startRef, &localStart.x_, &localEnd.x_, queryFilter, &resultPos.x_, maxVisited ?
     navMeshQuery_->moveAlongSurface(startRef, &localStart.x_, &localEnd.x_, queryFilter, &resultPos.x_, maxVisited ?
         &visited[0] : (dtPolyRef*)0, &visitedCount, maxVisited);
         &visited[0] : (dtPolyRef*)0, &visitedCount, maxVisited);
     return transform * resultPos;
     return transform * resultPos;
 }
 }
 
 
-void NavigationMesh::FindPath(PODVector<Vector3>& dest, const Vector3& start, const Vector3& end, const Vector3& extents, const dtQueryFilter* filter)
+void NavigationMesh::FindPath(PODVector<Vector3>& dest, const Vector3& start, const Vector3& end, const Vector3& extents,
+    const dtQueryFilter* filter)
 {
 {
     PROFILE(FindPath);
     PROFILE(FindPath);
 
 
@@ -579,7 +583,8 @@ Vector3 NavigationMesh::GetRandomPoint(const dtQueryFilter* filter, dtPolyRef* r
     return node_->GetWorldTransform() * point;
     return node_->GetWorldTransform() * point;
 }
 }
 
 
-Vector3 NavigationMesh::GetRandomPointInCircle(const Vector3& center, float radius, const Vector3& extents, const dtQueryFilter* filter, dtPolyRef* randomRef)
+Vector3 NavigationMesh::GetRandomPointInCircle(const Vector3& center, float radius, const Vector3& extents,
+    const dtQueryFilter* filter, dtPolyRef* randomRef)
 {
 {
     if (randomRef)
     if (randomRef)
         *randomRef = 0;
         *randomRef = 0;
@@ -607,7 +612,8 @@ Vector3 NavigationMesh::GetRandomPointInCircle(const Vector3& center, float radi
     return transform * point;
     return transform * point;
 }
 }
 
 
-float NavigationMesh::GetDistanceToWall(const Vector3& point, float radius, const Vector3& extents, const dtQueryFilter* filter, Vector3* hitPos, Vector3* hitNormal)
+float NavigationMesh::GetDistanceToWall(const Vector3& point, float radius, const Vector3& extents, const dtQueryFilter* filter,
+    Vector3* hitPos, Vector3* hitNormal)
 {
 {
     if (hitPos)
     if (hitPos)
         *hitPos = Vector3::ZERO;
         *hitPos = Vector3::ZERO;
@@ -639,7 +645,8 @@ float NavigationMesh::GetDistanceToWall(const Vector3& point, float radius, cons
     return hitDist;
     return hitDist;
 }
 }
 
 
-Vector3 NavigationMesh::Raycast(const Vector3& start, const Vector3& end, const Vector3& extents, const dtQueryFilter* filter, Vector3* hitNormal)
+Vector3 NavigationMesh::Raycast(const Vector3& start, const Vector3& end, const Vector3& extents, const dtQueryFilter* filter,
+    Vector3* hitNormal)
 {
 {
     if (hitNormal)
     if (hitNormal)
         *hitNormal = Vector3::DOWN;
         *hitNormal = Vector3::DOWN;
@@ -665,7 +672,8 @@ Vector3 NavigationMesh::Raycast(const Vector3& start, const Vector3& end, const
     float t;
     float t;
     int numPolys;
     int numPolys;
 
 
-    navMeshQuery_->raycast(startRef, &localStart.x_, &localEnd.x_, queryFilter, &t, &hitNormal->x_, pathData_->polys_, &numPolys, MAX_POLYS);
+    navMeshQuery_->raycast(startRef, &localStart.x_, &localEnd.x_, queryFilter, &t, &hitNormal->x_, pathData_->polys_, &numPolys,
+        MAX_POLYS);
     if (t == FLT_MAX)
     if (t == FLT_MAX)
         t = 1.0f;
         t = 1.0f;
 
 
@@ -794,8 +802,8 @@ PODVector<unsigned char> NavigationMesh::GetNavigationDataAttr() const
                 ret.WriteInt(x);
                 ret.WriteInt(x);
                 ret.WriteInt(z);
                 ret.WriteInt(z);
                 ret.WriteUInt(navMesh->getTileRef(tile));
                 ret.WriteUInt(navMesh->getTileRef(tile));
-                ret.WriteUInt(tile->dataSize);
-                ret.Write(tile->data, tile->dataSize);
+                ret.WriteUInt((unsigned)tile->dataSize);
+                ret.Write(tile->data, (unsigned)tile->dataSize);
             }
             }
         }
         }
     }
     }
@@ -856,7 +864,8 @@ void NavigationMesh::CollectGeometries(Vector<NavigationGeometryInfo>& geometryL
     }
     }
 }
 }
 
 
-void NavigationMesh::CollectGeometries(Vector<NavigationGeometryInfo>& geometryList, Node* node, HashSet<Node*>& processedNodes, bool recursive)
+void NavigationMesh::CollectGeometries(Vector<NavigationGeometryInfo>& geometryList, Node* node, HashSet<Node*>& processedNodes,
+    bool recursive)
 {
 {
     // Make sure nodes are not included twice
     // Make sure nodes are not included twice
     if (processedNodes.Contains(node))
     if (processedNodes.Contains(node))
@@ -928,7 +937,7 @@ void NavigationMesh::CollectGeometries(Vector<NavigationGeometryInfo>& geometryL
     if (recursive)
     if (recursive)
     {
     {
         const Vector<SharedPtr<Node> >& children = node->GetChildren();
         const Vector<SharedPtr<Node> >& children = node->GetChildren();
-        for(unsigned i = 0; i < children.Size(); ++i)
+        for (unsigned i = 0; i < children.Size(); ++i)
             CollectGeometries(geometryList, children[i], processedNodes, recursive);
             CollectGeometries(geometryList, children[i], processedNodes, recursive);
     }
     }
 }
 }
@@ -952,9 +961,9 @@ void NavigationMesh::GetTileGeometry(NavBuildData* build, Vector<NavigationGeome
                 build->offMeshVertices_.Push(start);
                 build->offMeshVertices_.Push(start);
                 build->offMeshVertices_.Push(end);
                 build->offMeshVertices_.Push(end);
                 build->offMeshRadii_.Push(connection->GetRadius());
                 build->offMeshRadii_.Push(connection->GetRadius());
-                build->offMeshFlags_.Push(connection->GetMask());
+                build->offMeshFlags_.Push((unsigned short)connection->GetMask());
                 build->offMeshAreas_.Push((unsigned char)connection->GetAreaID());
                 build->offMeshAreas_.Push((unsigned char)connection->GetAreaID());
-                build->offMeshDir_.Push(connection->IsBidirectional() ? DT_OFFMESH_CON_BIDIR : 0);
+                build->offMeshDir_.Push((unsigned char)(connection->IsBidirectional() ? DT_OFFMESH_CON_BIDIR : 0));
                 continue;
                 continue;
             }
             }
             else if (geometryList[i].component_->GetType() == NavArea::GetTypeStatic())
             else if (geometryList[i].component_->GetType() == NavArea::GetTypeStatic())
@@ -1111,15 +1120,15 @@ bool NavigationMesh::BuildTile(Vector<NavigationGeometryInfo>& geometryList, int
     float tileEdgeLength = (float)tileSize_ * cellSize_;
     float tileEdgeLength = (float)tileSize_ * cellSize_;
 
 
     BoundingBox tileBoundingBox(Vector3(
     BoundingBox tileBoundingBox(Vector3(
-        boundingBox_.min_.x_ + tileEdgeLength * (float)x,
-        boundingBox_.min_.y_,
-        boundingBox_.min_.z_ + tileEdgeLength * (float)z
-    ),
-    Vector3(
-        boundingBox_.min_.x_ + tileEdgeLength * (float)(x + 1),
-        boundingBox_.max_.y_,
-        boundingBox_.min_.z_ + tileEdgeLength * (float)(z + 1)
-    ));
+            boundingBox_.min_.x_ + tileEdgeLength * (float)x,
+            boundingBox_.min_.y_,
+            boundingBox_.min_.z_ + tileEdgeLength * (float)z
+        ),
+        Vector3(
+            boundingBox_.min_.x_ + tileEdgeLength * (float)(x + 1),
+            boundingBox_.max_.y_,
+            boundingBox_.min_.z_ + tileEdgeLength * (float)(z + 1)
+        ));
 
 
     SimpleNavBuildData build;
     SimpleNavBuildData build;
 
 
@@ -1203,7 +1212,8 @@ bool NavigationMesh::BuildTile(Vector<NavigationGeometryInfo>& geometryList, int
 
 
     // Mark area volumes
     // Mark area volumes
     for (unsigned i = 0; i < build.navAreas_.Size(); ++i)
     for (unsigned i = 0; i < build.navAreas_.Size(); ++i)
-        rcMarkBoxArea(build.ctx_, &build.navAreas_[i].bounds_.min_.x_, &build.navAreas_[i].bounds_.max_.x_, build.navAreas_[i].areaID_, *build.compactHeightField_);
+        rcMarkBoxArea(build.ctx_, &build.navAreas_[i].bounds_.min_.x_, &build.navAreas_[i].bounds_.max_.x_,
+            build.navAreas_[i].areaID_, *build.compactHeightField_);
 
 
     if (this->partitionType_ == NAVMESH_PARTITION_WATERSHED)
     if (this->partitionType_ == NAVMESH_PARTITION_WATERSHED)
     {
     {

+ 42 - 11
Source/Urho3D/Navigation/NavigationMesh.h

@@ -23,10 +23,10 @@
 #pragma once
 #pragma once
 
 
 #include "../Container/ArrayPtr.h"
 #include "../Container/ArrayPtr.h"
-#include "../Math/BoundingBox.h"
-#include "../Scene/Component.h"
 #include "../Container/HashSet.h"
 #include "../Container/HashSet.h"
+#include "../Math/BoundingBox.h"
 #include "../Math/Matrix3x4.h"
 #include "../Math/Matrix3x4.h"
+#include "../Scene/Component.h"
 
 
 #ifdef DT_POLYREF64
 #ifdef DT_POLYREF64
 typedef uint64_t dtPolyRef;
 typedef uint64_t dtPolyRef;
@@ -118,67 +118,97 @@ public:
     /// Rebuild part of the navigation mesh contained by the world-space bounding box. Return true if successful.
     /// Rebuild part of the navigation mesh contained by the world-space bounding box. Return true if successful.
     virtual bool Build(const BoundingBox& boundingBox);
     virtual bool Build(const BoundingBox& boundingBox);
     /// Find the nearest point on the navigation mesh to a given point. Extents specifies how far out from the specified point to check along each axis.
     /// Find the nearest point on the navigation mesh to a given point. Extents specifies how far out from the specified point to check along each axis.
-    Vector3 FindNearestPoint(const Vector3& point, const Vector3& extents = Vector3::ONE, const dtQueryFilter* filter = 0, dtPolyRef* nearestRef = 0);
+    Vector3 FindNearestPoint
+        (const Vector3& point, const Vector3& extents = Vector3::ONE, const dtQueryFilter* filter = 0, dtPolyRef* nearestRef = 0);
     /// Try to move along the surface from one point to another.
     /// Try to move along the surface from one point to another.
-    Vector3 MoveAlongSurface(const Vector3& start, const Vector3& end, const Vector3& extents = Vector3::ONE, int maxVisited = 3, const dtQueryFilter* filter = 0);
+    Vector3 MoveAlongSurface(const Vector3& start, const Vector3& end, const Vector3& extents = Vector3::ONE, int maxVisited = 3,
+        const dtQueryFilter* filter = 0);
     /// Find a path between world space points. Return non-empty list of points if successful. Extents specifies how far off the navigation mesh the points can be.
     /// Find a path between world space points. Return non-empty list of points if successful. Extents specifies how far off the navigation mesh the points can be.
-    void FindPath(PODVector<Vector3>& dest, const Vector3& start, const Vector3& end, const Vector3& extents = Vector3::ONE, const dtQueryFilter* filter = 0);
+    void FindPath(PODVector<Vector3>& dest, const Vector3& start, const Vector3& end, const Vector3& extents = Vector3::ONE,
+        const dtQueryFilter* filter = 0);
     /// Return a random point on the navigation mesh.
     /// Return a random point on the navigation mesh.
     Vector3 GetRandomPoint(const dtQueryFilter* filter = 0, dtPolyRef* randomRef = 0);
     Vector3 GetRandomPoint(const dtQueryFilter* filter = 0, dtPolyRef* randomRef = 0);
     /// Return a random point on the navigation mesh within a circle. The circle radius is only a guideline and in practice the returned point may be further away.
     /// Return a random point on the navigation mesh within a circle. The circle radius is only a guideline and in practice the returned point may be further away.
-    Vector3 GetRandomPointInCircle(const Vector3& center, float radius, const Vector3& extents = Vector3::ONE, const dtQueryFilter* filter = 0, dtPolyRef* randomRef = 0);
+    Vector3 GetRandomPointInCircle
+        (const Vector3& center, float radius, const Vector3& extents = Vector3::ONE, const dtQueryFilter* filter = 0,
+            dtPolyRef* randomRef = 0);
     /// Return distance to wall from a point. Maximum search radius must be specified.
     /// Return distance to wall from a point. Maximum search radius must be specified.
-    float GetDistanceToWall(const Vector3& point, float radius, const Vector3& extents = Vector3::ONE, const dtQueryFilter* filter = 0, Vector3* hitPos = 0, Vector3* hitNormal = 0);
+    float GetDistanceToWall
+        (const Vector3& point, float radius, const Vector3& extents = Vector3::ONE, const dtQueryFilter* filter = 0,
+            Vector3* hitPos = 0, Vector3* hitNormal = 0);
     /// Perform a walkability raycast on the navigation mesh between start and end and return the point where a wall was hit, or the end point if no walls.
     /// Perform a walkability raycast on the navigation mesh between start and end and return the point where a wall was hit, or the end point if no walls.
-    Vector3 Raycast(const Vector3& start, const Vector3& end, const Vector3& extents = Vector3::ONE, const dtQueryFilter* filter = 0, Vector3* hitNormal = 0);
+    Vector3 Raycast
+        (const Vector3& start, const Vector3& end, const Vector3& extents = Vector3::ONE, const dtQueryFilter* filter = 0,
+            Vector3* hitNormal = 0);
     /// Add debug geometry to the debug renderer.
     /// Add debug geometry to the debug renderer.
     void DrawDebugGeometry(bool depthTest);
     void DrawDebugGeometry(bool depthTest);
 
 
     /// Return the given name of this navigation mesh.
     /// Return the given name of this navigation mesh.
     String GetMeshName() const { return meshName_; }
     String GetMeshName() const { return meshName_; }
+
     /// Set the name of this navigation mesh.
     /// Set the name of this navigation mesh.
     void SetMeshName(const String& newName);
     void SetMeshName(const String& newName);
+
     /// Return tile size.
     /// Return tile size.
     int GetTileSize() const { return tileSize_; }
     int GetTileSize() const { return tileSize_; }
+
     /// Return cell size.
     /// Return cell size.
     float GetCellSize() const { return cellSize_; }
     float GetCellSize() const { return cellSize_; }
+
     /// Return cell height.
     /// Return cell height.
     float GetCellHeight() const { return cellHeight_; }
     float GetCellHeight() const { return cellHeight_; }
+
     /// Return navigation agent height.
     /// Return navigation agent height.
     float GetAgentHeight() const { return agentHeight_; }
     float GetAgentHeight() const { return agentHeight_; }
+
     /// Return navigation agent radius.
     /// Return navigation agent radius.
     float GetAgentRadius() const { return agentRadius_; }
     float GetAgentRadius() const { return agentRadius_; }
+
     /// Return navigation agent max vertical climb.
     /// Return navigation agent max vertical climb.
     float GetAgentMaxClimb() const { return agentMaxClimb_; }
     float GetAgentMaxClimb() const { return agentMaxClimb_; }
+
     /// Return navigation agent max slope.
     /// Return navigation agent max slope.
     float GetAgentMaxSlope() const { return agentMaxSlope_; }
     float GetAgentMaxSlope() const { return agentMaxSlope_; }
+
     /// Return region minimum size.
     /// Return region minimum size.
     float GetRegionMinSize() const { return regionMinSize_; }
     float GetRegionMinSize() const { return regionMinSize_; }
+
     /// Return region merge size.
     /// Return region merge size.
     float GetRegionMergeSize() const { return regionMergeSize_; }
     float GetRegionMergeSize() const { return regionMergeSize_; }
+
     /// Return edge max length.
     /// Return edge max length.
     float GetEdgeMaxLength() const { return edgeMaxLength_; }
     float GetEdgeMaxLength() const { return edgeMaxLength_; }
+
     /// Return edge max error.
     /// Return edge max error.
     float GetEdgeMaxError() const { return edgeMaxError_; }
     float GetEdgeMaxError() const { return edgeMaxError_; }
+
     /// Return detail sampling distance.
     /// Return detail sampling distance.
     float GetDetailSampleDistance() const { return detailSampleDistance_; }
     float GetDetailSampleDistance() const { return detailSampleDistance_; }
+
     /// Return detail sampling maximum error.
     /// Return detail sampling maximum error.
     float GetDetailSampleMaxError() const { return detailSampleMaxError_; }
     float GetDetailSampleMaxError() const { return detailSampleMaxError_; }
+
     /// Return navigation mesh bounding box padding.
     /// Return navigation mesh bounding box padding.
     const Vector3& GetPadding() const { return padding_; }
     const Vector3& GetPadding() const { return padding_; }
+
     /// Get the current cost of an area
     /// Get the current cost of an area
     float GetAreaCost(unsigned areaID) const;
     float GetAreaCost(unsigned areaID) const;
+
     /// Return whether has been initialized with valid navigation data.
     /// Return whether has been initialized with valid navigation data.
     bool IsInitialized() const { return navMesh_ != 0; }
     bool IsInitialized() const { return navMesh_ != 0; }
+
     /// Return local space bounding box of the navigation mesh.
     /// Return local space bounding box of the navigation mesh.
     const BoundingBox& GetBoundingBox() const { return boundingBox_; }
     const BoundingBox& GetBoundingBox() const { return boundingBox_; }
+
     /// Return world space bounding box of the navigation mesh.
     /// Return world space bounding box of the navigation mesh.
     BoundingBox GetWorldBoundingBox() const;
     BoundingBox GetWorldBoundingBox() const;
+
     /// Return number of tiles.
     /// Return number of tiles.
     IntVector2 GetNumTiles() const { return IntVector2(numTilesX_, numTilesZ_); }
     IntVector2 GetNumTiles() const { return IntVector2(numTilesX_, numTilesZ_); }
 
 
     /// Set the partition type used for polygon generation.
     /// Set the partition type used for polygon generation.
     void SetPartitionType(NavmeshPartitionType aType);
     void SetPartitionType(NavmeshPartitionType aType);
+
     /// Return Partition Type.
     /// Return Partition Type.
     NavmeshPartitionType GetPartitionType() const { return partitionType_; }
     NavmeshPartitionType GetPartitionType() const { return partitionType_; }
 
 
@@ -189,11 +219,13 @@ public:
 
 
     /// Draw debug geometry for OffMeshConnection components.
     /// Draw debug geometry for OffMeshConnection components.
     void SetDrawOffMeshConnections(bool enable) { drawOffMeshConnections_ = enable; }
     void SetDrawOffMeshConnections(bool enable) { drawOffMeshConnections_ = enable; }
+
     /// Return whether to draw OffMeshConnection components.
     /// Return whether to draw OffMeshConnection components.
     bool GetDrawOffMeshConnections() const { return drawOffMeshConnections_; }
     bool GetDrawOffMeshConnections() const { return drawOffMeshConnections_; }
 
 
     /// Draw debug geometry for NavArea components.
     /// Draw debug geometry for NavArea components.
     void SetDrawNavAreas(bool enable) { drawNavAreas_ = enable; }
     void SetDrawNavAreas(bool enable) { drawNavAreas_ = enable; }
+
     /// Return whether to draw NavArea components.
     /// Return whether to draw NavArea components.
     bool GetDrawNavAreas() const { return drawNavAreas_; }
     bool GetDrawNavAreas() const { return drawNavAreas_; }
 
 
@@ -201,7 +233,8 @@ protected:
     /// Collect geometry from under Navigable components.
     /// Collect geometry from under Navigable components.
     void CollectGeometries(Vector<NavigationGeometryInfo>& geometryList);
     void CollectGeometries(Vector<NavigationGeometryInfo>& geometryList);
     /// Visit nodes and collect navigable geometry.
     /// Visit nodes and collect navigable geometry.
-    void CollectGeometries(Vector<NavigationGeometryInfo>& geometryList, Node* node, HashSet<Node*>& processedNodes, bool recursive);
+    void
+        CollectGeometries(Vector<NavigationGeometryInfo>& geometryList, Node* node, HashSet<Node*>& processedNodes, bool recursive);
     /// Get geometry data within a bounding box.
     /// Get geometry data within a bounding box.
     void GetTileGeometry(NavBuildData* build, Vector<NavigationGeometryInfo>& geometryList, BoundingBox& box);
     void GetTileGeometry(NavBuildData* build, Vector<NavigationGeometryInfo>& geometryList, BoundingBox& box);
     /// Add a triangle mesh to the geometry data.
     /// Add a triangle mesh to the geometry data.
@@ -262,8 +295,6 @@ protected:
     NavmeshPartitionType partitionType_;
     NavmeshPartitionType partitionType_;
     /// Keep internal build resources for debug draw modes.
     /// Keep internal build resources for debug draw modes.
     bool keepInterResults_;
     bool keepInterResults_;
-    /// Internal build resources for creating the navmesh.
-    HashMap<Pair<int, int>, NavBuildData*> builds_;
 
 
     /// Debug draw OffMeshConnection components.
     /// Debug draw OffMeshConnection components.
     bool drawOffMeshConnections_;
     bool drawOffMeshConnections_;

+ 2 - 3
Source/Urho3D/Navigation/Obstacle.cpp

@@ -22,12 +22,11 @@
 
 
 #include "../Precompiled.h"
 #include "../Precompiled.h"
 
 
-#include "../Navigation/Obstacle.h"
-
 #include "../Core/Context.h"
 #include "../Core/Context.h"
 #include "../Graphics/DebugRenderer.h"
 #include "../Graphics/DebugRenderer.h"
-#include "../Navigation/DynamicNavigationMesh.h"
 #include "../IO/Log.h"
 #include "../IO/Log.h"
+#include "../Navigation/DynamicNavigationMesh.h"
+#include "../Navigation/Obstacle.h"
 #include "../Navigation/NavigationEvents.h"
 #include "../Navigation/NavigationEvents.h"
 #include "../Scene/Scene.h"
 #include "../Scene/Scene.h"
 
 

+ 4 - 0
Source/Urho3D/Navigation/Obstacle.h

@@ -34,6 +34,7 @@ class DynamicNavigationMesh;
 class URHO3D_API Obstacle : public Component
 class URHO3D_API Obstacle : public Component
 {
 {
     OBJECT(Obstacle)
     OBJECT(Obstacle)
+
     friend class DynamicNavigationMesh;
     friend class DynamicNavigationMesh;
 
 
 public:
 public:
@@ -50,10 +51,13 @@ public:
 
 
     /// Get the height of this obstacle.
     /// Get the height of this obstacle.
     float GetHeight() const { return height_; }
     float GetHeight() const { return height_; }
+
     /// Set the height of this obstacle.
     /// Set the height of this obstacle.
     void SetHeight(float);
     void SetHeight(float);
+
     /// Get the blocking radius of this obstacle.
     /// Get the blocking radius of this obstacle.
     float GetRadius() const { return radius_; }
     float GetRadius() const { return radius_; }
+
     /// Set the blocking radius of this obstacle.
     /// Set the blocking radius of this obstacle.
     void SetRadius(float);
     void SetRadius(float);
 
 

+ 4 - 0
Source/Urho3D/Navigation/OffMeshConnection.h

@@ -60,12 +60,16 @@ public:
 
 
     /// Return endpoint node.
     /// Return endpoint node.
     Node* GetEndPoint() const;
     Node* GetEndPoint() const;
+
     /// Return radius.
     /// Return radius.
     float GetRadius() const { return radius_; }
     float GetRadius() const { return radius_; }
+
     /// Return whether is bidirectional.
     /// Return whether is bidirectional.
     bool IsBidirectional() const { return bidirectional_; }
     bool IsBidirectional() const { return bidirectional_; }
+
     /// Return the user assigned mask
     /// Return the user assigned mask
     unsigned GetMask() const { return mask_; }
     unsigned GetMask() const { return mask_; }
+
     /// Return the user assigned area ID
     /// Return the user assigned area ID
     unsigned GetAreaID() const { return areaId_; }
     unsigned GetAreaID() const { return areaId_; }