aboutsummaryrefslogtreecommitdiff
path: root/src/dynamics/joint
diff options
context:
space:
mode:
authorCrozet Sébastien <developer@crozet.re>2021-04-26 17:59:25 +0200
committerCrozet Sébastien <developer@crozet.re>2021-04-26 18:00:50 +0200
commitc32da78f2a6014c491aa3e975fb83ddb7c80610e (patch)
treeedd20f23270baee1577c486f78d825eb93ea0de0 /src/dynamics/joint
parentaaf80bfa872c6f29b248cab8eb5658ab0d73cb4a (diff)
downloadrapier-c32da78f2a6014c491aa3e975fb83ddb7c80610e.tar.gz
rapier-c32da78f2a6014c491aa3e975fb83ddb7c80610e.tar.bz2
rapier-c32da78f2a6014c491aa3e975fb83ddb7c80610e.zip
Split rigid-bodies and colliders into multiple components
Diffstat (limited to 'src/dynamics/joint')
-rw-r--r--src/dynamics/joint/joint_set.rs116
1 files changed, 68 insertions, 48 deletions
diff --git a/src/dynamics/joint/joint_set.rs b/src/dynamics/joint/joint_set.rs
index 2e4b394..8e4d9b8 100644
--- a/src/dynamics/joint/joint_set.rs
+++ b/src/dynamics/joint/joint_set.rs
@@ -2,31 +2,33 @@ use super::Joint;
use crate::geometry::{InteractionGraph, RigidBodyGraphIndex, TemporaryInteractionIndex};
use crate::data::arena::Arena;
-use crate::dynamics::{JointParams, RigidBodyHandle, RigidBodySet};
+use crate::data::{BundleSet, ComponentSet, ComponentSetMut};
+use crate::dynamics::{IslandManager, RigidBodyActivation, RigidBodyIds, RigidBodyType};
+use crate::dynamics::{JointParams, RigidBodyHandle};
/// The unique identifier of a joint added to the joint set.
/// 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);
+pub struct JointHandle(pub crate::data::arena::Index);
impl JointHandle {
/// Converts this handle into its (index, generation) components.
- pub fn into_raw_parts(self) -> (usize, u64) {
+ pub fn into_raw_parts(self) -> (u32, u32) {
self.0.into_raw_parts()
}
/// Reconstructs an handle from its (index, generation) components.
- pub fn from_raw_parts(id: usize, generation: u64) -> Self {
+ pub fn from_raw_parts(id: u32, generation: u32) -> 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,
+ crate::INVALID_U32,
+ crate::INVALID_U32,
))
}
}
@@ -157,7 +159,7 @@ impl JointSet {
/// Inserts a new joint into this set and retrieve its handle.
pub fn insert<J>(
&mut self,
- bodies: &mut RigidBodySet,
+ bodies: &mut impl ComponentSetMut<RigidBodyIds>,
body1: RigidBodyHandle,
body2: RigidBodyHandle,
joint_params: J,
@@ -177,57 +179,64 @@ impl JointSet {
params: joint_params.into(),
};
- let (rb1, rb2) = bodies.get2_mut_internal(joint.body1, joint.body2);
- let (rb1, rb2) = (
- rb1.expect("Attempt to attach a joint to a non-existing body."),
- rb2.expect("Attempt to attach a joint to a non-existing body."),
- );
+ let mut graph_index1 = bodies.index(joint.body1.0).joint_graph_index;
+ let mut graph_index2 = bodies.index(joint.body2.0).joint_graph_index;
// NOTE: the body won't have a graph index if it does not
// have any joint attached.
- 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::<RigidBodyHandle, Joint>::is_graph_index_valid(graph_index1) {
+ graph_index1 = self.joint_graph.graph.add_node(joint.body1);
+ bodies.map_mut_internal(joint.body1.0, |ids| ids.joint_graph_index = graph_index1);
}
- if !InteractionGraph::<RigidBodyHandle, Joint>::is_graph_index_valid(rb2.joint_graph_index)
- {
- rb2.joint_graph_index = self.joint_graph.graph.add_node(joint.body2);
+ if !InteractionGraph::<RigidBodyHandle, Joint>::is_graph_index_valid(graph_index2) {
+ graph_index2 = self.joint_graph.graph.add_node(joint.body2);
+ bodies.map_mut_internal(joint.body2.0, |ids| ids.joint_graph_index = graph_index2);
}
- let id = self
- .joint_graph
- .add_edge(rb1.joint_graph_index, rb2.joint_graph_index, joint);
-
- self.joint_ids[handle] = id;
+ self.joint_ids[handle] = self.joint_graph.add_edge(graph_index1, graph_index2, joint);
JointHandle(handle)
}
/// Retrieve all the joints happening between two active bodies.
// NOTE: this is very similar to the code from NarrowPhase::select_active_interactions.
- pub(crate) fn select_active_interactions(
+ pub(crate) fn select_active_interactions<Bodies>(
&self,
- bodies: &RigidBodySet,
+ islands: &IslandManager,
+ bodies: &Bodies,
out: &mut Vec<Vec<JointIndex>>,
- ) {
- for out_island in &mut out[..bodies.num_islands()] {
+ ) where
+ Bodies: ComponentSet<RigidBodyType>
+ + ComponentSet<RigidBodyActivation>
+ + ComponentSet<RigidBodyIds>,
+ {
+ for out_island in &mut out[..islands.num_islands()] {
out_island.clear();
}
// FIXME: don't iterate through all the interactions.
for (i, edge) in self.joint_graph.graph.edges.iter().enumerate() {
let joint = &edge.weight;
- let rb1 = &bodies[joint.body1];
- let rb2 = &bodies[joint.body2];
- if (rb1.is_dynamic() || rb2.is_dynamic())
- && (!rb1.is_dynamic() || !rb1.is_sleeping())
- && (!rb2.is_dynamic() || !rb2.is_sleeping())
+ let (status1, activation1, ids1): (
+ &RigidBodyType,
+ &RigidBodyActivation,
+ &RigidBodyIds,
+ ) = bodies.index_bundle(joint.body1.0);
+ let (status2, activation2, ids2): (
+ &RigidBodyType,
+ &RigidBodyActivation,
+ &RigidBodyIds,
+ ) = bodies.index_bundle(joint.body2.0);
+
+ if (status1.is_dynamic() || status2.is_dynamic())
+ && (!status1.is_dynamic() || !activation1.sleeping)
+ && (!status2.is_dynamic() || !activation2.sleeping)
{
- let island_index = if !rb1.is_dynamic() {
- rb2.active_island_id
+ let island_index = if !status1.is_dynamic() {
+ ids2.active_island_id
} else {
- rb1.active_island_id
+ ids1.active_island_id
};
out[island_index].push(i);
@@ -239,22 +248,28 @@ impl JointSet {
///
/// If `wake_up` is set to `true`, then the bodies attached to this joint will be
/// automatically woken up.
- pub fn remove(
+ pub fn remove<Bodies>(
&mut self,
handle: JointHandle,
- bodies: &mut RigidBodySet,
+ islands: &mut IslandManager,
+ bodies: &mut Bodies,
wake_up: bool,
- ) -> Option<Joint> {
+ ) -> Option<Joint>
+ where
+ Bodies: ComponentSetMut<RigidBodyActivation>
+ + ComponentSet<RigidBodyType>
+ + ComponentSetMut<RigidBodyIds>,
+ {
let id = self.joint_ids.remove(handle.0)?;
let endpoints = self.joint_graph.graph.edge_endpoints(id)?;
if wake_up {
// Wake-up the bodies attached to this joint.
if let Some(rb_handle) = self.joint_graph.graph.node_weight(endpoints.0) {
- bodies.wake_up(*rb_handle, true);
+ islands.wake_up(bodies, *rb_handle, true);
}
if let Some(rb_handle) = self.joint_graph.graph.node_weight(endpoints.1) {
- bodies.wake_up(*rb_handle, true);
+ islands.wake_up(bodies, *rb_handle, true);
}
}
@@ -267,11 +282,16 @@ impl JointSet {
removed_joint
}
- pub(crate) fn remove_rigid_body(
+ pub(crate) fn remove_rigid_body<Bodies>(
&mut self,
deleted_id: RigidBodyGraphIndex,
- bodies: &mut RigidBodySet,
- ) {
+ islands: &mut IslandManager,
+ bodies: &mut Bodies,
+ ) where
+ Bodies: ComponentSetMut<RigidBodyActivation>
+ + ComponentSet<RigidBodyType>
+ + ComponentSetMut<RigidBodyIds>,
+ {
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.
@@ -292,16 +312,16 @@ impl JointSet {
}
// Wake up the attached bodies.
- bodies.wake_up(h1, true);
- bodies.wake_up(h2, true);
+ islands.wake_up(bodies, h1, true);
+ islands.wake_up(bodies, h2, true);
}
if let Some(other) = self.joint_graph.remove_node(deleted_id) {
// One rigid-body joint graph index may have been invalidated
// so we need to update it.
- if let Some(replacement) = bodies.get_mut_internal(other) {
- replacement.joint_graph_index = deleted_id;
- }
+ bodies.map_mut_internal(other.0, |ids: &mut RigidBodyIds| {
+ ids.joint_graph_index = deleted_id;
+ });
}
}
}