bulldog_physics 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/.document +5 -0
  2. data/Gemfile +13 -0
  3. data/Gemfile.lock +22 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.rdoc +25 -0
  6. data/Rakefile +55 -0
  7. data/VERSION +1 -0
  8. data/bulldog_physics.gemspec +92 -0
  9. data/lib/Particles/particle.rb +75 -0
  10. data/lib/Particles/particle_anchored_spring.rb +42 -0
  11. data/lib/Particles/particle_cable.rb +52 -0
  12. data/lib/Particles/particle_contact.rb +121 -0
  13. data/lib/Particles/particle_contact_generator.rb +28 -0
  14. data/lib/Particles/particle_contact_resolver.rb +49 -0
  15. data/lib/Particles/particle_drag.rb +30 -0
  16. data/lib/Particles/particle_force_generator.rb +23 -0
  17. data/lib/Particles/particle_force_registration.rb +15 -0
  18. data/lib/Particles/particle_force_registry.rb +50 -0
  19. data/lib/Particles/particle_gravity.rb +31 -0
  20. data/lib/Particles/particle_ground_contacts.rb +43 -0
  21. data/lib/Particles/particle_link.rb +41 -0
  22. data/lib/Particles/particle_particle_contacts.rb +48 -0
  23. data/lib/Particles/particle_rod.rb +58 -0
  24. data/lib/Particles/particle_spring.rb +44 -0
  25. data/lib/Particles/particle_world.rb +116 -0
  26. data/lib/Particles/projectile.rb +15 -0
  27. data/lib/bulldog_physics.rb +43 -0
  28. data/lib/examples/GlStuff/gl_utility.rb +21 -0
  29. data/lib/examples/GlStuff/lighting.rb +35 -0
  30. data/lib/examples/GlStuff/material.rb +24 -0
  31. data/lib/examples/GlStuff/terrain.rb +216 -0
  32. data/lib/examples/simple_game.rb +289 -0
  33. data/lib/matrix3.rb +242 -0
  34. data/lib/matrix4.rb +230 -0
  35. data/lib/quaternion.rb +86 -0
  36. data/lib/vector3.rb +155 -0
  37. data/test/helper.rb +18 -0
  38. data/test/test_bulldog_physics.rb +7 -0
  39. metadata +190 -0
@@ -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
+
@@ -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
+
@@ -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