1use nightshade_api::prelude::*;
2use std::time::{Duration, Instant};
3
4const CUBE_COUNT: usize = 500;
5const PHASE_FRAMES: u32 = 300;
6
7fn main() {
8 let mut app = open();
9 show_grid(&mut app.world, false);
10 orbit_camera(&mut app.world, vec3(0.0, 0.5, 0.0), 45.0);
11
12 let positions = grid_positions();
13 let mut entities = spawn_objects(
14 &mut app.world,
15 Object {
16 color: TEAL,
17 ..Object::default()
18 },
19 &positions,
20 );
21
22 let label = spawn_text(
23 &mut app.world,
24 "phase 1: api spelling",
25 ScreenAnchor::TopLeft,
26 );
27
28 let mut frame_index = 0u32;
29 let mut api_total = Duration::ZERO;
30 let mut api_frames = 0u32;
31 let mut longhand_total = Duration::ZERO;
32 let mut longhand_frames = 0u32;
33
34 while frame(&mut app) {
35 let step = delta_time(&app.world);
36 if frame_index < PHASE_FRAMES {
37 let start = Instant::now();
38 for &entity in &entities {
39 rotate(&mut app.world, entity, Vec3::y(), step);
40 }
41 api_total += start.elapsed();
42 api_frames += 1;
43 if frame_index + 1 == PHASE_FRAMES {
44 for &entity in &entities {
45 despawn(&mut app.world, entity);
46 }
47 entities = longhand::spawn_grid(&mut app.world, &positions, ORANGE);
48 app.world.resources.mesh_render_state.request_full_rebuild();
49 set_text(&mut app.world, label, "phase 2: longhand spelling");
50 }
51 } else {
52 let start = Instant::now();
53 for &entity in &entities {
54 longhand::rotate(&mut app.world, entity, Vec3::y(), step);
55 }
56 longhand_total += start.elapsed();
57 longhand_frames += 1;
58 if frame_index + 1 == PHASE_FRAMES * 2 {
59 break;
60 }
61 }
62 frame_index += 1;
63 }
64
65 report("api", api_total, api_frames);
66 report("longhand", longhand_total, longhand_frames);
67}
68
69fn report(name: &str, total: Duration, frames: u32) {
70 if frames == 0 {
71 println!("{name}: no frames measured");
72 return;
73 }
74 let milliseconds = total.as_secs_f64() * 1000.0 / frames as f64;
75 println!(
76 "{name}: {CUBE_COUNT} cubes rotated in {milliseconds:.4} ms per frame average over {frames} frames"
77 );
78}
79
80fn grid_positions() -> Vec<Vec3> {
81 let mut positions = Vec::with_capacity(CUBE_COUNT);
82 for row in 0..20 {
83 for column in 0..25 {
84 positions.push(vec3(
85 column as f32 * 2.0 - 24.0,
86 0.5,
87 row as f32 * 2.0 - 19.0,
88 ));
89 }
90 }
91 positions
92}
93
94mod longhand {
95 use nightshade_api::nightshade;
96 use nightshade_api::nightshade::prelude::*;
97
98 pub fn spawn_grid(world: &mut World, positions: &[Vec3], color: [f32; 4]) -> Vec<Entity> {
99 let material_name = nightshade::ecs::material::resources::material_registry_find_or_insert(
100 &mut world.resources.assets.material_registry,
101 "parity::longhand".to_string(),
102 Material {
103 base_color: color,
104 ..Default::default()
105 },
106 );
107 let mut entities = Vec::with_capacity(positions.len());
108 for &position in positions {
109 let entity = spawn_mesh_at(world, "Cube", position, Vec3::new(1.0, 1.0, 1.0));
110 let previous = world
111 .core
112 .get_material_ref(entity)
113 .map(|material_ref| material_ref.name.clone());
114 if let Some(previous_name) = previous
115 && let Some((index, _)) = registry_lookup_index(
116 &world.resources.assets.material_registry.registry,
117 &previous_name,
118 )
119 {
120 registry_remove_reference(
121 &mut world.resources.assets.material_registry.registry,
122 index,
123 );
124 }
125 if let Some((index, _)) = registry_lookup_index(
126 &world.resources.assets.material_registry.registry,
127 &material_name,
128 ) {
129 registry_add_reference(
130 &mut world.resources.assets.material_registry.registry,
131 index,
132 );
133 }
134 world
135 .core
136 .set_material_ref(entity, MaterialRef::new(material_name.clone()));
137 world.resources.mesh_render_state.mark_entity_added(entity);
138 entities.push(entity);
139 }
140 entities
141 }
142
143 pub fn rotate(world: &mut World, entity: Entity, axis: Vec3, radians: f32) {
144 if let Some(transform) = mutate_local_transform(world, entity) {
145 transform.rotation =
146 nalgebra_glm::quat_angle_axis(radians, &axis.normalize()) * transform.rotation;
147 }
148 }
149}