sync_bodies_from_physics.rs (1928B)
1 use std::marker::PhantomData; 2 3 use specs::{Join, ReadExpect, System, SystemData, World, WriteStorage}; 4 5 use crate::{ 6 bodies::{PhysicsBody, Position}, 7 nalgebra::RealField, 8 Physics, 9 }; 10 11 /// The `SyncBodiesFromPhysicsSystem` synchronised the updated position of 12 /// the `RigidBody`s in the nphysics `World` with their Specs counterparts. This 13 /// affects the `Position` `Component` related to the `Entity`. 14 pub struct SyncBodiesFromPhysicsSystem<N, P> { 15 n_marker: PhantomData<N>, 16 p_marker: PhantomData<P>, 17 } 18 19 impl<'s, N, P> System<'s> for SyncBodiesFromPhysicsSystem<N, P> 20 where 21 N: RealField, 22 P: Position<N>, 23 { 24 type SystemData = ( 25 ReadExpect<'s, Physics<N>>, 26 WriteStorage<'s, PhysicsBody<N>>, 27 WriteStorage<'s, P>, 28 ); 29 30 fn run(&mut self, data: Self::SystemData) { 31 let (physics, mut physics_bodies, mut positions) = data; 32 33 // iterate over all PhysicBody components joined with their Positions 34 for (physics_body, position) in (&mut physics_bodies, &mut positions).join() { 35 // if a RigidBody exists in the nphysics World we fetch it and update the 36 // Position component accordingly 37 if let Some(rigid_body) = physics.bodies.rigid_body(physics_body.handle.unwrap()) { 38 position.set_isometry(rigid_body.position()); 39 physics_body.update_from_physics_world(rigid_body); 40 } 41 } 42 } 43 44 fn setup(&mut self, res: &mut World) { 45 info!("SyncBodiesFromPhysicsSystem.setup"); 46 Self::SystemData::setup(res); 47 48 // initialise required resources 49 res.entry::<Physics<N>>().or_insert_with(Physics::default); 50 } 51 } 52 53 impl<N, P> Default for SyncBodiesFromPhysicsSystem<N, P> 54 where 55 N: RealField, 56 P: Position<N>, 57 { 58 fn default() -> Self { 59 Self { 60 n_marker: PhantomData, 61 p_marker: PhantomData, 62 } 63 } 64 }