aboutsummaryrefslogtreecommitdiff
path: root/src/dynamics/solver/joint_constraint/joint_position_constraint.rs
diff options
context:
space:
mode:
authorSébastien Crozet <developer@crozet.re>2020-08-25 22:10:25 +0200
committerSébastien Crozet <developer@crozet.re>2020-08-25 22:10:25 +0200
commit754a48b7ff6d8c58b1ee08651e60112900b60455 (patch)
tree7d777a6c003f1f5d8f8d24f533f35a95a88957fe /src/dynamics/solver/joint_constraint/joint_position_constraint.rs
downloadrapier-0.1.0.tar.gz
rapier-0.1.0.tar.bz2
rapier-0.1.0.zip
First public release of Rapier.v0.1.0
Diffstat (limited to 'src/dynamics/solver/joint_constraint/joint_position_constraint.rs')
-rw-r--r--src/dynamics/solver/joint_constraint/joint_position_constraint.rs169
1 files changed, 169 insertions, 0 deletions
diff --git a/src/dynamics/solver/joint_constraint/joint_position_constraint.rs b/src/dynamics/solver/joint_constraint/joint_position_constraint.rs
new file mode 100644
index 0000000..4773687
--- /dev/null
+++ b/src/dynamics/solver/joint_constraint/joint_position_constraint.rs
@@ -0,0 +1,169 @@
+use super::{
+ BallPositionConstraint, BallPositionGroundConstraint, FixedPositionConstraint,
+ FixedPositionGroundConstraint, PrismaticPositionConstraint, PrismaticPositionGroundConstraint,
+};
+#[cfg(feature = "dim3")]
+use super::{RevolutePositionConstraint, RevolutePositionGroundConstraint};
+#[cfg(feature = "simd-is-enabled")]
+use super::{WBallPositionConstraint, WBallPositionGroundConstraint};
+use crate::dynamics::{IntegrationParameters, Joint, JointParams, RigidBodySet};
+use crate::math::Isometry;
+#[cfg(feature = "simd-is-enabled")]
+use crate::math::SIMD_WIDTH;
+
+pub(crate) enum AnyJointPositionConstraint {
+ BallJoint(BallPositionConstraint),
+ BallGroundConstraint(BallPositionGroundConstraint),
+ #[cfg(feature = "simd-is-enabled")]
+ WBallJoint(WBallPositionConstraint),
+ #[cfg(feature = "simd-is-enabled")]
+ WBallGroundConstraint(WBallPositionGroundConstraint),
+ FixedJoint(FixedPositionConstraint),
+ FixedGroundConstraint(FixedPositionGroundConstraint),
+ PrismaticJoint(PrismaticPositionConstraint),
+ PrismaticGroundConstraint(PrismaticPositionGroundConstraint),
+ #[cfg(feature = "dim3")]
+ RevoluteJoint(RevolutePositionConstraint),
+ #[cfg(feature = "dim3")]
+ RevoluteGroundConstraint(RevolutePositionGroundConstraint),
+ #[allow(dead_code)] // The Empty variant is only used with parallel code.
+ Empty,
+}
+
+impl AnyJointPositionConstraint {
+ #[cfg(feature = "parallel")]
+ pub fn num_active_constraints(joint: &Joint, grouped: bool) -> usize {
+ #[cfg(feature = "simd-is-enabled")]
+ if !grouped {
+ 1
+ } else {
+ match &joint.params {
+ JointParams::BallJoint(_) => 1,
+ _ => SIMD_WIDTH, // For joints that don't support SIMD position constraints yet.
+ }
+ }
+
+ #[cfg(not(feature = "simd-is-enabled"))]
+ {
+ 1
+ }
+ }
+
+ pub fn from_joint(joint: &Joint, bodies: &RigidBodySet) -> Self {
+ let rb1 = &bodies[joint.body1];
+ let rb2 = &bodies[joint.body2];
+
+ match &joint.params {
+ JointParams::BallJoint(p) => AnyJointPositionConstraint::BallJoint(
+ BallPositionConstraint::from_params(rb1, rb2, p),
+ ),
+ JointParams::FixedJoint(p) => AnyJointPositionConstraint::FixedJoint(
+ FixedPositionConstraint::from_params(rb1, rb2, p),
+ ),
+ JointParams::PrismaticJoint(p) => AnyJointPositionConstraint::PrismaticJoint(
+ PrismaticPositionConstraint::from_params(rb1, rb2, p),
+ ),
+ #[cfg(feature = "dim3")]
+ JointParams::RevoluteJoint(p) => AnyJointPositionConstraint::RevoluteJoint(
+ RevolutePositionConstraint::from_params(rb1, rb2, p),
+ ),
+ }
+ }
+
+ #[cfg(feature = "simd-is-enabled")]
+ pub fn from_wide_joint(joints: [&Joint; SIMD_WIDTH], bodies: &RigidBodySet) -> Option<Self> {
+ let rbs1 = array![|ii| &bodies[joints[ii].body1]; SIMD_WIDTH];
+ let rbs2 = array![|ii| &bodies[joints[ii].body2]; SIMD_WIDTH];
+
+ match &joints[0].params {
+ JointParams::BallJoint(_) => {
+ let joints = array![|ii| joints[ii].params.as_ball_joint().unwrap(); SIMD_WIDTH];
+ Some(AnyJointPositionConstraint::WBallJoint(
+ WBallPositionConstraint::from_params(rbs1, rbs2, joints),
+ ))
+ }
+ JointParams::FixedJoint(_) => None,
+ JointParams::PrismaticJoint(_) => None,
+ #[cfg(feature = "dim3")]
+ JointParams::RevoluteJoint(_) => None,
+ }
+ }
+
+ pub fn from_joint_ground(joint: &Joint, bodies: &RigidBodySet) -> Self {
+ let mut rb1 = &bodies[joint.body1];
+ let mut rb2 = &bodies[joint.body2];
+ let flipped = !rb2.is_dynamic();
+
+ if flipped {
+ std::mem::swap(&mut rb1, &mut rb2);
+ }
+
+ match &joint.params {
+ JointParams::BallJoint(p) => AnyJointPositionConstraint::BallGroundConstraint(
+ BallPositionGroundConstraint::from_params(rb1, rb2, p, flipped),
+ ),
+ JointParams::FixedJoint(p) => AnyJointPositionConstraint::FixedGroundConstraint(
+ FixedPositionGroundConstraint::from_params(rb1, rb2, p, flipped),
+ ),
+ JointParams::PrismaticJoint(p) => {
+ AnyJointPositionConstraint::PrismaticGroundConstraint(
+ PrismaticPositionGroundConstraint::from_params(rb1, rb2, p, flipped),
+ )
+ }
+ #[cfg(feature = "dim3")]
+ JointParams::RevoluteJoint(p) => AnyJointPositionConstraint::RevoluteGroundConstraint(
+ RevolutePositionGroundConstraint::from_params(rb1, rb2, p, flipped),
+ ),
+ }
+ }
+
+ #[cfg(feature = "simd-is-enabled")]
+ pub fn from_wide_joint_ground(
+ joints: [&Joint; SIMD_WIDTH],
+ bodies: &RigidBodySet,
+ ) -> Option<Self> {
+ let mut rbs1 = array![|ii| &bodies[joints[ii].body1]; SIMD_WIDTH];
+ let mut rbs2 = array![|ii| &bodies[joints[ii].body2]; SIMD_WIDTH];
+ let mut flipped = [false; SIMD_WIDTH];
+
+ for ii in 0..SIMD_WIDTH {
+ if !rbs2[ii].is_dynamic() {
+ std::mem::swap(&mut rbs1[ii], &mut rbs2[ii]);
+ flipped[ii] = true;
+ }
+ }
+
+ match &joints[0].params {
+ JointParams::BallJoint(_) => {
+ let joints = array![|ii| joints[ii].params.as_ball_joint().unwrap(); SIMD_WIDTH];
+ Some(AnyJointPositionConstraint::WBallGroundConstraint(
+ WBallPositionGroundConstraint::from_params(rbs1, rbs2, joints, flipped),
+ ))
+ }
+ JointParams::FixedJoint(_) => None,
+ JointParams::PrismaticJoint(_) => None,
+ #[cfg(feature = "dim3")]
+ JointParams::RevoluteJoint(_) => None,
+ }
+ }
+
+ pub fn solve(&self, params: &IntegrationParameters, positions: &mut [Isometry<f32>]) {
+ match self {
+ AnyJointPositionConstraint::BallJoint(c) => c.solve(params, positions),
+ AnyJointPositionConstraint::BallGroundConstraint(c) => c.solve(params, positions),
+ #[cfg(feature = "simd-is-enabled")]
+ AnyJointPositionConstraint::WBallJoint(c) => c.solve(params, positions),
+ #[cfg(feature = "simd-is-enabled")]
+ AnyJointPositionConstraint::WBallGroundConstraint(c) => c.solve(params, positions),
+ AnyJointPositionConstraint::FixedJoint(c) => c.solve(params, positions),
+ AnyJointPositionConstraint::FixedGroundConstraint(c) => c.solve(params, positions),
+ AnyJointPositionConstraint::PrismaticJoint(c) => c.solve(params, positions),
+ AnyJointPositionConstraint::PrismaticGroundConstraint(c) => c.solve(params, positions),
+ #[cfg(feature = "dim3")]
+ AnyJointPositionConstraint::RevoluteJoint(c) => c.solve(params, positions),
+ #[cfg(feature = "dim3")]
+ AnyJointPositionConstraint::RevoluteGroundConstraint(c) => c.solve(params, positions),
+ AnyJointPositionConstraint::Empty => unreachable!(),
+ }
+ }
+}