mittsu 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +3 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +7 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/examples/01_-_Default1noCulling.png +0 -0
- data/examples/01_scene_example.rb +14 -0
- data/examples/02_box_mesh_example.rb +30 -0
- data/examples/02_sphere_mesh_example.rb +30 -0
- data/examples/03_complex_object_example.rb +52 -0
- data/examples/04_ambient_light_example.rb +33 -0
- data/examples/04_dir_light_example.rb +36 -0
- data/examples/04_hemi_light_example.rb +30 -0
- data/examples/04_point_light_example.rb +50 -0
- data/examples/04_spot_light_example.rb +44 -0
- data/examples/05_earth_example.rb +42 -0
- data/examples/05_earth_moon_example.rb +46 -0
- data/examples/05_texture_example.rb +32 -0
- data/examples/06_cube_texture_example.rb +36 -0
- data/examples/06_skybox_example.rb +60 -0
- data/examples/07_earth_normal_example.rb +36 -0
- data/examples/08_shadow_example.rb +87 -0
- data/examples/09_line_example.rb +52 -0
- data/examples/10_obj_loader_example.rb +68 -0
- data/examples/11_character_input_example.rb +18 -0
- data/examples/11_continuous_keyboard_input_example.rb +35 -0
- data/examples/11_keyboard_input_example.rb +43 -0
- data/examples/12_mouse_click_example.rb +38 -0
- data/examples/12_mouse_motion_example.rb +35 -0
- data/examples/12_mouse_scroll_example.rb +36 -0
- data/examples/12_orbit_zoom_example.rb +68 -0
- data/examples/13_joystick_example.rb +80 -0
- data/examples/cubemap/tron_bk.png +0 -0
- data/examples/cubemap/tron_dn.png +0 -0
- data/examples/cubemap/tron_ft.png +0 -0
- data/examples/cubemap/tron_lf.png +0 -0
- data/examples/cubemap/tron_rt.png +0 -0
- data/examples/cubemap/tron_up.png +0 -0
- data/examples/earth.png +0 -0
- data/examples/earth_normal.png +0 -0
- data/examples/example_helper.rb +2 -0
- data/examples/male-02-1noCulling.png +0 -0
- data/examples/male02.mtl +54 -0
- data/examples/male02.obj +13888 -0
- data/examples/moon.png +0 -0
- data/examples/orig_02_-_Defaul1noCulling.png +0 -0
- data/examples/texture.png +0 -0
- data/lib/mittsu.rb +15 -0
- data/lib/mittsu/cameras.rb +4 -0
- data/lib/mittsu/cameras/camera.rb +34 -0
- data/lib/mittsu/cameras/cube_camera.rb +74 -0
- data/lib/mittsu/cameras/orthographic_camera.rb +53 -0
- data/lib/mittsu/cameras/perspective_camera.rb +115 -0
- data/lib/mittsu/constants.rb +160 -0
- data/lib/mittsu/core.rb +10 -0
- data/lib/mittsu/core/buffer_attribute.rb +87 -0
- data/lib/mittsu/core/buffer_geometry.rb +694 -0
- data/lib/mittsu/core/clock.rb +44 -0
- data/lib/mittsu/core/dynamic_buffer_attribute.rb +16 -0
- data/lib/mittsu/core/event_dispatcher.rb +39 -0
- data/lib/mittsu/core/face3.rb +30 -0
- data/lib/mittsu/core/geometry.rb +596 -0
- data/lib/mittsu/core/hash_array.rb +36 -0
- data/lib/mittsu/core/hash_object.rb +19 -0
- data/lib/mittsu/core/object_3d.rb +421 -0
- data/lib/mittsu/core/raycaster.rb +78 -0
- data/lib/mittsu/extras.rb +3 -0
- data/lib/mittsu/extras/geometries.rb +2 -0
- data/lib/mittsu/extras/geometries/box_geometry.rb +108 -0
- data/lib/mittsu/extras/geometries/sphere_geometry.rb +88 -0
- data/lib/mittsu/extras/helpers.rb +1 -0
- data/lib/mittsu/extras/helpers/camera_helper.rb +155 -0
- data/lib/mittsu/extras/image.rb +3 -0
- data/lib/mittsu/extras/image_utils.rb +80 -0
- data/lib/mittsu/lights.rb +7 -0
- data/lib/mittsu/lights/ambient_light.rb +16 -0
- data/lib/mittsu/lights/area_light.rb +24 -0
- data/lib/mittsu/lights/directional_light.rb +131 -0
- data/lib/mittsu/lights/hemisphere_light.rb +29 -0
- data/lib/mittsu/lights/light.rb +21 -0
- data/lib/mittsu/lights/point_light.rb +27 -0
- data/lib/mittsu/lights/spot_light.rb +104 -0
- data/lib/mittsu/loaders.rb +7 -0
- data/lib/mittsu/loaders/cache.rb +53 -0
- data/lib/mittsu/loaders/file_loader.rb +22 -0
- data/lib/mittsu/loaders/image_loader.rb +32 -0
- data/lib/mittsu/loaders/loader.rb +212 -0
- data/lib/mittsu/loaders/loading_manager.rb +17 -0
- data/lib/mittsu/loaders/mtl_loader.rb +242 -0
- data/lib/mittsu/loaders/obj_mtl_loader.rb +225 -0
- data/lib/mittsu/materials.rb +7 -0
- data/lib/mittsu/materials/line_basic_material.rb +39 -0
- data/lib/mittsu/materials/material.rb +156 -0
- data/lib/mittsu/materials/mesh_basic_material.rb +122 -0
- data/lib/mittsu/materials/mesh_face_material.rb +30 -0
- data/lib/mittsu/materials/mesh_lambert_material.rb +126 -0
- data/lib/mittsu/materials/mesh_phong_material.rb +152 -0
- data/lib/mittsu/materials/shader_material.rb +108 -0
- data/lib/mittsu/math.rb +105 -0
- data/lib/mittsu/math/box2.rb +135 -0
- data/lib/mittsu/math/box3.rb +194 -0
- data/lib/mittsu/math/color.rb +252 -0
- data/lib/mittsu/math/color_keywords.rb +151 -0
- data/lib/mittsu/math/euler.rb +182 -0
- data/lib/mittsu/math/frustum.rb +106 -0
- data/lib/mittsu/math/line3.rb +76 -0
- data/lib/mittsu/math/matrix3.rb +163 -0
- data/lib/mittsu/math/matrix4.rb +581 -0
- data/lib/mittsu/math/plane.rb +128 -0
- data/lib/mittsu/math/quaternion.rb +309 -0
- data/lib/mittsu/math/ray.rb +292 -0
- data/lib/mittsu/math/sphere.rb +91 -0
- data/lib/mittsu/math/spline.rb +128 -0
- data/lib/mittsu/math/triangle.rb +121 -0
- data/lib/mittsu/math/vector2.rb +238 -0
- data/lib/mittsu/math/vector3.rb +491 -0
- data/lib/mittsu/math/vector4.rb +414 -0
- data/lib/mittsu/objects.rb +3 -0
- data/lib/mittsu/objects/group.rb +8 -0
- data/lib/mittsu/objects/line.rb +143 -0
- data/lib/mittsu/objects/mesh.rb +243 -0
- data/lib/mittsu/renderers.rb +1 -0
- data/lib/mittsu/renderers/glfw_window.rb +216 -0
- data/lib/mittsu/renderers/opengl/opengl_debug.rb +38 -0
- data/lib/mittsu/renderers/opengl/opengl_program.rb +402 -0
- data/lib/mittsu/renderers/opengl/opengl_shader.rb +58 -0
- data/lib/mittsu/renderers/opengl/opengl_state.rb +207 -0
- data/lib/mittsu/renderers/opengl/plugins/shadow_map_plugin.rb +416 -0
- data/lib/mittsu/renderers/opengl_render_target.rb +87 -0
- data/lib/mittsu/renderers/opengl_renderer.rb +3376 -0
- data/lib/mittsu/renderers/shaders/shader_chunk.rb +12 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/alphamap_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/alphamap_pars_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/alphatest_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/bumpmap_pars_fragment.glsl +40 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/color_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/color_pars_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/color_pars_vertex.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/color_vertex.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/common.glsl +60 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/default_vertex.glsl +15 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/defaultnormal_vertex.glsl +21 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/envmap_fragment.glsl +62 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/envmap_pars_fragment.glsl +21 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/envmap_pars_vertex.glsl +7 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/envmap_vertex.glsl +17 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/fog_fragment.glsl +26 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/fog_pars_fragment.glsl +15 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lightmap_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lightmap_pars_fragment.glsl +6 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lightmap_pars_vertex.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lightmap_vertex.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lights_lambert_pars_vertex.glsl +43 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lights_lambert_vertex.glsl +196 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lights_phong_fragment.glsl +243 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lights_phong_pars_fragment.glsl +58 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lights_phong_pars_vertex.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lights_phong_vertex.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/linear_to_gamma_fragment.glsl +2 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/logdepthbuf_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/logdepthbuf_pars_fragment.glsl +12 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/logdepthbuf_pars_vertex.glsl +11 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/logdepthbuf_vertex.glsl +15 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/map_fragment.glsl +9 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/map_pars_fragment.glsl +11 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/map_pars_vertex.glsl +6 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/map_particle_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/map_particle_pars_fragment.glsl +6 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/map_vertex.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/morphnormal_vertex.glsl +12 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/morphtarget_pars_vertex.glsl +13 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/morphtarget_vertex.glsl +20 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/normalmap_pars_fragment.glsl +27 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/shadowmap_fragment.glsl +217 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/shadowmap_pars_fragment.glsl +19 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/shadowmap_pars_vertex.glsl +6 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/shadowmap_vertex.glsl +9 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/skinbase_vertex.glsl +8 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/skinning_pars_vertex.glsl +47 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/skinning_vertex.glsl +20 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/skinnormal_vertex.glsl +20 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/specularmap_fragment.glsl +12 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/specularmap_pars_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/worldpos_vertex.glsl +17 -0
- data/lib/mittsu/renderers/shaders/shader_lib.rb +420 -0
- data/lib/mittsu/renderers/shaders/uniforms_lib.rb +107 -0
- data/lib/mittsu/renderers/shaders/uniforms_utils.rb +31 -0
- data/lib/mittsu/scenes.rb +1 -0
- data/lib/mittsu/scenes/scene.rb +27 -0
- data/lib/mittsu/textures.rb +5 -0
- data/lib/mittsu/textures/compressed_texture.rb +30 -0
- data/lib/mittsu/textures/cube_texture.rb +19 -0
- data/lib/mittsu/textures/data_texture.rb +17 -0
- data/lib/mittsu/textures/texture.rb +92 -0
- data/lib/mittsu/textures/video_texture.rb +17 -0
- data/lib/mittsu/version.rb +4 -0
- data/mittsu.gemspec +31 -0
- metadata +357 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
module Mittsu
|
2
|
+
module Cache
|
3
|
+
@@files = {}
|
4
|
+
|
5
|
+
def self.add(key, file)
|
6
|
+
@@files[key] = file
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.get(key)
|
10
|
+
@@files[key]
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.remove(key)
|
14
|
+
@@files.delete(key)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.clear
|
18
|
+
@@files.clear
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# files: {},
|
24
|
+
#
|
25
|
+
# add: function ( key, file ) {
|
26
|
+
#
|
27
|
+
# // console.log( 'THREE.Cache', 'Adding key:', key );
|
28
|
+
#
|
29
|
+
# this.files[ key ] = file;
|
30
|
+
#
|
31
|
+
# },
|
32
|
+
#
|
33
|
+
# get: function ( key ) {
|
34
|
+
#
|
35
|
+
# // console.log( 'THREE.Cache', 'Checking key:', key );
|
36
|
+
#
|
37
|
+
# return this.files[ key ];
|
38
|
+
#
|
39
|
+
# },
|
40
|
+
#
|
41
|
+
# remove: function ( key ) {
|
42
|
+
#
|
43
|
+
# delete this.files[ key ];
|
44
|
+
#
|
45
|
+
# },
|
46
|
+
#
|
47
|
+
# clear: function () {
|
48
|
+
#
|
49
|
+
# this.files = {}
|
50
|
+
#
|
51
|
+
# }
|
52
|
+
#
|
53
|
+
# };
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Mittsu
|
2
|
+
class FileLoader
|
3
|
+
def initialize(manager = nil)
|
4
|
+
@manager = manager || DefaultLoadingManager
|
5
|
+
end
|
6
|
+
|
7
|
+
def load(url)
|
8
|
+
cached = Cache.get(url)
|
9
|
+
|
10
|
+
return cached unless cached.nil?
|
11
|
+
|
12
|
+
@manager.item_start(url)
|
13
|
+
|
14
|
+
text = File.read(url)
|
15
|
+
Cache.add(url, text)
|
16
|
+
|
17
|
+
@manager.item_end(url)
|
18
|
+
|
19
|
+
text
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rmagick'
|
2
|
+
require 'mittsu/extras/image'
|
3
|
+
|
4
|
+
module Mittsu
|
5
|
+
class ImageLoader
|
6
|
+
attr_accessor :manager
|
7
|
+
|
8
|
+
def initialize(manager = DefaultLoadingManager)
|
9
|
+
@manager = manager
|
10
|
+
end
|
11
|
+
|
12
|
+
def load(url, flip: false, flop: false)
|
13
|
+
chache_url = "#{url}?flip=#{flip}&flop=#{flop}"
|
14
|
+
cached = Cache.get(url)
|
15
|
+
return cached unless cached.nil?
|
16
|
+
|
17
|
+
rm_image = Magick::Image.read(url).first
|
18
|
+
rm_image = rm_image.flip if flip
|
19
|
+
rm_image = rm_image.flop if flop
|
20
|
+
rgba_data = rm_image.to_blob { |i|
|
21
|
+
i.format = "RGBA"
|
22
|
+
i.depth = 8
|
23
|
+
}
|
24
|
+
|
25
|
+
image = Image.new(rm_image.columns, rm_image.rows, rgba_data)
|
26
|
+
|
27
|
+
Cache.add(url, image)
|
28
|
+
@manager.item_start(url)
|
29
|
+
image
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,212 @@
|
|
1
|
+
module Mittsu
|
2
|
+
class Loader
|
3
|
+
def initialize(show_status = false)
|
4
|
+
@image_loader = ImageLoader.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def init_materials(materials, texture_path)
|
8
|
+
materials.map do |m|
|
9
|
+
create_material(m, texture_path)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def needs_tangents(materials)
|
14
|
+
materials.each do |m|
|
15
|
+
return true if m.is_a?(ShareMaterial)
|
16
|
+
end
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_material(m, texture_path)
|
21
|
+
# defaults
|
22
|
+
|
23
|
+
mtype = 'MeshLambertMaterial'
|
24
|
+
mpars = {
|
25
|
+
color: 0xeeeeee,
|
26
|
+
opactity: 1.0,
|
27
|
+
map: nil,
|
28
|
+
light_map: nil,
|
29
|
+
normal_map: nil,
|
30
|
+
bump_map: nil,
|
31
|
+
wireframe: false
|
32
|
+
}
|
33
|
+
|
34
|
+
# parameters from model file
|
35
|
+
|
36
|
+
if m.shading
|
37
|
+
shading = m.shading.downcase
|
38
|
+
|
39
|
+
if shading == 'phong'
|
40
|
+
mtype = 'MeshPhongMaterial'
|
41
|
+
elsif shading == 'basic'
|
42
|
+
mtype = 'MeshBasicMaterial'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
if m.blending && Mittsu.const_get(m.blending)
|
47
|
+
mpars[:blending] = Mittsu.const_get(m.blending)
|
48
|
+
end
|
49
|
+
|
50
|
+
mpars[:transparent] = m.transparent if !m.transparent.nil?
|
51
|
+
mpars[:transparent] = true if m.opacity && m.opacity < 1.0
|
52
|
+
mpars[:depth_test] = m.depth_test if !m.depth_test.nil?
|
53
|
+
mpars[:depth_write] = m.depth_write if !m.depth_write.nil?
|
54
|
+
mpars[:visible] = m.visible if !m.visible.nil?
|
55
|
+
mpars[:flip_sided] = BackSide if !m.flip_sided.nil?
|
56
|
+
mpars[:double_sided] = DoubleSide if !m.double_sided.nil?
|
57
|
+
mpars[:wireframe] = m.wireframe if !m.wireframe.nil?
|
58
|
+
|
59
|
+
if !m.vertex_colors.nil?
|
60
|
+
if m.vertex_colors == 'face'
|
61
|
+
mpars[:vertex_colors] = FaceColors
|
62
|
+
elsif !m.vertex_colors.empty?
|
63
|
+
mpars[:vertex_colors] = VertexColors
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# colors
|
68
|
+
|
69
|
+
if m.color_diffuse
|
70
|
+
mpars[:color] = rgb2hex(m.color_diffuse)
|
71
|
+
elsif m.dgb_color
|
72
|
+
mpars[:color] = m.dgb_color
|
73
|
+
end
|
74
|
+
|
75
|
+
if m.color_specular
|
76
|
+
mpars[:specular] = rgb2hex(m.color_specular)
|
77
|
+
end
|
78
|
+
|
79
|
+
if m.color_emissive
|
80
|
+
mpars[:emissive] = rgb2hex(m.color_emissive)
|
81
|
+
end
|
82
|
+
|
83
|
+
# modifiers
|
84
|
+
|
85
|
+
if !m.transparency.nil?
|
86
|
+
puts "WARNING: Mitsu::Loader: transparency has been renamed to opacity"
|
87
|
+
m.opacity = m.transparency
|
88
|
+
end
|
89
|
+
|
90
|
+
if !m.opacity.nil?
|
91
|
+
mpars[:opacity] = m.opacity
|
92
|
+
end
|
93
|
+
|
94
|
+
if m.specular_coef
|
95
|
+
mpars[:shininess] = m.specular_coef
|
96
|
+
end
|
97
|
+
|
98
|
+
# textures
|
99
|
+
|
100
|
+
if m.map_diffuse && texture_path
|
101
|
+
create_texture(mpars, 'map', m.map_diffuse, m.map_diffuse_repeat, m.map_diffuse_offset, m.map_diffuse_wrap, m.map_diffuse_anisotropy)
|
102
|
+
end
|
103
|
+
|
104
|
+
if m.map_light && texture_path
|
105
|
+
create_texture(mpars, 'light_map', m.map_light, m.map_light_repeat, m.map_light_offset, m.map_light_wrap, m.map_light_anisotropy)
|
106
|
+
end
|
107
|
+
|
108
|
+
if m.map_bump && texture_path
|
109
|
+
create_texture(mpars, 'bump_map', m.map_bump, m.map_bump_repeat, m.map_bump_offset, m.map_bump_wrap, m.map_bump_anisotropy)
|
110
|
+
end
|
111
|
+
|
112
|
+
if m.map_normal && texture_path
|
113
|
+
create_texture(mpars, 'normal_map', m.map_normal, m.map_normal_repeat, m.map_normal_offset, m.map_normal_wrap, m.map_normal_anisotropy)
|
114
|
+
end
|
115
|
+
|
116
|
+
if m.map_specular && texture_path
|
117
|
+
create_texture(mpars, 'specular_map', m.map_specular, m.map_specular_repeat, m.map_specular_offset, m.map_specular_wrap, m.map_specular_anisotropy)
|
118
|
+
end
|
119
|
+
|
120
|
+
if m.map_alpha && texture_path
|
121
|
+
create_texture(mpars, 'alpha_map', m.map_alpha, m.map_alpha_repeat, m.map_alpha_offset, m.map_alpha_wrap, m.map_alpha_anisotropy)
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
|
126
|
+
if m.map_bump_scale
|
127
|
+
mpars[:bump_scale] = m.map_bump_scale
|
128
|
+
end
|
129
|
+
|
130
|
+
if m.map_normal_factor
|
131
|
+
mpars[:normal_scale] = Vector2.new(m.map_normal_factor, m.map_normal_factor)
|
132
|
+
end
|
133
|
+
|
134
|
+
Mittsu.const_get(mtype).new(mpars).tap do |material|
|
135
|
+
material.name = m.dbg_name if !m.dbg_name.nil?
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
module Handlers
|
140
|
+
def self.add(regex, loader)
|
141
|
+
@@handlers ||= {}
|
142
|
+
@@handlers[regex] = loader
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.get(file)
|
146
|
+
@@handlers ||= {}
|
147
|
+
@@handlers.find(-> () { [nil, nil] }) { |regex, loader| regex =~ file }[1]
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def nearest_pow2(n)
|
154
|
+
l = Math.log(n) / Math::LN2
|
155
|
+
Math.pow(2, Math.round(l))
|
156
|
+
end
|
157
|
+
|
158
|
+
def create_texture(where, name, source_file, repeat, offset, wrap, anisotropy)
|
159
|
+
full_path = File.join(texture_path, source_file)
|
160
|
+
|
161
|
+
loader = Handlers.get(full_path)
|
162
|
+
|
163
|
+
if !loader.nil?
|
164
|
+
texture = loader.load full_path
|
165
|
+
else
|
166
|
+
texture = Texture.new
|
167
|
+
|
168
|
+
loader = @image_loader
|
169
|
+
image = loader.load full_path
|
170
|
+
|
171
|
+
if !Math.power_of_two?(image.width) || !Math.power_of_two?(image.height)
|
172
|
+
# TODO: resize image to power of two
|
173
|
+
else
|
174
|
+
texture.image = image
|
175
|
+
end
|
176
|
+
|
177
|
+
texture.needs_update = true
|
178
|
+
end
|
179
|
+
|
180
|
+
texture.source_file = source_file
|
181
|
+
|
182
|
+
if repeat
|
183
|
+
texture.repeat.set(repeat[0], repeat[1])
|
184
|
+
|
185
|
+
texture.wrap_s = RepeatWrapping if repeat[0] != 1
|
186
|
+
texture.wrap_t = RepeatWrapping if repeat[1] != 1
|
187
|
+
end
|
188
|
+
|
189
|
+
if offset
|
190
|
+
texture.offset.set(offset[0], offset[1])
|
191
|
+
end
|
192
|
+
|
193
|
+
if wrap
|
194
|
+
wrap_map = {
|
195
|
+
repeat: RepeatWrapping,
|
196
|
+
mirror: MirroredRepeatWrapping
|
197
|
+
}
|
198
|
+
|
199
|
+
texture.wrap_s = wrap_map[wrap[0]] unless wrap_map[wrap[0]].nil?
|
200
|
+
texture.wrap_t = wrap_map[wrap[1]] unless wrap_map[wrap[1]].nil?
|
201
|
+
end
|
202
|
+
|
203
|
+
texture.anisotropy = anisotropy if anisotropy
|
204
|
+
|
205
|
+
where[name] = texture
|
206
|
+
end
|
207
|
+
|
208
|
+
def rgb2hex(rgb)
|
209
|
+
(rgb[0] * 255 << 16) + (rgb[1] * 255 << 8) + rgb[2] * 255
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
module Mittsu
|
2
|
+
class MTLLoader
|
3
|
+
include EventDispatcher
|
4
|
+
|
5
|
+
def initialize(base_url, options = {}) # TODO: cross_origin?
|
6
|
+
@base_url = base_url
|
7
|
+
@options = options
|
8
|
+
# @cross_origin = cross_origin
|
9
|
+
end
|
10
|
+
|
11
|
+
def load(url)
|
12
|
+
loader = FileLoader.new
|
13
|
+
# loader.cross_origin = @cross_origin
|
14
|
+
|
15
|
+
text = loader.load File.join(@base_url, url)
|
16
|
+
parse(text)
|
17
|
+
end
|
18
|
+
|
19
|
+
def parse(text)
|
20
|
+
lines = text.split("\n")
|
21
|
+
info = {}
|
22
|
+
delimiter_pattern = /\s+/
|
23
|
+
materials_info = {}
|
24
|
+
|
25
|
+
lines.each do |line|
|
26
|
+
line = line.strip
|
27
|
+
|
28
|
+
next if line.empty? || line.start_with?('#')
|
29
|
+
|
30
|
+
pos = line.index(' ')
|
31
|
+
|
32
|
+
key = ( pos >= 0 ) ? line[0...pos] : line
|
33
|
+
key = key.downcase
|
34
|
+
|
35
|
+
value = ( pos >= 0 ) ? line[pos + 1..-1] : ""
|
36
|
+
value = value.strip
|
37
|
+
|
38
|
+
if key == "newmtl"
|
39
|
+
# New material
|
40
|
+
|
41
|
+
info = { name: value };
|
42
|
+
materials_info[value] = info
|
43
|
+
elsif info
|
44
|
+
if key == "ka" || key == "kd" || key == "ks"
|
45
|
+
ss = value.split(delimiter_pattern).take(3)
|
46
|
+
info[key] = [ss[0].to_f, ss[1].to_f, ss[2].to_f]
|
47
|
+
else
|
48
|
+
info[key] = value
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
MaterialCreator.new(@base_url, @options).tap do |material_creator|
|
54
|
+
material_creator.set_materials(materials_info)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class MaterialCreator
|
59
|
+
def initialize(base_url, options = nil)
|
60
|
+
@base_url = base_url
|
61
|
+
@options = options
|
62
|
+
@material_info = {}
|
63
|
+
@materials = {}
|
64
|
+
@materials_array = []
|
65
|
+
@name_lookup = {}
|
66
|
+
|
67
|
+
@side = (@options || {}).fetch(:side, FrontSide)
|
68
|
+
@wrap = (@options || {}).fetch(:wrap, RepeatWrapping)
|
69
|
+
end
|
70
|
+
|
71
|
+
def set_materials(materials_info)
|
72
|
+
@materials_info = convert materials_info
|
73
|
+
@materials = {}
|
74
|
+
@materials_array = []
|
75
|
+
@name_lookup = {}
|
76
|
+
end
|
77
|
+
|
78
|
+
def convert(materials_info)
|
79
|
+
return materials_info if !@options
|
80
|
+
|
81
|
+
converted = {}
|
82
|
+
|
83
|
+
materials_info.each do |mn, mat|
|
84
|
+
covmat = {}
|
85
|
+
converted[mn] = covmat
|
86
|
+
|
87
|
+
mat.each do |prop, value|
|
88
|
+
save = true
|
89
|
+
lprop = prop.to_s.downcase
|
90
|
+
|
91
|
+
case lprop
|
92
|
+
when 'kd', 'ka', 'ks'
|
93
|
+
# Diffuse color, (color under white light) using RGB values
|
94
|
+
|
95
|
+
if @options && @options[:normalize_rgb]
|
96
|
+
value = [value[0] / 255.0, value[1] / 255.0, value[2] / 255.0]
|
97
|
+
end
|
98
|
+
|
99
|
+
if @options && @options[:ignore_zero_rgbs]
|
100
|
+
if value.take(3).any?(&:zero?)
|
101
|
+
# ignore
|
102
|
+
save = false
|
103
|
+
end
|
104
|
+
end
|
105
|
+
when 'd'
|
106
|
+
# According to MTL format (http://paulbourke.net/dataformats/mtl/):
|
107
|
+
# d is dissolve for current material
|
108
|
+
# factor of 1.0 is fully opaque, a factor of 0 is fully dissolved (completely transparent)
|
109
|
+
|
110
|
+
if @options && @options[:invert_transparency]
|
111
|
+
value = 1.0 - value
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
covmat[lprop] = value if save
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
converted
|
120
|
+
end
|
121
|
+
|
122
|
+
def preload
|
123
|
+
@materials_info.each_key do |mn|
|
124
|
+
create mn
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def get_index(material_name)
|
129
|
+
@name_lookup[material_name]
|
130
|
+
end
|
131
|
+
|
132
|
+
def get_as_array
|
133
|
+
@materials_info.keys.each_with_index do |mn, index|
|
134
|
+
@materials_array[index] = create mn
|
135
|
+
@name_lookup[mn] = index
|
136
|
+
end
|
137
|
+
|
138
|
+
@materials_array
|
139
|
+
end
|
140
|
+
|
141
|
+
def create(material_name)
|
142
|
+
if @materials[material_name].nil?
|
143
|
+
create_material(material_name)
|
144
|
+
end
|
145
|
+
|
146
|
+
@materials[material_name]
|
147
|
+
end
|
148
|
+
|
149
|
+
def load_texture(url, mapping = nil)
|
150
|
+
loader = Loader::Handlers.get(url)
|
151
|
+
|
152
|
+
if !loader.nil?
|
153
|
+
texture = loader.load url
|
154
|
+
else
|
155
|
+
texture = Texture.new
|
156
|
+
|
157
|
+
loader = ImageLoader.new
|
158
|
+
# loader.cross_origin = @cross_origin # TODO: ???
|
159
|
+
image = loader.load url
|
160
|
+
|
161
|
+
texture.image = ensure_power_of_two(image)
|
162
|
+
texture.needs_update = true
|
163
|
+
end
|
164
|
+
|
165
|
+
texture.mapping = mapping unless mapping.nil?
|
166
|
+
|
167
|
+
texture
|
168
|
+
end
|
169
|
+
|
170
|
+
private
|
171
|
+
|
172
|
+
def create_material(material_name)
|
173
|
+
mat = @materials_info[material_name]
|
174
|
+
params = {
|
175
|
+
name: material_name,
|
176
|
+
side: @side
|
177
|
+
}
|
178
|
+
|
179
|
+
mat.each do |prop, value|
|
180
|
+
case prop.downcase
|
181
|
+
when 'kd'
|
182
|
+
# Diffuse color (color under white light) using RGB values
|
183
|
+
params[:diffuse] = Color.new.from_array(value)
|
184
|
+
when 'ka'
|
185
|
+
# Ambient color (color under shadow) using RGB value
|
186
|
+
when 'ks'
|
187
|
+
# Specular color (color when light is reflected from shiny surface) using RGB values
|
188
|
+
params[:specular] = Color.new.from_array(value)
|
189
|
+
when 'map_kd'
|
190
|
+
# Diffuse texture map
|
191
|
+
params[:map] = load_texture File.join(@base_url, value)
|
192
|
+
params[:map].wrap_s = @wrap
|
193
|
+
params[:map].wrap_t = @wrap
|
194
|
+
when 'ns'
|
195
|
+
# The specular exponent (defines the focus of the specular highlight)
|
196
|
+
# A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000.
|
197
|
+
params[:shininess] = value.to_f
|
198
|
+
when 'd'
|
199
|
+
# According to MTL format (http://paulbourke.net/dataformats/mtl/):
|
200
|
+
# d is dissolve for current material
|
201
|
+
# factor of 1.0 is fully opaque, a factor of 0 is fully dissolved (completely transparent)
|
202
|
+
|
203
|
+
if value.to_f < 1
|
204
|
+
params[:transparent] = true
|
205
|
+
params[:opacity] = value.to_f
|
206
|
+
end
|
207
|
+
when 'map_bump', 'bump'
|
208
|
+
# Bump texture map
|
209
|
+
if !params[:bump_map]
|
210
|
+
params[:bump_map] = load_texture File.join(@base_url, value)
|
211
|
+
params[:bump_map].wrap_s = @wrap
|
212
|
+
params[:bump_map].wrap_t = @wrap
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
if params[:diffuse]
|
218
|
+
params[:color] = params[:diffuse]
|
219
|
+
end
|
220
|
+
|
221
|
+
@materials[material_name] = MeshPhongMaterial.new(params)
|
222
|
+
end
|
223
|
+
|
224
|
+
def ensure_power_of_two(image)
|
225
|
+
if !Math.power_of_two?(image.width) || !Math.power_of_two?(image.height)
|
226
|
+
# TODO: resize image ???
|
227
|
+
end
|
228
|
+
image
|
229
|
+
end
|
230
|
+
|
231
|
+
def next_highest_power_of_two(x)
|
232
|
+
x -= 1
|
233
|
+
i = 1
|
234
|
+
while i < 32
|
235
|
+
x = x | x >> i
|
236
|
+
i <<= 1
|
237
|
+
end
|
238
|
+
x + 1
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|