aboutsummaryrefslogtreecommitdiff
path: root/src/dynamics/solver/parallel_position_solver.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/dynamics/solver/parallel_position_solver.rs')
-rw-r--r--src/dynamics/solver/parallel_position_solver.rs529
1 files changed, 27 insertions, 502 deletions
diff --git a/src/dynamics/solver/parallel_position_solver.rs b/src/dynamics/solver/parallel_position_solver.rs
index b7a7876..ec480f5 100644
--- a/src/dynamics/solver/parallel_position_solver.rs
+++ b/src/dynamics/solver/parallel_position_solver.rs
@@ -1,508 +1,30 @@
-use super::ParallelInteractionGroups;
use super::{AnyJointPositionConstraint, AnyPositionConstraint, ThreadContext};
-use crate::dynamics::solver::categorization::{categorize_joints, categorize_position_contacts};
-use crate::dynamics::solver::{InteractionGroups, PositionConstraint, PositionGroundConstraint};
-use crate::dynamics::{IntegrationParameters, JointGraphEdge, RigidBodySet};
-use crate::geometry::ContactManifold;
-use crate::math::Isometry;
-#[cfg(feature = "simd-is-enabled")]
-use crate::{
- dynamics::solver::{WPositionConstraint, WPositionGroundConstraint},
- simd::SIMD_WIDTH,
+use crate::dynamics::solver::{
+ AnyJointVelocityConstraint, AnyVelocityConstraint, ParallelSolverConstraints,
};
+use crate::dynamics::IntegrationParameters;
+use crate::math::{Isometry, Real};
use std::sync::atomic::Ordering;
-pub(crate) enum PositionConstraintDesc {
- NongroundNongrouped(usize),
- GroundNongrouped(usize),
- #[cfg(feature = "simd-is-enabled")]
- NongroundGrouped([usize; SIMD_WIDTH]),
- #[cfg(feature = "simd-is-enabled")]
- GroundGrouped([usize; SIMD_WIDTH]),
-}
-
-pub(crate) struct ParallelPositionSolverContactPart {
- pub point_point: Vec<usize>,
- pub plane_point: Vec<usize>,
- pub ground_point_point: Vec<usize>,
- pub ground_plane_point: Vec<usize>,
- pub interaction_groups: InteractionGroups,
- pub ground_interaction_groups: InteractionGroups,
- pub constraints: Vec<AnyPositionConstraint>,
- pub constraint_descs: Vec<(usize, PositionConstraintDesc)>,
- pub parallel_desc_groups: Vec<usize>,
-}
-
-pub(crate) struct ParallelPositionSolverJointPart {
- pub not_ground_interactions: Vec<usize>,
- pub ground_interactions: Vec<usize>,
- pub interaction_groups: InteractionGroups,
- pub ground_interaction_groups: InteractionGroups,
- pub constraints: Vec<AnyJointPositionConstraint>,
- pub constraint_descs: Vec<(usize, PositionConstraintDesc)>,
- pub parallel_desc_groups: Vec<usize>,
-}
-
-impl ParallelPositionSolverContactPart {
- pub fn new() -> Self {
- Self {
- point_point: Vec::new(),
- plane_point: Vec::new(),
- ground_point_point: Vec::new(),
- ground_plane_point: Vec::new(),
- interaction_groups: InteractionGroups::new(),
- ground_interaction_groups: InteractionGroups::new(),
- constraints: Vec::new(),
- constraint_descs: Vec::new(),
- parallel_desc_groups: Vec::new(),
- }
- }
-}
-impl ParallelPositionSolverJointPart {
- pub fn new() -> Self {
- Self {
- not_ground_interactions: Vec::new(),
- ground_interactions: Vec::new(),
- interaction_groups: InteractionGroups::new(),
- ground_interaction_groups: InteractionGroups::new(),
- constraints: Vec::new(),
- constraint_descs: Vec::new(),
- parallel_desc_groups: Vec::new(),
- }
- }
-}
-
-impl ParallelPositionSolverJointPart {
- pub fn init_constraints_groups(
- &mut self,
- island_id: usize,
- bodies: &RigidBodySet,
- joints: &mut [JointGraphEdge],
- joint_groups: &ParallelInteractionGroups,
- ) {
- let mut total_num_constraints = 0;
- let num_groups = joint_groups.num_groups();
-
- self.interaction_groups.clear_groups();
- self.ground_interaction_groups.clear_groups();
- self.parallel_desc_groups.clear();
- self.constraint_descs.clear();
- self.parallel_desc_groups.push(0);
-
- for i in 0..num_groups {
- let group = joint_groups.group(i);
-
- self.not_ground_interactions.clear();
- self.ground_interactions.clear();
- categorize_joints(
- bodies,
- joints,
- group,
- &mut self.ground_interactions,
- &mut self.not_ground_interactions,
- );
-
- #[cfg(feature = "simd-is-enabled")]
- let start_grouped = self.interaction_groups.grouped_interactions.len();
- let start_nongrouped = self.interaction_groups.nongrouped_interactions.len();
- #[cfg(feature = "simd-is-enabled")]
- let start_grouped_ground = self.ground_interaction_groups.grouped_interactions.len();
- let start_nongrouped_ground =
- self.ground_interaction_groups.nongrouped_interactions.len();
-
- self.interaction_groups.group_joints(
- island_id,
- bodies,
- joints,
- &self.not_ground_interactions,
- );
- self.ground_interaction_groups.group_joints(
- island_id,
- bodies,
- joints,
- &self.ground_interactions,
- );
-
- // Compute constraint indices.
- for interaction_i in
- &self.interaction_groups.nongrouped_interactions[start_nongrouped..]
- {
- let joint = &mut joints[*interaction_i].weight;
- joint.position_constraint_index = total_num_constraints;
- self.constraint_descs.push((
- total_num_constraints,
- PositionConstraintDesc::NongroundNongrouped(*interaction_i),
- ));
- total_num_constraints +=
- AnyJointPositionConstraint::num_active_constraints(joint, false);
- }
-
- #[cfg(feature = "simd-is-enabled")]
- for interaction_i in
- self.interaction_groups.grouped_interactions[start_grouped..].chunks(SIMD_WIDTH)
- {
- let joint = &mut joints[interaction_i[0]].weight;
- joint.position_constraint_index = total_num_constraints;
- self.constraint_descs.push((
- total_num_constraints,
- PositionConstraintDesc::NongroundGrouped(
- array![|ii| interaction_i[ii]; SIMD_WIDTH],
- ),
- ));
- total_num_constraints +=
- AnyJointPositionConstraint::num_active_constraints(joint, true);
- }
-
- for interaction_i in
- &self.ground_interaction_groups.nongrouped_interactions[start_nongrouped_ground..]
- {
- let joint = &mut joints[*interaction_i].weight;
- joint.position_constraint_index = total_num_constraints;
- self.constraint_descs.push((
- total_num_constraints,
- PositionConstraintDesc::GroundNongrouped(*interaction_i),
- ));
- total_num_constraints +=
- AnyJointPositionConstraint::num_active_constraints(joint, false);
- }
-
- #[cfg(feature = "simd-is-enabled")]
- for interaction_i in self.ground_interaction_groups.grouped_interactions
- [start_grouped_ground..]
- .chunks(SIMD_WIDTH)
- {
- let joint = &mut joints[interaction_i[0]].weight;
- joint.position_constraint_index = total_num_constraints;
- self.constraint_descs.push((
- total_num_constraints,
- PositionConstraintDesc::GroundGrouped(
- array![|ii| interaction_i[ii]; SIMD_WIDTH],
- ),
- ));
- total_num_constraints +=
- AnyJointPositionConstraint::num_active_constraints(joint, true);
- }
-
- self.parallel_desc_groups.push(self.constraint_descs.len());
- }
-
- // Resize the constraints set.
- self.constraints.clear();
- self.constraints
- .resize_with(total_num_constraints, || AnyJointPositionConstraint::Empty)
- }
-
- fn fill_constraints(
- &mut self,
- thread: &ThreadContext,
- bodies: &RigidBodySet,
- joints_all: &[JointGraphEdge],
- ) {
- let descs = &self.constraint_descs;
-
- crate::concurrent_loop! {
- let batch_size = thread.batch_size;
- for desc in descs[thread.position_joint_constraint_initialization_index, thread.num_initialized_position_joint_constraints] {
- match &desc.1 {
- PositionConstraintDesc::NongroundNongrouped(joint_id) => {
- let joint = &joints_all[*joint_id].weight;
- let constraint = AnyJointPositionConstraint::from_joint(
- joint,
- bodies,
- );
- self.constraints[joint.position_constraint_index] = constraint;
- }
- PositionConstraintDesc::GroundNongrouped(joint_id) => {
- let joint = &joints_all[*joint_id].weight;
- let constraint = AnyJointPositionConstraint::from_joint_ground(
- joint,
- bodies,
- );
- self.constraints[joint.position_constraint_index] = constraint;
- }
- #[cfg(feature = "simd-is-enabled")]
- PositionConstraintDesc::NongroundGrouped(joint_id) => {
- let joints = array![|ii| &joints_all[joint_id[ii]].weight; SIMD_WIDTH];
- if let Some(constraint) = AnyJointPositionConstraint::from_wide_joint(
- joints, bodies,
- ) {
- self.constraints[joints[0].position_constraint_index] = constraint
- } else {
- for ii in 0..SIMD_WIDTH {
- let constraint = AnyJointPositionConstraint::from_joint(joints[ii], bodies);
- self.constraints[joints[0].position_constraint_index + ii] = constraint;
- }
- }
- }
- #[cfg(feature = "simd-is-enabled")]
- PositionConstraintDesc::GroundGrouped(joint_id) => {
- let joints = array![|ii| &joints_all[joint_id[ii]].weight; SIMD_WIDTH];
- if let Some(constraint) = AnyJointPositionConstraint::from_wide_joint_ground(
- joints, bodies,
- ) {
- self.constraints[joints[0].position_constraint_index] = constraint
- } else {
- for ii in 0..SIMD_WIDTH {
- let constraint = AnyJointPositionConstraint::from_joint_ground(joints[ii], bodies);
- self.constraints[joints[0].position_constraint_index + ii] = constraint;
- }
- }
- }
- }
- }
- }
- }
-}
-
-impl ParallelPositionSolverContactPart {
- pub fn init_constraints_groups(
- &mut self,
- island_id: usize,
- bodies: &RigidBodySet,
- manifolds: &mut [&mut ContactManifold],
- manifold_groups: &ParallelInteractionGroups,
- ) {
- let mut total_num_constraints = 0;
- let num_groups = manifold_groups.num_groups();
-
- self.interaction_groups.clear_groups();
- self.ground_interaction_groups.clear_groups();
- self.parallel_desc_groups.clear();
- self.constraint_descs.clear();
- self.parallel_desc_groups.push(0);
-
- for i in 0..num_groups {
- let group = manifold_groups.group(i);
-
- self.ground_point_point.clear();
- self.ground_plane_point.clear();
- self.point_point.clear();
- self.plane_point.clear();
- categorize_position_contacts(
- bodies,
- manifolds,
- group,
- &mut self.ground_point_point,
- &mut self.ground_plane_point,
- &mut self.point_point,
- &mut self.plane_point,
- );
-
- #[cfg(feature = "simd-is-enabled")]
- let start_grouped = self.interaction_groups.grouped_interactions.len();
- let start_nongrouped = self.interaction_groups.nongrouped_interactions.len();
- #[cfg(feature = "simd-is-enabled")]
- let start_grouped_ground = self.ground_interaction_groups.grouped_interactions.len();
- let start_nongrouped_ground =
- self.ground_interaction_groups.nongrouped_interactions.len();
-
- self.interaction_groups.group_manifolds(
- island_id,
- bodies,
- manifolds,
- &self.point_point,
- );
- self.interaction_groups.group_manifolds(
- island_id,
- bodies,
- manifolds,
- &self.plane_point,
- );
- self.ground_interaction_groups.group_manifolds(
- island_id,
- bodies,
- manifolds,
- &self.ground_point_point,
- );
- self.ground_interaction_groups.group_manifolds(
- island_id,
- bodies,
- manifolds,
- &self.ground_plane_point,
- );
-
- // Compute constraint indices.
- for interaction_i in
- &self.interaction_groups.nongrouped_interactions[start_nongrouped..]
- {
- let manifold = &mut *manifolds[*interaction_i];
- manifold.position_constraint_index = total_num_constraints;
- self.constraint_descs.push((
- total_num_constraints,
- PositionConstraintDesc::NongroundNongrouped(*interaction_i),
- ));
- total_num_constraints += PositionConstraint::num_active_constraints(manifold);
- }
-
- #[cfg(feature = "simd-is-enabled")]
- for interaction_i in
- self.interaction_groups.grouped_interactions[start_grouped..].chunks(SIMD_WIDTH)
- {
- let manifold = &mut *manifolds[interaction_i[0]];
- manifold.position_constraint_index = total_num_constraints;
- self.constraint_descs.push((
- total_num_constraints,
- PositionConstraintDesc::NongroundGrouped(
- array![|ii| interaction_i[ii]; SIMD_WIDTH],
- ),
- ));
- total_num_constraints += PositionConstraint::num_active_constraints(manifold);
- }
-
- for interaction_i in
- &self.ground_interaction_groups.nongrouped_interactions[start_nongrouped_ground..]
- {
- let manifold = &mut *manifolds[*interaction_i];
- manifold.position_constraint_index = total_num_constraints;
- self.constraint_descs.push((
- total_num_constraints,
- PositionConstraintDesc::GroundNongrouped(*interaction_i),
- ));
- total_num_constraints += PositionConstraint::num_active_constraints(manifold);
- }
-
- #[cfg(feature = "simd-is-enabled")]
- for interaction_i in self.ground_interaction_groups.grouped_interactions
- [start_grouped_ground..]
- .chunks(SIMD_WIDTH)
- {
- let manifold = &mut *manifolds[interaction_i[0]];
- manifold.position_constraint_index = total_num_constraints;
- self.constraint_descs.push((
- total_num_constraints,
- PositionConstraintDesc::GroundGrouped(
- array![|ii| interaction_i[ii]; SIMD_WIDTH],
- ),
- ));
- total_num_constraints += PositionConstraint::num_active_constraints(manifold);
- }
-
- self.parallel_desc_groups.push(self.constraint_descs.len());
- }
-
- // Resize the constraints set.
- self.constraints.clear();
- self.constraints
- .resize_with(total_num_constraints, || AnyPositionConstraint::Empty)
- }
-
- fn fill_constraints(
- &mut self,
- thread: &ThreadContext,
- params: &IntegrationParameters,
- bodies: &RigidBodySet,
- manifolds_all: &[&mut ContactManifold],
- ) {
- let descs = &self.constraint_descs;
-
- crate::concurrent_loop! {
- let batch_size = thread.batch_size;
- for desc in descs[thread.position_constraint_initialization_index, thread.num_initialized_position_constraints] {
- match &desc.1 {
- PositionConstraintDesc::NongroundNongrouped(manifold_id) => {
- let manifold = &*manifolds_all[*manifold_id];
- PositionConstraint::generate(
- params,
- manifold,
- bodies,
- &mut self.constraints,
- false,
- );
- }
- PositionConstraintDesc::GroundNongrouped(manifold_id) => {
- let manifold = &*manifolds_all[*manifold_id];
- PositionGroundConstraint::generate(
- params,
- manifold,
- bodies,
- &mut self.constraints,
- false,
- );
- }
- #[cfg(feature = "simd-is-enabled")]
- PositionConstraintDesc::NongroundGrouped(manifold_id) => {
- let manifolds = array![|ii| &*manifolds_all[manifold_id[ii]]; SIMD_WIDTH];
- WPositionConstraint::generate(
- params,
- manifolds,
- bodies,
- &mut self.constraints,
- false,
- );
- }
- #[cfg(feature = "simd-is-enabled")]
- PositionConstraintDesc::GroundGrouped(manifold_id) => {
- let manifolds = array![|ii| &*manifolds_all[manifold_id[ii]]; SIMD_WIDTH];
- WPositionGroundConstraint::generate(
- params,
- manifolds,
- bodies,
- &mut self.constraints,
- false,
- );
- }
- }
- }
- }
- }
-}
-
-pub(crate) struct ParallelPositionSolver {
- part: ParallelPositionSolverContactPart,
- joint_part: ParallelPositionSolverJointPart,
-}
+pub(crate) struct ParallelPositionSolver;
impl ParallelPositionSolver {
- pub fn new() -> Self {
- Self {
- part: ParallelPositionSolverContactPart::new(),
- joint_part: ParallelPositionSolverJointPart::new(),
- }
- }
-
- pub fn init_constraint_groups(
- &mut self,
- island_id: usize,
- bodies: &RigidBodySet,
- manifolds: &mut [&mut ContactManifold],
- manifold_groups: &ParallelInteractionGroups,
- joints: &mut [JointGraphEdge],
- joint_groups: &ParallelInteractionGroups,
- ) {
- self.part
- .init_constraints_groups(island_id, bodies, manifolds, manifold_groups);
- self.joint_part
- .init_constraints_groups(island_id, bodies, joints, joint_groups);
- }
-
- pub fn fill_constraints(
- &mut self,
- thread: &ThreadContext,
- params: &IntegrationParameters,
- bodies: &RigidBodySet,
- manifolds: &[&mut ContactManifold],
- joints: &[JointGraphEdge],
- ) {
- self.part
- .fill_constraints(thread, params, bodies, manifolds);
- self.joint_part.fill_constraints(thread, bodies, joints);
- ThreadContext::lock_until_ge(
- &thread.num_initialized_position_constraints,
- self.part.constraint_descs.len(),
- );
- ThreadContext::lock_until_ge(
- &thread.num_initialized_position_joint_constraints,
- self.joint_part.constraint_descs.len(),
- );
- }
-
- pub fn solve_constraints(
- &mut self,
+ pub fn solve(
thread: &ThreadContext,
params: &IntegrationParameters,
- positions: &mut [Isometry<f32>],
+ positions: &mut [Isometry<Real>],
+ contact_constraints: &mut ParallelSolverConstraints<
+ AnyVelocityConstraint,
+ AnyPositionConstraint,
+ >,
+ joint_constraints: &mut ParallelSolverConstraints<
+ AnyJointVelocityConstraint,
+ AnyJointPositionConstraint,
+ >,
) {
- if self.part.constraint_descs.len() == 0 {
+ if contact_constraints.constraint_descs.is_empty()
+ && joint_constraints.constraint_descs.is_empty()
+ {
return;
}
@@ -518,8 +40,8 @@ impl ParallelPositionSolver {
.solve_position_interaction_index
.fetch_add(thread.batch_size, Ordering::SeqCst);
let mut batch_size = thread.batch_size;
- let contact_descs = &self.part.constraint_descs[..];
- let joint_descs = &self.joint_part.constraint_descs[..];
+ let contact_descs = &contact_constraints.constraint_descs[..];
+ let joint_descs = &joint_constraints.constraint_descs[..];
let mut target_num_desc = 0;
let mut shift = 0;
@@ -535,9 +57,12 @@ impl ParallelPositionSolver {
let end_index = (start_index + batch_size).min(group[1]);
let constraints = if end_index == $part.constraint_descs.len() {
- &mut $part.constraints[$part.constraint_descs[start_index].0..]
+ &mut $part.position_constraints
+ [$part.constraint_descs[start_index].0..]
} else {
- &mut $part.constraints[$part.constraint_descs[start_index].0
+ &mut $part.position_constraints[$part.constraint_descs
+ [start_index]
+ .0
..$part.constraint_descs[end_index].0]
};
@@ -570,10 +95,10 @@ impl ParallelPositionSolver {
};
}
- solve!(self.joint_part);
+ solve!(joint_constraints);
shift += joint_descs.len();
start_index -= joint_descs.len();
- solve!(self.part);
+ solve!(contact_constraints);
shift += contact_descs.len();
start_index -= contact_descs.len();
}