diff options
| author | Crozet Sébastien <developer@crozet.re> | 2021-01-20 16:33:42 +0100 |
|---|---|---|
| committer | Crozet Sébastien <developer@crozet.re> | 2021-01-20 16:33:42 +0100 |
| commit | 0ade350b5f4b6e7c0c4116e1f4f2b30ab86b7e52 (patch) | |
| tree | cd97339b03d01378e4da5b2f60a8b78f2dc267d1 | |
| parent | 28b7866aee68ca844406bea4761d630a7913188d (diff) | |
| download | rapier-0ade350b5f4b6e7c0c4116e1f4f2b30ab86b7e52.tar.gz rapier-0ade350b5f4b6e7c0c4116e1f4f2b30ab86b7e52.tar.bz2 rapier-0ade350b5f4b6e7c0c4116e1f4f2b30ab86b7e52.zip | |
Use newtypes for collider, rigid-body and joint handles.
| -rw-r--r-- | examples2d/trimesh2.rs | 6 | ||||
| -rw-r--r-- | src/dynamics/joint/joint_set.rs | 65 | ||||
| -rw-r--r-- | src/dynamics/rigid_body.rs | 4 | ||||
| -rw-r--r-- | src/dynamics/rigid_body_set.rs | 121 | ||||
| -rw-r--r-- | src/dynamics/solver/parallel_island_solver.rs | 4 | ||||
| -rw-r--r-- | src/geometry/collider.rs | 6 | ||||
| -rw-r--r-- | src/geometry/collider_set.rs | 60 | ||||
| -rw-r--r-- | src/geometry/contact_pair.rs | 7 | ||||
| -rw-r--r-- | src/geometry/interaction_graph.rs | 72 | ||||
| -rw-r--r-- | src/geometry/narrow_phase.rs | 46 | ||||
| -rw-r--r-- | src/utils.rs | 8 |
11 files changed, 224 insertions, 175 deletions
diff --git a/examples2d/trimesh2.rs b/examples2d/trimesh2.rs index 3176861..d77d841 100644 --- a/examples2d/trimesh2.rs +++ b/examples2d/trimesh2.rs @@ -79,11 +79,7 @@ pub fn init_world(testbed: &mut Testbed) { transform.get_scale().1 as f32 * 0.2, ); - let indices: Vec<_> = mesh - .indices - .chunks(3) - .map(|v| Point3::new(v[0], v[1], v[2])) - .collect(); + let indices: Vec<_> = mesh.indices.chunks(3).map(|v| [v[0], v[1], v[2]]).collect(); let vertices: Vec<_> = mesh .vertices .iter() diff --git a/src/dynamics/joint/joint_set.rs b/src/dynamics/joint/joint_set.rs index 5144d97..50c88a2 100644 --- a/src/dynamics/joint/joint_set.rs +++ b/src/dynamics/joint/joint_set.rs @@ -1,11 +1,34 @@ use super::Joint; use crate::geometry::{InteractionGraph, RigidBodyGraphIndex, TemporaryInteractionIndex}; -use crate::data::arena::{Arena, Index}; +use crate::data::arena::Arena; use crate::dynamics::{JointParams, RigidBodyHandle, RigidBodySet}; /// The unique identifier of a joint added to the joint set. -pub type JointHandle = Index; +/// The unique identifier of a collider added to a collider set. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +#[repr(transparent)] +pub struct JointHandle(pub(crate) crate::data::arena::Index); + +impl JointHandle { + pub fn into_raw_parts(self) -> (usize, u64) { + self.0.into_raw_parts() + } + + pub fn from_raw_parts(id: usize, generation: u64) -> Self { + Self(crate::data::arena::Index::from_raw_parts(id, generation)) + } + + /// An always-invalid joint handle. + pub fn invalid() -> Self { + Self(crate::data::arena::Index::from_raw_parts( + crate::INVALID_USIZE, + crate::INVALID_U64, + )) + } +} + pub(crate) type JointIndex = usize; pub(crate) type JointGraphEdge = crate::data::graph::Edge<Joint>; @@ -13,7 +36,7 @@ pub(crate) type JointGraphEdge = crate::data::graph::Edge<Joint>; /// A set of joints that can be handled by a physics `World`. pub struct JointSet { joint_ids: Arena<TemporaryInteractionIndex>, // Map joint handles to edge ids on the graph. - joint_graph: InteractionGraph<Joint>, + joint_graph: InteractionGraph<RigidBodyHandle, Joint>, } impl JointSet { @@ -25,29 +48,24 @@ impl JointSet { } } - /// An always-invalid joint handle. - pub fn invalid_handle() -> JointHandle { - JointHandle::from_raw_parts(crate::INVALID_USIZE, crate::INVALID_U64) - } - /// The number of joints on this set. pub fn len(&self) -> usize { self.joint_graph.graph.edges.len() } /// Retrieve the joint graph where edges are joints and nodes are rigid body handles. - pub fn joint_graph(&self) -> &InteractionGraph<Joint> { + pub fn joint_graph(&self) -> &InteractionGraph<RigidBodyHandle, Joint> { &self.joint_graph } /// Is the given joint handle valid? pub fn contains(&self, handle: JointHandle) -> bool { - self.joint_ids.contains(handle) + self.joint_ids.contains(handle.0) } /// Gets the joint with the given handle. pub fn get(&self, handle: JointHandle) -> Option<&Joint> { - let id = self.joint_ids.get(handle)?; + let id = self.joint_ids.get(handle.0)?; self.joint_graph.graph.edge_weight(*id) } @@ -62,7 +80,10 @@ impl JointSet { /// suffer form the ABA problem. pub fn get_unknown_gen(&self, i: usize) -> Option<(&Joint, JointHandle)> { let (id, handle) = self.joint_ids.get_unknown_gen(i)?; - Some((self.joint_graph.graph.edge_weight(*id)?, handle)) + Some(( + self.joint_graph.graph.edge_weight(*id)?, + JointHandle(handle), + )) } /// Iterates through all the joint on this set. @@ -117,7 +138,7 @@ impl JointSet { let joint = Joint { body1, body2, - handle, + handle: JointHandle(handle), #[cfg(feature = "parallel")] constraint_index: 0, #[cfg(feature = "parallel")] @@ -133,11 +154,13 @@ impl JointSet { // NOTE: the body won't have a graph index if it does not // have any joint attached. - if !InteractionGraph::<Joint>::is_graph_index_valid(rb1.joint_graph_index) { + if !InteractionGraph::<RigidBodyHandle, Joint>::is_graph_index_valid(rb1.joint_graph_index) + { rb1.joint_graph_index = self.joint_graph.graph.add_node(joint.body1); } - if !InteractionGraph::<Joint>::is_graph_index_valid(rb2.joint_graph_index) { + if !InteractionGraph::<RigidBodyHandle, Joint>::is_graph_index_valid(rb2.joint_graph_index) + { rb2.joint_graph_index = self.joint_graph.graph.add_node(joint.body2); } @@ -146,7 +169,7 @@ impl JointSet { .add_edge(rb1.joint_graph_index, rb2.joint_graph_index, joint); self.joint_ids[handle] = id; - handle + JointHandle(handle) } /// Retrieve all the joints happening between two active bodies. @@ -191,7 +214,7 @@ impl JointSet { bodies: &mut RigidBodySet, wake_up: bool, ) -> Option<Joint> { - let id = self.joint_ids.remove(handle)?; + let id = self.joint_ids.remove(handle.0)?; let endpoints = self.joint_graph.graph.edge_endpoints(id)?; if wake_up { @@ -207,7 +230,7 @@ impl JointSet { let removed_joint = self.joint_graph.graph.remove_edge(id); if let Some(edge) = self.joint_graph.graph.edge_weight(id) { - self.joint_ids[edge.handle] = id; + self.joint_ids[edge.handle.0] = id; } removed_joint @@ -218,7 +241,7 @@ impl JointSet { deleted_id: RigidBodyGraphIndex, bodies: &mut RigidBodySet, ) { - if InteractionGraph::<()>::is_graph_index_valid(deleted_id) { + if InteractionGraph::<(), ()>::is_graph_index_valid(deleted_id) { // We have to delete each joint one by one in order to: // - Wake-up the attached bodies. // - Update our Handle -> graph edge mapping. @@ -229,12 +252,12 @@ impl JointSet { .map(|e| (e.0, e.1, e.2.handle)) .collect(); for (h1, h2, to_delete_handle) in to_delete { - let to_delete_edge_id = self.joint_ids.remove(to_delete_handle).unwrap(); + let to_delete_edge_id = self.joint_ids.remove(to_delete_handle.0).unwrap(); self.joint_graph.graph.remove_edge(to_delete_edge_id); // Update the id of the edge which took the place of the deleted one. if let Some(j) = self.joint_graph.graph.edge_weight_mut(to_delete_edge_id) { - self.joint_ids[j.handle] = to_delete_edge_id; + self.joint_ids[j.handle.0] = to_delete_edge_id; } // Wake up the attached bodies. diff --git a/src/dynamics/rigid_body.rs b/src/dynamics/rigid_body.rs index 1574100..20d04b0 100644 --- a/src/dynamics/rigid_body.rs +++ b/src/dynamics/rigid_body.rs @@ -108,7 +108,7 @@ impl RigidBody { angular_damping: 0.0, colliders: Vec::new(), activation: ActivationStatus::new_active(), - joint_graph_index: InteractionGraph::<()>::invalid_graph_index(), + joint_graph_index: InteractionGraph::<(), ()>::invalid_graph_index(), active_island_id: 0, active_set_id: 0, active_set_offset: 0, @@ -122,7 +122,7 @@ impl RigidBody { pub(crate) fn reset_internal_references(&mut self) { self.colliders = Vec::new(); - self.joint_graph_index = InteractionGraph::<()>::invalid_graph_index(); + self.joint_graph_index = InteractionGraph::<(), ()>::invalid_graph_index(); self.active_island_id = 0; self.active_set_id = 0; self.active_set_offset = 0; diff --git a/src/dynamics/rigid_body_set.rs b/src/dynamics/rigid_body_set.rs index c1c9003..9cb23ee 100644 --- a/src/dynamics/rigid_body_set.rs +++ b/src/dynamics/rigid_body_set.rs @@ -3,11 +3,43 @@ use rayon::prelude::*; use crate::data::arena::Arena; use crate::dynamics::{Joint, JointSet, RigidBody, RigidBodyChanges}; -use crate::geometry::{ColliderHandle, ColliderSet, InteractionGraph, NarrowPhase}; +use crate::geometry::{ColliderSet, InteractionGraph, NarrowPhase}; +use cdl::partitioning::IndexedData; use std::ops::{Index, IndexMut}; /// The unique handle of a rigid body added to a `RigidBodySet`. -pub type RigidBodyHandle = crate::data::arena::Index; +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +#[repr(transparent)] +pub struct RigidBodyHandle(pub(crate) crate::data::arena::Index); + +impl RigidBodyHandle { + pub fn into_raw_parts(self) -> (usize, u64) { + self.0.into_raw_parts() + } + + pub fn from_raw_parts(id: usize, generation: u64) -> Self { + Self(crate::data::arena::Index::from_raw_parts(id, generation)) + } + + /// An always-invalid rigid-body handle. + pub fn invalid() -> Self { + Self(crate::data::arena::Index::from_raw_parts( + crate::INVALID_USIZE, + crate::INVALID_U64, + )) + } +} + +impl IndexedData for RigidBodyHandle { + fn default() -> Self { + Self(IndexedData::default()) + } + + fn index(&self) -> usize { + self.0.index() + } +} #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] @@ -66,11 +98,6 @@ impl RigidBodySet { } } - /// An always-invalid rigid-body handle. - pub fn invalid_handle() -> RigidBodyHandle { - RigidBodyHandle::from_raw_parts(crate::INVALID_USIZE, crate::INVALID_U64) - } - /// The number of rigid bodies on this set. pub fn len(&self) -> usize { self.bodies.len() @@ -78,7 +105,7 @@ impl RigidBodySet { /// Is the given body handle valid? pub fn contains(&self, handle: RigidBodyHandle) -> bool { - self.bodies.contains(handle) + self.bodies.contains(handle.0) } /// Insert a rigid body into this set and retrieve its handle. @@ -88,10 +115,10 @@ impl RigidBodySet { rb.reset_internal_references(); rb.changes.set(RigidBodyChanges::all(), true); - let handle = self.bodies.insert(rb); + let handle = RigidBodyHandle(self.bodies.insert(rb)); self.modified_bodies.push(handle); - let rb = &mut self.bodies[handle]; + let rb = &mut self.bodies[handle.0]; if rb.is_kinematic() { rb.active_set_id = self.active_kinematic_set.len(); @@ -108,7 +135,7 @@ impl RigidBodySet { colliders: &mut ColliderSet, joints: &mut JointSet, ) -> Option<RigidBody> { - let rb = self.bodies.remove(handle)?; + let rb = self.bodies.remove(handle.0)?; /* * Update active sets. */ @@ -119,7 +146,7 @@ impl RigidBodySet { active_set.swap_remove(rb.active_set_id); if let Some(replacement) = active_set.get(rb.active_set_id) { - self.bodies[*replacement].active_set_id = rb.active_set_id; + self.bodies[replacement.0].active_set_id = rb.active_set_id; } } } @@ -148,7 +175,7 @@ impl RigidBodySet { /// If `strong` is `true` then it is assured that the rigid-body will /// remain awake during multiple subsequent timesteps. pub fn wake_up(&mut self, handle: RigidBodyHandle, strong: bool) { - if let Some(rb) = self.bodies.get_mut(handle) { + if let Some(rb) = self.bodies.get_mut(handle.0) { // TODO: what about kinematic bodies? if rb.is_dynamic() { rb.wake_up(strong); @@ -171,7 +198,9 @@ impl RigidBodySet { /// Using this is discouraged in favor of `self.get(handle)` which does not /// suffer form the ABA problem. pub fn get_unknown_gen(&self, i: usize) -> Option<(&RigidBody, RigidBodyHandle)> { - self.bodies.get_unknown_gen(i) + self.bodies + .get_unknown_gen(i) + .map(|(b, h)| (b, RigidBodyHandle(h))) } /// Gets a mutable reference to the rigid-body with the given handle without a known generation. @@ -187,19 +216,19 @@ impl RigidBodySet { let result = self.bodies.get_unknown_gen_mut(i)?; if !self.modified_all_bodies && !result.0.changes.contains(RigidBodyChanges::MODIFIED) { result.0.changes = RigidBodyChanges::MODIFIED; - self.modified_bodies.push(result.1); + self.modified_bodies.push(RigidBodyHandle(result.1)); } - Some(result) + Some((result.0, RigidBodyHandle(result.1))) } /// Gets the rigid-body with the given handle. pub fn get(&self, handle: RigidBodyHandle) -> Option<&RigidBody> { - self.bodies.get(handle) + self.bodies.get(handle.0) } /// Gets a mutable reference to the rigid-body with the given handle. pub fn get_mut(&mut self, handle: RigidBodyHandle) -> Option<&mut RigidBody> { - let result = self.bodies.get_mut(handle)?; + let result = self.bodies.get_mut(handle.0)?; if !self.modified_all_bodies && !result.changes.contains(RigidBodyChanges::MODIFIED) { result.changes = RigidBodyChanges::MODIFIED; self.modified_bodies.push(handle); @@ -208,7 +237,7 @@ impl RigidBodySet { } pub(crate) fn get_mut_internal(&mut self, handle: RigidBodyHandle) -> Option<&mut RigidBody> { - self.bodies.get_mut(handle) + self.bodies.get_mut(handle.0) } pub(crate) fn get2_mut_internal( @@ -216,19 +245,19 @@ impl RigidBodySet { h1: RigidBodyHandle, h2: RigidBodyHandle, ) -> (Option<&mut RigidBody>, Option<&mut RigidBody>) { - self.bodies.get2_mut(h1, h2) + self.bodies.get2_mut(h1.0, h2.0) } /// Iterates through all the rigid-bodies on this set. pub fn iter(&self) -> impl Iterator<Item = (RigidBodyHandle, &RigidBody)> { - self.bodies.iter() + self.bodies.iter().map(|(h, b)| (RigidBodyHandle(h), b)) } /// Iterates mutably through all the rigid-bodies on this set. pub fn iter_mut(&mut self) -> impl Iterator<Item = (RigidBodyHandle, &mut RigidBody)> { self.modified_bodies.clear(); self.modified_all_bodies = true; - self.bodies.iter_mut() + self.bodies.iter_mut().map(|(h, b)| (RigidBodyHandle(h), b)) } /// Iter through all the active kinematic rigid-bodies on this set. @@ -238,7 +267,7 @@ impl RigidBodySet { let bodies: &'a _ = &self.bodies; self.active_kinematic_set .iter() - .filter_map(move |h| Some((*h, bodies.get(*h)?))) + .filter_map(move |h| Some((*h, bodies.get(h.0)?))) } /// Iter through all the active dynamic rigid-bodies on this set. @@ -248,7 +277,7 @@ impl RigidBodySet { let bodies: &'a _ = &self.bodies; self.active_dynamic_set .iter() - .filter_map(move |h| Some((*h, bodies.get(*h)?))) + .filter_map(move |h| Some((*h, bodies.get(h.0)?))) } #[cfg(not(feature = "parallel"))] @@ -260,7 +289,7 @@ impl RigidBodySet { let bodies: &'a _ = &self.bodies; self.active_dynamic_set[island_range] .iter() - .filter_map(move |h| Some((*h, bodies.get(*h)?))) + .filter_map(move |h| Some((*h, bodies.get(h.0)?))) } #[inline(always)] @@ -269,13 +298,13 @@ impl RigidBodySet { mut f: impl FnMut(RigidBodyHandle, &mut RigidBody), ) { for handle in &self.active_dynamic_set { - if let Some(rb) = self.bodies.get_mut(*handle) { + if let Some(rb) = self.bodies.get_mut(handle.0) { f(*handle, rb) } } for handle in &self.active_kinematic_set { - if let Some(rb) = self.bodies.get_mut(*handle) { + if let Some(rb) = self.bodies.get_mut(handle.0) { f(*handle, rb) } } @@ -287,7 +316,7 @@ impl RigidBodySet { mut f: impl FnMut(RigidBodyHandle, &mut RigidBody), ) { for handle in &self.active_dynamic_set { - if let Some(rb) = self.bodies.get_mut(*handle) { + if let Some(rb) = self.bodies.get_mut(handle.0) { f(*handle, rb) } } @@ -299,7 +328,7 @@ impl RigidBodySet { mut f: impl FnMut(RigidBodyHandle, &mut RigidBody), ) { for handle in &self.active_kinematic_set { - if let Some(rb) = self.bodies.get_mut(*handle) { + if let Some(rb) = self.bodies.get_mut(handle.0) { f(*handle, rb) } } @@ -314,7 +343,7 @@ impl RigidBodySet { ) { let island_range = self.active_islands[island_id]..self.active_islands[island_id + 1]; for handle in &self.active_dynamic_set[island_range] { - if let Some(rb) = self.bodies.get_mut(*handle) { + if let Some(rb) = self.bodies.get_mut(handle.0) { f(*handle, rb) } } @@ -338,7 +367,7 @@ impl RigidBodySet { || bodies.load(Ordering::Relaxed), |bodies, handle| { let bodies: &mut Arena<RigidBody> = unsafe { std::mem::transmute(*bodies) }; - if let Some(rb) = bodies.get_mut(*handle) { + if let Some(rb) = bodies.get_mut(handle.0) { f(*handle, rb) } }, @@ -401,7 +430,7 @@ impl RigidBodySet { for (handle, rb) in self.bodies.iter_mut() { Self::maintain_one( colliders, - handle, + RigidBodyHandle(handle), rb, &mut self.modified_inactive_set, &mut self.active_kinematic_set, @@ -413,7 +442,7 @@ impl RigidBodySet { self.modified_all_bodies = false; } else { for handle in self.modified_bodies.drain(..) { - if let Some(rb) = self.bodies.get_mut(handle) { + if let Some(rb) = self.bodies.get_mut(handle.0) { Self::maintain_one( colliders, handle, @@ -431,7 +460,7 @@ impl RigidBodySet { &mut self, colliders: &ColliderSet, narrow_phase: &NarrowPhase, - joint_graph: &InteractionGraph<Joint>, + joint_graph: &InteractionGraph<RigidBodyHandle, Joint>, min_island_size: usize, ) { assert!( @@ -451,7 +480,7 @@ impl RigidBodySet { // does not seem to affect performances nor stability. However it makes // debugging slightly nicer so we keep this rev. for h in self.active_dynamic_set.drain(..).rev() { - let rb = &mut self.bodies[h]; + let rb = &mut self.bodies[h.0]; rb.update_energy(); if rb.activation.energy <= rb.activation.threshold { // Mark them as sleeping for now. This will @@ -466,18 +495,18 @@ impl RigidBodySet { // Read all the contacts and push objects touching touching this rigid-body. #[inline(always)] - fn push_contacting_colliders( + fn push_contacting_bodies( rb: &RigidBody, colliders: &ColliderSet, narrow_phase: &NarrowPhase, - stack: &mut Vec<ColliderHandle>, + stack: &mut Vec<RigidBodyHandle>, ) { for collider_handle in &rb.colliders { 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::other_handle( + let other = crate::utils::select_other( (inter.0, inter.1), *collider_handle, ); @@ -494,7 +523,7 @@ impl RigidBodySet { // Now iterate on all active kinematic bodies and push all the bodies // touching them to the stack so they can be woken up. for h in self.active_kinematic_set.iter() { - let rb = &self.bodies[*h]; + let rb = &self.bodies[h.0]; if !rb.is_moving() { // If the kinematic body does not move, it does not have @@ -502,7 +531,7 @@ impl RigidBodySet { continue; } - push_contacting_colliders(rb, colliders, narrow_phase, &mut self.stack); + push_contacting_bodies(rb, colliders, narrow_phase, &mut self.stack); } // println!("Selection: {}", instant::now() - t); @@ -517,7 +546,7 @@ impl RigidBodySet { let mut island_marker = self.stack.len().max(1) - 1; while let Some(handle) = self.stack.pop() { - let rb = &mut self.bodies[handle]; + let rb = &mut self.bodies[handle.0]; if rb.active_set_timestamp == self.active_set_timestamp || !rb.is_dynamic() { // We already visited this body and its neighbors. @@ -545,10 +574,10 @@ impl RigidBodySet { // Transmit the active state to all the rigid-bodies with colliders // in contact or joined with this collider. - push_contacting_colliders(rb, colliders, narrow_phase, &mut self.stack); + push_contacting_bodies(rb, colliders, narrow_phase, &mut self.stack); for inter in joint_graph.interactions_with(rb.joint_graph_index) { - let other = crate::utils::other_handle((inter.0, inter.1), handle); + let other = crate::utils::select_other((inter.0, inter.1), handle); self.stack.push(other); } } @@ -563,7 +592,7 @@ impl RigidBodySet { // Actually put to sleep bodies which have not been detected as awake. // let t = instant::now(); for h in &self.can_sleep { - let b = &mut self.bodies[*h]; + let b = &mut self.bodies[h.0]; if b.activation.sleeping { b.sleep(); } @@ -576,12 +605,12 @@ impl Index<RigidBodyHandle> for RigidBodySet { type Output = RigidBody; fn index(&self, index: RigidBodyHandle) -> &RigidBody { - &self.bodies[index] + &self.bodies[index.0] } } impl IndexMut<RigidBodyHandle> for RigidBodySet { fn index_mut(&mut self, index: RigidBodyHandle) -> &mut RigidBody { - &mut self.bodies[index] + &mut self.bodies[index.0] } } diff --git a/src/dynamics/solver/parallel_island_solver.rs b/src/dynamics/solver/parallel_island_solver.rs index ea5ed23..9a02330 100644 --- a/src/dynamics/solver/parallel_island_solver.rs +++ b/src/dynamics/solver/parallel_island_solver.rs @@ -247,7 +247,7 @@ impl ParallelIslandSolver { concurrent_loop! { let batch_size = thread.batch_size; for handle in active_bodies[thread.body_integration_index, thread.num_integrated_bodies] { - let rb = &mut bodies[*handle]; + let rb = &mut bodies[handle.0]; let dvel = mj_lambdas[rb.active_set_offset]; rb.linvel += dvel.linear; rb.angvel += rb.world_inv_inertia_sqrt.transform_vector(dvel.angular); @@ -272,7 +272,7 @@ impl ParallelIslandSolver { concurrent_loop! { let batch_size = thread.batch_size; for handle in active_bodies[thread.position_writeback_index] { - let rb = &mut bodies[*handle]; + let rb = &mut bodies[handle.0]; rb.set_position_internal(positions[rb.active_set_offset]); } } diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index 96fcbf9..a4de108 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -1,4 +1,4 @@ -use crate::dynamics::{MassProperties, RigidBodyHandle, RigidBodySet}; +use crate::dynamics::{MassProperties, RigidBodyHandle}; use crate::geometry::InteractionGroups; use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector}; use cdl::bounding_volume::AABB; @@ -333,7 +333,7 @@ pub struct Collider { impl Collider { pub(crate) fn reset_internal_references(&mut self) { - self.parent = RigidBodySet::invalid_handle(); + self.parent = RigidBodyHandle::invalid(); self.proxy_index = crate::INVALID_USIZE; } @@ -708,7 +708,7 @@ impl ColliderBuilder { restitution: self.restitution, delta: self.delta, is_sensor: self.is_sensor, - parent: RigidBodySet::invalid_handle(), + parent: RigidBodyHandle::invalid(), position: Isometry::identity(), predicted_position: Isometry::identity(), proxy_index: crate::INVALID_USIZE, diff --git a/src/geometry/collider_set.rs b/src/geometry/collider_set.rs index eb09322..60ce007 100644 --- a/src/geometry/collider_set.rs +++ b/src/geometry/collider_set.rs @@ -2,10 +2,42 @@ use crate::data::arena::Arena; use crate::data::pubsub::PubSub; use crate::dynamics::{RigidBodyHandle, RigidBodySet}; use crate::geometry::Collider; +use cdl::partitioning::IndexedData; use std::ops::{Index, IndexMut}; /// The unique identifier of a collider added to a collider set. -pub type ColliderHandle = crate::data::arena::Index; +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] +#[repr(transparent)] +pub struct ColliderHandle(pub(crate) crate::data::arena::Index); + +impl ColliderHandle { + pub fn into_raw_parts(self) -> (usize, u64) { + self.0.into_raw_parts() + } + + pub fn from_raw_parts(id: usize, generation: u64) -> Self { + Self(crate::data::arena::Index::from_raw_parts(id, generation)) + } + + /// An always-invalid collider handle. + pub fn invalid() -> Self { + Self(crate::data::arena::Index::from_raw_parts( + crate::INVALID_USIZE, + crate::INVALID_U64, + )) + } +} + +impl IndexedData for ColliderHandle { + fn default() -> Self { + Self(IndexedData::default()) + } + + fn index(&self) -> usize { + self.0.index() + } +} #[derive(Copy, Clone, Debug)] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] @@ -38,7 +70,7 @@ impl ColliderSet { /// Iterate through all the colliders on this set. pub fn iter(&self) -> impl ExactSizeIterator<Item = (ColliderHandle, &Collider)> { - self.colliders.iter() + self.colliders.iter().map(|(h, c)| (ColliderHandle(h), c)) } /// The number of colliders on this set. @@ -48,7 +80,7 @@ impl ColliderSet { /// Is this collider handle valid? pub fn contains(&self, handle: ColliderHandle) -> bool { - self.colliders.contains(handle) + self.colliders.contains(handle.0) } /// Inserts a new collider to this set and retrieve its handle. @@ -71,8 +103,8 @@ impl ColliderSet { .expect("Parent rigid body not found."); coll.position = parent.position * coll.delta; coll.predicted_position = parent.predicted_position * coll.delta; - let handle = self.colliders.insert(coll); - let coll = self.colliders.get(handle).unwrap(); + let handle = ColliderHandle(self.colliders.insert(coll)); + let coll = self.colliders.get(handle.0).unwrap(); parent.add_collider(handle, &coll); handle } @@ -87,7 +119,7 @@ impl ColliderSet { bodies: &mut RigidBodySet, wake_up: bool, ) -> Option<Collider> { - let collider = self.colliders.remove(handle)?; + let collider = self.colliders.remove(handle.0)?; /* * Delete the collider from its parent body. @@ -125,7 +157,9 @@ impl ColliderSet { /// Using this is discouraged in favor of `self.get(handle)` which does not /// suffer form the ABA problem. pub fn get_unknown_gen(&self, i: usize) -> Option<(&Collider, ColliderHandle)> { - self.colliders.get_unknown_gen(i) + self.colliders + .get_unknown_gen(i) + .map(|(c, h)| (c, ColliderHandle(h))) } /// Gets a mutable reference to the collider with the given handle without a known generation. @@ -138,17 +172,19 @@ impl ColliderSet { /// Using this is discouraged in favor of `self.get_mut(handle)` which does not /// suffer form the ABA problem. pub fn get_unknown_gen_mut(&mut self, i: usize) -> Option<(&mut Collider, ColliderHandle)> { - self.colliders.get_unknown_gen_mut(i) + self.colliders + .get_unknown_gen_mut(i) + .map(|(c, h)| (c, ColliderHandle(h))) } /// Get the collider with the given handle. pub fn get(&self, handle: ColliderHandle) -> Option<&Collider> { - self.colliders.get(handle) + self.colliders.get(handle.0) } /// Gets a mutable reference to the collider with the given handle. pub fn get_mut(&mut self, handle: ColliderHandle) -> Option<&mut Collider> { - self.colliders.get_mut(handle) + self.colliders.get_mut(handle.0) } // pub(crate) fn get2_mut_internal( @@ -177,12 +213,12 @@ impl Index<ColliderHandle> for ColliderSet { type Output = Collider; fn index(&self, index: ColliderHandle) -> &Collider { - &self.colliders[index] + &self.colliders[index.0] } } impl IndexMut<ColliderHandle> for ColliderSet { fn index_mut(&mut self, index: ColliderHandle) -> &mut Collider { - &mut self.colliders[index] + &mut self.colliders[index.0] } } diff --git a/src/geometry/contact_pair.rs b/src/geometry/contact_pair.rs index 546b127..bd18a5d 100644 --- a/src/geometry/contact_pair.rs +++ b/src/geometry/contact_pair.rs @@ -1,4 +1,4 @@ -use crate::dynamics::{BodyPair, RigidBodySet}; +use crate::dynamics::{BodyPair, RigidBodyHandle}; use crate::geometry::{ColliderPair, ContactManifold}; use crate::math::{Point, Real, Vector}; use cdl::query::ContactManifoldsWorkspace; @@ -113,10 +113,7 @@ pub struct SolverContact { impl Default for ContactManifoldData { fn default() -> Self { Self::new( - BodyPair::new( - RigidBodySet::invalid_handle(), - RigidBodySet::invalid_handle(), - ), + BodyPair::new(RigidBodyHandle::invalid(), RigidBodyHandle::invalid()), SolverFlags::empty(), ) } diff --git a/src/geometry/interaction_graph.rs b/src/geometry/interaction_graph.rs index 54a19ce..657050c 100644 --- a/src/geometry/interaction_graph.rs +++ b/src/geometry/interaction_graph.rs @@ -1,5 +1,4 @@ use crate::data::graph::{Direction, EdgeIndex, Graph, NodeIndex}; -use crate::geometry::ColliderHandle; /// Index of a node of the interaction graph. pub type ColliderGraphIndex = NodeIndex; @@ -11,11 +10,11 @@ pub type TemporaryInteractionIndex = EdgeIndex; /// A graph where nodes are collision objects and edges are contact or proximity algorithms. #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[derive(Clone)] -pub struct InteractionGraph<T> { - pub(crate) graph: Graph<ColliderHandle, T>, +pub struct InteractionGraph<N, E> { + pub(crate) graph: Graph<N, E>, } -impl<T> InteractionGraph<T> { +impl<N: Copy, E> InteractionGraph<N, E> { /// Creates a new empty collection of collision objects. pub fn new() -> Self { InteractionGraph { @@ -24,7 +23,7 @@ impl<T> InteractionGraph<T> { } /// The underlying raw graph structure of this interaction graph. - pub fn raw_graph(&self) -> &Graph<ColliderHandle, T> { + pub fn raw_graph(&self) -> &Graph<N, E> { &self.graph } @@ -40,7 +39,7 @@ impl<T> InteractionGraph<T> { &mut self, index1: ColliderGraphIndex, index2: ColliderGraphIndex, - interaction: T, + interaction: E, ) -> TemporaryInteractionIndex { self.graph.add_edge(index1, index2, interaction) } @@ -49,7 +48,7 @@ impl<T> InteractionGraph<T> { &mut self, index1: ColliderGraphIndex, index2: ColliderGraph |
