Skip to content

Commit

Permalink
Add FixedOnce mode to PhysicsTimestep
Browse files Browse the repository at this point in the history
  • Loading branch information
NiseVoid committed Jul 8, 2023
1 parent 0f6e289 commit 2ac5864
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 17 deletions.
44 changes: 27 additions & 17 deletions src/plugins/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,26 +188,36 @@ fn run_physics_schedule(world: &mut World) {
let time_step = *world.resource::<PhysicsTimestep>();

// Update `DeltaTime` according to the `PhysicsTimestep` configuration
let dt = match time_step {
PhysicsTimestep::Fixed(fixed_delta_seconds) => fixed_delta_seconds,
PhysicsTimestep::Variable { max_dt } => delta_seconds.min(max_dt),
let (dt, accumulate) = match time_step {
PhysicsTimestep::Fixed(fixed_delta_seconds) => (fixed_delta_seconds, true),
PhysicsTimestep::FixedOnce(fixed_delta_seconds) => (fixed_delta_seconds, false),
PhysicsTimestep::Variable { max_dt } => (delta_seconds.min(max_dt), true),
};
world.resource_mut::<DeltaTime>().0 = dt;

// Add time to the accumulator
if physics_loop.paused {
physics_loop.accumulator += dt * physics_loop.queued_steps as Scalar;
physics_loop.queued_steps = 0;
} else {
physics_loop.accumulator += delta_seconds;
}

// Step the simulation until the accumulator has been consumed.
// Note that a small remainder may be passed on to the next run of the physics schedule.
while physics_loop.accumulator >= dt && dt > 0.0 {
debug!("running PhysicsSchedule");
world.run_schedule(PhysicsSchedule);
physics_loop.accumulator -= dt;
match accumulate {
false if physics_loop.paused => {}
false => {
debug!("running PhysicsSchedule");
world.run_schedule(PhysicsSchedule);
}
true => {
// Add time to the accumulator
if physics_loop.paused {
physics_loop.accumulator += dt * physics_loop.queued_steps as Scalar;
physics_loop.queued_steps = 0;
} else {
physics_loop.accumulator += delta_seconds;
}

// Step the simulation until the accumulator has been consumed.
// Note that a small remainder may be passed on to the next run of the physics schedule.
while physics_loop.accumulator >= dt && dt > 0.0 {
debug!("running PhysicsSchedule");
world.run_schedule(PhysicsSchedule);
physics_loop.accumulator -= dt;
}
}
}

world.insert_resource(physics_loop);
Expand Down
2 changes: 2 additions & 0 deletions src/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ use crate::prelude::*;
pub enum PhysicsTimestep {
/// **Fixed timestep**: the physics simulation will be advanced by a fixed value `dt` for every `dt` seconds passed since the previous physics frame. This allows consistent behavior across different machines and framerates.
Fixed(Scalar),
/// **Fixed delta, once per frame**: the physics simulation will be advanced by a fixed value `dt` once every frame. This should only be used in cases where you can guarantee a fixed number of executions, like in FixedUpdate or on a server.
FixedOnce(Scalar),
/// **Variable timestep**: the physics simulation will be advanced by `Time::delta_seconds().min(max_dt)` seconds at each Bevy tick.
Variable {
/// The maximum amount of time the physics simulation can be advanced at each Bevy tick. This makes sure that the simulation doesn't break when the delta time is large.
Expand Down

0 comments on commit 2ac5864

Please sign in to comment.