feat: begin implementation of material loader
This commit is contained in:
1 parent
20c1d2c0c8
commit
363c21136d
8 files changed
+122
-11
No files matched your search
@@ -0,0 +1,16 @@
|
||||
use std::path::Path;
|
||||
use crate::loaders::material::mat_loader::{MaterialFileLoader, MaterialInfo};
|
||||
|
||||
pub struct GltfMaterialLoader;
|
||||
|
||||
impl MaterialFileLoader for GltfMaterialLoader {
|
||||
fn load_material(&self, path: &Path) -> anyhow::Result<MaterialInfo> {
|
||||
let (document, buffers, images) = gltf::import(path)?;
|
||||
|
||||
// We just want to read through the information to see what kinds of materials are available.
|
||||
// I'm not sure how gltf defines materials, especially if they're applied to specific sets
|
||||
// of vertices.
|
||||
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use thiserror::Error;
|
||||
use anyhow::Result;
|
||||
use crate::loaders::material::gltf_mat_loader::GltfMaterialLoader;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum MaterialLoaderError {
|
||||
#[error("file extension is missing")]
|
||||
MissingExtension,
|
||||
#[error("extension {0} is not supported")]
|
||||
ExtensionNotSupported(String)
|
||||
}
|
||||
|
||||
/// A material loader struct that handles multiple different file types.
|
||||
/// List of supported and planned file formats:
|
||||
/// - `.gltf`
|
||||
/// - `.mtl` (planned, not implemented)
|
||||
pub struct MaterialLoader {
|
||||
loaders: HashMap<String, Box<dyn MaterialFileLoader>>,
|
||||
}
|
||||
|
||||
impl MaterialLoader {
|
||||
/// Creates a new `MaterialLoader` struct.
|
||||
pub fn new() -> Self {
|
||||
let mut loaders = HashMap::new();
|
||||
loaders.insert("gltf".into(), Box::new(GltfMaterialLoader) as Box<dyn MaterialFileLoader>);
|
||||
|
||||
Self { loaders }
|
||||
}
|
||||
|
||||
/// Loads a material from the given path. Note that some materials are loaded through their
|
||||
/// mesh's file (GLTF embeds materials, however OBJ files have a separate .mtl file). These
|
||||
/// quirks must be handled differently. Refer to the [`MaterialLoader`] for more information
|
||||
/// on supported material files and which files to target.
|
||||
pub fn load_material<P: AsRef<Path>>(&mut self, path: P) -> Result<MaterialInfo> {
|
||||
let path = path.as_ref();
|
||||
let file_ext = path.extension().and_then(|ext| ext.to_str())
|
||||
.ok_or(MaterialLoaderError::MissingExtension)?;
|
||||
|
||||
self.loaders.get(file_ext)
|
||||
.ok_or(MaterialLoaderError::ExtensionNotSupported(file_ext.to_string()))?
|
||||
.load_material(path)
|
||||
}
|
||||
}
|
||||
|
||||
/// Contains all information required for the application to load a new material.
|
||||
pub struct MaterialInfo {
|
||||
/// The ID of this material
|
||||
pub name: String,
|
||||
/// The material uniforms. These should be defined on every imported material.
|
||||
pub uniforms: MaterialUniforms,
|
||||
/// The ID of the base color map, if any.
|
||||
pub base_color_map: Option<String>,
|
||||
/// The ID of the roughness map, if any. This is ignored for now.
|
||||
pub roughness_map: Option<String>,
|
||||
/// The ID of the normal map, if any. This is ignored for now.
|
||||
pub normal_map: Option<String>,
|
||||
}
|
||||
|
||||
/// A struct composed of the material uniforms. These uniforms will typically scale the material
|
||||
/// texture maps if there are any. Refer to [`MaterialInfo`] for more information.
|
||||
pub struct MaterialUniforms {
|
||||
/// The base color of the material. This scales the base color texture, if any.
|
||||
/// This value must be specified in normalized RGBA format (all values between 0 and 1).
|
||||
pub base_color: [f32; 4],
|
||||
/// The metalness of the material. This scales the metalness texture, if any. This value should
|
||||
/// be specified as a normalized float between 0 and 1, based on an 8-bit number space.
|
||||
///
|
||||
/// This is ignored until the shaders are updated.
|
||||
pub metalness_factor: f32,
|
||||
/// The roughness of the material. This scales the roughness texture, if any. This value should
|
||||
/// be specified as a normalized float between 0 and 1, based on an 8-bit number space.
|
||||
///
|
||||
/// This is ignored until the shaders are updated.
|
||||
pub roughness_factor: f32,
|
||||
}
|
||||
|
||||
/// A trait that must be implemented on all material loaders. Ensures consistent material
|
||||
/// import/load information.
|
||||
pub trait MaterialFileLoader {
|
||||
fn load_material(&self, path: &Path) -> anyhow::Result<MaterialInfo>;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod mat_loader;
|
||||
pub mod gltf_mat_loader;
|
||||
File renamed without changes.
@@ -1,5 +1,5 @@
|
||||
use super::gltf_loader::*;
|
||||
use crate::loaders::obj_loader::ObjLoader;
|
||||
use crate::loaders::mesh::obj_loader::ObjLoader;
|
||||
use anyhow::Result;
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
@@ -20,10 +20,6 @@ pub trait MeshFileLoader {
|
||||
fn load_mesh(&self, path: &Path) -> Result<MeshInfo>;
|
||||
}
|
||||
|
||||
pub struct MeshLoader {
|
||||
loaders: HashMap<String, Box<dyn MeshFileLoader>>,
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum MeshLoaderError {
|
||||
#[error("file extension is missing")]
|
||||
@@ -32,6 +28,14 @@ pub enum MeshLoaderError {
|
||||
ExtensionNotSupported(String),
|
||||
}
|
||||
|
||||
/// A mesh loader struct that handles multiple different file types. The list of supported and
|
||||
/// planned file formats follows:
|
||||
/// - `.gltf`
|
||||
/// - `.obj`
|
||||
pub struct MeshLoader {
|
||||
loaders: HashMap<String, Box<dyn MeshFileLoader>>,
|
||||
}
|
||||
|
||||
impl MeshLoader {
|
||||
pub fn new() -> Self {
|
||||
let mut loaders = HashMap::new();
|
||||
@@ -48,7 +52,9 @@ impl MeshLoader {
|
||||
Self { loaders }
|
||||
}
|
||||
|
||||
/// Loads a mesh and returns a `Result` containing the information.
|
||||
/// Loads a mesh from the given path. Note that materials are not automatically loaded through
|
||||
/// this function, and must be manually loaded. Refer to the [`MeshLoader`] for more information
|
||||
/// on what file types are supported.
|
||||
pub fn load_mesh<P: AsRef<Path>>(&self, path: &P) -> Result<MeshInfo> {
|
||||
let ext = path
|
||||
.as_ref()
|
||||
@@ -70,11 +76,11 @@ pub mod test_load_meshes {
|
||||
use super::*;
|
||||
|
||||
fn load_gltf(loader: &MeshLoader) -> Result<MeshInfo> {
|
||||
loader.load_mesh(&Path::new("meshes/laat_gltf/scene.gltf"))
|
||||
loader.load_mesh(&Path::new("../../../meshes/laat_gltf/scene.gltf"))
|
||||
}
|
||||
|
||||
fn load_obj(loader: &MeshLoader) -> Result<MeshInfo> {
|
||||
loader.load_mesh(&Path::new("meshes/laat_gunship/scene.obj"))
|
||||
loader.load_mesh(&Path::new("../../../meshes/laat_gunship/scene.obj"))
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -0,0 +1,3 @@
|
||||
pub mod gltf_loader;
|
||||
pub mod mesh_loader;
|
||||
mod obj_loader;
|
||||
File renamed without changes.
+4
-3
@@ -1,3 +1,4 @@
|
||||
pub mod gltf_loader;
|
||||
pub mod mesh_loader;
|
||||
mod obj_loader;
|
||||
pub mod mesh;
|
||||
pub mod material;
|
||||
|
||||
pub use mesh::*;
|
||||
Reference in new issue
Block a user