Skip to content

Commit

Permalink
Shoot the events AND the entities!
Browse files Browse the repository at this point in the history
  • Loading branch information
AnneKitsune committed Dec 19, 2018
1 parent 73374ae commit 73e4ff8
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/systems/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use core::marker::PhantomData;
use crate::colliders::SyncCollidersToPhysicsSystem;

pub use self::physics_stepper::PhysicsStepperSystem;
pub use self::sync_bodies_from_physics::SyncBodiesFromPhysicsSystem;
pub use self::sync_bodies_from_physics::*;
pub use self::sync_bodies_to_physics::SyncBodiesToPhysicsSystem;
pub use self::sync_force_generators_to_physics::SyncForceGeneratorsToPhysicsSystem;
pub use self::sync_gravity_to_physics::SyncGravityToPhysicsSystem;
Expand Down
39 changes: 34 additions & 5 deletions src/systems/sync_bodies_from_physics.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
use nphysics3d::object::ColliderHandle;
use crate::colliders::Collider;
use crate::bodies::DynamicBody;
use crate::PhysicsWorld;
use amethyst::core::{GlobalTransform, Transform};
use amethyst::ecs::{Join, ReadStorage, System, Write, ReadExpect, WriteStorage};
use amethyst::ecs::{Join, ReadStorage, System, Write, ReadExpect, WriteStorage, Entity, Entities};
use amethyst::ecs::world::EntitiesRes;
use amethyst::shrev::EventChannel;
use nalgebra::Vector3;
use ncollide3d::events::{ContactEvent, ProximityEvent};
use nphysics3d::object::Body;

// Might want to replace by better types.
pub type EntityContactEvent = (Entity, Entity, ContactEvent);
pub type EntityProximityEvent = (Entity, Entity, ProximityEvent);

#[derive(Default)]
pub struct SyncBodiesFromPhysicsSystem;

Expand All @@ -18,22 +25,26 @@ impl SyncBodiesFromPhysicsSystem {

impl<'a> System<'a> for SyncBodiesFromPhysicsSystem {
type SystemData = (
Entities<'a>,
ReadExpect<'a, PhysicsWorld>,
Write<'a, EventChannel<ContactEvent>>,
Write<'a, EventChannel<ProximityEvent>>,
Write<'a, EventChannel<EntityContactEvent>>,
Write<'a, EventChannel<EntityProximityEvent>>,
WriteStorage<'a, GlobalTransform>,
WriteStorage<'a, DynamicBody>,
ReadStorage<'a, Transform>,
ReadStorage<'a, Collider>,
);

fn run(&mut self, data: Self::SystemData) {
let (
entities,
physical_world,
mut contact_events,
mut proximity_events,
mut global_transforms,
mut physics_bodies,
local_transforms,
colliders,
) = data;

// Apply the updated values of the simulated world to our Components
Expand Down Expand Up @@ -89,8 +100,22 @@ impl<'a> System<'a> for SyncBodiesFromPhysicsSystem {

let collision_world = physical_world.collision_world();

contact_events.iter_write(collision_world.contact_events().iter().cloned());
proximity_events.iter_write(collision_world.proximity_events().iter().cloned());
contact_events.iter_write(collision_world.contact_events().iter().cloned().map(|ev| {
let (handle1, handle2) = match ev {
ContactEvent::Started(h1, h2) => (h1, h2),
ContactEvent::Stopped(h1, h2) => (h1, h2),
};

let e1 = entity_from_handle(&entities, &colliders, &handle1).expect("Failed to find entity for collider.");
let e2 = entity_from_handle(&entities, &colliders, &handle2).expect("Failed to find entity for collider.");
(e1, e2, ev)
}));

proximity_events.iter_write(collision_world.proximity_events().iter().cloned().map(|ev| {
let e1 = entity_from_handle(&entities, &colliders, &ev.collider1).expect("Failed to find entity for collider.");
let e2 = entity_from_handle(&entities, &colliders, &ev.collider2).expect("Failed to find entity for collider.");
(e1, e2, ev)
}));

// TODO: reader id from other system?
// Now that we changed them all, let's remove all those pesky events that were generated.
Expand All @@ -104,3 +129,7 @@ impl<'a> System<'a> for SyncBodiesFromPhysicsSystem {
// .for_each(|_| ());
}
}

pub fn entity_from_handle(entities: &EntitiesRes, colliders: &ReadStorage<Collider>, handle: &ColliderHandle) -> Option<Entity> {
(&*entities, colliders).join().find(|(_, c)| c.handle.expect("Collider has no handle and wasn't removed.") == *handle).map(|(e, _)| e)
}

0 comments on commit 73e4ff8

Please sign in to comment.