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,414 @@
1
+ require 'mittsu/math'
2
+
3
+ module Mittsu
4
+ class Vector4
5
+ attr_accessor :x, :y, :z, :w
6
+ def initialize(x = 0.0, y = 0.0, z = 0.0, w = 1.0)
7
+ self.set(x, y, z, w)
8
+ end
9
+
10
+ def set(x, y, z, w)
11
+ @x, @y, @z, @w = x.to_f, y.to_f, z.to_f, w.to_f
12
+ self
13
+ end
14
+
15
+ def set_x(x)
16
+ @x = x.to_f
17
+ self
18
+ end
19
+
20
+ def set_y(y)
21
+ @y = y.to_f
22
+ self
23
+ end
24
+
25
+ def set_z(z)
26
+ @z = z.to_f
27
+ self
28
+ end
29
+
30
+ def set_w(w)
31
+ @w = w.to_f
32
+ self
33
+ end
34
+
35
+ def set_component(index, value)
36
+ case index
37
+ when 0 then @x = value.to_f
38
+ when 1 then @y = value.to_f
39
+ when 2 then @z = value.to_f
40
+ when 3 then @w = value.to_f
41
+ else raise IndexError.new
42
+ end
43
+ end
44
+
45
+ def get_component(index)
46
+ case index
47
+ when 0 then return @x
48
+ when 1 then return @y
49
+ when 2 then return @z
50
+ when 3 then return @w
51
+ else raise IndexError.new
52
+ end
53
+ end
54
+
55
+ def copy(v)
56
+ @x = v.x
57
+ @y = v.y
58
+ @z = v.z
59
+ @w = v.w || 1.0
60
+ self
61
+ end
62
+
63
+ def add(v)
64
+ @x += v.x
65
+ @y += v.y
66
+ @z += v.z
67
+ @w += v.w
68
+ self
69
+ end
70
+
71
+ def add_scalar(s)
72
+ @x += s
73
+ @y += s
74
+ @z += s
75
+ @w += s
76
+ self
77
+ end
78
+
79
+ def add_vectors(a, b)
80
+ @x = a.x + b.x
81
+ @y = a.y + b.y
82
+ @z = a.z + b.z
83
+ @w = a.w + b.w
84
+ self
85
+ end
86
+
87
+ def sub(v)
88
+ @x -= v.x
89
+ @y -= v.y
90
+ @z -= v.z
91
+ @w -= v.w
92
+ self
93
+ end
94
+
95
+ def sub_scalar(s)
96
+ @x -= s
97
+ @y -= s
98
+ @z -= s
99
+ @w -= s
100
+ self
101
+ end
102
+
103
+ def sub_vectors(a, b)
104
+ @x = a.x - b.x
105
+ @y = a.y - b.y
106
+ @z = a.z - b.z
107
+ @w = a.w - b.w
108
+ self
109
+ end
110
+
111
+ def multiply_scalar(scalar)
112
+ @x *= scalar
113
+ @y *= scalar
114
+ @z *= scalar
115
+ @w *= scalar
116
+ self
117
+ end
118
+
119
+ def apply_matrix4(m)
120
+ x1, y1, z1, w1 = @x, @y, @z, @w
121
+ e = m.elements
122
+ @x = e[0] * x1 + e[4] * y1 + e[8] * z1 + e[12] * w1
123
+ @y = e[1] * x1 + e[5] * y1 + e[9] * z1 + e[13] * w1
124
+ @z = e[2] * x1 + e[6] * y1 + e[10] * z1 + e[14] * w1
125
+ @w = e[3] * x1 + e[7] * y1 + e[11] * z1 + e[15] * w1
126
+ self
127
+ end
128
+
129
+ def divide_scalar(scalar)
130
+ if scalar != 0.0
131
+ inv_scalar = 1.0 / scalar
132
+ @x *= inv_scalar
133
+ @y *= inv_scalar
134
+ @z *= inv_scalar
135
+ @w *= inv_scalar
136
+ else
137
+ @x, @y, @z, @w = 0.0, 0.0, 0.0, 1.0
138
+ end
139
+ self
140
+ end
141
+
142
+ def set_axis_angle_from_quaternion(q)
143
+ # http:#www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
144
+ # q is assumed to be normalized
145
+ @w = 2.0 * Math.acos(q.w)
146
+ s = Math.sqrt(1.0 - q.w * q.w)
147
+ if s < 0.0001
148
+ @x = 1.0
149
+ @y = 0.0
150
+ @z = 0.0
151
+ else
152
+ @x = q.x / s
153
+ @y = q.y / s
154
+ @z = q.z / s
155
+ end
156
+ self
157
+ end
158
+
159
+ def set_axis_angle_from_rotation_matrix(m)
160
+ # http:#www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
161
+ # assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
162
+ angle, x1, y1, z1 = nil # variables for result
163
+ epsilon = 0.01 # margin to allow for rounding errors
164
+ epsilon2 = 0.1 # margin to distinguish between 0 and 180 degrees
165
+ te = m.elements
166
+ m11, m12, m13 = te[0], te[4], te[8]
167
+ m21, m22, m23 = te[1], te[5], te[9]
168
+ m31, m32, m33 = te[2], te[6], te[10]
169
+ if (((m12 - m21).abs < epsilon) &&
170
+ ((m13 - m31).abs < epsilon) &&
171
+ ((m23 - m32).abs < epsilon))
172
+ # singularity found
173
+ # first check for identity matrix which must have +1 for all terms
174
+ # in leading diagonal and zero in other terms
175
+ if (((m12 + m21).abs < epsilon2) &&
176
+ ((m13 + m31).abs < epsilon2) &&
177
+ ((m23 + m32).abs < epsilon2) &&
178
+ ((m11 + m22 + m33 - 3).abs < epsilon2))
179
+ # self singularity is identity matrix so angle = 0
180
+ self.set(1, 0, 0, 0)
181
+ return self # zero angle, arbitrary axis
182
+ end
183
+ # otherwise self singularity is angle = 180
184
+ angle = Math::PI
185
+ xx = (m11 + 1.0) / 2.0
186
+ yy = (m22 + 1.0) / 2.0
187
+ zz = (m33 + 1.0) / 2.0
188
+ xy = (m12 + m21) / 4.0
189
+ xz = (m13 + m31) / 4.0
190
+ yz = (m23 + m32) / 4.0
191
+ if (xx > yy) && (xx > zz) # m11 is the largest diagonal term
192
+ if xx < epsilon
193
+ x1 = 0.0
194
+ y1 = 0.707106781
195
+ z1 = 0.707106781
196
+ else
197
+ x1 = Math.sqrt(xx)
198
+ y1 = xy / x1
199
+ z1 = xz / x1
200
+ end
201
+ elsif yy > zz # m22 is the largest diagonal term
202
+ if yy < epsilon
203
+ x1 = 0.707106781
204
+ y1 = 0.0
205
+ z1 = 0.707106781
206
+ else
207
+ y1 = Math.sqrt(yy)
208
+ x1 = xy / y1
209
+ z1 = yz / y1
210
+ end
211
+ else # m33 is the largest diagonal term so base result on self
212
+ if zz < epsilon
213
+ x1 = 0.707106781
214
+ y1 = 0.707106781
215
+ z1 = 0.0
216
+ else
217
+ z1 = Math.sqrt(zz)
218
+ x1 = xz / z1
219
+ y1 = yz / z1
220
+ end
221
+ end
222
+ self.set(x1, y1, z1, angle)
223
+ return self # return 180 deg rotation
224
+ end
225
+ # as we have reached here there are no singularities so we can handle normally
226
+ s = Math.sqrt((m32 - m23) * (m32 - m23) +
227
+ (m13 - m31) * (m13 - m31) +
228
+ (m21 - m12) * (m21 - m12)) # used to normalize
229
+ s = 1.0 if (s.abs < 0.001)
230
+ # prevent divide by zero, should not happen if matrix is orthogonal and should be
231
+ # caught by singularity test above, but I've left it in just in case
232
+ @x = (m32 - m23) / s
233
+ @y = (m13 - m31) / s
234
+ @z = (m21 - m12) / s
235
+ @w = Math.acos((m11 + m22 + m33 - 1.0) / 2.0)
236
+ self
237
+ end
238
+
239
+ def min(v)
240
+ if @x > v.x
241
+ @x = v.x
242
+ end
243
+ if @y > v.y
244
+ @y = v.y
245
+ end
246
+ if @z > v.z
247
+ @z = v.z
248
+ end
249
+ if @w > v.w
250
+ @w = v.w
251
+ end
252
+ self
253
+ end
254
+
255
+ def max(v)
256
+ if @x < v.x
257
+ @x = v.x
258
+ end
259
+ if @y < v.y
260
+ @y = v.y
261
+ end
262
+ if @z < v.z
263
+ @z = v.z
264
+ end
265
+ if @w < v.w
266
+ @w = v.w
267
+ end
268
+ self
269
+ end
270
+
271
+ def clamp(min, max)
272
+ # This function assumes min < max, if self assumption isn't true it will not operate correctly
273
+ if @x < min.x
274
+ @x = min.x
275
+ elsif @x > max.x
276
+ @x = max.x
277
+ end
278
+ if @y < min.y
279
+ @y = min.y
280
+ elsif @y > max.y
281
+ @y = max.y
282
+ end
283
+ if @z < min.z
284
+ @z = min.z
285
+ elsif @z > max.z
286
+ @z = max.z
287
+ end
288
+ if @w < min.w
289
+ @w = min.w
290
+ elsif @w > max.w
291
+ @w = max.w
292
+ end
293
+ self
294
+ end
295
+
296
+ def floor
297
+ @x = (@x).floor
298
+ @y = (@y).floor
299
+ @z = (@z).floor
300
+ @w = (@w).floor
301
+ self
302
+ end
303
+
304
+ def ceil
305
+ @x = (@x).ceil
306
+ @y = (@y).ceil
307
+ @z = (@z).ceil
308
+ @w = (@w).ceil
309
+ self
310
+ end
311
+
312
+ def round
313
+ @x = (@x).round
314
+ @y = (@y).round
315
+ @z = (@z).round
316
+ @w = (@w).round
317
+ self
318
+ end
319
+
320
+ def round_to_zero
321
+ @x = (@x < 0) ? (@x).ceil : (@x).floor
322
+ @y = (@y < 0) ? (@y).ceil : (@y).floor
323
+ @z = (@z < 0) ? (@z).ceil : (@z).floor
324
+ @w = (@w < 0) ? (@w).ceil : (@w).floor
325
+ self
326
+ end
327
+
328
+ def negate
329
+ @x = - @x
330
+ @y = - @y
331
+ @z = - @z
332
+ @w = - @w
333
+ self
334
+ end
335
+
336
+ def dot(v)
337
+ @x * v.x + @y * v.y + @z * v.z + @w * v.w
338
+ end
339
+
340
+ def length_sq
341
+ @x * @x + @y * @y + @z * @z + @w * @w
342
+ end
343
+
344
+ def length
345
+ Math.sqrt(@x * @x + @y * @y + @z * @z + @w * @w)
346
+ end
347
+
348
+ def length_manhattan
349
+ (@x).abs + (@y).abs + (@z).abs + (@w).abs
350
+ end
351
+
352
+ def normalize
353
+ self.divide_scalar(self.length)
354
+ end
355
+
356
+ def set_length(l)
357
+ old_length = self.length
358
+ if old_length != 0 && l != old_length
359
+ self.multiply_scalar(l / old_length)
360
+ end
361
+ self
362
+ end
363
+
364
+ def lerp(v, alpha)
365
+ @x += (v.x - @x) * alpha
366
+ @y += (v.y - @y) * alpha
367
+ @z += (v.z - @z) * alpha
368
+ @w += (v.w - @w) * alpha
369
+ self
370
+ end
371
+
372
+ def lerp_vectors(v1, v2, alpha)
373
+ self.sub_vectors(v2, v1).multiply_scalar(alpha).add(v1)
374
+ self
375
+ end
376
+
377
+ def ==(v)
378
+ ((v.x == @x) && (v.y == @y) && (v.z == @z) && (v.w == @w))
379
+ end
380
+
381
+ def from_array(array, offset = 0)
382
+ @x = array[offset]
383
+ @y = array[offset + 1]
384
+ @z = array[offset + 2]
385
+ @w = array[offset + 3]
386
+ self
387
+ end
388
+
389
+ def to_array(array = [], offset = 0)
390
+ array[offset] = @x
391
+ array[offset + 1] = @y
392
+ array[offset + 2] = @z
393
+ array[offset + 3] = @w
394
+ array
395
+ end
396
+
397
+ def from_attribute(attribute, index, offset = 0)
398
+ index = index * attribute.itemSize + offset
399
+ @x = attribute.array[index]
400
+ @y = attribute.array[index + 1]
401
+ @z = attribute.array[index + 2]
402
+ @w = attribute.array[index + 3]
403
+ self
404
+ end
405
+
406
+ def clone
407
+ Mittsu::Vector4.new @x, @y, @z, @w
408
+ end
409
+
410
+ def to_s
411
+ "[#{x}, #{y}, #{z}, #{w}]"
412
+ end
413
+ end
414
+ end
@@ -0,0 +1,3 @@
1
+ require 'mittsu/objects/mesh'
2
+ require 'mittsu/objects/line'
3
+ require 'mittsu/objects/group'
@@ -0,0 +1,8 @@
1
+ module Mittsu
2
+ class Group < Object3D
3
+ def initialize
4
+ super
5
+ @type = 'Group'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,143 @@
1
+ module Mittsu
2
+ class Line < Object3D
3
+ attr_accessor :geometry, :material, :mode, :type
4
+
5
+ def initialize(geometry = nil, material = nil, mode = nil)
6
+ super()
7
+
8
+ @type = 'Line'
9
+
10
+ @geometry = geometry || Geometry.new
11
+ @material = material || LineBasicMaterial.new(color: rand * 0xffffff)
12
+
13
+ @mode = mode || LineStrip
14
+
15
+ @_inverse_matrix = Matrix4.new
16
+ @_ray = Ray.new
17
+ @_sphere = Sphere.new
18
+ end
19
+
20
+ def raycast(raycaster, intersects)
21
+ precision = raycaster.line_precision
22
+ precision_sq = precision * precision
23
+
24
+ @geometry.compute_bounding_sphere if @geometry.bounding_sphere.nil?
25
+
26
+ # Checking bounding_sphere distance to ray
27
+
28
+ @_sphere.copy(geometry.bounding_sphere)
29
+ @_sphere.apply_matrix4(@matrix_world)
30
+
31
+ return unless raycaster.ray.intersetion_sphere?(sphere)
32
+
33
+ @_inverse_matrix.get_inverse(@matrix_world)
34
+ @_ray.copy(raycaster.ray).apply_matrix4(@_inverse_matrix)
35
+
36
+ v_start = Vector3.new
37
+ v_end = Vector3.new
38
+ inter_segment = Vector3.new
39
+ inter_ray = Vector3.new
40
+ step = @mode == LineStrip ? 1 : 2
41
+
42
+ if geometry.is_a?(BufferGeometry)
43
+ attributes = @geometry.attributes
44
+
45
+ if !attributes.index.nil?
46
+ indices = attributes.index.array
47
+ positions = attributes.position.array
48
+ offsets = geometry.offsets
49
+
50
+ if offsets.empty?
51
+ offsets = [{ start: 0, count: indices.length, index: 0 }]
52
+ end
53
+
54
+ offsets.each_with_index do |offset, oi|
55
+ start = offset[:start]
56
+ count = offset[:count]
57
+ index = offset[:index]
58
+
59
+ (start...(count-1)).step(step).each do |i|
60
+ v_start.from_array(positions, a * 3)
61
+ v_end.from_array(positions, b * 3)
62
+
63
+ dist_sq = @_ray.distance_sq_to_segment(v_start, v_end, inter_ray, inter_segment)
64
+
65
+ next if dist_sq > precision_sq
66
+
67
+ distance = @_ray.origin.distance_to(inter_ray)
68
+
69
+ next if distance < raycaster.near || distance > raycaster.far
70
+
71
+ intersects << {
72
+ distance: distance,
73
+ # What to we want? intersection point on the ray or on the segment??
74
+ # point: raycaster.ray.at(distance),
75
+ point: inter_segment.clone.apply_matrix4(@matrix_matrix),
76
+ index: i,
77
+ offset_index: oi,
78
+ face: nil,
79
+ face_index: nil,
80
+ object: self
81
+ }
82
+ end
83
+ end
84
+ else
85
+ positions = attributes.position.array
86
+
87
+ (0...(positions.length / 3 - 1)).step(step) do |i|
88
+ v_start.from_array(positions, 3 * i)
89
+ v_end.from_array(positions, 3 * i + 3)
90
+
91
+ dist_sq = @_ray.distance_sq_to_segment(v_start, v_end, inter_ray, inter_segment)
92
+
93
+ next if dist_sq > precision_sq
94
+
95
+ distance = @_ray.origin.distance_to(inter_ray)
96
+
97
+ next if distance < raycaster.near || distance > raycaster.far
98
+
99
+ intersects << {
100
+ distance: distance,
101
+ # What do we want? intersection point on the ray or on the segment??
102
+ # point: raycaster.ray.at(distance),
103
+ point: inter_segment.clone.apply_matrix4(@matrix_world),
104
+ index: i,
105
+ face: nil,
106
+ face_index: nil,
107
+ object: self
108
+ }
109
+ end
110
+ end
111
+ elsif geometry.is_a?(Geometry)
112
+ vertices = @geometry.vertices
113
+ nb_vertices = vertices.length
114
+
115
+ (0...(nb_vertices - 1)).step(step).each do |i|
116
+ dist_sq = @_ray.distance_sq_to_segment(vertices[i], vertices[i + 1], inter_ray, inter_segment)
117
+
118
+ next if dist_sq > precision_sq
119
+
120
+ distance = @_ray.origin.distance_to(inter_ray)
121
+
122
+ next if distance < raycaster.near || distance > raycaster.far
123
+
124
+ intersects << {
125
+ distance: distance,
126
+ # What do we want? intersection point on the ray or on the segment??
127
+ # point: raycaster.ray.at(distance),
128
+ point: inter_segment.clone.apply_matrix4(@matrix_world),
129
+ index: i,
130
+ face: nil,
131
+ face_index: nil,
132
+ object: self
133
+ }
134
+ end
135
+ end
136
+ end
137
+
138
+ def clone(object = Line.new(@geometry, @material, @mode))
139
+ super(object)
140
+ object
141
+ end
142
+ end
143
+ end