Skip to content

Commit

Permalink
Fixed GFX running on wall time instead of sim. time
Browse files Browse the repository at this point in the history
I noticed beacons run when game is paused and also ignore simulation speed, always running at wall time. I remembered there are multiple other issues like this (props/water waves moving when paused) and I figured a way to tackle everything at once - I changed the time input for the entire scene update code (which is already consolidated into `GfxScene::UpdateScene()`) - instead of inputting wall time, I now input the adjusted simulation time, and I input zero if the game is paused or physics are globally paused.

The particles had a custom code to correctly calc. sim. time and skip the update entirely when paused. I reverted all that, expecting the adjusted time input to fix particles, but that didn't work. I already researched this at RigsOfRods#3138 and figured to use `Ogre::ParticleSystem::setSpeedFactor()` - that did the trick.
  • Loading branch information
ohlidalp committed Jul 30, 2024
1 parent 8550874 commit 9843b20
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 11 deletions.
8 changes: 8 additions & 0 deletions source/main/gfx/DustPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "Application.h"
#include "GameContext.h"
#include "GfxScene.h"
#include "Terrain.h"
#include "Water.h"

Expand Down Expand Up @@ -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>() == 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();
Expand Down
2 changes: 1 addition & 1 deletion source/main/gfx/DustPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
24 changes: 15 additions & 9 deletions source/main/gfx/GfxScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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();
Expand Down Expand Up @@ -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
Expand All @@ -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();
Expand All @@ -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)
Expand Down
9 changes: 8 additions & 1 deletion source/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>() == SimState::RUNNING && !App::GetGameContext()->GetActorManager()->IsSimulationPaused())
{
dt_sim = dt * App::GetGameContext()->GetActorManager()->GetSimulationSpeed();
}

// Advance simulation
if (App::sim_state->getEnum<SimState>() == SimState::RUNNING)
{
Expand All @@ -1689,7 +1696,7 @@ int main(int argc, char *argv[])
}
else if (App::app_state->getEnum<AppState>() == AppState::SIMULATION)
{
App::GetGfxScene()->UpdateScene(dt); // Draws GUI as well
App::GetGfxScene()->UpdateScene(dt_sim); // Draws GUI as well
}

// Render!
Expand Down

0 comments on commit 9843b20

Please sign in to comment.