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#ifndef JPH_PLATFORM_DOXYGEN // Somehow Doxygen gets confused and thinks the parameters to CalculateSpringProperties belong to this macro
9JPH_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
10#endif // !JPH_PLATFORM_DOXYGEN
11
14{
15private:
16 JPH_INLINE void CalculateSpringPropertiesHelper(float inDeltaTime, float inInvEffectiveMass, float inBias, float inC, float inStiffness, float inDamping, float &outEffectiveMass)
17 {
18 // Soft constraints as per: Soft Contraints: Reinventing The Spring - Erin Catto - GDC 2011
19
20 // Note that the calculation of beta and gamma below are based on the solution of an implicit Euler integration scheme
21 // This scheme is unconditionally stable but has built in damping, so even when you set the damping ratio to 0 there will still
22 // be damping. See page 16 and 32.
23
24 // Calculate softness (gamma in the slides)
25 // See page 34 and note that the gamma needs to be divided by delta time since we're working with impulses rather than forces:
26 // softness = 1 / (dt * (c + dt * k))
27 // Note that the spring stiffness is k and the spring damping is c
28 mSoftness = 1.0f / (inDeltaTime * (inDamping + inDeltaTime * inStiffness));
29
30 // Calculate bias factor (baumgarte stabilization):
31 // beta = dt * k / (c + dt * k) = dt * k^2 * softness
32 // b = beta / dt * C = dt * k * softness * C
33 mBias = inBias + inDeltaTime * inStiffness * mSoftness * inC;
34
35 // Update the effective mass, see post by Erin Catto: http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=4&t=1354
36 //
37 // Newton's Law:
38 // M * (v2 - v1) = J^T * lambda
39 //
40 // Velocity constraint with softness and Baumgarte:
41 // J * v2 + softness * lambda + b = 0
42 //
43 // where b = beta * C / dt
44 //
45 // We know everything except v2 and lambda.
46 //
47 // First solve Newton's law for v2 in terms of lambda:
48 //
49 // v2 = v1 + M^-1 * J^T * lambda
50 //
51 // Substitute this expression into the velocity constraint:
52 //
53 // J * (v1 + M^-1 * J^T * lambda) + softness * lambda + b = 0
54 //
55 // Now collect coefficients of lambda:
56 //
57 // (J * M^-1 * J^T + softness) * lambda = - J * v1 - b
58 //
59 // Now we define:
60 //
61 // K = J * M^-1 * J^T + softness
62 //
63 // So our new effective mass is K^-1
64 outEffectiveMass = 1.0f / (inInvEffectiveMass + mSoftness);
65 }
66
67public:
71 inline void CalculateSpringPropertiesWithBias(float inBias)
72 {
73 mSoftness = 0.0f;
74 mBias = inBias;
75 }
76
86 inline void CalculateSpringPropertiesWithFrequencyAndDamping(float inDeltaTime, float inInvEffectiveMass, float inBias, float inC, float inFrequency, float inDamping, float &outEffectiveMass)
87 {
88 outEffectiveMass = 1.0f / inInvEffectiveMass;
89
90 if (inFrequency > 0.0f)
91 {
92 // Calculate angular frequency
93 float omega = 2.0f * JPH_PI * inFrequency;
94
95 // Calculate spring stiffness k and damping constant c (page 45)
96 float k = outEffectiveMass * Square(omega);
97 float c = 2.0f * outEffectiveMass * inDamping * omega;
98
99 CalculateSpringPropertiesHelper(inDeltaTime, inInvEffectiveMass, inBias, inC, k, c, outEffectiveMass);
100 }
101 else
102 {
104 }
105 }
106
116 inline void CalculateSpringPropertiesWithStiffnessAndDamping(float inDeltaTime, float inInvEffectiveMass, float inBias, float inC, float inStiffness, float inDamping, float &outEffectiveMass)
117 {
118 if (inStiffness > 0.0f)
119 {
120 CalculateSpringPropertiesHelper(inDeltaTime, inInvEffectiveMass, inBias, inC, inStiffness, inDamping, outEffectiveMass);
121 }
122 else
123 {
124 outEffectiveMass = 1.0f / inInvEffectiveMass;
125
127 }
128 }
129
131 inline bool IsActive() const
132 {
133 return mSoftness != 0.0f;
134 }
135
137 inline float GetBias(float inTotalLambda) const
138 {
139 // Remainder of post by Erin Catto: http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=4&t=1354
140 //
141 // Each iteration we are not computing the whole impulse, we are computing an increment to the impulse and we are updating the velocity.
142 // Also, as we solve each constraint we get a perfect v2, but then some other constraint will come along and mess it up.
143 // So we want to patch up the constraint while acknowledging the accumulated impulse and the damaged velocity.
144 // To help with that we use P for the accumulated impulse and lambda as the update. Mathematically we have:
145 //
146 // M * (v2new - v2damaged) = J^T * lambda
147 // J * v2new + softness * (total_lambda + lambda) + b = 0
148 //
149 // If we solve this we get:
150 //
151 // v2new = v2damaged + M^-1 * J^T * lambda
152 // J * (v2damaged + M^-1 * J^T * lambda) + softness * total_lambda + softness * lambda + b = 0
153 //
154 // (J * M^-1 * J^T + softness) * lambda = -(J * v2damaged + softness * total_lambda + b)
155 //
156 // So our lagrange multiplier becomes:
157 //
158 // lambda = -K^-1 (J v + softness * total_lambda + b)
159 //
160 // So we return the bias: softness * total_lambda + b
161 return mSoftness * inTotalLambda + mBias;
162 }
163
164private:
165 float mBias = 0.0f;
166 float mSoftness = 0.0f;
167};
168
#define JPH_NAMESPACE_END
Definition: Core.h:354
#define JPH_MSVC_SUPPRESS_WARNING(w)
Definition: Core.h:264
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:348
constexpr T Square(T inV)
Square a value.
Definition: Math.h:52
Class used in other constraint parts to calculate the required bias factor in the lagrange multiplier...
Definition: SpringPart.h:14
void CalculateSpringPropertiesWithFrequencyAndDamping(float inDeltaTime, float inInvEffectiveMass, float inBias, float inC, float inFrequency, float inDamping, float &outEffectiveMass)
Definition: SpringPart.h:86
void CalculateSpringPropertiesWithStiffnessAndDamping(float inDeltaTime, float inInvEffectiveMass, float inBias, float inC, float inStiffness, float inDamping, float &outEffectiveMass)
Definition: SpringPart.h:116
float GetBias(float inTotalLambda) const
Get total bias b, including supplied bias and bias for spring: lambda = J v + b.
Definition: SpringPart.h:137
void CalculateSpringPropertiesWithBias(float inBias)
Definition: SpringPart.h:71
bool IsActive() const
Returns if this spring is active.
Definition: SpringPart.h:131