diff options
| author | Crozet Sébastien <developer@crozet.re> | 2021-06-01 12:36:01 +0200 |
|---|---|---|
| committer | Crozet Sébastien <developer@crozet.re> | 2021-06-01 12:36:01 +0200 |
| commit | 826ce5f014281fd04b7a18238f102f2591d0b255 (patch) | |
| tree | b35c16371dcfac726c2821b7bfd9da21184155bd /src/dynamics | |
| parent | 1bef66fea941307a7305ddaebdb0abe3d0cb281f (diff) | |
| download | rapier-826ce5f014281fd04b7a18238f102f2591d0b255.tar.gz rapier-826ce5f014281fd04b7a18238f102f2591d0b255.tar.bz2 rapier-826ce5f014281fd04b7a18238f102f2591d0b255.zip | |
Rework the event system
Diffstat (limited to 'src/dynamics')
| -rw-r--r-- | src/dynamics/ccd/ccd_solver.rs | 30 | ||||
| -rw-r--r-- | src/dynamics/ccd/toi_entry.rs | 2 | ||||
| -rw-r--r-- | src/dynamics/island_manager.rs | 22 | ||||
| -rw-r--r-- | src/dynamics/rigid_body.rs | 27 | ||||
| -rw-r--r-- | src/dynamics/rigid_body_components.rs | 46 | ||||
| -rw-r--r-- | src/dynamics/solver/island_solver.rs | 4 | ||||
| -rw-r--r-- | src/dynamics/solver/joint_constraint/ball_position_constraint.rs | 8 | ||||
| -rw-r--r-- | src/dynamics/solver/joint_constraint/ball_position_constraint_wide.rs | 6 | ||||
| -rw-r--r-- | src/dynamics/solver/joint_constraint/fixed_position_constraint.rs | 6 | ||||
| -rw-r--r-- | src/dynamics/solver/joint_constraint/generic_position_constraint.rs | 6 | ||||
| -rw-r--r-- | src/dynamics/solver/joint_constraint/revolute_position_constraint.rs | 6 | ||||
| -rw-r--r-- | src/dynamics/solver/parallel_island_solver.rs | 2 |
12 files changed, 95 insertions, 70 deletions
diff --git a/src/dynamics/ccd/ccd_solver.rs b/src/dynamics/ccd/ccd_solver.rs index b348283..354f183 100644 --- a/src/dynamics/ccd/ccd_solver.rs +++ b/src/dynamics/ccd/ccd_solver.rs @@ -10,6 +10,7 @@ use crate::geometry::{ use crate::math::Real; use crate::parry::utils::SortedPair; use crate::pipeline::{EventHandler, QueryPipeline, QueryPipelineMode}; +use crate::prelude::{ActiveEvents, ColliderFlags}; use parry::query::{DefaultQueryDispatcher, QueryDispatcher}; use parry::utils::hashmap::HashMap; use std::collections::BinaryHeap; @@ -66,7 +67,7 @@ impl CCDSolver { &RigidBodyCcd, &RigidBodyMassProps, ) = bodies.index_bundle(handle.0); - let local_com = &mprops.mass_properties.local_com; + let local_com = &mprops.local_mprops.local_com; let min_toi = (ccd.ccd_thickness * 0.15 @@ -272,7 +273,8 @@ impl CCDSolver { Colliders: ComponentSetOption<ColliderParent> + ComponentSet<ColliderPosition> + ComponentSet<ColliderShape> - + ComponentSet<ColliderType>, + + ComponentSet<ColliderType> + + ComponentSet<ColliderFlags>, { let mut frozen = HashMap::<_, Real>::default(); let mut all_toi = BinaryHeap::new(); @@ -522,10 +524,16 @@ impl CCDSolver { // - If the intersection isn't active anymore, and it wasn't intersecting // before, then we need to generate one interaction-start and one interaction-stop // events because it will never be detected by the narrow-phase because of tunneling. - let (co_pos1, co_shape1): (&ColliderPosition, &ColliderShape) = - colliders.index_bundle(toi.c1.0); - let (co_pos2, co_shape2): (&ColliderPosition, &ColliderShape) = - colliders.index_bundle(toi.c2.0); + let (co_pos1, co_shape1, co_flags1): ( + &ColliderPosition, + &ColliderShape, + &ColliderFlags, + ) = colliders.index_bundle(toi.c1.0); + let (co_pos2, co_shape2, co_flags2): ( + &ColliderPosition, + &ColliderShape, + &ColliderFlags, + ) = colliders.index_bundle(toi.c2.0); let co_next_pos1 = if let Some(b1) = toi.b1 { let co_parent1: &ColliderParent = colliders.get(toi.c1.0).unwrap(); @@ -535,7 +543,7 @@ impl CCDSolver { &RigidBodyMassProps, ) = bodies.index_bundle(b1.0); - let local_com1 = &rb_mprops1.mass_properties.local_com; + let local_com1 = &rb_mprops1.local_mprops.local_com; let frozen1 = frozen.get(&b1); let pos1 = frozen1 .map(|t| rb_vels1.integrate(*t, &rb_pos1.position, local_com1)) @@ -553,7 +561,7 @@ impl CCDSolver { &RigidBodyMassProps, ) = bodies.index_bundle(b2.0); - let local_com2 = &rb_mprops2.mass_properties.local_com; + let local_com2 = &rb_mprops2.local_mprops.local_com; let frozen2 = frozen.get(&b2); let pos2 = frozen2 .map(|t| rb_vels2.integrate(*t, &rb_pos2.position, local_com2)) @@ -575,7 +583,11 @@ impl CCDSolver { .intersection_test(&next_coll_pos12, co_shape1.as_ref(), co_shape2.as_ref()) .unwrap_or(false); - if !intersect_before && !intersect_after { + if !intersect_before + && !intersect_after + && (co_flags1.active_events | co_flags2.active_events) + .contains(ActiveEvents::INTERSECTION_EVENTS) + { // Emit one intersection-started and one intersection-stopped event. events.handle_intersection_event(IntersectionEvent::new(toi.c1, toi.c2, true)); events.handle_intersection_event(IntersectionEvent::new(toi.c1, toi.c2, false)); diff --git a/src/dynamics/ccd/toi_entry.rs b/src/dynamics/ccd/toi_entry.rs index 4637940..78396c0 100644 --- a/src/dynamics/ccd/toi_entry.rs +++ b/src/dynamics/ccd/toi_entry.rs @@ -173,7 +173,7 @@ impl TOIEntry { if ccd.ccd_active { NonlinearRigidMotion::new( poss.position, - mprops.mass_properties.local_com, + mprops.local_mprops.local_com, vels.linvel, vels.angvel, ) diff --git a/src/dynamics/island_manager.rs b/src/dynamics/island_manager.rs index b79cdb2..34fa3bd 100644 --- a/src/dynamics/island_manager.rs +++ b/src/dynamics/island_manager.rs @@ -229,19 +229,17 @@ impl IslandManager { stack: &mut Vec<RigidBodyHandle>, ) { for collider_handle in &rb_colliders.0 { - if let Some(contacts) = narrow_phase.contacts_with(*collider_handle) { - for inter in contacts { - for manifold in &inter.2.manifolds { - if !manifold.data.solver_contacts.is_empty() { - let other = crate::utils::select_other( - (inter.0, inter.1), - *collider_handle, - ); - if let Some(other_body) = colliders.get(other.0) { - stack.push(other_body.handle); - } - break; + for inter in narrow_phase.contacts_with(*collider_handle) { + for manifold in &inter.manifolds { + if !manifold.data.solver_contacts.is_empty() { + let other = crate::utils::select_other( + (inter.collider1, inter.collider2), + *collider_handle, + ); + if let Some(other_body) = colliders.get(other.0) { + stack.push(other_body.handle); } + break; } } } diff --git a/src/dynamics/rigid_body.rs b/src/dynamics/rigid_body.rs index d53ff98..07e362d 100644 --- a/src/dynamics/rigid_body.rs +++ b/src/dynamics/rigid_body.rs @@ -4,8 +4,7 @@ use crate::dynamics::{ RigidBodyMassPropsFlags, RigidBodyPosition, RigidBodyType, RigidBodyVelocity, }; use crate::geometry::{ - Collider, ColliderHandle, ColliderMassProperties, ColliderParent, ColliderPosition, - ColliderShape, + Collider, ColliderHandle, ColliderMassProps, ColliderParent, ColliderPosition, ColliderShape, }; use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector}; use crate::utils::{self, WCross}; @@ -48,7 +47,7 @@ impl RigidBody { rb_ccd: RigidBodyCcd::default(), rb_ids: RigidBodyIds::default(), rb_colliders: RigidBodyColliders::default(), - rb_activation: RigidBodyActivation::new_active(), + rb_activation: RigidBodyActivation::active(), changes: RigidBodyChanges::all(), rb_type: RigidBodyType::Dynamic, rb_dominance: RigidBodyDominance::default(), @@ -112,7 +111,7 @@ impl RigidBody { /// The mass properties of this rigid-body. #[inline] pub fn mass_properties(&self) -> &MassProperties { - &self.rb_mprops.mass_properties + &self.rb_mprops.local_mprops } /// The dominance group of this rigid-body. @@ -256,7 +255,7 @@ impl RigidBody { self.wake_up(true); } - self.rb_mprops.mass_properties = props; + self.rb_mprops.local_mprops = props; self.update_world_mass_properties(); } @@ -290,7 +289,7 @@ impl RigidBody { /// /// Returns zero if this rigid body has an infinite mass. pub fn mass(&self) -> Real { - utils::inv(self.rb_mprops.mass_properties.inv_mass) + utils::inv(self.rb_mprops.local_mprops.inv_mass) } /// The predicted position of this rigid-body. @@ -335,7 +334,7 @@ impl RigidBody { co_parent: &ColliderParent, co_pos: &mut ColliderPosition, co_shape: &ColliderShape, - co_mprops: &ColliderMassProperties, + co_mprops: &ColliderMassProps, ) { self.rb_colliders.attach_collider( &mut self.changes, @@ -359,7 +358,7 @@ impl RigidBody { let mass_properties = coll .mass_properties() .transform_by(coll.position_wrt_parent().unwrap()); - self.rb_mprops.mass_properties -= mass_properties; + self.rb_mprops.local_mprops -= mass_properties; self.update_world_mass_properties(); } } @@ -463,8 +462,8 @@ impl RigidBody { /// The translational part of this rigid-body's position. #[inline] - pub fn translation(&self) -> Vector<Real> { - self.rb_pos.position.translation.vector + pub fn translation(&self) -> &Vector<Real> { + &self.rb_pos.position.translation.vector } /// Sets the translational part of this rigid-body's position. @@ -482,8 +481,8 @@ impl RigidBody { /// The translational part of this rigid-body's position. #[inline] - pub fn rotation(&self) -> Rotation<Real> { - self.rb_pos.position.rotation + pub fn rotation(&self) -> &Rotation<Real> { + &self.rb_pos.position.rotation } /// Sets the rotational part of this rigid-body's position. @@ -692,7 +691,7 @@ impl RigidBody { pub fn gravitational_potential_energy(&self, dt: Real, gravity: Vector<Real>) -> Real { let world_com = self .rb_mprops - .mass_properties + .local_mprops .world_com(&self.rb_pos.position) .coords; @@ -979,7 +978,7 @@ impl RigidBodyBuilder { rb.rb_vels.angvel = self.angvel; rb.rb_type = self.rb_type; rb.user_data = self.user_data; - rb.rb_mprops.mass_properties = self.mass_properties; + rb.rb_mprops.local_mprops = self.mass_properties; rb.rb_mprops.flags = self.mprops_flags; rb.rb_damping.linear_damping = self.linear_damping; rb.rb_damping.angular_damping = self.angular_damping; diff --git a/src/dynamics/rigid_body_components.rs b/src/dynamics/rigid_body_components.rs index 2a652f7..b536d07 100644 --- a/src/dynamics/rigid_body_components.rs +++ b/src/dynamics/rigid_body_components.rs @@ -1,7 +1,7 @@ use crate::data::{ComponentSetMut, ComponentSetOption}; use crate::dynamics::MassProperties; use crate::geometry::{ - ColliderChanges, ColliderHandle, ColliderMassProperties, ColliderParent, ColliderPosition, + ColliderChanges, ColliderHandle, ColliderMassProps, ColliderParent, ColliderPosition, ColliderShape, InteractionGraph, RigidBodyGraphIndex, }; use crate::math::{AngVector, AngularInertia, Isometry, Point, Real, Translation, Vector}; @@ -166,7 +166,7 @@ impl RigidBodyPosition { mprops: &RigidBodyMassProps, ) -> Isometry<Real> { let new_vels = forces.integrate(dt, vels, mprops); - new_vels.integrate(dt, &self.position, &mprops.mass_properties.local_com) + new_vels.integrate(dt, &self.position, &mprops.local_mprops.local_com) } } @@ -208,7 +208,7 @@ pub struct RigidBodyMassProps { /// Flags for locking rotation and translation. pub flags: RigidBodyMassPropsFlags, /// The local mass properties of the rigid-body. - pub mass_properties: MassProperties, + pub local_mprops: MassProperties, /// The world-space center of mass of the rigid-body. pub world_com: Point<Real>, /// The inverse mass taking into account translation locking. @@ -222,7 +222,7 @@ impl Default for RigidBodyMassProps { fn default() -> Self { Self { flags: RigidBodyMassPropsFlags::empty(), - mass_properties: MassProperties::zero(), + local_mprops: MassProperties::zero(), world_com: Point::origin(), effective_inv_mass: 0.0, effective_world_inv_inertia_sqrt: AngularInertia::zero(), @@ -239,11 +239,20 @@ impl From<RigidBodyMassPropsFlags> for RigidBodyMassProps { } } +impl From<MassProperties> for RigidBodyMassProps { + fn from(local_mprops: MassProperties) -> Self { + Self { + local_mprops, + ..Default::default() + } + } +} + impl RigidBodyMassProps { /// The mass of the rigid-body. #[must_use] pub fn mass(&self) -> Real { - crate::utils::inv(self.mass_properties.inv_mass) + crate::utils::inv(self.local_mprops.inv_mass) } /// The effective mass (that takes the potential translation locking into account) of @@ -255,11 +264,10 @@ impl RigidBodyMassProps { /// Update the world-space mass properties of `self`, taking into account the new position. pub fn update_world_mass_properties(&mut self, position: &Isometry<Real>) { - self.world_com = self.mass_properties.world_com(&position); - self.effective_inv_mass = self.mass_properties.inv_mass; - self.effective_world_inv_inertia_sqrt = self - .mass_properties - .world_inv_inertia_sqrt(&position.rotation); + self.world_com = self.local_mprops.world_com(&position); + self.effective_inv_mass = self.local_mprops.inv_mass; + self.effective_world_inv_inertia_sqrt = + self.local_mprops.world_inv_inertia_sqrt(&position.rotation); // Take into account translation/rotation locking. if self @@ -665,7 +673,7 @@ impl RigidBodyColliders { co_pos: &mut ColliderPosition, co_parent: &ColliderParent, co_shape: &ColliderShape, - co_mprops: &ColliderMassProperties, + co_mprops: &ColliderMassProps, ) { rb_changes.set( RigidBodyChanges::MODIFIED | RigidBodyChanges::COLLIDERS, @@ -684,7 +692,7 @@ impl RigidBodyColliders { .mass_properties(&**co_shape) .transform_by(&co_parent.pos_wrt_parent); self.0.push(co_handle); - rb_mprops.mass_properties += mass_properties; + rb_mprops.local_mprops += mass_properties; rb_mprops.update_world_mass_properties(&rb_pos.position); } @@ -759,7 +767,7 @@ pub struct RigidBodyActivation { impl Default for RigidBodyActivation { fn default() -> Self { - Self::new_active() + Self::active() } } @@ -770,7 +778,7 @@ impl RigidBodyActivation { } /// Create a new rb_activation status initialised with the default rb_activation threshold and is active. - pub fn new_active() -> Self { + pub fn active() -> Self { RigidBodyActivation { threshold: Self::default_threshold(), energy: Self::default_threshold() * 4.0, @@ -779,7 +787,7 @@ impl RigidBodyActivation { } /// Create a new rb_activation status initialised with the default rb_activation threshold and is inactive. - pub fn new_inactive() -> Self { + pub fn inactive() -> Self { RigidBodyActivation { threshold: Self::default_threshold(), energy: 0.0, @@ -787,6 +795,14 @@ impl RigidBodyActivation { } } + /// Create a new activation status that prevents the rigid-body from sleeping. + pub fn cannot_sleep() -> Self { + RigidBodyActivation { + threshold: -Real::MAX, + ..Self::active() + } + } + /// Returns `true` if the body is not asleep. #[inline] pub fn is_active(&self) -> bool { diff --git a/src/dynamics/solver/island_solver.rs b/src/dynamics/solver/island_solver.rs index 1e65341..0c4c323 100644 --- a/src/dynamics/solver/island_solver.rs +++ b/src/dynamics/solver/island_solver.rs @@ -113,7 +113,7 @@ impl IslandSolver { let mut new_poss = *poss; let new_vels = vels.apply_damping(params.dt, damping); new_poss.next_position = - vels.integrate(params.dt, &poss.position, &mprops.mass_properties.local_com); + vels.integrate(params.dt, &poss.position, &mprops.local_mprops.local_com); bodies.set_internal(handle.0, new_vels); bodies.set_internal(handle.0, new_poss); @@ -140,7 +140,7 @@ impl IslandSolver { .integrate(params.dt, vels, mprops) .apply_damping(params.dt, &damping); new_poss.next_position = - vels.integrate(params.dt, &poss.position, &mprops.mass_properties.local_com); + vels.integrate(params.dt, &poss.position, &mprops.local_mprops.local_com); bodies.set_internal(handle.0, new_vels); bodies.set_internal(handle.0, new_poss); diff --git a/src/dynamics/solver/joint_constraint/ball_position_constraint.rs b/src/dynamics/solver/joint_constraint/ball_position_constraint.rs index 159cc77..0227960 100644 --- a/src/dynamics/solver/joint_constraint/ball_position_constraint.rs +++ b/src/dynamics/solver/joint_constraint/ball_position_constraint.rs @@ -34,8 +34,8 @@ impl BallPositionConstraint { let (mprops2, ids2) = rb2; Self { - local_com1: mprops1.mass_properties.local_com, - local_com2: mprops2.mass_properties.local_com, + local_com1: mprops1.local_mprops.local_com, + local_com2: mprops2.local_mprops.local_com, im1: mprops1.effective_inv_mass, im2: mprops2.effective_inv_mass, ii1: mprops1.effective_world_inv_inertia_sqrt.squared(), @@ -131,7 +131,7 @@ impl BallPositionGroundConstraint { ii2: mprops2.effective_world_inv_inertia_sqrt.squared(), local_anchor2: cparams.local_anchor1, position2: ids2.active_set_offset, - local_com2: mprops2.mass_properties.local_com, + local_com2: mprops2.local_mprops.local_com, } } else { Self { @@ -140,7 +140,7 @@ impl BallPositionGroundConstraint { ii2: mprops2.effective_world_inv_inertia_sqrt.squared(), local_anchor2: cparams.local_anchor2, position2: ids2.active_set_offset, - local_com2: mprops2.mass_properties.local_com, + local_com2: mprops2.local_mprops.local_com, } } } diff --git a/src/dynamics/solver/joint_constraint/ball_position_constraint_wide.rs b/src/dynamics/solver/joint_constraint/ball_position_constraint_wide.rs index 6b00639..ea462ed 100644 --- a/src/dynamics/solver/joint_constraint/ball_position_constraint_wide.rs +++ b/src/dynamics/solver/joint_constraint/ball_position_constraint_wide.rs @@ -40,8 +40,8 @@ impl WBallPositionConstraint { let (mprops1, ids1) = rbs1; let (mprops2, ids2) = rbs2; - let local_com1 = Point::from(gather![|ii| mprops1[ii].mass_properties.local_com]); - let local_com2 = Point::from(gather![|ii| mprops2[ii].mass_properties.local_com]); + let local_com1 = Point::from(gather![|ii| mprops1[ii].local_mprops.local_com]); + let local_com2 = Point::from(gather![|ii| mprops2[ii].local_mprops.local_com]); let im1 = SimdReal::from(gather![|ii| mprops1[ii].effective_inv_mass]); let im2 = SimdReal::from(gather![|ii| mprops2[ii].effective_inv_mass]); let ii1 = AngularInertia::<SimdReal>::from(gather![ @@ -169,7 +169,7 @@ impl WBallPositionGroundConstraint { cparams[ii].local_anchor2 }]); let position2 = gather![|ii| ids2[ii].active_set_offset]; - let local_com2 = Point::from(gather![|ii| mprops2[ii].mass_properties.local_com]); + let local_com2 = Point::from(gather![|ii| mprops2[ii].local_mprops.local_com]); Self { anchor1, diff --git a/src/dynamics/solver/joint_constraint/fixed_position_constraint.rs b/src/dynamics/solver/joint_constraint/fixed_position_constraint.rs index f8945c3..3ab13f7 100644 --- a/src/dynamics/solver/joint_constraint/fixed_position_constraint.rs +++ b/src/dynamics/solver/joint_constraint/fixed_position_constraint.rs @@ -46,8 +46,8 @@ impl FixedPositionConstraint { im2, ii1, ii2, - local_com1: mprops1.mass_properties.local_com, - local_com2: mprops2.mass_properties.local_com, + local_com1: mprops1.local_mprops.local_com, + local_com2: mprops2.local_mprops.local_com, lin_inv_lhs, ang_inv_lhs, } @@ -125,7 +125,7 @@ impl FixedPositionGroundConstraint { position2: ids2.active_set_offset, im2: mprops2.effective_inv_mass, ii2: mprops2.effective_world_inv_inertia_sqrt.squared(), - local_com2: mprops2.mass_properties.local_com, + local_com2: mprops2.local_mprops.local_com, impulse: 0.0, } } diff --git a/src/dynamics/solver/joint_constraint/generic_position_constraint.rs b/src/dynamics/solver/joint_constraint/generic_position_constraint.rs index 76901b1..a7b5ea0 100644 --- a/src/dynamics/solver/joint_constraint/generic_position_constraint.rs +++ b/src/dynamics/solver/joint_constraint/generic_position_constraint.rs @@ -41,8 +41,8 @@ impl GenericPositionConstraint { im2, ii1, ii2, - local_com1: rb1.mass_properties.local_com, - local_com2: rb2.mass_properties.local_com, + local_com1: rb1.local_mprops.local_com, + local_com2: rb2.local_mprops.local_com, joint: *joint, } } @@ -215,7 +215,7 @@ impl GenericPositionGroundConstraint { position2: rb2.active_set_offset, im2: rb2.effective_inv_mass, ii2: rb2.effective_world_inv_inertia_sqrt.squared(), - local_com2: rb2.mass_properties.local_com, + local_com2: rb2.local_mprops.local_com, joint: *joint, } } diff --git a/src/dynamics/solver/joint_constraint/revolute_position_constraint.rs b/src/dynamics/solver/joint_constraint/revolute_position_constraint.rs index 1b3e23a..731d0e2 100644 --- a/src/dynamics/solver/joint_constraint/revolute_position_constraint.rs +++ b/src/dynamics/solver/joint_constraint/revolute_position_constraint.rs @@ -51,8 +51,8 @@ impl RevolutePositionConstraint { ii1, ii2, ang_inv_lhs, - local_com1: mprops1.mass_properties.local_com, - local_com2: mprops2.mass_properties.local_com, + local_com1: mprops1.local_mprops.local_com, + local_com2: mprops2.local_mprops.local_com, local_anchor1: cparams.local_anchor1, local_anchor2: cparams.local_anchor2, local_axis1: cparams.local_axis1, @@ -183,7 +183,7 @@ impl RevolutePositionGroundConstraint { local_anchor2, im2: mprops2.effective_inv_mass, ii2: mprops2.effective_world_inv_inertia_sqrt.squared(), - local_com2: mprops2.mass_properties.local_com, + local_com2: mprops2.local_mprops.local_com, axis1, local_axis2, position2: ids2.active_set_offset, diff --git a/src/dynamics/solver/parallel_island_solver.rs b/src/dynamics/solver/parallel_island_solver.rs index 9d565c1..e12e7af 100644 --- a/src/dynamics/solver/parallel_island_solver.rs +++ b/src/dynamics/solver/parallel_island_solver.rs @@ -392,7 +392,7 @@ impl ParallelIslandSolver { let new_rb_vels = new_rb_vels.apply_damping(params.dt, rb_damping); new_rb_pos.next_position = - new_rb_vels.integrate(params.dt, &rb_pos.position, &rb_mprops.mass_properties.local_com); + new_rb_vels.integrate(params.dt, &rb_pos.position, &rb_mprops.local_mprops.local_com); bodies.set_internal(handle.0, new_rb_vels); bodies.set_internal(handle.0, new_rb_pos); |
