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 super::gltf_loader::*;
|
||||||
use crate::loaders::obj_loader::ObjLoader;
|
use crate::loaders::mesh::obj_loader::ObjLoader;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
@@ -20,10 +20,6 @@ pub trait MeshFileLoader {
|
|||||||
fn load_mesh(&self, path: &Path) -> Result<MeshInfo>;
|
fn load_mesh(&self, path: &Path) -> Result<MeshInfo>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MeshLoader {
|
|
||||||
loaders: HashMap<String, Box<dyn MeshFileLoader>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum MeshLoaderError {
|
pub enum MeshLoaderError {
|
||||||
#[error("file extension is missing")]
|
#[error("file extension is missing")]
|
||||||
@@ -32,6 +28,14 @@ pub enum MeshLoaderError {
|
|||||||
ExtensionNotSupported(String),
|
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 {
|
impl MeshLoader {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let mut loaders = HashMap::new();
|
let mut loaders = HashMap::new();
|
||||||
@@ -48,7 +52,9 @@ impl MeshLoader {
|
|||||||
Self { loaders }
|
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> {
|
pub fn load_mesh<P: AsRef<Path>>(&self, path: &P) -> Result<MeshInfo> {
|
||||||
let ext = path
|
let ext = path
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -70,11 +76,11 @@ pub mod test_load_meshes {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
fn load_gltf(loader: &MeshLoader) -> Result<MeshInfo> {
|
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> {
|
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]
|
#[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;
|
||||||
pub mod mesh_loader;
|
pub mod material;
|
||||||
mod obj_loader;
|
|
||||||
|
pub use mesh::*;
|
||||||
Reference in new issue
Block a user