From a04efbf968fda09243b7ecf3a461519bf61571a9 Mon Sep 17 00:00:00 2001 From: Hirek193 Date: Fri, 23 Oct 2026 18:20:49 +0200 Subject: [PATCH] perf(physics): vehicles standing still and held by their brakes let their physics sleep (physics.sleepheld) --- McZapkie/MOVER.h | 4 ++++ McZapkie/Mover.cpp | 19 ++++++++++++++++--- application/driveruipanels.cpp | 2 ++ utilities/Globals.cpp | 7 +++++++ utilities/Globals.h | 1 + utilities/Timer.h | 2 +- vehicle/DynObj.cpp | 4 ++-- 7 files changed, 33 insertions(+), 6 deletions(-) diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index ccd0935b..5c2c0532 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -2325,6 +2325,10 @@ class TMoverParameters double GetTrainsetVoltage(int const Coupling = coupling::heating | coupling::highvoltage) const; double GetTrainsetHighVoltage() const; bool switch_physics(bool const State); + // whether the vehicle accelerates, for the test which turns the physics off in vehicles standing still (ComputeTotalForce()). + // standing still, its acceleration is the pull of the slope and of the couplers, as the brakes and the resistance count only + // against a speed (FTotal); with Global.physics_sleepheld one held by them, the way ComputeMovement() keeps it standing, doesn't + bool accelerating() const; double LocalBrakeRatio(void) const; double ManualBrakeRatio(void) const; double PipeRatio(void) const; /*ile napelniac*/ diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 69d20723..fed027ed 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -4958,13 +4958,13 @@ void TMoverParameters::ComputeTotalForce(double dt) // McZapkie-031103: sprawdzanie czy warto liczyc fizyke i inne updaty // ABu 300105: cos tu mieszalem , dziala teraz troche lepiej, wiec zostawiam { - auto const vehicleisactive{CabActive != 0 || Vel > 0.0001 || std::abs(AccS) > 0.0001 || LastSwitchingTime < 5 || TrainType == dt_EZT || TrainType == dt_DMU}; + auto const vehicleisactive{CabActive != 0 || Vel > 0.0001 || accelerating() || LastSwitchingTime < 5 || TrainType == dt_EZT || TrainType == dt_DMU}; auto const movingvehicleahead{Neighbours[end::front].vehicle != nullptr && - (Neighbours[end::front].vehicle->MoverParameters->Vel > 0.0001 || std::abs(Neighbours[end::front].vehicle->MoverParameters->AccS) > 0.0001)}; + (Neighbours[end::front].vehicle->MoverParameters->Vel > 0.0001 || Neighbours[end::front].vehicle->MoverParameters->accelerating())}; auto const movingvehiclebehind{Neighbours[end::rear].vehicle != nullptr && - (Neighbours[end::rear].vehicle->MoverParameters->Vel > 0.0001 || std::abs(Neighbours[end::rear].vehicle->MoverParameters->AccS) > 0.0001)}; + (Neighbours[end::rear].vehicle->MoverParameters->Vel > 0.0001 || Neighbours[end::rear].vehicle->MoverParameters->accelerating())}; auto const calculatephysics{vehicleisactive || movingvehicleahead || movingvehiclebehind}; @@ -8918,6 +8918,19 @@ double TMoverParameters::GetTrainsetHighVoltage() const return std::max(GetTrainsetVoltage(coupling::highvoltage), HeatingAllow ? GetTrainsetVoltage(coupling::heating) : 0.0); } +// ************************************************************************************************* +// whether the vehicle accelerates, for the test which turns the physics off in vehicles standing still +// ************************************************************************************************* +bool TMoverParameters::accelerating() const +{ + if (std::abs(AccS) <= 0.0001) + return false; + // standing still and held by the brakes and the resistance, against the slope and the couplers: the test ComputeMovement() + // sets the speed to zero by. the forces are of the last ComputeTotalForce(), the ones the movement went by + auto const held{Global.physics_sleepheld && Vel <= 0.0001 && std::abs(FStand) > std::abs(FTrain)}; + return false == held; +} + // ************************************************************************************************* // Kasowanie zmiennych pracy fizyki // ************************************************************************************************* diff --git a/application/driveruipanels.cpp b/application/driveruipanels.cpp index 8525ffcf..c7215a23 100644 --- a/application/driveruipanels.cpp +++ b/application/driveruipanels.cpp @@ -1513,6 +1513,8 @@ debug_panel::render_section_renderer() { } ImGui::PopTextWrapPos(); ImGui::PopStyleColor(); + // the physics of the vehicles, timed in the section of the main loop + ImGui::Checkbox( "let vehicles standing still and held by their brakes sleep (physics.sleepheld)", &Global.physics_sleepheld ); return true; } diff --git a/utilities/Globals.cpp b/utilities/Globals.cpp index 792e3d7a..3557a8c2 100644 --- a/utilities/Globals.cpp +++ b/utilities/Globals.cpp @@ -479,6 +479,12 @@ bool global_settings::ConfigParseSimulation(cParser& Parser, const std::string& return true; } + if (token == "physics.sleepheld") + { + ParseOne(Parser, physics_sleepheld); + return true; + } + if (token == "enabletraction") { ParseOne(Parser, bEnableTraction); @@ -1887,6 +1893,7 @@ global_settings::export_as_text( std::ostream &Output ) const { export_as_text( Output, "sound.asyncload", AudioAsyncLoad ); export_as_text( Output, "physicslog", WriteLogFlag ); export_as_text( Output, "fullphysics", FullPhysics ); + export_as_text( Output, "physics.sleepheld", physics_sleepheld ); export_as_text( Output, "debuglog", iWriteLogEnabled ); export_as_text( Output, "multiplelogs", MultipleLogs ); export_as_text( Output, "showsystemconsole", ShowSystemConsole ); diff --git a/utilities/Globals.h b/utilities/Globals.h index 07c165f8..38a73dd3 100644 --- a/utilities/Globals.h +++ b/utilities/Globals.h @@ -114,6 +114,7 @@ struct global_settings { std::string Weather{ "cloudy:" }; // current weather std::string Period{}; // time of the day, based on sun position bool FullPhysics{ true }; // full calculations performed for each simulation step + bool physics_sleepheld{ true }; // vehicles standing still and held by their brakes let their physics sleep, see TMoverParameters::accelerating() bool bnewAirCouplers{ true }; float fMoveLight{ 0.f }; // numer dnia w roku albo -1 bool FakeLight{ false }; // toggle between fixed and dynamic daylight diff --git a/utilities/Timer.h b/utilities/Timer.h index 9612d519..505f414b 100644 --- a/utilities/Timer.h +++ b/utilities/Timer.h @@ -132,7 +132,7 @@ struct subsystem_stopwatches { unsigned int vehicles { 0 }; unsigned int cab { 0 }; // CabActive unsigned int speed { 0 }; // Vel above 0.0001 km/h - unsigned int acceleration { 0 }; // AccS above 0.0001 m/s2 + unsigned int acceleration { 0 }; // AccS above 0.0001 m/s2, and not held by the brakes (TMoverParameters::accelerating()) unsigned int switching { 0 }; // LastSwitchingTime below 5 s unsigned int multipleunit { 0 }; // EZT, DMU unsigned int neighbour { 0 }; // a neighbour moving or accelerating diff --git a/vehicle/DynObj.cpp b/vehicle/DynObj.cpp index d04334d4..541668e9 100644 --- a/vehicle/DynObj.cpp +++ b/vehicle/DynObj.cpp @@ -8635,12 +8635,12 @@ vehicle_table::update( double Deltatime, int Iterationcount ) { // the test of TMoverParameters::ComputeTotalForce(), part by part auto const moving = []( neighbour_data const &Neighbour ) { return ( Neighbour.vehicle != nullptr ) - && ( ( Neighbour.vehicle->MoverParameters->Vel > 0.0001 ) || ( std::abs( Neighbour.vehicle->MoverParameters->AccS ) > 0.0001 ) ); }; + && ( ( Neighbour.vehicle->MoverParameters->Vel > 0.0001 ) || Neighbour.vehicle->MoverParameters->accelerating() ); }; auto &awake { counts.awake }; ++awake.vehicles; if( mover->CabActive != 0 ) { ++awake.cab; } if( mover->Vel > 0.0001 ) { ++awake.speed; } - if( std::abs( mover->AccS ) > 0.0001 ) { ++awake.acceleration; } + if( mover->accelerating() ) { ++awake.acceleration; } if( mover->LastSwitchingTime < 5 ) { ++awake.switching; } if( ( mover->TrainType == dt_EZT ) || ( mover->TrainType == dt_DMU ) ) { ++awake.multipleunit; } if( moving( mover->Neighbours[ end::front ] ) || moving( mover->Neighbours[ end::rear ] ) ) { ++awake.neighbour; }