aboutsummaryrefslogtreecommitdiff
path: root/src/dynamics/solver/solver_constraints.rs
diff options
context:
space:
mode:
authorCrozet Sébastien <developer@crozet.re>2020-12-31 10:32:34 +0100
committerCrozet Sébastien <developer@crozet.re>2020-12-31 10:32:34 +0100
commit64507a68e179ebc652f177e727fac5ff1a82d931 (patch)
treeb2d7173cd6484479d1b78cff08e547b28cddc426 /src/dynamics/solver/solver_constraints.rs
parent348a339fe350aff6d885cb5a857a0bb6afbea990 (diff)
downloadrapier-64507a68e179ebc652f177e727fac5ff1a82d931.tar.gz
rapier-64507a68e179ebc652f177e727fac5ff1a82d931.tar.bz2
rapier-64507a68e179ebc652f177e727fac5ff1a82d931.zip
Refactor the constraints solver code.
Diffstat (limited to 'src/dynamics/solver/solver_constraints.rs')
-rw-r--r--src/dynamics/solver/solver_constraints.rs383
1 files changed, 383 insertions, 0 deletions
diff --git a/src/dynamics/solver/solver_constraints.rs b/src/dynamics/solver/solver_constraints.rs
new file mode 100644
index 0000000..88371ba
--- /dev/null
+++ b/src/dynamics/solver/solver_constraints.rs
@@ -0,0 +1,383 @@
+use super::{
+ AnyJointVelocityConstraint, InteractionGroups, VelocityConstraint, VelocityGroundConstraint,
+};
+#[cfg(feature = "simd-is-enabled")]
+use super::{WVelocityConstraint, WVelocityGroundConstraint};
+use crate::dynamics::solver::categorization::{categorize_contacts, categorize_joints};
+use crate::dynamics::solver::{
+ AnyJointPositionConstraint, AnyPositionConstraint, PositionConstraint,
+ PositionGroundConstraint, WPositionConstraint, WPositionGroundConstraint,
+};
+use crate::dynamics::{
+ solver::{AnyVelocityConstraint, DeltaVel},
+ IntegrationParameters, JointGraphEdge, JointIndex, RigidBodySet,
+};
+use crate::geometry::{ContactManifold, ContactManifoldIndex};
+#[cfg(feature = "simd-is-enabled")]
+use crate::math::SIMD_WIDTH;
+use crate::utils::WAngularInertia;
+
+pub(crate) struct SolverConstraints<VelocityConstraint, PositionConstraint> {
+ pub not_ground_interactions: Vec<usize>,
+ pub ground_interactions: Vec<usize>,
+ pub interaction_groups: InteractionGroups,
+ pub ground_interaction_groups: InteractionGroups,
+ pub velocity_constraints: Vec<VelocityConstraint>,
+ pub position_constraints: Vec<PositionConstraint>,
+}
+
+impl<VelocityConstraint, PositionConstraint>
+ SolverConstraints<VelocityConstraint, PositionConstraint>
+{
+ pub fn new() -> Self {
+ Self {
+ not_ground_interactions: Vec::new(),
+ ground_interactions: Vec::new(),
+ interaction_groups: InteractionGroups::new(),
+ ground_interaction_groups: InteractionGroups::new(),
+ velocity_constraints: Vec::new(),
+ position_constraints: Vec::new(),
+ }
+ }
+}
+
+impl SolverConstraints<AnyVelocityConstraint, AnyPositionConstraint> {
+ pub fn init_constraint_groups(
+ &mut self,
+ island_id: usize,
+ bodies: &RigidBodySet,
+ manifolds: &[&mut ContactManifold],
+ manifold_indices: &[ContactManifoldIndex],
+ ) {
+ self.not_ground_interactions.clear();
+ self.ground_interactions.clear();
+ categorize_contacts(
+ bodies,
+ manifolds,
+ manifold_indices,
+ &mut self.ground_interactions,
+ &mut self.not_ground_interactions,
+ );
+
+ self.interaction_groups.clear_groups();
+ self.interaction_groups.group_manifolds(
+ island_id,
+ bodies,
+ manifolds,
+ &self.not_ground_interactions,
+ );
+
+ self.ground_interaction_groups.clear_groups();
+ self.ground_interaction_groups.group_manifolds(
+ island_id,
+ bodies,
+ manifolds,
+ &self.ground_interactions,
+ );
+
+ // NOTE: uncomment this do disable SIMD contact resolution.
+ // self.interaction_groups
+ // .nongrouped_interactions
+ // .append(&mut self.interaction_groups.grouped_interactions);
+ // self.ground_interaction_groups
+ // .nongrouped_interactions
+ // .append(&mut self.ground_interaction_groups.grouped_interactions);
+ }
+
+ pub fn init(
+ &mut self,
+ island_id: usize,
+ params: &IntegrationParameters,
+ bodies: &RigidBodySet,
+ manifolds: &[&mut ContactManifold],
+ manifold_indices: &[ContactManifoldIndex],
+ ) {
+ self.velocity_constraints.clear();
+ self.position_constraints.clear();
+
+ self.init_constraint_groups(island_id, bodies, manifolds, manifold_indices);
+
+ #[cfg(feature = "simd-is-enabled")]
+ {
+ self.compute_grouped_constraints(params, bodies, manifolds);
+ }
+ self.compute_nongrouped_constraints(params, bodies, manifolds);
+ #[cfg(feature = "simd-is-enabled")]
+ {
+ self.compute_grouped_ground_constraints(params, bodies, manifolds);
+ }
+ self.compute_nongrouped_ground_constraints(params, bodies, manifolds);
+ }
+
+ #[cfg(feature = "simd-is-enabled")]
+ fn compute_grouped_constraints(
+ &mut self,
+ params: &IntegrationParameters,
+ bodies: &RigidBodySet,
+ manifolds_all: &[&mut ContactManifold],
+ ) {
+ for manifolds_i in self
+ .interaction_groups
+ .grouped_interactions
+ .chunks_exact(SIMD_WIDTH)
+ {
+ let manifold_id = array![|ii| manifolds_i[ii]; SIMD_WIDTH];
+ let manifolds = array![|ii| &*manifolds_all[manifolds_i[ii]]; SIMD_WIDTH];
+ WVelocityConstraint::generate(
+ params,
+ manifold_id,
+ manifolds,
+ bodies,
+ &mut self.velocity_constraints,
+ true,
+ );
+ WPositionConstraint::generate(
+ params,
+ manifolds,
+ bodies,
+ &mut self.position_constraints,
+ true,
+ );
+ }
+ }
+
+ fn compute_nongrouped_constraints(
+ &mut self,
+ params: &IntegrationParameters,
+ bodies: &RigidBodySet,
+ manifolds_all: &[&mut ContactManifold],
+ ) {
+ for manifold_i in &self.interaction_groups.nongrouped_interactions {
+ let manifold = &manifolds_all[*manifold_i];
+ VelocityConstraint::generate(
+ params,
+ *manifold_i,
+ manifold,
+ bodies,
+ &mut self.velocity_constraints,
+ true,
+ );
+ PositionConstraint::generate(
+ params,
+ manifold,
+ bodies,
+ &mut self.position_constraints,
+ true,
+ );
+ }
+ }
+
+ #[cfg(feature = "simd-is-enabled")]
+ fn compute_grouped_ground_constraints(
+ &mut self,
+ params: &IntegrationParameters,
+ bodies: &RigidBodySet,
+ manifolds_all: &[&mut ContactManifold],
+ ) {
+ for manifolds_i in self
+ .ground_interaction_groups
+ .grouped_interactions
+ .chunks_exact(SIMD_WIDTH)
+ {
+ let manifold_id = array![|ii| manifolds_i[ii]; SIMD_WIDTH];
+ let manifolds = array![|ii| &*manifolds_all[manifolds_i[ii]]; SIMD_WIDTH];
+ WVelocityGroundConstraint::generate(
+ params,
+ manifold_id,
+ manifolds,
+ bodies,
+ &mut self.velocity_constraints,
+ true,
+ );
+ WPositionGroundConstraint::generate(
+ params,
+ manifolds,
+ bodies,
+ &mut self.position_constraints,
+ true,
+ );
+ }
+ }
+
+ fn compute_nongrouped_ground_constraints(
+ &mut self,
+ params: &IntegrationParameters,
+ bodies: &RigidBodySet,
+ manifolds_all: &[&mut ContactManifold],
+ ) {
+ for manifold_i in &self.ground_interaction_groups.nongrouped_interactions {
+ let manifold = &manifolds_all[*manifold_i];
+ VelocityGroundConstraint::generate(
+ params,
+ *manifold_i,
+ manifold,
+ bodies,
+ &mut self.velocity_constraints,
+ true,
+ );
+ PositionGroundConstraint::generate(
+ params,
+ manifold,
+ bodies,
+ &mut self.position_constraints,
+ true,
+ )
+ }
+ }
+}
+
+impl SolverConstraints<AnyJointVelocityConstraint, AnyJointPositionConstraint> {
+ pub fn init(
+ &mut self,
+ island_id: usize,
+ params: &IntegrationParameters,
+ bodies: &RigidBodySet,
+ joints: &[JointGraphEdge],
+ joint_constraint_indices: &[JointIndex],
+ ) {
+ // Generate constraints for joints.
+ self.not_ground_interactions.clear();
+ self.ground_interactions.clear();
+ categorize_joints(
+ bodies,
+ joints,
+ joint_constraint_indices,
+ &mut self.ground_interactions,
+ &mut self.not_ground_interactions,
+ );
+
+ self.velocity_constraints.clear();
+ self.position_constraints.clear();
+
+ self.interaction_groups.clear_groups();
+ self.interaction_groups.group_joints(
+ island_id,
+ bodies,
+ joints,
+ &self.not_ground_interactions,
+ );
+
+ self.ground_interaction_groups.clear_groups();
+ self.ground_interaction_groups.group_joints(
+ island_id,
+ bodies,
+ joints,
+ &self.ground_interactions,
+ );
+ // NOTE: uncomment this do disable SIMD joint resolution.
+ // self.interaction_groups
+ // .nongrouped_interactions
+ // .append(&mut self.interaction_groups.grouped_interactions);
+ // self.ground_interaction_groups
+ // .nongrouped_interactions
+ // .append(&mut self.ground_interaction_groups.grouped_interactions);
+
+ self.compute_nongrouped_joint_ground_constraints(params, bodies, joints);
+ #[cfg(feature = "simd-is-enabled")]
+ {
+ self.compute_grouped_joint_ground_constraints(params, bodies, joints);
+ }
+ self.compute_nongrouped_joint_constraints(params, bodies, joints);
+ #[cfg(feature = "simd-is-enabled")]
+ {
+ self.compute_grouped_joint_constraints(params, bodies, joints);
+ }
+ }
+
+ fn compute_nongrouped_joint_ground_constraints(
+ &mut self,
+ params: &IntegrationParameters,
+ bodies: &RigidBodySet,
+ joints_all: &[JointGraphEdge],
+ ) {
+ for joint_i in &self.ground_interaction_groups.nongrouped_interactions {
+ let joint = &joints_all[*joint_i].weight;
+ let vel_constraint =
+ AnyJointVelocityConstraint::from_joint_ground(params, *joint_i, joint, bodies);
+ self.velocity_constraints.push(vel_constraint);
+ let pos_constraint = AnyJointPositionConstraint::from_joint_ground(joint, bodies);
+ self.position_constraints.push(pos_constraint);
+ }
+ }
+
+ #[cfg(feature = "simd-is-enabled")]
+ fn compute_grouped_joint_ground_constraints(
+ &mut self,
+ params: &IntegrationParameters,
+ bodies: &RigidBodySet,
+ joints_all: &[JointGraphEdge],
+ ) {
+ for joints_i in self
+ .ground_interaction_groups
+ .grouped_interactions
+ .chunks_exact(SIMD_WIDTH)
+ {
+ let joints_id = array![|ii| joints_i[ii]; SIMD_WIDTH];
+ let joints = array![|ii| &joints_all[joints_i[ii]].weight; SIMD_WIDTH];
+ let vel_constraint = AnyJointVelocityConstraint::from_wide_joint_ground(
+ params, joints_id, joints, bodies,
+ );
+ self.velocity_constraints.push(vel_constraint);
+
+ if let Some(pos_constraint) =
+ AnyJointPositionConstraint::from_wide_joint_ground(joints, bodies)
+ {
+ self.position_constraints.push(pos_constraint);
+ } else {
+ for joint in joints.iter() {
+ self.position_constraints
+ .push(AnyJointPositionConstraint::from_joint_ground(
+ *joint, bodies,
+ ))
+ }
+ }
+ }
+ }
+
+ fn compute_nongrouped_joint_constraints(
+ &mut self,
+ params: &IntegrationParameters,
+ bodies: &RigidBodySet,
+ joints_all: &[JointGraphEdge],
+ ) {
+ for joint_i in &self.interaction_groups.nongrouped_interactions {
+ let joint = &joints_all[*joint_i].weight;
+ let vel_constraint =
+ AnyJointVelocityConstraint::from_joint(params, *joint_i, joint, bodies);
+ self.velocity_constraints.push(vel_constraint);
+ let pos_constraint = AnyJointPositionConstraint::from_joint(joint, bodies);
+ self.position_constraints.push(pos_constraint);
+ }
+ }
+
+ #[cfg(feature = "simd-is-enabled")]
+ fn compute_grouped_joint_constraints(
+ &mut self,
+ params: &IntegrationParameters,
+ bodies: &RigidBodySet,
+ joints_all: &[JointGraphEdge],
+ ) {
+ for joints_i in self
+ .interaction_groups
+ .grouped_interactions
+ .chunks_exact(SIMD_WIDTH)
+ {
+ let joints_id = array![|ii| joints_i[ii]; SIMD_WIDTH];
+ let joints = array![|ii| &joints_all[joints_i[ii]].weight; SIMD_WIDTH];
+ let vel_constraint =
+ AnyJointVelocityConstraint::from_wide_joint(params, joints_id, joints, bodies);
+ self.velocity_constraints.push(vel_constraint);
+
+ if let Some(pos_constraint) =
+ AnyJointPositionConstraint::from_wide_joint(joints, bodies)
+ {
+ self.position_constraints.push(pos_constraint);
+ } else {
+ for joint in joints.iter() {
+ self.position_constraints
+ .push(AnyJointPositionConstraint::from_joint(*joint, bodies))
+ }
+ }
+ }
+ }
+}