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.
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