diff --git a/Cargo.lock b/Cargo.lock index 6a9a1e0..dc26dde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -94,15 +94,6 @@ version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" -[[package]] -name = "approx" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" -dependencies = [ - "num-traits", -] - [[package]] name = "approx" version = "0.5.1" @@ -235,12 +226,6 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - [[package]] name = "bit_field" version = "0.10.3" @@ -383,16 +368,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" -[[package]] -name = "cgmath" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317" -dependencies = [ - "approx 0.4.0", - "num-traits", -] - [[package]] name = "cmake" version = "0.1.57" @@ -583,18 +558,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" -[[package]] -name = "easy-gltf" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1203d5e3b06d11431cd680b7d89fe3565ea797e948a3869aa791f10855b02175" -dependencies = [ - "base64 0.22.1", - "cgmath", - "gltf", - "image", -] - [[package]] name = "either" version = "1.15.0" @@ -925,7 +888,7 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3ce1918195723ce6ac74e80542c5a96a40c2b26162c1957a5cd70799b8cacf7" dependencies = [ - "base64 0.13.1", + "base64", "byteorder", "gltf-json", "image", @@ -1326,7 +1289,7 @@ version = "0.34.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df76ea0ff5c7e6b88689085804d6132ded0ddb9de5ca5b8aeb9eeadc0508a70a" dependencies = [ - "approx 0.5.1", + "approx", "glam 0.14.0", "glam 0.15.2", "glam 0.16.0", @@ -2347,7 +2310,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c99284beb21666094ba2b75bbceda012e610f5479dfcc2d6e2426f53197ffd95" dependencies = [ - "approx 0.5.1", + "approx", "num-complex", "num-traits", "paste", @@ -2735,7 +2698,7 @@ name = "vulkano-test" version = "0.1.0" dependencies = [ "anyhow", - "easy-gltf", + "gltf", "image", "log", "nalgebra", diff --git a/Cargo.toml b/Cargo.toml index 19b1ced..716a386 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,4 +17,4 @@ serde_json = "1.0.149" anyhow = "1.0.104" thiserror = "2.0.19" log = "0.4.29" -easy-gltf = "1.1.5" +gltf = "1.4.1" diff --git a/src/common/material.rs b/src/common/material.rs new file mode 100644 index 0000000..70ad37c --- /dev/null +++ b/src/common/material.rs @@ -0,0 +1,36 @@ +use std::collections::HashMap; + +pub struct MaterialRegistry { + materials: HashMap +} + +impl MaterialRegistry { + pub fn new() -> Self { + Self { + materials: HashMap::new() + } + } + + pub fn register(&mut self, id: String, material: Material) { + self.materials.insert(id, material); + } + + pub fn get(&self, id: &String) -> Option<&Material> { + self.materials.get(id) + } +} + +/// Encapsulates all the information that makes up a PBR (physically based rendering) material. +/// These materials should be stored in a [`MaterialRegistry`], with a unique key. +pub struct Material { + /// The base color of the material. + pub base_color: [f32; 4], + /// The metallic value of the material. This should be a number between 0 and 1. + pub metallic: f32, + /// The roughness value of the material. This should be a number between 0 and 1. + pub roughness: f32, + /// The path of the normal map for this material, if any. + pub normal_map: Option, + /// The path of the base color's texture, if any. + pub base_color_texture: Option, +} diff --git a/src/common/mod.rs b/src/common/mod.rs index 13957ac..439b6b2 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -3,3 +3,4 @@ pub mod mesh; pub mod scene; pub mod render_batch; pub mod camera; +mod material; diff --git a/src/loaders/gltf_loader.rs b/src/loaders/gltf_loader.rs index 1d87c8a..9354bc1 100644 --- a/src/loaders/gltf_loader.rs +++ b/src/loaders/gltf_loader.rs @@ -1,40 +1,50 @@ use std::path::Path; -use anyhow::{anyhow, Result}; +use anyhow::Result; use crate::loaders::mesh_loader::{MeshFileLoader, MeshInfo}; pub struct GltfLoader; impl MeshFileLoader for GltfLoader { fn load_mesh(&self, path: &Path) -> Result { - let scenes = easy_gltf::load(path) - .map_err(|e| anyhow!("could not load gltf file: {e}"))?; - - println!("Found {} scene(s) in gltf file", scenes.len()); - - let scene = scenes.first() - .ok_or(anyhow!("no scenes in gltf file"))?; - - println!("Found {} model(s) in gltf file", scene.models.len()); + let (document, buffers, _) = gltf::import(path)?; let mut vertices = Vec::new(); let mut normals = Vec::new(); let mut uvs = Vec::new(); let mut indices = Vec::::new(); - for model in &scene.models { - // Indices must be offset by the number of vertices that are already registered. - let idx_offset = vertices.len() as u32; - // Put all vertex info together for a MeshInfo struct - for vertex in model.vertices() { - vertices.push(*vertex.position.as_ref()); - normals.push(*vertex.normal.as_ref()); - uvs.push([vertex.tex_coords.x, vertex.tex_coords.y, 0.0]); + for mesh in document.meshes() { + for primitive in mesh.primitives() { + // Read the primitives as vertices and indices, + // and register a material for the primitive as well + let vert_offset = vertices.len() as u32; + + let reader = primitive.reader(|buffer_index| Some(&buffers[buffer_index.index()])); + + if let Some(positions) = reader.read_positions() { + for position in positions { + vertices.push(position); + } + } + + if let Some(normals_iter) = reader.read_normals() { + for normal in normals_iter { + normals.push(normal); + } + } + + if let Some(tex_coords) = reader.read_tex_coords(0) { + for uv in tex_coords.into_f32() { + uvs.push([uv[0], uv[1], 0.0]); + } + } + + if let Some(indices_iter) = reader.read_indices() { + for index in indices_iter.into_u32() { + indices.push(index + vert_offset); + } + } } - model.indices() - .expect("failed to find indices") - .iter() - .map(|i| i + idx_offset) - .for_each(|i| indices.push(i)); } Ok(MeshInfo { diff --git a/test_scene.scene b/test_scene.scene index e93c0a6..0598906 100644 --- a/test_scene.scene +++ b/test_scene.scene @@ -17,9 +17,9 @@ 0.0 ], "scale": [ - 20.0, - 20.0, - 20.0 + 1.0, + 1.0, + 1.0 ] } }