diff --git a/.gitmodules b/.gitmodules index de96c6f9..1881e8c0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "3rdparty/Catch2"] path = 3rdparty/Catch2 url = https://github.com/catchorg/Catch2 +[submodule "3rdparty/pareto"] + path = 3rdparty/pareto + url = https://github.com/alandefreitas/pareto.git diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index 6bd8f098..c55ba636 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -2,3 +2,4 @@ add_subdirectory(fmt EXCLUDE_FROM_ALL) add_subdirectory(Catch2 EXCLUDE_FROM_ALL) add_subdirectory(json EXCLUDE_FROM_ALL) add_subdirectory(nanobench EXCLUDE_FROM_ALL) +add_subdirectory(pareto EXCLUDE_FROM_ALL) diff --git a/3rdparty/pareto b/3rdparty/pareto new file mode 160000 index 00000000..47f491ee --- /dev/null +++ b/3rdparty/pareto @@ -0,0 +1 @@ +Subproject commit 47f491eeaead1b5a95e27ee3d6bc4c591b0e4462 diff --git a/include/qbsp/map.hh b/include/qbsp/map.hh index b665d06a..e08c8ff1 100644 --- a/include/qbsp/map.hh +++ b/include/qbsp/map.hh @@ -136,12 +136,6 @@ struct maptexdata_t extern std::shared_mutex map_planes_lock; -struct hashvert_t -{ - qvec3d point; - size_t num; -}; - struct mapplane_t : qbsp_plane_t { std::optional outputnum; @@ -173,6 +167,8 @@ struct qbsp_plane_eq } }; +#include + struct mapdata_t { /* Arrays of actual items */ @@ -256,7 +252,7 @@ struct mapdata_t std::unordered_map> planehash; // hashed vertices; generated by EmitVertices - std::map> hashverts; + pareto::spatial_map hashverts {}; // find vector of points in hash closest to vec inline auto find_hash_vector(const qvec3d &vec) @@ -267,12 +263,11 @@ struct mapdata_t // find output index for specified already-output vector. inline std::optional find_emitted_hash_vector(const qvec3d &vert) { - if (auto it = find_hash_vector(vert); it != hashverts.end()) { - for (hashvert_t &hv : it->second) { - if (qv::epsilonEqual(hv.point, vert, POINT_EQUAL_EPSILON)) { - return hv.num; - } - } + static const vec_t point_epsilon_with_border = std::nextafter(POINT_EQUAL_EPSILON, 1.0); + + if (auto it = hashverts.find_intersection({{ vert[0] - (POINT_EQUAL_EPSILON * 0.5), vert[1] - (POINT_EQUAL_EPSILON * 0.5), vert[2] - (POINT_EQUAL_EPSILON * 0.5) }}, + {{ vert[0] + (POINT_EQUAL_EPSILON * 0.5) }, { vert[1] + (POINT_EQUAL_EPSILON * 0.5) }, { vert[2] + (POINT_EQUAL_EPSILON * 0.5) }}); it != hashverts.end()) { + return it->second; } return std::nullopt; @@ -281,17 +276,7 @@ struct mapdata_t // add vector to hash inline void add_hash_vector(const qvec3d &point, const size_t &num) { - // insert each vert at floor(pos[axis]) and floor(pos[axis]) + 1 (for each axis) - // so e.g. a vert at (0.99, 0.99, 0.99) shows up if we search at (1.01, 1.01, 1.01) - // this is a bit wasteful.. - for (int32_t x = -1; x <= 1; x++) { - for (int32_t y = -1; y <= 1; y++) { - for (int32_t z = -1; z <= 1; z++) { - const qvec3i h{floor(point[0]) + x, floor(point[1]) + y, floor(point[2]) + z}; - hashverts[h].push_front({point, num}); - } - } - } + hashverts.emplace(pareto::point({ point[0], point[1], point[2] }), num); } // hashed edges; generated by EmitEdges diff --git a/qbsp/CMakeLists.txt b/qbsp/CMakeLists.txt index ffc3b22f..092b7095 100644 --- a/qbsp/CMakeLists.txt +++ b/qbsp/CMakeLists.txt @@ -31,7 +31,7 @@ set(QBSP_SOURCES ${QBSP_INCLUDES}) add_library(libqbsp STATIC ${QBSP_SOURCES}) -target_link_libraries(libqbsp common ${CMAKE_THREAD_LIBS_INIT} TBB::tbb fmt::fmt nlohmann_json::nlohmann_json) +target_link_libraries(libqbsp common ${CMAKE_THREAD_LIBS_INIT} TBB::tbb fmt::fmt nlohmann_json::nlohmann_json pareto) add_executable(qbsp main.cc) target_link_libraries(qbsp libqbsp)