diff options
| author | Sébastien Crozet <developer@crozet.re> | 2022-01-02 18:05:50 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-02 18:05:50 +0100 |
| commit | 1308db89948bc62fb865b32f832f19268f23dd23 (patch) | |
| tree | b3d8b0cbb6d2e75aa8fc7686e9cb8801527a31b8 /src/dynamics/solver/velocity_constraint_element.rs | |
| parent | 8e7da5ad45d180b0d3fa2bde37f8f3771b153b70 (diff) | |
| parent | 9f9d3293605fa84555c08bec5efe68a71cd18432 (diff) | |
| download | rapier-1308db89948bc62fb865b32f832f19268f23dd23.tar.gz rapier-1308db89948bc62fb865b32f832f19268f23dd23.tar.bz2 rapier-1308db89948bc62fb865b32f832f19268f23dd23.zip | |
Merge pull request #267 from dimforge/multibody
Implement multibody joints, and new velocity-based constraints solver
Diffstat (limited to 'src/dynamics/solver/velocity_constraint_element.rs')
| -rw-r--r-- | src/dynamics/solver/velocity_constraint_element.rs | 114 |
1 files changed, 24 insertions, 90 deletions
diff --git a/src/dynamics/solver/velocity_constraint_element.rs b/src/dynamics/solver/velocity_constraint_element.rs index cb6d476..406f68e 100644 --- a/src/dynamics/solver/velocity_constraint_element.rs +++ b/src/dynamics/solver/velocity_constraint_element.rs @@ -9,49 +9,24 @@ pub(crate) struct VelocityConstraintTangentPart<N: SimdRealField + Copy> { pub gcross2: [AngVector<N>; DIM - 1], pub rhs: [N; DIM - 1], #[cfg(feature = "dim2")] - pub impulse: [N; DIM - 1], + pub impulse: na::Vector1<N>, #[cfg(feature = "dim3")] pub impulse: na::Vector2<N>, pub r: [N; DIM - 1], } impl<N: SimdRealField + Copy> VelocityConstraintTangentPart<N> { - #[cfg(any(not(target_arch = "wasm32"), feature = "simd-is-enabled"))] fn zero() -> Self { Self { gcross1: [na::zero(); DIM - 1], gcross2: [na::zero(); DIM - 1], rhs: [na::zero(); DIM - 1], - #[cfg(feature = "dim2")] - impulse: [na::zero(); DIM - 1], - #[cfg(feature = "dim3")] impulse: na::zero(), r: [na::zero(); DIM - 1], } } #[inline] - pub fn warmstart( - &self, - tangents1: [&Vector<N>; DIM - 1], - im1: N, - im2: N, - mj_lambda1: &mut DeltaVel<N>, - mj_lambda2: &mut DeltaVel<N>, - ) where - AngVector<N>: WDot<AngVector<N>, Result = N>, - N::Element: SimdRealField + Copy, - { - for j in 0..DIM - 1 { - mj_lambda1.linear += tangents1[j] * (im1 * self.impulse[j]); - mj_lambda1.angular += self.gcross1[j] * self.impulse[j]; - - mj_lambda2.linear += tangents1[j] * (-im2 * self.impulse[j]); - mj_lambda2.angular += self.gcross2[j] * self.impulse[j]; - } - } - - #[inline] pub fn solve( &mut self, tangents1: [&Vector<N>; DIM - 1], @@ -125,41 +100,24 @@ pub(crate) struct VelocityConstraintNormalPart<N: SimdRealField + Copy> { pub gcross1: AngVector<N>, pub gcross2: AngVector<N>, pub rhs: N, + pub rhs_wo_bias: N, pub impulse: N, pub r: N, } impl<N: SimdRealField + Copy> VelocityConstraintNormalPart<N> { - #[cfg(any(not(target_arch = "wasm32"), feature = "simd-is-enabled"))] fn zero() -> Self { Self { gcross1: na::zero(), gcross2: na::zero(), rhs: na::zero(), + rhs_wo_bias: na::zero(), impulse: na::zero(), r: na::zero(), } } #[inline] - pub fn warmstart( - &self, - dir1: &Vector<N>, - im1: N, - im2: N, - mj_lambda1: &mut DeltaVel<N>, - mj_lambda2: &mut DeltaVel<N>, - ) where - AngVector<N>: WDot<AngVector<N>, Result = N>, - { - mj_lambda1.linear += dir1 * (im1 * self.impulse); - mj_lambda1.angular += self.gcross1 * self.impulse; - - mj_lambda2.linear += dir1 * (-im2 * self.impulse); - mj_lambda2.angular += self.gcross2 * self.impulse; - } - - #[inline] pub fn solve( &mut self, dir1: &Vector<N>, @@ -193,7 +151,6 @@ pub(crate) struct VelocityConstraintElement<N: SimdRealField + Copy> { } impl<N: SimdRealField + Copy> VelocityConstraintElement<N> { - #[cfg(any(not(target_arch = "wasm32"), feature = "simd-is-enabled"))] pub fn zero() -> Self { Self { normal_part: VelocityConstraintNormalPart::zero(), @@ -202,35 +159,6 @@ impl<N: SimdRealField + Copy> VelocityConstraintElement<N> { } #[inline] - pub fn warmstart_group( - elements: &[Self], - dir1: &Vector<N>, - #[cfg(feature = "dim3")] tangent1: &Vector<N>, - im1: N, - im2: N, - mj_lambda1: &mut DeltaVel<N>, - mj_lambda2: &mut DeltaVel<N>, - ) where - Vector<N>: WBasis, - AngVector<N>: WDot<AngVector<N>, Result = N>, - N::Element: SimdRealField + Copy, - { - #[cfg(feature = "dim3")] - let tangents1 = [tangent1, &dir1.cross(&tangent1)]; - #[cfg(feature = "dim2")] - let tangents1 = [&dir1.orthonormal_vector()]; - - for element in elements { - element - .tangent_part - .warmstart(tangents1, im1, im2, mj_lambda1, mj_lambda2); - element - .normal_part - .warmstart(dir1, im1, im2, mj_lambda1, mj_lambda2); - } - } - - #[inline] pub fn solve_group( elements: &mut [Self], dir1: &Vector<N>, @@ -240,28 +168,34 @@ impl<N: SimdRealField + Copy> VelocityConstraintElement<N> { limit: N, mj_lambda1: &mut DeltaVel<N>, mj_lambda2: &mut DeltaVel<N>, + solve_normal: bool, + solve_friction: bool, ) where Vector<N>: WBasis, AngVector<N>: WDot<AngVector<N>, Result = N>, N::Element: SimdRealField + Copy, { - // Solve friction. - #[cfg(feature = "dim3")] - let tangents1 = [tangent1, &dir1.cross(&tangent1)]; - #[cfg(feature = "dim2")] - let tangents1 = [&dir1.orthonormal_vector()]; - - for element in elements.iter_mut() { - let limit = limit * element.normal_part.impulse; - let part = &mut element.tangent_part; - part.solve(tangents1, im1, im2, limit, mj_lambda1, mj_lambda2); + // Solve penetration. + if solve_normal { + for element in elements.iter_mut() { + element + .normal_part + .solve(&dir1, im1, im2, mj_lambda1, mj_lambda2); + } } - // Solve penetration. - for element in elements.iter_mut() { - element - .normal_part - .solve(&dir1, im1, im2, mj_lambda1, mj_lambda2); + // Solve friction. + if solve_friction { + #[cfg(feature = "dim3")] + let tangents1 = [tangent1, &dir1.cross(&tangent1)]; + #[cfg(feature = "dim2")] + let tangents1 = [&dir1.orthonormal_vector()]; + + for element in elements.iter_mut() { + let limit = limit * element.normal_part.impulse; + let part = &mut element.tangent_part; + part.solve(tangents1, im1, im2, limit, mj_lambda1, mj_lambda2); + } } } } |
