-
Notifications
You must be signed in to change notification settings - Fork 0
/
damped_rotary_spring.go
69 lines (51 loc) · 1.67 KB
/
damped_rotary_spring.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package cm
import "math"
type DampedRotarySpring struct {
*Constraint
RestAngle, Stiffness, Damping float64
SpringTorqueFunc func(spring *DampedRotarySpring, relativeAngle float64) float64
targetWrn, wCoef float64
iSum, jAcc float64
}
func defaultSpringTorque(spring *DampedRotarySpring, relativeAngle float64) float64 {
return (relativeAngle - spring.RestAngle) * spring.Stiffness
}
func NewDampedRotarySpring(a, b *Body, restAngle, stiffness, damping float64) *Constraint {
joint := &DampedRotarySpring{
RestAngle: restAngle,
Stiffness: stiffness,
Damping: damping,
SpringTorqueFunc: defaultSpringTorque,
}
joint.Constraint = NewConstraint(joint, a, b)
return joint.Constraint
}
func (spring *DampedRotarySpring) PreStep(dt float64) {
a := spring.bodyA
b := spring.bodyB
moment := a.momentOfInertiaInverse + b.momentOfInertiaInverse
spring.iSum = 1.0 / moment
spring.wCoef = 1.0 - math.Exp(-spring.Damping*dt*moment)
spring.targetWrn = 0
jSpring := spring.SpringTorqueFunc(spring, a.angle-b.angle) * dt
spring.jAcc = jSpring
a.w -= jSpring * a.momentOfInertiaInverse
b.w += jSpring * b.momentOfInertiaInverse
}
func (joint *DampedRotarySpring) ApplyCachedImpulse(dtCoef float64) {
// nothing to do here
}
func (spring *DampedRotarySpring) ApplyImpulse(dt float64) {
a := spring.bodyA
b := spring.bodyB
wrn := a.w - b.w
wDamp := (spring.targetWrn - wrn) * spring.wCoef
spring.targetWrn = wrn + wDamp
jDamp := wDamp * spring.iSum
spring.jAcc += jDamp
a.w += jDamp * a.momentOfInertiaInverse
b.w -= jDamp * b.momentOfInertiaInverse
}
func (joint *DampedRotarySpring) GetImpulse() float64 {
return joint.jAcc
}