/// bench_bvh.cpp — BVH construction + ray query benchmarks /// /// Metrics: /// BVH_Build/N{size} — SAH construction time for N random triangles /// BVH_RayQuery/N{size} — M random ray queries against a BVH of N triangles #include #include #include #include #include #include #include using namespace vde; namespace { /// Generate N pseudo-random triangles inside [-R, R]³ std::vector random_triangles(int n, double R = 100.0) { std::mt19937 rng(42); std::uniform_real_distribution dist(-R, R); std::vector tris; tris.reserve(n); for (int i = 0; i < n; ++i) { core::Point3D v0(dist(rng), dist(rng), dist(rng)); core::Point3D v1(v0.x() + dist(rng) * 0.2, v0.y() + dist(rng) * 0.2, v0.z() + dist(rng) * 0.2); core::Point3D v2(v0.x() + dist(rng) * 0.2, v0.y() + dist(rng) * 0.2, v0.z() + dist(rng) * 0.2); tris.emplace_back(v0, v1, v2); } return tris; } /// Generate M random rays with origin/direction inside [-R, R]³ std::vector random_rays(int m, double R = 100.0) { std::mt19937 rng(42); std::uniform_real_distribution dist(-R, R); std::vector rays; rays.reserve(m); for (int i = 0; i < m; ++i) { core::Point3D org(dist(rng), dist(rng), dist(rng)); core::Vector3D dir(dist(rng), dist(rng), dist(rng)); rays.emplace_back(org, dir); } return rays; } } // namespace // ── BVH Build ───────────────────────────────────────────────────────── static void BVH_Build(benchmark::State& state) { auto tris = random_triangles(state.range(0)); for (auto _ : state) { spatial::BVH bvh; bvh.build(tris); benchmark::DoNotOptimize(bvh.size()); } state.SetItemsProcessed(state.iterations() * state.range(0)); } BENCHMARK(BVH_Build)->Arg(500)->Arg(1000)->Arg(2000); // ── BVH Ray Query ───────────────────────────────────────────────────── class BVH_RayFixture : public benchmark::Fixture { public: void SetUp(const benchmark::State& state) override { tris = random_triangles(state.range(0)); bvh.build(tris); rays = random_rays(1000); // fixed query count } spatial::BVH bvh; std::vector rays; std::vector tris; }; BENCHMARK_DEFINE_F(BVH_RayFixture, BVH_RayQuery)(benchmark::State& state) { size_t hit_count = 0; for (auto _ : state) { for (const auto& ray : rays) { auto res = bvh.query_ray_nearest(ray); hit_count += res.has_value(); } } benchmark::DoNotOptimize(hit_count); state.SetItemsProcessed(state.iterations() * rays.size()); } BENCHMARK_REGISTER_F(BVH_RayFixture, BVH_RayQuery) ->Arg(500)->Arg(1000)->Arg(2000);