geo3d 0.0.1

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.
@@ -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: []