mittsu 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 (203) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +3 -0
  4. data/CODE_OF_CONDUCT.md +13 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +39 -0
  8. data/Rakefile +7 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +7 -0
  11. data/examples/01_-_Default1noCulling.png +0 -0
  12. data/examples/01_scene_example.rb +14 -0
  13. data/examples/02_box_mesh_example.rb +30 -0
  14. data/examples/02_sphere_mesh_example.rb +30 -0
  15. data/examples/03_complex_object_example.rb +52 -0
  16. data/examples/04_ambient_light_example.rb +33 -0
  17. data/examples/04_dir_light_example.rb +36 -0
  18. data/examples/04_hemi_light_example.rb +30 -0
  19. data/examples/04_point_light_example.rb +50 -0
  20. data/examples/04_spot_light_example.rb +44 -0
  21. data/examples/05_earth_example.rb +42 -0
  22. data/examples/05_earth_moon_example.rb +46 -0
  23. data/examples/05_texture_example.rb +32 -0
  24. data/examples/06_cube_texture_example.rb +36 -0
  25. data/examples/06_skybox_example.rb +60 -0
  26. data/examples/07_earth_normal_example.rb +36 -0
  27. data/examples/08_shadow_example.rb +87 -0
  28. data/examples/09_line_example.rb +52 -0
  29. data/examples/10_obj_loader_example.rb +68 -0
  30. data/examples/11_character_input_example.rb +18 -0
  31. data/examples/11_continuous_keyboard_input_example.rb +35 -0
  32. data/examples/11_keyboard_input_example.rb +43 -0
  33. data/examples/12_mouse_click_example.rb +38 -0
  34. data/examples/12_mouse_motion_example.rb +35 -0
  35. data/examples/12_mouse_scroll_example.rb +36 -0
  36. data/examples/12_orbit_zoom_example.rb +68 -0
  37. data/examples/13_joystick_example.rb +80 -0
  38. data/examples/cubemap/tron_bk.png +0 -0
  39. data/examples/cubemap/tron_dn.png +0 -0
  40. data/examples/cubemap/tron_ft.png +0 -0
  41. data/examples/cubemap/tron_lf.png +0 -0
  42. data/examples/cubemap/tron_rt.png +0 -0
  43. data/examples/cubemap/tron_up.png +0 -0
  44. data/examples/earth.png +0 -0
  45. data/examples/earth_normal.png +0 -0
  46. data/examples/example_helper.rb +2 -0
  47. data/examples/male-02-1noCulling.png +0 -0
  48. data/examples/male02.mtl +54 -0
  49. data/examples/male02.obj +13888 -0
  50. data/examples/moon.png +0 -0
  51. data/examples/orig_02_-_Defaul1noCulling.png +0 -0
  52. data/examples/texture.png +0 -0
  53. data/lib/mittsu.rb +15 -0
  54. data/lib/mittsu/cameras.rb +4 -0
  55. data/lib/mittsu/cameras/camera.rb +34 -0
  56. data/lib/mittsu/cameras/cube_camera.rb +74 -0
  57. data/lib/mittsu/cameras/orthographic_camera.rb +53 -0
  58. data/lib/mittsu/cameras/perspective_camera.rb +115 -0
  59. data/lib/mittsu/constants.rb +160 -0
  60. data/lib/mittsu/core.rb +10 -0
  61. data/lib/mittsu/core/buffer_attribute.rb +87 -0
  62. data/lib/mittsu/core/buffer_geometry.rb +694 -0
  63. data/lib/mittsu/core/clock.rb +44 -0
  64. data/lib/mittsu/core/dynamic_buffer_attribute.rb +16 -0
  65. data/lib/mittsu/core/event_dispatcher.rb +39 -0
  66. data/lib/mittsu/core/face3.rb +30 -0
  67. data/lib/mittsu/core/geometry.rb +596 -0
  68. data/lib/mittsu/core/hash_array.rb +36 -0
  69. data/lib/mittsu/core/hash_object.rb +19 -0
  70. data/lib/mittsu/core/object_3d.rb +421 -0
  71. data/lib/mittsu/core/raycaster.rb +78 -0
  72. data/lib/mittsu/extras.rb +3 -0
  73. data/lib/mittsu/extras/geometries.rb +2 -0
  74. data/lib/mittsu/extras/geometries/box_geometry.rb +108 -0
  75. data/lib/mittsu/extras/geometries/sphere_geometry.rb +88 -0
  76. data/lib/mittsu/extras/helpers.rb +1 -0
  77. data/lib/mittsu/extras/helpers/camera_helper.rb +155 -0
  78. data/lib/mittsu/extras/image.rb +3 -0
  79. data/lib/mittsu/extras/image_utils.rb +80 -0
  80. data/lib/mittsu/lights.rb +7 -0
  81. data/lib/mittsu/lights/ambient_light.rb +16 -0
  82. data/lib/mittsu/lights/area_light.rb +24 -0
  83. data/lib/mittsu/lights/directional_light.rb +131 -0
  84. data/lib/mittsu/lights/hemisphere_light.rb +29 -0
  85. data/lib/mittsu/lights/light.rb +21 -0
  86. data/lib/mittsu/lights/point_light.rb +27 -0
  87. data/lib/mittsu/lights/spot_light.rb +104 -0
  88. data/lib/mittsu/loaders.rb +7 -0
  89. data/lib/mittsu/loaders/cache.rb +53 -0
  90. data/lib/mittsu/loaders/file_loader.rb +22 -0
  91. data/lib/mittsu/loaders/image_loader.rb +32 -0
  92. data/lib/mittsu/loaders/loader.rb +212 -0
  93. data/lib/mittsu/loaders/loading_manager.rb +17 -0
  94. data/lib/mittsu/loaders/mtl_loader.rb +242 -0
  95. data/lib/mittsu/loaders/obj_mtl_loader.rb +225 -0
  96. data/lib/mittsu/materials.rb +7 -0
  97. data/lib/mittsu/materials/line_basic_material.rb +39 -0
  98. data/lib/mittsu/materials/material.rb +156 -0
  99. data/lib/mittsu/materials/mesh_basic_material.rb +122 -0
  100. data/lib/mittsu/materials/mesh_face_material.rb +30 -0
  101. data/lib/mittsu/materials/mesh_lambert_material.rb +126 -0
  102. data/lib/mittsu/materials/mesh_phong_material.rb +152 -0
  103. data/lib/mittsu/materials/shader_material.rb +108 -0
  104. data/lib/mittsu/math.rb +105 -0
  105. data/lib/mittsu/math/box2.rb +135 -0
  106. data/lib/mittsu/math/box3.rb +194 -0
  107. data/lib/mittsu/math/color.rb +252 -0
  108. data/lib/mittsu/math/color_keywords.rb +151 -0
  109. data/lib/mittsu/math/euler.rb +182 -0
  110. data/lib/mittsu/math/frustum.rb +106 -0
  111. data/lib/mittsu/math/line3.rb +76 -0
  112. data/lib/mittsu/math/matrix3.rb +163 -0
  113. data/lib/mittsu/math/matrix4.rb +581 -0
  114. data/lib/mittsu/math/plane.rb +128 -0
  115. data/lib/mittsu/math/quaternion.rb +309 -0
  116. data/lib/mittsu/math/ray.rb +292 -0
  117. data/lib/mittsu/math/sphere.rb +91 -0
  118. data/lib/mittsu/math/spline.rb +128 -0
  119. data/lib/mittsu/math/triangle.rb +121 -0
  120. data/lib/mittsu/math/vector2.rb +238 -0
  121. data/lib/mittsu/math/vector3.rb +491 -0
  122. data/lib/mittsu/math/vector4.rb +414 -0
  123. data/lib/mittsu/objects.rb +3 -0
  124. data/lib/mittsu/objects/group.rb +8 -0
  125. data/lib/mittsu/objects/line.rb +143 -0
  126. data/lib/mittsu/objects/mesh.rb +243 -0
  127. data/lib/mittsu/renderers.rb +1 -0
  128. data/lib/mittsu/renderers/glfw_window.rb +216 -0
  129. data/lib/mittsu/renderers/opengl/opengl_debug.rb +38 -0
  130. data/lib/mittsu/renderers/opengl/opengl_program.rb +402 -0
  131. data/lib/mittsu/renderers/opengl/opengl_shader.rb +58 -0
  132. data/lib/mittsu/renderers/opengl/opengl_state.rb +207 -0
  133. data/lib/mittsu/renderers/opengl/plugins/shadow_map_plugin.rb +416 -0
  134. data/lib/mittsu/renderers/opengl_render_target.rb +87 -0
  135. data/lib/mittsu/renderers/opengl_renderer.rb +3376 -0
  136. data/lib/mittsu/renderers/shaders/shader_chunk.rb +12 -0
  137. data/lib/mittsu/renderers/shaders/shader_chunk/alphamap_fragment.glsl +5 -0
  138. data/lib/mittsu/renderers/shaders/shader_chunk/alphamap_pars_fragment.glsl +5 -0
  139. data/lib/mittsu/renderers/shaders/shader_chunk/alphatest_fragment.glsl +5 -0
  140. data/lib/mittsu/renderers/shaders/shader_chunk/bumpmap_pars_fragment.glsl +40 -0
  141. data/lib/mittsu/renderers/shaders/shader_chunk/color_fragment.glsl +5 -0
  142. data/lib/mittsu/renderers/shaders/shader_chunk/color_pars_fragment.glsl +5 -0
  143. data/lib/mittsu/renderers/shaders/shader_chunk/color_pars_vertex.glsl +5 -0
  144. data/lib/mittsu/renderers/shaders/shader_chunk/color_vertex.glsl +5 -0
  145. data/lib/mittsu/renderers/shaders/shader_chunk/common.glsl +60 -0
  146. data/lib/mittsu/renderers/shaders/shader_chunk/default_vertex.glsl +15 -0
  147. data/lib/mittsu/renderers/shaders/shader_chunk/defaultnormal_vertex.glsl +21 -0
  148. data/lib/mittsu/renderers/shaders/shader_chunk/envmap_fragment.glsl +62 -0
  149. data/lib/mittsu/renderers/shaders/shader_chunk/envmap_pars_fragment.glsl +21 -0
  150. data/lib/mittsu/renderers/shaders/shader_chunk/envmap_pars_vertex.glsl +7 -0
  151. data/lib/mittsu/renderers/shaders/shader_chunk/envmap_vertex.glsl +17 -0
  152. data/lib/mittsu/renderers/shaders/shader_chunk/fog_fragment.glsl +26 -0
  153. data/lib/mittsu/renderers/shaders/shader_chunk/fog_pars_fragment.glsl +15 -0
  154. data/lib/mittsu/renderers/shaders/shader_chunk/lightmap_fragment.glsl +5 -0
  155. data/lib/mittsu/renderers/shaders/shader_chunk/lightmap_pars_fragment.glsl +6 -0
  156. data/lib/mittsu/renderers/shaders/shader_chunk/lightmap_pars_vertex.glsl +5 -0
  157. data/lib/mittsu/renderers/shaders/shader_chunk/lightmap_vertex.glsl +5 -0
  158. data/lib/mittsu/renderers/shaders/shader_chunk/lights_lambert_pars_vertex.glsl +43 -0
  159. data/lib/mittsu/renderers/shaders/shader_chunk/lights_lambert_vertex.glsl +196 -0
  160. data/lib/mittsu/renderers/shaders/shader_chunk/lights_phong_fragment.glsl +243 -0
  161. data/lib/mittsu/renderers/shaders/shader_chunk/lights_phong_pars_fragment.glsl +58 -0
  162. data/lib/mittsu/renderers/shaders/shader_chunk/lights_phong_pars_vertex.glsl +5 -0
  163. data/lib/mittsu/renderers/shaders/shader_chunk/lights_phong_vertex.glsl +5 -0
  164. data/lib/mittsu/renderers/shaders/shader_chunk/linear_to_gamma_fragment.glsl +2 -0
  165. data/lib/mittsu/renderers/shaders/shader_chunk/logdepthbuf_fragment.glsl +5 -0
  166. data/lib/mittsu/renderers/shaders/shader_chunk/logdepthbuf_pars_fragment.glsl +12 -0
  167. data/lib/mittsu/renderers/shaders/shader_chunk/logdepthbuf_pars_vertex.glsl +11 -0
  168. data/lib/mittsu/renderers/shaders/shader_chunk/logdepthbuf_vertex.glsl +15 -0
  169. data/lib/mittsu/renderers/shaders/shader_chunk/map_fragment.glsl +9 -0
  170. data/lib/mittsu/renderers/shaders/shader_chunk/map_pars_fragment.glsl +11 -0
  171. data/lib/mittsu/renderers/shaders/shader_chunk/map_pars_vertex.glsl +6 -0
  172. data/lib/mittsu/renderers/shaders/shader_chunk/map_particle_fragment.glsl +5 -0
  173. data/lib/mittsu/renderers/shaders/shader_chunk/map_particle_pars_fragment.glsl +6 -0
  174. data/lib/mittsu/renderers/shaders/shader_chunk/map_vertex.glsl +5 -0
  175. data/lib/mittsu/renderers/shaders/shader_chunk/morphnormal_vertex.glsl +12 -0
  176. data/lib/mittsu/renderers/shaders/shader_chunk/morphtarget_pars_vertex.glsl +13 -0
  177. data/lib/mittsu/renderers/shaders/shader_chunk/morphtarget_vertex.glsl +20 -0
  178. data/lib/mittsu/renderers/shaders/shader_chunk/normalmap_pars_fragment.glsl +27 -0
  179. data/lib/mittsu/renderers/shaders/shader_chunk/shadowmap_fragment.glsl +217 -0
  180. data/lib/mittsu/renderers/shaders/shader_chunk/shadowmap_pars_fragment.glsl +19 -0
  181. data/lib/mittsu/renderers/shaders/shader_chunk/shadowmap_pars_vertex.glsl +6 -0
  182. data/lib/mittsu/renderers/shaders/shader_chunk/shadowmap_vertex.glsl +9 -0
  183. data/lib/mittsu/renderers/shaders/shader_chunk/skinbase_vertex.glsl +8 -0
  184. data/lib/mittsu/renderers/shaders/shader_chunk/skinning_pars_vertex.glsl +47 -0
  185. data/lib/mittsu/renderers/shaders/shader_chunk/skinning_vertex.glsl +20 -0
  186. data/lib/mittsu/renderers/shaders/shader_chunk/skinnormal_vertex.glsl +20 -0
  187. data/lib/mittsu/renderers/shaders/shader_chunk/specularmap_fragment.glsl +12 -0
  188. data/lib/mittsu/renderers/shaders/shader_chunk/specularmap_pars_fragment.glsl +5 -0
  189. data/lib/mittsu/renderers/shaders/shader_chunk/worldpos_vertex.glsl +17 -0
  190. data/lib/mittsu/renderers/shaders/shader_lib.rb +420 -0
  191. data/lib/mittsu/renderers/shaders/uniforms_lib.rb +107 -0
  192. data/lib/mittsu/renderers/shaders/uniforms_utils.rb +31 -0
  193. data/lib/mittsu/scenes.rb +1 -0
  194. data/lib/mittsu/scenes/scene.rb +27 -0
  195. data/lib/mittsu/textures.rb +5 -0
  196. data/lib/mittsu/textures/compressed_texture.rb +30 -0
  197. data/lib/mittsu/textures/cube_texture.rb +19 -0
  198. data/lib/mittsu/textures/data_texture.rb +17 -0
  199. data/lib/mittsu/textures/texture.rb +92 -0
  200. data/lib/mittsu/textures/video_texture.rb +17 -0
  201. data/lib/mittsu/version.rb +4 -0
  202. data/mittsu.gemspec +31 -0
  203. metadata +357 -0
