diff --git a/src/model/material.rs b/src/model/material.rs index f626fa3..25e1fdc 100644 --- a/src/model/material.rs +++ b/src/model/material.rs @@ -2,9 +2,8 @@ use std::collections::HashMap; -use glium::texture::SrgbTexture2d; - /// A 3D material. +#[derive(Clone)] pub struct Material { /// The name of the material. @@ -17,9 +16,6 @@ pub struct Material { /// /// They might be necessary for the export though. pub unknown_instructions: Vec, - - /// The texture that will be used for rendering. - pub rendering_texture: Option, } impl Material { @@ -30,7 +26,6 @@ impl Material { name: name.to_owned(), textures: HashMap::new(), unknown_instructions: vec![], - rendering_texture: None, } } diff --git a/src/model/mod.rs b/src/model/mod.rs index f9ddeb4..cac51ec 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -7,6 +7,7 @@ use std::collections::HashMap; use std::collections::hash_map::Entry; use glium::VertexBuffer; +use glium::texture::SrgbTexture2d; use parser::{parse, ParserError}; @@ -89,6 +90,9 @@ pub struct Model { /// Map associating the name of a material to the real material. pub materials: HashMap, + /// Map associating the name of a texture and the real texture. + pub textures: HashMap>, + /// The list of parts of the model. pub parts: Vec, @@ -119,6 +123,7 @@ impl Model { parts: vec![], faces: vec![], current_part_index: None, + textures: HashMap::new(), } } @@ -393,15 +398,21 @@ impl Model { /// Builds the textures of all materials. pub fn build_textures(&mut self, renderer: &Renderer) { - for (_, ref mut material) in &mut self.materials { - Model::build_texture_for_material(material, renderer); + for (_, material) in self.materials.clone() { + self.build_texture_for_material(&material, renderer); } } /// Builds the SrgbTextures for rendering. - pub fn build_texture_for_material(material: &mut Material, renderer: &Renderer) { + pub fn build_texture_for_material(&mut self, material: &Material, renderer: &Renderer) { if let Some(path) = material.textures.get("map_Kd") { - material.rendering_texture = Some(renderer.make_texture(path)); + let texture = renderer.make_texture(path); + self.textures.insert(path.to_owned(), Some(texture)); }; } + + /// Returns the rendering texture. + pub fn get_texture_by_name(&self, name: &str) -> Option<&SrgbTexture2d> { + self.textures[name].as_ref() + } } diff --git a/src/renderer.rs b/src/renderer.rs index ce7f52a..df5b331 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -160,8 +160,12 @@ impl Renderer { fn get_texture_of_part<'a>(&self, model: &'a Model, part: &Part) -> Option<&'a SrgbTexture2d> { if let Some(ref material_name) = part.material_name { if let Some(ref material) = model.materials.get(material_name) { - if let Some(ref texture) = material.rendering_texture { - Some(texture) + if let Some(texture) = material.textures.get("map_Kd") { + if let Some(ref texture) = model.get_texture_by_name(&texture) { + Some(texture) + } else { + None + } } else { None } diff --git a/src/scene.rs b/src/scene.rs index f681a51..38a9e09 100644 --- a/src/scene.rs +++ b/src/scene.rs @@ -43,3 +43,11 @@ impl IntoIterator for Scene { self.models.into_iter() } } + +impl From> for Scene { + fn from(input: Vec) -> Scene { + Scene { + models: input.into_iter().map(|x| Rc::new(RefCell::new(x))).collect(), + } + } +}