Load materials from gltf
This commit is contained in:
parent
792596078d
commit
9d6d51af83
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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>,
|
||||||
|
@ -49,3 +59,20 @@ pub struct Material {
|
||||||
|
|
||||||
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)]
|
||||||
|
|
Loading…
Reference in New Issue