Open
Conversation
9 tasks
ThierryBerger
commented
Dec 26, 2024
ThierryBerger
commented
Dec 26, 2024
1161a12 to
8effd48
Compare
ThierryBerger
commented
Dec 26, 2024
Comment on lines
83
to
134
| fn ease_translation_lerp( | ||
| mut query: Query<(&mut Transform, &TranslationEasingState)>, | ||
| time: Query<(&TaskToRenderTime, &Timestep)>, | ||
| ) { | ||
| let Ok((time, timestep)) = time.get_single() else { | ||
| return; | ||
| }; | ||
| let overstep = (time.diff.max(0.0) / timestep.timestep.as_secs_f64()).min(1.0) as f32; | ||
| query.iter_mut().for_each(|(mut transform, interpolation)| { | ||
| if let (Some(start), Some(end)) = (interpolation.start, interpolation.end) { | ||
| transform.translation = start.lerp(end, overstep); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| /// Eases the rotations of entities with spherical linear interpolation. | ||
| fn ease_rotation_slerp( | ||
| mut query: Query<(&mut Transform, &RotationEasingState)>, | ||
| time: Query<(&TaskToRenderTime, &Timestep)>, | ||
| ) { | ||
| let Ok((time, timestep)) = time.get_single() else { | ||
| return; | ||
| }; | ||
| let overstep = (time.diff.max(0.0) / timestep.timestep.as_secs_f64()).min(1.0) as f32; | ||
|
|
||
| query | ||
| .par_iter_mut() | ||
| .for_each(|(mut transform, interpolation)| { | ||
| if let (Some(start), Some(end)) = (interpolation.start, interpolation.end) { | ||
| // Note: `slerp` will always take the shortest path, but when the two rotations are more than | ||
| // 180 degrees apart, this can cause visual artifacts as the rotation "flips" to the other side. | ||
| transform.rotation = start.slerp(end, overstep); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| /// Eases the scales of entities with linear interpolation. | ||
| fn ease_scale_lerp( | ||
| mut query: Query<(&mut Transform, &ScaleEasingState)>, | ||
| time: Query<(&TaskToRenderTime, &Timestep)>, | ||
| ) { | ||
| let Ok((time, timestep)) = time.get_single() else { | ||
| return; | ||
| }; | ||
| let overstep = (time.diff.max(0.0) / timestep.timestep.as_secs_f64()).min(1.0) as f32; | ||
|
|
||
| query.iter_mut().for_each(|(mut transform, interpolation)| { | ||
| if let (Some(start), Some(end)) = (interpolation.start, interpolation.end) { | ||
| transform.scale = start.lerp(end, overstep); | ||
| } | ||
| }); | ||
| } |
Author
There was a problem hiding this comment.
Those systems could use a helper function to only retrieve the overstep(), the rest of the code is similar to the easing plugin.
Author
There was a problem hiding this comment.
This comment is still relevant, as it could be more practical to opt-out of Res<Time<Fixed>> time management. That said, it's a minor inconvenience.
1 task
ThierryBerger
added a commit
to ThierryBerger/bevy_fixed_update_task
that referenced
this pull request
Jan 7, 2025
ThierryBerger
commented
Jan 17, 2025
| /// | ||
| /// ``` | ||
| /// use bevy::{ecs::query::QueryData, prelude::*}; | ||
| /// use bevy::{ecs::query::QueryData, time::TimePlugin, prelude::*}; |
Author
There was a problem hiding this comment.
Those are slightly out of scope for this PR, but needed for bevy 0.15.1 due to #7.
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Objective
I published https://github.com/vrixyz/bevy_fixed_update_task ; This PR allows to tweak schedules used by the plugin.
See https://github.com/Vrixyz/bevy_fixed_update_task/blob/main/examples/interpolate_custom_schedule.rs for an example integration.
Changelog
FixedUpdate.ease_[translation|rotation|scale]_lerp, useful when your time management does not rely onRes<Time<Fixed>.Migration Guide
default()is supported.Previous description for historical context
Objective
bevy's
FixedUpdateruns synchronously whenTime<Virtual>exceedsTime<Fixed> + its accumulated time. This can lead to lag if the fixed update logic takes too long.When the FixedUpdate doesn't run every frame, we can take advantage of that by running it in parallel.
Solution
This PR is quite similar to how bevy's fixed update works, but eagerly extracts ECS data into a background task, to synchronize it only when we exceed
Time<Fixed> + its accumulated time.The implementation doesn't use
Time<Fixed>but a component approachTimeStep+TaskToRender.bevy_transform_ interpolation. I think a component approach is cleaner long term, but definitely error prone right now.background_fixed_schedule.Fixedbecause I think we could have a different implementation involving a FixedUpdate being run in advance of the Virtual time, resulting in a "negative accumulated time".mermaid
Unfortunately mermaid has a few bugs and github doesn't rely on latest mermaid, you can paste that is https://mermaid.live for a better formatting:
Demo
This recording simulates (through sleep) a constant task time of 0.5 second.
We can see that at a too high fixed update rate, the rendering is struggling. but at a lower fixed framerate, the rendering has a steady 60FPS.
Using bevy's synchronous
FixedUpdatewould result in a 0.5 lag at every fixed update. While an extreme example, it illustrates quite well the advantages of this approach.Screencast.from.12-24-2024.03_58_11.PM.webm
This approach also could allow some "time deviation" between virtual time and "task" time, to avoid a "catch back" phase (where the time speed appears to go quicker). The objective is to allow user to customize the "fixed steps" to consume before spawning the task.
How to test
Run the example with
bevy/multi_threadedto have the same behaviour as the above demo. Add inbevy/trace_tracyfeature and profile with tracy to have a better visualization of what's going on.cargo run --example interpolate_custom_schedule --features bevy/multi_threadedBackground task drawbacks
Transformoutside of expectedFixedUpdate, so we'd need some special handlingTime<Virtual>, and it's non trivial to make work with interpolation.