From 38e7b543c0ee6d44f921c416d8c7895ec7f5aff0 Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Thu, 21 Sep 2023 14:22:46 -0400 Subject: [PATCH] Start working on gltf --- Cargo.lock | 85 +++++++++++++++++++++++++++ lyra-resource/Cargo.toml | 1 + lyra-resource/src/lib.rs | 3 + lyra-resource/src/loader/mod.rs | 35 +++++++++-- lyra-resource/src/loader/model.rs | 29 +++++++++ lyra-resource/src/loader/texture.rs | 24 +------- lyra-resource/src/model.rs | 18 ++++++ lyra-resource/src/resource_manager.rs | 2 +- 8 files changed, 170 insertions(+), 27 deletions(-) create mode 100644 lyra-resource/src/loader/model.rs create mode 100644 lyra-resource/src/model.rs diff --git a/Cargo.lock b/Cargo.lock index 8b637df..6a482f6 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -297,6 +297,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "bit-set" version = "0.5.3" @@ -890,6 +896,44 @@ dependencies = [ "web-sys", ] +[[package]] +name = "gltf" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad2dcfb6dd7a66f9eb3d181a29dcfb22d146b0bcdc2e1ed1713cbf03939a88ea" +dependencies = [ + "base64", + "byteorder", + "gltf-json", + "image", + "lazy_static", + "urlencoding", +] + +[[package]] +name = "gltf-derive" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cbcea5dd47e7ad4e9ee6f040384fcd7204bbf671aa4f9e7ca7dfc9bfa1de20" +dependencies = [ + "inflections", + "proc-macro2", + "quote", + "syn 2.0.26", +] + +[[package]] +name = "gltf-json" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5b810806b78dde4b71a95cc0e6fdcab34c4c617da3574df166f9987be97d03" +dependencies = [ + "gltf-derive", + "serde", + "serde_derive", + "serde_json", +] + [[package]] name = "gpu-alloc" version = "0.5.4" @@ -1041,6 +1085,12 @@ dependencies = [ "hashbrown 0.14.0", ] +[[package]] +name = "inflections" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" + [[package]] name = "instant" version = "0.1.12" @@ -1241,6 +1291,7 @@ name = "lyra-resource" version = "0.0.1" dependencies = [ "anyhow", + "gltf", "image", "thiserror", "uuid", @@ -1963,6 +2014,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + [[package]] name = "scoped-tls" version = "1.0.1" @@ -1994,6 +2051,28 @@ version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31" +[[package]] +name = "serde_derive" +version = "1.0.179" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "741e124f5485c7e60c03b043f79f320bff3527f4bbf12cf3831750dc46a0ec2c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.26", +] + +[[package]] +name = "serde_json" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "sharded-slab" version = "0.1.4" @@ -2371,6 +2450,12 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "uuid" version = "1.4.1" diff --git a/lyra-resource/Cargo.toml b/lyra-resource/Cargo.toml index 0207327..6166616 100644 --- a/lyra-resource/Cargo.toml +++ b/lyra-resource/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0.75" +gltf = "1.3.0" image = "0.24.7" thiserror = "1.0.48" uuid = { version = "1.4.1", features = ["v4"] } diff --git a/lyra-resource/src/lib.rs b/lyra-resource/src/lib.rs index 347aa03..d1a4deb 100644 --- a/lyra-resource/src/lib.rs +++ b/lyra-resource/src/lib.rs @@ -9,3 +9,6 @@ pub use texture::*; pub mod loader; pub use loader::*; + +pub mod model; +pub use model::*; diff --git a/lyra-resource/src/loader/mod.rs b/lyra-resource/src/loader/mod.rs index 78e5e23..fb0b7eb 100644 --- a/lyra-resource/src/loader/mod.rs +++ b/lyra-resource/src/loader/mod.rs @@ -1,6 +1,7 @@ pub mod texture; +pub mod model; -use std::{io, sync::Arc, fs::File}; +use std::{io, sync::Arc, fs::File, path::Path, ffi::OsStr}; use thiserror::Error; @@ -15,7 +16,7 @@ pub enum LoaderError { UnsupportedExtension(String), #[error("IOError: '{0}'")] - IOError(io::Error), + IoError(io::Error), // From is implemented for this field in each loader module #[error("Decoding error: '{0}'")] @@ -24,12 +25,38 @@ pub enum LoaderError { impl From for LoaderError { fn from(value: io::Error) -> Self { - LoaderError::IOError(value) + LoaderError::IoError(value) } } pub trait ResourceLoader: Send + Sync { fn extensions(&self) -> &[&str]; - fn does_support_file(&self, path: &str) -> bool; + + fn does_support_file(&self, path: &str) -> bool { + match Path::new(path).extension().and_then(OsStr::to_str) { + Some(ext) => { + self.extensions().contains(&ext) + }, + _ => false, + } + } + fn load(&self, path: &str) -> Result, LoaderError>; +} + + +#[cfg(test)] +mod tests { + use super::{*, texture::TextureLoader}; + + /// Ensure that `does_support_file` works + #[test] + fn check_support() { + let loader = TextureLoader::default(); + let extensions = loader.extensions(); + let fake_paths: Vec = extensions.iter().map(|e| format!("a.{}", e)).collect(); + for path in fake_paths.iter() { + assert!(loader.does_support_file(&path)); + } + } } \ No newline at end of file diff --git a/lyra-resource/src/loader/model.rs b/lyra-resource/src/loader/model.rs new file mode 100644 index 0000000..83197fc --- /dev/null +++ b/lyra-resource/src/loader/model.rs @@ -0,0 +1,29 @@ +use crate::{ResourceLoader, LoaderError}; + +impl From for LoaderError { + fn from(value: gltf::Error) -> Self { + LoaderError::DecodingError(value.into()) + } +} + +#[derive(Default)] +pub struct ModelLoader; + +impl ResourceLoader for ModelLoader { + fn extensions(&self) -> &[&str] { + &[ + "gltf" + ] + } + + fn load(&self, path: &str) -> Result, crate::LoaderError> { + // check if the file is supported by this loader + if !self.does_support_file(path) { + return Err(LoaderError::UnsupportedExtension(path.to_string())); + } + + let gltf = gltf::Gltf::open(path)?; + + todo!() + } +} \ No newline at end of file diff --git a/lyra-resource/src/loader/texture.rs b/lyra-resource/src/loader/texture.rs index c781ffa..c77ed80 100644 --- a/lyra-resource/src/loader/texture.rs +++ b/lyra-resource/src/loader/texture.rs @@ -8,7 +8,7 @@ use super::{LoaderError, ResourceLoader}; impl From for LoaderError { fn from(value: ImageError) -> Self { - LoaderError::DecodingError(anyhow::Error::from(value)) + LoaderError::DecodingError(value.into()) } } @@ -30,15 +30,6 @@ impl ResourceLoader for TextureLoader { ] } - fn does_support_file(&self, path: &str) -> bool { - match Path::new(path).extension().and_then(OsStr::to_str) { - Some(ext) => { - self.extensions().contains(&ext) - }, - _ => false, - } - } - fn load(&self, path: &str) -> Result, LoaderError> { // check if the file is supported by this loader if !self.does_support_file(path) { @@ -53,7 +44,7 @@ impl ResourceLoader for TextureLoader { // load the image and construct Resource let image = image::load_from_memory(&buf) .map_err(|e| match e { - ImageError::IoError(e) => LoaderError::IOError(e), + ImageError::IoError(e) => LoaderError::IoError(e), _ => LoaderError::DecodingError(e.into()), })?; let texture = Texture { @@ -75,17 +66,6 @@ mod tests { format!("{manifest}/test_files/img/{path}") } - /// Ensure that `does_support_file` works - #[test] - fn check_support() { - let loader = TextureLoader::default(); - let extensions = loader.extensions(); - let fake_paths: Vec = extensions.iter().map(|e| format!("a.{}", e)).collect(); - for path in fake_paths.iter() { - assert!(loader.does_support_file(&path)); - } - } - #[test] fn check_unsupport() { let loader = TextureLoader::default(); diff --git a/lyra-resource/src/model.rs b/lyra-resource/src/model.rs new file mode 100644 index 0000000..f8c0344 --- /dev/null +++ b/lyra-resource/src/model.rs @@ -0,0 +1,18 @@ + +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct Vertex { + pub position: [f32; 3], + pub tex_coords: [f32; 2] +} + +#[derive(Clone)] +pub struct Mesh { + pub vertices: Vec, + pub indices: Option>, +} + +pub struct Model { + pub mesh: Mesh, + //pub material +} \ No newline at end of file diff --git a/lyra-resource/src/resource_manager.rs b/lyra-resource/src/resource_manager.rs index 09b699e..03853d5 100644 --- a/lyra-resource/src/resource_manager.rs +++ b/lyra-resource/src/resource_manager.rs @@ -125,7 +125,7 @@ mod tests { assert!( match err { // make sure the error is NotFound - RequestError::Loader(LoaderError::IOError(e)) if e.kind() == io::ErrorKind::NotFound => true, + RequestError::Loader(LoaderError::IoError(e)) if e.kind() == io::ErrorKind::NotFound => true, _ => false } );