From 421f13bc357367ee358784b86f1c318412b88b17 Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Thu, 9 Apr 2020 17:28:33 -0700 Subject: [PATCH] Upgrade specs-physics to latest nphysics --- Cargo.toml | 11 ++- src/amethyst.rs | 32 ++++++++ src/bodies.rs | 4 +- src/colliders.rs | 18 +++-- src/lib.rs | 74 ++++++++++++------- src/systems/physics_stepper.rs | 90 ++++++++++++++--------- src/systems/sync_bodies_from_physics.rs | 2 +- src/systems/sync_bodies_to_physics.rs | 21 +++--- src/systems/sync_colliders_to_physics.rs | 53 ++++++------- src/systems/sync_parameters_to_physics.rs | 14 ++-- 10 files changed, 196 insertions(+), 123 deletions(-) create mode 100644 src/amethyst.rs diff --git a/Cargo.toml b/Cargo.toml index 854e5fd..8baa02c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,12 +20,12 @@ amethyst = ["amethyst_core"] [dependencies] log = "0.4.6" -specs = "0.15.0" -specs-hierarchy = { git = "https://github.com/cedric-h/specs-hierarchy.git", branch = "update-specs" } +specs = "0.16.0" +specs-hierarchy = "0.6.0" shrev = "1.1.1" -nalgebra = "0.18.0" -ncollide3d = "0.19" -nphysics3d = "0.11.1" +nalgebra = "0.19.0" +ncollide3d = "0.21.0" +nphysics3d = "0.13.1" amethyst_core = { git = "https://github.com/amethyst/amethyst", optional = true } objekt = "0.1.2" @@ -52,4 +52,3 @@ path = "examples/collision.rs" [[example]] name = "events" path = "examples/events.rs" - diff --git a/src/amethyst.rs b/src/amethyst.rs new file mode 100644 index 0000000..dbe3590 --- /dev/null +++ b/src/amethyst.rs @@ -0,0 +1,32 @@ +use amethyst_core::{SystemBundle, Transform}; +use amethyst_error::Error; +use specs::{DispatcherBuilder, World}; + +use crate::{nalgebra::Isometry3, register_physics_systems, Position}; + +impl Position for Transform { + fn isometry(&self) -> &Isometry3 { + self.isometry() + } + + fn isometry_mut(&mut self) -> &mut Isometry3 { + self.isometry_mut() + } + + fn set_isometry(&mut self, isometry: &Isometry3) -> &mut Self { + self.set_isometry(*isometry) + } +} + +pub struct PhysicsBundle; + +impl<'a, 'b> SystemBundle<'a, 'b> for PhysicsBundle { + fn build( + self, + _world: &mut World, + dispatcher: &mut DispatcherBuilder<'a, 'b>, + ) -> Result<(), Error> { + register_physics_systems::(dispatcher); + Ok(()) + } +} diff --git a/src/bodies.rs b/src/bodies.rs index 58c33c5..1bec681 100644 --- a/src/bodies.rs +++ b/src/bodies.rs @@ -4,7 +4,7 @@ use crate::{ nalgebra::{Isometry3, Matrix3, Point3, RealField}, nphysics::{ algebra::{Force3, ForceType, Velocity3}, - object::{Body, BodyHandle, BodyPart, BodyStatus, RigidBody, RigidBodyDesc}, + object::{Body, BodyPart, BodyStatus, DefaultBodyHandle, RigidBody, RigidBodyDesc}, }, }; @@ -73,7 +73,7 @@ impl Position for amethyst_core::Transform { /// both worlds. #[derive(Clone, Copy, Debug)] pub struct PhysicsBody { - pub(crate) handle: Option, + pub(crate) handle: Option, pub gravity_enabled: bool, pub body_status: BodyStatus, pub velocity: Velocity3, diff --git a/src/colliders.rs b/src/colliders.rs index b13b808..e8e833d 100644 --- a/src/colliders.rs +++ b/src/colliders.rs @@ -5,6 +5,7 @@ use specs::{Component, DenseVecStorage, FlaggedStorage}; use crate::{ nalgebra::{DMatrix, Isometry3, Point2, Point3, RealField, Unit, Vector3}, ncollide::{ + pipeline::CollisionGroups, shape::{ Ball, Capsule, @@ -19,11 +20,10 @@ use crate::{ TriMesh, Triangle, }, - world::CollisionGroups, }, nphysics::{ material::{BasicMaterial, MaterialHandle}, - object::ColliderHandle, + object::DefaultColliderHandle, }, }; @@ -138,16 +138,18 @@ impl Shape { #[derive(Clone)] pub struct PhysicsCollider { /// The handle to the collider in the physics world. - pub(crate) handle: Option, + pub(crate) handle: Option, /// The shape of this collider. pub shape: Shape, - /// The position/rotation offset of the collider from the entity it is attached to. + /// The position/rotation offset of the collider from the entity it is + /// attached to. pub offset_from_parent: Isometry3, pub density: N, /// The physics material of which this collider is composed. /// Defines properties like bounciness and others. pub material: MaterialHandle, - /// Margin between the detection zone of what is "near" the collider and the actual collider. + /// Margin between the detection zone of what is "near" the collider and the + /// actual collider. pub margin: N, /// Collision groups this collider is part of. /// Defines with which other colliders this collider can interact. @@ -156,8 +158,8 @@ pub struct PhysicsCollider { pub linear_prediction: N, /// Prediction amount of the angular momentum. pub angular_prediction: N, - /// Whether this collider is a sensor and only emits events without interacting (true) or - /// if it is a regular collider (false). + /// Whether this collider is a sensor and only emits events without + /// interacting (true) or if it is a regular collider (false). pub sensor: bool, } @@ -210,7 +212,7 @@ impl PhysicsCollider { /// use specs_physics::{ /// colliders::Shape, /// nalgebra::{Isometry3, Vector3}, -/// ncollide::world::CollisionGroups, +/// ncollide::pipeline::CollisionGroups, /// nphysics::material::{BasicMaterial, MaterialHandle}, /// PhysicsColliderBuilder, /// }; diff --git a/src/lib.rs b/src/lib.rs index ceaccdc..3003695 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -114,7 +114,7 @@ //! use specs_physics::{ //! colliders::Shape, //! nalgebra::{Isometry3, Vector3}, -//! ncollide::world::CollisionGroups, +//! ncollide::pipeline::CollisionGroups, //! nphysics::material::{BasicMaterial, MaterialHandle}, //! PhysicsColliderBuilder, //! }; @@ -151,11 +151,11 @@ //! `SyncBodiesToPhysicsSystem` as [Collider][] can depend on [RigidBody][]. //! //! 3. `specs_physics::systems::SyncParametersToPhysicsSystem` - handles the -//! modification of the [nphysics][] `World`s parameters. +//! modification of the [nphysics][] `DefaultMechanicalWorld`s parameters. //! //! 4. `specs_physics::systems::PhysicsStepperSystem` - handles the progression -//! of the [nphysics][] `World` and causes objects to actually move and -//! change their position. This `System` is the backbone for collision +//! of the [nphysics][] `DefaultMechanicalWorld` and causes objects to actually +//! move and change their position. This `System` is the backbone for collision //! detection. //! //! 5. `specs_physics::systems::SyncBodiesFromPhysicsSystem` - @@ -215,9 +215,12 @@ //! arguments like so: //! //! ``` +//! # #[cfg(feature = "amethyst")] +//! # { //! use amethyst_core::Transform; //! use specs_physics::systems::SyncBodiesToPhysicsSystem; //! SyncBodiesToPhysicsSystem::::default(); +//! # } //! ``` //! //! Alternatively to building your own `Dispatcher`, you can always fall back on @@ -267,10 +270,18 @@ use self::{ nalgebra::{RealField, Vector3}, nphysics::{ counters::Counters, + force_generator::DefaultForceGeneratorSet, + joint::DefaultJointConstraintSet, material::MaterialsCoefficientsTable, - object::{BodyHandle, ColliderHandle}, + object::{ + DefaultBodyHandle, + DefaultBodySet, + DefaultColliderHandle, + DefaultColliderSet, + Ground, + }, solver::IntegrationParameters, - world::World, + world::{DefaultGeometricalWorld, DefaultMechanicalWorld}, }, systems::{ PhysicsStepperSystem, @@ -281,25 +292,31 @@ use self::{ }, }; +#[cfg(feature = "amethyst")] +pub mod amethyst; pub mod bodies; pub mod colliders; pub mod events; pub mod parameters; pub mod systems; - /// Resource holding the internal fields where physics computation occurs. /// Some inspection methods are exposed to allow debugging. pub struct Physics { /// Core structure where physics computation and synchronization occurs. - /// Also contains ColliderWorld. - pub(crate) world: World, + pub(crate) mechanical_world: DefaultMechanicalWorld, + pub(crate) geometrical_world: DefaultGeometricalWorld, + pub(crate) bodies: DefaultBodySet, + pub(crate) colliders: DefaultColliderSet, + pub(crate) joint_constraints: DefaultJointConstraintSet, + pub(crate) force_generators: DefaultForceGeneratorSet, + pub(crate) ground: DefaultBodyHandle, /// Hashmap of Entities to internal Physics bodies. /// Necessary for reacting to removed Components. - pub(crate) body_handles: HashMap, + pub(crate) body_handles: HashMap, /// Hashmap of Entities to internal Collider handles. /// Necessary for reacting to removed Components. - pub(crate) collider_handles: HashMap, + pub(crate) collider_handles: HashMap, } // Some non-mutating methods for diagnostics and testing @@ -312,45 +329,47 @@ impl Physics { /// Reports the internal value for the timestep. /// See also `TimeStep` for setting this value. pub fn timestep(&self) -> N { - self.world.timestep() + self.mechanical_world.timestep() } /// Reports the internal value for the gravity. /// See also `Gravity` for setting this value. pub fn gravity(&self) -> &Vector3 { - self.world.gravity() - } - - /// Reports the internal value for prediction distance in collision - /// detection. This cannot change and will normally be `0.002m` - pub fn prediction(&self) -> N { - self.world.prediction() + &self.mechanical_world.gravity } /// Retrieves the performance statistics for the last simulated timestep. /// Profiling is disabled by default. /// See also `PhysicsProfilingEnabled` for enabling performance counters. pub fn performance_counters(&self) -> &Counters { - self.world.performance_counters() + &self.mechanical_world.counters } /// Retrieves the internal parameters for integration. /// See also `PhysicsIntegrationParameters` for setting these parameters. pub fn integration_parameters(&self) -> &IntegrationParameters { - self.world.integration_parameters() + &self.mechanical_world.integration_parameters } /// Retrieves the internal lookup table for friction and restitution /// constants. Exposing this for modification is TODO. pub fn materials_coefficients_table(&self) -> &MaterialsCoefficientsTable { - self.world.materials_coefficients_table() + &self.mechanical_world.material_coefficients } } impl Default for Physics { fn default() -> Self { + let mut bodies = DefaultBodySet::new(); + let ground = bodies.insert(Ground::new()); Self { - world: World::new(), + mechanical_world: DefaultMechanicalWorld::new(Vector3::zeros()), + geometrical_world: DefaultGeometricalWorld::new(), + bodies, + ground, + colliders: DefaultColliderSet::new(), + joint_constraints: DefaultJointConstraintSet::new(), + force_generators: DefaultForceGeneratorSet::new(), body_handles: HashMap::new(), collider_handles: HashMap::new(), } @@ -427,8 +446,9 @@ where ); // add PhysicsStepperSystem after all other Systems that write data to the - // nphysics World and has to depend on them; this System is used to progress the - // nphysics World for all existing objects + // nphysics DefaultMechanicalWorld and has to depend on them; this System is + // used to progress the nphysics DefaultMechanicalWorld for all existing + // objects dispatcher_builder.add( PhysicsStepperSystem::::default(), "physics_stepper_system", @@ -440,8 +460,8 @@ where ); // add SyncBodiesFromPhysicsSystem last as it handles the - // synchronisation between nphysics World bodies and the Position - // components; this depends on the PhysicsStepperSystem + // synchronisation between nphysics DefaultMechanicalWorld bodies and the + // Position components; this depends on the PhysicsStepperSystem dispatcher_builder.add( SyncBodiesFromPhysicsSystem::::default(), "sync_bodies_from_physics_system", diff --git a/src/systems/physics_stepper.rs b/src/systems/physics_stepper.rs index e63e868..54e2e4d 100644 --- a/src/systems/physics_stepper.rs +++ b/src/systems/physics_stepper.rs @@ -5,8 +5,8 @@ use specs::{world::Index, Entities, Entity, Read, System, SystemData, World, Wri use crate::{ events::{ContactEvent, ContactEvents, ContactType, ProximityEvent, ProximityEvents}, nalgebra::RealField, - ncollide::{events::ContactEvent as NContactEvent, world::CollisionObjectHandle}, - nphysics::world::ColliderWorld, + ncollide::pipeline::{CollisionObjectSet, ContactEvent as NContactEvent}, + nphysics::object::{DefaultColliderHandle, DefaultColliderSet}, parameters::TimeStep, Physics, }; @@ -28,55 +28,73 @@ impl<'s, N: RealField> System<'s> for PhysicsStepperSystem { fn run(&mut self, data: Self::SystemData) { let (entities, time_step, mut contact_events, mut proximity_events, mut physics) = data; + // Convert physics from Write to &mut pointer so rustc can correctly reason + // about independence of &mut borrows to struct components + let physics: &mut Physics = &mut *physics; + // if a TimeStep resource exits, set the timestep for the nphysics integration // accordingly; this should not be required if the Systems are executed in a // fixed interval if let Some(time_step) = time_step { // only update timestep if it actually differs from the current nphysics World // one; keep in mind that changing the Resource will destabilize the simulation - if physics.world.timestep() != time_step.0 { + if physics.mechanical_world.timestep() != time_step.0 { warn!( "TimeStep and world.timestep() differ, changing worlds timestep from {} to: {:?}", - physics.world.timestep(), + physics.mechanical_world.timestep(), time_step.0 ); - physics.world.set_timestep(time_step.0); + physics.mechanical_world.set_timestep(time_step.0); } } - physics.world.step(); - - let collider_world = physics.world.collider_world(); + physics.mechanical_world.step( + &mut physics.geometrical_world, + &mut physics.bodies, + &mut physics.colliders, + &mut physics.joint_constraints, + &mut physics.force_generators, + ); // map occurred ncollide ContactEvents to a custom ContactEvent type; this // custom type contains data that is more relevant for Specs users than // CollisionObjectHandles, such as the Entities that took part in the collision - contact_events.iter_write(collider_world.contact_events().iter().map(|contact_event| { - debug!("Got ContactEvent: {:?}", contact_event); - // retrieve CollisionObjectHandles from ContactEvent and map the ContactEvent - // type to our own custom ContactType - let (handle1, handle2, contact_type) = match contact_event { - NContactEvent::Started(handle1, handle2) => { - (*handle1, *handle2, ContactType::Started) - } - NContactEvent::Stopped(handle1, handle2) => { - (*handle1, *handle2, ContactType::Stopped) + contact_events.iter_write(physics.geometrical_world.contact_events().iter().map( + |contact_event| { + debug!("Got ContactEvent: {:?}", contact_event); + // retrieve CollisionObjectHandles from ContactEvent and map the ContactEvent + // type to our own custom ContactType + let (handle1, handle2, contact_type) = match contact_event { + NContactEvent::Started(handle1, handle2) => { + (*handle1, *handle2, ContactType::Started) + } + NContactEvent::Stopped(handle1, handle2) => { + (*handle1, *handle2, ContactType::Stopped) + } + }; + + // create our own ContactEvent from the extracted data; mapping the + // CollisionObjectHandles to Entities is error prone but should work as intended + // as long as we're the only ones working directly with the nphysics World + ContactEvent { + collider1: entity_from_collision_object_handle( + &entities, + handle1, + &physics.colliders, + ), + collider2: entity_from_collision_object_handle( + &entities, + handle2, + &physics.colliders, + ), + contact_type, } - }; - - // create our own ContactEvent from the extracted data; mapping the - // CollisionObjectHandles to Entities is error prone but should work as intended - // as long as we're the only ones working directly with the nphysics World - ContactEvent { - collider1: entity_from_collision_object_handle(&entities, handle1, &collider_world), - collider2: entity_from_collision_object_handle(&entities, handle2, &collider_world), - contact_type, - } - })); + }, + )); // map occurred ncollide ProximityEvents to a custom ProximityEvent type; see // ContactEvents for reasoning - proximity_events.iter_write(collider_world.proximity_events().iter().map( + proximity_events.iter_write(physics.geometrical_world.proximity_events().iter().map( |proximity_event| { debug!("Got ProximityEvent: {:?}", proximity_event); // retrieve CollisionObjectHandles and Proximity statuses from the ncollide @@ -95,12 +113,12 @@ impl<'s, N: RealField> System<'s> for PhysicsStepperSystem { collider1: entity_from_collision_object_handle( &entities, handle1, - &collider_world, + &physics.colliders, ), collider2: entity_from_collision_object_handle( &entities, handle2, - &collider_world, + &physics.colliders, ), prev_status, new_status, @@ -131,12 +149,12 @@ where fn entity_from_collision_object_handle( entities: &Entities, - collision_object_handle: CollisionObjectHandle, - collider_world: &ColliderWorld, + collision_object_handle: DefaultColliderHandle, + collider_set: &DefaultColliderSet, ) -> Entity { entities.entity( - *collider_world - .collider(collision_object_handle) + *collider_set + .collision_object(collision_object_handle) .unwrap() .user_data() .unwrap() diff --git a/src/systems/sync_bodies_from_physics.rs b/src/systems/sync_bodies_from_physics.rs index c88ffe0..f62b104 100644 --- a/src/systems/sync_bodies_from_physics.rs +++ b/src/systems/sync_bodies_from_physics.rs @@ -34,7 +34,7 @@ where for (physics_body, position) in (&mut physics_bodies, &mut positions).join() { // if a RigidBody exists in the nphysics World we fetch it and update the // Position component accordingly - if let Some(rigid_body) = physics.world.rigid_body(physics_body.handle.unwrap()) { + if let Some(rigid_body) = physics.bodies.rigid_body(physics_body.handle.unwrap()) { position.set_isometry(rigid_body.position()); physics_body.update_from_physics_world(rigid_body); } diff --git a/src/systems/sync_bodies_to_physics.rs b/src/systems/sync_bodies_to_physics.rs index befc8b0..84e5c5c 100644 --- a/src/systems/sync_bodies_to_physics.rs +++ b/src/systems/sync_bodies_to_physics.rs @@ -144,17 +144,18 @@ fn add_rigid_body( // handles clean if let Some(body_handle) = physics.body_handles.remove(&id) { warn!("Removing orphaned body handle: {:?}", body_handle); - physics.world.remove_bodies(&[body_handle]); + physics.bodies.remove(body_handle); } // create a new RigidBody in the PhysicsWorld and store its // handle for later usage - let handle = physics_body - .to_rigid_body_desc() - .position(*position.isometry()) - .user_data(id) - .build(&mut physics.world) - .handle(); + let handle = physics.bodies.insert( + physics_body + .to_rigid_body_desc() + .position(*position.isometry()) + .user_data(id) + .build(), + ); physics_body.handle = Some(handle); physics.body_handles.insert(id, handle); @@ -176,7 +177,7 @@ fn update_rigid_body( N: RealField, P: Position, { - if let Some(rigid_body) = physics.world.rigid_body_mut(physics_body.handle.unwrap()) { + if let Some(rigid_body) = physics.bodies.rigid_body_mut(physics_body.handle.unwrap()) { // the PhysicsBody was modified, update everything but the position if modified_physics_bodies.contains(id) { physics_body.apply_to_physics_world(rigid_body); @@ -201,7 +202,7 @@ where { if let Some(handle) = physics.body_handles.remove(&id) { // remove body if it still exists in the PhysicsWorld - physics.world.remove_bodies(&[handle]); + physics.bodies.remove(handle); info!("Removed rigid body from world with id: {}", id); } } @@ -244,6 +245,6 @@ mod tests { // fetch the Physics instance and check for new bodies let physics = world.read_resource::>(); assert_eq!(physics.body_handles.len(), 1); - assert_eq!(physics.world.bodies().count(), 1); + assert_eq!(physics.bodies.iter().count(), 2); } } diff --git a/src/systems/sync_colliders_to_physics.rs b/src/systems/sync_colliders_to_physics.rs index cab49e0..02c94e8 100644 --- a/src/systems/sync_colliders_to_physics.rs +++ b/src/systems/sync_colliders_to_physics.rs @@ -151,34 +151,35 @@ fn add_collider( // remove already existing colliders for this inserted event if let Some(handle) = physics.collider_handles.remove(&id) { warn!("Removing orphaned collider handle: {:?}", handle); - physics.world.remove_colliders(&[handle]); + physics.colliders.remove(handle); } // attempt to find an existing RigidBody for this Index; if one exists we'll // fetch its BodyPartHandle and use it as the Colliders parent in the // nphysics World + let ground_handle = BodyPartHandle(physics.ground, 0); let parent_part_handle = match physics.body_handles.get(&id) { Some(parent_handle) => physics - .world + .bodies .rigid_body(*parent_handle) - .map_or(BodyPartHandle::ground(), |body| body.part_handle()), + .map_or(ground_handle, |_| BodyPartHandle(*parent_handle, 0)), None => { // if BodyHandle was found for the current Entity/Index, check for a potential // parent Entity and repeat the first step if let Some(parent_entity) = parent_entity { match physics.body_handles.get(&parent_entity.entity.id()) { Some(parent_handle) => physics - .world + .bodies .rigid_body(*parent_handle) - .map_or(BodyPartHandle::ground(), |body| body.part_handle()), + .map_or(ground_handle, |_| BodyPartHandle(*parent_handle, 0)), None => { // ultimately default to BodyPartHandle::ground() - BodyPartHandle::ground() + ground_handle } } } else { // no parent Entity exists, default to BodyPartHandle::ground() - BodyPartHandle::ground() + ground_handle } } }; @@ -186,7 +187,7 @@ fn add_collider( // translation based on parent handle; if we did not have a valid parent and // ended up defaulting to BodyPartHandle::ground(), we'll need to take the // Position into consideration - let translation = if parent_part_handle.is_ground() { + let translation = if parent_part_handle == ground_handle { // let scale = 1.0; may be added later let iso = &mut position.isometry().clone(); iso.translation.vector += @@ -198,19 +199,19 @@ fn add_collider( }; // create the actual Collider in the nphysics World and fetch its handle - let handle = ColliderDesc::new(physics_collider.shape_handle()) - .position(translation) - .density(physics_collider.density) - .material(physics_collider.material.clone()) - .margin(physics_collider.margin) - .collision_groups(physics_collider.collision_groups) - .linear_prediction(physics_collider.linear_prediction) - .angular_prediction(physics_collider.angular_prediction) - .sensor(physics_collider.sensor) - .user_data(id) - .build_with_parent(parent_part_handle, &mut physics.world) - .unwrap() - .handle(); + let handle = physics.colliders.insert( + ColliderDesc::new(physics_collider.shape_handle()) + .position(translation) + .density(physics_collider.density) + .material(physics_collider.material.clone()) + .margin(physics_collider.margin) + .collision_groups(physics_collider.collision_groups) + .linear_prediction(physics_collider.linear_prediction) + .angular_prediction(physics_collider.angular_prediction) + .sensor(physics_collider.sensor) + .user_data(id) + .build(parent_part_handle), + ); physics_collider.handle = Some(handle); physics.collider_handles.insert(id, handle); @@ -228,10 +229,10 @@ where { debug!("Modified PhysicsCollider with id: {}", id); let collider_handle = physics_collider.handle.unwrap(); - let collider_world = physics.world.collider_world_mut(); + let collider = physics.colliders.get_mut(collider_handle).unwrap(); // update collision groups - collider_world.set_collision_groups(collider_handle, physics_collider.collision_groups); + collider.set_collision_groups(physics_collider.collision_groups); info!( "Updated collider in world with values: {:?}", @@ -250,8 +251,8 @@ where // attempting to delete it as removing a collider that does not exist anymore // causes the nphysics World to panic; colliders are implicitly removed when a // parent body is removed so this is actually a valid scenario - if physics.world.collider(handle).is_some() { - physics.world.remove_colliders(&[handle]); + if physics.colliders.get(handle).is_some() { + physics.colliders.remove(handle); } info!("Removed collider from world with id: {}", id); @@ -297,6 +298,6 @@ mod tests { // fetch the Physics instance and check for new colliders let physics = world.read_resource::>(); assert_eq!(physics.collider_handles.len(), 1); - assert_eq!(physics.world.colliders().count(), 1); + assert_eq!(physics.colliders.iter().count(), 1); } } diff --git a/src/systems/sync_parameters_to_physics.rs b/src/systems/sync_parameters_to_physics.rs index cfa862a..775ba98 100644 --- a/src/systems/sync_parameters_to_physics.rs +++ b/src/systems/sync_parameters_to_physics.rs @@ -33,7 +33,7 @@ impl<'s, N: RealField> System<'s> for SyncParametersToPhysicsSystem { physics.gravity(), gravity.0 ); - physics.world.set_gravity(gravity.0); + physics.mechanical_world.gravity = gravity.0; } } @@ -41,17 +41,17 @@ impl<'s, N: RealField> System<'s> for SyncParametersToPhysicsSystem { if enable_profiling.0 != physics.performance_counters().enabled() { if enable_profiling.0 { info!("Physics performance counters enabled."); - physics.world.enable_performance_counters(); + physics.mechanical_world.counters.enable(); } else { info!("Physics performance counters disabled."); - physics.world.disable_performance_counters(); + physics.mechanical_world.counters.disable(); } } } if let Some(params) = integration_params { if *params != *physics.integration_parameters() { - params.apply(physics.world.integration_parameters_mut()); + params.apply(&mut physics.mechanical_world.integration_parameters); info!("Integration parameters have been updated."); } } @@ -105,8 +105,8 @@ mod tests { dispatcher.dispatch(&world); let physics = world.read_resource::>(); - assert_ulps_eq!(physics.world.gravity().x, 1.0); - assert_ulps_eq!(physics.world.gravity().y, 2.0); - assert_ulps_eq!(physics.world.gravity().z, 3.0); + assert_ulps_eq!(physics.mechanical_world.gravity.x, 1.0); + assert_ulps_eq!(physics.mechanical_world.gravity.y, 2.0); + assert_ulps_eq!(physics.mechanical_world.gravity.z, 3.0); } }