#include "entt/entt.hpp" #include "interest_management/FixedGrid.hpp" #include "interest_management/SpatialHashGrid.hpp" #include #include #include #include #include #include // #include "Quadtree.h" void* operator new(std::size_t count) { auto ptr = malloc(count); TracyAlloc(ptr, count); return ptr; } void operator delete(void* ptr) noexcept { TracyFree(ptr); free(ptr); } const long SIZE = 4096*4; const long VIEW = 100; struct Position { float x, y, z; Position(float x, float y, float z) : x(x), y(y), z(z) {} }; struct Velocity { float x, y, z; }; void generate_points(entt::registry& registry, uint32_t num_entities) { std::mt19937 rng{std::random_device{}()}; std::uniform_real_distribution pos_dist(-SIZE, SIZE); std::uniform_real_distribution vel_dist(-5.0f, 5.0f); for (uint32_t i = 0; i < num_entities; ++i) { auto entity = registry.create(); registry.emplace(entity, pos_dist(rng), pos_dist(rng), pos_dist(rng)); registry.emplace(entity, vel_dist(rng), vel_dist(rng), vel_dist(rng)); } } float clamp(float value, float min, float max) { return std::max(min, std::min(max, value)); } void move_points(entt::registry& registry) { for (auto entity : registry.view()) { auto& pos = registry.get(entity); auto& vel = registry.get(entity); pos.x += vel.x; pos.y += vel.y; pos.z += vel.z; pos.x = clamp(pos.x, -SIZE, SIZE); pos.y = clamp(pos.y, -SIZE, SIZE); pos.z = clamp(pos.z, -SIZE, SIZE); } } std::vector generate_query_points(uint32_t num_points) { std::mt19937 rng{std::random_device{}()}; std::uniform_real_distribution dist(-SIZE, SIZE); std::vector points; for (uint32_t i = 0; i < num_points; ++i) { points.emplace_back(dist(rng), dist(rng), dist(rng)); } return points; } const uint32_t ENTITY_COUNT = 100000; const uint32_t FRAME_COUNT = 100; using Clock = std::chrono::high_resolution_clock; using TimePoint = std::chrono::time_point; void hash_grid(entt::registry& registry, const std::vector& query_points) { tw::net::im::SpatialHashGrid hash_grid; ZoneScopedN("HashGrid"); TimePoint start = Clock::now(); for(int frame = 0; frame < FRAME_COUNT; frame++) { { ZoneScopedN("move"); move_points(registry); } hash_grid.begin_frame(); { ZoneScopedN("insert"); for (auto entity : registry.view()) { auto [x, y, z] = registry.get(entity); hash_grid.insert(entity, glm::vec3(x, y, z)); } } { ZoneScopedN("query"); for (const auto& pos : query_points) { std::vector out_entities; hash_grid.query_neighbors(pos, out_entities); } } } TimePoint end = Clock::now(); auto elapsed = std::chrono::duration_cast(end - start); spdlog::info("HashGrid Elapsed time: {}s", elapsed.count()); } void fixed_grid(entt::registry& registry, const std::vector& query_points) { tw::net::im::FixedGrid fixed_grid(-10000, 10000, -10000, 10000); ZoneScopedN("FixedGrid"); auto start = Clock::now(); for(int frame = 0; frame < FRAME_COUNT; frame++) { { ZoneScopedN("move"); move_points(registry); } fixed_grid.begin_frame(); { ZoneScopedN("insert"); for (auto entity : registry.view()) { auto [x, y, z] = registry.get(entity); fixed_grid.insert(entity, glm::vec3(x, y, z)); } } { ZoneScopedN("query"); for (const auto& pos : query_points) { std::vector out_entities; fixed_grid.query_neighbors(pos, out_entities); } } } auto end = Clock::now(); auto elapsed = std::chrono::duration_cast(end - start); spdlog::info("FixedGrid Elapsed time: {}s", elapsed.count()); } void naive(entt::registry& registry, const std::vector& query_points) { auto start = Clock::now(); ZoneScopedN("Naive"); for(int frame = 0; frame < FRAME_COUNT; frame++) { { ZoneScopedN("move"); move_points(registry); } { ZoneScopedN("query"); for(const auto& player : query_points) { std::vector out_entities; for(const auto& position : registry.view()) { auto [x, y, z] = registry.get(position); Position diff(player.x - x, player.y - y, 0.0f); if(diff.x * diff.x + diff.y * diff.y < VIEW * VIEW) { out_entities.push_back((entt::entity)position); } } } } } auto end = Clock::now(); auto elapsed = std::chrono::duration_cast(end - start); spdlog::info("Naive Elapsed time: {}ms", elapsed.count()); } // void quadtree_query(entt::registry& registry, const std::vector& query_points) { // ZoneScopedN("quadtree_query"); // struct Node // { // quadtree::Box box; // uint32_t id; // }; // auto getBox = [](Node* node) // { // return node->box; // }; // auto box = quadtree::Box((float)-SIZE, (float)-SIZE, (float)2*SIZE, (float)2*SIZE); // std::vector nodes(ENTITY_COUNT); // auto start = Clock::now(); // for(int frame = 0; frame < FRAME_COUNT; frame++) { // quadtree::Quadtree quad_tree(box, getBox); // { ZoneScopedN("move"); // move_points(registry); } // { ZoneScopedN("insert"); // for (auto entity : registry.view()) { // auto [x, y, z] = registry.get(entity); // auto node = &nodes[(uint32_t)entity]; // node->box = quadtree::Box(x, y, 0.0f, 0.0f); // node->id = (uint32_t)entity; // quad_tree.add(node); // } // } // { ZoneScopedN("query"); // for (const auto& pos : query_points) { // quad_tree.query(quadtree::Box(pos.x - 10.0f, pos.y - 10.0f, 20.0f, 20.0f)); // } // } // } // auto end = Clock::now(); // auto elapsed = std::chrono::duration_cast(end - start); // spdlog::info("QuadTree Elapsed time: {}ms", elapsed.count()); // } int main() { entt::registry registry; generate_points(registry, ENTITY_COUNT); auto query_points = generate_query_points(1000); naive(registry, query_points); // quadtree_query(registry, query_points); fixed_grid(registry, query_points); hash_grid(registry, query_points); }