//! Benchmark for scene world-transform resolution. //! //! Stage 3 test criterion: a 10,000-entity scene with a 5-level-deep hierarchy //! must resolve all world transforms in under 1ms. The `world_transforms_10k` //! benchmark builds exactly that scene and measures a full bulk resolve; check //! its reported time against the 1ms budget. use criterion::{black_box, criterion_group, criterion_main, Criterion}; use oxide_engine::math::{Transform, Vec3}; use oxide_engine::scene::{Entity, Scene}; /// Builds a scene of `total` entities arranged as a `depth`-level hierarchy. /// /// Level 0 holds the roots; each subsequent level's entities are distributed as /// children of the previous level, so the tree is `depth` levels deep and the /// node count is exactly `total`. fn build_scene(total: usize, depth: usize) -> Scene { let mut scene = Scene::new(); let per_level = total / depth; let mut previous: Vec = Vec::new(); for level in 0..depth { // The last level absorbs any remainder so the count is exact. let count = if level == depth - 1 { total - per_level * (depth - 1) } else { per_level }; let mut current = Vec::with_capacity(count); for i in 0..count { let t = Transform::from_translation(Vec3::new(0.01 * i as f32, 0.02, 0.03)); let entity = if previous.is_empty() { scene.spawn("n", t) } else { // Spread children across the previous level round-robin. scene.spawn_child(previous[i % previous.len()], "n", t) }; current.push(entity); } previous = current; } scene } fn world_transforms_10k(c: &mut Criterion) { let scene = build_scene(10_000, 5); assert_eq!(scene.len(), 10_000); c.bench_function("world_transforms_10k_depth5", |bencher| { bencher.iter(|| { let resolved = scene.world_transforms(); black_box(resolved.len()) }); }); } criterion_group!(benches, world_transforms_10k); criterion_main!(benches);