Load materials from gltf

This commit is contained in:
SeanOMik 2023-09-29 14:20:28 -04:00
parent 792596078d
commit 9d6d51af83
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
3 changed files with 41 additions and 12 deletions

View File

@ -2,7 +2,7 @@ use std::sync::Arc;
use base64::Engine; use base64::Engine;
use crate::{ResourceLoader, LoaderError, Mesh, Model, MeshVertexAttribute, VertexAttributeData, Resource, Material, PbrRoughness}; use crate::{ResourceLoader, LoaderError, Mesh, Model, MeshVertexAttribute, VertexAttributeData, Resource, Material, ResHandle};
impl From<gltf::Error> for LoaderError { impl From<gltf::Error> for LoaderError {
fn from(value: gltf::Error) -> Self { fn from(value: gltf::Error) -> Self {
@ -73,7 +73,9 @@ impl ModelLoader {
new_mesh.indices = Some(indices); new_mesh.indices = Some(indices);
} }
prim.material(). let mat = materials.get(prim.material().index().unwrap()).unwrap();
new_mesh.set_material(mat.clone());
//prim.material().
meshes.push(new_mesh); meshes.push(new_mesh);
} }
@ -113,13 +115,7 @@ impl ResourceLoader for ModelLoader {
// Load the materials // Load the materials
let materials: Vec<Material> = gltf.materials() let materials: Vec<Material> = gltf.materials()
.map(|mat| Material { .map(|mat| Material::from(mat)).collect();
double_sided: mat.double_sided(),
name: mat.name().map(|s| s.to_string()),
shader_uuid: None,
pbr: Some(PbrRoughness::from(mat.pbr_metallic_roughness())),
texture: None
}).collect();
let meshes: Vec<Mesh> = scene.nodes() let meshes: Vec<Mesh> = scene.nodes()
.map(|node| self.process_node(&buffers, &materials, node)) .map(|node| self.process_node(&buffers, &materials, node))
@ -146,12 +142,14 @@ mod tests {
let loader = ModelLoader::default(); let loader = ModelLoader::default();
let model = loader.load(&path).unwrap(); let model = loader.load(&path).unwrap();
let model = Arc::downcast::<Model>(model.as_arc_any()).unwrap(); let model = Arc::downcast::<Resource<Model>>(model.as_arc_any()).unwrap();
let model = model.data.as_ref().unwrap();
assert_eq!(model.meshes.len(), 1); // There should only be 1 mesh assert_eq!(model.meshes.len(), 1); // There should only be 1 mesh
let mesh = &model.meshes[0]; let mesh = &model.meshes[0];
assert!(mesh.position().unwrap().len() > 0); assert!(mesh.position().unwrap().len() > 0);
assert!(mesh.normals().unwrap().len() > 0); assert!(mesh.normals().unwrap().len() > 0);
assert!(mesh.tex_coords().unwrap().len() > 0); assert!(mesh.tex_coords().unwrap().len() > 0);
assert!(mesh.indices.clone().unwrap().len() > 0); assert!(mesh.indices.clone().unwrap().len() > 0);
let _mesh_mat = mesh.material(); // inner panic if material was not loaded
} }
} }

View File

@ -37,6 +37,16 @@ pub struct PbrGlossiness {
// pub glossiness_texture // TODO // pub glossiness_texture // TODO
} }
impl From<gltf::material::PbrSpecularGlossiness<'_>> for PbrGlossiness {
fn from(value: gltf::material::PbrSpecularGlossiness) -> Self {
PbrGlossiness {
diffuse_color: value.diffuse_factor(),
specular: value.specular_factor(),
glossiness: value.glossiness_factor()
}
}
}
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub struct Material { pub struct Material {
pub shader_uuid: Option<u64>, pub shader_uuid: Option<u64>,
@ -48,4 +58,21 @@ pub struct Material {
pub alpha_mode: gltf::material::AlphaMode, pub alpha_mode: gltf::material::AlphaMode,
pub texture: Option<ResHandle<Texture>>, pub texture: Option<ResHandle<Texture>>,
}
impl From<gltf::Material<'_>> for Material {
fn from(value: gltf::Material) -> Self {
Material {
name: value.name()
.map(|s| s.to_string()),
double_sided: value.double_sided(),
pbr_roughness: value.pbr_metallic_roughness().into(),
pbr_glossiness: value.pbr_specular_glossiness()
.map(|o| o.into()),
alpha_cutoff: value.alpha_cutoff(),
alpha_mode: value.alpha_mode(),
shader_uuid: None,
texture: None,
}
}
} }

View File

@ -46,7 +46,7 @@ pub enum MeshVertexAttribute {
pub struct Mesh { pub struct Mesh {
pub attributes: HashMap<MeshVertexAttribute, VertexAttributeData>, pub attributes: HashMap<MeshVertexAttribute, VertexAttributeData>,
pub indices: Option<Vec<u32>>, pub indices: Option<Vec<u32>>,
material: Option<ResHandle<Material>>, material: Option<Material>,
} }
impl Mesh { impl Mesh {
@ -76,9 +76,13 @@ impl Mesh {
.map(|p| p.as_vec2()) .map(|p| p.as_vec2())
} }
pub fn material(&self) -> ResHandle<Material> { pub fn material(&self) -> Material {
self.material.clone().expect("This mesh is missing a material!") self.material.clone().expect("This mesh is missing a material!")
} }
pub fn set_material(&mut self, val: Material) {
self.material = Some(val);
}
} }
#[derive(Clone, Default)] #[derive(Clone, Default)]