lib/mittsu/loaders/obj_mtl_loader.rb in mittsu-0.1.1 vs lib/mittsu/loaders/obj_mtl_loader.rb in mittsu-0.1.2

- old
+ new

@@ -4,222 +4,26 @@ def initialize(manager = DefaultLoadingManager) @manager = manager end - def load(url, mtlurl) - mtl_loader = MTLLoader.new(File.dirname(url)) - # mtl_loader.cross_origin = @cross_origin # TODO: not needed? - materials_creator = mtl_loader.load(mtlurl) + def load(url, mtlurl = nil) + object = OBJLoader.new(@manager).load(url) - materials_creator.preload + if !mtlurl.nil? + mtl_loader = MTLLoader.new(File.dirname(url)) + materials_creator = mtl_loader.load(mtlurl) - loader = FileLoader.new(@manager) - # loader.cross_origin = @cross_origin # TODO: not needed? + materials_creator.preload - text = loader.load(url) - object = parse(text) - - object.traverse do |child_object| - if child_object.is_a?(Mesh) && child_object.material.name && !child_object.material.name.empty? - material = materials_creator.create(child_object.material.name) - child_object.material = material if material + object.traverse do |child_object| + if child_object.is_a?(Mesh) && child_object.material.name && !child_object.material.name.empty? + material = materials_creator.create(child_object.material.name) + child_object.material = material if material + end end end object - end - - def parse(data) - @face_offset = 0 - @group = Group.new - @object = @group - - @geometry = Geometry.new - @material = MeshLambertMaterial.new - @mesh = Mesh.new(@geometry, @material) - - @vertices = [] - @normals = [] - @uvs = [] - - # v float float float - vertex_pattern = /v( +[\d|.|+|\-|e]+)( +[\d|.|+|\-|e]+)( +[\d|.|+|\-|e]+)/ - - # vn float float float - normal_pattern = /vn( +[\d|.|+|\-|e]+)( +[\d|.|+|\-|e]+)( +[\d|.|+|\-|e]+)/ - - # vt float flot - uv_pattern = /vt( +[\d|.|+|\-|e]+)( +[\d|.|+|\-|e]+)/ - - # f vertex vertex vertex - face_pattern1 = /f( +\d+)( +\d+)( +\d+)?/ - - # f vertex/uv vertex/uv vertex/uv - face_pattern2 = /f( +(\d+)\/(\d+))( +(\d+)\/(\d+))( +(\d+)\/(\d+))( +(\d+)\/(\d+))?/ - - # f vertex/uv/normal vertex/uv/normal vertex/uv/normal ... - face_pattern3 = /f( +(\d+)\/(\d+)\/(\d+))( +(\d+)\/(\d+)\/(\d+))( +(\d+)\/(\d+)\/(\d+))( +(\d+)\/(\d+)\/(\d+))?/ - - # f vertex//normal vertex//normal vertex//normal ... - face_pattern4 = /f( +(\d+)\/\/(\d+))( +(\d+)\/\/(\d+))( +(\d+)\/\/(\d+))( +(\d+)\/\/(\d+))?/ - - lines = data.split("\n") - - lines.each do |line| - line = line.strip - - next if line.empty? || line.start_with?('#') - - if vertex_pattern =~ line - # ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"] - @vertices << vector($1.to_f, $2.to_f, $3.to_f) - elsif normal_pattern =~ line - # ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"] - @normals << vector($1.to_f, $2.to_f, $3.to_f) - elsif uv_pattern =~ line - # ["vt 0.1 0.2", "0.1", "0.2"] - @uvs << uv($1.to_f, $2.to_f) - elsif face_pattern1 =~ line - # ["f 1 2 3", "1", "2", "3", undefined] - handle_face_line([ $1, $2, $3, $4 ]) - elsif face_pattern2 =~ line - # ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined] - handle_face_line( - [ $2, $5, $8, $11 ], #faces - [ $3, $6, $9, $12 ] #uv - ) - elsif face_pattern3 =~ line - # ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined] - handle_face_line( - [ $2, $6, $10, $14 ], #faces - [ $3, $7, $11, $15 ], #uv - [ $4, $8, $12, $16 ] #normal - ) - elsif face_pattern4 =~ line - # ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined] - handle_face_line( - [ $2, $5, $8, $11 ], #faces - [ ], #uv - [ $3, $6, $9, $12 ] #normal - ) - elsif /^o / =~ line - # object - mesh_n - @face_offset = @face_offset + @vertices.length - @vertices = [] - object = Object3D.new - object.name = line[2..-1].strip - @group.add(object) - elsif /^g / =~ line - # group - mesh_n(line[2..-1].strip, nil) - elsif /^usemtl / =~ line - # material - mesh_n(nil, line[7..-1].strip) - elsif /^mtllib / =~ line - # mtl file - - # TODO: ??? - # if mtllib_callback - # mtlfile = line[7..-1].strip - # mtllib_callback.(mtlfile) - # end - elsif /^s / =~ line - # Smooth shading - else - puts "Mittsu::OBJMTLLoader: Unhandled line #{line}" - end - end - - mesh_n(nil, nil) - - @group - end - - private - - def vector(x, y, z) - Vector3.new(x, y, z) - end - - def uv(u, v) - Vector2.new(u, v) - end - - def face3(a, b, c, normals = nil) - Face3.new(a, b, c, normals) - end - - def mesh_n(mesh_name = nil, material_name = nil) - if !@vertices.empty? - @geometry.vertices = @vertices - - @geometry.merge_vertices - @geometry.compute_face_normals - @geometry.compute_bounding_sphere - - @object.add(@mesh) - - @geometry = Geometry.new - @mesh = Mesh.new(@geometry, @material) - end - - @mesh.name = mesh_name unless mesh_name.nil? - - if !material_name.nil? - @material = MeshLambertMaterial.new - @material.name = material_name - - @mesh.material = @material - end - end - - def add_face(a, b, c, normal_inds = nil) - if normal_inds.nil? - @geometry.faces << face3( - a.to_i - (@face_offset + 1), - b.to_i - (@face_offset + 1), - c.to_i - (@face_offset + 1) - ) - else - @geometry.faces << face3( - a.to_i - (@face_offset + 1), - b.to_i - (@face_offset + 1), - c.to_i - (@face_offset + 1), - normal_inds.take(3).map { |i| @normals[i.to_i - 1].clone } - ) - end - end - - def add_uvs(a, b, c) - @geometry.face_vertex_uvs[0] << [ - @uvs[a.to_i - 1].clone, - @uvs[b.to_i - 1].clone, - @uvs[c.to_i - 1].clone - ] - end - - def handle_face_line(faces, uvs = nil, normal_inds = nil) - if faces[3].nil? - add_face(faces[0], faces[1], faces[2], normal_inds) - - if !uvs.nil? && !uvs.empty? - add_uvs(uvs[0], uvs[1], uvs[2]) - end - else - if !normal_inds.nil? && !normal_inds.empty? - add_face(faces[0], faces[1], fances[3], [normal_inds[0], normal_inds[1], normal_inds[3]]) - add_face(faces[1], faces[2], fances[3], [normal_inds[1], normal_inds[2], normal_inds[3]]) - else - add_face(faces[0], faces[1], faces[3]) - add_face(faces[1], faces[2], faces[3]) - end - - if !uvs.nil? && !uvs.empty? - add_uvs(uvs[0], uvs[1], uvs[2]) - add_uvs(uvs[1], uvs[2], uvs[2]) - end - end end end end