Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
SpringPart.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
8
10#ifndef JPH_PLATFORM_DOXYGEN // Somehow Doxygen gets confused and thinks the parameters to CalculateSpringProperties belong to this macro
11JPH_MSVC_SUPPRESS_WARNING(4723) // potential divide by 0 - caused by line: outEffectiveMass = 1.0f / inInvEffectiveMass, note that JPH_NAMESPACE_BEGIN already pushes the warning state
12#endif // !JPH_PLATFORM_DOXYGEN
13
16{
17public:
21 JPH_INLINE void CalculateSpringPropertiesWithBias(float inBias)
22 {
23 mSoftness = 0.0f;
24 mBias = inBias;
25 }
26
36 JPH_INLINE void CalculateSpringPropertiesWithStiffnessAndDamping(float inDeltaTime, float inInvEffectiveMass, float inBias, float inC, float inStiffness, float inDamping, float &outEffectiveMass)
37 {
38 JPH_ASSERT(inStiffness > 0.0f || inDamping > 0.0f);
39
40 // Soft constraints as per: Soft Constraints: Reinventing The Spring - Erin Catto - GDC 2011
41
42 // Note that the calculation of beta and gamma below are based on the solution of an implicit Euler integration scheme
43 // This scheme is unconditionally stable but has built in damping, so even when you set the damping ratio to 0 there will still
44 // be damping. See page 16 and 32.
45
46 // Calculate softness (gamma in the slides)
47 // See page 34 and note that the gamma needs to be divided by delta time since we're working with impulses rather than forces:
48 // softness = 1 / (dt * (c + dt * k))
49 // Note that the spring stiffness is k and the spring damping is c
50 mSoftness = 1.0f / (inDeltaTime * (inDamping + inDeltaTime * inStiffness));
51
52 // Calculate bias factor (baumgarte stabilization):
53 // beta = dt * k / (c + dt * k) = dt * k^2 * softness
54 // b = beta / dt * C = dt * k * softness * C
55 mBias = inBias + inDeltaTime * inStiffness * mSoftness * inC;
56
57 // Update the effective mass, see post by Erin Catto: http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=4&t=1354
58 //
59 // Newton's Law:
60 // M * (v2 - v1) = J^T * lambda
61 //
62 // Velocity constraint with softness and Baumgarte:
63 // J * v2 + softness * lambda + b = 0
64 //
65 // where b = beta * C / dt
66 //
67 // We know everything except v2 and lambda.
68 //
69 // First solve Newton's law for v2 in terms of lambda:
70 //
71 // v2 = v1 + M^-1 * J^T * lambda
72 //
73 // Substitute this expression into the velocity constraint:
74 //
75 // J * (v1 + M^-1 * J^T * lambda) + softness * lambda + b = 0
76 //
77 // Now collect coefficients of lambda:
78 //
79 // (J * M^-1 * J^T + softness) * lambda = - J * v1 - b
80 //
81 // Now we define:
82 //
83 // K = J * M^-1 * J^T + softness
84 //
85 // So our new effective mass is K^-1
86 outEffectiveMass = 1.0f / (inInvEffectiveMass + mSoftness);
87 }
88
98 JPH_INLINE void CalculateSpringPropertiesWithFrequencyAndDamping(float inDeltaTime, float inInvEffectiveMass, float inBias, float inC, float inFrequency, float inDamping, float &outEffectiveMass)
99 {
100 JPH_ASSERT(inFrequency > 0.0f);
101
102 outEffectiveMass = 1.0f / inInvEffectiveMass;
103
104 // Calculate angular frequency
105 float omega = 2.0f * JPH_PI * inFrequency;
106
107 // Calculate spring stiffness k and damping constant c (page 45)
108 float k = outEffectiveMass * Square(omega);
109 float c = 2.0f * outEffectiveMass * inDamping * omega;
110
111 CalculateSpringPropertiesWithStiffnessAndDamping(inDeltaTime, inInvEffectiveMass, inBias, inC, k, c, outEffectiveMass);
112 }
113
123 JPH_INLINE void CalculateSpringPropertiesWithMassNormalizedStiffnessAndDamping(float inDeltaTime, float inInvEffectiveMass, float inBias, float inC, float inStiffness, float inDamping, float &outEffectiveMass)
124 {
125 CalculateSpringPropertiesWithStiffnessAndDamping(inDeltaTime, inInvEffectiveMass, inBias, inC, inStiffness / inInvEffectiveMass, inDamping / inInvEffectiveMass, outEffectiveMass);
126 }
127
130 JPH_INLINE void CalculateSpringPropertiesWithSettings(float inDeltaTime, float inInvEffectiveMass, float inBias, float inC, const SpringSettings &inSpringSettings, float &outEffectiveMass)
131 {
132 switch (inSpringSettings.mMode)
133 {
135 CalculateSpringPropertiesWithFrequencyAndDamping(inDeltaTime, inInvEffectiveMass, inBias, inC, inSpringSettings.mFrequency, inSpringSettings.mDamping, outEffectiveMass);
136 break;
138 CalculateSpringPropertiesWithStiffnessAndDamping(inDeltaTime, inInvEffectiveMass, inBias, inC, inSpringSettings.mStiffness, inSpringSettings.mDamping, outEffectiveMass);
139 break;
141 CalculateSpringPropertiesWithMassNormalizedStiffnessAndDamping(inDeltaTime, inInvEffectiveMass, inBias, inC, inSpringSettings.mStiffness, inSpringSettings.mDamping, outEffectiveMass);
142 break;
143 }
144 }
145
147 JPH_INLINE bool IsActive() const
148 {
149 return mSoftness != 0.0f;
150 }
151
153 JPH_INLINE float GetBias(float inTotalLambda) const
154 {
155 // Remainder of post by Erin Catto: http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=4&t=1354
156 //
157 // Each iteration we are not computing the whole impulse, we are computing an increment to the impulse and we are updating the velocity.
158 // Also, as we solve each constraint we get a perfect v2, but then some other constraint will come along and mess it up.
159 // So we want to patch up the constraint while acknowledging the accumulated impulse and the damaged velocity.
160 // To help with that we use P for the accumulated impulse and lambda as the update. Mathematically we have:
161 //
162 // M * (v2new - v2damaged) = J^T * lambda
163 // J * v2new + softness * (total_lambda + lambda) + b = 0
164 //
165 // If we solve this we get:
166 //
167 // v2new = v2damaged + M^-1 * J^T * lambda
168 // J * (v2damaged + M^-1 * J^T * lambda) + softness * total_lambda + softness * lambda + b = 0
169 //
170 // (J * M^-1 * J^T + softness) * lambda = -(J * v2damaged + softness * total_lambda + b)
171 //
172 // So our lagrange multiplier becomes:
173 //
174 // lambda = -K^-1 (J v + softness * total_lambda + b)
175 //
176 // So we return the bias: softness * total_lambda + b
177 return mSoftness * inTotalLambda + mBias;
178 }
179
180private:
181 float mBias = 0.0f;
182 float mSoftness = 0.0f;
183};
184
#define JPH_NAMESPACE_END
Definition Core.h:434
#define JPH_MSVC_SUPPRESS_WARNING(w)
Definition Core.h:338
#define JPH_NAMESPACE_BEGIN
Definition Core.h:428
#define JPH_ASSERT(...)
Definition IssueReporting.h:33
JPH_INLINE constexpr T Square(T inV)
Square a value.
Definition Math.h:70
@ MassNormalizedStiffnessAndDamping
Stiffness and damping divided by mass / inertia are specified (also known as acceleration mode)....
@ FrequencyAndDamping
Frequency and damping are specified.
@ StiffnessAndDamping
Stiffness and damping are specified.
Class used in other constraint parts to calculate the required bias factor in the lagrange multiplier...
Definition SpringPart.h:16
JPH_INLINE void CalculateSpringPropertiesWithMassNormalizedStiffnessAndDamping(float inDeltaTime, float inInvEffectiveMass, float inBias, float inC, float inStiffness, float inDamping, float &outEffectiveMass)
Definition SpringPart.h:123
JPH_INLINE bool IsActive() const
Returns if this spring is active.
Definition SpringPart.h:147
JPH_INLINE void CalculateSpringPropertiesWithFrequencyAndDamping(float inDeltaTime, float inInvEffectiveMass, float inBias, float inC, float inFrequency, float inDamping, float &outEffectiveMass)
Definition SpringPart.h:98
JPH_INLINE float GetBias(float inTotalLambda) const
Get total bias b, including supplied bias and bias for spring: lambda = J v + b.
Definition SpringPart.h:153
JPH_INLINE void CalculateSpringPropertiesWithStiffnessAndDamping(float inDeltaTime, float inInvEffectiveMass, float inBias, float inC, float inStiffness, float inDamping, float &outEffectiveMass)
Definition SpringPart.h:36
JPH_INLINE void CalculateSpringPropertiesWithBias(float inBias)
Definition SpringPart.h:21
JPH_INLINE void CalculateSpringPropertiesWithSettings(float inDeltaTime, float inInvEffectiveMass, float inBias, float inC, const SpringSettings &inSpringSettings, float &outEffectiveMass)
Definition SpringPart.h:130
Settings for a linear or angular spring.
Definition SpringSettings.h:24
float mStiffness
Definition SpringSettings.h:70
float mDamping
Definition SpringSettings.h:84
ESpringMode mMode
Selects the way in which the spring is defined. See the descriptions of the mFrequency,...
Definition SpringSettings.h:47
float mFrequency
Definition SpringSettings.h:54