diff --git a/include/qbsp/map.hh b/include/qbsp/map.hh index 1d29c6b2..e4b12bfc 100644 --- a/include/qbsp/map.hh +++ b/include/qbsp/map.hh @@ -166,7 +166,8 @@ struct mapplane_t : qbsp_plane_t inline mapplane_t(const qbsp_plane_t ©) : qbsp_plane_t(copy) { } }; -#include +struct planehash_t; +struct vertexhash_t; struct mapdata_t { @@ -183,74 +184,24 @@ struct mapdata_t std::vector planes; // planes indices (into the `planes` vector) - pareto::spatial_map plane_hash {}; + std::unique_ptr plane_hash; + + mapdata_t(); // add the specified plane to the list - inline size_t add_plane(const qplane3d &plane) - { - planes.emplace_back(plane); - planes.emplace_back(-plane); - - size_t positive_index = planes.size() - 2; - size_t negative_index = planes.size() - 1; - - auto &positive = planes[positive_index]; - auto &negative = planes[negative_index]; - - size_t result; - - if (positive.get_normal()[static_cast(positive.get_type()) % 3] < 0.0) { - std::swap(positive, negative); - result = negative_index; - } else { - result = positive_index; - } - - plane_hash.emplace(pareto::point { positive.get_normal()[0], positive.get_normal()[1], positive.get_normal()[2], positive.get_dist() }, positive_index); - plane_hash.emplace(pareto::point { negative.get_normal()[0], negative.get_normal()[1], negative.get_normal()[2], negative.get_dist() }, negative_index); - - return result; - } + size_t add_plane(const qplane3d &plane); - inline std::optional find_plane_nonfatal(const qplane3d &plane) - { - constexpr vec_t HALF_NORMAL_EPSILON = NORMAL_EPSILON * 0.5; - constexpr vec_t HALF_DIST_EPSILON = DIST_EPSILON * 0.5; - - if (auto it = plane_hash.find_intersection({ plane.normal[0] - HALF_NORMAL_EPSILON, plane.normal[1] - HALF_NORMAL_EPSILON, plane.normal[2] - HALF_NORMAL_EPSILON, plane.dist - HALF_DIST_EPSILON }, - { plane.normal[0] + HALF_NORMAL_EPSILON, plane.normal[1] + HALF_NORMAL_EPSILON, plane.normal[2] + HALF_NORMAL_EPSILON, plane.dist + HALF_DIST_EPSILON }); it != plane_hash.end()) { - return it->second; - } - - return std::nullopt; - } + std::optional find_plane_nonfatal(const qplane3d &plane); // find the specified plane in the list if it exists. throws // if not. - inline size_t find_plane(const qplane3d &plane) - { - if (auto index = find_plane_nonfatal(plane)) { - return *index; - } - - throw std::bad_function_call(); - } + size_t find_plane(const qplane3d &plane); // find the specified plane in the list if it exists, or // return a new one - inline size_t add_or_find_plane(const qplane3d &plane) - { - if (auto index = find_plane_nonfatal(plane)) { - return *index; - } + size_t add_or_find_plane(const qplane3d &plane); - return add_plane(plane); - } - - inline const qbsp_plane_t &get_plane(size_t pnum) - { - return planes[pnum]; - } + const qbsp_plane_t &get_plane(size_t pnum); std::vector miptex; std::vector mtexinfos; @@ -259,26 +210,13 @@ struct mapdata_t std::map mtexinfo_lookup; // hashed vertices; generated by EmitVertices - pareto::spatial_map hashverts {}; + std::unique_ptr hashverts; // find output index for specified already-output vector. - inline std::optional find_emitted_hash_vector(const qvec3d &vert) - { - constexpr vec_t HALF_EPSILON = POINT_EQUAL_EPSILON * 0.5; - - if (auto it = hashverts.find_intersection({ vert[0] - HALF_EPSILON, vert[1] - HALF_EPSILON, vert[2] - HALF_EPSILON }, - { vert[0] + HALF_EPSILON, vert[1] + HALF_EPSILON, vert[2] + HALF_EPSILON }); it != hashverts.end()) { - return it->second; - } - - return std::nullopt; - } + std::optional find_emitted_hash_vector(const qvec3d &vert); // add vector to hash - inline void add_hash_vector(const qvec3d &point, const size_t &num) - { - hashverts.emplace(pareto::point({ point[0], point[1], point[2] }), num); - } + void add_hash_vector(const qvec3d &point, const size_t &num); // hashed edges; generated by EmitEdges std::map, int64_t> hashedges; @@ -401,4 +339,4 @@ void ExportObj_Marksurfaces(const std::string &filesuffix, const node_t *nodes); void WriteBspBrushMap(const fs::path &name, const bspbrush_t::container &list); -bool IsValidTextureProjection(const qvec3f &faceNormal, const qvec3f &s_vec, const qvec3f &t_vec); \ No newline at end of file +bool IsValidTextureProjection(const qvec3f &faceNormal, const qvec3f &s_vec, const qvec3f &t_vec); diff --git a/qbsp/map.cc b/qbsp/map.cc index e17803d5..2ead26e9 100644 --- a/qbsp/map.cc +++ b/qbsp/map.cc @@ -41,8 +41,110 @@ #include #include +#include + mapdata_t map; +struct planehash_t { + // planes indices (into the `planes` vector) + pareto::spatial_map hash; +}; + +struct vertexhash_t { + // hashed vertices; generated by EmitVertices + pareto::spatial_map hash; +}; + +mapdata_t::mapdata_t() : + plane_hash(std::make_unique()), + hashverts(std::make_unique()) {} + +// add the specified plane to the list +size_t mapdata_t::add_plane(const qplane3d &plane) +{ + planes.emplace_back(plane); + planes.emplace_back(-plane); + + size_t positive_index = planes.size() - 2; + size_t negative_index = planes.size() - 1; + + auto &positive = planes[positive_index]; + auto &negative = planes[negative_index]; + + size_t result; + + if (positive.get_normal()[static_cast(positive.get_type()) % 3] < 0.0) { + std::swap(positive, negative); + result = negative_index; + } else { + result = positive_index; + } + + plane_hash->hash.emplace(pareto::point { positive.get_normal()[0], positive.get_normal()[1], positive.get_normal()[2], positive.get_dist() }, positive_index); + plane_hash->hash.emplace(pareto::point { negative.get_normal()[0], negative.get_normal()[1], negative.get_normal()[2], negative.get_dist() }, negative_index); + + return result; +} + +std::optional mapdata_t::find_plane_nonfatal(const qplane3d &plane) +{ + constexpr vec_t HALF_NORMAL_EPSILON = NORMAL_EPSILON * 0.5; + constexpr vec_t HALF_DIST_EPSILON = DIST_EPSILON * 0.5; + + if (auto it = plane_hash->hash.find_intersection({ plane.normal[0] - HALF_NORMAL_EPSILON, plane.normal[1] - HALF_NORMAL_EPSILON, plane.normal[2] - HALF_NORMAL_EPSILON, plane.dist - HALF_DIST_EPSILON }, + { plane.normal[0] + HALF_NORMAL_EPSILON, plane.normal[1] + HALF_NORMAL_EPSILON, plane.normal[2] + HALF_NORMAL_EPSILON, plane.dist + HALF_DIST_EPSILON }); it != plane_hash->hash.end()) { + return it->second; + } + + return std::nullopt; +} + +// find the specified plane in the list if it exists. throws +// if not. +size_t mapdata_t::find_plane(const qplane3d &plane) +{ + if (auto index = find_plane_nonfatal(plane)) { + return *index; + } + + throw std::bad_function_call(); +} + +// find the specified plane in the list if it exists, or +// return a new one +size_t mapdata_t::add_or_find_plane(const qplane3d &plane) +{ + if (auto index = find_plane_nonfatal(plane)) { + return *index; + } + + return add_plane(plane); +} + +const qbsp_plane_t &mapdata_t::get_plane(size_t pnum) +{ + return planes[pnum]; +} + +// find output index for specified already-output vector. +std::optional mapdata_t::find_emitted_hash_vector(const qvec3d &vert) +{ + constexpr vec_t HALF_EPSILON = POINT_EQUAL_EPSILON * 0.5; + + if (auto it = hashverts->hash.find_intersection({ vert[0] - HALF_EPSILON, vert[1] - HALF_EPSILON, vert[2] - HALF_EPSILON }, + { vert[0] + HALF_EPSILON, vert[1] + HALF_EPSILON, vert[2] + HALF_EPSILON }); it != hashverts->hash.end()) { + return it->second; + } + + return std::nullopt; +} + +// add vector to hash +void mapdata_t::add_hash_vector(const qvec3d &point, const size_t &num) +{ + hashverts->hash.emplace(pareto::point({ point[0], point[1], point[2] }), num); +} + const std::optional &mapdata_t::load_image_meta(const std::string_view &name) { static std::optional nullmeta = std::nullopt;