@@ -62,8 +62,9 @@ class ScenarioSimulationMotionSystem final : public engine::EngineSystem {
6262
6363 auto & query = world.query ();
6464 const auto entities = simulationEntities (query);
65+ refreshActiveEntities (query, entities);
6566 std::vector<MovementPlan> plans;
66- plans.reserve (entities .size ());
67+ plans.reserve (activeEntities_ .size ());
6768 if (!resources.contains <ScenarioEnvironmentReactionResource>()) {
6869 resources.set (ScenarioEnvironmentReactionResource{});
6970 }
@@ -76,15 +77,15 @@ class ScenarioSimulationMotionSystem final : public engine::EngineSystem {
7677 : nullptr ;
7778
7879 applyRouteGuidance (query, entities, layoutCache, clock.elapsedSeconds , step.derivedSeed );
79- advanceRoutesForCurrentZones (query, entities , layoutCache);
80- replanBlockedExitRoutes (query, entities , layoutCache, clock.elapsedSeconds , layoutRevision, reactions);
81- advanceRoutesForWaypointProgress (query, 0.0 , entities , layoutCache);
82- replanBlockedRouteSegments (query, entities , layoutCache, clock.elapsedSeconds , layoutRevision);
83- replanHazardAwareExitRoutes (query, entities , layoutCache, clock.elapsedSeconds , reactions, activeHazards);
84- updateAgentPhysicsFloorIds (query, layoutCache, entities );
80+ advanceRoutesForCurrentZones (query, activeEntities_ , layoutCache);
81+ replanBlockedExitRoutes (query, activeEntities_ , layoutCache, clock.elapsedSeconds , layoutRevision, reactions);
82+ advanceRoutesForWaypointProgress (query, 0.0 , activeEntities_ , layoutCache);
83+ replanBlockedRouteSegments (query, activeEntities_ , layoutCache, clock.elapsedSeconds , layoutRevision);
84+ replanHazardAwareExitRoutes (query, activeEntities_ , layoutCache, clock.elapsedSeconds , reactions, activeHazards);
85+ updateAgentPhysicsFloorIds (query, layoutCache, activeEntities_ );
8586 std::optional<AgentSpatialIndex> localNeighborIndex;
8687 if (sharedSpatialIndex == nullptr ) {
87- localNeighborIndex = buildAgentSpatialIndex (query, entities , 1.0 );
88+ localNeighborIndex = buildAgentSpatialIndex (query, activeEntities_ , 1.0 );
8889 }
8990 const auto * pressureFeedback = resources.contains <ScenarioPressureFeedbackResource>()
9091 ? &resources.get <ScenarioPressureFeedbackResource>()
@@ -100,15 +101,11 @@ class ScenarioSimulationMotionSystem final : public engine::EngineSystem {
100101
101102 std::size_t evacuatedAtStartCount = 0 ;
102103 std::size_t newlyEvacuatedCount = 0 ;
103- for (const auto entity : entities ) {
104+ for (const auto entity : activeEntities_ ) {
104105 auto & position = query.get <Position>(entity);
105106 auto & velocity = query.get <Velocity>(entity);
106107 auto & route = query.get <EvacuationRoute>(entity);
107108 auto & status = query.get <EvacuationStatus>(entity);
108- if (status.evacuated ) {
109- ++evacuatedAtStartCount;
110- continue ;
111- }
112109 if (route.destinationZoneId .empty ()) {
113110 continue ;
114111 }
@@ -124,7 +121,11 @@ class ScenarioSimulationMotionSystem final : public engine::EngineSystem {
124121 }
125122 }
126123
124+ evacuatedAtStartCount = totalAgentCount - activeEntities_.size ();
127125 const auto evacuatedAfterCount = evacuatedAtStartCount + newlyEvacuatedCount;
126+ if (newlyEvacuatedCount > 0 ) {
127+ refreshActiveEntities (query, entities);
128+ }
128129 const bool shouldCaptureT90 = t90TargetCount > 0
129130 && !timingKeyframes.t90Frame .has_value ()
130131 && evacuatedAtStartCount < t90TargetCount
@@ -140,13 +141,8 @@ class ScenarioSimulationMotionSystem final : public engine::EngineSystem {
140141 keyframe.evacuatedAgentCount = evacuatedAfterCount;
141142 keyframe.complete = totalAgentCount > 0 && evacuatedAfterCount >= totalAgentCount;
142143
143- const auto view = query.view <Position, Agent, Velocity, EvacuationStatus>();
144- keyframe.agents .reserve (view.size ());
145- for (const auto entity : view) {
146- const auto & status = query.get <EvacuationStatus>(entity);
147- if (status.evacuated ) {
148- continue ;
149- }
144+ keyframe.agents .reserve (activeEntities_.size ());
145+ for (const auto entity : activeEntities_) {
150146 const auto & position = query.get <Position>(entity);
151147 const auto & velocity = query.get <Velocity>(entity);
152148 const auto & agent = query.get <Agent>(entity);
@@ -183,15 +179,11 @@ class ScenarioSimulationMotionSystem final : public engine::EngineSystem {
183179 }
184180 }
185181
186- for (const auto entity : entities ) {
182+ for (const auto entity : activeEntities_ ) {
187183 auto & position = query.get <Position>(entity);
188184 const auto & agent = query.get <Agent>(entity);
189185 auto & velocity = query.get <Velocity>(entity);
190186 auto & route = query.get <EvacuationRoute>(entity);
191- auto & status = query.get <EvacuationStatus>(entity);
192- if (status.evacuated ) {
193- continue ;
194- }
195187
196188 if (route.nextWaypointIndex >= route.waypoints .size ()) {
197189 velocity.value = {};
@@ -330,13 +322,13 @@ class ScenarioSimulationMotionSystem final : public engine::EngineSystem {
330322 updateDisplayFloor (route, nextPosition);
331323 }
332324
333- advanceVerticalRoutesAtPortal (query, entities , layoutCache);
334- updateAgentPhysicsFloorIds (query, layoutCache, entities );
335- resolveAgentOverlaps (query, entities , layoutCache);
336- advanceRoutesForCurrentZones (query, entities , layoutCache);
337- advanceRoutesForWaypointProgress (query, clampedDelta, entities , layoutCache);
338- updateAgentPhysicsFloorIds (query, layoutCache, entities );
339- resolveAgentOverlaps (query, entities , layoutCache);
325+ advanceVerticalRoutesAtPortal (query, activeEntities_ , layoutCache);
326+ updateAgentPhysicsFloorIds (query, layoutCache, activeEntities_ );
327+ resolveAgentOverlaps (query, activeEntities_ , layoutCache);
328+ advanceRoutesForCurrentZones (query, activeEntities_ , layoutCache);
329+ advanceRoutesForWaypointProgress (query, clampedDelta, activeEntities_ , layoutCache);
330+ updateAgentPhysicsFloorIds (query, layoutCache, activeEntities_ );
331+ resolveAgentOverlaps (query, activeEntities_ , layoutCache);
340332 advanceClock (query, clock, entities, clampedDelta);
341333 resources.set (ScenarioSimulationStepResource{});
342334 }
@@ -364,6 +356,16 @@ class ScenarioSimulationMotionSystem final : public engine::EngineSystem {
364356 bool advanced{false };
365357 };
366358
359+ void refreshActiveEntities (engine::WorldQuery& query, const std::vector<engine::Entity>& entities) {
360+ activeEntities_.clear ();
361+ activeEntities_.reserve (entities.size ());
362+ for (const auto entity : entities) {
363+ if (!query.get <EvacuationStatus>(entity).evacuated ) {
364+ activeEntities_.push_back (entity);
365+ }
366+ }
367+ }
368+
367369 static const ScenarioEnvironmentReactionAgentState* activeHazardState (
368370 const ScenarioEnvironmentReactionResource* reactions,
369371 std::uint64_t agentId) {
@@ -2171,6 +2173,7 @@ class ScenarioSimulationMotionSystem final : public engine::EngineSystem {
21712173 std::optional<RouteGuidanceDraft> guidanceReplanGuidance_{};
21722174 std::uint64_t guidanceReplanSeed_{0U };
21732175 std::uint64_t guidanceReplanIdHash_{0U };
2176+ std::vector<engine::Entity> activeEntities_{};
21742177};
21752178
21762179
0 commit comments