@@ -0,0 +1,163 @@
1
+ require 'mittsu/math'
2
+
3
+ module Mittsu
4
+ class Matrix3
5
+ attr_accessor :elements
6
+ def initialize
7
+ @elements = [
8
+ 1.0, 0.0, 0.0,
9
+ 0.0, 1.0, 0.0,
10
+ 0.0, 0.0, 1.0
11
+ ]
12
+ end
13
+
14
+ def set(n11, n12, n13, n21, n22, n23, n31, n32, n33)
15
+ te = self.elements
16
+ te[0] = n11.to_f; te[3] = n12.to_f; te[6] = n13.to_f
17
+ te[1] = n21.to_f; te[4] = n22.to_f; te[7] = n23.to_f
18
+ te[2] = n31.to_f; te[5] = n32.to_f; te[8] = n33.to_f
19
+ self
20
+ end
21
+
22
+ def identity
23
+ self.set(
24
+ 1.0, 0.0, 0.0,
25
+ 0.0, 1.0, 0.0,
26
+ 0.0, 0.0, 1.0
27
+ )
28
+ self
29
+ end
30
+
31
+ def copy(m)
32
+ me = m.elements
33
+ self.set(
34
+ me[0], me[3], me[6],
35
+ me[1], me[4], me[7],
36
+ me[2], me[5], me[8]
37
+ )
38
+ self
39
+ end
40
+
41
+ def apply_to_vector3_array(array, offset = 0, length = array.length)
42
+ v1 = Mittsu::Vector3.new
43
+ i, j = 0, offset
44
+ while i < length
45
+ v1.x = array[j]
46
+ v1.y = array[j + 1]
47
+ v1.z = array[j + 2]
48
+ v1.apply_matrix3(self)
49
+ array[j] = v1.x
50
+ array[j + 1] = v1.y
51
+ array[j + 2] = v1.z
52
+ i += 3
53
+ j += 3
54
+ end
55
+ array
56
+ end
57
+
58
+ def multiply_scalar(s)
59
+ te = self.elements
60
+ te[0] *= s; te[3] *= s; te[6] *= s
61
+ te[1] *= s; te[4] *= s; te[7] *= s
62
+ te[2] *= s; te[5] *= s; te[8] *= s
63
+ self
64
+ end
65
+
66
+ def determinant
67
+ a, b, c, d, e, f, g, h, i = *self.elements
68
+ a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g
69
+ end
70
+
71
+ def inverse(matrix, throw_on_invertible = false)
72
+ # input: Mittsu::Matrix4
73
+ # (based on http:#code.google.com/p/webgl-mjs/)
74
+ me = matrix.elements
75
+ te = self.elements
76
+ te[0] = me[10] * me[5] - me[6] * me[9]
77
+ te[1] = - me[10] * me[1] + me[2] * me[9]
78
+ te[2] = me[6] * me[1] - me[2] * me[5]
79
+ te[3] = - me[10] * me[4] + me[6] * me[8]
80
+ te[4] = me[10] * me[0] - me[2] * me[8]
81
+ te[5] = - me[6] * me[0] + me[2] * me[4]
82
+ te[6] = me[9] * me[4] - me[5] * me[8]
83
+ te[7] = - me[9] * me[0] + me[1] * me[8]
84
+ te[8] = me[5] * me[0] - me[1] * me[4]
85
+ det = me[0] * te[0] + me[1] * te[3] + me[2] * te[6]
86
+ # no inverse
87
+ if det.zero?
88
+ msg = "Mittsu::Matrix3#inverse: can't invert matrix, determinant is 0"
89
+ if throw_on_invertible
90
+ raise Error.new(msg)
91
+ else
92
+ puts "WARNING: #{msg}"
93
+ # THREE.warn(msg)
94
+ end
95
+ self.identity
96
+ return self
97
+ end
98
+ self.multiply_scalar(1.0 / det)
99
+ self
100
+ end
101
+
102
+ def transpose
103
+ m = self.elements
104
+ tmp = m[1]; m[1] = m[3]; m[3] = tmp
105
+ tmp = m[2]; m[2] = m[6]; m[6] = tmp
106
+ tmp = m[5]; m[5] = m[7]; m[7] = tmp
107
+ self
108
+ end
109
+
110
+ def flatten_to_array_offset(array, offset)
111
+ te = self.elements
112
+ array[offset ] = te[0]
113
+ array[offset + 1] = te[1]
114
+ array[offset + 2] = te[2]
115
+ array[offset + 3] = te[3]
116
+ array[offset + 4] = te[4]
117
+ array[offset + 5] = te[5]
118
+ array[offset + 6] = te[6]
119
+ array[offset + 7] = te[7]
120
+ array[offset + 8] = te[8]
121
+ array
122
+ end
123
+
124
+ def normal_matrix(m)
125
+ # input: THREE.Matrix4
126
+ self.inverse(m).transpose
127
+ self
128
+ end
129
+
130
+ def transpose_into_array(r)
131
+ m = self.elements
132
+ r[0] = m[0]
133
+ r[1] = m[3]
134
+ r[2] = m[6]
135
+ r[3] = m[1]
136
+ r[4] = m[4]
137
+ r[5] = m[7]
138
+ r[6] = m[2]
139
+ r[7] = m[5]
140
+ r[8] = m[8]
141
+ self
142
+ end
143
+
144
+ def from_array(array)
145
+ self.elements[0..array.length] = (array)
146
+ self
147
+ end
148
+
149
+ def to_a
150
+ te = self.elements
151
+ [
152
+ te[0], te[1], te[2],
153
+ te[3], te[4], te[5],
154
+ te[6], te[7], te[8]
155
+ ]
156
+ end
157
+
158
+ def clone
159
+ Mittsu::Matrix3.new.from_array(self.elements)
160
+ end
161
+
162
+ end
163
+ end
@@ -0,0 +1,581 @@
1
+ require 'mittsu/math'
2
+
3
+ module Mittsu
4
+ class Matrix4
5
+ attr_accessor :elements
6
+
7
+ def initialize()
8
+ @elements = [
9
+ 1.0, 0.0, 0.0, 0.0,
10
+ 0.0, 1.0, 0.0, 0.0,
11
+ 0.0, 0.0, 1.0, 0.0,
12
+ 0.0, 0.0, 0.0, 1.0
13
+ ]
14
+ end
15
+
16
+ def set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44)
17
+ te = self.elements
18
+ te[0] = n11.to_f; te[4] = n12.to_f; te[8] = n13.to_f; te[12] = n14.to_f
19
+ te[1] = n21.to_f; te[5] = n22.to_f; te[9] = n23.to_f; te[13] = n24.to_f
20
+ te[2] = n31.to_f; te[6] = n32.to_f; te[10] = n33.to_f; te[14] = n34.to_f
21
+ te[3] = n41.to_f; te[7] = n42.to_f; te[11] = n43.to_f; te[15] = n44.to_f
22
+ self
23
+ end
24
+
25
+ def identity
26
+ self.set(
27
+ 1.0, 0.0, 0.0, 0.0,
28
+ 0.0, 1.0, 0.0, 0.0,
29
+ 0.0, 0.0, 1.0, 0.0,
30
+ 0.0, 0.0, 0.0, 1.0
31
+ )
32
+ self
33
+ end
34
+
35
+ def copy(m)
36
+ self.from_array(m.elements)
37
+ self
38
+ end
39
+
40
+ def copy_position(m)
41
+ te = self.elements
42
+ me = m.elements
43
+ te[12] = me[12]
44
+ te[13] = me[13]
45
+ te[14] = me[14]
46
+ self
47
+ end
48
+
49
+ def extract_basis(x_axis, y_axis, z_axis)
50
+ te = self.elements
51
+ x_axis.set(te[0], te[1], te[2])
52
+ y_axis.set(te[4], te[5], te[6])
53
+ z_axis.set(te[8], te[9], te[10])
54
+ self
55
+ end
56
+
57
+ def make_basis(x_axis, y_axis, z_axis)
58
+ self.set(
59
+ x_axis.x, y_axis.x, z_axis.x, 0.0,
60
+ x_axis.y, y_axis.y, z_axis.y, 0.0,
61
+ x_axis.z, y_axis.z, z_axis.z, 0.0,
62
+ 0.0, 0.0, 0.0, 1.0
63
+ )
64
+ self
65
+ end
66
+
67
+ def extract_rotation(m)
68
+ v1 = Mittsu::Vector3.new
69
+ te = self.elements
70
+ me = m.elements
71
+ scale_x = 1.0 / v1.set(me[0], me[1], me[2]).length
72
+ scale_y = 1.0 / v1.set(me[4], me[5], me[6]).length
73
+ scale_z = 1.0 / v1.set(me[8], me[9], me[10]).length
74
+ te[0] = me[0] * scale_x
75
+ te[1] = me[1] * scale_x
76
+ te[2] = me[2] * scale_x
77
+ te[4] = me[4] * scale_y
78
+ te[5] = me[5] * scale_y
79
+ te[6] = me[6] * scale_y
80
+ te[8] = me[8] * scale_z
81
+ te[9] = me[9] * scale_z
82
+ te[10] = me[10] * scale_z
83
+ self
84
+ end
85
+
86
+ def make_rotation_from_euler(euler)
87
+ te = self.elements
88
+ x, y, z = euler.x, euler.y, euler.z
89
+ a, b = Math.cos(x), Math.sin(x)
90
+ c, d = Math.cos(y), Math.sin(y)
91
+ e, f = Math.cos(z), Math.sin(z)
92
+ if euler.order == 'XYZ'
93
+ ae = a * e; af = a * f; be = b * e; bf = b * f
94
+ te[0] = c * e
95
+ te[4] = - c * f
96
+ te[8] = d
97
+ te[1] = af + be * d
98
+ te[5] = ae - bf * d
99
+ te[9] = - b * c
100
+ te[2] = bf - ae * d
101
+ te[6] = be + af * d
102
+ te[10] = a * c
103
+ elsif euler.order == 'YXZ'
104
+ ce = c * e; cf = c * f; de = d * e; df = d * f
105
+ te[0] = ce + df * b
106
+ te[4] = de * b - cf
107
+ te[8] = a * d
108
+ te[1] = a * f
109
+ te[5] = a * e
110
+ te[9] = - b
111
+ te[2] = cf * b - de
112
+ te[6] = df + ce * b
113
+ te[10] = a * c
114
+ elsif euler.order == 'ZXY'
115
+ ce = c * e; cf = c * f; de = d * e; df = d * f
116
+ te[0] = ce - df * b
117
+ te[4] = - a * f
118
+ te[8] = de + cf * b
119
+ te[1] = cf + de * b
120
+ te[5] = a * e
121
+ te[9] = df - ce * b
122
+ te[2] = - a * d
123
+ te[6] = b
124
+ te[10] = a * c
125
+ elsif euler.order == 'ZYX'
126
+ ae = a * e; af = a * f; be = b * e; bf = b * f
127
+ te[0] = c * e
128
+ te[4] = be * d - af
129
+ te[8] = ae * d + bf
130
+ te[1] = c * f
131
+ te[5] = bf * d + ae
132
+ te[9] = af * d - be
133
+ te[2] = - d
134
+ te[6] = b * c
135
+ te[10] = a * c
136
+ elsif euler.order == 'YZX'
137
+ ac = a * c; ad = a * d; bc = b * c; bd = b * d
138
+ te[0] = c * e
139
+ te[4] = bd - ac * f
140
+ te[8] = bc * f + ad
141
+ te[1] = f
142
+ te[5] = a * e
143
+ te[9] = - b * e
144
+ te[2] = - d * e
145
+ te[6] = ad * f + bc
146
+ te[10] = ac - bd * f
147
+ elsif euler.order == 'XZY'
148
+ ac = a * c; ad = a * d; bc = b * c; bd = b * d
149
+ te[0] = c * e
150
+ te[4] = - f
151
+ te[8] = d * e
152
+ te[1] = ac * f + bd
153
+ te[5] = a * e
154
+ te[9] = ad * f - bc
155
+ te[2] = bc * f - ad
156
+ te[6] = b * e
157
+ te[10] = bd * f + ac
158
+ end
159
+ # last column
160
+ te[3] = 0.0
161
+ te[7] = 0.0
162
+ te[11] = 0.0
163
+ # bottom row
164
+ te[12] = 0.0
165
+ te[13] = 0.0
166
+ te[14] = 0.0
167
+ te[15] = 1.0
168
+ self
169
+ end
170
+
171
+ def make_rotation_from_quaternion(q)
172
+ te = self.elements
173
+ x, y, z, w = q.x, q.y, q.z, q.w
174
+ x2, y2, z2 = x + x, y + y, z + z
175
+ xx, xy, xz = x * x2, x * y2, x * z2
176
+ yy, yz, zz = y * y2, y * z2, z * z2
177
+ wx, wy, wz = w * x2, w * y2, w * z2
178
+ te[0] = 1.0 - (yy + zz)
179
+ te[4] = xy - wz
180
+ te[8] = xz + wy
181
+ te[1] = xy + wz
182
+ te[5] = 1.0 - (xx + zz)
183
+ te[9] = yz - wx
184
+ te[2] = xz - wy
185
+ te[6] = yz + wx
186
+ te[10] = 1.0 - (xx + yy)
187
+ # last column
188
+ te[3] = 0.0
189
+ te[7] = 0.0
190
+ te[11] = 0.0
191
+ # bottom row
192
+ te[12] = 0.0
193
+ te[13] = 0.0
194
+ te[14] = 0.0
195
+ te[15] = 1.0
196
+ self
197
+ end
198
+
199
+ def look_at(eye, target, up)
200
+ x = Mittsu::Vector3.new
201
+ y = Mittsu::Vector3.new
202
+ z = Mittsu::Vector3.new
203
+ te = self.elements
204
+ z.sub_vectors(eye, target).normalize
205
+ if z.length.zero?
206
+ z.z = 1.0
207
+ end
208
+ x.cross_vectors(up, z).normalize
209
+ if x.length.zero?
210
+ z.x += 0.0001
211
+ x.cross_vectors(up, z).normalize
212
+ end
213
+ y.cross_vectors(z, x)
214
+ te[0] = x.x; te[4] = y.x; te[8] = z.x
215
+ te[1] = x.y; te[5] = y.y; te[9] = z.y
216
+ te[2] = x.z; te[6] = y.z; te[10] = z.z
217
+ self
218
+ end
219
+
220
+ def multiply(m)
221
+ self.multiply_matrices(self, m)
222
+ end
223
+
224
+ def multiply_matrices(a, b)
225
+ ae = a.elements
226
+ be = b.elements
227
+ te = self.elements
228
+ a11 = ae[0]; a12 = ae[4]; a13 = ae[8]; a14 = ae[12]
229
+ a21 = ae[1]; a22 = ae[5]; a23 = ae[9]; a24 = ae[13]
230
+ a31 = ae[2]; a32 = ae[6]; a33 = ae[10]; a34 = ae[14]
231
+ a41 = ae[3]; a42 = ae[7]; a43 = ae[11]; a44 = ae[15]
232
+ b11 = be[0]; b12 = be[4]; b13 = be[8]; b14 = be[12]
233
+ b21 = be[1]; b22 = be[5]; b23 = be[9]; b24 = be[13]
234
+ b31 = be[2]; b32 = be[6]; b33 = be[10]; b34 = be[14]
235
+ b41 = be[3]; b42 = be[7]; b43 = be[11]; b44 = be[15]
236
+ te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41
237
+ te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42
238
+ te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43
239
+ te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44
240
+ te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41
241
+ te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42
242
+ te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43
243
+ te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44
244
+ te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41
245
+ te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42
246
+ te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43
247
+ te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44
248
+ te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41
249
+ te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42
250
+ te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43
251
+ te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44
252
+ self
253
+ end
254
+
255
+ def multiply_to_array(a, b, r)
256
+ te = self.elements
257
+ self.multiply_matrices(a, b)
258
+ r[0] = te[0]; r[1] = te[1]; r[2] = te[2]; r[3] = te[3]
259
+ r[4] = te[4]; r[5] = te[5]; r[6] = te[6]; r[7] = te[7]
260
+ r[8] = te[8]; r[9] = te[9]; r[10] = te[10]; r[11] = te[11]
261
+ r[12] = te[12]; r[13] = te[13]; r[14] = te[14]; r[15] = te[15]
262
+ self
263
+ end
264
+
265
+ def multiply_scalar(s)
266
+ te = self.elements
267
+ s = s.to_f
268
+ te[0] *= s; te[4] *= s; te[8] *= s; te[12] *= s
269
+ te[1] *= s; te[5] *= s; te[9] *= s; te[13] *= s
270
+ te[2] *= s; te[6] *= s; te[10] *= s; te[14] *= s
271
+ te[3] *= s; te[7] *= s; te[11] *= s; te[15] *= s
272
+ self
273
+ end
274
+
275
+ def apply_to_vector3_array(array, offset = 0, length = array.length)
276
+ v1 = Mittsu::Vector3.new
277
+ i = 0
278
+ j = offset
279
+ while i < length
280
+ v1.x = array[j].to_f
281
+ v1.y = array[j + 1].to_f
282
+ v1.z = array[j + 2].to_f
283
+ v1.apply_matrix4(self)
284
+ array[j] = v1.x
285
+ array[j + 1] = v1.y
286
+ array[j + 2] = v1.z
287
+ i += 3
288
+ j += 3
289
+ end
290
+ array
291
+ end
292
+
293
+ def determinant
294
+ te = self.elements
295
+ n11 = te[0]; n12 = te[4]; n13 = te[8]; n14 = te[12]
296
+ n21 = te[1]; n22 = te[5]; n23 = te[9]; n24 = te[13]
297
+ n31 = te[2]; n32 = te[6]; n33 = te[10]; n34 = te[14]
298
+ n41 = te[3]; n42 = te[7]; n43 = te[11]; n44 = te[15]
299
+ #TODO: make this more efficient
300
+ #(based on http:#www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm)
301
+ n41 * (n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34) +
302
+ n42 * (n11 * n23 * n34 - n11 * n24 * n33 + n14 * n21 * n33 - n13 * n21 * n34 + n13 * n24 * n31 - n14 * n23 * n31) +
303
+ n43 * (n11 * n24 * n32 - n11 * n22 * n34 - n14 * n21 * n32 + n12 * n21 * n34 + n14 * n22 * n31 - n12 * n24 * n31) +
304
+ n44 * (-n13 * n22 * n31 - n11 * n23 * n32 + n11 * n22 * n33 + n13 * n21 * n32 - n12 * n21 * n33 + n12 * n23 * n31)
305
+ end
306
+
307
+ def transpose
308
+ te = self.elements
309
+ tmp = te[1]; te[1] = te[4]; te[4] = tmp
310
+ tmp = te[2]; te[2] = te[8]; te[8] = tmp
311
+ tmp = te[6]; te[6] = te[9]; te[9] = tmp
312
+ tmp = te[3]; te[3] = te[12]; te[12] = tmp
313
+ tmp = te[7]; te[7] = te[13]; te[13] = tmp
314
+ tmp = te[11]; te[11] = te[14]; te[14] = tmp
315
+ self
316
+ end
317
+
318
+ def flatten_to_array_offset(array, offset)
319
+ te = self.elements
320
+ array[offset ] = te[0]
321
+ array[offset + 1] = te[1]
322
+ array[offset + 2] = te[2]
323
+ array[offset + 3] = te[3]
324
+ array[offset + 4] = te[4]
325
+ array[offset + 5] = te[5]
326
+ array[offset + 6] = te[6]
327
+ array[offset + 7] = te[7]
328
+ array[offset + 8] = te[8]
329
+ array[offset + 9] = te[9]
330
+ array[offset + 10] = te[10]
331
+ array[offset + 11] = te[11]
332
+ array[offset + 12] = te[12]
333
+ array[offset + 13] = te[13]
334
+ array[offset + 14] = te[14]
335
+ array[offset + 15] = te[15]
336
+ array
337
+ end
338
+
339
+ def set_position(v)
340
+ te = self.elements
341
+ te[12] = v.x
342
+ te[13] = v.y
343
+ te[14] = v.z
344
+ self
345
+ end
346
+
347
+ def inverse(m, throw_on_invertable = false)
348
+ # based on http:#www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
349
+ te = @elements
350
+ me = m.elements
351
+ n11 = me[0]; n12 = me[4]; n13 = me[8]; n14 = me[12]
352
+ n21 = me[1]; n22 = me[5]; n23 = me[9]; n24 = me[13]
353
+ n31 = me[2]; n32 = me[6]; n33 = me[10]; n34 = me[14]
354
+ n41 = me[3]; n42 = me[7]; n43 = me[11]; n44 = me[15]
355
+ te[0] = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44
356
+ te[4] = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44
357
+ te[8] = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44
358
+ te[12] = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34
359
+ te[1] = n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44
360
+ te[5] = n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44
361
+ te[9] = n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44
362
+ te[13] = n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34
363
+ te[2] = n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44
364
+ te[6] = n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44
365
+ te[10] = n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44
366
+ te[14] = n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34
367
+ te[3] = n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43
368
+ te[7] = n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43
369
+ te[11] = n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43
370
+ te[15] = n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33
371
+ det = n11 * te[0] + n21 * te[4] + n31 * te[8] + n41 * te[12]
372
+ if det.zero?
373
+ msg = "Mittsu::Matrix4#inverse: can't invert matrix, determinant is 0"
374
+ if throw_on_invertable
375
+ raise Error.new(msg)
376
+ else
377
+ # THREE.warn(msg)
378
+ puts "WARNING: #{msg}"
379
+ end
380
+ self.identity
381
+ return self
382
+ end
383
+ self.multiply_scalar(1.0 / det)
384
+ self
385
+ end
386
+
387
+ def scale(v)
388
+ te = self.elements
389
+ x = v.x; y = v.y; z = v.z
390
+ te[0] *= x; te[4] *= y; te[8] *= z
391
+ te[1] *= x; te[5] *= y; te[9] *= z
392
+ te[2] *= x; te[6] *= y; te[10] *= z
393
+ te[3] *= x; te[7] *= y; te[11] *= z
394
+ self
395
+ end
396
+
397
+ def max_scale_on_axis
398
+ te = self.elements
399
+ scale_x_sq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2]
400
+ scale_y_sq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6]
401
+ scale_z_sq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10]
402
+ Math.sqrt([scale_x_sq, scale_y_sq, scale_z_sq].max)
403
+ end
404
+
405
+ def make_translation(x, y, z)
406
+ self.set(
407
+ 1.0, 0.0, 0.0, x.to_f,
408
+ 0.0, 1.0, 0.0, y.to_f,
409
+ 0.0, 0.0, 1.0, z.to_f,
410
+ 0.0, 0.0, 0.0, 1.0
411
+ )
412
+ self
413
+ end
414
+
415
+ def make_rotation_x(theta)
416
+ c, s = Math.cos(theta), Math.sin(theta)
417
+ self.set(
418
+ 1.0, 0.0, 0.0, 0.0,
419
+ 0.0, c, -s, 0.0,
420
+ 0.0, s, c, 0.0,
421
+ 0.0, 0.0, 0.0, 1.0
422
+ )
423
+ self
424
+ end
425
+
426
+ def make_rotation_y(theta)
427
+ c, s = Math.cos(theta), Math.sin(theta)
428
+ self.set(
429
+ c, 0.0, s, 0.0,
430
+ 0.0, 1.0, 0.0, 0.0,
431
+ -s, 0.0, c, 0.0,
432
+ 0.0, 0.0, 0.0, 1.0
433
+ )
434
+ self
435
+ end
436
+
437
+ def make_rotation_z(theta)
438
+ c, s = Math.cos(theta), Math.sin(theta)
439
+ self.set(
440
+ c, -s, 0.0, 0.0,
441
+ s, c, 0.0, 0.0,
442
+ 0.0, 0.0, 1.0, 0.0,
443
+ 0.0, 0.0, 0.0, 1.0
444
+ )
445
+ self
446
+ end
447
+
448
+ def make_rotation_axis(axis, angle)
449
+ # Based on http:#www.gamedev.net/reference/articles/article1199.asp
450
+ c = Math.cos(angle)
451
+ s = Math.sin(angle)
452
+ t = 1.0 - c
453
+ x, y, z = axis.x, axis.y, axis.z
454
+ tx, ty = t * x, t * y
455
+ self.set(
456
+ tx * x + c, tx * y - s * z, tx * z + s * y, 0.0,
457
+ tx * y + s * z, ty * y + c, ty * z - s * x, 0.0,
458
+ tx * z - s * y, ty * z + s * x, t * z * z + c, 0.0,
459
+ 0.0, 0.0, 0.0, 1.0
460
+ )
461
+ self
462
+ end
463
+
464
+ def make_scale(x, y, z)
465
+ self.set(
466
+ x.to_f, 0.0, 0.0, 0.0,
467
+ 0.0, y.to_f, 0.0, 0.0,
468
+ 0.0, 0.0, z.to_f, 0.0,
469
+ 0.0, 0.0, 0.0, 1.0
470
+ )
471
+ self
472
+ end
473
+
474
+ def compose(position, quaternion, scale)
475
+ self.make_rotation_from_quaternion(quaternion)
476
+ self.scale(scale)
477
+ self.set_position(position)
478
+ self
479
+ end
480
+
481
+ def decompose(position, quaternion, scale)
482
+ vector = Mittsu::Vector3.new
483
+ matrix = Mittsu::Matrix4.new
484
+ te = self.elements
485
+ sx = vector.set(te[0], te[1], te[2]).length
486
+ sy = vector.set(te[4], te[5], te[6]).length
487
+ sz = vector.set(te[8], te[9], te[10]).length
488
+ # if determine is negative, we need to invert one scale
489
+ det = self.determinant
490
+ if det < 0.0
491
+ sx = -sx
492
+ end
493
+ position.x = te[12]
494
+ position.y = te[13]
495
+ position.z = te[14]
496
+ # scale the rotation part
497
+ matrix.elements[0...15] = self.elements # at this point matrix is incomplete so we can't use .copy
498
+ inv_sx = 1.0 / sx
499
+ inv_sy = 1.0 / sy
500
+ inv_sz = 1.0 / sz
501
+ matrix.elements[0] *= inv_sx
502
+ matrix.elements[1] *= inv_sx
503
+ matrix.elements[2] *= inv_sx
504
+ matrix.elements[4] *= inv_sy
505
+ matrix.elements[5] *= inv_sy
506
+ matrix.elements[6] *= inv_sy
507
+ matrix.elements[8] *= inv_sz
508
+ matrix.elements[9] *= inv_sz
509
+ matrix.elements[10] *= inv_sz
510
+ quaternion.set_from_rotation_matrix(matrix)
511
+ scale.x = sx
512
+ scale.y = sy
513
+ scale.z = sz
514
+ self
515
+ end
516
+
517
+ def make_frustum(left, right, bottom, top, near, far)
518
+ left, right, bottom, top, near, far =
519
+ left.to_f, right.to_f, bottom.to_f, top.to_f, near.to_f, far.to_f
520
+ te = self.elements
521
+ x = 2.0 * near / (right - left)
522
+ y = 2.0 * near / (top - bottom)
523
+ a = (right + left) / (right - left)
524
+ b = (top + bottom) / (top - bottom)
525
+ c = -(far + near) / (far - near)
526
+ d = -2.0 * far * near / (far - near)
527
+ te[0] = x; te[4] = 0.0; te[8] = a; te[12] = 0.0
528
+ te[1] = 0.0; te[5] = y; te[9] = b; te[13] = 0.0
529
+ te[2] = 0.0; te[6] = 0.0; te[10] = c; te[14] = d
530
+ te[3] = 0.0; te[7] = 0.0; te[11] = -1.0; te[15] = 0.0
531
+ self
532
+ end
533
+
534
+ def make_perspective(fov, aspect, near, far)
535
+ fov, aspect, near, far =
536
+ fov.to_f, aspect.to_f, near.to_f, far.to_f
537
+ ymax = near * Math.tan(Math.deg_to_rad(fov * 0.5))
538
+ ymin = -ymax
539
+ xmin = ymin * aspect
540
+ xmax = ymax * aspect
541
+ self.make_frustum(xmin, xmax, ymin, ymax, near, far)
542
+ end
543
+
544
+ def make_orthographic(left, right, top, bottom, near, far)
545
+ left, right, top, bottom, near, far =
546
+ left.to_f, right.to_f, top.to_f, bottom.to_f, near.to_f, far.to_f
547
+ te = self.elements
548
+ w = right - left
549
+ h = top - bottom
550
+ p = far - near
551
+ x = (right + left) / w
552
+ y = (top + bottom) / h
553
+ z = (far + near) / p
554
+ te[0] = 2.0 / w; te[4] = 0.0; te[8] = 0.0; te[12] = -x
555
+ te[1] = 0.0; te[5] = 2.0 / h; te[9] = 0.0; te[13] = -y
556
+ te[2] = 0.0; te[6] = 0.0; te[10] = -2.0 / p; te[14] = -z
557
+ te[3] = 0.0; te[7] = 0.0; te[11] = 0.0; te[15] = 1.0
558
+ self
559
+ end
560
+
561
+ def from_array(array)
562
+ self.elements[0..array.length] = array
563
+ self
564
+ end
565
+
566
+ def to_a
567
+ te = self.elements
568
+ [
569
+ te[0], te[1], te[2], te[3],
570
+ te[4], te[5], te[6], te[7],
571
+ te[8], te[9], te[10], te[11],
572
+ te[12], te[13], te[14], te[15]
573
+ ]
574
+ end
575
+
576
+ def clone
577
+ Mittsu::Matrix4.new.from_array(self.elements)
578
+ end
579
+
580
+ end
581
+ end