diff --git a/source/main/gfx/DustPool.cpp b/source/main/gfx/DustPool.cpp index 146e51c1d2..8664a25bf2 100644 --- a/source/main/gfx/DustPool.cpp +++ b/source/main/gfx/DustPool.cpp @@ -24,6 +24,7 @@ #include "Application.h" #include "GameContext.h" +#include "GfxScene.h" #include "Terrain.h" #include "Water.h" @@ -193,8 +194,15 @@ void DustPool::allocRipple(Vector3 pos, Vector3 vel) void DustPool::update() { + float speed_factor = 0.f; + if (App::sim_state->getEnum() == SimState::RUNNING && !App::GetGameContext()->GetActorManager()->IsSimulationPaused()) + { + speed_factor = App::GetGfxScene()->GetSimDataBuffer().simbuf_sim_speed; + } + for (int i = 0; i < allocated; i++) { + pss[i]->setSpeedFactor(speed_factor); ParticleEmitter* emit = pss[i]->getEmitter(0); Vector3 ndir = velocities[i]; Real vel = ndir.length(); diff --git a/source/main/gfx/DustPool.h b/source/main/gfx/DustPool.h index 956e54889c..9ddc6d836b 100644 --- a/source/main/gfx/DustPool.h +++ b/source/main/gfx/DustPool.h @@ -80,7 +80,7 @@ class DustPool Ogre::SceneNode* sns[MAX_DUSTS]; Ogre::SceneNode* parent_snode; Ogre::Vector3 positions[MAX_DUSTS]; - Ogre::Vector3 velocities[MAX_DUSTS]; + Ogre::Vector3 velocities[MAX_DUSTS]; //!< Velocity in wall time, ignoring the time scale. float rates[MAX_DUSTS]; int allocated; int size; diff --git a/source/main/gfx/GfxScene.cpp b/source/main/gfx/GfxScene.cpp index e9f62e2d51..93bad10de8 100644 --- a/source/main/gfx/GfxScene.cpp +++ b/source/main/gfx/GfxScene.cpp @@ -89,6 +89,9 @@ void GfxScene::Init() void GfxScene::UpdateScene(float dt) { + // NOTE: The `dt` parameter here is simulation time (0 when paused), not real time! + // ================================================================================ + // Actors - start threaded tasks for (GfxActor* gfx_actor: m_live_gfx_actors) { @@ -114,13 +117,14 @@ void GfxScene::UpdateScene(float dt) // Particles if (App::gfx_particles_mode->getInt() == 1) { + // Generate particles as needed for (GfxActor* gfx_actor: m_all_gfx_actors) { - if (!m_simbuf.simbuf_sim_paused && !gfx_actor->GetSimDataBuffer().simbuf_physics_paused) - { - gfx_actor->UpdateParticles(m_simbuf.simbuf_sim_speed * dt); - } + float dt_actor = (!gfx_actor->GetSimDataBuffer().simbuf_physics_paused) ? dt : 0.f; + gfx_actor->UpdateParticles(dt_actor); } + + // Update particle movement for (auto itor : m_dustpools) { itor.second->update(); @@ -197,7 +201,7 @@ void GfxScene::UpdateScene(float dt) // HUD - network labels (always update) for (GfxActor* gfx_actor: m_all_gfx_actors) { - gfx_actor->UpdateNetLabels(m_simbuf.simbuf_sim_speed * dt); + gfx_actor->UpdateNetLabels(dt); } // Player avatars @@ -209,6 +213,7 @@ void GfxScene::UpdateScene(float dt) // Actors - update misc visuals for (GfxActor* gfx_actor: m_all_gfx_actors) { + float dt_actor = (!gfx_actor->GetSimDataBuffer().simbuf_physics_paused) ? dt : 0.f; if (gfx_actor->IsActorLive()) { gfx_actor->UpdateRods(); @@ -217,17 +222,18 @@ void GfxScene::UpdateScene(float dt) gfx_actor->UpdateAirbrakes(); gfx_actor->UpdateCParticles(); gfx_actor->UpdateAeroEngines(); - gfx_actor->UpdatePropAnimations(dt); + gfx_actor->UpdatePropAnimations(dt_actor); gfx_actor->UpdateRenderdashRTT(); } // Beacon flares must always be updated - gfx_actor->UpdateProps(dt, (gfx_actor == player_gfx_actor)); + gfx_actor->UpdateProps(dt_actor, (gfx_actor == player_gfx_actor)); // Blinkers (turn signals) must always be updated - gfx_actor->UpdateFlares(dt, (gfx_actor == player_gfx_actor)); + gfx_actor->UpdateFlares(dt_actor, (gfx_actor == player_gfx_actor)); } if (player_gfx_actor != nullptr) { - player_gfx_actor->UpdateVideoCameras(dt); + float dt_actor = (!player_gfx_actor->GetSimDataBuffer().simbuf_physics_paused) ? dt : 0.f; + player_gfx_actor->UpdateVideoCameras(dt_actor); // The old-style render-to-texture dashboard (based on OGRE overlays) if (m_simbuf.simbuf_player_actor->ar_driveable == TRUCK && m_simbuf.simbuf_player_actor->ar_engine != nullptr) diff --git a/source/main/main.cpp b/source/main/main.cpp index 383b38748b..62d3ca8ca2 100644 --- a/source/main/main.cpp +++ b/source/main/main.cpp @@ -1676,6 +1676,13 @@ int main(int argc, char *argv[]) App::GetGfxScene()->BufferSimulationData(); } + // Calculate elapsed simulation time (taking simulation speed and pause into account) + float dt_sim = 0.f; + if (App::sim_state->getEnum() == SimState::RUNNING && !App::GetGameContext()->GetActorManager()->IsSimulationPaused()) + { + dt_sim = dt * App::GetGameContext()->GetActorManager()->GetSimulationSpeed(); + } + // Advance simulation if (App::sim_state->getEnum() == SimState::RUNNING) { @@ -1689,7 +1696,7 @@ int main(int argc, char *argv[]) } else if (App::app_state->getEnum() == AppState::SIMULATION) { - App::GetGfxScene()->UpdateScene(dt); // Draws GUI as well + App::GetGfxScene()->UpdateScene(dt_sim); // Draws GUI as well } // Render!