aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.vscode/tasks.json15
-rw-r--r--Cargo.toml3
-rw-r--r--src/dynamics/joint/impulse_joint/impulse_joint.rs1
-rw-r--r--src/dynamics/joint/impulse_joint/impulse_joint_set.rs1
-rw-r--r--src/dynamics/joint/multibody_joint/multibody.rs43
-rw-r--r--src/dynamics/joint/multibody_joint/multibody_joint.rs5
-rw-r--r--src/dynamics/joint/multibody_joint/unit_multibody_joint.rs24
-rw-r--r--src/dynamics/solver/generic_velocity_constraint.rs11
-rw-r--r--src/dynamics/solver/generic_velocity_ground_constraint.rs12
-rw-r--r--src/dynamics/solver/interaction_groups.rs4
-rw-r--r--src/dynamics/solver/joint_constraint/joint_constraint.rs85
-rw-r--r--src/dynamics/solver/parallel_solver_constraints.rs99
-rw-r--r--src/dynamics/solver/solver_constraints.rs25
-rw-r--r--src/dynamics/solver/velocity_constraint.rs18
-rw-r--r--src/dynamics/solver/velocity_constraint_wide.rs10
-rw-r--r--src/dynamics/solver/velocity_ground_constraint.rs11
-rw-r--r--src/dynamics/solver/velocity_ground_constraint_wide.rs10
-rw-r--r--src/geometry/contact_pair.rs4
18 files changed, 227 insertions, 154 deletions
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index c445107..285a051 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -57,6 +57,21 @@
"group": "build"
},
{
+ "label": "run 3d (simd - parallel - debug) ",
+ "type": "shell",
+ "command": "cargo",
+ "args": [
+ "run",
+ "--bin",
+ "all_examples3",
+ "--features",
+ "simd-stable,parallel",
+ "--",
+ "--pause"
+ ],
+ "group": "build"
+ },
+ {
"label": "run 2d (no-simd - release) ",
"type": "shell",
"command": "cargo",
diff --git a/Cargo.toml b/Cargo.toml
index 543850e..eb264e4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,6 +27,9 @@ resolver = "2"
#opt-level = 1
#lto = true
+[profile.dev]
+opt-level = 1
+
#[profile.dev.package.rapier3d]
#opt-level = 3
diff --git a/src/dynamics/joint/impulse_joint/impulse_joint.rs b/src/dynamics/joint/impulse_joint/impulse_joint.rs
index 4677a1f..f80380e 100644
--- a/src/dynamics/joint/impulse_joint/impulse_joint.rs
+++ b/src/dynamics/joint/impulse_joint/impulse_joint.rs
@@ -15,5 +15,4 @@ pub struct ImpulseJoint {
// A joint needs to know its handle to simplify its removal.
pub(crate) handle: ImpulseJointHandle,
- pub(crate) constraint_index: usize,
}
diff --git a/src/dynamics/joint/impulse_joint/impulse_joint_set.rs b/src/dynamics/joint/impulse_joint/impulse_joint_set.rs
index cd11a61..448b87d 100644
--- a/src/dynamics/joint/impulse_joint/impulse_joint_set.rs
+++ b/src/dynamics/joint/impulse_joint/impulse_joint_set.rs
@@ -187,7 +187,6 @@ impl ImpulseJointSet {
data,
impulses: na::zero(),
handle: ImpulseJointHandle(handle),
- constraint_index: 0,
};
let default_id = InteractionGraph::<(), ()>::invalid_graph_index();
diff --git a/src/dynamics/joint/multibody_joint/multibody.rs b/src/dynamics/joint/multibody_joint/multibody.rs
index f2fa623..58d11b6 100644
--- a/src/dynamics/joint/multibody_joint/multibody.rs
+++ b/src/dynamics/joint/multibody_joint/multibody.rs
@@ -971,27 +971,48 @@ impl Multibody {
}
#[inline]
+ pub fn num_active_internal_constraints_and_jacobian_lines(&self) -> (usize, usize) {
+ let num_constraints: usize = self
+ .links
+ .iter()
+ .map(|l| l.joint().num_velocity_constraints())
+ .sum();
+ (num_constraints, num_constraints)
+ }
+
+ #[inline]
pub fn generate_internal_constraints(
&self,
params: &IntegrationParameters,
j_id: &mut usize,
jacobians: &mut DVector<Real>,
out: &mut Vec<AnyJointVelocityConstraint>,
+ mut insert_at: Option<usize>,
) {
- let num_constraints: usize = self
- .links
- .iter()
- .map(|l| l.joint().num_velocity_constraints())
- .sum();
-
- let required_jacobian_len = *j_id + num_constraints * self.ndofs * 2;
- if jacobians.nrows() < required_jacobian_len {
- jacobians.resize_vertically_mut(required_jacobian_len, 0.0);
+ if !cfg!(feature = "parallel") {
+ let num_constraints: usize = self
+ .links
+ .iter()
+ .map(|l| l.joint().num_velocity_constraints())
+ .sum();
+
+ let required_jacobian_len = *j_id + num_constraints * self.ndofs * 2;
+ if jacobians.nrows() < required_jacobian_len {
+ jacobians.resize_vertically_mut(required_jacobian_len, 0.0);
+ }
}
for link in self.links.iter() {
- link.joint()
- .velocity_constraints(params, self, link, 0, j_id, jacobians, out);
+ link.joint().velocity_constraints(
+ params,
+ self,
+ link,
+ 0,
+ j_id,
+ jacobians,
+ out,
+ &mut insert_at,
+ );
}
}
}
diff --git a/src/dynamics/joint/multibody_joint/multibody_joint.rs b/src/dynamics/joint/multibody_joint/multibody_joint.rs
index 2f7a71e..5a04070 100644
--- a/src/dynamics/joint/multibody_joint/multibody_joint.rs
+++ b/src/dynamics/joint/multibody_joint/multibody_joint.rs
@@ -255,6 +255,7 @@ impl MultibodyJoint {
j_id: &mut usize,
jacobians: &mut DVector<Real>,
constraints: &mut Vec<AnyJointVelocityConstraint>,
+ insert_at: &mut Option<usize>,
) {
let locked_bits = self.data.locked_axes.bits();
let limit_bits = self.data.limit_axes.bits();
@@ -281,6 +282,7 @@ impl MultibodyJoint {
j_id,
jacobians,
constraints,
+ insert_at,
);
}
@@ -295,6 +297,7 @@ impl MultibodyJoint {
j_id,
jacobians,
constraints,
+ insert_at,
);
}
curr_free_dof += 1;
@@ -329,6 +332,7 @@ impl MultibodyJoint {
j_id,
jacobians,
constraints,
+ insert_at,
);
Some(limits)
} else {
@@ -347,6 +351,7 @@ impl MultibodyJoint {
j_id,
jacobians,
constraints,
+ insert_at,
);
}
curr_free_dof += 1;
diff --git a/src/dynamics/joint/multibody_joint/unit_multibody_joint.rs b/src/dynamics/joint/multibody_joint/unit_multibody_joint.rs
index 42212be..a1ec483 100644
--- a/src/dynamics/joint/multibody_joint/unit_multibody_joint.rs
+++ b/src/dynamics/joint/multibody_joint/unit_multibody_joint.rs
@@ -20,6 +20,7 @@ pub fn unit_joint_limit_constraint(
j_id: &mut usize,
jacobians: &mut DVector<Real>,
constraints: &mut Vec<AnyJointVelocityConstraint>,
+ insert_at: &mut Option<usize>,
) {
let ndofs = multibody.ndofs();
let joint_velocity = multibody.joint_velocity(link);
@@ -60,9 +61,14 @@ pub fn unit_joint_limit_constraint(
writeback_id: WritebackId::Limit(dof_id),
};
- constraints.push(AnyJointVelocityConstraint::JointGenericGroundConstraint(
- constraint,
- ));
+ if let Some(at) = insert_at {
+ constraints[*at] = AnyJointVelocityConstraint::JointGenericGroundConstraint(constraint);
+ *at += 1;
+ } else {
+ constraints.push(AnyJointVelocityConstraint::JointGenericGroundConstraint(
+ constraint,
+ ));
+ }
*j_id += 2 * ndofs;
}
@@ -79,6 +85,7 @@ pub fn unit_joint_motor_constraint(
j_id: &mut usize,
jacobians: &mut DVector<Real>,
constraints: &mut Vec<AnyJointVelocityConstraint>,
+ insert_at: &mut Option<usize>,
) {
let inv_dt = params.inv_dt();
let ndofs = multibody.ndofs();
@@ -128,8 +135,13 @@ pub fn unit_joint_motor_constraint(
writeback_id: WritebackId::Limit(dof_id),
};
- constraints.push(AnyJointVelocityConstraint::JointGenericGroundConstraint(
- constraint,
- ));
+ if let Some(at) = insert_at {
+ constraints[*at] = AnyJointVelocityConstraint::JointGenericGroundConstraint(constraint);
+ *at += 1;
+ } else {
+ constraints.push(AnyJointVelocityConstraint::JointGenericGroundConstraint(
+ constraint,
+ ));
+ }
*j_id += 2 * ndofs;
}
diff --git a/src/dynamics/solver/generic_velocity_constraint.rs b/src/dynamics/solver/generic_velocity_constraint.rs
index 99dc40e..261c4c8 100644
--- a/src/dynamics/solver/generic_velocity_constraint.rs
+++ b/src/dynamics/solver/generic_velocity_constraint.rs
@@ -36,7 +36,7 @@ impl GenericVelocityConstraint {
out_constraints: &mut Vec<AnyVelocityConstraint>,
jacobians: &mut DVector<Real>,
jacobian_id: &mut usize,
- push: bool,
+ insert_at: Option<usize>,
) where
Bodies: ComponentSet<RigidBodyIds>
+ ComponentSet<RigidBodyVelocity>
@@ -99,7 +99,7 @@ impl GenericVelocityConstraint {
let required_jacobian_len =
*jacobian_id + manifold.data.solver_contacts.len() * multibodies_ndof * 2 * DIM;
- if jacobians.nrows() < required_jacobian_len {
+ if jacobians.nrows() < required_jacobian_len && !cfg!(feature = "parallel") {
jacobians.resize_vertically_mut(required_jacobian_len, 0.0);
}
@@ -320,11 +320,10 @@ impl GenericVelocityConstraint {
generic_constraint_mask,
};
- if push {
- out_constraints.push(AnyVelocityConstraint::NongroupedGeneric(constraint));
+ if let Some(at) = insert_at {
+ out_constraints[at + _l] = AnyVelocityConstraint::NongroupedGeneric(constraint);
} else {
- out_constraints[manifold.data.constraint_index + _l] =
- AnyVelocityConstraint::NongroupedGeneric(constraint);
+ out_constraints.push(AnyVelocityConstraint::NongroupedGeneric(constraint));
}
}
}
diff --git a/src/dynamics/solver/generic_velocity_ground_constraint.rs b/src/dynamics/solver/generic_velocity_ground_constraint.rs
index b2e5878..044bd48 100644
--- a/src/dynamics/solver/generic_velocity_ground_constraint.rs
+++ b/src/dynamics/solver/generic_velocity_ground_constraint.rs
@@ -34,7 +34,7 @@ impl GenericVelocityGroundConstraint {
out_constraints: &mut Vec<AnyVelocityConstraint>,
jacobians: &mut DVector<Real>,
jacobian_id: &mut usize,
- push: bool,
+ insert_at: Option<usize>,
) where
Bodies: ComponentSet<RigidBodyIds>
+ ComponentSet<RigidBodyVelocity>
@@ -87,7 +87,7 @@ impl GenericVelocityGroundConstraint {
let required_jacobian_len =
*jacobian_id + manifold.data.solver_contacts.len() * multibodies_ndof * 2 * DIM;
- if jacobians.nrows() < required_jacobian_len {
+ if jacobians.nrows() < required_jacobian_len && !cfg!(feature = "parallel") {
jacobians.resize_vertically_mut(required_jacobian_len, 0.0);
}
@@ -200,11 +200,11 @@ impl GenericVelocityGroundConstraint {
ndofs2: mb2.ndofs(),
};
- if push {
- out_constraints.push(AnyVelocityConstraint::NongroupedGenericGround(constraint));
- } else {
- out_constraints[manifold.data.constraint_index + _l] =
+ if let Some(at) = insert_at {
+ out_constraints[at + _l] =
AnyVelocityConstraint::NongroupedGenericGround(constraint);
+ } else {
+ out_constraints.push(AnyVelocityConstraint::NongroupedGenericGround(constraint));
}
}
}
diff --git a/src/dynamics/solver/interaction_groups.rs b/src/dynamics/solver/interaction_groups.rs
index 4adbc18..7f49ec3 100644
--- a/src/dynamics/solver/interaction_groups.rs
+++ b/src/dynamics/solver/interaction_groups.rs
@@ -131,14 +131,14 @@ impl ParallelInteractionGroups {
(true, false) => {
let rb_ids2: &RigidBodyIds = bodies.index(body_pair.1.unwrap().0);
let color_mask = bcolors[rb_ids2.active_set_offset];
- *color = (!color_mask).leading_zeros() as usize;
+ *color = 127 - (!color_mask).leading_zeros() as usize;
color_len[*color] += 1;
bcolors[rb_ids2.active_set_offset] |= 1 << *color;
}
(false, true) => {
let rb_ids1: &RigidBodyIds = bodies.index(body_pair.0.unwrap().0);
let color_mask = bcolors[rb_ids1.active_set_offset];
- *color = (!color_mask).leading_zeros() as usize;
+ *color = 127 - (!color_mask).leading_zeros() as usize;
color_len[*color] += 1;
bcolors[rb_ids1.active_set_offset] |= 1 << *color;
}
diff --git a/src/dynamics/solver/joint_constraint/joint_constraint.rs b/src/dynamics/solver/joint_constraint/joint_constraint.rs
index c006417..988e6a2 100644
--- a/src/dynamics/solver/joint_constraint/joint_constraint.rs
+++ b/src/dynamics/solver/joint_constraint/joint_constraint.rs
@@ -30,20 +30,21 @@ pub enum AnyJointVelocityConstraint {
impl AnyJointVelocityConstraint {
#[cfg(feature = "parallel")]
- pub fn num_active_constraints(joint: &ImpulseJoint) -> usize {
+ pub fn num_active_constraints_and_jacobian_lines(joint: &ImpulseJoint) -> (usize, usize) {
let joint = &joint.data;
let locked_axes = joint.locked_axes.bits();
let motor_axes = joint.motor_axes.bits() & !locked_axes;
let limit_axes = joint.limit_axes.bits() & !locked_axes;
let coupled_axes = joint.coupled_axes.bits();
- (motor_axes & !coupled_axes).count_ones() as usize
+ let num_constraints = (motor_axes & !coupled_axes).count_ones() as usize
+ ((motor_axes & coupled_axes) & JointAxesMask::ANG_AXES.bits() != 0) as usize
+ ((motor_axes & coupled_axes) & JointAxesMask::LIN_AXES.bits() != 0) as usize
+ locked_axes.count_ones() as usize
+ (limit_axes & !coupled_axes).count_ones() as usize
+ ((limit_axes & coupled_axes) & JointAxesMask::ANG_AXES.bits() != 0) as usize
- + ((limit_axes & coupled_axes) & JointAxesMask::LIN_AXES.bits() != 0) as usize
+ + ((limit_axes & coupled_axes) & JointAxesMask::LIN_AXES.bits() != 0) as usize;
+ (num_constraints, num_constraints)
}
pub fn from_joint<Bodies>(
@@ -55,7 +56,7 @@ impl AnyJointVelocityConstraint {
j_id: &mut usize,
jacobians: &mut DVector<Real>,
out: &mut Vec<Self>,
- push: bool,
+ insert_at: Option<usize>,
) where
Bodies: ComponentSet<RigidBodyPosition>
+ ComponentSet<RigidBodyVelocity>
@@ -122,7 +123,7 @@ impl AnyJointVelocityConstraint {
// TODO: is this count correct when we take both motors and limits into account?
let required_jacobian_len = *j_id + multibodies_ndof * 2 * SPATIAL_DIM;
- if jacobians.nrows() < required_jacobian_len {
+ if jacobians.nrows() < required_jacobian_len && !cfg!(feature = "parallel") {
jacobians.resize_vertically_mut(required_jacobian_len, 0.0);
}
@@ -143,14 +144,13 @@ impl AnyJointVelocityConstraint {
&mut out_tmp,
);
- if push {
- for c in out_tmp.into_iter().take(out_tmp_len) {
- out.push(AnyJointVelocityConstraint::JointGenericConstraint(c));
+ if let Some(at) = insert_at {
+ for (i, c) in out_tmp.into_iter().take(out_tmp_len).enumerate() {
+ out[at + i] = AnyJointVelocityConstraint::JointGenericConstraint(c);
}
} else {
- for (i, c) in out_tmp.into_iter().take(out_tmp_len).enumerate() {
- out[joint.constraint_index + i] =
- AnyJointVelocityConstraint::JointGenericConstraint(c);
+ for c in out_tmp.into_iter().take(out_tmp_len) {
+ out.push(AnyJointVelocityConstraint::JointGenericConstraint(c));
}
}
} else {
@@ -167,14 +167,13 @@ impl AnyJointVelocityConstraint {
&mut out_tmp,
);
- if push {
- for c in out_tmp.into_iter().take(out_tmp_len) {
- out.push(AnyJointVelocityConstraint::JointConstraint(c));
+ if let Some(at) = insert_at {
+ for (i, c) in out_tmp.into_iter().take(out_tmp_len).enumerate() {
+ out[at + i] = AnyJointVelocityConstraint::JointConstraint(c);
}
} else {
- for (i, c) in out_tmp.into_iter().take(out_tmp_len).enumerate() {
- out[joint.constraint_index + i] =
- AnyJointVelocityConstraint::JointConstraint(c);
+ for c in out_tmp.into_iter().take(out_tmp_len) {
+ out.push(AnyJointVelocityConstraint::JointConstraint(c));
}
}
}
@@ -187,7 +186,7 @@ impl AnyJointVelocityConstraint {
impulse_joints: [&ImpulseJoint; SIMD_WIDTH],
bodies: &Bodies,
out: &mut Vec<Self>,
- push: bool,
+ insert_at: Option<usize>,
) where
Bodies: ComponentSet<RigidBodyPosition>
+ ComponentSet<RigidBodyVelocity>
@@ -260,14 +259,13 @@ impl AnyJointVelocityConstraint {
&mut out_tmp,
);
- if push {
- for c in out_tmp.into_iter().take(out_tmp_len) {
- out.push(AnyJointVelocityConstraint::JointConstraintSimd(c));
+ if let Some(at) = insert_at {
+ for (i, c) in out_tmp.into_iter().take(out_tmp_len).enumerate() {
+ out[at + i] = AnyJointVelocityConstraint::JointConstraintSimd(c);
}
} else {
- for (i, c) in out_tmp.into_iter().take(out_tmp_len).enumerate() {
- out[impulse_joints[0].constraint_index + i] =
- AnyJointVelocityConstraint::JointConstraintSimd(c);
+ for c in out_tmp.into_iter().take(out_tmp_len) {
+ out.push(AnyJointVelocityConstraint::JointConstraintSimd(c));
}
}
}
@@ -281,7 +279,7 @@ impl AnyJointVelocityConstraint {
j_id: &mut usize,
jacobians: &mut DVector<Real>,
out: &mut Vec<Self>,
- push: bool,
+ insert_at: Option<usize>,
) where
Bodies: ComponentSet<RigidBodyPosition>
+ ComponentSet<RigidBodyType>
@@ -350,7 +348,7 @@ impl AnyJointVelocityConstraint {
// TODO: is this count correct when we take both motors and limits into account?
let required_jacobian_len = *j_id + multibodies_ndof * 2 * SPATIAL_DIM;
- if jacobians.nrows() < required_jacobian_len {
+ if jacobians.nrows() < required_jacobian_len && !cfg!(feature = "parallel") {
jacobians.resize_vertically_mut(required_jacobian_len, 0.0);
}
@@ -370,14 +368,13 @@ impl AnyJointVelocityConstraint {
&mut out_tmp,
);
- if push {
- for c in out_tmp.into_iter().take(out_tmp_len) {
- out.push(AnyJointVelocityConstraint::JointGenericGroundConstraint(c));
+ if let Some(at) = insert_at {
+ for (i, c) in out_tmp.into_iter().take(out_tmp_len).enumerate() {
+ out[at + i] = AnyJointVelocityConstraint::JointGenericGroundConstraint(c);
}
} else {
- for (i, c) in out_tmp.into_iter().take(out_tmp_len).enumerate() {
- out[joint.constraint_index + i] =
- AnyJointVelocityConstraint::JointGenericGroundConstraint(c);
+ for c in out_tmp.into_iter().take(out_tmp_len) {
+ out.push(AnyJointVelocityConstraint::JointGenericGroundConstraint(c));
}
}
} else {
@@ -394,14 +391,13 @@ impl AnyJointVelocityConstraint {
&mut out_tmp,
);
- if push {
- for c in out_tmp.into_iter().take(out_tmp_len) {
- out.push(AnyJointVelocityConstraint::JointGroundConstraint(c));
+ if let Some(at) = insert_at {
+ for (i, c) in out_tmp.into_iter().take(out_tmp_len).enumerate() {
+ out[at + i] = AnyJointVelocityConstraint::JointGroundConstraint(c);
}
} else {
- for (i, c) in out_tmp.into_iter().take(out_tmp_len).enumerate() {
- out[joint.constraint_index + i] =
- AnyJointVelocityConstraint::JointGroundConstraint(c);
+ for c in out_tmp.into_iter().take(out_tmp_len) {
+ out.push(AnyJointVelocityConstraint::JointGroundConstraint(c));
}
}
}
@@ -414,7 +410,7 @@ impl AnyJointVelocityConstraint {
impulse_joints: [&ImpulseJoint; SIMD_WIDTH],
bodies: &Bodies,
out: &mut Vec<Self>,
- push: bool,
+ insert_at: Option<usize>,
) where
Bodies: ComponentSet<RigidBodyPosition>
+ ComponentSet<RigidBodyType>
@@ -506,14 +502,13 @@ impl AnyJointVelocityConstraint {
&mut out_tmp,
);
- if push {
- for c in out_tmp.into_iter().take(out_tmp_len) {
- out.push(AnyJointVelocityConstraint::JointGroundConstraintSimd(c));
+ if let Some(at) = insert_at {
+ for (i, c) in out_tmp.into_iter().take(out_tmp_len).enumerate() {
+ out[at + i] = AnyJointVelocityConstraint::JointGroundConstraintSimd(c);
}
} else {
- for (i, c) in out_tmp.into_iter().take(out_tmp_len).enumerate() {
- out[impulse_joints[0].constraint_index + i] =
- AnyJointVelocityConstraint::JointGroundConstraintSimd(c);
+ for c in out_tmp.into_iter().take(out_tmp_len) {
+ out.push(AnyJointVelocityConstraint::JointGroundConstraintSimd(c));
}
}
}
diff --git a/src/dynamics/solver/parallel_solver_constraints.rs b/src/dynamics/solver/parallel_solver_constraints.rs
index 3a8f9c8..4c43f46 100644
--- a/src/dynamics/solver/parallel_solver_constraints.rs
+++ b/src/dynamics/solver/parallel_solver_constraints.rs
@@ -8,12 +8,12 @@ use crate::dynamics::solver::{
VelocityGroundConstraint,
};
use crate::dynamics::{
- ImpulseJoint, IntegrationParameters, IslandManager, JointGraphEdge, MultibodyJointSet,
- RigidBodyHandle, RigidBodyIds, RigidBodyMassProps, RigidBodyPosition, RigidBodyType,
- RigidBodyVelocity,
+ ImpulseJoint, IntegrationParameters, IslandManager, JointGraphEdge, MultibodyIndex,
+ MultibodyJointSet, RigidBodyHandle, RigidBodyIds, RigidBodyMassProps, RigidBodyPosition,
+ RigidBodyType, RigidBodyVelocity,
};
use crate::geometry::ContactManifold;
-use crate::math::{Real, SPATIAL_DIM};
+use crate::math::{Real, DIM, SPATIAL_DIM};
#[cfg(feature = "simd-is-enabled")]
use crate::{
dynamics::solver::{WVelocityConstraint, WVelocityGroundConstraint},
@@ -46,6 +46,7 @@ pub(crate) enum ConstraintDesc {
GroundGrouped([usize; SIMD_WIDTH]),
GenericNongroundNongrouped(usize, usize),
GenericGroundNongrouped(usize, usize),
+ GenericMultibodyInternal(MultibodyIndex, usize),
}
pub(crate) struct ParallelSolverConstraints<VelocityConstraint> {
@@ -81,10 +82,10 @@ impl<VelocityConstraint> ParallelSolverConstraints<VelocityConstraint> {
macro_rules! impl_init_constraints_group {
($VelocityConstraint: ty, $Interaction: ty,
$categorize: ident, $group: ident,
- $data: ident$(.$constraint_index: ident)*,
$body1: ident,
$body2: ident,
- $num_active_constraints: path,
+ $generate_internal_constraints: expr,
+ $num_active_constraints_and_jacobian_lines: path,
$empty_velocity_constraint: expr $(, $weight: ident)*) => {
impl ParallelSolverConstraints<$VelocityConstraint> {
pub fn init_constraint_groups<Bodies>(
@@ -151,12 +152,11 @@ macro_rules! impl_init_constraints_group {
// Compute constraint indices.
for interaction_i in &self.interaction_groups.nongrouped_interactions[start_nongrouped..] {
let interaction = &mut interactions[*interaction_i]$(.$weight)*;
- interaction.$data$(.$constraint_index)* = total_num_constraints;
self.constraint_descs.push((
total_num_constraints,
ConstraintDesc::NongroundNongrouped(*interaction_i),
));
- total_num_constraints += $num_active_constraints(interaction);
+ total_num_constraints += $num_active_constraints_and_jacobian_lines(interaction).0;
}
#[cfg(feature = "simd-is-enabled")]
@@ -164,26 +164,24 @@ macro_rules! impl_init_constraints_group {
self.interaction_groups.grouped_interactions[start_grouped..].chunks(SIMD_WIDTH)
{
let interaction = &mut interactions[interaction_i[0]]$(.$weight)*;
- interaction.$data$(.$constraint_index)* = total_num_constraints;
self.constraint_descs.push((
total_num_constraints,
ConstraintDesc::NongroundGrouped(
gather![|ii| interaction_i[ii]],
),
));
- total_num_constraints += $num_active_constraints(interaction);
+ total_num_constraints += $num_active_constraints_and_jacobian_lines(interaction).0;
}
for interaction_i in
&self.ground_interaction_groups.nongrouped_interactions[start_nongrouped_ground..]
{
let interaction = &mut interactions[*interaction_i]$(.$weight)*;
- interaction.$data$(.$constraint_index)* = total_num_constraints;
self.constraint_descs.push((
total_num_constraints,
ConstraintDesc::GroundNongrouped(*interaction_i),
));
- total_num_constraints += $num_active_constraints(interaction);
+ total_num_constraints += $num_active_constraints_and_jacobian_lines(interaction).0;
}
#[cfg(feature = "simd-is-enabled")]
@@ -192,14 +190,13 @@ macro_rules! impl_init_constraints_group {
.chunks(SIMD_WIDTH)
{
let interaction = &mut interactions[interaction_i[0]]$(.$weight)*;
- interaction.$data$(.$constraint_index)* = total_num_constraints;
self.constraint_descs.push((
total_num_constraints,
ConstraintDesc::GroundGrouped(
gather![|ii| interaction_i[ii]],
),
));
- total_num_constraints += $num_active_constraints(interaction);
+ total_num_constraints += $num_active_constraints_and_jacobian_lines(interaction).0;
}
let multibody_ndofs = |handle| {
@@ -215,38 +212,62 @@ macro_rules! impl_init_constraints_group {
for interaction_i in &self.generic_not_ground_interactions[..] {
let interaction = &mut interactions[*interaction_i]$(.$weight)*;
- interaction.$data$(.$constraint_index)* = total_num_constraints;
self.constraint_descs.push((
total_num_constraints,
ConstraintDesc::GenericNongroundNongrouped(*interaction_i, *j_id),
));
- let num_constraints = $num_active_constraints(interaction);
+ let (num_constraints, num_jac_lines) = $num_active_constraints_and_jacobian_lines(interaction);
let ndofs1 = $body1(interaction).map(multibody_ndofs).unwrap_or(0);
let ndofs2 = $body2(interaction).map(multibody_ndofs).unwrap_or(0);
- *j_id += num_constraints * (ndofs1 + ndofs2) * 2;
+ *j_id += (ndofs1 + ndofs2) * 2 * num_jac_lines;
total_num_constraints += num_constraints;
}
for interaction_i in &self.generic_ground_interactions[..] {
let interaction = &mut interactions[*interaction_i]$(.$weight)*;
- interaction.$data$(.$constraint_index)* = total_num_constraints;
self.constraint_descs.push((
total_num_constraints,
ConstraintDesc::GenericGroundNongrouped(*interaction_i, *j_id),
));
- let num_constraints = $num_active_constraints(interaction);
+ let (num_constraints, num_jac_lines) = $num_active_constraints_and_jacobian_lines(interaction);
let ndofs1 = $body1(interaction).map(multibody_ndofs).unwrap_or(0);
let ndofs2 = $body2(interaction).map(multibody_ndofs).unwrap_or(0);
- *j_id += num_constraints * (ndofs1 + ndofs2) * 2;
+ *j_id += (ndofs1 + ndofs2) * 2 * num_jac_lines;
total_num_constraints += num_constraints;
}
self.parallel_desc_groups.push(self.constraint_descs.len());
}
+ if $generate_internal_constraints {
+ let mut had_any_internal_constraint = false;
+ for handle in islands.active_island(island_id) {
+ if let Some(link) = multibodies.rigid_body_link(*handle) {
+ let multibody = multibodies.get_multibody(link.multibody).unwrap();
+ if link.id == 0 || link.id == 1 && !multibody.root_is_dynamic {
+ let (num_constraints, num_jac_lines) = multibody.num_active_internal_constraints_and_jacobian_lines();
+ let ndofs = multibody.ndofs();
+
+ self.constraint_descs.push((
+ total_num_constraints,
+ ConstraintDesc::GenericMultibodyInternal(link.multibody, *j_id)
+ ));
+
+ *j_id += ndofs * 2 * num_jac_lines;
+ total_num_constraints += num_constraints;
+ had_any_internal_constraint = true;
+ }
+ }
+ }
+
+ if had_any_internal_constraint {
+ self.parallel_desc_groups.push(self.constraint_descs.len());
+ }
+ }
+
// Resize the constraint sets.
self.velocity_constraints.clear();
self.velocity_constraints
@@ -274,10 +295,10 @@ impl_init_constraints_group!(
&mut ContactManifold,
categorize_contacts,
group_manifolds,
- data.constraint_index,
manifold_body1,
manifold_body2,
- VelocityConstraint::num_active_constraints,
+ false,
+ VelocityConstraint::num_active_constraints_and_jacobian_lines,
AnyVelocityConstraint::Empty
);
@@ -286,10 +307,10 @@ impl_init_constraints_group!(
JointGraphEdge,
categorize_joints,
group_joints,
- constraint_index,
joint_body1,
joint_body2,
- AnyJointVelocityConstraint::num_active_constraints,
+ true,
+ AnyJointVelocityConstraint::num_active_constraints_and_jacobian_lines,
AnyJointVelocityConstraint::Empty,
weight
);
@@ -317,32 +338,33 @@ impl ParallelSolverConstraints<AnyVelocityConstraint> {
match &desc.1 {
ConstraintDesc::NongroundNongrouped(manifold_id) => {
let manifold = &*manifolds_all[*manifold_id];
- VelocityConstraint::generate(params, *manifold_id, manifold, bodies, &mut self.velocity_constraints, false);
+ VelocityConstraint::generate(params, *manifold_id, manifold, bodies, &mut self.velocity_constraints, Some(desc.0));
}
ConstraintDesc::GroundNongrouped(manifold_id) => {
let manifold = &*manifolds_all[*manifold_id];
- VelocityGroundConstraint::generate(params, *manifold_id, manifold, bodies, &mut self.velocity_constraints, false);
+ VelocityGroundConstraint::generate(params, *manifold_id, manifold, bodies, &mut self.velocity_constraints, Some(desc.0));
}
#[cfg(feature = "simd-is-enabled")]
ConstraintDesc::Nongro