bulldog_physics 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +22 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +25 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/bulldog_physics.gemspec +92 -0
- data/lib/Particles/particle.rb +75 -0
- data/lib/Particles/particle_anchored_spring.rb +42 -0
- data/lib/Particles/particle_cable.rb +52 -0
- data/lib/Particles/particle_contact.rb +121 -0
- data/lib/Particles/particle_contact_generator.rb +28 -0
- data/lib/Particles/particle_contact_resolver.rb +49 -0
- data/lib/Particles/particle_drag.rb +30 -0
- data/lib/Particles/particle_force_generator.rb +23 -0
- data/lib/Particles/particle_force_registration.rb +15 -0
- data/lib/Particles/particle_force_registry.rb +50 -0
- data/lib/Particles/particle_gravity.rb +31 -0
- data/lib/Particles/particle_ground_contacts.rb +43 -0
- data/lib/Particles/particle_link.rb +41 -0
- data/lib/Particles/particle_particle_contacts.rb +48 -0
- data/lib/Particles/particle_rod.rb +58 -0
- data/lib/Particles/particle_spring.rb +44 -0
- data/lib/Particles/particle_world.rb +116 -0
- data/lib/Particles/projectile.rb +15 -0
- data/lib/bulldog_physics.rb +43 -0
- data/lib/examples/GlStuff/gl_utility.rb +21 -0
- data/lib/examples/GlStuff/lighting.rb +35 -0
- data/lib/examples/GlStuff/material.rb +24 -0
- data/lib/examples/GlStuff/terrain.rb +216 -0
- data/lib/examples/simple_game.rb +289 -0
- data/lib/matrix3.rb +242 -0
- data/lib/matrix4.rb +230 -0
- data/lib/quaternion.rb +86 -0
- data/lib/vector3.rb +155 -0
- data/test/helper.rb +18 -0
- data/test/test_bulldog_physics.rb +7 -0
- metadata +190 -0
data/lib/matrix4.rb
ADDED
@@ -0,0 +1,230 @@
|
|
1
|
+
module BulldogPhysics
|
2
|
+
class Matrix4
|
3
|
+
|
4
|
+
attr_accessor :data
|
5
|
+
|
6
|
+
|
7
|
+
def initialize()
|
8
|
+
@data = [ 1, 0, 0, 0,
|
9
|
+
0, 1, 0, 0,
|
10
|
+
0, 0, 1, 0 ]
|
11
|
+
end
|
12
|
+
|
13
|
+
def *(vector)
|
14
|
+
|
15
|
+
|
16
|
+
if( @data.size < 8)
|
17
|
+
raise Exception.new("@data not big enough for vector math")
|
18
|
+
end
|
19
|
+
|
20
|
+
if( vector.kind_of? Matrix4)
|
21
|
+
o = vector.dup
|
22
|
+
|
23
|
+
result = Matrix4.new
|
24
|
+
result.data[0] = (o.data[0]*@data[0]) + (o.data[4]*@data[1]) + (o.data[8]*@data[2]);
|
25
|
+
result.data[4] = (o.data[0]*@data[4]) + (o.data[4]*@data[5]) + (o.data[8]*@data[6]);
|
26
|
+
result.data[8] = (o.data[0]*@data[8]) + (o.data[4]*@data[9]) + (o.data[8]*@data[10]);
|
27
|
+
|
28
|
+
result.data[1] = (o.data[1]*@data[0]) + (o.data[5]*@data[1]) + (o.data[9]*@data[2]);
|
29
|
+
result.data[5] = (o.data[1]*@data[4]) + (o.data[5]*@data[5]) + (o.data[9]*@data[6]);
|
30
|
+
result.data[9] = (o.data[1]*@data[8]) + (o.data[5]*@data[9]) + (o.data[9]*@data[10]);
|
31
|
+
|
32
|
+
result.data[2] = (o.data[2]*@data[0]) + (o.data[6]*@data[1]) + (o.data[10]*@data[2]);
|
33
|
+
result.data[6] = (o.data[2]*@data[4]) + (o.data[6]*@data[5]) + (o.data[10]*@data[6]);
|
34
|
+
result.data[10] = (o.data[2]*@data[8]) + (o.data[6]*data[9]) + (o.data[10]*@data[10]);
|
35
|
+
|
36
|
+
result.data[3] = (o.data[3]*@data[0]) + (o.data[7]*@data[1]) + (o.data[11]*@data[2]) + @data[3];
|
37
|
+
result.data[7] = (o.data[3]*@data[4]) + (o.data[7]*@data[5]) + (o.data[11]*@data[6]) + @data[7];
|
38
|
+
result.data[11] = (o.data[3]*@data[8]) + (o.data[7]*@data[9]) + (o.data[11]*@data[10]) + @data[11];
|
39
|
+
return result;
|
40
|
+
else
|
41
|
+
return Vector3.new(
|
42
|
+
vector.x * @data[0] + \
|
43
|
+
vector.y * @data[1] + \
|
44
|
+
vector.z * @data[2] + @data[3],\
|
45
|
+
vector.x * @data[4] + \
|
46
|
+
vector.y * @data[5] + \
|
47
|
+
vector.z * @data[6] + @data[7], \
|
48
|
+
vector.x * @data[8] + \
|
49
|
+
vector.y * @data[9] + \
|
50
|
+
vector.z * @data[10] + @data[11]\
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
# Sets the matrix to be the inverse of the given matrix.
|
59
|
+
# @param m The matrix to invert and use to set this.
|
60
|
+
def setInverse(m)
|
61
|
+
#Make sure the determinant is non-zero.
|
62
|
+
det = getDeterminant();
|
63
|
+
if (det == 0)
|
64
|
+
return
|
65
|
+
end
|
66
|
+
|
67
|
+
det = 1.0/det;
|
68
|
+
|
69
|
+
@data[0] = (-m.data[9]*m.data[6]+m.data[5]*m.data[10])*det;
|
70
|
+
@data[4] = (m.data[8]*m.data[6]-m.data[4]*m.data[10])*det;
|
71
|
+
@data[8] = (-m.data[8]*m.data[5]+m.data[4]*m.data[9])*det;
|
72
|
+
|
73
|
+
@data[1] = (m.data[9]*m.data[2]-m.data[1]*m.data[10])*det;
|
74
|
+
@data[5] = (-m.data[8]*m.data[2]+m.data[0]*m.data[10])*det;
|
75
|
+
@data[9] = (m.data[8]*m.data[1]-m.data[0]*m.data[9])*det;
|
76
|
+
|
77
|
+
@data[2] = (-m.data[5]*m.data[2]+m.data[1]*m.data[6])*det;
|
78
|
+
@data[6] = (+m.data[4]*m.data[2]-m.data[0]*m.data[6])*det;
|
79
|
+
@data[10] = (-m.data[4]*m.data[1]+m.data[0]*m.data[5])*det;
|
80
|
+
|
81
|
+
@data[3] = (m.data[9]*m.data[6]*m.data[3]
|
82
|
+
-m.data[5]*m.data[10]*m.data[3]
|
83
|
+
-m.data[9]*m.data[2]*m.data[7]
|
84
|
+
+m.data[1]*m.data[10]*m.data[7]
|
85
|
+
+m.data[5]*m.data[2]*m.data[11]
|
86
|
+
-m.data[1]*m.data[6]*m.data[11])*det;
|
87
|
+
@data[7] = (-m.data[8]*m.data[6]*m.data[3]
|
88
|
+
+m.data[4]*m.data[10]*m.data[3]
|
89
|
+
+m.data[8]*m.data[2]*m.data[7]
|
90
|
+
-m.data[0]*m.data[10]*m.data[7]
|
91
|
+
-m.data[4]*m.data[2]*m.data[11]
|
92
|
+
+m.data[0]*m.data[6]*m.data[11])*det;
|
93
|
+
@data[11] =(m.data[8]*m.data[5]*m.data[3]
|
94
|
+
-m.data[4]*m.data[9]*m.data[3]
|
95
|
+
-m.data[8]*m.data[1]*m.data[7]
|
96
|
+
+m.data[0]*m.data[9]*m.data[7]
|
97
|
+
+m.data[4]*m.data[1]*m.data[11]
|
98
|
+
-m.data[0]*m.data[5]*m.data[11])*det;
|
99
|
+
end
|
100
|
+
# Returns a new matrix containing the inverse of this matrix. */
|
101
|
+
def inverse
|
102
|
+
result = Matrix3.new
|
103
|
+
result.setInverse(self);
|
104
|
+
return result
|
105
|
+
end
|
106
|
+
|
107
|
+
def transformDirection(vector)
|
108
|
+
Vector3.new(
|
109
|
+
vector.x * @data[0] +
|
110
|
+
vector.y * @data[1] +
|
111
|
+
vector.z * @data[2],
|
112
|
+
|
113
|
+
vector.x * @data[4] +
|
114
|
+
vector.y * @data[5] +
|
115
|
+
vector.z * @data[6],
|
116
|
+
|
117
|
+
vector.x * @data[8] +
|
118
|
+
vector.y * @data[9] +
|
119
|
+
vector.z * @data[10]
|
120
|
+
);
|
121
|
+
end
|
122
|
+
|
123
|
+
def transformInverseDirection(vector)
|
124
|
+
Vector3.new(
|
125
|
+
vector.x * @data[0] +
|
126
|
+
vector.y * @data[4] +
|
127
|
+
vector.z * @data[8],
|
128
|
+
|
129
|
+
vector.x * @data[1] +
|
130
|
+
vector.y * @data[5] +
|
131
|
+
vector.z * @data[9],
|
132
|
+
|
133
|
+
vector.x * @data[2] +
|
134
|
+
vector.y * @data[6] +
|
135
|
+
vector.z * @data[10]
|
136
|
+
);
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
def transformInverse(vector)
|
141
|
+
tmp = vector.dup;
|
142
|
+
tmp.x -= @data[3];
|
143
|
+
tmp.y -= @data[7];
|
144
|
+
tmp.z -= @data[11];
|
145
|
+
Vector3.new(
|
146
|
+
tmp.x * @data[0] +
|
147
|
+
tmp.y * @data[4] +
|
148
|
+
tmp.z * @data[8],
|
149
|
+
|
150
|
+
tmp.x * @data[1] +
|
151
|
+
tmp.y * @data[5] +
|
152
|
+
tmp.z * @data[9],
|
153
|
+
|
154
|
+
tmp.x * @data[2] +
|
155
|
+
tmp.y * @data[6] +
|
156
|
+
tmp.z * @data[10]
|
157
|
+
)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Fills the given array with this transform matrix, so it is
|
161
|
+
# usable as an open-gl transform matrix. OpenGL uses a column
|
162
|
+
# major format, so that the values are transposed as they are
|
163
|
+
# written.
|
164
|
+
def getGLArray()
|
165
|
+
array = Array.new
|
166
|
+
array[0] = @data[0];
|
167
|
+
array[1] = @data[4];
|
168
|
+
array[2] = @data[8];
|
169
|
+
array[3] = 0;
|
170
|
+
|
171
|
+
array[4] = @data[1];
|
172
|
+
array[5] = @data[5];
|
173
|
+
array[6] = @data[9];
|
174
|
+
array[7] = 0;
|
175
|
+
|
176
|
+
array[8] = @data[2];
|
177
|
+
array[9] = @data[6];
|
178
|
+
array[10] = @data[10];
|
179
|
+
array[11] = 0;
|
180
|
+
|
181
|
+
array[12] = @data[3];
|
182
|
+
array[13] = @data[7];
|
183
|
+
array[14] = @data[11];
|
184
|
+
array[15] = 1;
|
185
|
+
return array
|
186
|
+
end
|
187
|
+
|
188
|
+
def getAxisVector(i)
|
189
|
+
Vector3.new(@data[i], @data[i+4], @data[i+8]);
|
190
|
+
end
|
191
|
+
|
192
|
+
def setOrientationAndPos(q, pos)
|
193
|
+
@data[0] = 1 - (2*q.j*q.j + 2*q.k*q.k);
|
194
|
+
@data[1] = 2*q.i*q.j + 2*q.k*q.r;
|
195
|
+
@data[2] = 2*q.i*q.k - 2*q.j*q.r;
|
196
|
+
@data[3] = pos.x;
|
197
|
+
|
198
|
+
@data[4] = 2*q.i*q.j - 2*q.k*q.r;
|
199
|
+
@data[5] = 1 - (2*q.i*q.i + 2*q.k*q.k);
|
200
|
+
@data[6] = 2*q.j*q.k + 2*q.i*q.r;
|
201
|
+
@data[7] = pos.y;
|
202
|
+
|
203
|
+
@data[8] = 2*q.i*q.k + 2*q.j*q.r;
|
204
|
+
@data[9] = 2*q.j*q.k - 2*q.i*q.r;
|
205
|
+
@data[10] = 1 - (2*q.i*q.i + 2*q.j*q.j);
|
206
|
+
@data[11] = pos.z;
|
207
|
+
end
|
208
|
+
|
209
|
+
# Inverts the matrix.
|
210
|
+
def invert()
|
211
|
+
setInverse(self)
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
def transform(vector)
|
216
|
+
self * vector
|
217
|
+
end
|
218
|
+
|
219
|
+
def getDeterminant
|
220
|
+
return @data[8]*@data[5]*@data[2]+
|
221
|
+
@data[4]*@data[9]*@data[2]+
|
222
|
+
@data[8]*@data[1]*@data[6]-
|
223
|
+
@data[0]*@data[9]*@data[6]-
|
224
|
+
@data[4]*@data[1]*@data[10]+
|
225
|
+
@data[0]*@data[5]*@data[10];
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
data/lib/quaternion.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
module BulldogPhysics
|
2
|
+
class Quaternion
|
3
|
+
|
4
|
+
#attr :data
|
5
|
+
attr_accessor :r, :i, :j, :k
|
6
|
+
|
7
|
+
def initialize(r = 1.0, i =0, j = 0, k = 0)
|
8
|
+
@r, @i, @j, @k = r, i, j, k
|
9
|
+
end
|
10
|
+
|
11
|
+
def intialize(r, i, j, k)
|
12
|
+
@r = r
|
13
|
+
@i = i
|
14
|
+
@j = j
|
15
|
+
@k = k
|
16
|
+
end
|
17
|
+
|
18
|
+
def data=(data)
|
19
|
+
@r = data[0]
|
20
|
+
@i = data[1]
|
21
|
+
@j = data[2]
|
22
|
+
@k = data[3]
|
23
|
+
end
|
24
|
+
|
25
|
+
def data
|
26
|
+
[@r, @i, @j, @k]
|
27
|
+
end
|
28
|
+
|
29
|
+
def *(multiplier)
|
30
|
+
q = self
|
31
|
+
r = q.r*multiplier.r - q.i*multiplier.i -
|
32
|
+
q.j*multiplier.j - q.k*multiplier.k
|
33
|
+
i = q.r*multiplier.i + q.i*multiplier.r +
|
34
|
+
q.j*multiplier.k - q.k*multiplier.j
|
35
|
+
j = q.r*multiplier.j + q.j*multiplier.r +
|
36
|
+
q.k*multiplier.i - q.i*multiplier.k;
|
37
|
+
k = q.r*multiplier.k + q.k*multiplier.r +
|
38
|
+
q.i*multiplier.j - q.j*multiplier.i;
|
39
|
+
Quaternion.new( r, i, j, k )
|
40
|
+
end
|
41
|
+
|
42
|
+
def normalize()
|
43
|
+
d = (@r*@r) + (@i*@i) + (@j*@j) + (@k*@k)
|
44
|
+
|
45
|
+
if( d == 0)
|
46
|
+
@r = 1
|
47
|
+
return
|
48
|
+
end
|
49
|
+
#return if d.nan?
|
50
|
+
begin
|
51
|
+
d = (1.0 / Math.sqrt(d))
|
52
|
+
rescue
|
53
|
+
puts "FUCK D IS #{d}"
|
54
|
+
end
|
55
|
+
@r *= d
|
56
|
+
@i *= d
|
57
|
+
@j *= d
|
58
|
+
@k *= d
|
59
|
+
end
|
60
|
+
|
61
|
+
def addScaledVector(vector, scale)
|
62
|
+
|
63
|
+
q = Quaternion.new(0,
|
64
|
+
vector.x * scale,
|
65
|
+
vector.y * scale,
|
66
|
+
vector.z * scale)
|
67
|
+
|
68
|
+
q *= self;
|
69
|
+
@r += q.r * 0.5
|
70
|
+
@i += q.i * 0.5
|
71
|
+
@j += q.j * 0.5
|
72
|
+
@k += q.k * 0.5
|
73
|
+
end
|
74
|
+
|
75
|
+
def rotateByVector(vector)
|
76
|
+
q = Quaternion.new( 0, vector.x, vector.y, vector.z)
|
77
|
+
new_q = self * q
|
78
|
+
@r = q.r
|
79
|
+
@i = q.i
|
80
|
+
@j = q.j
|
81
|
+
@k = q.k
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
data/lib/vector3.rb
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
module BulldogPhysics
|
2
|
+
|
3
|
+
class Vector3
|
4
|
+
|
5
|
+
attr_accessor :x, :y, :z
|
6
|
+
attr_reader :pad #padding to ensure four world alignment
|
7
|
+
|
8
|
+
## create Vertex, defaults all to zero
|
9
|
+
def initialize(x = 0,y = 0,z = 0)
|
10
|
+
@x = x
|
11
|
+
@y = y
|
12
|
+
@z = z
|
13
|
+
end
|
14
|
+
|
15
|
+
## flip the components
|
16
|
+
def invert
|
17
|
+
@x = -@x
|
18
|
+
@y = -@y
|
19
|
+
@z = -@z
|
20
|
+
end
|
21
|
+
|
22
|
+
## Gets the magnitude of this vector.
|
23
|
+
def magnitude
|
24
|
+
num = (@x*@x) + (@y * @y) + (@z * @z)
|
25
|
+
return 0 if num.nan?
|
26
|
+
Math.sqrt((@x*@x)+(@y*@y)+(@z*@z))
|
27
|
+
end
|
28
|
+
|
29
|
+
def squareMagnitude
|
30
|
+
return (@x*@x)+(@y*@y)+(@z*@z)
|
31
|
+
end
|
32
|
+
|
33
|
+
## Turns a non-zero vector into a vector of unit length.
|
34
|
+
def normalize
|
35
|
+
length = self.magnitude
|
36
|
+
if length > 0
|
37
|
+
@x /= length
|
38
|
+
@y /= length
|
39
|
+
@z /= length
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def unit
|
44
|
+
length = self.magnitude
|
45
|
+
if length > 0
|
46
|
+
x = @x * (1.0 / length)
|
47
|
+
#x = @x / length
|
48
|
+
y = @y * (1.0 / length)
|
49
|
+
#y = @y / length
|
50
|
+
#z = @z / length
|
51
|
+
z = @z * (1.0 / length)
|
52
|
+
return Vector3.new(x,y,z)
|
53
|
+
else
|
54
|
+
return Vector3.new
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def addScaledVector(v, scalar)
|
59
|
+
@x += (v.x * scalar)
|
60
|
+
@y += (v.y * scalar)
|
61
|
+
@z += (v.z * scalar)
|
62
|
+
end
|
63
|
+
|
64
|
+
def componentProduct(v)
|
65
|
+
Vector3.new(@x * v.x, @y * v.y, @z * v.z)
|
66
|
+
end
|
67
|
+
|
68
|
+
def componentProductUpdate(v)
|
69
|
+
@x *= v.x
|
70
|
+
@y *= v.y
|
71
|
+
@z *= v.z
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
def scalarProduct(v)
|
76
|
+
(@x * v.x) + (@y * v.y) + (@z * v.z)
|
77
|
+
end
|
78
|
+
|
79
|
+
def crossProduct(v)
|
80
|
+
Vector3.new( (@y * v.z) - (@z * v.y),
|
81
|
+
(@z * v.x) - (@x * v.z),
|
82
|
+
(@x * v.y) - (@y * v.x))
|
83
|
+
end
|
84
|
+
|
85
|
+
def crossProductUpdate(v)
|
86
|
+
new_v = vectorProduct(v)
|
87
|
+
@x = new_v.x
|
88
|
+
@y = new_v.y
|
89
|
+
@z = new_v.z
|
90
|
+
end
|
91
|
+
|
92
|
+
def *(scalar)
|
93
|
+
if scalar.kind_of? Float
|
94
|
+
Vector3.new(@x*scalar, @y*scalar, @z*scalar)
|
95
|
+
elsif scalar.kind_of? Vector3
|
96
|
+
return @x * scalar.x + @y * scalar.y + @z * scalar.z
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def +(v)
|
101
|
+
Vector3.new(@x + v.x, @y + v.y, @z + v.z)
|
102
|
+
end
|
103
|
+
|
104
|
+
def vector_product(vector)
|
105
|
+
Vector3.new(@y*vector.z - @z*vector.y,
|
106
|
+
@z*vector.x - @x*vector.z,
|
107
|
+
@x*vector.y - @y*vector.x)
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
#Updates this vector to be the vector product of its current
|
112
|
+
# => value and the given vector.
|
113
|
+
def %(vector)
|
114
|
+
vector_product(vector)
|
115
|
+
end
|
116
|
+
def addVector(v)
|
117
|
+
@x += v.x
|
118
|
+
@y += v.y
|
119
|
+
@z += v.z
|
120
|
+
self
|
121
|
+
end
|
122
|
+
|
123
|
+
def multiplyByScalar(scalar)
|
124
|
+
@x *= scalar
|
125
|
+
@y *= scalar
|
126
|
+
@z *= scalar
|
127
|
+
end
|
128
|
+
|
129
|
+
def subtractVector(v)
|
130
|
+
@x -= v.x
|
131
|
+
@y -= v.y
|
132
|
+
@z -= v.z
|
133
|
+
end
|
134
|
+
|
135
|
+
def divideByScalar(scalar)
|
136
|
+
@x *= scalar
|
137
|
+
@y *= scalar
|
138
|
+
@z *= scalar
|
139
|
+
end
|
140
|
+
|
141
|
+
def -(v)
|
142
|
+
Vector3.new(@x - v.x, @y - v.y, @z - v.z)
|
143
|
+
end
|
144
|
+
|
145
|
+
def clear
|
146
|
+
@x, @y, @z = 0,0,0
|
147
|
+
end
|
148
|
+
|
149
|
+
def to_s
|
150
|
+
"(#{@x},#{@y},#{@z})"
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|