leaves
with objects described in obj_def
# Fill `leaves` with objects described in `obj_def`
fun fill_leaves(target_model: ModelAsset)
do
var leaves = target_model.leaves_cache
# Sort faces by material
var obj_mtl_to_faces = new Map[ObjObj, MultiHashMap[String, ObjFace]]
for obj in obj_def.objects do
var mtl_to_faces = new MultiHashMap[String, ObjFace]
obj_mtl_to_faces[obj] = mtl_to_faces
for face in obj.faces do
var mtl_lib_name = face.material_lib
var mtl_name = face.material_name
var full_name = ""
if mtl_lib_name != null and mtl_name != null then full_name = mtl_lib_name / mtl_name
mtl_to_faces[full_name].add face
end
end
# Load material libs
var mtl_libs = sys.mtl_libs
var lib_names = obj_def.material_libs
for name in lib_names do
var asset_path = self.path.dirname / name
var lib_asset = new TextAsset(asset_path)
lib_asset.load
var error = lib_asset.error
if error != null then
errors.add error
continue
end
var mtl_parser = new MtlFileParser(lib_asset.to_s)
var mtl_lib = mtl_parser.parse
mtl_libs[asset_path] = mtl_lib
end
# Create 1 mesh per material per object, and prepare materials
var mesh_to_mtl = new Map[Mesh, nullable MtlDef]
var mesh_to_name = new Map[Mesh, String]
var texture_names = new Set[String]
for obj in obj_def.objects do
var mtl_to_faces = obj_mtl_to_faces[obj]
for mtl_path, faces in mtl_to_faces do
# Create mesh
var mesh = new Mesh
mesh.vertices = vertices(faces)
mesh.normals = normals(faces)
mesh.texture_coords = texture_coords(faces)
# Material
var mtl_def = null
var mtl_lib_name = faces.first.material_lib
var mtl_name = faces.first.material_name
if mtl_lib_name != null and mtl_name != null then
var asset_path = self.path.dirname / mtl_lib_name
var mtl_lib = mtl_libs[asset_path]
var mtl = mtl_lib.get_or_null(mtl_name)
if mtl != null then
mtl_def = mtl
for e in mtl.maps do
texture_names.add self.path.dirname / e
end
else
errors.add new Error("Error loading model at '{path}': mtl '{mtl_name}' not found in '{asset_path}'")
end
end
mesh_to_mtl[mesh] = mtl_def
mesh_to_name[mesh] = obj.name
end
end
# Load textures need for these materials
for name in texture_names do
if not asset_textures_by_name.keys.has(name) then
var tex = new TextureAsset(name)
asset_textures_by_name[name] = tex
tex.load
var error = tex.error
if error != null then errors.add error
end
end
# Create final `Materials` from defs and textures
var materials = new Map[MtlDef, Material]
for mtl in mesh_to_mtl.values do
if mtl == null then continue
var ambient = mtl.ambient.to_a
ambient.add 1.0
var diffuse = mtl.diffuse.to_a
diffuse.add 1.0
var specular = mtl.specular.to_a
specular.add 1.0
var material = new TexturedMaterial(ambient, diffuse, specular)
materials[mtl] = material
var tex_name = mtl.map_ambient
if tex_name != null then
tex_name = self.path.dirname / tex_name
material.ambient_texture = asset_textures_by_name[tex_name]
end
tex_name = mtl.map_diffuse
if tex_name != null then
tex_name = self.path.dirname / tex_name
material.diffuse_texture = asset_textures_by_name[tex_name]
end
tex_name = mtl.map_specular
if tex_name != null then
tex_name = self.path.dirname / tex_name
material.specular_texture = asset_textures_by_name[tex_name]
end
end
# Create models and store them
var name_to_leaves = new MultiHashMap[String, LeafModel]
for mesh, mtl_def in mesh_to_mtl do
var material = materials.get_or_null(mtl_def)
if material == null then material = new Material
var model = new LeafModel(mesh, material)
leaves.add model
name_to_leaves[mesh_to_name[mesh]].add model
end
# Collect objects with a name
for name, models in name_to_leaves do
if models.length == 1 then
target_model.named_leaves_cache[name] = models.first
else
var named_model = new CompositeModel
named_model.leaves.add_all models
target_model.named_leaves_cache[name] = named_model
end
end
end
lib/gamnit/depth/more_models.nit:141,2--291,4