cyberarm_engine 0.24.4 → 0.24.5

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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -8
  3. data/.rubocop.yml +7 -7
  4. data/.travis.yml +5 -5
  5. data/Gemfile +6 -6
  6. data/Gemfile.lock +24 -0
  7. data/LICENSE.txt +21 -21
  8. data/README.md +74 -74
  9. data/Rakefile +10 -10
  10. data/assets/shaders/fragment/g_buffer.glsl +30 -30
  11. data/assets/shaders/fragment/lighting.glsl +115 -69
  12. data/assets/shaders/include/light_struct.glsl +11 -11
  13. data/assets/shaders/include/material_struct.glsl +16 -16
  14. data/assets/shaders/vertex/g_buffer.glsl +28 -28
  15. data/assets/shaders/vertex/lighting.glsl +24 -24
  16. data/bin/console +14 -14
  17. data/bin/setup +8 -8
  18. data/cyberarm_engine.gemspec +36 -36
  19. data/lib/cyberarm_engine/animator.rb +219 -219
  20. data/lib/cyberarm_engine/background.rb +180 -179
  21. data/lib/cyberarm_engine/background_image.rb +93 -93
  22. data/lib/cyberarm_engine/background_nine_slice.rb +142 -142
  23. data/lib/cyberarm_engine/bounding_box.rb +150 -150
  24. data/lib/cyberarm_engine/builtin/intro_state.rb +130 -130
  25. data/lib/cyberarm_engine/cache/download_manager.rb +123 -123
  26. data/lib/cyberarm_engine/cache.rb +4 -4
  27. data/lib/cyberarm_engine/common.rb +128 -128
  28. data/lib/cyberarm_engine/config_file.rb +46 -46
  29. data/lib/cyberarm_engine/console/command.rb +157 -157
  30. data/lib/cyberarm_engine/console/commands/help_command.rb +43 -43
  31. data/lib/cyberarm_engine/console/subcommand.rb +99 -99
  32. data/lib/cyberarm_engine/console.rb +248 -248
  33. data/lib/cyberarm_engine/game_object.rb +244 -244
  34. data/lib/cyberarm_engine/game_state.rb +124 -124
  35. data/lib/cyberarm_engine/gosu_ext/draw_arc.rb +97 -97
  36. data/lib/cyberarm_engine/gosu_ext/draw_circle.rb +30 -30
  37. data/lib/cyberarm_engine/gosu_ext/draw_path.rb +17 -17
  38. data/lib/cyberarm_engine/model/material.rb +21 -21
  39. data/lib/cyberarm_engine/model/{model_object.rb → mesh.rb} +131 -131
  40. data/lib/cyberarm_engine/model/parser.rb +74 -74
  41. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -138
  42. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -154
  43. data/lib/cyberarm_engine/model.rb +216 -213
  44. data/lib/cyberarm_engine/model_cache.rb +31 -31
  45. data/lib/cyberarm_engine/notification.rb +82 -82
  46. data/lib/cyberarm_engine/notification_manager.rb +241 -241
  47. data/lib/cyberarm_engine/opengl/light.rb +52 -50
  48. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -46
  49. data/lib/cyberarm_engine/opengl/perspective_camera.rb +41 -38
  50. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -249
  51. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +167 -165
  52. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +307 -304
  53. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +33 -33
  54. data/lib/cyberarm_engine/opengl/shader.rb +408 -406
  55. data/lib/cyberarm_engine/opengl/texture.rb +69 -69
  56. data/lib/cyberarm_engine/opengl.rb +53 -40
  57. data/lib/cyberarm_engine/ray.rb +56 -56
  58. data/lib/cyberarm_engine/stats.rb +200 -200
  59. data/lib/cyberarm_engine/text.rb +260 -260
  60. data/lib/cyberarm_engine/timer.rb +23 -23
  61. data/lib/cyberarm_engine/transform.rb +296 -296
  62. data/lib/cyberarm_engine/trees/aabb_node.rb +126 -0
  63. data/lib/cyberarm_engine/trees/aabb_tree.rb +55 -0
  64. data/lib/cyberarm_engine/trees/aabb_tree_debug.rb +29 -0
  65. data/lib/cyberarm_engine/ui/border_canvas.rb +102 -102
  66. data/lib/cyberarm_engine/ui/dsl.rb +142 -142
  67. data/lib/cyberarm_engine/ui/element.rb +662 -662
  68. data/lib/cyberarm_engine/ui/elements/button.rb +100 -100
  69. data/lib/cyberarm_engine/ui/elements/check_box.rb +54 -54
  70. data/lib/cyberarm_engine/ui/elements/container.rb +404 -404
  71. data/lib/cyberarm_engine/ui/elements/edit_box.rb +179 -179
  72. data/lib/cyberarm_engine/ui/elements/edit_line.rb +297 -297
  73. data/lib/cyberarm_engine/ui/elements/flow.rb +15 -15
  74. data/lib/cyberarm_engine/ui/elements/image.rb +72 -72
  75. data/lib/cyberarm_engine/ui/elements/list_box.rb +79 -79
  76. data/lib/cyberarm_engine/ui/elements/menu.rb +27 -27
  77. data/lib/cyberarm_engine/ui/elements/menu_item.rb +6 -6
  78. data/lib/cyberarm_engine/ui/elements/progress.rb +93 -93
  79. data/lib/cyberarm_engine/ui/elements/radio.rb +6 -6
  80. data/lib/cyberarm_engine/ui/elements/slider.rb +107 -107
  81. data/lib/cyberarm_engine/ui/elements/stack.rb +11 -11
  82. data/lib/cyberarm_engine/ui/elements/text_block.rb +216 -216
  83. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +67 -67
  84. data/lib/cyberarm_engine/ui/event.rb +54 -54
  85. data/lib/cyberarm_engine/ui/gui_state.rb +321 -321
  86. data/lib/cyberarm_engine/ui/style.rb +50 -50
  87. data/lib/cyberarm_engine/ui/theme.rb +225 -225
  88. data/lib/cyberarm_engine/vector.rb +312 -312
  89. data/lib/cyberarm_engine/version.rb +4 -4
  90. data/lib/cyberarm_engine/window.rb +195 -195
  91. data/lib/cyberarm_engine.rb +70 -78
  92. data/mrbgem.rake +29 -29
  93. metadata +8 -7
