bevy_fsc_point_cloud/
playback.rs1use bevy::{prelude::*, utils::HashMap};
2
3use crate::PointCloudAsset;
4
5#[derive(Resource, Clone, Default)]
6pub struct PointCloudPlaybackControls {
7 pub(crate) controls: HashMap<Handle<PointCloudAsset>, PlaybackControls>,
8}
9
10#[derive(Clone, Copy)]
11pub struct PlaybackControls {
12 pub time: f32,
13 pub playing: bool,
14 pub speed: f32,
15}
16
17impl Default for PlaybackControls {
18 fn default() -> Self {
19 Self {
20 time: 0.,
21 playing: false,
22 speed: 1.,
23 }
24 }
25}
26
27impl PointCloudPlaybackControls {
28 pub fn controls(&self, handle: &Handle<PointCloudAsset>) -> PlaybackControls {
29 self.controls.get(handle).copied().unwrap_or_default()
30 }
31
32 pub fn controls_mut(&mut self, handle: &Handle<PointCloudAsset>) -> &mut PlaybackControls {
33 self.controls.entry(handle.clone_weak()).or_default()
34 }
35
36 pub fn playback_system(
37 mut controls: ResMut<Self>,
38 time: Res<Time>,
39 assets: Res<Assets<PointCloudAsset>>,
40 ) {
41 let mut changed = false;
42 let len = controls.controls.len();
43
44 controls
45 .bypass_change_detection()
46 .controls
47 .retain(|handle, controls| {
48 let Some(animation_duration) = assets
49 .get(handle)
50 .and_then(|asset| asset.animation_duration())
51 else {
52 return false;
54 };
55
56 if controls.playing {
57 changed |= true;
58 controls.time += controls.speed * time.delta_seconds();
59 controls.time = controls.time.rem_euclid(animation_duration);
60 }
61
62 true
63 });
64
65 if changed || controls.controls.len() != len {
66 controls.set_changed();
67 }
68 }
69}