#include #include #include "systems/collision.hpp" #include "entities/solid_box.hpp" #include "utils/globals.hpp" #include "utils/math.hpp" namespace Nimbin { // How does collision cost scale with the number of objects? // ────────────────────────────────────────────────────────────────────────── // Pure math benchmarks — no GameObject, just the algorithm // ────────────────────────────────────────────────────────────────────────── static void BM_SweptRayAabb_Hit(benchmark::State& state) { Vec3 origin { 0.0, 0.0, 0.0 }; Vec3 dir { 1.0, 0.0, 0.0 }; Vec3 bmin { 0.5, -0.5, -0.5 }; Vec3 bmax { 1.5, 0.5, 0.5 }; for (auto _ : state) { Collision::SweptResult sw = Collision::swept_RayAabb(origin, dir, bmin, bmax); benchmark::DoNotOptimize(sw); } } BENCHMARK(BM_SweptRayAabb_Hit); static void BM_SweptRayAabb_Miss(benchmark::State& state) { Vec3 origin { 0.0, 0.0, 0.0 }; Vec3 dir { 1.0, 0.0, 0.0 }; Vec3 bmin { 0.5, 5.0, -0.5 }; // above the ray Vec3 bmax { 1.5, 6.0, 0.5 }; for (auto _ : state) { Collision::SweptResult sw = Collision::swept_RayAabb(origin, dir, bmin, bmax); benchmark::DoNotOptimize(sw); } } BENCHMARK(BM_SweptRayAabb_Miss); // ────────────────────────────────────────────────────────────────────────── // GameObject-based — includes the yaw-aware aabb_min/max cost // ────────────────────────────────────────────────────────────────────────── static void BM_AabbOverlap_Yawed(benchmark::State& state) { // SolidBox is the simplest concrete GameObject. SolidBox a({0,0,0}, {0.5, 0.5, 0.5}); SolidBox b({0.4, 0.0, 0.0}, {0.5, 0.5, 0.5}); a.yaw = 0.7f; // exercise the yaw-aware AABB path b.yaw = 1.2f; for (auto _ : state) { bool hit = Collision::aabb_Overlap(a, b); benchmark::DoNotOptimize(hit); } } BENCHMARK(BM_AabbOverlap_Yawed); static void BM_AabbOverlap_AxisAligned(benchmark::State& state) { SolidBox a({0,0,0}, {0.5, 0.5, 0.5}); SolidBox b({0.4, 0.0, 0.0}, {0.5, 0.5, 0.5}); // yaw = 0 by default for (auto _ : state) { bool hit = Collision::aabb_Overlap(a, b); benchmark::DoNotOptimize(hit); } } BENCHMARK(BM_AabbOverlap_AxisAligned); // ────────────────────────────────────────────────────────────────────────── // Scaling: how does pair-collision cost grow with N? // This is the O(N²) loop in PhysicsSystem::update_Objects. // ────────────────────────────────────────────────────────────────────────── static void BM_PairwiseOverlap_Scaling(benchmark::State& state) { const size_t N = static_cast(state.range(0)); // Build N boxes in a grid so most pairs don't overlap. std::vector boxes; boxes.reserve(N); for (size_t i = 0; i < N; ++i) { double x = static_cast(i % 10) * 2.0; double z = static_cast(i / 10) * 2.0; boxes.emplace_back(Vec3{x, 0.0, z}, Vec3{0.5, 0.5, 0.5}); } for (auto _ : state) { int hits = 0; for (size_t i = 0; i < N; ++i) for (size_t j = i + 1; j < N; ++j) if (Collision::aabb_Overlap(boxes[i], boxes[j])) ++hits; benchmark::DoNotOptimize(hits); } state.SetLabel("N=" + std::to_string(N) + " pairs=" + std::to_string(N*(N-1)/2)); } BENCHMARK(BM_PairwiseOverlap_Scaling)->Arg(10)->Arg(25)->Arg(50)->Arg(100)->Arg(200); } // namespace Nimbin