2
0
Эх сурвалжийг харах

Fix slowed down navigation crowd agent when node dirtied in E_CROWD_AGENT_NODE_REPOSITION. Send the event only after position has been updated. Check for only rotation changing when node dirtied, and do not update position / reset state in that case. Closes #1548.

Lasse Öörni 9 жил өмнө
parent
commit
8bef941082

+ 1 - 1
Source/Samples/39_CrowdNavigation/CrowdNavigation.cpp

@@ -539,7 +539,7 @@ void CrowdNavigation::HandleCrowdAgentReposition(StringHash eventType, VariantMa
         else
             animCtrl->Play(WALKING_ANI, 0, true, 0.1f);
 
-        // If speed is too low then stopping the animation
+        // If speed is too low then stop the animation
         if (speed < agent->GetRadius())
             animCtrl->Stop(WALKING_ANI, 0.8f);
     }

+ 18 - 11
Source/Urho3D/Navigation/CrowdAgent.cpp

@@ -519,6 +519,13 @@ void CrowdAgent::OnCrowdUpdate(dtCrowdAgent* ag, float dt)
         {
             previousPosition_ = newPos;
 
+            if (updateNodePosition_)
+            {
+                ignoreTransformChanges_ = true;
+                node_->SetPosition(newPos);
+                ignoreTransformChanges_ = false;
+            }
+
             using namespace CrowdAgentReposition;
 
             VariantMap& map = GetEventDataMap();
@@ -530,13 +537,6 @@ void CrowdAgent::OnCrowdUpdate(dtCrowdAgent* ag, float dt)
             map[P_TIMESTEP] = dt;
             crowdManager_->SendEvent(E_CROWD_AGENT_REPOSITION, map);
             node_->SendEvent(E_CROWD_AGENT_NODE_REPOSITION, map);
-
-            if (updateNodePosition_)
-            {
-                ignoreTransformChanges_ = true;
-                node_->SetPosition(newPos);
-                ignoreTransformChanges_ = false;
-            }
         }
 
         // Send a notification event if we've reached the destination
@@ -603,11 +603,18 @@ void CrowdAgent::OnMarkedDirty(Node* node)
         dtCrowdAgent* agent = const_cast<dtCrowdAgent*>(GetDetourCrowdAgent());
         if (agent)
         {
-            memcpy(agent->npos, node->GetWorldPosition().Data(), sizeof(float) * 3);
+            Vector3& agentPos = reinterpret_cast<Vector3&>(agent->npos);
+            Vector3 nodeWorldPos = node->GetWorldPosition();
+            
+            // Only reset position / state if actually changed
+            if (nodeWorldPos != agentPos)
+            {
+                agentPos = nodeWorldPos;
 
-            // If the node has been externally altered, provide the opportunity for DetourCrowd to reevaluate the crowd agent
-            if (agent->state == CA_STATE_INVALID)
-                agent->state = CA_STATE_WALKING;
+                // If the node has been externally altered, provide the opportunity for DetourCrowd to reevaluate the crowd agent
+                if (agent->state == CA_STATE_INVALID)
+                    agent->state = CA_STATE_WALKING;
+            }
         }
     }
 }

+ 1 - 1
bin/Data/LuaScripts/39_CrowdNavigation.lua

@@ -438,7 +438,7 @@ function HandleCrowdAgentReposition(eventType, eventData)
             animCtrl:Play(WALKING_ANI, 0, true, 0.1)
         end
 
-        -- If speed is too low then stopping the animation
+        -- If speed is too low then stop the animation
         if speed < agent.radius then
             animCtrl:Stop(WALKING_ANI, 0.8)
         end

+ 1 - 1
bin/Data/Scripts/39_CrowdNavigation.as

@@ -490,7 +490,7 @@ void HandleCrowdAgentReposition(StringHash eventType, VariantMap& eventData)
         else
             animCtrl.Play(WALKING_ANI, 0, true, 0.1f);
 
-        // If speed is too low then stopping the animation
+        // If speed is too low then stop the animation
         if (speed < agent.radius)
             animCtrl.Stop(WALKING_ANI, 0.8f);
     }