diff --git a/common/prtfile.cc b/common/prtfile.cc index 4cfcb784..57139437 100644 --- a/common/prtfile.cc +++ b/common/prtfile.cc @@ -24,6 +24,7 @@ #include #include +#include constexpr const char *PORTALFILE = "PRT1"; constexpr const char *PORTALFILE2 = "PRT2"; @@ -171,3 +172,28 @@ prtfile_t LoadPrtFile(const fs::path &name, const bspversion_t *loadversion) return result; } + +static void WriteDebugPortal(const polylib::winding_t &w, std::ofstream &portalFile) +{ + fmt::print(portalFile, "{} {} {} ", w.size(), 0, 0); + for (int i = 0; i < w.size(); i++) { + fmt::print(portalFile, "({} {} {}) ", w.at(i)[0], w.at(i)[1], w.at(i)[2]); + } + fmt::print(portalFile, "\n"); +} + +void WriteDebugPortals(const std::vector &portals, fs::path name) +{ + size_t portal_count = portals.size(); + + std::ofstream portal_file(name, std::ios_base::binary | std::ios_base::out); + if (!portal_file) + FError("Failed to open {}: {}", name, strerror(errno)); + + fmt::print(portal_file, "PRT1\n"); + fmt::print(portal_file, "{}\n", 0); + fmt::print(portal_file, "{}\n", portal_count); + for (auto &p : portals) { + WriteDebugPortal(p, portal_file); + } +} diff --git a/include/common/aabb.hh b/include/common/aabb.hh index 30372517..095aae63 100644 --- a/include/common/aabb.hh +++ b/include/common/aabb.hh @@ -228,6 +228,21 @@ public: auto stream_data() { return std::tie(m_corners); } }; +template +inline std::array, 6> aabb_planes(const aabb &bbox) +{ + return { + qplane3{qvec( 1,0,0), bbox.maxs()[0]}, // +X + qplane3{qvec(-1,0,0), -bbox.mins()[0]}, // -X + + qplane3{qvec(0, 1,0), bbox.maxs()[1]}, // +Y + qplane3{qvec(0,-1,0), -bbox.mins()[1]}, // -Y + + qplane3{qvec(0,0, 1), bbox.maxs()[2]}, // +Z + qplane3{qvec(0,0,-1), -bbox.mins()[2]}, // -Z + }; +} + // Fmt support template struct fmt::formatter> : formatter> diff --git a/include/common/polylib.hh b/include/common/polylib.hh index 3b70ec81..d85c4ca8 100644 --- a/include/common/polylib.hh +++ b/include/common/polylib.hh @@ -1321,6 +1321,33 @@ public: { return directional_equal(w, equal_epsilon) || directional_equal(w.flip(), equal_epsilon); } + + static std::array aabb_windings(const aabb3d &bbox) { + double worldextent = 0; + for (int i = 0; i < 3; ++i) { + worldextent = max(worldextent, abs(bbox.maxs()[i])); + worldextent = max(worldextent, abs(bbox.mins()[i])); + } + worldextent += 1; + + std::array result; + auto planes = aabb_planes(bbox); + + for (int i = 0; i < 6; ++i) { + result[i] = winding_base_t::from_plane(planes[i], worldextent); + } + + for (int i = 0; i < 6; ++i) { + for (int j = 0; j < 6; ++j) { + if (i == j) + continue; + + result[i] = *result[i].clip_back(planes[j]); + } + } + + return result; + } }; // the default amount of points to keep on stack diff --git a/include/common/prtfile.hh b/include/common/prtfile.hh index e3509141..3e4ce620 100644 --- a/include/common/prtfile.hh +++ b/include/common/prtfile.hh @@ -50,3 +50,4 @@ struct prtfile_t struct bspversion_t; prtfile_t LoadPrtFile(const fs::path &name, const bspversion_t *loadversion); +void WriteDebugPortals(const std::vector &portals, fs::path name); diff --git a/light/lightgrid.cc b/light/lightgrid.cc index 291fe4cc..af26dc1e 100644 --- a/light/lightgrid.cc +++ b/light/lightgrid.cc @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -96,6 +97,10 @@ void LightGrid(bspdata_t *bspdata) ceil(world_size[2] / light_options.lightgrid_dist.value()[2]) }; + auto grid_index_to_world = [&](const qvec3i &index) -> qvec3f { + return grid_mins + (index * light_options.lightgrid_dist.value()); + }; + std::vector grid_result; grid_result.resize(grid_size[0] * grid_size[1] * grid_size[2]); @@ -414,6 +419,25 @@ void LightGrid(bspdata_t *bspdata) // build the root node const uint32_t root_node = build_octree(qvec3i{0,0,0}, grid_size, 0); + // visualize the leafs + { + std::vector windings; + + for (auto &leaf : octree_leafs) { + auto leaf_world_mins = grid_index_to_world(leaf.mins); + auto leaf_world_maxs = grid_index_to_world(leaf.mins + leaf.size - qvec3i(1,1,1)); + + aabb3d bounds(leaf_world_mins, leaf_world_maxs); + + auto bounds_windings = polylib::winding_t::aabb_windings(bounds); + for (auto &w : bounds_windings) { + windings.push_back(std::move(w)); + } + } + + WriteDebugPortals(windings, fs::path(light_options.sourceMap).replace_extension(".octree.prt")); + } + // stats int stored_cells = 0; for (auto &leaf : octree_leafs) {