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 2d3c7fabe6365c0454266fae23b68fc0632043da
parent e70b07560de2dc0c8ab9f4ea3981341b4d24f008
Author: kel <distransient@protonmail.com>
Date:   Thu, 27 Dec 2018 18:15:25 -0500

Refactor enum out of dynamicbody

Diffstat:
Msrc/bodies.rs | 67++++++++++++++++++++++++-------------------------------------------
Msrc/systems/sync_bodies_from_physics.rs | 101+++++++++++++++++++++++++++++++++++--------------------------------------------
Msrc/systems/sync_bodies_to_physics.rs | 79+++++++++++++++++++++++++++++++++----------------------------------------------
3 files changed, 102 insertions(+), 145 deletions(-)

diff --git a/src/bodies.rs b/src/bodies.rs @@ -1,15 +1,24 @@ -use amethyst::ecs::world::Index; use amethyst::ecs::{Component, FlaggedStorage}; use nalgebra::Matrix3; use nphysics3d::math::{Force, Point, Velocity}; use nphysics3d::object::BodyHandle; -use std::collections::HashMap; -/// Physics body component for describing (currently) rigid body dynamics. -#[derive(Serialize, Deserialize, Debug, Clone, Copy)] -pub enum DynamicBody { - RigidBody(RigidPhysicsBody), - Multibody(PhysicsMultibody), +/// Rigid physics body, for use in `PhysicsBody` Component. +/// Currently only the velocity is read and updated at runtime. +/// The properties of mass are only written at physics body creation time. +#[derive(Serialize, Deserialize, Clone, Copy, Debug, new)] +pub struct DynamicBody { + #[serde(skip)] + #[new(default)] + pub(crate) handle: Option<BodyHandle>, + pub velocity: Velocity<f32>, + + // TODO: update these in the physics system below. + pub mass: f32, + pub angular_mass: Matrix3<f32>, + pub center_of_mass: Point<f32>, + + pub external_forces: Force<f32>, } impl DynamicBody { @@ -18,12 +27,14 @@ impl DynamicBody { angular_mass: Matrix3<f32>, center_of_mass: Point<f32>, ) -> Self { - DynamicBody::new_rigidbody_with_velocity( - Velocity::<f32>::zero(), + DynamicBody { + handle: None, + velocity: Velocity::<f32>::zero(), mass, angular_mass, center_of_mass, - ) + external_forces: Force::<f32>::zero(), + } } pub fn new_rigidbody_with_velocity( @@ -32,51 +43,21 @@ impl DynamicBody { angular_mass: Matrix3<f32>, center_of_mass: Point<f32>, ) -> Self { - DynamicBody::RigidBody(RigidPhysicsBody { + DynamicBody { handle: None, velocity, mass, angular_mass, center_of_mass, external_forces: Force::<f32>::zero(), - }) + } } pub fn handle(&self) -> Option<BodyHandle> { - match self { - DynamicBody::RigidBody(x) => x.handle, - DynamicBody::Multibody(x) => x.handle, - } + self.handle } } impl Component for DynamicBody { type Storage = FlaggedStorage<Self>; } - -/// Rigid physics body, for use in `PhysicsBody` Component. -/// Currently only the velocity is read and updated at runtime. -/// The properties of mass are only written at physics body creation time. -#[derive(Serialize, Deserialize, Clone, Copy, Debug, new)] -pub struct RigidPhysicsBody { - #[serde(skip)] - #[new(default)] - pub(crate) handle: Option<BodyHandle>, - pub velocity: Velocity<f32>, - - // TODO: update these in the physics system below. - pub mass: f32, - pub angular_mass: Matrix3<f32>, - pub center_of_mass: Point<f32>, - - pub external_forces: Force<f32>, -} - -/// Multipart physics body, for use in `PhysicsBody` Component. Not implemented yet. -#[derive(Serialize, Deserialize, Clone, Copy, Debug)] -pub struct PhysicsMultibody { - #[serde(skip)] - pub handle: Option<BodyHandle>, -} - -pub type DynamicsBodyRelations = HashMap<Index, BodyHandle>; diff --git a/src/systems/sync_bodies_from_physics.rs b/src/systems/sync_bodies_from_physics.rs @@ -59,74 +59,63 @@ impl<'a> System<'a> for SyncBodiesFromPhysicsSystem { .join() { if let Some(updated_body_handle) = body.handle() { - let updated_body = physical_world.body(updated_body_handle); + if let Some(updated_body) = physical_world.rigid_body(updated_body_handle) { + if !updated_body.is_active() || updated_body.is_static() { + trace!( + "Skipping synchronizing data from non-dynamic body: {:?}", + updated_body.handle() + ); + continue; + } - if updated_body.is_ground() || !updated_body.is_active() || updated_body.is_static() - { trace!( - "Skipping synchronizing data from non-dynamic body: {:?}", + "Synchronizing RigidBody from handle: {:?}", updated_body.handle() ); - continue; - } - match (body, updated_body) { - ( - DynamicBody::RigidBody(ref mut rigid_body), - Body::RigidBody(ref updated_rigid_body), - ) => { - trace!( - "Synchronizing RigidBody from handle: {:?}", - updated_rigid_body.handle() - ); + trace!( + "Synchronized RigidBody's updated position: {:?}", + updated_body.position() + ); - trace!( - "Synchronized RigidBody's updated position: {:?}", - updated_rigid_body.position() + global_transform.0 = updated_body + .position() + .to_homogeneous() + .prepend_nonuniform_scaling( + &local_transform + .as_ref() + .map(|tr| tr.scale().clone()) + .unwrap_or(Vector3::new(1.0, 1.0, 1.0)), ); - global_transform.0 = updated_rigid_body - .position() - .to_homogeneous() - .prepend_nonuniform_scaling( - &local_transform - .as_ref() - .map(|tr| *tr.scale()) - .unwrap_or_else(|| Vector3::new(1.0, 1.0, 1.0)), - ); - - if let Some(ref mut local_transform) = local_transform { - *local_transform.isometry_mut() = updated_rigid_body.position(); - } + if let Some(ref mut local_transform) = local_transform { + *local_transform.isometry_mut() = updated_body.position().clone(); + } - trace!( - "Synchronized RigidBody's updated velocity: {:?}", - updated_rigid_body.velocity() - ); - rigid_body.velocity = *updated_rigid_body.velocity(); + trace!( + "Synchronized RigidBody's updated velocity: {:?}", + updated_body.velocity() + ); + body.velocity = *updated_body.velocity(); - trace!( - "Synchronized RigidBody's updated inertia: {:?}", - updated_rigid_body.inertia() - ); - let inertia = updated_rigid_body.inertia(); - rigid_body.mass = inertia.linear; - rigid_body.angular_mass = inertia.angular; + trace!( + "Synchronized RigidBody's updated inertia: {:?}", + updated_body.inertia() + ); + let inertia = updated_body.inertia(); + body.mass = inertia.linear; + body.angular_mass = inertia.angular; - trace!( - "Synchronized RigidBody's updated center of mass: {:?}", - updated_rigid_body.center_of_mass() - ); - rigid_body.center_of_mass = updated_rigid_body.center_of_mass(); - } - (DynamicBody::Multibody(_multibody), Body::Multibody(_updated_multibody)) => { - error!("Multibody found; not implemented currently, sorry!") - } - // TODO: Add data to unexpected pair message. Not straightforward. - _ => error!("Unexpected dynamics body pair!"), - }; + trace!( + "Synchronized RigidBody's updated center of mass: {:?}", + updated_body.center_of_mass() + ); + body.center_of_mass = updated_body.center_of_mass(); + } else { + error!("Found body without pair in physics world!"); + } } else { - warn!("Found body in physics world not registered in the ECS world!"); + error!("Found body without handle!"); } } diff --git a/src/systems/sync_bodies_to_physics.rs b/src/systems/sync_bodies_to_physics.rs @@ -78,60 +78,47 @@ impl<'a> System<'a> for SyncBodiesToPhysicsSystem { if inserted_transforms.contains(id) || inserted_physics_bodies.contains(id) { trace!("Detected inserted dynamics body with id {}", id); - match body { - DynamicBody::RigidBody(ref mut rigid_body) => { - // Just inserted. Remove old one and insert new. - if let Some(handle) = rigid_body.handle { - if physical_world.rigid_body(handle).is_some() { - trace!("Removing body marked as inserted that already exists with handle: {:?}", handle); - physical_world.remove_bodies(&[handle]); - } - } + // Just inserted. Remove old one and insert new. + if let Some(handle) = body.handle { + if physical_world.rigid_body(handle).is_some() { + trace!("Removing body marked as inserted that already exists with handle: {:?}", handle); + physical_world.remove_bodies(&[handle]); + } + } - rigid_body.handle = Some(physical_world.add_rigid_body( - try_convert(transform.0).unwrap(), - Inertia::new(rigid_body.mass, rigid_body.angular_mass), - rigid_body.center_of_mass, - )); + body.handle = Some(physical_world.add_rigid_body( + try_convert(transform.0).unwrap(), + Inertia::new(body.mass, body.angular_mass), + body.center_of_mass, + )); - trace!("Inserted rigid body to world with values: {:?}", rigid_body); + trace!("Inserted rigid body to world with values: {:?}", body); - let physical_body = physical_world - .rigid_body_mut(rigid_body.handle.unwrap()) - .unwrap(); + let physical_body = physical_world.rigid_body_mut(body.handle.unwrap()).unwrap(); - physical_body.set_velocity(rigid_body.velocity); - physical_body.apply_force(&rigid_body.external_forces); - rigid_body.external_forces = Force::<f32>::zero(); + physical_body.set_velocity(body.velocity); + physical_body.apply_force(&body.external_forces); + body.external_forces = Force::<f32>::zero(); - trace!("Velocity and external forces applied, external forces reset to zero, for body with handle: {:?}", rigid_body.handle); - } - DynamicBody::Multibody(_) => { - // TODO - error!("Multibody found; not implemented currently, sorry!") - } - } + trace!("Velocity and external forces applied, external forces reset to zero, for body with handle: {:?}", body.handle); } else if modified_transforms.contains(id) || modified_physics_bodies.contains(id) { trace!("Detected changed dynamics body with id {}", id); - match body { - DynamicBody::RigidBody(ref mut rigid_body) => { - if let Some(physical_body) = physical_world.rigid_body_mut(rigid_body.handle.unwrap()) { - let position: Isometry<f32> = try_convert(transform.0).unwrap(); - trace!( - "Updating rigid body in physics world with isometry: {}", - position - ); - physical_body.set_position(position); - physical_body.set_velocity(rigid_body.velocity); - physical_body.apply_force(&rigid_body.external_forces); - - // if you changed the mass properties at all... too bad! - } - } - DynamicBody::Multibody(_) => { - // TODO - error!("Multibody found; not implemented currently, sorry!") + match physical_world.rigid_body_mut(body.handle.unwrap()) { + Some(physical_body) => { + let position: Isometry<f32> = try_convert(transform.0).unwrap(); + trace!( + "Updating rigid body in physics world with isometry: {}", + position + ); + physical_body.set_position(position); + + physical_body.set_velocity(body.velocity); + physical_body.apply_force(&body.external_forces); + body.external_forces = Force::<f32>::zero(); + + // if you changed the mass properties at all... too bad! } + None => {} } } }