rhusics_ecs/physics/systems/
current_frame.rs

1use std::fmt::Debug;
2use std::marker;
3
4use cgmath::{BaseFloat, EuclideanSpace, InnerSpace, Rotation, VectorSpace, Zero};
5use core::{NextFrame, PhysicalEntity, Pose, Velocity};
6use specs::prelude::{Component, Join, ReadStorage, System, WriteStorage};
7
8/// Current frame update system.
9///
10/// Will update positions and velocities for the current frame, based on `NextFrame` values.
11///
12/// ### Type parameters:
13///
14/// - `P`: Positional quantity, usually `Point2` or `Point3`
15/// - `R`: Rotational quantity, usually `Basis2` or `Quaternion`
16/// - `A`: Angular velocity, usually `Scalar` or `Vector3`
17/// - `T`: Transform type (`BodyPose2` or similar)
18///
19/// ### System function:
20///
21/// `fn(NextFrame<Velocity>, NextFrame<T>) -> (Velocity, T)`
22pub struct CurrentFrameUpdateSystem<P, R, A, T> {
23    m: marker::PhantomData<(P, R, A, T)>,
24}
25
26impl<P, R, A, T> CurrentFrameUpdateSystem<P, R, A, T>
27where
28    P: EuclideanSpace,
29    P::Diff: VectorSpace + InnerSpace + Debug,
30    P::Scalar: BaseFloat,
31    R: Rotation<P>,
32    A: Clone + Zero,
33    T: Pose<P, R>,
34{
35    /// Create system.
36    pub fn new() -> Self {
37        Self {
38            m: marker::PhantomData,
39        }
40    }
41}
42
43impl<'a, P, R, A, T> System<'a> for CurrentFrameUpdateSystem<P, R, A, T>
44where
45    P: EuclideanSpace + Send + Sync + 'static,
46    P::Diff: VectorSpace + InnerSpace + Debug + Send + Sync + 'static,
47    P::Scalar: BaseFloat + Send + Sync + 'static,
48    R: Rotation<P> + Send + Sync + 'static,
49    A: Clone + Zero + Send + Sync + 'static,
50    T: Pose<P, R> + Component + Clone + Send + Sync + 'static,
51{
52    type SystemData = (
53        ReadStorage<'a, PhysicalEntity<P::Scalar>>,
54        WriteStorage<'a, Velocity<P::Diff, A>>,
55        ReadStorage<'a, NextFrame<Velocity<P::Diff, A>>>,
56        WriteStorage<'a, T>,
57        ReadStorage<'a, NextFrame<T>>,
58    );
59
60    fn run(&mut self, data: Self::SystemData) {
61        let (entities, mut velocities, next_velocities, mut poses, next_poses) = data;
62
63        // Update current pose
64        for (_, next, pose) in (&entities, &next_poses, &mut poses)
65            .join()
66            .filter(|(e, ..)| e.active())
67        {
68            *pose = next.value.clone();
69        }
70
71        // Update current velocity
72        for (_, next, velocity) in (&entities, &next_velocities, &mut velocities)
73            .join()
74            .filter(|(e, ..)| e.active())
75        {
76            *velocity = next.value.clone();
77        }
78    }
79}