diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 6e770e732e..2d186933c3 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -90,6 +90,8 @@ set(CUBOS_ENGINE_SOURCE "src/screen_picker/plugin.cpp" "src/screen_picker/screen_picker.cpp" + + "src/fixedstep/plugin.cpp" ) # Create cubos engine diff --git a/engine/include/cubos/engine/fixedstep/accumulated_time.hpp b/engine/include/cubos/engine/fixedstep/accumulated_time.hpp new file mode 100644 index 0000000000..2196ef609f --- /dev/null +++ b/engine/include/cubos/engine/fixedstep/accumulated_time.hpp @@ -0,0 +1,16 @@ +/// @file +/// @brief Resource @ref cubos::engine::AccumulatedTime. +/// @ingroup fixedstep-plugin + +#pragma once + +namespace cubos::engine +{ + /// @brief Resource which holds the time passed without running fixedStep systems, incremented every frame + /// by deltaTime and decremented once the systems run. + /// @ingroup fixedstep-plugin + struct AccumulatedTime + { + float value = 0.0F; + }; +} // namespace cubos::engine diff --git a/engine/include/cubos/engine/fixedstep/plugin.hpp b/engine/include/cubos/engine/fixedstep/plugin.hpp new file mode 100644 index 0000000000..db679d08b2 --- /dev/null +++ b/engine/include/cubos/engine/fixedstep/plugin.hpp @@ -0,0 +1,23 @@ +/// @dir +/// @brief @ref fixedstep-plugin plugin directory. + +/// @file +/// @brief Plugin entry point. +/// @ingroup fixedstep-plugin + +#pragma once + +#include + +namespace cubos::engine +{ + /// @defgroup fixedstep-plugin FixedStep + /// @ingroup engine + /// @brief Adds cubos.fixedStep tag which makes its systems run at a fixed framerate. + /// + + /// @brief Plugin entry function. + /// @param cubos @b CUBOS. main class + /// @ingroup fixedstep-plugin + void fixedStepPlugin(Cubos& cubos); +} // namespace cubos::engine \ No newline at end of file diff --git a/engine/src/fixedstep/plugin.cpp b/engine/src/fixedstep/plugin.cpp new file mode 100644 index 0000000000..e2d02f44a0 --- /dev/null +++ b/engine/src/fixedstep/plugin.cpp @@ -0,0 +1,26 @@ +#include +#include + + +using namespace cubos::engine; + +const float frametime = 1/60; + + + +void cubos::engine::fixedStepPlugin(Cubos& cubos) +{ + cubos.addResource(); + + cubos.system("accumulate time resource").call([](AccumulatedTime& timer, const DeltaTime& dt) { + timer.value += dt.value; + }); + + cubos.tag("cubos.fixedStep").repeatWhile([](AccumulatedTime& timer) { + if (timer.value >= frametime) { + timer.value -= frametime; + return true; + } + return false; + }); +} \ No newline at end of file diff --git a/engine/src/physics/plugin.cpp b/engine/src/physics/plugin.cpp index 3c6c95134d..c09edc4c2e 100644 --- a/engine/src/physics/plugin.cpp +++ b/engine/src/physics/plugin.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "physics_accumulator.hpp" @@ -61,10 +62,6 @@ CUBOS_REFLECT_IMPL(PhysicsBundle) .build(); } -static bool simulatePhysicsStep(PhysicsAccumulator& accumulator, const FixedDeltaTime& fixedDeltaTime) -{ - return accumulator.value >= fixedDeltaTime.value; -} void cubos::engine::physicsPlugin(Cubos& cubos) { @@ -84,6 +81,7 @@ void cubos::engine::physicsPlugin(Cubos& cubos) cubos.addPlugin(collisionsPlugin); cubos.addPlugin(gravityPlugin); cubos.addPlugin(solverPlugin); + cubos.addPlugin(fixedStepPlugin); // add components to entities created with PhysicsBundle cubos.system("unpack PhysicsBundle's") @@ -108,22 +106,16 @@ void cubos::engine::physicsPlugin(Cubos& cubos) } }); - // executed every frame - cubos.system("increase fixed-step accumulator") - .tagged("cubos.physics.simulation.prepare") - .call( - [](PhysicsAccumulator& accumulator, const DeltaTime& deltaTime) { accumulator.value += deltaTime.value; }); cubos.tag("cubos.physics.apply_forces") .after("cubos.physics.simulation.prepare") - .before("cubos.physics.simulation.substeps.integrate") - .runIf(simulatePhysicsStep); + .before("cubos.physics.simulation.substeps.integrate"); cubos.system("apply impulses") .tagged("cubos.physics.simulation.apply_impulses") .after("cubos.physics.apply_forces") .before("cubos.physics.simulation.substeps.integrate") - .onlyIf(simulatePhysicsStep) + .tagged("cubos.fixedStep") .call([](Query query) { for (auto [velocity, impulse, mass] : query) { @@ -134,7 +126,7 @@ void cubos::engine::physicsPlugin(Cubos& cubos) cubos.system("integrate position") .tagged("cubos.physics.simulation.substeps.integrate") .after("cubos.physics.simulation.prepare") - .onlyIf(simulatePhysicsStep) + .tagged("cubos.fixedStep") .call([](Query query, const Damping& damping, const FixedDeltaTime& fixedDeltaTime, const Substeps& substeps) { float subDeltaTime = fixedDeltaTime.value / (float)substeps.value; @@ -162,7 +154,7 @@ void cubos::engine::physicsPlugin(Cubos& cubos) cubos.system("apply corrections to positions") .tagged("cubos.physics.simulation.substeps.correct_position") .after("cubos.physics.simulation.substeps.integrate") - .onlyIf(simulatePhysicsStep) + .tagged("cubos.fixedStep") .call([](Query query) { for (auto [position, correction, mass] : query) { @@ -178,7 +170,7 @@ void cubos::engine::physicsPlugin(Cubos& cubos) cubos.system("update velocities") .tagged("cubos.physics.simulation.substeps.update_velocity") .after("cubos.physics.simulation.substeps.correct_position") - .onlyIf(simulatePhysicsStep) + .tagged("cubos.fixedStep") .call([](Query query, const FixedDeltaTime& fixedDeltaTime, const Substeps& substeps) { float subDeltaTime = fixedDeltaTime.value / (float)substeps.value; @@ -192,7 +184,7 @@ void cubos::engine::physicsPlugin(Cubos& cubos) cubos.system("clear forces") .tagged("cubos.physics.simulation.clear_forces") .after("cubos.physics.simulation.substeps.update_velocity") - .onlyIf(simulatePhysicsStep) + .tagged("cubos.fixedStep") .call([](Query query) { for (auto [force] : query) { @@ -203,7 +195,7 @@ void cubos::engine::physicsPlugin(Cubos& cubos) cubos.system("clear impulses") .tagged("cubos.physics.simulation.clear_forces") .after("cubos.physics.simulation.substeps.update_velocity") - .onlyIf(simulatePhysicsStep) + .tagged("cubos.fixedStep") .call([](Query query) { for (auto [impulse] : query) { @@ -214,7 +206,7 @@ void cubos::engine::physicsPlugin(Cubos& cubos) cubos.system("decrease fixed-step accumulator") .tagged("cubos.physics.simulation.decrease_accumulator") .after("cubos.physics.simulation.clear_forces") - .onlyIf(simulatePhysicsStep) + .tagged("cubos.fixedStep") .call([](PhysicsAccumulator& accumulator, const FixedDeltaTime& fixedDeltaTime) { accumulator.value -= fixedDeltaTime.value; });