summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2025-05-24 19:40:41 +0200
committerHampusM <hampus@hampusmat.com>2025-05-24 19:41:02 +0200
commit66799c1a44d1f4871a42547f1ac3e2dde49d364c (patch)
treee9e85ceef39aad7a8a0696b598f83bc16c7c8d1e /engine
parent4ad0f20f90147b663e0b151ffcdb88ca62c60281 (diff)
refactor(engine): make mtl parser not open texture maps
Diffstat (limited to 'engine')
-rw-r--r--engine/src/file_format/wavefront/mtl.rs182
1 files changed, 95 insertions, 87 deletions
diff --git a/engine/src/file_format/wavefront/mtl.rs b/engine/src/file_format/wavefront/mtl.rs
index d90dbcf..7d1c570 100644
--- a/engine/src/file_format/wavefront/mtl.rs
+++ b/engine/src/file_format/wavefront/mtl.rs
@@ -2,7 +2,7 @@
//!
//! File format documentation: <https://paulbourke.net/dataformats/mtl>
-use std::path::Path;
+use std::path::{Path, PathBuf};
use crate::color::Color;
use crate::file_format::wavefront::common::{
@@ -11,8 +11,6 @@ use crate::file_format::wavefront::common::{
ParsingError,
Statement,
};
-use crate::material::{Builder as MaterialBuilder, Material};
-use crate::texture::{Error as TextureError, Texture};
/// Parses the content of a Wavefront `.mtl`.
///
@@ -50,18 +48,41 @@ pub fn parse(obj_content: &str) -> Result<Vec<NamedMaterial>, Error>
}
#[derive(Debug, Clone)]
+#[non_exhaustive]
pub struct NamedMaterial
{
pub name: String,
- pub material: Material,
+ pub ambient: Color<f32>,
+ pub diffuse: Color<f32>,
+ pub specular: Color<f32>,
+ pub ambient_map: Option<TextureMap>,
+ pub diffuse_map: Option<TextureMap>,
+ pub specular_map: Option<TextureMap>,
+ pub shininess: f32,
+}
+
+impl Default for NamedMaterial
+{
+ fn default() -> Self
+ {
+ Self {
+ name: String::new(),
+ ambient: Color::WHITE_F32,
+ diffuse: Color::WHITE_F32,
+ specular: Color::WHITE_F32,
+ ambient_map: None,
+ diffuse_map: None,
+ specular_map: None,
+ shininess: 0.0,
+ }
+ }
}
#[derive(Debug, Clone)]
-pub struct UnfinishedNamedMaterial
+#[non_exhaustive]
+pub struct TextureMap
{
- name: String,
- material_builder: MaterialBuilder,
- ready: bool,
+ pub path: PathBuf,
}
#[derive(Debug, thiserror::Error)]
@@ -70,8 +91,14 @@ pub enum Error
#[error(transparent)]
ParsingError(#[from] ParsingError),
- #[error("Failed to open texture")]
- TextureError(#[from] TextureError),
+ #[error(
+ "A material start statement (newmtl) is expected before statement at line {}",
+ line_no
+ )]
+ ExpectedMaterialStartStmtBeforeStmt
+ {
+ line_no: usize
+ },
#[error(
"Unsupported number of arguments ({arg_count}) to {keyword} at line {line_no}"
@@ -100,59 +127,52 @@ fn statements_to_materials(
{
let mut materials = Vec::<NamedMaterial>::with_capacity(material_cnt);
- let mut curr_material = UnfinishedNamedMaterial {
- name: String::new(),
- material_builder: MaterialBuilder::new(),
- ready: false,
- };
-
for (line_no, statement) in statements {
if statement.keyword == Keyword::Newmtl {
- if curr_material.ready {
- tracing::debug!("Building material");
-
- let material = curr_material.material_builder.clone().build();
-
- materials.push(NamedMaterial { name: curr_material.name, material });
- }
-
let name = statement.get_text_arg(0, line_no)?;
- curr_material.name = name.to_string();
- curr_material.ready = true;
+ materials.push(NamedMaterial {
+ name: name.to_string(),
+ ..Default::default()
+ });
continue;
}
- if !curr_material.ready {
- // Discard statements not belonging to a material
- continue;
+ let Some(curr_material) = materials.last_mut() else {
+ return Err(Error::ExpectedMaterialStartStmtBeforeStmt { line_no });
};
match statement.keyword {
Keyword::Ka => {
let color = get_color_from_statement(&statement, line_no)?;
- tracing::debug!("Adding ambient color");
+ tracing::debug!(
+ "Adding ambient color {color:?} to material {}",
+ curr_material.name
+ );
- curr_material.material_builder =
- curr_material.material_builder.ambient(color);
+ curr_material.ambient = color;
}
Keyword::Kd => {
let color = get_color_from_statement(&statement, line_no)?;
- tracing::debug!("Adding diffuse color");
+ tracing::debug!(
+ "Adding diffuse color {color:?} to material {}",
+ curr_material.name
+ );
- curr_material.material_builder =
- curr_material.material_builder.diffuse(color);
+ curr_material.diffuse = color;
}
Keyword::Ks => {
let color = get_color_from_statement(&statement, line_no)?;
- tracing::debug!("Adding specular color");
+ tracing::debug!(
+ "Adding specular color {color:?} to material {}",
+ curr_material.name
+ );
- curr_material.material_builder =
- curr_material.material_builder.specular(color);
+ curr_material.specular = color;
}
Keyword::MapKa => {
if statement.arguments.len() > 1 {
@@ -165,53 +185,59 @@ fn statements_to_materials(
let texture_file_path = statement.get_text_arg(0, line_no)?;
- let texture = Texture::open(Path::new(texture_file_path))?;
+ tracing::debug!(
+ "Adding ambient map {texture_file_path} to material {}",
+ curr_material.name
+ );
- tracing::debug!("Adding ambient map");
-
- let texture_id = texture.id();
-
- curr_material.material_builder = curr_material
- .material_builder
- .texture(texture)
- .ambient_map(texture_id);
+ curr_material.ambient_map = Some(TextureMap {
+ path: Path::new(texture_file_path).to_path_buf(),
+ });
}
Keyword::MapKd => {
- let texture = get_map_from_texture(&statement, line_no)?;
+ if statement.arguments.len() > 1 {
+ return Err(Error::UnsupportedArgumentCount {
+ keyword: statement.keyword.to_string(),
+ arg_count: statement.arguments.len(),
+ line_no,
+ });
+ }
- tracing::debug!("Adding diffuse map");
+ let texture_file_path = statement.get_text_arg(0, line_no)?;
- let texture_id = texture.id();
+ tracing::debug!(
+ "Adding diffuse map {texture_file_path} to material {}",
+ curr_material.name
+ );
- curr_material.material_builder = curr_material
- .material_builder
- .texture(texture)
- .diffuse_map(texture_id);
+ curr_material.diffuse_map = Some(TextureMap {
+ path: Path::new(texture_file_path).to_path_buf(),
+ });
}
Keyword::MapKs => {
- let texture = get_map_from_texture(&statement, line_no)?;
+ if statement.arguments.len() > 1 {
+ return Err(Error::UnsupportedArgumentCount {
+ keyword: statement.keyword.to_string(),
+ arg_count: statement.arguments.len(),
+ line_no,
+ });
+ }
- tracing::debug!("Adding specular map");
+ let texture_file_path = statement.get_text_arg(0, line_no)?;
- let texture_id = texture.id();
+ tracing::debug!(
+ "Adding specular map {texture_file_path} to material {}",
+ curr_material.name
+ );
- curr_material.material_builder = curr_material
- .material_builder
- .texture(texture)
- .specular_map(texture_id);
+ curr_material.specular_map = Some(TextureMap {
+ path: Path::new(texture_file_path).to_path_buf(),
+ });
}
Keyword::Newmtl => {}
}
}
- if curr_material.ready {
- tracing::debug!("Building last material");
-
- let material = curr_material.material_builder.build();
-
- materials.push(NamedMaterial { name: curr_material.name, material });
- }
-
Ok(materials)
}
@@ -235,24 +261,6 @@ fn get_color_from_statement(
Ok(Color { red, green, blue })
}
-fn get_map_from_texture(
- statement: &Statement<Keyword>,
- line_no: usize,
-) -> Result<Texture, Error>
-{
- if statement.arguments.len() > 1 {
- return Err(Error::UnsupportedArgumentCount {
- keyword: statement.keyword.to_string(),
- arg_count: statement.arguments.len(),
- line_no,
- });
- }
-
- let texture_file_path = statement.get_text_arg(0, line_no)?;
-
- Ok(Texture::open(Path::new(texture_file_path))?)
-}
-
keyword! {
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum Keyword {