From d20094708df2e29652843ee43edaa89e8a823cbf Mon Sep 17 00:00:00 2001 From: kel Date: Sun, 16 Dec 2018 18:58:57 -0500 Subject: [PATCH] Switch to property-based force application. --- examples/amethyst.rs | 3 +- src/bodies.rs | 5 +- src/forces.rs | 113 ------------------ src/lib.rs | 1 - src/systems/mod.rs | 27 +---- src/systems/sync_bodies_to_physics.rs | 2 + .../sync_force_generators_to_physics.rs | 49 -------- 7 files changed, 10 insertions(+), 190 deletions(-) delete mode 100644 src/forces.rs delete mode 100644 src/systems/sync_force_generators_to_physics.rs diff --git a/examples/amethyst.rs b/examples/amethyst.rs index 70e8378..fad6fa1 100644 --- a/examples/amethyst.rs +++ b/examples/amethyst.rs @@ -9,7 +9,6 @@ use amethyst::renderer::{ }; use amethyst::{Application, GameData, GameDataBuilder, SimpleState, StateData}; use nphysics_ecs_dumb::bodies::DynamicBody; -use nphysics_ecs_dumb::forces::DefaultForceGenerators; use nphysics_ecs_dumb::nphysics::math::{Point, Velocity}; use nphysics_ecs_dumb::systems::PhysicsBundle; use num_traits::identities::One; @@ -111,7 +110,7 @@ fn main() -> amethyst::Result<()> { let game_data = GameDataBuilder::default() .with_bundle(TransformBundle::new())? .with_bundle( - PhysicsBundle::::new().with_dep(&["transform_system"]), + PhysicsBundle::new().with_dep(&["transform_system"]), )? .with_bundle(RenderBundle::new(pipe, Some(display_config)))?; diff --git a/src/bodies.rs b/src/bodies.rs index 2d45f7f..4b0f40d 100644 --- a/src/bodies.rs +++ b/src/bodies.rs @@ -1,7 +1,7 @@ use amethyst::ecs::world::Index; use amethyst::ecs::{Component, FlaggedStorage}; use nalgebra::Matrix3; -use nphysics3d::math::{Point, Velocity}; +use nphysics3d::math::{Point, Velocity, Force}; use nphysics3d::object::BodyHandle; use std::collections::HashMap; @@ -37,6 +37,7 @@ impl DynamicBody { mass, angular_mass, center_of_mass, + external_forces: Force::::zero(), }) } @@ -63,6 +64,8 @@ pub struct RigidPhysicsBody { pub mass: f32, pub angular_mass: Matrix3, pub center_of_mass: Point, + + pub external_forces: Force, } /// Multipart physics body, for use in `PhysicsBody` Component. Not implemented yet. diff --git a/src/forces.rs b/src/forces.rs deleted file mode 100644 index f5a60db..0000000 --- a/src/forces.rs +++ /dev/null @@ -1,113 +0,0 @@ -use crate::bodies::DynamicsBodyRelations; -use amethyst::core::approx::AbsDiffEq; -use amethyst::ecs::{BitSet, Component, FlaggedStorage}; -use nalgebra::Unit; -use nphysics3d::force_generator::ForceGenerator; -use nphysics3d::math::{Force, Point, Vector, Velocity}; -use nphysics3d::object::{BodyHandle, BodySet}; -use nphysics3d::solver::IntegrationParameters; - -pub trait ForceGenerators: Default + Send + Sync { - type LocalForceGenerators: LocalForceGenerators; - type LinkedForceGenerators: LinkedForceGenerators; -} - -pub trait LocalForceGenerators: - ForceGenerator + Component> -{ -} - -pub trait LinkedForceGenerators: - ForceGenerator + Component> -{ - fn affected_bodies(&self) -> DynamicsBodyRelations; // TODO this signature is definitely wrong. -} - -#[derive(Default)] -pub struct DefaultForceGenerators; - -impl ForceGenerators for DefaultForceGenerators { - type LocalForceGenerators = DefaultLocalForceGenerators; - type LinkedForceGenerators = DefaultLinkedForceGenerators; -} - -pub enum DefaultLocalForceGenerators { - ConstantAcceleration(ConstantAcceleration), -} - -pub struct ConstantAcceleration { - pub acceleration: Velocity, -} - -impl Component for DefaultLocalForceGenerators { - type Storage = FlaggedStorage; -} - -impl ForceGenerator for DefaultLocalForceGenerators { - fn apply(&mut self, _: &IntegrationParameters, _bodies: &mut BodySet) -> bool { - false - } -} - -impl LocalForceGenerators for DefaultLocalForceGenerators {} - -pub enum DefaultLinkedForceGenerators { - Spring(Spring), -} - -pub struct Spring { - pub length: f32, - pub stiffness: f32, - pub anchor1: Point, - pub anchor2: Point, - pub handle1: BodyHandle, - pub handle2: BodyHandle, - pub links: BitSet, -} - -impl Component for DefaultLinkedForceGenerators { - type Storage = FlaggedStorage; -} - -impl LinkedForceGenerators for DefaultLinkedForceGenerators { - fn affected_bodies(&self) -> DynamicsBodyRelations { - DynamicsBodyRelations::new() - // match self { - // DefaultLinkedForceGenerators::Spring(x) => x.links - // } - } -} - -impl ForceGenerator for DefaultLinkedForceGenerators { - fn apply(&mut self, _: &IntegrationParameters, bodies: &mut BodySet) -> bool { - match self { - DefaultLinkedForceGenerators::Spring(spring) => { - if !bodies.contains(spring.handle1) || !bodies.contains(spring.handle2) { - return false; - } - - let anchor1 = bodies.body_part(spring.handle1).position() * spring.anchor1; - let anchor2 = bodies.body_part(spring.handle2).position() * spring.anchor2; - - let force_dir; - let delta_length; - - if let Some((dir, length)) = - Unit::try_new_and_get(anchor2 - anchor1, f32::default_epsilon()) - { - force_dir = dir; - delta_length = length - spring.length; - } else { - force_dir = Vector::y_axis(); - delta_length = -spring.length; - } - - let force = Force::linear(force_dir.as_ref() * delta_length * spring.stiffness); - bodies.body_part_mut(spring.handle1).apply_force(&force); - bodies.body_part_mut(spring.handle2).apply_force(&-force); - - true - } - } - } -} diff --git a/src/lib.rs b/src/lib.rs index 91f89e3..1d361a9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,6 @@ pub extern crate nphysics3d as nphysics; extern crate num_traits; pub mod bodies; -pub mod forces; pub mod systems; pub type World = self::nphysics::world::World; diff --git a/src/systems/mod.rs b/src/systems/mod.rs index a1c5121..7a0df9b 100644 --- a/src/systems/mod.rs +++ b/src/systems/mod.rs @@ -1,42 +1,30 @@ mod physics_stepper; mod sync_bodies_from_physics; mod sync_bodies_to_physics; -mod sync_force_generators_to_physics; mod sync_gravity_to_physics; -use crate::forces::ForceGenerators; use amethyst::core::bundle::{Result, SystemBundle}; use amethyst::core::specs::DispatcherBuilder; -use core::marker::PhantomData; pub use self::physics_stepper::PhysicsStepperSystem; pub use self::sync_bodies_from_physics::SyncBodiesFromPhysicsSystem; 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; // TODO: Implement contact events, use Entity id's instead of nphysics handles. // contact_events.iter_write(physical_world.contact_events()); -pub const SYNC_FORCE_GENERATORS_TO_PHYSICS_SYSTEM: &str = "sync_force_generators_to_physics_system"; pub const SYNC_BODIES_TO_PHYSICS_SYSTEM: &str = "sync_bodies_to_physics_system"; pub const SYNC_GRAVITY_TO_PHYSICS_SYSTEM: &str = "sync_gravity_to_physics_system"; pub const PHYSICS_STEPPER_SYSTEM: &str = "physics_stepper_system"; pub const SYNC_BODIES_FROM_PHYSICS_SYSTEM: &str = "sync_bodies_from_physics_system"; #[derive(Default)] -pub struct PhysicsBundle<'a, F> -where - F: ForceGenerators, -{ +pub struct PhysicsBundle<'a> { dep: &'a [&'a str], - phantom_force_generators: PhantomData, } -impl<'a, F> PhysicsBundle<'a, F> -where - F: ForceGenerators, -{ +impl<'a> PhysicsBundle<'a> { pub fn new() -> Self { Default::default() } @@ -47,16 +35,8 @@ where } } -impl<'a, 'b, 'c, F: 'a> SystemBundle<'a, 'b> for PhysicsBundle<'c, F> -where - F: ForceGenerators, -{ +impl<'a, 'b, 'c> SystemBundle<'a, 'b> for PhysicsBundle<'c> { fn build(self, builder: &mut DispatcherBuilder<'a, 'b>) -> Result<()> { - builder.add( - SyncForceGeneratorsToPhysicsSystem::::new(), - SYNC_FORCE_GENERATORS_TO_PHYSICS_SYSTEM, - self.dep, - ); builder.add( SyncBodiesToPhysicsSystem::new(), SYNC_BODIES_TO_PHYSICS_SYSTEM, @@ -72,7 +52,6 @@ where PhysicsStepperSystem::new(), PHYSICS_STEPPER_SYSTEM, &[ - SYNC_FORCE_GENERATORS_TO_PHYSICS_SYSTEM, SYNC_BODIES_TO_PHYSICS_SYSTEM, SYNC_GRAVITY_TO_PHYSICS_SYSTEM, ], diff --git a/src/systems/sync_bodies_to_physics.rs b/src/systems/sync_bodies_to_physics.rs index e1cc7fe..259517b 100644 --- a/src/systems/sync_bodies_to_physics.rs +++ b/src/systems/sync_bodies_to_physics.rs @@ -97,6 +97,7 @@ impl<'a> System<'a> for SyncBodiesToPhysicsSystem { .unwrap(); physical_body.set_velocity(rigid_body.velocity); + physical_body.apply_force(&rigid_body.external_forces); } DynamicBody::Multibody(_) => { // TODO @@ -112,6 +113,7 @@ impl<'a> System<'a> for SyncBodiesToPhysicsSystem { physical_body.set_position(try_convert(transform.0).unwrap()); 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! } diff --git a/src/systems/sync_force_generators_to_physics.rs b/src/systems/sync_force_generators_to_physics.rs deleted file mode 100644 index 42456d4..0000000 --- a/src/systems/sync_force_generators_to_physics.rs +++ /dev/null @@ -1,49 +0,0 @@ -use crate::forces::{DefaultForceGenerators, ForceGenerators}; -use crate::World; -use amethyst::ecs::{ReadStorage, System, Write, WriteExpect}; -use amethyst::shrev::EventChannel; -use core::marker::PhantomData; -use ncollide3d::events::ContactEvent; - -// TODO: Synchronize force generators, tidy up api. - -pub struct SyncForceGeneratorsToPhysicsSystem -where - F: ForceGenerators, -{ - phantom_force_generators: PhantomData, -} - -impl SyncForceGeneratorsToPhysicsSystem -where - F: ForceGenerators, -{ - pub fn new() -> Self { - Default::default() - } -} - -impl Default for SyncForceGeneratorsToPhysicsSystem -where - F: ForceGenerators, -{ - fn default() -> Self { - SyncForceGeneratorsToPhysicsSystem:: { - phantom_force_generators: PhantomData, - } - } -} - -impl<'a, F> System<'a> for SyncForceGeneratorsToPhysicsSystem -where - F: ForceGenerators, -{ - type SystemData = ( - WriteExpect<'a, World>, - Write<'a, EventChannel>, - ReadStorage<'a, F::LocalForceGenerators>, - ReadStorage<'a, F::LinkedForceGenerators>, - ); - - fn run(&mut self, _data: Self::SystemData) {} -}