diff --git a/Cargo.lock b/Cargo.lock index 1aa29ba..4162686 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,9 +90,9 @@ checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "approx" @@ -117,7 +117,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -192,7 +192,7 @@ dependencies = [ "num-traits", "pastey", "rayon", - "thiserror 2.0.18", + "thiserror 2.0.19", "v_frame", "y4m", ] @@ -285,7 +285,7 @@ checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -377,7 +377,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" dependencies = [ - "thiserror 2.0.18", + "thiserror 2.0.19", ] [[package]] @@ -587,7 +587,7 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -638,7 +638,7 @@ checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -690,7 +690,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1019,7 +1019,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1268,7 +1268,7 @@ checksum = "973e7178a678cfd059ccec50887658d482ce16b0aa9da3888ddeab5cd5eb4889" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1359,7 +1359,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1410,7 +1410,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1754,7 +1754,7 @@ checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1831,7 +1831,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.117", ] [[package]] @@ -1868,7 +1868,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" dependencies = [ "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1981,7 +1981,7 @@ dependencies = [ "rand", "rand_chacha", "simd_helpers", - "thiserror 2.0.18", + "thiserror 2.0.19", "v_frame", "wasm-bindgen", ] @@ -2204,7 +2204,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2359,6 +2359,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -2370,11 +2381,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.19", ] [[package]] @@ -2385,18 +2396,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -2601,7 +2612,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2615,7 +2626,7 @@ dependencies = [ "proc-macro2", "quote", "shaderc", - "syn", + "syn 2.0.117", "vulkano", ] @@ -2623,11 +2634,14 @@ dependencies = [ name = "vulkano-test" version = "0.1.0" dependencies = [ + "anyhow", "image", + "log", "nalgebra", "postcard", "serde", "serde_json", + "thiserror 2.0.19", "uuid", "vulkano", "vulkano-shaders", @@ -2709,7 +2723,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wasm-bindgen-shared", ] @@ -3173,7 +3187,7 @@ dependencies = [ "heck 0.5.0", "indexmap", "prettyplease", - "syn", + "syn 2.0.117", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -3189,7 +3203,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -3323,7 +3337,7 @@ checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 947e6a0..185a3fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,6 @@ nalgebra = "*" uuid = { version = "1.23.1", features = ["v4"] } postcard = { version = "1.1", features = ["alloc"] } serde_json = "1.0.149" +anyhow = "1.0.104" +thiserror = "2.0.19" +log = "0.4.29" diff --git a/src/common/instance.rs b/src/common/instance.rs index e161182..523d998 100644 --- a/src/common/instance.rs +++ b/src/common/instance.rs @@ -5,7 +5,7 @@ use nalgebra::{Matrix4, Vector3, Vector4}; /// Contains all information about an instance of a mesh, specifically its translation, rotation, /// and scale. Note that the rotation is a [`Vector4`], and not a `Quaternion`. /// -/// This may be taken from a scene instance by calling the `Instance::from` method on the +/// This may be taken from a scene instance by calling the [`MeshInstance::from`] method on the /// corresponding [`SceneInstance`]. This is important, as the `Vector4` is not serializable. /// /// Before passing this instance into the shaders, construct a transformation matrix by calling diff --git a/src/common/mesh.rs b/src/common/mesh.rs index 43886b1..f2c5157 100644 --- a/src/common/mesh.rs +++ b/src/common/mesh.rs @@ -5,6 +5,7 @@ use std::sync::Arc; use vulkano::buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer}; use vulkano::memory::allocator::{AllocationCreateInfo, MemoryAllocator, MemoryTypeFilter}; use wavefront::Obj; +use crate::loaders::mesh_loader::{MeshInfo, MeshLoader}; /// This struct is slightly misleading - it doesn't actually contain the mesh information, but /// the locations of the mesh's information in the overall application's vertex buffer, index buffer, @@ -47,16 +48,18 @@ impl MeshRegistry { pub fn from_scene(scene: &Scene, allocator: Arc) -> Self { // Load all the meshes into a single map. println!("Loading meshes from scene"); + + let mesh_loader = MeshLoader::new(); let meshes = scene .mesh_paths .iter() .map(|(id, path)| { ( id.clone(), - Obj::from_file(path).expect("Couldn't read wavefront file"), + mesh_loader.load_mesh(path).expect("Couldn't read wavefront file"), ) }) - .collect::>(); + .collect::>(); let mut buf_verts = Vec::new(); let mut buf_indices = Vec::new(); @@ -65,27 +68,18 @@ impl MeshRegistry { // Information will be added directly to the verts and indices vectors, and a new Mesh // struct will be created and inserted into the mesh_list. let vert_start = buf_verts.len(); - let all_verts = obj.positions(); - let all_norms = obj.normals(); + let all_verts = obj.vertices; + let all_norms = obj.normals; let obj_num_verts = all_verts.len(); all_verts.iter().zip(all_norms.iter()) - .zip(obj.uvs().iter()) + .zip(obj.uvs.iter()) .for_each(|((pos, norm), uv)| { buf_verts.push(Vertex3::new(*pos, *norm, *uv)); }); - // buf_verts.extend(all_verts.map(|v| Vertex3::new(v.position(), v.normal().unwrap_or_default()))); - let index_list = obj - .triangles() - .flat_map(|t| { - t.iter() - .map(|i| i.position_index() as u32) - .collect::>() - }) - .collect::>(); let index_start = buf_indices.len(); - let obj_num_idx = index_list.len(); - buf_indices.extend(index_list); + let obj_num_idx = obj.indices.len(); + buf_indices.extend(obj.indices); println!("Loaded mesh {} with {} vertices and {} indices", id, obj_num_verts, obj_num_idx); diff --git a/src/loaders/gltf_loader.rs b/src/loaders/gltf_loader.rs new file mode 100644 index 0000000..d473502 --- /dev/null +++ b/src/loaders/gltf_loader.rs @@ -0,0 +1,11 @@ +use std::path::Path; +use anyhow::Result; +use crate::loaders::mesh_loader::{MeshFileLoader, MeshInfo}; + +pub struct GltfLoader; + +impl MeshFileLoader for GltfLoader { + fn load_mesh(&self, path: &Path) -> Result { + todo!() + } +} \ No newline at end of file diff --git a/src/loaders/mesh_loader.rs b/src/loaders/mesh_loader.rs new file mode 100644 index 0000000..9986ca6 --- /dev/null +++ b/src/loaders/mesh_loader.rs @@ -0,0 +1,54 @@ +use std::collections::HashMap; +use std::path::Path; +use anyhow::Result; +use thiserror::Error; +use crate::loaders::obj_loader::ObjLoader; +use super::gltf_loader::*; + +pub struct MeshInfo { + pub vertices: Vec<[f32; 3]>, + pub normals: Vec<[f32; 3]>, + pub indices: Vec, + pub uvs: Vec<[f32; 3]>, +} + +pub trait MeshFileLoader { + fn load_mesh(&self, path: &Path) -> Result; +} + +pub struct MeshLoader { + loaders: HashMap> +} + +#[derive(Error, Debug)] +pub enum MeshLoaderError { + #[error("file extension is missing")] + MissingExtension, + #[error("extension {0} is not supported")] + ExtensionNotSupported(String) +} + +impl MeshLoader { + pub fn new() -> Self { + let mut loaders = HashMap::new(); + loaders.insert("gltf".into(), Box::new(GltfLoader) as Box); + loaders.insert("obj".into(), Box::new(ObjLoader)); + + Self { + loaders + } + } + + /// Loads a mesh and returns a `Result` containing the information. + pub fn load_mesh>(&self, path: &P) -> Result { + let ext = path.as_ref().extension() + .and_then(|ext| ext.to_str()) + .ok_or(MeshLoaderError::MissingExtension)?; + + println!("Found extension {}, continuing with loading", ext); + + self.loaders.get(ext) + .ok_or(MeshLoaderError::ExtensionNotSupported(ext.to_string()))? + .load_mesh(path.as_ref()) + } +} diff --git a/src/loaders/mod.rs b/src/loaders/mod.rs new file mode 100644 index 0000000..5d9dca3 --- /dev/null +++ b/src/loaders/mod.rs @@ -0,0 +1,3 @@ +pub mod gltf_loader; +pub mod mesh_loader; +mod obj_loader; \ No newline at end of file diff --git a/src/loaders/obj_loader.rs b/src/loaders/obj_loader.rs new file mode 100644 index 0000000..ad4ab6a --- /dev/null +++ b/src/loaders/obj_loader.rs @@ -0,0 +1,29 @@ +use std::path::Path; +use wavefront::Obj; +use crate::gpu::vertex3::Vertex3; +use crate::loaders::mesh_loader::{MeshFileLoader, MeshInfo}; + +pub struct ObjLoader; + +impl MeshFileLoader for ObjLoader { + fn load_mesh(&self, path: &Path) -> anyhow::Result { + let obj_info = Obj::from_file(path) + .expect("Couldn't read wavefront file"); + + let index_list = obj_info + .triangles() + .flat_map(|t| { + t.iter() + .map(|i| i.position_index() as u32) + .collect::>() + }) + .collect::>(); + + Ok(MeshInfo { + vertices: obj_info.positions().to_vec(), + normals: obj_info.normals().to_vec(), + indices: index_list, + uvs: obj_info.uvs().to_vec() + }) + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 62a8170..9adabb6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ mod app; mod common; pub mod gpu; +pub mod loaders; // pub mod math; use crate::app::App;