specs-physics

[Fork] Integration of Amethyst, SPECS and Nphysics together.
git clone https://git.jojolepro.com/specs-physics.git
Log | Files | Refs | README | LICENSE

commit a75bfa674cfc78b79319643b7274165bd01d4aa6
parent 37d818336b4f4186512f9bbc1f244d0498d00b4e
Author: kel <distransient@protonmail.com>
Date:   Fri,  7 Dec 2018 04:10:33 -0500

Split off utility function iterate_events in body syncing

Diffstat:
MREADME.md | 2++
Msrc/systems/sync_bodies_from_physics.rs | 7++++---
Msrc/systems/sync_bodies_to_physics.rs | 120+++++++++++++++++++++++++++++++++++++++++++------------------------------------
3 files changed, 72 insertions(+), 57 deletions(-)

diff --git a/README.md b/README.md @@ -35,3 +35,5 @@ Investigating: - [ ] Constraint-based Joints - [ ] Kinematics - [ ] Body Activation & Sleeping. + +Also, implement logging using the log crate. diff --git a/src/systems/sync_bodies_from_physics.rs b/src/systems/sync_bodies_from_physics.rs @@ -1,7 +1,7 @@ use crate::bodies::DynamicBody; use crate::World; use amethyst::core::{GlobalTransform, Transform}; -use amethyst::ecs::{Join, ReadStorage, System, Write, WriteExpect, WriteStorage}; +use amethyst::ecs::{Join, ReadStorage, System, Write, ReadExpect, WriteStorage}; use amethyst::shrev::EventChannel; use nalgebra::Vector3; use ncollide3d::events::ContactEvent; @@ -18,7 +18,7 @@ impl SyncBodiesFromPhysicsSystem { impl<'a> System<'a> for SyncBodiesFromPhysicsSystem { type SystemData = ( - WriteExpect<'a, World>, + ReadExpect<'a, World>, Write<'a, EventChannel<ContactEvent>>, WriteStorage<'a, GlobalTransform>, WriteStorage<'a, DynamicBody>, @@ -27,7 +27,7 @@ impl<'a> System<'a> for SyncBodiesFromPhysicsSystem { fn run(&mut self, data: Self::SystemData) { let ( - mut physical_world, + physical_world, _contact_events, mut global_transforms, mut physics_bodies, @@ -35,6 +35,7 @@ impl<'a> System<'a> for SyncBodiesFromPhysicsSystem { ) = data; // Apply the updated values of the simulated world to our Components + #[allow(unused_mut)] for (mut global_transform, mut body, local_transform) in ( &mut global_transforms, &mut physics_bodies, diff --git a/src/systems/sync_bodies_to_physics.rs b/src/systems/sync_bodies_to_physics.rs @@ -1,14 +1,13 @@ use crate::bodies::DynamicBody; use crate::World; use amethyst::core::GlobalTransform; -use amethyst::ecs::storage::ComponentEvent; +use amethyst::ecs::storage::{ComponentEvent, MaskedStorage, GenericReadStorage}; use amethyst::ecs::{ - BitSet, Entities, Join, ReaderId, Resources, System, SystemData, Write, WriteExpect, - WriteStorage, + BitSet, Component, Entities, Join, ReadStorage, ReaderId, Resources, Storage, System, + SystemData, Tracked, WriteExpect, WriteStorage, }; -use amethyst::shrev::EventChannel; +use core::ops::Deref; use nalgebra::try_convert; -use ncollide3d::events::ContactEvent; use nphysics3d::math::Inertia; #[derive(Default)] @@ -26,15 +25,13 @@ impl SyncBodiesToPhysicsSystem { impl<'a> System<'a> for SyncBodiesToPhysicsSystem { type SystemData = ( WriteExpect<'a, World>, - Write<'a, EventChannel<ContactEvent>>, Entities<'a>, - WriteStorage<'a, GlobalTransform>, + ReadStorage<'a, GlobalTransform>, WriteStorage<'a, DynamicBody>, ); fn run(&mut self, data: Self::SystemData) { - let (mut physical_world, _contact_events, entities, mut transforms, mut physics_bodies) = - data; + let (mut physical_world, entities, transforms, mut physics_bodies) = data; let mut inserted_transforms = BitSet::new(); let mut modified_transforms = BitSet::new(); @@ -42,55 +39,29 @@ impl<'a> System<'a> for SyncBodiesToPhysicsSystem { let mut modified_physics_bodies = BitSet::new(); // Get change flag events for transforms, removing deleted ones from the physics world. - { - let events = transforms - .channel() - .read(&mut self.transforms_reader_id.as_mut().unwrap()); - for event in events { - match event { - ComponentEvent::Modified(id) => { - modified_transforms.add(*id); - } - ComponentEvent::Inserted(id) => { - inserted_transforms.add(*id); - } - ComponentEvent::Removed(id) => { - physical_world.remove_bodies(&[physics_bodies - .get(entities.entity(*id)) - .unwrap() - .handle() - .unwrap()]); - } - }; - } - } + iterate_events( + &transforms, + self.transforms_reader_id.as_mut().unwrap(), + &mut inserted_transforms, + &mut modified_transforms, + &mut physical_world, + &entities, + &physics_bodies, + ); // Get change flag events for physics bodies, removing deleted ones from the physics world. - { - let events = physics_bodies - .channel() - .read(&mut self.physics_bodies_reader_id.as_mut().unwrap()); - for event in events { - match event { - ComponentEvent::Modified(id) => { - modified_physics_bodies.add(*id); - } - ComponentEvent::Inserted(id) => { - inserted_physics_bodies.add(*id); - println!("I'm in!"); - } - ComponentEvent::Removed(id) => { - physical_world.remove_bodies(&[physics_bodies - .get(entities.entity(*id)) - .unwrap() - .handle() - .unwrap()]); - } - }; - } - } + iterate_events( + &physics_bodies, + self.physics_bodies_reader_id.as_mut().unwrap(), + &mut inserted_physics_bodies, + &mut modified_physics_bodies, + &mut physical_world, + &entities, + &physics_bodies, + ); // Update simulation world with the value of Components flagged as changed + #[allow(unused_mut)] for (_entity, transform, mut body, id) in ( &entities, &transforms, @@ -162,3 +133,44 @@ impl<'a> System<'a> for SyncBodiesToPhysicsSystem { self.physics_bodies_reader_id = Some(physics_body_storage.register_reader()); } } + +fn iterate_events<'a, T, D, S>( + tracked_storage: &Storage<T, D>, + reader: &mut ReaderId<ComponentEvent>, + inserted: &mut BitSet, + modified: &mut BitSet, + world: &mut World, + entities: &Entities, + bodies: &S +) where + T: Component, + T::Storage: Tracked, + D: Deref<Target = MaskedStorage<T>>, + S: GenericReadStorage<Component=DynamicBody>, +{ + let events = tracked_storage.channel().read(reader); + + for event in events { + match event { + ComponentEvent::Modified(id) => { modified.add(*id); }, + ComponentEvent::Inserted(id) => { inserted.add(*id); }, + ComponentEvent::Removed(id) => { + match bodies.get(entities.entity(*id)) { + Some(body) => { + match body.handle() { + Some(handle) => { + world.remove_bodies(&[handle]); + } + None => { + // TODO: Log missing handle + } + }; + } + None => { + // TODO: Log missing body + } + }; + } + }; + } +}