-
Notifications
You must be signed in to change notification settings - Fork 33
/
motor.go
106 lines (87 loc) · 2.01 KB
/
motor.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package chipmunk
import (
"github.com/vova616/chipmunk/vect"
)
/*
SimpleMotor represents a joint that will rotate an object relative to another while also correctly moving it forward.
Most useful for turning wheels.
*/
type SimpleMotor struct {
BasicConstraint
iSum vect.Float
jAcc vect.Float
rate vect.Float
}
/*
PreStep calculates necessary values before the physics step is applied.
*/
func (joint *SimpleMotor) PreStep(dt vect.Float) {
a := joint.BodyA
b := joint.BodyB
// calculate moment of inertia coefficient.
joint.iSum = 1.0/(a.i_inv + b.i_inv)
}
/*
ApplyCachedImpulse applies the cached impulse to the connected bodies.
*/
func (joint *SimpleMotor) ApplyCachedImpulse(dt_coef vect.Float) {
a := joint.BodyA
b := joint.BodyB
j := joint.jAcc*dt_coef
a.w -= j*a.i_inv
b.w += j*b.i_inv
}
/*
ApplyImpule applies the motors impulse to the connected bodies.
*/
func (joint *SimpleMotor) ApplyImpulse() {
a := joint.BodyA
b := joint.BodyB
// compute relative rotational velocity
wr := b.w - a.w + joint.rate
jMax := joint.MaxForce
// compute normal impulse
j := -wr*joint.iSum
jOld := joint.jAcc
joint.jAcc = clamp(jOld + j, -jMax, jMax)
j = joint.jAcc - jOld
// apply impulse
a.w -= j*a.i_inv
b.w += j*b.i_inv
}
func clamp(value, min, max vect.Float) vect.Float {
if value > max {
return max
}
if value < min {
return min
}
return value
}
/*
Impulse returns the motors impulse.
*/
func (joint *SimpleMotor) Impulse() vect.Float {
if joint.jAcc < 0 {
return -joint.jAcc
}
return joint.jAcc
}
/*
GetRate returns the motor rate.
*/
func (joint *SimpleMotor) GetRate() vect.Float {
return joint.rate
}
/*
SetRate sets the motor rate (aka power).
*/
func (joint *SimpleMotor) SetRate(rate vect.Float) {
joint.rate = rate
}
/*
NewSimpleMotor creates a new motor joint.
*/
func NewSimpleMotor(a, b *Body, rate vect.Float) *SimpleMotor {
return &SimpleMotor{BasicConstraint: NewConstraint(a, b), rate: rate, jAcc: 0.0}
}