From 36c3860ddf47c1c7c2ccad43512091d20f5a2dff Mon Sep 17 00:00:00 2001 From: HampusM Date: Mon, 28 Sep 2026 22:58:05 +0200 Subject: refactor(engine): make model & material assets use asset dependencies --- engine/src/material.rs | 99 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 7 deletions(-) (limited to 'engine/src/material.rs') diff --git a/engine/src/material.rs b/engine/src/material.rs index 5f77950..ae0751b 100644 --- a/engine/src/material.rs +++ b/engine/src/material.rs @@ -1,4 +1,14 @@ -use crate::asset::{Asset, Handle as AssetHandle}; +use ecs::sole::Single; + +use crate::asset::{ + Asset, + Assets, + Dependency as AssetDependency, + Event as AssetEvent, + Events as AssetEvents, + Handle as AssetHandle, + Label as AssetLabel, +}; use crate::builder; use crate::color::{Color, Rgb}; use crate::ecs::Component; @@ -18,6 +28,7 @@ pub struct Material pub diffuse_map: Option>, pub specular_map: Option>, pub shininess: f32, + pub loading_textures: Vec<(LoadingTextureName, AssetLabel<'static>)>, } impl Material @@ -46,12 +57,26 @@ impl Default for Material impl Asset for Material { - fn dependencies(&self) -> impl Iterator> + fn dependencies(&self) -> impl Iterator> { - [].into_iter() + self.loading_textures.iter().map(|(_, texture_label)| { + AssetDependency::new::(AssetLabel { + path: (&*texture_label.path).into(), + name: texture_label.name.as_deref().map(Into::into), + }) + }) } } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[non_exhaustive] +pub enum LoadingTextureName +{ + AmbientMap, + DiffuseMap, + SpecularMap, +} + /// [`Material`] builder. #[derive(Debug, Clone)] pub struct Builder @@ -63,6 +88,7 @@ pub struct Builder diffuse_map: Option>, specular_map: Option>, shininess: f32, + loading_textures: Vec<(LoadingTextureName, AssetLabel<'static>)>, } impl Builder @@ -78,6 +104,7 @@ impl Builder diffuse_map: None, specular_map: None, shininess: 32.0, + loading_textures: Vec::with_capacity(3), } } @@ -129,6 +156,17 @@ impl Builder self } + #[must_use] + pub fn loading_texture( + mut self, + name: LoadingTextureName, + asset_label: AssetLabel<'static>, + ) -> Self + { + self.loading_textures.push((name, asset_label)); + self + } + #[must_use] pub fn shininess(mut self, shininess: f32) -> Self { @@ -138,11 +176,8 @@ impl Builder } /// Builds a new [`Material`]. - /// - /// # Panics - /// Will panic if no ambient map, diffuse map or specular map is set. #[must_use] - pub const fn build(self) -> Material + pub fn build(self) -> Material { Material { ambient: self.ambient, @@ -152,6 +187,7 @@ impl Builder diffuse_map: self.diffuse_map, specular_map: self.specular_map, shininess: self.shininess, + loading_textures: self.loading_textures, } } } @@ -210,3 +246,52 @@ impl Default for FlagsBuilder Self::new() } } + +pub(crate) fn set_stored_materials_texture_handles( + mut assets: Single, + asset_events: Single, +) +{ + let assets = assets.get_mut().unwrap(); + let asset_events = asset_events.get().unwrap(); + + for AssetEvent::Stored(asset_id, ..) in asset_events.iter_last_tick() { + let asset_handle = AssetHandle::::from_id(*asset_id); + + if !assets.is_loaded_and_has_type(&asset_handle) { + continue; + } + + let Some(material_textures) = assets.get(&asset_handle).map(|mat| { + mat.loading_textures + .iter() + .map(|(tex_name, tex_label)| { + ( + *tex_name, + assets.get_handle_to_loaded::(tex_label.clone()), + ) + }) + .collect::>() + }) else { + unreachable!(); + }; + + let Some(material) = assets.get_mut(&asset_handle) else { + unreachable!(); + }; + + for (tex_name, tex_asset) in material_textures { + let Some(tex_asset) = tex_asset else { + unreachable!(); + }; + + let dst = match tex_name { + LoadingTextureName::AmbientMap => &mut material.ambient_map, + LoadingTextureName::DiffuseMap => &mut material.diffuse_map, + LoadingTextureName::SpecularMap => &mut material.specular_map, + }; + + *dst = Some(tex_asset); + } + } +} -- cgit v1.2.3-18-g5258