@@ -72,16 +72,21 @@ struct Args {
7272 #[ argh( switch) ]
7373 shadows : bool ,
7474
75+ /// whether to continously rotate individual cubes.
76+ #[ argh( switch) ]
77+ rotate_cubes : bool ,
78+
7579 /// animate the cube materials by updating the material from the cpu each frame
7680 #[ argh( switch) ]
7781 animate_materials : bool ,
7882}
7983
80- #[ derive( Default , Clone ) ]
84+ #[ derive( Default , Clone , PartialEq ) ]
8185enum Layout {
8286 Cube ,
8387 #[ default]
8488 Sphere ,
89+ Dense ,
8590}
8691
8792impl FromStr for Layout {
@@ -91,8 +96,9 @@ impl FromStr for Layout {
9196 match s {
9297 "cube" => Ok ( Self :: Cube ) ,
9398 "sphere" => Ok ( Self :: Sphere ) ,
99+ "dense" => Ok ( Self :: Dense ) ,
94100 _ => Err ( format ! (
95- "Unknown layout value: '{s}', valid options: 'cube', 'sphere'"
101+ "Unknown layout value: '{s}', valid options: 'cube', 'sphere', 'dense' "
96102 ) ) ,
97103 }
98104 }
@@ -123,7 +129,15 @@ fn main() {
123129 unfocused_mode : UpdateMode :: Continuous ,
124130 } )
125131 . add_systems ( Startup , setup)
126- . add_systems ( Update , ( move_camera, print_mesh_count) ) ;
132+ . add_systems ( Update , print_mesh_count) ;
133+
134+ if args. layout != Layout :: Dense {
135+ app. add_systems ( Update , move_camera) ;
136+ }
137+
138+ if args. rotate_cubes {
139+ app. add_systems ( Update , rotate_cubes) ;
140+ }
127141
128142 if args. animate_materials {
129143 app. add_systems ( Update , update_materials) ;
@@ -199,7 +213,7 @@ fn setup(
199213 NotShadowCaster ,
200214 ) ) ;
201215 }
202- _ => {
216+ Layout :: Cube => {
203217 // NOTE: This pattern is good for demonstrating that frustum culling is working correctly
204218 // as the number of visible meshes rises and falls depending on the viewing angle.
205219 let scale = 2.5 ;
@@ -247,6 +261,34 @@ fn setup(
247261 NotShadowCaster ,
248262 ) ) ;
249263 }
264+ Layout :: Dense => {
265+ // NOTE: This pattern is good for demonstrating a dense configuration of cubes
266+ // overlapping each other, all within the camera frustum.
267+ let count = WIDTH * HEIGHT * 2 ;
268+ let size = ( count as f32 ) . cbrt ( ) . round ( ) ;
269+ let gap = 1.25 ;
270+
271+ let cubes = ( 0 ..count) . map ( move |i| {
272+ let x = i as f32 % size;
273+ let y = ( i as f32 / size) % size;
274+ let z = i as f32 / ( size * size) ;
275+ let pos = Vec3 :: new ( x * gap, y * gap, z * gap) ;
276+ (
277+ Mesh3d ( meshes. choose ( & mut material_rng) . unwrap ( ) . 0 . clone ( ) ) ,
278+ MeshMaterial3d ( materials. choose ( & mut material_rng) . unwrap ( ) . clone ( ) ) ,
279+ Transform :: from_translation ( pos) ,
280+ )
281+ } ) ;
282+
283+ // camera
284+ commands. spawn ( (
285+ Camera3d :: default ( ) ,
286+ Transform :: from_xyz ( 100.0 , 90.0 , 100.0 )
287+ . looking_at ( Vec3 :: new ( 0.0 , -10.0 , 0.0 ) , Vec3 :: Y ) ,
288+ ) ) ;
289+
290+ commands. spawn_batch ( cubes) ;
291+ }
250292 }
251293
252294 commands. spawn ( (
@@ -294,6 +336,7 @@ fn init_materials(
294336 match args. layout {
295337 Layout :: Cube => ( WIDTH - WIDTH / 10 ) * ( HEIGHT - HEIGHT / 10 ) ,
296338 Layout :: Sphere => WIDTH * HEIGHT * 4 ,
339+ Layout :: Dense => WIDTH * HEIGHT * 2 ,
297340 }
298341 } else {
299342 args. material_texture_count
@@ -500,6 +543,15 @@ fn update_materials(mut materials: ResMut<Assets<StandardMaterial>>, time: Res<T
500543 }
501544}
502545
546+ fn rotate_cubes (
547+ mut query : Query < & mut Transform , ( With < Mesh3d > , Without < NotShadowCaster > ) > ,
548+ time : Res < Time > ,
549+ ) {
550+ for mut transform in query. iter_mut ( ) {
551+ transform. rotate_y ( 10.0 * time. delta_secs ( ) ) ;
552+ }
553+ }
554+
503555#[ inline]
504556fn fast_hue_to_rgb ( hue : f32 ) -> Vec3 {
505557 ( hue * 6.0 - vec3 ( 3.0 , 2.0 , 4.0 ) ) . abs ( ) * vec3 ( 1.0 , -1.0 , -1.0 ) + vec3 ( -1.0 , 2.0 , 2.0 )
0 commit comments