@@ -1,296 +1,296 @@
1
- module CyberarmEngine
2
- # Basic 4x4 matrix operations
3
- class Transform
4
- attr_reader :elements
5
-
6
- def initialize(matrix)
7
- @elements = matrix
8
-
9
- raise "Transform is wrong size! Got #{@elements.size}, expected 16" if 16 != @elements.size
10
- raise "Invalid value for matrix, must all be numeric!" if @elements.any? { |e| e.nil? || !e.is_a?(Numeric) }
11
- end
12
-
13
- def self.identity
14
- Transform.new(
15
- [
16
- 1, 0, 0, 0,
17
- 0, 1, 0, 0,
18
- 0, 0, 1, 0,
19
- 0, 0, 0, 1
20
- ]
21
- )
22
- end
23
-
24
- ### 2D Operations meant for interacting with Gosu ###
25
-
26
- # 2d rotate operation, replicates Gosu's Gosu.rotate function
27
- def self.rotate(angle, rotate_around = nil)
28
- double c = Math.cos(angle).degrees_to_radians
29
- double s = Math.sin(angle).degrees_to_radians
30
- matrix = [
31
- +c, +s, 0, 0,
32
- -s, +c, 0, 0,
33
- 0, 0, 1, 0,
34
- 0, 0, 0, 1
35
- ]
36
-
37
- rotate_matrix = Transform.new(matrix, rows: 4, columns: 4)
38
-
39
- if rotate_around && (rotate_around.x != 0.0 || rotate_around.y != 0.0)
40
- negative_rotate_around = Vector.new(-rotate_around.x, -rotate_around.y, -rotate_around.z)
41
-
42
- rotate_matrix = concat(
43
- concat(translate(negative_rotate_around), rotate_matrix),
44
- translate(rotate_around)
45
- )
46
- end
47
-
48
- rotate_matrix
49
- end
50
-
51
- # 2d translate operation, replicates Gosu's Gosu.translate function
52
- def self.translate(vector)
53
- x, y, z = vector.to_a[0..2]
54
- matrix = [
55
- 1, 0, 0, 0,
56
- 0, 1, 0, 0,
57
- 0, 0, 1, 0,
58
- x, y, z, 1
59
- ]
60
-
61
- Transform.new(matrix)
62
- end
63
-
64
- # 2d scale operation, replicates Gosu's Gosu.rotate function
65
- def self.scale(vector, center_around = nil)
66
- scale_x, scale_y, scale_z = vector.to_a[0..2]
67
- matrix = [
68
- scale_x, 0, 0, 0,
69
- 0, scale_y, 0, 0,
70
- 0, 0, scale_z, 0,
71
- 0, 0, 0, 1
72
- ]
73
-
74
- scale_matrix = Transform.new(matrix)
75
-
76
- if center_around && (center_around.x != 0.0 || center_around.y != 0.0)
77
- negative_center_around = Vector.new(-center_around.x, -center_around.y, -center_around.z)
78
-
79
- scale_matrix = concat(
80
- concat(translate(negative_center_around), scale_matrix),
81
- translate(center_around)
82
- )
83
- end
84
-
85
- scale_matrix
86
- end
87
-
88
- def self.concat(left, right)
89
- matrix = Array.new(left.elements.size)
90
- rows = 4
91
-
92
- matrix.size.times do |i|
93
- matrix[i] = 0
94
-
95
- rows.times do |j|
96
- matrix[i] += left.elements[i / rows * rows + j] * right.elements[i % rows + j * rows]
97
- end
98
- end
99
-
100
- Transform.new(matrix)
101
- end
102
-
103
- #### 3D Operations meant for OpenGL ###
104
-
105
- def self.translate_3d(vector)
106
- x, y, z = vector.to_a[0..2]
107
- matrix = [
108
- 1, 0, 0, x,
109
- 0, 1, 0, y,
110
- 0, 0, 1, z,
111
- 0, 0, 0, 1
112
- ]
113
-
114
- Transform.new(matrix)
115
- end
116
-
117
- def self.rotate_3d(vector, _order = "zyx")
118
- x, y, z = vector.to_a[0..2].map { |axis| axis * Math::PI / 180.0 }
119
-
120
- rotation_x = Transform.new(
121
- [
122
- 1, 0, 0, 0,
123
- 0, Math.cos(x), -Math.sin(x), 0,
124
- 0, Math.sin(x), Math.cos(x), 0,
125
- 0, 0, 0, 1
126
- ]
127
- )
128
-
129
- rotation_y = Transform.new(
130
- [
131
- Math.cos(y), 0, Math.sin(y), 0,
132
- 0, 1, 0, 0,
133
- -Math.sin(y), 0, Math.cos(y), 0,
134
- 0, 0, 0, 1
135
- ]
136
- )
137
-
138
- rotation_z = Transform.new(
139
- [
140
- Math.cos(z), -Math.sin(z), 0, 0,
141
- Math.sin(z), Math.cos(z), 0, 0,
142
- 0, 0, 1, 0,
143
- 0, 0, 0, 1
144
- ]
145
- )
146
-
147
- rotation_z * rotation_y * rotation_x
148
- end
149
-
150
- # Implements glRotatef
151
- # https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glRotate.xml
152
- def self.rotate_gl(angle, axis)
153
- radians = angle * Math::PI / 180.0
154
- s = Math.sin(radians)
155
- c = Math.cos(radians)
156
-
157
- axis = axis.normalized
158
- x, y, z = axis.to_a[0..2]
159
-
160
- n = (1.0 - c)
161
-
162
- Transform.new(
163
- [
164
- x * x * n + c, x * y * n - z * s, x * z * n + y * s, 0,
165
- y * x * n + z * s, y * y * n + c, y * z * n - x * s, 0,
166
- x * z * n - y * s, y * z * n + x * s, z * z * n + c, 0,
167
- 0, 0, 0, 1.0
168
- ]
169
- )
170
- end
171
-
172
- def self.scale_3d(vector)
173
- x, y, z = vector.to_a[0..2]
174
-
175
- Transform.new(
176
- [
177
- x, 0, 0, 0,
178
- 0, y, 0, 0,
179
- 0, 0, z, 0,
180
- 0, 0, 0, 1
181
- ]
182
- )
183
- end
184
-
185
- def self.perspective(fov_y, aspect_ratio, near, far)
186
- f = 1.0 / Math.tan(fov_y.degrees_to_radians / 2.0) # cotangent
187
- zn = (far + near.to_f) / (near - far.to_f)
188
- zf = (2.0 * far * near.to_f) / (near - far.to_f)
189
-
190
- Transform.new(
191
- [
192
- f / aspect_ratio, 0.0, 0.0, 0.0,
193
- 0.0, f, 0.0, 0.0,
194
- 0.0, 0.0, zn, zf,
195
- 0.0, 0.0, -1.0, 0.0
196
- ]
197
- )
198
- end
199
-
200
- def self.orthographic(left, right, bottom, top, near, far)
201
- s = Vector.new(
202
- 2 / (right - left.to_f),
203
- 2 / (top - bottom.to_f),
204
- -2 / (far - near.to_f)
205
- )
206
-
207
- t = Vector.new(
208
- (right + left.to_f) / (right - left.to_f),
209
- (top + bottom.to_f) / (top - bottom.to_f),
210
- (far + near.to_f) / (far - near.to_f)
211
- )
212
-
213
- Transform.new(
214
- [
215
- s.x, 0.0, 0.0, t.x,
216
- 0.0, s.y, 0.0, t.y,
217
- 0.0, 0.0, s.z, t.z,
218
- 0.0, 0.0, 0.0, 1.0
219
- ]
220
- )
221
- end
222
-
223
- def self.view(eye, orientation)
224
- # https://www.3dgep.com/understanding-the-view-matrix/#The_View_Matrix
225
- cosPitch = Math.cos(orientation.z * Math::PI / 180.0)
226
- sinPitch = Math.sin(orientation.z * Math::PI / 180.0)
227
- cosYaw = Math.cos(orientation.y * Math::PI / 180.0)
228
- sinYaw = Math.sin(orientation.y * Math::PI / 180.0)
229
-
230
- x_axis = Vector.new(cosYaw, 0, -sinYaw)
231
- y_axis = Vector.new(sinYaw * sinPitch, cosPitch, cosYaw * sinPitch)
232
- z_axis = Vector.new(sinYaw * cosPitch, -sinPitch, cosPitch * cosYaw)
233
-
234
- Transform.new(
235
- [
236
- x_axis.x, y_axis.y, z_axis.z, 0,
237
- x_axis.x, y_axis.y, z_axis.z, 0,
238
- x_axis.x, y_axis.y, z_axis.z, 0,
239
- -x_axis.dot(eye), -y_axis.dot(eye), -z_axis.dot(eye), 1
240
- ]
241
- )
242
- end
243
-
244
- def *(other)
245
- case other
246
- when CyberarmEngine::Vector
247
- matrix = @elements.clone
248
- list = other.to_a
249
-
250
- @elements.each_with_index do |e, i|
251
- matrix[i] = e + list[i % 4]
252
- end
253
-
254
- Transform.new(matrix)
255
-
256
- when CyberarmEngine::Transform
257
- multiply_matrices(other)
258
- else
259
- p other.class
260
- raise TypeError, "Expected CyberarmEngine::Vector or CyberarmEngine::Transform got #{other.class}"
261
- end
262
- end
263
-
264
- def get(x, y)
265
- width = 4
266
-
267
- # puts "Transform|#{self.object_id} -> #{@elements[width * y + x].inspect} (index: #{width * y + x})"
268
- @elements[width * y + x]
269
- end
270
-
271
- def multiply_matrices(other)
272
- matrix = Array.new(16, 0)
273
-
274
- 4.times do |x|
275
- 4.times do |y|
276
- 4.times do |k|
277
- matrix[4 * y + x] += get(x, k) * other.get(k, y)
278
- end
279
- end
280
- end
281
-
282
- Transform.new(matrix)
283
- end
284
-
285
- # arranges Matrix in column major form
286
- def to_gl
287
- e = @elements
288
- [
289
- e[0], e[4], e[8], e[12],
290
- e[1], e[5], e[9], e[13],
291
- e[2], e[6], e[10], e[14],
292
- e[3], e[7], e[11], e[15]
293
- ]
294
- end
295
- end
296
- end
1
+ module CyberarmEngine
2
+ # Basic 4x4 matrix operations
3
+ class Transform
4
+ attr_reader :elements
5
+
6
+ def initialize(matrix)
7
+ @elements = matrix
8
+
9
+ raise "Transform is wrong size! Got #{@elements.size}, expected 16" if 16 != @elements.size
10
+ raise "Invalid value for matrix, must all be numeric!" if @elements.any? { |e| e.nil? || !e.is_a?(Numeric) }
11
+ end
12
+
13
+ def self.identity
14
+ Transform.new(
15
+ [
16
+ 1, 0, 0, 0,
17
+ 0, 1, 0, 0,
18
+ 0, 0, 1, 0,
19
+ 0, 0, 0, 1
20
+ ]
21
+ )
22
+ end
23
+
24
+ ### 2D Operations meant for interacting with Gosu ###
25
+
26
+ # 2d rotate operation, replicates Gosu's Gosu.rotate function
27
+ def self.rotate(angle, rotate_around = nil)
28
+ double c = Math.cos(angle).degrees_to_radians
29
+ double s = Math.sin(angle).degrees_to_radians
30
+ matrix = [
31
+ +c, +s, 0, 0,
32
+ -s, +c, 0, 0,
33
+ 0, 0, 1, 0,
34
+ 0, 0, 0, 1
35
+ ]
36
+
37
+ rotate_matrix = Transform.new(matrix, rows: 4, columns: 4)
38
+
39
+ if rotate_around && (rotate_around.x != 0.0 || rotate_around.y != 0.0)
40
+ negative_rotate_around = Vector.new(-rotate_around.x, -rotate_around.y, -rotate_around.z)
41
+
42
+ rotate_matrix = concat(
43
+ concat(translate(negative_rotate_around), rotate_matrix),
44
+ translate(rotate_around)
45
+ )
46
+ end
47
+
48
+ rotate_matrix
49
+ end
50
+
51
+ # 2d translate operation, replicates Gosu's Gosu.translate function
52
+ def self.translate(vector)
53
+ x, y, z = vector.to_a[0..2]
54
+ matrix = [
55
+ 1, 0, 0, 0,
56
+ 0, 1, 0, 0,
57
+ 0, 0, 1, 0,
58
+ x, y, z, 1
59
+ ]
60
+
61
+ Transform.new(matrix)
62
+ end
63
+
64
+ # 2d scale operation, replicates Gosu's Gosu.rotate function
65
+ def self.scale(vector, center_around = nil)
66
+ scale_x, scale_y, scale_z = vector.to_a[0..2]
67
+ matrix = [
68
+ scale_x, 0, 0, 0,
69
+ 0, scale_y, 0, 0,
70
+ 0, 0, scale_z, 0,
71
+ 0, 0, 0, 1
72
+ ]
73
+
74
+ scale_matrix = Transform.new(matrix)
75
+
76
+ if center_around && (center_around.x != 0.0 || center_around.y != 0.0)
77
+ negative_center_around = Vector.new(-center_around.x, -center_around.y, -center_around.z)
78
+
79
+ scale_matrix = concat(
80
+ concat(translate(negative_center_around), scale_matrix),
81
+ translate(center_around)
82
+ )
83
+ end
84
+
85
+ scale_matrix
86
+ end
87
+
88
+ def self.concat(left, right)
89
+ matrix = Array.new(left.elements.size)
90
+ rows = 4
91
+
92
+ matrix.size.times do |i|
93
+ matrix[i] = 0
94
+
95
+ rows.times do |j|
96
+ matrix[i] += left.elements[i / rows * rows + j] * right.elements[i % rows + j * rows]
97
+ end
98
+ end
99
+
100
+ Transform.new(matrix)
101
+ end
102
+
103
+ #### 3D Operations meant for OpenGL ###
104
+
105
+ def self.translate_3d(vector)
106
+ x, y, z = vector.to_a[0..2]
107
+ matrix = [
108
+ 1, 0, 0, x,
109
+ 0, 1, 0, y,
110
+ 0, 0, 1, z,
111
+ 0, 0, 0, 1
112
+ ]
113
+
114
+ Transform.new(matrix)
115
+ end
116
+
117
+ def self.rotate_3d(vector, _order = "zyx")
118
+ x, y, z = vector.to_a[0..2].map { |axis| axis * Math::PI / 180.0 }
119
+
120
+ rotation_x = Transform.new(
121
+ [
122
+ 1, 0, 0, 0,
123
+ 0, Math.cos(x), -Math.sin(x), 0,
124
+ 0, Math.sin(x), Math.cos(x), 0,
125
+ 0, 0, 0, 1
126
+ ]
127
+ )
128
+
129
+ rotation_y = Transform.new(
130
+ [
131
+ Math.cos(y), 0, Math.sin(y), 0,
132
+ 0, 1, 0, 0,
133
+ -Math.sin(y), 0, Math.cos(y), 0,
134
+ 0, 0, 0, 1
135
+ ]
136
+ )
137
+
138
+ rotation_z = Transform.new(
139
+ [
140
+ Math.cos(z), -Math.sin(z), 0, 0,
141
+ Math.sin(z), Math.cos(z), 0, 0,
142
+ 0, 0, 1, 0,
143
+ 0, 0, 0, 1
144
+ ]
145
+ )
146
+
147
+ rotation_z * rotation_y * rotation_x
148
+ end
149
+
150
+ # Implements glRotatef
151
+ # https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glRotate.xml
152
+ def self.rotate_gl(angle, axis)
153
+ radians = angle * Math::PI / 180.0
154
+ s = Math.sin(radians)
155
+ c = Math.cos(radians)
156
+
157
+ axis = axis.normalized
158
+ x, y, z = axis.to_a[0..2]
159
+
160
+ n = (1.0 - c)
161
+
162
+ Transform.new(
163
+ [
164
+ x * x * n + c, x * y * n - z * s, x * z * n + y * s, 0,
165
+ y * x * n + z * s, y * y * n + c, y * z * n - x * s, 0,
166
+ x * z * n - y * s, y * z * n + x * s, z * z * n + c, 0,
167
+ 0, 0, 0, 1.0
168
+ ]
169
+ )
170
+ end
171
+
172
+ def self.scale_3d(vector)
173
+ x, y, z = vector.to_a[0..2]
174
+
175
+ Transform.new(
176
+ [
177
+ x, 0, 0, 0,
178
+ 0, y, 0, 0,
179
+ 0, 0, z, 0,
180
+ 0, 0, 0, 1
181
+ ]
182
+ )
183
+ end
184
+
185
+ def self.perspective(fov_y, aspect_ratio, near, far)
186
+ f = 1.0 / Math.tan(fov_y.degrees_to_radians / 2.0) # cotangent
187
+ zn = (far + near.to_f) / (near - far.to_f)
188
+ zf = (2.0 * far * near.to_f) / (near - far.to_f)
189
+
190
+ Transform.new(
191
+ [
192
+ f / aspect_ratio, 0.0, 0.0, 0.0,
193
+ 0.0, f, 0.0, 0.0,
194
+ 0.0, 0.0, zn, zf,
195
+ 0.0, 0.0, -1.0, 0.0
196
+ ]
197
+ )
198
+ end
199
+
200
+ def self.orthographic(left, right, bottom, top, near, far)
201
+ s = Vector.new(
202
+ 2 / (right - left.to_f),
203
+ 2 / (top - bottom.to_f),
204
+ -2 / (far - near.to_f)
205
+ )
206
+
207
+ t = Vector.new(
208
+ (right + left.to_f) / (right - left.to_f),
209
+ (top + bottom.to_f) / (top - bottom.to_f),
210
+ (far + near.to_f) / (far - near.to_f)
211
+ )
212
+
213
+ Transform.new(
214
+ [
215
+ s.x, 0.0, 0.0, t.x,
216
+ 0.0, s.y, 0.0, t.y,
217
+ 0.0, 0.0, s.z, t.z,
218
+ 0.0, 0.0, 0.0, 1.0
219
+ ]
220
+ )
221
+ end
222
+
223
+ def self.view(eye, orientation)
224
+ # https://www.3dgep.com/understanding-the-view-matrix/#The_View_Matrix
225
+ cosPitch = Math.cos(orientation.z * Math::PI / 180.0)
226
+ sinPitch = Math.sin(orientation.z * Math::PI / 180.0)
227
+ cosYaw = Math.cos(orientation.y * Math::PI / 180.0)
228
+ sinYaw = Math.sin(orientation.y * Math::PI / 180.0)
229
+
230
+ x_axis = Vector.new(cosYaw, 0, -sinYaw)
231
+ y_axis = Vector.new(sinYaw * sinPitch, cosPitch, cosYaw * sinPitch)
232
+ z_axis = Vector.new(sinYaw * cosPitch, -sinPitch, cosPitch * cosYaw)
233
+
234
+ Transform.new(
235
+ [
236
+ x_axis.x, y_axis.y, z_axis.z, 0,
237
+ x_axis.x, y_axis.y, z_axis.z, 0,
238
+ x_axis.x, y_axis.y, z_axis.z, 0,
239
+ -x_axis.dot(eye), -y_axis.dot(eye), -z_axis.dot(eye), 1
240
+ ]
241
+ )
242
+ end
243
+
244
+ def *(other)
245
+ case other
246
+ when CyberarmEngine::Vector
247
+ matrix = @elements.clone
248
+ list = other.to_a
249
+
250
+ @elements.each_with_index do |e, i|
251
+ matrix[i] = e + list[i % 4]
252
+ end
253
+
254
+ Transform.new(matrix)
255
+
256
+ when CyberarmEngine::Transform
257
+ multiply_matrices(other)
258
+ else
259
+ p other.class
260
+ raise TypeError, "Expected CyberarmEngine::Vector or CyberarmEngine::Transform got #{other.class}"
261
+ end
262
+ end
263
+
264
+ def get(x, y)
265
+ width = 4
266
+
267
+ # puts "Transform|#{self.object_id} -> #{@elements[width * y + x].inspect} (index: #{width * y + x})"
268
+ @elements[width * y + x]
269
+ end
270
+
271
+ def multiply_matrices(other)
272
+ matrix = Array.new(16, 0)
273
+
274
+ 4.times do |x|
275
+ 4.times do |y|
276
+ 4.times do |k|
277
+ matrix[4 * y + x] += get(x, k) * other.get(k, y)
278
+ end
279
+ end
280
+ end
281
+
282
+ Transform.new(matrix)
283
+ end
284
+
285
+ # arranges Matrix in column major form
286
+ def to_gl
287
+ e = @elements
288
+ [
289
+ e[0], e[4], e[8], e[12],
290
+ e[1], e[5], e[9], e[13],
291
+ e[2], e[6], e[10], e[14],
292
+ e[3], e[7], e[11], e[15]
293
+ ]
294
+ end
295
+ end
296
+ end