mittsu 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,36 @@
1
+ module Mittsu
2
+ class HashArray
3
+ include Enumerable
4
+
5
+ def initialize()
6
+ @array = []
7
+ @hash = {}
8
+ end
9
+
10
+ def [](key)
11
+ if key.is_a? Fixnum
12
+ @array[key]
13
+ else
14
+ @hash[key]
15
+ end
16
+ end
17
+
18
+ def []=(key, value)
19
+ if key.is_a? Fixnum
20
+ @array[key] = value
21
+ else
22
+ @hash[key] = value
23
+ end
24
+ end
25
+
26
+ def each(&block)
27
+ @array.each(&block)
28
+ end
29
+
30
+ def length
31
+ @array.length
32
+ end
33
+ alias_method :count, :length
34
+ alias_method :size, :length
35
+ end
36
+ end
@@ -0,0 +1,19 @@
1
+ module Mittsu
2
+ class HashObject
3
+ def initialize
4
+ @_hash = {}
5
+ end
6
+
7
+ def [](key)
8
+ @_hash[key]
9
+ end
10
+
11
+ def []=(key, value)
12
+ @_hash[key] = value
13
+ end
14
+
15
+ def delete(key)
16
+ @_hash.delete(key)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,421 @@
1
+ require 'securerandom'
2
+ require 'mittsu'
3
+ require 'mittsu/core/hash_object'
4
+
5
+ module Mittsu
6
+ class Object3D < HashObject
7
+ include EventDispatcher
8
+
9
+ attr_accessor :name, :children, :up, :position, :rotation, :quaternion, :scale, :rotation_auto_update, :matrix, :matrix_world, :matrix_auto_update, :matrix_world_needs_update, :visible, :cast_shadow, :receive_shadow, :frustum_culled, :render_order, :user_data, :parent, :geometry
10
+
11
+ attr_reader :id, :uuid, :type
12
+
13
+ DefaultUp = Vector3.new(0.0, 1.0, 0.0)
14
+
15
+ def initialize
16
+ super
17
+ @id = (@@id ||= 1).tap { @@id += 1 }
18
+
19
+ @uuid = SecureRandom.uuid
20
+
21
+ @name = ''
22
+ @type = 'Object3D'
23
+
24
+ @children = []
25
+
26
+ @up = DefaultUp.clone
27
+
28
+ @position = Vector3.new
29
+ @rotation = Euler.new
30
+ @quaternion = Quaternion.new
31
+ @scale = Vector3.new(1.0, 1.0, 1.0)
32
+
33
+ @rotation.on_change do
34
+ @quaternion.set_from_euler(rotation, false)
35
+ end
36
+
37
+ @quaternion.on_change do
38
+ @rotation.set_from_quaternion(quaternion, false)
39
+ end
40
+
41
+ @rotation_auto_update = true
42
+
43
+ @matrix = Matrix4.new
44
+ @matrix_world = Matrix4.new
45
+
46
+ @matrix_auto_update = true
47
+ @matrix_world_needs_update = false
48
+
49
+ @visible = true
50
+
51
+ @cast_shadow = false
52
+ @receive_shadow = false
53
+
54
+ @frustum_culled = true
55
+ @render_order = 0
56
+
57
+ @user_data = {}
58
+ end
59
+
60
+ def apply_matrix(matrix)
61
+ @matrix.multiply_matrices(matrix, @matrix)
62
+ @matrix.decompose(@position, @quaternion, @scale)
63
+ end
64
+
65
+ def set_rotation_from_axis_angle(axis, angle)
66
+ # assumes axis is normalized
67
+ @quaternion.set_from_axis_angle(axis, angle)
68
+ end
69
+
70
+ def set_rotation_from_euler(euler)
71
+ @quaternion.set_from_euler(euler, true)
72
+ end
73
+
74
+ def set_rotation_from_matrix(m)
75
+ # assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
76
+ @quaternion.set_from_rotation_matrix(m)
77
+ end
78
+
79
+ def set_rotation_from_quaternion(q)
80
+ # assumes q is normalized
81
+ @quaternion.copy(q)
82
+ end
83
+
84
+ def rotate_on_axis(axis, angle)
85
+ # rotate object on axis in object space
86
+ # axis is assumed to be normalized
87
+ @_q1 ||= Quaternion.new
88
+ @_q1.set_from_axis_angle(axis, angle)
89
+ @quaternion.multiply(@_q1)
90
+ self
91
+ end
92
+
93
+ def rotate_x(angle)
94
+ @_v1 ||= Vector3.new(1, 0, 0)
95
+ self.rotate_on_axis(@_v1, angle)
96
+ end
97
+
98
+ def rotate_y(angle)
99
+ @_v1 ||= Vector3.new(0, 1, 0)
100
+ self.rotate_on_axis(@_v1, angle)
101
+ end
102
+
103
+ def rotate_z(angle)
104
+ @_v1 ||= Vector3.new(0, 0, 1)
105
+ self.rotate_on_axis(@_v1, angle)
106
+ end
107
+
108
+ def translate_on_axis(axis, distance)
109
+ # translate object by distance along axis in object space
110
+ # axis is assumed to be normalized
111
+ @_v1 ||= Vector3.new
112
+ @_v1.copy(axis).apply_quaternion(@quaternion)
113
+ @position.add(@_v1.multiply_scalar(distance))
114
+ self
115
+ end
116
+
117
+ def translate_x(distance)
118
+ @_x_axis ||= Vector3.new(1, 0, 0)
119
+ self.translate_on_axis(@_x_axis, distance)
120
+ end
121
+
122
+ def translate_y(distance)
123
+ @_y_axis ||= Vector3.new(0, 1, 0)
124
+ self.translate_on_axis(@_y_axis, distance)
125
+ end
126
+
127
+ def translate_z(distance)
128
+ @_z_axis ||= Vector3.new(0, 0, 1)
129
+ self.translate_on_axis(@_z_axis, distance)
130
+ end
131
+
132
+ def local_to_world(vector)
133
+ vector.apply_matrix4(@matrix_world)
134
+ end
135
+
136
+ def world_to_local(vector)
137
+ @_m1 ||= Matrix4.new
138
+ vector.apply_matrix4(@_m1.get_inverse(@matrix_world))
139
+ end
140
+
141
+ def look_at(vector)
142
+ # This routine does not support objects with rotated and/or translated parent(s)
143
+ @_m1 ||= Matrix4.new
144
+ @_m1.look_at(vector, @position, self.up)
145
+ @quaternion.set_from_rotation_matrix(@_m1)
146
+ end
147
+
148
+ def add(*arguments)
149
+ if arguments.length > 1
150
+ arguments.each do |arg|
151
+ self.add(arg)
152
+ end
153
+ return self
154
+ end
155
+ object = arguments.first
156
+ if object == self
157
+ puts("ERROR: Mittsu::Object3D#add: object can't be added as a child of itself.", object.inspect)
158
+ return self
159
+ end
160
+ if object.is_a? Object3D
161
+ object.parent.remove(object) unless object.parent.nil?
162
+ object.parent = self
163
+ object.dispatch_event type: :added
164
+ @children << object
165
+ else
166
+ puts('ERROR: Mittsu::Object3D#add: object not an instance of Object3D.', object.inspect)
167
+ end
168
+ self
169
+ end
170
+
171
+ def remove(*arguments)
172
+ if arguments.length > 1
173
+ arguments.each do |arg|
174
+ self.remove(arg)
175
+ end
176
+ return
177
+ end
178
+ object = arguments.first
179
+ index = @children.index(object)
180
+ if index
181
+ object.parent = nil
182
+ object.dispatch_event type: :removed
183
+ @children.delete_at index
184
+ end
185
+ nil
186
+ end
187
+
188
+ def get_object_by_id(id)
189
+ self.get_object_by_property(:id, id)
190
+ end
191
+
192
+ def get_object_by_name(name)
193
+ self.get_object_by_property(:name, name)
194
+ end
195
+
196
+ def get_object_by_property(name, value)
197
+ return self if self.send(name) == value
198
+ @children.each do |child|
199
+ object = child.get_object_by_property(name, value)
200
+ return object unless object.nil?
201
+ end
202
+ nil
203
+ end
204
+
205
+ def get_world_position(target = Vector3.new)
206
+ self.update_matrix_world(true)
207
+ target.set_from_matrix_position(@matrix_world)
208
+ end
209
+
210
+ def get_world_quaternion(target = Quaternion.new)
211
+ @_position ||= Vector3.new
212
+ @_scale ||= Vector3.new
213
+ self.update_matrix_world(true)
214
+ @matrix_world.decompose(@_position, target, @_scale)
215
+ target
216
+ end
217
+
218
+ def get_world_rotation(target = Euler.new)
219
+ @_quaternion ||= Quaternion.new
220
+ self.get_world_quaternion(quaternion)
221
+ target.set_from_quaternion(quaternion, @rotation.order, false)
222
+ end
223
+
224
+ def get_world_scale(target = Vector3.new)
225
+ @_position ||= Vector3.new
226
+ @_quaternion ||= Quaternion.new
227
+ self.update_matrix_world(true)
228
+ @matrix_world.decompose(@_position, @_quaternion, target)
229
+ target
230
+ end
231
+
232
+ def get_world_direction(target = Vector3.new)
233
+ @_quaternion ||= Quaternion.new
234
+ self.get_world_quaternion(@_quaternion)
235
+ target.set(0.0, 0.0, 1.0).apply_quaternion(@_quaternion)
236
+ end
237
+
238
+ def raycast; end
239
+
240
+ def traverse(&callback)
241
+ callback.yield self
242
+ @children.each do |child|
243
+ child.traverse(&callback)
244
+ end
245
+ end
246
+
247
+ def print_tree(lines=[])
248
+ if lines.empty?
249
+ puts self
250
+ else
251
+ last = !lines.last
252
+ indent = lines[0..-2].map{|l| l ? '┃ ' : ' '}.join
253
+ puts "#{indent}#{last ? '┗' : '┣'}╸#{self}"
254
+ end
255
+ @children.each do |child|
256
+ child.print_tree(lines + [child != @children.last])
257
+ end
258
+ end
259
+
260
+ def to_s
261
+ "#{type} (#{name}) #{position}"
262
+ end
263
+
264
+ def traverse_visible(&callback)
265
+ return unless @visible
266
+ callback.yield self
267
+ @children.each do |child|
268
+ child.traverse_visible(&callback)
269
+ end
270
+ end
271
+
272
+ def traverse_ancestors(&callback)
273
+ if @parent
274
+ callback.yielf @parent
275
+ @parent.traverse_ancestors(&callback)
276
+ end
277
+ end
278
+
279
+ def update_matrix
280
+ @matrix.compose(@position, @quaternion, @scale)
281
+ @matrix_world_needs_update = true
282
+ end
283
+
284
+ def update_matrix_world(force = false)
285
+ self.update_matrix if @matrix_auto_update
286
+ if @matrix_world_needs_update || force
287
+ if @parent.nil?
288
+ @matrix_world.copy(@matrix)
289
+ else
290
+ @matrix_world.multiply_matrices(@parent.matrix_world, @matrix)
291
+ end
292
+ @matrix_world_needs_update = false
293
+ force = true
294
+ end
295
+ # update children
296
+ @children.each do |child|
297
+ child.update_matrix_world(force)
298
+ end
299
+ end
300
+
301
+ def to_json
302
+ @_output = {
303
+ metadata: {
304
+ version: 4.3,
305
+ type: 'Object',
306
+ generator: 'ObjectExporter'
307
+ }
308
+ }
309
+ @_geometries = {}
310
+ @_materials = {}
311
+ @_output[:object] = parse_object(self)
312
+ @_output
313
+ end
314
+
315
+ def clone(object = Object3D.new, recursive = true)
316
+ object.name = @name
317
+ object.up.copy(@up)
318
+ object.position.copy(@position)
319
+ object.quaternion.copy(@quaternion)
320
+ object.scale.copy(@scale)
321
+ object.rotation_auto_update = @rotation_auto_update
322
+ object.matrix.copy(@matrix)
323
+ object.matrix_world.copy(@matrix_world)
324
+ object.matrix_auto_update = @matrix_auto_update
325
+ object.matrix_world_needs_update = @matrix_world_needs_update
326
+ object.visible = @visible
327
+ object.cast_shadow = @cast_shadow
328
+ object.receive_shadow = @receive_shadow
329
+ object.frustum_culled = @frustum_culled
330
+ object.user_data = @user_data
331
+ if recursive
332
+ @children.each do |child|
333
+ object.add(child.clone)
334
+ end
335
+ end
336
+ object
337
+ end
338
+
339
+ private
340
+
341
+ def parse_geometry(geometry)
342
+ @_output[:geometries] ||= []
343
+ if @_geometries[geometry.uuid].nil?
344
+ json = geometry.to_json
345
+ json.delete :metadata
346
+ @_geometries[geometry.uuid] = json
347
+ @_output[:geometries] << json
348
+ end
349
+ geometry.uuid
350
+ end
351
+
352
+ def parse_material(material)
353
+ @_output[:materials] ||= []
354
+ if @_materials[material.uuid].nil?
355
+ json = material.to_json
356
+ json.delete :metadata
357
+ @_materials[material.uuid] = json
358
+ @_output[:materials] << json
359
+ end
360
+ material.uuid
361
+ end
362
+
363
+ def parse_object(object)
364
+ data = {}
365
+ data[:uuid] = object.uuid
366
+ data[:type] = object.type
367
+ data[:name] = object.name unless object.name.nil? || object.name.empty?
368
+ data.user_data = object.user_data unless object.user_data.nil? || object.user_data.empty?
369
+ data[:visible] = object.visible unless object.visible
370
+
371
+ case object
372
+ when PerspectiveCamera
373
+ data[:fov] = object.fov
374
+ data[:aspect] = object.aspect
375
+ data[:near] = object.near
376
+ data[:far] = object.far
377
+ when OrthographicCamera
378
+ data[:left] = object.left
379
+ data[:right] = object.right
380
+ data[:top] = object.top
381
+ data[:bottom] = object.bottom
382
+ data[:near] = object.near
383
+ data[:far] = object.far
384
+ when AmbientLight
385
+ data[:color] = object.color.get_hex
386
+ when DirectionalLight
387
+ data[:color] = object.color.get_hex
388
+ data[:intensity] = object.intensity
389
+ when PointLight
390
+ data[:color] = object.color.get_hex
391
+ data[:intensity] = object.intensity
392
+ data[:distance] = object.distance
393
+ data[:decay] = object.decay
394
+ when SpotLight
395
+ data[:color] = object.color.get_hex
396
+ data[:intensity] = object.intensity
397
+ data[:distance] = object.distance
398
+ data[:angle] = object.angle
399
+ data[:exponent] = object.exponent
400
+ data[:decay] = object.decay
401
+ when HemisphereLight
402
+ data[:color] = object.color.get_hex
403
+ data[:ground_color] = object.ground_color.get_hex
404
+ when Mesh, Line, PointCloud
405
+ data[:geometry] = parse_geometry(object.geometry)
406
+ data[:material] = parse_material(object.material)
407
+ data[:mode] = object.mode if object.is_a? Line
408
+ when Sprite
409
+ data[:material] = parse_material(object.material)
410
+ end
411
+ data[:matrix] = object.matrix.to_a
412
+ if !object.children.length.empty?
413
+ data[:children] = []
414
+ object.children.each do |child|
415
+ data[:children] << parse_object(child)
416
+ end
417
+ end
418
+ data
419
+ end
420
+ end
421
+ end