Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
AngularFrictionConstraintPart.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2026 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
8
10
12template <EMotionType Type1>
13class AngularFrictionConstraintPart1 : public ContactConstraintPart1<EMotionType::Static>
14{
15};
16
17template <>
19{
20protected:
21 // Note: Constructor will not be called
23};
24
25template <EMotionType Type2>
29
30template <>
32{
33protected:
34 // Note: Constructor will not be called
36};
37
39template <EMotionType Type1, EMotionType Type2>
41{
43 JPH_INLINE bool ApplyVelocityStep(Vec3 &ioAngularVelocity1, Vec3 &ioAngularVelocity2, float inLambda) const
44 {
45 // Apply impulse if delta is not zero
46 if (inLambda != 0.0f)
47 {
48 if constexpr (Type1 == EMotionType::Dynamic)
49 ioAngularVelocity1 -= inLambda * Vec3::sLoadFloat3Unsafe(this->mInvI1_Axis);
50 if constexpr (Type2 == EMotionType::Dynamic)
51 ioAngularVelocity2 += inLambda * Vec3::sLoadFloat3Unsafe(this->mInvI2_Axis);
52 return true;
53 }
54
55 return false;
56 }
57
58public:
60 inline void CalculateConstraintProperties(Mat44Arg inInvI1, Mat44Arg inInvI2, Vec3Arg inWorldSpaceAxis, float inBias = 0.0f)
61 {
62 JPH_ASSERT(inWorldSpaceAxis.IsNormalized(1.0e-4f));
63
64 // Store bias
65 mBias = inBias;
66
67 Vec3 invi1_axis, invi2_axis;
68 if constexpr (Type1 == EMotionType::Dynamic)
69 {
70 invi1_axis = inInvI1.Multiply3x3(inWorldSpaceAxis);
71 invi1_axis.StoreFloat3(&this->mInvI1_Axis);
72 }
73 if constexpr (Type2 == EMotionType::Dynamic)
74 {
75 invi2_axis = inInvI2.Multiply3x3(inWorldSpaceAxis);
76 invi2_axis.StoreFloat3(&this->mInvI2_Axis);
77 }
78
79 float inv_effective_mass = 0.0f;
80 if constexpr (Type1 == EMotionType::Dynamic && Type2 == EMotionType::Dynamic)
81 inv_effective_mass = inWorldSpaceAxis.Dot(invi1_axis + invi2_axis);
82 else if constexpr (Type1 == EMotionType::Dynamic)
83 inv_effective_mass = inWorldSpaceAxis.Dot(invi1_axis);
84 else if constexpr (Type2 == EMotionType::Dynamic)
85 inv_effective_mass = inWorldSpaceAxis.Dot(invi2_axis);
86 else
87 JPH_ASSERT(false); // Static vs static is nonsensical!
88
89 if (inv_effective_mass == 0.0f)
90 this->Deactivate();
91 else
92 this->mEffectiveMass = 1.0f / inv_effective_mass;
93 }
94
96 inline bool WarmStart(Vec3 &ioAngularVelocity1, Vec3 &ioAngularVelocity2, float inWarmStartImpulseRatio)
97 {
98 this->mTotalLambda *= inWarmStartImpulseRatio;
99 return ApplyVelocityStep(ioAngularVelocity1, ioAngularVelocity2, this->mTotalLambda);
100 }
101
103 inline bool SolveVelocityConstraint(Vec3 &ioAngularVelocity1, Vec3 &ioAngularVelocity2, Vec3Arg inWorldSpaceAxis, float inMinLambda, float inMaxLambda)
104 {
105 float jv;
106 if constexpr (Type1 != EMotionType::Static && Type2 != EMotionType::Static)
107 jv = inWorldSpaceAxis.Dot(ioAngularVelocity1 - ioAngularVelocity2);
108 else if constexpr (Type1 != EMotionType::Static)
109 jv = inWorldSpaceAxis.Dot(ioAngularVelocity1);
110 else if constexpr (Type2 != EMotionType::Static)
111 jv = -inWorldSpaceAxis.Dot(ioAngularVelocity2);
112 else
113 JPH_ASSERT(false); // Static vs static is nonsensical!
114
115 float lambda = this->mEffectiveMass * (jv - mBias);
116 float new_lambda = Clamp(this->mTotalLambda + lambda, inMinLambda, inMaxLambda); // Clamp impulse
117 lambda = new_lambda - this->mTotalLambda; // Lambda potentially got clamped, calculate the new impulse to apply
118 this->mTotalLambda = new_lambda; // Store accumulated impulse
119
120 return ApplyVelocityStep(ioAngularVelocity1, ioAngularVelocity2, lambda);
121 }
122
123private:
124 // Note: Constructor will not be called. This serves as 1 extra float so we can read the previous member using Vec3::sLoadFloat3Unsafe
125 float mBias;
126};
127
128static_assert(sizeof(AngularFrictionConstraintPart<EMotionType::Dynamic, EMotionType::Dynamic>) == 3 * sizeof(float) + 2 * sizeof(Float3));
129static_assert(sizeof(AngularFrictionConstraintPart<EMotionType::Dynamic, EMotionType::Kinematic>) == 3 * sizeof(float) + sizeof(Float3));
130static_assert(sizeof(AngularFrictionConstraintPart<EMotionType::Dynamic, EMotionType::Static>) == 3 * sizeof(float) + sizeof(Float3));
131static_assert(sizeof(AngularFrictionConstraintPart<EMotionType::Kinematic, EMotionType::Dynamic>) == 3 * sizeof(float) + sizeof(Float3));
134static_assert(sizeof(AngularFrictionConstraintPart<EMotionType::Static, EMotionType::Dynamic>) == 3 * sizeof(float) + sizeof(Float3));
136static_assert(sizeof(AngularFrictionConstraintPart<EMotionType::Static, EMotionType::Static>) == 3 * sizeof(float));
137
#define JPH_NAMESPACE_END
Definition Core.h:434
#define JPH_NAMESPACE_BEGIN
Definition Core.h:428
#define JPH_ASSERT(...)
Definition IssueReporting.h:33
JPH_INLINE constexpr T Clamp(T inV, T inMin, T inMax)
Clamp a value between two values.
Definition Math.h:63
EMotionType
Motion type of a physics body.
Definition MotionType.h:11
@ Static
Non movable.
@ Dynamic
Responds to forces as a normal physics object.
Float3 mInvI1_Axis
Definition AngularFrictionConstraintPart.h:22
Decide which members this constraint part needs based on motion type.
Definition AngularFrictionConstraintPart.h:14
Float3 mInvI2_Axis
Definition AngularFrictionConstraintPart.h:35
Definition AngularFrictionConstraintPart.h:27
This is a copy of AngleConstraintPart, specialized to handle contact constraints. See the documentati...
Definition AngularFrictionConstraintPart.h:41
bool SolveVelocityConstraint(Vec3 &ioAngularVelocity1, Vec3 &ioAngularVelocity2, Vec3Arg inWorldSpaceAxis, float inMinLambda, float inMaxLambda)
See: AngleConstraintPart::SolveVelocityConstraint.
Definition AngularFrictionConstraintPart.h:103
bool WarmStart(Vec3 &ioAngularVelocity1, Vec3 &ioAngularVelocity2, float inWarmStartImpulseRatio)
See: AngleConstraintPart::WarmStart.
Definition AngularFrictionConstraintPart.h:96
void CalculateConstraintProperties(Mat44Arg inInvI1, Mat44Arg inInvI2, Vec3Arg inWorldSpaceAxis, float inBias=0.0f)
See: AngleConstraintPart::CalculateConstraintProperties.
Definition AngularFrictionConstraintPart.h:60
Decide which members this constraint part needs based on motion type.
Definition ContactConstraintPart.h:14
float mEffectiveMass
Definition ContactConstraintPart.h:43
void Deactivate()
Definition ContactConstraintPart.h:17
float mTotalLambda
Definition ContactConstraintPart.h:44
Class that holds 3 floats. Used as a storage class. Convert to Vec3 for calculations.
Definition Float3.h:13
Holds a 4x4 matrix of floats, but supports also operations on the 3x3 upper left part of the matrix.
Definition Mat44.h:13
JPH_INLINE Vec3 Multiply3x3(Vec3Arg inV) const
Multiply vector by only 3x3 part of the matrix.
Definition Mat44.inl:384
Definition Vec3.h:17
JPH_INLINE float Dot(Vec3Arg inV2) const
Dot product.
Definition Vec3.inl:931
JPH_INLINE bool IsNormalized(float inTolerance=1.0e-6f) const
Test if vector is normalized.
Definition Vec3.inl:1030
JPH_INLINE void StoreFloat3(Float3 *outV) const
Store 3 floats to memory.
Definition Vec3.inl:1055
static JPH_INLINE Vec3 sLoadFloat3Unsafe(const Float3 &inV)
Load 3 floats from memory (reads 32 bits extra which it doesn't use)
Definition Vec3.inl:167