aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCrozet Sébastien <developer@crozet.re>2021-01-20 16:33:42 +0100
committerCrozet Sébastien <developer@crozet.re>2021-01-20 16:33:42 +0100
commit0ade350b5f4b6e7c0c4116e1f4f2b30ab86b7e52 (patch)
treecd97339b03d01378e4da5b2f60a8b78f2dc267d1
parent28b7866aee68ca844406bea4761d630a7913188d (diff)
downloadrapier-0ade350b5f4b6e7c0c4116e1f4f2b30ab86b7e52.tar.gz
rapier-0ade350b5f4b6e7c0c4116e1f4f2b30ab86b7e52.tar.bz2
rapier-0ade350b5f4b6e7c0c4116e1f4f2b30ab86b7e52.zip
Use newtypes for collider, rigid-body and joint handles.
-rw-r--r--examples2d/trimesh2.rs6
-rw-r--r--src/dynamics/joint/joint_set.rs65
-rw-r--r--src/dynamics/rigid_body.rs4
-rw-r--r--src/dynamics/rigid_body_set.rs121
-rw-r--r--src/dynamics/solver/parallel_island_solver.rs4
-rw-r--r--src/geometry/collider.rs6
-rw-r--r--src/geometry/collider_set.rs60
-rw-r--r--src/geometry/contact_pair.rs7
-rw-r--r--src/geometry/interaction_graph.rs72
-rw-r--r--src/geometry/narrow_phase.rs46
-rw-r--r--src/utils.rs8
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