aboutsummaryrefslogtreecommitdiff
path: root/src/dynamics/joint/joint_set.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/dynamics/joint/joint_set.rs')
-rw-r--r--src/dynamics/joint/joint_set.rs67
1 files changed, 46 insertions, 21 deletions
diff --git a/src/dynamics/joint/joint_set.rs b/src/dynamics/joint/joint_set.rs
index 5144d97..a87532a 100644
--- a/src/dynamics/joint/joint_set.rs
+++ b/src/dynamics/joint/joint_set.rs
@@ -1,11 +1,36 @@
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 {
+ /// Converts this handle into its (index, generation) components.
+ pub fn into_raw_parts(self) -> (usize, u64) {
+ self.0.into_raw_parts()
+ }
+
+ /// Reconstructs an handle from its (index, generation) components.
+ 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 +38,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 +50,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 +82,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 +140,7 @@ impl JointSet {
let joint = Joint {
body1,
body2,
- handle,
+ handle: JointHandle(handle),
#[cfg(feature = "parallel")]
constraint_index: 0,
#[cfg(feature = "parallel")]
@@ -133,11 +156,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 +171,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 +216,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 +232,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 +243,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 +254,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.