geo3d 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 138773d3e8cf380540b6739a3a80ffadcda6d5cd
4
+ data.tar.gz: 6f8470eb7aef952eb1f54750d1ca1249e338d11b
5
+ SHA512:
6
+ metadata.gz: ed5bc833a4aac2126d532fd738a64d0d098413fc35566e92579a35dbcca8dceb56e8610e9db364e636f6fff9fd4fc348933608bad4995a2cae0d756bc4805ef7
7
+ data.tar.gz: 52b7c187aab6b6ccb3383dabb73eb9dfed31b2168266f1d8ad0133714d300f7434b75dbd86368983386fc5bc6556951fd1e66457d9830484aca219d129ff4fac
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in geo3d.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Misha Conway
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,172 @@
1
+ # Geo3d
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'geo3d'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install geo3d
18
+
19
+ ## Usage
20
+ ```
21
+ a = Geo3d::Vector.new 1, 0, 0
22
+ b = Geo3d::Vector.new 0, 1, 0
23
+ sum = a + b # add them together
24
+ sum *= 2 #double the vector
25
+
26
+ m = Geo3d::Matrix.translation 0, 5, 0 #create a translation matrix that transforms a points 5 units on the y-axis
27
+ sum = m * sum #apply the transform to our vector
28
+ ```
29
+
30
+
31
+ ## Vector
32
+
33
+ Describes a three dimensional point or direction. A vector has the following read/write attributes: x, y, z, w
34
+
35
+ Vectors are overloaded with all of the basic math operations.
36
+
37
+ Addition
38
+ ```
39
+ vec_a + vec_b
40
+ ```
41
+ Subtraction
42
+ ```
43
+ vec_a - vec_b
44
+ ```
45
+ Multiplication
46
+ ```
47
+ vec * scalar
48
+ ```
49
+ Division
50
+ ```
51
+ vec / scalar
52
+ ```
53
+
54
+ Additional vector operations
55
+
56
+ Dot product
57
+ ```
58
+ vec.dot
59
+ ```
60
+ Cross product
61
+ ```
62
+ vec_a.cross vec_b
63
+ ```
64
+ Magnitude
65
+ ```
66
+ vec.length
67
+ ```
68
+ Squared Magnitude
69
+ ```
70
+ vec.length_squared
71
+ ```
72
+ Normalize
73
+ ```
74
+ vec.normalize #returns a normalized version of the vector
75
+ vec.normalize! #normalizes the vector in place
76
+ ```
77
+ Linear Interpolation
78
+ ```
79
+ vec_a.lerp vec_b, 0.4 #returns a new vector which is the 40% linear interpolation between vec_a and vec_b
80
+ ```
81
+
82
+
83
+ ## Matrix
84
+
85
+ A 4x4 matrix used for transforming vectors. Elements can be read/written to with the double subscription operation.
86
+ For instance, matrix[0,1] = 7 writes seven to the element in column zero and row one.
87
+
88
+ Matrices are overloaded with all of the basic math operations
89
+
90
+ Addition
91
+ ```
92
+ mat_a + mat_b
93
+ ```
94
+ Subtraction
95
+ ```
96
+ mat_a - mat_b
97
+ ```
98
+ Scalar Multiplication
99
+ ```
100
+ mat * scalar
101
+ ```
102
+ Scalar Division
103
+ ```
104
+ mat / scalar
105
+ ```
106
+ Matrix Multiplication
107
+ ```
108
+ mat_a * mat_b
109
+ ```
110
+ Matrix Vector Multiplication
111
+ ```
112
+ mat * vec
113
+ ```
114
+
115
+
116
+ Additional matrix operations
117
+
118
+ Inverse
119
+ ```
120
+ mat.inverse #returns inverse of matrix
121
+ mat.inverse true #returns inverse of matrix along with its determinant
122
+ ```
123
+ Transpose
124
+ ```
125
+ mat.tranpose
126
+ ```
127
+
128
+ Common matrix constructors
129
+
130
+ Identity
131
+ ```
132
+ Geo3d::Matrix.identity #returns the identity matrix
133
+ ```
134
+ Translation
135
+ ```
136
+ Geo3d::Matrix.translation x,y,z #returns a translation matrix
137
+ ```
138
+ Scaling
139
+ ```
140
+ Geo3d::Matrix.scaling x,y,z #returns a scaling matrix
141
+ Geo3d::Matrix.uniform_scaling scale #returns a uniform scaling matrix
142
+ ```
143
+ Projection matrix constructors
144
+ ```
145
+ Geo3d::Matrix.matrix_perspective_fov_rh fovy, aspect, z_near, z_far #returns a right handed perspective projection matrix
146
+ Geo3d::Matrix.matrix_perspective_fov_lh fovy, aspect, z_near, z_far #returns a left handed perspective projection matrix
147
+ ```
148
+ View matrix constructors
149
+ ```
150
+ Geo3d::Matrix.look_at_rh eye_position, look_at_position, up_direction #returns a right handed view matrix
151
+ Geo3d::Matrix.look_at_lh eye_position, look_at_position, up_direction #returns a left handed view matrix
152
+ ```
153
+ Misc constructors
154
+ ```
155
+ Geo3d::Matrix.reflection reflection_plane #returns a reflection matrix where reflection_plane is a Geo3d::Vector that corresponds to the normal of the plane
156
+ ```
157
+
158
+
159
+
160
+
161
+
162
+
163
+
164
+
165
+
166
+ ## Contributing
167
+
168
+ 1. Fork it
169
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
170
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
171
+ 4. Push to the branch (`git push origin my-new-feature`)
172
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'geo3d/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "geo3d"
8
+ spec.version = Geo3d::VERSION
9
+ spec.authors = ["Misha Conway"]
10
+ spec.email = ["MishaAConway@gmail.com"]
11
+ spec.description = %q{Library for common 3d graphics vector and matrix operations}
12
+ spec.summary = %q{Library for common 3d graphics vector and matrix operations}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
@@ -0,0 +1,6 @@
1
+ require 'geo3d/version'
2
+ require 'vector'
3
+ require 'matrix'
4
+ require 'quaternion'
5
+
6
+
@@ -0,0 +1,3 @@
1
+ module Geo3d
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,487 @@
1
+ module Geo3d
2
+ class Matrix
3
+ attr_accessor :_11, :_12, :_13, :_14
4
+ attr_accessor :_21, :_22, :_23, :_24
5
+ attr_accessor :_31, :_32, :_33, :_34
6
+ attr_accessor :_41, :_42, :_43, :_44
7
+
8
+ def initialize *args
9
+ @_11 = 0, @_12 = 0, @_13 = 0, @_14 = 0, @_21 = 0, @_22 = 0, @_23 = 0, @_24 = 0, @_31 = 0, @_32 = 0, @_33 = 0, @_34 = 0, @_41 = 0, @_42 = 0, @_43 = 0, @_44 = 0
10
+ @_11 = args[0] if args.size > 0
11
+ @_12 = args[1] if args.size > 1
12
+ @_13 = args[2] if args.size > 2
13
+ @_14 = args[3] if args.size > 3
14
+ @_21 = args[4] if args.size > 4
15
+ @_22 = args[5] if args.size > 5
16
+ @_23 = args[6] if args.size > 6
17
+ @_24 = args[7] if args.size > 7
18
+ @_31 = args[8] if args.size > 8
19
+ @_32 = args[9] if args.size > 9
20
+ @_33 = args[10] if args.size > 10
21
+ @_34 = args[11] if args.size > 11
22
+ @_41 = args[12] if args.size > 12
23
+ @_42 = args[13] if args.size > 13
24
+ @_43 = args[14] if args.size > 14
25
+ @_44 = args[15] if args.size > 15
26
+ end
27
+
28
+ def to_a
29
+ [_11, _12, _13, _14, _21, _22, _23, _24, _31, _32, _33, _34, _41, _42, _43, _44]
30
+ end
31
+
32
+ def [] x, y
33
+ to_a[4*y + x]
34
+ end
35
+
36
+ def []= x, y, v
37
+ send (%w{_11 _12 _13 _14 _21 _22 _23 _24 _31 _32 _33 _34 _41 _42 _43 _44}[4*y + x] + '=').to_sym, v
38
+ end
39
+
40
+ def +@
41
+ self * 1
42
+ end
43
+
44
+ def -@
45
+ self * -1
46
+ end
47
+
48
+ def + mat
49
+ sum = Matrix.new
50
+
51
+ sum._11 = _11 + mat._11
52
+ sum._12 = _12 + mat._12
53
+ sum._13 = _13 + mat._13
54
+ sum._14 = _14 + mat._14
55
+
56
+ sum._21 = _21 + mat._21
57
+ sum._22 = _22 + mat._22
58
+ sum._23 = _23 + mat._23
59
+ sum._24 = _24 + mat._24
60
+
61
+ sum._31 = _31 + mat._31
62
+ sum._32 = _32 + mat._32
63
+ sum._33 = _33 + mat._33
64
+ sum._34 = _34 + mat._34
65
+
66
+ sum._41 = _41 + mat._41
67
+ sum._42 = _42 + mat._42
68
+ sum._43 = _43 + mat._43
69
+ sum._44 = _44 + mat._44
70
+
71
+ sum
72
+ end
73
+
74
+ def - mat
75
+ sum = Matrix.new
76
+
77
+ sum._11 = _11 - mat._11
78
+ sum._12 = _12 - mat._12
79
+ sum._13 = _13 - mat._13
80
+ sum._14 = _14 - mat._14
81
+
82
+ sum._21 = _21 - mat._21
83
+ sum._22 = _22 - mat._22
84
+ sum._23 = _23 - mat._23
85
+ sum._24 = _24 - mat._24
86
+
87
+ sum._31 = _31 - mat._31
88
+ sum._32 = _32 - mat._32
89
+ sum._33 = _33 - mat._33
90
+ sum._34 = _34 - mat._34
91
+
92
+ sum._41 = _41 - mat._41
93
+ sum._42 = _42 - mat._42
94
+ sum._43 = _43 - mat._43
95
+ sum._44 = _44 - mat._44
96
+
97
+ sum
98
+ end
99
+
100
+ def * v
101
+ result = Matrix.new
102
+
103
+ if Matrix == v.class
104
+ matrix = v
105
+
106
+ result._11 = _11 * matrix._11 + _12 * matrix._21 + _13 * matrix._31 + _14 * matrix._41
107
+ result._12 = _11 * matrix._12 + _12 * matrix._22 + _13 * matrix._32 + _14 * matrix._42
108
+ result._13 = _11 * matrix._13 + _12 * matrix._23 + _13 * matrix._33 + _14 * matrix._43
109
+ result._14 = _11 * matrix._14 + _12 * matrix._24 + _13 * matrix._34 + _14 * matrix._44
110
+
111
+ result._21 = _21 * matrix._11 + _22 * matrix._21 + _23 * matrix._31 + _24 * matrix._41
112
+ result._22 = _21 * matrix._12 + _22 * matrix._22 + _23 * matrix._32 + _24 * matrix._42
113
+ result._23 = _21 * matrix._13 + _22 * matrix._23 + _23 * matrix._33 + _24 * matrix._43
114
+ result._24 = _21 * matrix._14 + _22 * matrix._24 + _23 * matrix._34 + _24 * matrix._44
115
+
116
+ result._31 = _31 * matrix._11 + _32 * matrix._21 + _33 * matrix._31 + _34 * matrix._41
117
+ result._32 = _31 * matrix._12 + _32 * matrix._22 + _33 * matrix._32 + _34 * matrix._42
118
+ result._33 = _31 * matrix._13 + _32 * matrix._23 + _33 * matrix._33 + _34 * matrix._43
119
+ result._34 = _31 * matrix._14 + _32 * matrix._24 + _33 * matrix._34 + _34 * matrix._44
120
+
121
+ result._41 = _41 * matrix._11 + _42 * matrix._21 + _43 * matrix._31 + _44 * matrix._41
122
+ result._42 = _41 * matrix._12 + _42 * matrix._22 + _43 * matrix._32 + _44 * matrix._42
123
+ result._43 = _41 * matrix._13 + _42 * matrix._23 + _43 * matrix._33 + _44 * matrix._43
124
+ result._44 = _41 * matrix._14 + _42 * matrix._24 + _43 * matrix._34 + _44 * matrix._44
125
+ elsif Vector == v.class
126
+ vec = v
127
+ transformed_vector = Vector.new
128
+ transformed_vector.x = _11 * vec.x + _21 * vec.y + _31 * vec.z + _41
129
+ transformed_vector.y = _12 * vec.x + _22 * vec.y + _32 * vec.z + _42
130
+ transformed_vector.z = _13 * vec.x + _23 * vec.y + _33 * vec.z + _43
131
+ transformed_vector.w = _14 * vec.x + _24 * vec.y + _34 * vec.z + _44
132
+ return transformed_vector
133
+ else
134
+ scalar = v
135
+ result._11 = _11 * scalar
136
+ result._12 = _12 * scalar
137
+ result._13 = _13 * scalar
138
+ result._14 = _14 * scalar
139
+ result._21 = _21 * scalar
140
+ result._22 = _22 * scalar
141
+ result._23 = _23 * scalar
142
+ result._24 = _24 * scalar
143
+ result._31 = _31 * scalar
144
+ result._32 = _32 * scalar
145
+ result._33 = _33 * scalar
146
+ result._34 = _34 * scalar
147
+ result._41 = _41 * scalar
148
+ result._42 = _42 * scalar
149
+ result._43 = _43 * scalar
150
+ result._44 = _44 * scalar
151
+ end
152
+
153
+ result
154
+ end
155
+
156
+ def / v
157
+ if Matrix == v.class
158
+ self * v.inverse
159
+ elsif Vector == v.class
160
+ raise 'dividing matrices by vectors not currently supported'
161
+ else
162
+ result = Matrix.new
163
+ scalar = v
164
+ result._11 = _11 / scalar
165
+ result._12 = _12 / scalar
166
+ result._13 = _13 / scalar
167
+ result._14 = _14 / scalar
168
+ result._21 = _21 / scalar
169
+ result._22 = _22 / scalar
170
+ result._23 = _23 / scalar
171
+ result._24 = _24 / scalar
172
+ result._31 = _31 / scalar
173
+ result._32 = _32 / scalar
174
+ result._33 = _33 / scalar
175
+ result._34 = _34 / scalar
176
+ result._41 = _41 / scalar
177
+ result._42 = _42 / scalar
178
+ result._43 = _43 / scalar
179
+ result._44 = _44 / scalar
180
+ result
181
+ end
182
+ end
183
+
184
+ def transform_coord vec
185
+ norm =_14 * vec.x + _24 * vec.y + _34 * vec.z + _44
186
+ transformed_vector = self * vec
187
+ transformed_vector.x /= norm
188
+ transformed_vector.y /= norm
189
+ transformed_vector.z /= norm
190
+ transformed_vector
191
+ end
192
+
193
+ def transform vec
194
+ self * vec
195
+ end
196
+
197
+ def self.identity
198
+ identity_matrix = Matrix.new
199
+ identity_matrix._12 = identity_matrix._13 = identity_matrix._14 = 0
200
+ identity_matrix._21 = identity_matrix._23 = identity_matrix._24 = 0
201
+ identity_matrix._31 = identity_matrix._32 = identity_matrix._34 = 0
202
+ identity_matrix._41 = identity_matrix._42 = identity_matrix._43 = 0
203
+ identity_matrix._11 = identity_matrix._22 = identity_matrix._33 = identity_matrix._44 = 1
204
+ identity_matrix
205
+ end
206
+
207
+ def inverse with_determinant = false
208
+ mat = to_a
209
+ dst = Array.new 16
210
+ tmp = Array.new 12
211
+ src = Array.new 16
212
+
213
+ for i in 0..3
214
+ src[i] = mat[i*4]
215
+ src[i + 4] = mat[i*4 + 1]
216
+ src[i + 8] = mat[i*4 + 2]
217
+ src[i + 12] = mat[i*4 + 3]
218
+ end
219
+
220
+ # calculate pairs for first 8 elements (cofactors)
221
+ tmp[0] = src[10] * src[15]
222
+ tmp[1] = src[11] * src[14]
223
+ tmp[2] = src[9] * src[15]
224
+ tmp[3] = src[11] * src[13]
225
+ tmp[4] = src[9] * src[14]
226
+ tmp[5] = src[10] * src[13]
227
+ tmp[6] = src[8] * src[15]
228
+ tmp[7] = src[11] * src[12]
229
+ tmp[8] = src[8] * src[14]
230
+ tmp[9] = src[10] * src[12]
231
+ tmp[10] = src[8] * src[13]
232
+ tmp[11] = src[9] * src[12]
233
+
234
+ # calculate first 8 elements (cofactors)
235
+ dst[0] = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7]
236
+ dst[0] -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7]
237
+ dst[1] = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7]
238
+ dst[1] -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7]
239
+ dst[2] = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7]
240
+ dst[2] -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7]
241
+ dst[3] = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6]
242
+ dst[3] -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6]
243
+ dst[4] = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3]
244
+ dst[4] -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3]
245
+ dst[5] = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3]
246
+ dst[5] -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3]
247
+ dst[6] = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3]
248
+ dst[6] -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3]
249
+ dst[7] = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2]
250
+ dst[7] -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2]
251
+
252
+ # calculate pairs for second 8 elements (cofactors)
253
+ tmp[0] = src[2]*src[7]
254
+ tmp[1] = src[3]*src[6]
255
+ tmp[2] = src[1]*src[7]
256
+ tmp[3] = src[3]*src[5]
257
+ tmp[4] = src[1]*src[6]
258
+ tmp[5] = src[2]*src[5]
259
+ tmp[6] = src[0]*src[7]
260
+ tmp[7] = src[3]*src[4]
261
+ tmp[8] = src[0]*src[6]
262
+ tmp[9] = src[2]*src[4]
263
+ tmp[10] = src[0]*src[5]
264
+ tmp[11] = src[1]*src[4]
265
+
266
+ # calculate second 8 elements (cofactors)
267
+ dst[8] = tmp[0]*src[13] + tmp[3]*src[14] + tmp[4]*src[15]
268
+ dst[8] -= tmp[1]*src[13] + tmp[2]*src[14] + tmp[5]*src[15]
269
+ dst[9] = tmp[1]*src[12] + tmp[6]*src[14] + tmp[9]*src[15]
270
+ dst[9] -= tmp[0]*src[12] + tmp[7]*src[14] + tmp[8]*src[15]
271
+ dst[10] = tmp[2]*src[12] + tmp[7]*src[13] + tmp[10]*src[15]
272
+ dst[10]-= tmp[3]*src[12] + tmp[6]*src[13] + tmp[11]*src[15]
273
+ dst[11] = tmp[5]*src[12] + tmp[8]*src[13] + tmp[11]*src[14]
274
+ dst[11]-= tmp[4]*src[12] + tmp[9]*src[13] + tmp[10]*src[14]
275
+ dst[12] = tmp[2]*src[10] + tmp[5]*src[11] + tmp[1]*src[9]
276
+ dst[12]-= tmp[4]*src[11] + tmp[0]*src[9] + tmp[3]*src[10]
277
+ dst[13] = tmp[8]*src[11] + tmp[0]*src[8] + tmp[7]*src[10]
278
+ dst[13]-= tmp[6]*src[10] + tmp[9]*src[11] + tmp[1]*src[8]
279
+ dst[14] = tmp[6]*src[9] + tmp[11]*src[11] + tmp[3]*src[8]
280
+ dst[14]-= tmp[10]*src[11] + tmp[2]*src[8] + tmp[7]*src[9]
281
+ dst[15] = tmp[10]*src[10] + tmp[4]*src[8] + tmp[9]*src[9]
282
+ dst[15]-= tmp[8]*src[9] + tmp[11]*src[10] + tmp[5]*src[8]
283
+
284
+ # calculate determinant
285
+ det=src[0]*dst[0]+src[1]*dst[1]+src[2]*dst[2]+src[3]*dst[3]
286
+
287
+
288
+ # calculate matrix inverse
289
+ det = 1.0/det
290
+ for j in 0..15
291
+ dst[j] *= det
292
+ end
293
+
294
+ inverted_matrix = Matrix.new *dst
295
+
296
+ if with_determinant
297
+ [inverted_matrix, det]
298
+ else
299
+ inverted_matrix
300
+ end
301
+ end
302
+
303
+ def transpose
304
+ transposed_matrix = Matrix.new
305
+ transposed_matrix._11 = _11
306
+ transposed_matrix._12 = _21
307
+ transposed_matrix._13 = _31
308
+ transposed_matrix._14 = _41
309
+ transposed_matrix._21 = _12
310
+ transposed_matrix._22 = _22
311
+ transposed_matrix._23 = _32
312
+ transposed_matrix._24 = _42
313
+ transposed_matrix._31 = _13
314
+ transposed_matrix._32 = _23
315
+ transposed_matrix._33 = _33
316
+ transposed_matrix._34 = _43
317
+ transposed_matrix._41 = _14
318
+ transposed_matrix._42 = _24
319
+ transposed_matrix._43 = _34
320
+ transposed_matrix._44 = _44
321
+ transposed_matrix
322
+ end
323
+
324
+ def self.matrix_perspective_fov_rh fovy, aspect, zn, zf
325
+ y_scale = 1.0 / Math.tan(0.5*fovy)
326
+ x_scale = y_scale / aspect
327
+ matrix = Matrix.new
328
+ matrix._11 = x_scale
329
+ matrix._22 = y_scale
330
+ matrix._33 = zf/(zn - zf)
331
+ matrix._34 = -1
332
+ matrix._43 = zn*zf/(zn - zf)
333
+ matrix
334
+ end
335
+
336
+ def self.matrix_perspective_fov_lh fovy, aspect, zn, zf
337
+ y_scale = 1.0 / Math.tan(0.5*fovy)
338
+ x_scale = y_scale / aspect
339
+ matrix = Matrix.new
340
+ matrix._11 = x_scale
341
+ matrix._22 = y_scale
342
+ matrix._33 = zf/(zn - zf)
343
+ matrix._34 = 1
344
+ matrix._43 = -zn*zf/(zn - zf)
345
+ matrix
346
+ end
347
+
348
+ def self.look_at_rh eye_position, look_at_position, up_direction
349
+ zaxis = (eye_position - look_at_position).normalize
350
+ xaxis = up_direction.cross(zaxis).normalize
351
+ yaxis = zaxis.cross xaxis
352
+
353
+ matrix = Matrix.new
354
+
355
+ # set column one
356
+ matrix._11 = xaxis.x
357
+ matrix._21 = xaxis.y
358
+ matrix._31 = xaxis.z
359
+ matrix._41 = -xaxis.dot(eye_position)
360
+
361
+ # set column two
362
+ matrix._12 = yaxis.x
363
+ matrix._22 = yaxis.y
364
+ matrix._32 = yaxis.z
365
+ matrix._42 = -yaxis.dot(eye_position)
366
+
367
+ # set column three
368
+ matrix._13 = zaxis.x
369
+ matrix._23 = zaxis.y
370
+ matrix._33 = zaxis.z
371
+ matrix._43 = -zaxis.dot(eye_position)
372
+
373
+ # set column four
374
+ matrix._14 = matrix._24 = matrix._34 = 0
375
+ matrix._44 = 1
376
+
377
+ matrix
378
+ end
379
+
380
+ def self.look_at_lh eye_position, look_at_position, up_direction
381
+ zaxis = (look_at_position - eye_position).normalize
382
+ xaxis = up_direction.cross(zaxis).normalize
383
+ yaxis = zaxis.cross xaxis
384
+
385
+ matrix = Matrix.new
386
+
387
+ # set column one
388
+ matrix._11 = xaxis.x
389
+ matrix._21 = xaxis.y
390
+ matrix._31 = xaxis.z
391
+ matrix._41 = -xaxis.dot(eye_position)
392
+
393
+ # set column two
394
+ matrix._12 = yaxis.x
395
+ matrix._22 = yaxis.y
396
+ matrix._32 = yaxis.z
397
+ matrix._42 = -yaxis.dot(eye_position)
398
+
399
+ # set column three
400
+ matrix._13 = zaxis.x
401
+ matrix._23 = zaxis.y
402
+ matrix._33 = zaxis.z
403
+ matrix._43 = -zaxis.dot(eye_position)
404
+
405
+ # set column four
406
+ matrix._14 = matrix._24 = matrix._34 = 0
407
+ matrix._44 = 1
408
+
409
+ matrix
410
+ end
411
+
412
+ def self.reflection reflection_plane
413
+ reflection_matrix = Matrix.new
414
+
415
+ plane_magnitude = Vector.new(reflection_plane.x, reflection_plane.y, reflection_plane.z, 0).length
416
+ normalized_plane = reflection_plane / plane_magnitude
417
+
418
+ # row one
419
+ reflection_matrix._11 = -2 * normalized_plane.x * normalized_plane.x + 1
420
+ reflection_matrix._12 = -2 * normalized_plane.y * normalized_plane.x
421
+ reflection_matrix._13 = -2 * normalized_plane.z * normalized_plane.x
422
+ reflection_matrix._14 = 0
423
+
424
+ # row two
425
+ reflection_matrix._21 = -2 * normalized_plane.x * normalized_plane.y
426
+ reflection_matrix._22 = -2 * normalized_plane.y * normalized_plane.y + 1
427
+ reflection_matrix._23 = -2 * normalized_plane.z * normalized_plane.y
428
+ reflection_matrix._24 = 0
429
+
430
+ # row three
431
+ reflection_matrix._31 = -2 * normalized_plane.x * normalized_plane.z
432
+ reflection_matrix._32 = -2 * normalized_plane.y * normalized_plane.z
433
+ reflection_matrix._33 = -2 * normalized_plane.z * normalized_plane.z + 1
434
+ reflection_matrix._34 = 0
435
+
436
+ # row four
437
+ reflection_matrix._41 = -2 * normalized_plane.x * normalized_plane.w
438
+ reflection_matrix._42 = -2 * normalized_plane.y * normalized_plane.w
439
+ reflection_matrix._43 = -2 * normalized_plane.z * normalized_plane.w
440
+ reflection_matrix._44 = 1
441
+
442
+ reflection_matrix
443
+ end
444
+
445
+ def self.translation x, y, z
446
+ translation_matrix = Matrix.new
447
+ translation_matrix._11 = translation_matrix._22 = translation_matrix._33 = translation_matrix._44 = 1
448
+ #todo: consider simplifying with identity
449
+ translation_matrix._41 = x
450
+ translation_matrix._42 = y
451
+ translation_matrix._43 = z
452
+ translation_matrix
453
+ end
454
+
455
+ def self.scaling x, y, z
456
+ scaling_matrix = Matrix.new
457
+ scaling_matrix._11 = x
458
+ scaling_matrix._22 = y
459
+ scaling_matrix._33 = z
460
+ scaling_matrix._44 = 1
461
+ scaling_matrix
462
+ end
463
+
464
+ def self.uniform_scaling scale
465
+ scaling scale, scale, scale
466
+ end
467
+
468
+ def self.rotation_y_rh angle
469
+ sine = Math.sin angle
470
+ cosine = Math.cos angle
471
+ rotation_matrix = Matrix.new
472
+ rotation_matrix._11 = cosine
473
+ rotation_matrix._12 = 0
474
+ rotation_matrix._13 = sine
475
+ rotation_matrix._14 = 0
476
+ rotation_matrix._21 = rotation_matrix._23 = rotation_matrix._24 = 0
477
+ rotation_matrix._22 = 1
478
+ rotation_matrix._31 = -sine
479
+ rotation_matrix._32 = 0
480
+ rotation_matrix._33 = cosine
481
+ rotation_matrix._34 = 0
482
+ rotation_matrix._41 = rotation_matrix._42 = rotation_matrix._43 = 0
483
+ rotation_matrix._44 = 1
484
+ rotation_matrix
485
+ end
486
+ end
487
+ end
@@ -0,0 +1,51 @@
1
+ module Geo3d
2
+ class Quaternion
3
+ attr_reader :x, :y, :z, :w
4
+
5
+ def initialize rotation_axis = nil, radians = 0
6
+ @x = @y = @z = @w = 0
7
+
8
+ if rotation_axis
9
+
10
+ normalized_rotation_axis = rotation_axis.normalize
11
+ #const float radians = GeoConvertToRadians( degrees );
12
+ @x = Math.sin(radians / 2.0) * normalized_rotation_axis.x
13
+ @y = Math.sin(radians / 2.0) * normalized_rotation_axis.y
14
+ @z = Math.sin(radians / 2.0) * normalized_rotation_axis.z
15
+ @w = Math.cos(radians / 2.0);
16
+ end
17
+ end
18
+
19
+ def * quat
20
+ out = Quat.new
21
+ out.w = w * quat.w - x * quat.x - y * quat.y - z * quat.z
22
+ out.x = w * quat.x + x * quat.w + y * quat.z - z * quat.y
23
+ out.y = w * quat.y - x * quat.z + y * quat.w + z * quat.x
24
+ out.z = w * quat.z + x * quat.y - y * quat.x + z * quat.w
25
+ out
26
+ end
27
+
28
+ def to_matrix
29
+ v = Vector.new(x, y, z, w); ## Normalize();
30
+ matrix = Matrix.identity
31
+ matrix._11 = 1.0 - 2.0 * (v.y * v.y + v.z * v.z)
32
+ matrix._12 = 2.0 * (v.x * v.y + v.z * v.w)
33
+ matrix._13 = 2.0 * (v.x * v.z - v.y * v.w)
34
+ matrix._21 = 2.0 * (v.x * v.y - v.z * v.w)
35
+ matrix._22 = 1.0 - 2.0 * (v.x * v.x + v.z * v.z)
36
+ matrix._23 = 2.0 * (v.y * v.z + v.x * v.w)
37
+ matrix._31 = 2.0 * (v.x * v.z + v.y * v.w)
38
+ matrix._32 = 2.0 * (v.y * v.z - v.x * v.w)
39
+ matrix._33 = 1.0 - 2.0 * (v.x * v.x + v.y * v.y)
40
+ matrix
41
+ end
42
+
43
+ def axis
44
+ Vector.new(x, y, z).normalize
45
+ end
46
+
47
+ def angle
48
+ Math.acos(w) * 2.0
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,88 @@
1
+ module Geo3d
2
+ class Vector
3
+ attr_accessor :x, :y, :z, :w
4
+
5
+ def initialize *args
6
+ @x, @y, @z, @w = 0, 0, 0, 0
7
+ @x = args[0] if args.size > 0
8
+ @y = args[1] if args.size > 1
9
+ @z = args[2] if args.size > 2
10
+ @w = args[3] if args.size > 3
11
+ end
12
+
13
+ def to_s
14
+ to_a.compact.join ' '
15
+ end
16
+
17
+ def to_a
18
+ [x, y, z, w]
19
+ end
20
+
21
+ def +@
22
+ self * 1
23
+ end
24
+
25
+ def -@
26
+ self * -1
27
+ end
28
+
29
+ def + vec
30
+ self.class.new x + vec.x, y + vec.y, z + vec.z, w + vec.w
31
+ end
32
+
33
+ def - vec
34
+ self.class.new x - vec.x, y - vec.y, z - vec.z, w - vec.w
35
+ end
36
+
37
+ def * scalar
38
+ self.class.new x * scalar, y * scalar, z * scalar, w * scalar
39
+ end
40
+
41
+ def / scalar
42
+ self.class.new x / scalar, y / scalar, z / scalar, w / scalar
43
+ end
44
+
45
+ def == vec
46
+ x == vec.x && y == vec.y && z == vec.z && w == vec.w
47
+ end
48
+
49
+ def != vec
50
+ x != vec.x || y != vec.y || z != vec.z || w != vec.w
51
+ end
52
+
53
+ def cross vec
54
+ self.class.new y * vec.z - z * vec.y, z * vec.x - x * vec.z, x * vec.y - y * vec.x
55
+ end
56
+
57
+ def dot vec
58
+ x * vec.x + y * vec.y + z * vec.z
59
+ end
60
+
61
+ def normalize!
62
+ len = length
63
+ if length > 0
64
+ @x /= len
65
+ @y /= len
66
+ @z /= len
67
+ end
68
+ end
69
+
70
+ def normalize
71
+ v = self.class.new x, y, z
72
+ v.normalize!
73
+ v
74
+ end
75
+
76
+ def length
77
+ Math.sqrt length_squared
78
+ end
79
+
80
+ def length_squared
81
+ dot self
82
+ end
83
+
84
+ def lerp vec, s
85
+ self + ( vec - self )*s;
86
+ end
87
+ end
88
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geo3d
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Misha Conway
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Library for common 3d graphics vector and matrix operations
42
+ email:
43
+ - MishaAConway@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - geo3d.gemspec
54
+ - lib/geo3d.rb
55
+ - lib/geo3d/version.rb
56
+ - lib/matrix.rb
57
+ - lib/quaternion.rb
58
+ - lib/vector.rb
59
+ homepage: ''
60
+ licenses:
61
+ - MIT
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 2.1.11
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: Library for common 3d graphics vector and matrix operations
83
+ test_files: []