@@ -10,10 +10,46 @@ use super::constants::ICING_MESH_NAME;
1010use crate :: actor:: constants:: NATEROID_DEATH_ALPHA_STEP ;
1111use crate :: asset_loader:: SceneAssets ;
1212
13- /// Precomputed materials for `Nateroid` death animation at different transparency levels
13+ /// Precomputed `Nateroid` death-animation materials: one faded donut+icing set
14+ /// per transparency level. Fades the donut/icing materials the meshes actually
15+ /// use (applied by `apply_nateroid_materials_to_children`), matched per mesh.
1416#[ derive( Resource ) ]
1517pub ( crate ) struct NateroidDeathMaterials {
16- pub ( crate ) materials : Vec < Vec < Handle < StandardMaterial > > > ,
18+ levels : Vec < NateroidDeathLevel > ,
19+ }
20+
21+ /// Faded donut and icing materials for a single transparency level.
22+ struct NateroidDeathLevel {
23+ donut : Handle < StandardMaterial > ,
24+ icing : Handle < StandardMaterial > ,
25+ }
26+
27+ impl NateroidDeathLevel {
28+ const fn handle ( & self , mesh : NateroidMesh ) -> & Handle < StandardMaterial > {
29+ match mesh {
30+ NateroidMesh :: Donut => & self . donut ,
31+ NateroidMesh :: Icing => & self . icing ,
32+ }
33+ }
34+ }
35+
36+ impl NateroidDeathMaterials {
37+ /// Number of precomputed transparency levels.
38+ pub const fn level_count ( & self ) -> usize { self . levels . len ( ) }
39+
40+ /// Faded material for the given alpha `level`, matched to `mesh_name`
41+ /// (donut/icing). Unknown mesh names fall back to the donut material.
42+ pub fn material_for (
43+ & self ,
44+ level : usize ,
45+ mesh_name : Option < & str > ,
46+ ) -> Option < Handle < StandardMaterial > > {
47+ let level = self . levels . get ( level) ?;
48+ let mesh = mesh_name
49+ . and_then ( NateroidMesh :: classify)
50+ . unwrap_or ( NateroidMesh :: Donut ) ;
51+ Some ( level. handle ( mesh) . clone ( ) )
52+ }
1753}
1854
1955#[ derive( Clone , Copy ) ]
@@ -154,17 +190,28 @@ pub(super) fn debug_mesh_components(
154190 }
155191}
156192
157- /// System that precomputes death materials when assets are loaded
193+ /// Precomputes faded donut/icing materials for the death animation once assets
194+ /// are loaded. Fades the custom materials the meshes use rather than the GLTF
195+ /// originals (the GLTF scene's embedded `World` is no longer queryable in 0.19).
158196pub ( super ) fn precompute_death_materials (
159197 mut commands : Commands ,
160198 scene_assets : Res < SceneAssets > ,
161- scenes : Res < Assets < Scene > > ,
162199 mut materials : ResMut < Assets < StandardMaterial > > ,
163200 nateroid_settings : Res < NateroidSettings > ,
164201) {
165- // Get the nateroid scene
166- let Some ( nateroid_scene) = scenes. get ( & scene_assets. nateroid ) else {
167- warn ! ( "Nateroid scene not loaded yet" ) ;
202+ let Some ( donut_handle) = scene_assets. nateroid_donut_material . clone ( ) else {
203+ warn ! ( "Nateroid donut material not created yet" ) ;
204+ return ;
205+ } ;
206+ let Some ( icing_handle) = scene_assets. nateroid_icing_material . clone ( ) else {
207+ warn ! ( "Nateroid icing material not created yet" ) ;
208+ return ;
209+ } ;
210+ let ( Some ( donut_base) , Some ( icing_base) ) = (
211+ materials. get ( & donut_handle) . cloned ( ) ,
212+ materials. get ( & icing_handle) . cloned ( ) ,
213+ ) else {
214+ warn ! ( "Nateroid base materials not loaded yet" ) ;
168215 return ;
169216 } ;
170217
@@ -174,57 +221,27 @@ pub(super) fn precompute_death_materials(
174221 let level_count =
175222 ( ( initial_alpha - target_alpha) * ( 1.0 / NATEROID_DEATH_ALPHA_STEP ) ) . to_usize ( ) + 1 ;
176223
177- // Collect material handles from the scene's world using try_query
178- let mut material_handles = Vec :: new ( ) ;
179- if let Some ( mut query_state) = nateroid_scene
180- . world
181- . try_query :: < & MeshMaterial3d < StandardMaterial > > ( )
182- {
183- for mesh_material in query_state. iter ( & nateroid_scene. world ) {
184- material_handles. push ( mesh_material. 0 . clone ( ) ) ;
185- }
186- }
187-
188- if material_handles. is_empty ( ) {
189- warn ! ( "No materials found in nateroid scene" ) ;
190- return ;
191- }
192-
193- debug ! (
194- "Collected {} material handles from nateroid scene" ,
195- material_handles. len( )
196- ) ;
197-
198- // Precompute materials for each alpha level
199- let mut precomputed_materials = Vec :: with_capacity ( level_count) ;
224+ let mut levels = Vec :: with_capacity ( level_count) ;
200225 for level in 0 ..level_count {
201226 // FMA optimization (faster + more precise): initial_alpha - (level as f32 * step)
202227 let alpha = level
203228 . to_f32 ( )
204229 . mul_add ( -NATEROID_DEATH_ALPHA_STEP , initial_alpha) ;
205- let mut level_materials = Vec :: with_capacity ( material_handles. len ( ) ) ;
206-
207- for material_handle in & material_handles {
208- if let Some ( original_material) = materials. get ( material_handle) {
209- let mut cloned_material = original_material. clone ( ) ;
210- cloned_material. base_color . set_alpha ( alpha) ;
211- cloned_material. alpha_mode = AlphaMode :: Blend ;
212- level_materials. push ( materials. add ( cloned_material) ) ;
213- }
214- }
215-
216- precomputed_materials. push ( level_materials) ;
230+ levels. push ( NateroidDeathLevel {
231+ donut : materials. add ( faded_material ( & donut_base, alpha) ) ,
232+ icing : materials. add ( faded_material ( & icing_base, alpha) ) ,
233+ } ) ;
217234 }
218235
219- let material_set_count = precomputed_materials. len ( ) ;
220- let materials_per_set_count = material_handles. len ( ) ;
221-
222- // Insert the resource
223- commands. insert_resource ( NateroidDeathMaterials {
224- materials : precomputed_materials,
225- } ) ;
236+ let level_count = levels. len ( ) ;
237+ commands. insert_resource ( NateroidDeathMaterials { levels } ) ;
238+ debug ! ( "Precomputed {level_count} nateroid death-material levels (donut + icing)" ) ;
239+ }
226240
227- debug ! (
228- "Precomputed {material_set_count} material sets with {materials_per_set_count} materials each"
229- ) ;
241+ /// Clones `base` into a translucent material at the given `alpha`.
242+ fn faded_material ( base : & StandardMaterial , alpha : f32 ) -> StandardMaterial {
243+ let mut material = base. clone ( ) ;
244+ material. base_color . set_alpha ( alpha) ;
245+ material. alpha_mode = AlphaMode :: Blend ;
246+ material
230247}
0 commit comments