91 lines
3.1 KiB
C++
91 lines
3.1 KiB
C++
/// 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 <benchmark/benchmark.h>
|
|
#include <vde/spatial/bvh.h>
|
|
#include <vde/core/triangle.h>
|
|
#include <vde/core/point.h>
|
|
#include <random>
|
|
#include <vector>
|
|
#include <cmath>
|
|
|
|
using namespace vde;
|
|
|
|
namespace {
|
|
|
|
/// Generate N pseudo-random triangles inside [-R, R]³
|
|
std::vector<core::Triangle3D> random_triangles(int n, double R = 100.0) {
|
|
std::mt19937 rng(42);
|
|
std::uniform_real_distribution<double> dist(-R, R);
|
|
std::vector<core::Triangle3D> 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<core::Ray3Dd> random_rays(int m, double R = 100.0) {
|
|
std::mt19937 rng(42);
|
|
std::uniform_real_distribution<double> dist(-R, R);
|
|
std::vector<core::Ray3Dd> 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<core::Ray3Dd> rays;
|
|
std::vector<core::Triangle3D> 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);
|