diff --git a/.clang-format b/.clang-format index bfb4af2a..06b52a48 100644 --- a/.clang-format +++ b/.clang-format @@ -27,7 +27,7 @@ AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false BinPackArguments: true BinPackParameters: true -BreakBeforeBraces: Linux +BreakBeforeBraces: Custom BraceWrapping: AfterCaseLabel: false AfterClass: true @@ -39,7 +39,7 @@ BraceWrapping: AfterStruct: true AfterUnion: true AfterExternBlock: true - BeforeCatch: true + BeforeCatch: false BeforeElse: false BeforeLambdaBody: false BeforeWhile: false diff --git a/bspinfo/main.cc b/bspinfo/main.cc index b25df50b..a0e16bcb 100644 --- a/bspinfo/main.cc +++ b/bspinfo/main.cc @@ -67,17 +67,14 @@ static void PrintBSPTextureUsage(const mbsp_t &bsp) static void FindInfiniteChains(const mbsp_t &bsp) { - for (auto &ti : bsp.texinfo) - { + for (auto &ti : bsp.texinfo) { if (ti.nexttexinfo == -1) continue; int loop = 0; - for (int i = ti.nexttexinfo; i != -1; i = bsp.texinfo[i].nexttexinfo, loop++) - { - if (loop > bsp.texinfo.size()) - { + for (int i = ti.nexttexinfo; i != -1; i = bsp.texinfo[i].nexttexinfo, loop++) { + if (loop > bsp.texinfo.size()) { printf("INFINITE LOOP!"); exit(1); } diff --git a/bsputil/bsputil.cc b/bsputil/bsputil.cc index 014b9fd4..5d47f053 100644 --- a/bsputil/bsputil.cc +++ b/bsputil/bsputil.cc @@ -593,8 +593,7 @@ int main(int argc, char **argv) const qvec3d pos{std::stof(argv[i + 1]), std::stof(argv[i + 2]), std::stof(argv[i + 3])}; const qvec3d normal{std::stof(argv[i + 4]), std::stof(argv[i + 5]), std::stof(argv[i + 6])}; FindFaces(&bsp, pos, normal); - } - catch (const std::exception &) { + } catch (const std::exception &) { Error("Error reading position/normal\n"); } return 0; @@ -618,7 +617,8 @@ int main(int argc, char **argv) WriteBSPFile(source, &bspdata); return 0; - } else if (!strcmp(argv[i], "--decompile") || !strcmp(argv[i], "--decompile-geomonly") || !strcmp(argv[i], "--decompile-ignore-brushes")) { + } else if (!strcmp(argv[i], "--decompile") || !strcmp(argv[i], "--decompile-geomonly") || + !strcmp(argv[i], "--decompile-ignore-brushes")) { const bool geomOnly = !strcmp(argv[i], "--decompile-geomonly"); const bool ignoreBrushes = !strcmp(argv[i], "--decompile-ignore-brushes"); diff --git a/common/bspfile.cc b/common/bspfile.cc index 30cae075..e20226fd 100644 --- a/common/bspfile.cc +++ b/common/bspfile.cc @@ -65,23 +65,13 @@ private: constexpr bool operator==(const q1_contentflags_data &other) const { - return is_origin == other.is_origin - && is_clip == other.is_clip - && is_fence == other.is_fence - && is_mist == other.is_mist - && is_detail == other.is_detail; + return is_origin == other.is_origin && is_clip == other.is_clip && is_fence == other.is_fence && + is_mist == other.is_mist && is_detail == other.is_detail; } constexpr bool operator!=(const q1_contentflags_data &other) const { return !(*this == other); } - constexpr explicit operator bool() const - { - return is_origin - || is_clip - || is_fence - || is_mist - || is_detail; - } + constexpr explicit operator bool() const { return is_origin || is_clip || is_fence || is_mist || is_detail; } }; // returns a blank entry if the given contents don't have @@ -124,7 +114,8 @@ private: constexpr size_t size() const { return 11; } constexpr size_t last_visible_contents() const { return 6; } - constexpr bitset_t bitset() const { + constexpr bitset_t bitset() const + { bitset_t result; result[0] = solid; result[1] = sky; @@ -143,27 +134,18 @@ private: } q1_contentflags_bits() = default; - explicit q1_contentflags_bits(const bitset_t& bitset) : - solid(bitset[0]), - sky(bitset[1]), - fence(bitset[2]), - lava(bitset[3]), - slime(bitset[4]), - water(bitset[5]), - mist(bitset[6]), - origin(bitset[7]), - clip(bitset[8]), - illusionary_visblocker(bitset[9]), - detail(bitset[10]), - mirror_inside(bitset[11]), - suppress_clipping_same_type(bitset[12]) {} + explicit q1_contentflags_bits(const bitset_t &bitset) + : solid(bitset[0]), sky(bitset[1]), fence(bitset[2]), lava(bitset[3]), slime(bitset[4]), water(bitset[5]), + mist(bitset[6]), origin(bitset[7]), clip(bitset[8]), illusionary_visblocker(bitset[9]), + detail(bitset[10]), mirror_inside(bitset[11]), suppress_clipping_same_type(bitset[12]) + { + } - static constexpr const char *bitflag_names[] = {"SOLID", "SKY", "FENCE", "LAVA", - "SLIME", "WATER", "MIST", "ORIGIN", "CLIP", "ILLUSIONARY_VISBLOCKER", "DETAIL", - "MIRROR_INSIDE", "SUPPRESS_CLIPPING_SAME_TYPE" - }; + static constexpr const char *bitflag_names[] = {"SOLID", "SKY", "FENCE", "LAVA", "SLIME", "WATER", "MIST", + "ORIGIN", "CLIP", "ILLUSIONARY_VISBLOCKER", "DETAIL", "MIRROR_INSIDE", "SUPPRESS_CLIPPING_SAME_TYPE"}; - constexpr bool operator[](size_t index) const { + constexpr bool operator[](size_t index) const + { switch (index) { case 0: return solid; case 1: return sky; @@ -182,7 +164,8 @@ private: } } - constexpr bool& operator[](size_t index) { + constexpr bool &operator[](size_t index) + { switch (index) { case 0: return solid; case 1: return sky; @@ -201,22 +184,22 @@ private: } } - constexpr q1_contentflags_bits operator|(const q1_contentflags_bits &other) const { + constexpr q1_contentflags_bits operator|(const q1_contentflags_bits &other) const + { return q1_contentflags_bits(bitset() | other.bitset()); } - constexpr q1_contentflags_bits operator^(const q1_contentflags_bits &other) const { + constexpr q1_contentflags_bits operator^(const q1_contentflags_bits &other) const + { return q1_contentflags_bits(bitset() ^ other.bitset()); } - constexpr bool operator==(const q1_contentflags_bits &other) const - { - return bitset() == other.bitset(); - } + constexpr bool operator==(const q1_contentflags_bits &other) const { return bitset() == other.bitset(); } constexpr bool operator!=(const q1_contentflags_bits &other) const { return !(*this == other); } - constexpr int32_t visible_contents_index() const { + constexpr int32_t visible_contents_index() const + { for (size_t i = 0; i <= last_visible_contents(); ++i) { if ((*this)[i]) { return static_cast(i); @@ -226,7 +209,8 @@ private: return -1; } - constexpr q1_contentflags_bits visible_contents() const { + constexpr q1_contentflags_bits visible_contents() const + { q1_contentflags_bits result; int32_t index = visible_contents_index(); @@ -237,7 +221,8 @@ private: return result; } - constexpr bool empty() const { + constexpr bool empty() const + { // fixme-brushbsp: what should we do with empty, but the detail flag set? q1_contentflags_bits empty_test; return (*this) == empty_test; @@ -250,21 +235,11 @@ private: // set bit for native contents switch (contents.native) { - case CONTENTS_SOLID: - result.solid = true; - break; - case CONTENTS_WATER: - result.water = true; - break; - case CONTENTS_SLIME: - result.slime = true; - break; - case CONTENTS_LAVA: - result.lava = true; - break; - case CONTENTS_SKY: - result.sky = true; - break; + case CONTENTS_SOLID: result.solid = true; break; + case CONTENTS_WATER: result.water = true; break; + case CONTENTS_SLIME: result.slime = true; break; + case CONTENTS_LAVA: result.lava = true; break; + case CONTENTS_SKY: result.sky = true; break; } // copy in extra flags @@ -321,7 +296,6 @@ private: } public: - explicit gamedef_q1_like_t(const char *base_dir = "ID1") : gamedef_t(base_dir) { this->id = ID; } bool surf_is_lightmapped(const surfflags_t &flags) const override { return !(flags.native & TEX_SPECIAL); } @@ -451,11 +425,8 @@ public: const auto visible = bits.visible_contents(); - // If the brush is non-solid, mirror faces for the inside view - return visible.water - || visible.slime - || visible.lava; + return visible.water || visible.slime || visible.lava; } bool contents_are_origin(const contentflags_t &contents) const override @@ -532,7 +503,9 @@ public: return 0; } - bool portal_can_see_through(const contentflags_t &contents0, const contentflags_t &contents1, bool transwater, bool transsky) const override { + bool portal_can_see_through( + const contentflags_t &contents0, const contentflags_t &contents1, bool transwater, bool transsky) const override + { auto bits_a = contentflags_to_bits(contents0); auto bits_b = contentflags_to_bits(contents1); @@ -548,10 +521,10 @@ public: bits_b = q1_contentflags_bits(); if (bits_a.solid || bits_b.solid) - return false; // can't see through solid + return false; // can't see through solid if ((bits_a ^ bits_b).empty()) - return true; // identical on both sides + return true; // identical on both sides if ((bits_a ^ bits_b).visible_contents().empty()) return true; @@ -598,8 +571,7 @@ public: q1_contentflags_bits result; - if (bits_a.suppress_clipping_same_type - || bits_b.suppress_clipping_same_type) { + if (bits_a.suppress_clipping_same_type || bits_b.suppress_clipping_same_type) { result = bits_a | bits_b; } else { result = bits_a ^ bits_b; @@ -610,7 +582,8 @@ public: return contentflags_from_bits(strongest_contents_change); } - bool portal_generates_face(const contentflags_t &portal_visible_contents, const contentflags_t &brushcontents, planeside_t brushside_side) const override + bool portal_generates_face(const contentflags_t &portal_visible_contents, const contentflags_t &brushcontents, + planeside_t brushside_side) const override { auto bits_portal = contentflags_to_bits(portal_visible_contents); auto bits_brush = contentflags_to_bits(brushcontents); @@ -627,10 +600,7 @@ public: } if (brushside_side == SIDE_BACK) { - return bits_brush.mirror_inside - || bits_brush.water - || bits_brush.slime - || bits_brush.lava; + return bits_brush.mirror_inside || bits_brush.water || bits_brush.slime || bits_brush.lava; } return true; } @@ -668,7 +638,7 @@ public: // todo: anything smarter we can do here? // think this can't even happen in Q1 anyways if (!contents_are_valid(contents, false)) { - contents = { CONTENTS_SOLID }; + contents = {CONTENTS_SOLID}; } } @@ -680,7 +650,8 @@ public: return hulls; } - contentflags_t face_get_contents(const std::string &texname, const surfflags_t &flags, const contentflags_t &) const override + contentflags_t face_get_contents( + const std::string &texname, const surfflags_t &flags, const contentflags_t &) const override { // check for strong content indicators if (!Q_strcasecmp(texname.data(), "origin")) { @@ -804,7 +775,8 @@ public: const content_stats_t &stats = dynamic_cast(stats_any); for (auto [bits, count] : stats.native_types) { - logging::print(logging::flag::STAT, " {:8} {} {}\n", count, get_contents_display(q1_contentflags_bits(bits)), what); + logging::print(logging::flag::STAT, " {:8} {} {}\n", count, + get_contents_display(q1_contentflags_bits(bits)), what); } logging::print(logging::flag::STAT, " {:8} {} total\n", stats.total_brushes, what); @@ -895,7 +867,10 @@ struct gamedef_q2_t : public gamedef_t max_entity_key = 256; } - bool surf_is_lightmapped(const surfflags_t &flags) const override { return !(flags.native & (Q2_SURF_NODRAW | Q2_SURF_SKIP)); } + bool surf_is_lightmapped(const surfflags_t &flags) const override + { + return !(flags.native & (Q2_SURF_NODRAW | Q2_SURF_SKIP)); + } bool surf_is_subdivided(const surfflags_t &flags) const override { return !(flags.native & Q2_SURF_SKY); } @@ -905,8 +880,8 @@ struct gamedef_q2_t : public gamedef_t return true; } - static constexpr const char *surf_bitflag_names[] = {"LIGHT", "SLICK", "SKY", "WARP", "TRANS33", "TRANS66", "FLOWING", "NODRAW", - "HINT" }; + static constexpr const char *surf_bitflag_names[] = { + "LIGHT", "SLICK", "SKY", "WARP", "TRANS33", "TRANS66", "FLOWING", "NODRAW", "HINT"}; int32_t surfflags_from_string(const std::string_view &str) const override { @@ -919,7 +894,8 @@ struct gamedef_q2_t : public gamedef_t return 0; } - bool texinfo_is_hintskip(const surfflags_t &flags, const std::string &name) const override { + bool texinfo_is_hintskip(const surfflags_t &flags, const std::string &name) const override + { // any face in a hint brush that isn't HINT are treated as "hintskip", and discarded return !(flags.native & Q2_SURF_HINT); } @@ -941,30 +917,33 @@ struct gamedef_q2_t : public gamedef_t inline int32_t get_content_type(const contentflags_t &contents) const { - return contents.native & (Q2_ALL_VISIBLE_CONTENTS | - (Q2_CONTENTS_PLAYERCLIP | Q2_CONTENTS_MONSTERCLIP | Q2_CONTENTS_ORIGIN | - Q2_CONTENTS_TRANSLUCENT | Q2_CONTENTS_AREAPORTAL)); + return contents.native & + (Q2_ALL_VISIBLE_CONTENTS | (Q2_CONTENTS_PLAYERCLIP | Q2_CONTENTS_MONSTERCLIP | Q2_CONTENTS_ORIGIN | + Q2_CONTENTS_TRANSLUCENT | Q2_CONTENTS_AREAPORTAL)); } contentflags_t create_empty_contents() const override { return {Q2_CONTENTS_EMPTY}; } contentflags_t create_solid_contents() const override { return {Q2_CONTENTS_SOLID}; } - contentflags_t create_detail_illusionary_contents(const contentflags_t &original) const override { + contentflags_t create_detail_illusionary_contents(const contentflags_t &original) const override + { contentflags_t result = original; result.native &= ~Q2_CONTENTS_SOLID; result.native |= Q2_CONTENTS_MIST | Q2_CONTENTS_DETAIL; return result; } - contentflags_t create_detail_fence_contents(const contentflags_t &original) const override { + contentflags_t create_detail_fence_contents(const contentflags_t &original) const override + { contentflags_t result = original; result.native &= ~Q2_CONTENTS_SOLID; result.native |= (Q2_CONTENTS_WINDOW | Q2_CONTENTS_TRANSLUCENT | Q2_CONTENTS_DETAIL); return result; } - contentflags_t create_detail_solid_contents(const contentflags_t &original) const override { + contentflags_t create_detail_solid_contents(const contentflags_t &original) const override + { contentflags_t result = original; result.native |= (Q2_CONTENTS_SOLID | Q2_CONTENTS_DETAIL); return result; @@ -978,8 +957,7 @@ struct gamedef_q2_t : public gamedef_t bool contents_are_equal(const contentflags_t &self, const contentflags_t &other) const override { - return self.illusionary_visblocker == other.illusionary_visblocker && - self.native == other.native; + return self.illusionary_visblocker == other.illusionary_visblocker && self.native == other.native; } bool contents_are_any_detail(const contentflags_t &contents) const override @@ -989,7 +967,7 @@ struct gamedef_q2_t : public gamedef_t bool contents_are_detail_solid(const contentflags_t &contents) const override { - int32_t test = (Q2_CONTENTS_DETAIL|Q2_CONTENTS_SOLID); + int32_t test = (Q2_CONTENTS_DETAIL | Q2_CONTENTS_SOLID); return ((contents.native & test) == test); } @@ -1000,7 +978,7 @@ struct gamedef_q2_t : public gamedef_t return false; } - int32_t test = (Q2_CONTENTS_DETAIL|Q2_CONTENTS_WINDOW); + int32_t test = (Q2_CONTENTS_DETAIL | Q2_CONTENTS_WINDOW); return ((contents.native & test) == test); } @@ -1010,11 +988,10 @@ struct gamedef_q2_t : public gamedef_t return false; } - int32_t mist1_type = (Q2_CONTENTS_DETAIL|Q2_CONTENTS_MIST); - int32_t mist2_type = (Q2_CONTENTS_DETAIL|Q2_CONTENTS_AUX); + int32_t mist1_type = (Q2_CONTENTS_DETAIL | Q2_CONTENTS_MIST); + int32_t mist2_type = (Q2_CONTENTS_DETAIL | Q2_CONTENTS_AUX); - return ((contents.native & mist1_type) == mist1_type) - || ((contents.native & mist2_type) == mist2_type); + return ((contents.native & mist1_type) == mist1_type) || ((contents.native & mist2_type) == mist2_type); } bool contents_are_mirrored(const contentflags_t &contents) const override @@ -1039,16 +1016,14 @@ struct gamedef_q2_t : public gamedef_t { return contents.native & (Q2_CONTENTS_PLAYERCLIP | Q2_CONTENTS_MONSTERCLIP); } - + bool contents_clip_same_type(const contentflags_t &self, const contentflags_t &other) const override { - return (self.native & Q2_ALL_VISIBLE_CONTENTS) == (other.native & Q2_ALL_VISIBLE_CONTENTS) && self.clips_same_type.value_or(true); + return (self.native & Q2_ALL_VISIBLE_CONTENTS) == (other.native & Q2_ALL_VISIBLE_CONTENTS) && + self.clips_same_type.value_or(true); } - inline bool contents_has_extended(const contentflags_t &contents) const - { - return contents.illusionary_visblocker; - } + inline bool contents_has_extended(const contentflags_t &contents) const { return contents.illusionary_visblocker; } bool contents_are_empty(const contentflags_t &contents) const override { @@ -1062,9 +1037,8 @@ struct gamedef_q2_t : public gamedef_t bool contents_are_solid(const contentflags_t &contents) const override { - return !contents_has_extended(contents) && - (contents.native & Q2_CONTENTS_SOLID) && - !(contents.native & Q2_CONTENTS_DETAIL); + return !contents_has_extended(contents) && (contents.native & Q2_CONTENTS_SOLID) && + !(contents.native & Q2_CONTENTS_DETAIL); } bool contents_are_sky(const contentflags_t &contents) const override { return false; } @@ -1094,9 +1068,9 @@ struct gamedef_q2_t : public gamedef_t } static constexpr const char *bitflag_names[] = {"SOLID", "WINDOW", "AUX", "LAVA", "SLIME", "WATER", "MIST", "128", - "256", "512", "1024", "2048", "4096", "8192", "16384", "AREAPORTAL", "PLAYERCLIP", "MONSTERCLIP", - "CURRENT_0", "CURRENT_90", "CURRENT_180", "CURRENT_270", "CURRENT_UP", "CURRENT_DOWN", "ORIGIN", "MONSTER", - "DEADMONSTER", "DETAIL", "TRANSLUCENT", "LADDER", "1073741824", "2147483648"}; + "256", "512", "1024", "2048", "4096", "8192", "16384", "AREAPORTAL", "PLAYERCLIP", "MONSTERCLIP", "CURRENT_0", + "CURRENT_90", "CURRENT_180", "CURRENT_270", "CURRENT_UP", "CURRENT_DOWN", "ORIGIN", "MONSTER", "DEADMONSTER", + "DETAIL", "TRANSLUCENT", "LADDER", "1073741824", "2147483648"}; int32_t contents_from_string(const std::string_view &str) const { @@ -1127,8 +1101,7 @@ struct gamedef_q2_t : public gamedef_t { contentflags_t result; - if (!a.clips_same_type.value_or(true) - || !b.clips_same_type.value_or(true)) { + if (!a.clips_same_type.value_or(true) || !b.clips_same_type.value_or(true)) { result.native = visible_contents(a.native | b.native); } else { result.native = visible_contents(a.native ^ b.native); @@ -1136,7 +1109,8 @@ struct gamedef_q2_t : public gamedef_t return result; } - bool portal_can_see_through(const contentflags_t &contents0, const contentflags_t &contents1, bool, bool) const override + bool portal_can_see_through( + const contentflags_t &contents0, const contentflags_t &contents1, bool, bool) const override { int32_t c0 = contents0.native, c1 = contents1.native; @@ -1163,15 +1137,12 @@ struct gamedef_q2_t : public gamedef_t return !visible_contents(c0 ^ c1); } - bool contents_seals_map(const contentflags_t& contents) const override + bool contents_seals_map(const contentflags_t &contents) const override { return contents_are_solid(contents) || contents_are_sky(contents); } - contentflags_t contents_remap_for_export(const contentflags_t &contents) const override - { - return contents; - } + contentflags_t contents_remap_for_export(const contentflags_t &contents) const override { return contents; } contentflags_t combine_contents(const contentflags_t &a, const contentflags_t &b) const override { @@ -1187,7 +1158,8 @@ struct gamedef_q2_t : public gamedef_t return result; } - bool portal_generates_face(const contentflags_t &portal_visible_contents, const contentflags_t &brushcontents, planeside_t brushside_side) const override + bool portal_generates_face(const contentflags_t &portal_visible_contents, const contentflags_t &brushcontents, + planeside_t brushside_side) const override { if ((portal_visible_contents.native & brushcontents.native) == 0) { return false; @@ -1216,7 +1188,7 @@ struct gamedef_q2_t : public gamedef_t if (s.size()) { s += " | "; } - + s += bitflag_names[i]; } } @@ -1317,13 +1289,13 @@ public: void init_filesystem(const fs::path &source, const settings::common_settings &options) const override { fs::clear(); - + if (options.defaultpaths.value()) { constexpr const char *MAPS_FOLDER = "maps"; // detect gamedir (mod directory path) fs::path gamedir, basedir; - + // pull in from settings if (options.gamedir.isChanged()) { gamedir = options.gamedir.value(); @@ -1331,7 +1303,7 @@ public: if (options.basedir.isChanged()) { basedir = options.basedir.value(); } - + // figure out the gamedir first if (!gamedir.is_absolute()) { if (!gamedir.empty() && basedir.is_absolute()) { @@ -1354,7 +1326,8 @@ public: gamedir = fs::weakly_canonical(source).parent_path(); if (!string_iequals(gamedir.filename().generic_string(), MAPS_FOLDER)) { - logging::print("WARNING: '{}' is not directly inside '{}'; gamedir can't be automatically determined.\n", + logging::print( + "WARNING: '{}' is not directly inside '{}'; gamedir can't be automatically determined.\n", source, MAPS_FOLDER); } @@ -1443,7 +1416,7 @@ private: struct content_stats_t : public content_stats_base_t { std::mutex stat_mutex; - //std::array, 32> native_types; + // std::array, 32> native_types; std::unordered_map native_types; std::atomic total_brushes; std::atomic visblocker_brushes; @@ -1482,7 +1455,8 @@ public: /*for (int32_t i = 0; i < 32; i++) { if (stats.native_types[i]) { - logging::print(logging::flag::STAT, " {:8} {} {}\n", stats.native_types[i], get_contents_display({nth_bit(i)}), what); + logging::print(logging::flag::STAT, " {:8} {} {}\n", stats.native_types[i], + get_contents_display({nth_bit(i)}), what); } }*/ for (auto &it : stats.native_types) { @@ -1674,9 +1648,8 @@ bool surfflags_t::is_valid(const gamedef_t *game) const bool contentflags_t::equals(const gamedef_t *game, const contentflags_t &other) const { - return game->contents_are_equal(*this, other) && - mirror_inside == other.mirror_inside && - clips_same_type == other.clips_same_type; + return game->contents_are_equal(*this, other) && mirror_inside == other.mirror_inside && + clips_same_type == other.clips_same_type; } bool contentflags_t::types_equal(const contentflags_t &other, const gamedef_t *game) const @@ -1764,11 +1737,13 @@ std::string contentflags_t::to_string(const gamedef_t *game) const std::string s = game->get_contents_display(*this); if (contentflags_t{native}.is_mirrored(game) != is_mirrored(game)) { - s += fmt::format(" | MIRROR_INSIDE[{}]", mirror_inside.has_value() ? (mirror_inside.value() ? "true" : "false") : "nullopt"); + s += fmt::format( + " | MIRROR_INSIDE[{}]", mirror_inside.has_value() ? (mirror_inside.value() ? "true" : "false") : "nullopt"); } if (contentflags_t{native}.will_clip_same_type(game) != will_clip_same_type(game)) { - s += fmt::format(" | CLIPS_SAME_TYPE[{}]", clips_same_type.has_value() ? (clips_same_type.value() ? "true" : "false") : "nullopt"); + s += fmt::format(" | CLIPS_SAME_TYPE[{}]", + clips_same_type.has_value() ? (clips_same_type.value() ? "true" : "false") : "nullopt"); } if (illusionary_visblocker) { @@ -2008,8 +1983,7 @@ bool ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version) } else { return false; } - } - catch (std::overflow_error e) { + } catch (std::overflow_error e) { logging::print("LIMITS EXCEEDED ON {}\n", e.what()); return false; } @@ -2074,7 +2048,7 @@ struct lump_reader s.read(reinterpret_cast(buffer.data()), length); } - Q_assert((bool) s); + Q_assert((bool)s); } // read string from stream @@ -2104,7 +2078,7 @@ struct lump_reader } // TODO: warn about bad .bsp if missing \0? - Q_assert((bool) s); + Q_assert((bool)s); } // read structured lump data from stream into struct @@ -2124,7 +2098,7 @@ struct lump_reader buffer.stream_read(s, lump); - Q_assert((bool) s); + Q_assert((bool)s); } }; @@ -2291,8 +2265,9 @@ void LoadBSPFile(fs::path &filename, bspdata_t *bspdata) logging::print("WARNING: invalid BSPX lump at index {}\n", i); return; } - - bspdata->bspx.transfer(xlump.lumpname.data(), std::vector(file_data->begin() + xlump.fileofs, file_data->begin() + xlump.fileofs + xlump.filelen)); + + bspdata->bspx.transfer(xlump.lumpname.data(), std::vector(file_data->begin() + xlump.fileofs, + file_data->begin() + xlump.fileofs + xlump.filelen)); } } } diff --git a/common/bspinfo.cc b/common/bspinfo.cc index bbdf14cf..2b2ef30b 100644 --- a/common/bspinfo.cc +++ b/common/bspinfo.cc @@ -174,7 +174,11 @@ static std::string serialize_image(const std::optional &texture_op auto &texture = texture_opt.value(); std::vector buf; - stbi_write_png_to_func([](void *context, void *data, int size) { std::copy(reinterpret_cast(data), reinterpret_cast(data) + size, std::back_inserter(*reinterpret_cast(context))); }, + stbi_write_png_to_func( + [](void *context, void *data, int size) { + std::copy(reinterpret_cast(data), reinterpret_cast(data) + size, + std::back_inserter(*reinterpret_cast(context))); + }, &buf, texture.meta.width, texture.meta.height, 4, texture.pixels.data(), texture.width * 4); std::string str{"data:image/png;base64,"}; @@ -189,10 +193,11 @@ static std::string serialize_image(const std::optional &texture_op static faceextents_t get_face_extents(const mbsp_t &bsp, const bspxentries_t &bspx, const mface_t &face, bool use_bspx) { if (!use_bspx) { - return { face, bsp, 16.0 }; + return {face, bsp, 16.0}; } - return { face, bsp, (float) nth_bit(reinterpret_cast(bspx.at("LMSHIFT").data())[&face - bsp.dfaces.data()]) }; + return {face, bsp, + (float)nth_bit(reinterpret_cast(bspx.at("LMSHIFT").data())[&face - bsp.dfaces.data()])}; } static json generate_lightmap_atlases(const mbsp_t &bsp, const bspxentries_t &bspx, bool use_bspx) @@ -240,9 +245,9 @@ static json generate_lightmap_atlases(const mbsp_t &bsp, const bspxentries_t &bs bspx_lmoffset >= faceofs; } - rectangles.emplace_back(face_rect { &face, get_face_extents(bsp, bspx, face, use_bspx), faceofs }); + rectangles.emplace_back(face_rect{&face, get_face_extents(bsp, bspx, face, use_bspx), faceofs}); } - + if (!rectangles.size()) { return nullptr; } @@ -279,7 +284,7 @@ static json generate_lightmap_atlases(const mbsp_t &bsp, const bspxentries_t &bs continue; } - atl.tallest = max(atl.tallest, (size_t) rect.extents.height()); + atl.tallest = max(atl.tallest, (size_t)rect.extents.height()); rect.x = atl.current_x; rect.y = atl.current_y; rect.atlas = current_atlas; @@ -342,7 +347,8 @@ static json generate_lightmap_atlases(const mbsp_t &bsp, const bspxentries_t &bs continue; } - auto in_pixel = bsp.dlightdata.begin() + rect.lightofs + (rect.extents.numsamples() * (is_rgb ? 3 : 1) * style_index); + auto in_pixel = + bsp.dlightdata.begin() + rect.lightofs + (rect.extents.numsamples() * (is_rgb ? 3 : 1) * style_index); for (size_t y = 0; y < rect.extents.height(); y++) { for (size_t x = 0; x < rect.extents.width(); x++) { @@ -373,8 +379,7 @@ static json generate_lightmap_atlases(const mbsp_t &bsp, const bspxentries_t &bs memset(full_atlas.pixels.data(), 0, sizeof(*full_atlas.pixels.data()) * full_atlas.pixels.size()); } - auto ExportObjFace = [&full_atlas](std::iostream &f, const mbsp_t *bsp, const face_rect &face, int &vertcount) - { + auto ExportObjFace = [&full_atlas](std::iostream &f, const mbsp_t *bsp, const face_rect &face, int &vertcount) { // export the vertices and uvs for (int i = 0; i < face.face->numedges; i++) { const int vertnum = Face_VertexAtIndex(bsp, face.face, i); @@ -386,7 +391,7 @@ static json generate_lightmap_atlases(const mbsp_t &bsp, const bspxentries_t &bs auto tc = face.extents.worldToLMCoord(pos); tc[0] += face.x; tc[1] += face.y; - + tc[0] /= full_atlas.width; tc[1] /= full_atlas.height; @@ -407,8 +412,7 @@ static json generate_lightmap_atlases(const mbsp_t &bsp, const bspxentries_t &bs vertcount += face.face->numedges; }; - auto ExportObj = [&ExportObjFace, &rectangles](const mbsp_t *bsp) - { + auto ExportObj = [&ExportObjFace, &rectangles](const mbsp_t *bsp) { std::stringstream objfile; int vertcount = 0; @@ -525,7 +529,7 @@ void serialize_bsp(const bspdata_t &bspdata, const mbsp_t &bsp, const fs::path & node.push_back({"numfaces", src_node.numfaces}); // human-readable plane - auto& plane = bsp.dplanes.at(src_node.planenum); + auto &plane = bsp.dplanes.at(src_node.planenum); node.push_back({"plane", json::array({plane.normal[0], plane.normal[1], plane.normal[2], plane.dist})}); } } @@ -656,8 +660,9 @@ void serialize_bsp(const bspdata_t &bspdata, const mbsp_t &bsp, const fs::path & tex.push_back({"height", src_tex.height}); if (src_tex.data.size() > sizeof(dmiptex_t)) { - json &mips = tex["mips"] = json::array(); - mips.emplace_back(serialize_image(img::load_mip(src_tex.name, src_tex.data, false, bspdata.loadversion->game))); + json &mips = tex["mips"] = json::array(); + mips.emplace_back( + serialize_image(img::load_mip(src_tex.name, src_tex.data, false, bspdata.loadversion->game))); } } } @@ -673,8 +678,7 @@ void serialize_bsp(const bspdata_t &bspdata, const mbsp_t &bsp, const fs::path & entry["models"] = serialize_bspxbrushlist(lump.second); } else { // unhandled BSPX lump, just write the raw data - entry["lumpdata"] = - hex_string(lump.second.data(), lump.second.size()); + entry["lumpdata"] = hex_string(lump.second.data(), lump.second.size()); } } } diff --git a/common/bsputils.cc b/common/bsputils.cc index ff0218ab..a68d419f 100644 --- a/common/bsputils.cc +++ b/common/bsputils.cc @@ -322,8 +322,8 @@ static bool EdgePlanes_PointInside(const std::vector &edgeplanes, cons /** * pass 0,0,0 for wantedNormal to disable the normal check */ -static void BSP_FindFaceAtPoint_r( - const mbsp_t *bsp, const int nodenum, const qvec3d &point, const qvec3d &wantedNormal, std::vector &result) +static void BSP_FindFaceAtPoint_r(const mbsp_t *bsp, const int nodenum, const qvec3d &point, const qvec3d &wantedNormal, + std::vector &result) { if (nodenum < 0) { // we're only interested in nodes, since faces are owned by nodes. @@ -384,8 +384,8 @@ const mface_t *BSP_FindFaceAtPoint( std::vector result; BSP_FindFaceAtPoint_r(bsp, model->headnode[0], point, wantedNormal, result); - if (result.empty()) { - return nullptr; + if (result.empty()) { + return nullptr; } return result[0]; } @@ -420,14 +420,13 @@ static const bsp2_dnode_t *BSP_FindNodeAtPoint_r( } } -const bsp2_dnode_t* BSP_FindNodeAtPoint( +const bsp2_dnode_t *BSP_FindNodeAtPoint( const mbsp_t *bsp, const dmodelh2_t *model, const qvec3d &point, const qvec3d &wanted_normal) { return BSP_FindNodeAtPoint_r(bsp, model->headnode[0], point, wanted_normal); } -static const mleaf_t *BSP_FindLeafAtPoint_r( - const mbsp_t *bsp, const int nodenum, const qvec3d &point) +static const mleaf_t *BSP_FindLeafAtPoint_r(const mbsp_t *bsp, const int nodenum, const qvec3d &point) { if (nodenum < 0) { return BSP_GetLeafFromNodeNum(bsp, nodenum); @@ -443,13 +442,12 @@ static const mleaf_t *BSP_FindLeafAtPoint_r( } } -const mleaf_t* BSP_FindLeafAtPoint(const mbsp_t* bsp, const dmodelh2_t* model, const qvec3d& point) +const mleaf_t *BSP_FindLeafAtPoint(const mbsp_t *bsp, const dmodelh2_t *model, const qvec3d &point) { return BSP_FindLeafAtPoint_r(bsp, model->headnode[0], point); } -static int BSP_FindClipnodeAtPoint_r( - const mbsp_t *bsp, const int clipnodenum, const qvec3d &point) +static int BSP_FindClipnodeAtPoint_r(const mbsp_t *bsp, const int clipnodenum, const qvec3d &point) { if (clipnodenum < 0) { // actually contents @@ -474,7 +472,7 @@ int BSP_FindContentsAtPoint(const mbsp_t *bsp, int hull, const dmodelh2_t *model return BSP_FindClipnodeAtPoint_r(bsp, model->headnode.at(hull), point); } -std::vector Leaf_Markfaces(const mbsp_t* bsp, const mleaf_t* leaf) +std::vector Leaf_Markfaces(const mbsp_t *bsp, const mleaf_t *leaf) { std::vector result; result.reserve(leaf->nummarksurfaces); @@ -487,7 +485,7 @@ std::vector Leaf_Markfaces(const mbsp_t* bsp, const mleaf_t* lea return result; } -std::vector Leaf_Brushes(const mbsp_t* bsp, const mleaf_t* leaf) +std::vector Leaf_Brushes(const mbsp_t *bsp, const mleaf_t *leaf) { std::vector result; result.reserve(leaf->numleafbrushes); @@ -537,7 +535,7 @@ void Face_DebugPrint(const mbsp_t *bsp, const mface_t *face) const char *texname = Face_TextureName(bsp, face); logging::print("face {}, texture '{}', {} edges; vectors:\n" - "{: 3.3}\n", + "{: 3.3}\n", Face_GetNum(bsp, face), texname, face->numedges, tex->vecs); for (int i = 0; i < face->numedges; i++) { diff --git a/common/cmdlib.cc b/common/cmdlib.cc index 91b17039..79db010d 100644 --- a/common/cmdlib.cc +++ b/common/cmdlib.cc @@ -101,25 +101,25 @@ string_iequals(const std::string_view &a, const std::string_view &b) constexpr uint16_t CRC_INIT_VALUE = 0xffff; -static uint16_t crctable[256] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, - 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, - 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, - 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, - 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, - 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, - 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, - 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, - 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, - 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, - 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, - 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, - 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, - 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, - 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, - 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, - 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, - 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0}; +static uint16_t crctable[256] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, + 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, + 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, + 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, + 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, + 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, + 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, + 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, + 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, + 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, + 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, + 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, + 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, + 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, + 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, + 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, + 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, + 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, + 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0}; void CRC_Init(uint16_t &crcvalue) { @@ -264,8 +264,9 @@ int natstrcmp(const char *s1, const char *s2, bool case_sensitive) numend1 = p1++; while (t_digit(*p2)) numend2 = p2++; - if (numend1 - numstart1 == numend2 - numstart2 && - case_sensitive ? (!strncmp(numstart1, numstart2, numend2 - numstart2 + 1)) : (!Q_strncasecmp(numstart1, numstart2, numend2 - numstart2 + 1))) + if (numend1 - numstart1 == numend2 - numstart2 && case_sensitive + ? (!strncmp(numstart1, numstart2, numend2 - numstart2 + 1)) + : (!Q_strncasecmp(numstart1, numstart2, numend2 - numstart2 + 1))) state = st_scan; else { if (numend1 - numstart1 < numend2 - numstart2) diff --git a/common/entdata.cc b/common/entdata.cc index 4c0145ab..007807d6 100644 --- a/common/entdata.cc +++ b/common/entdata.cc @@ -52,8 +52,7 @@ vec_t entdict_t::get_float(const std::string_view &key) const try { return std::stod(s); - } - catch (std::exception &) { + } catch (std::exception &) { return 0.0; } } @@ -68,8 +67,7 @@ int32_t entdict_t::get_int(const std::string_view &key) const try { return std::stoi(s); - } - catch (std::exception &) { + } catch (std::exception &) { return 0; } } @@ -170,7 +168,6 @@ void entdict_t::parse(parser_base_t &parser) } } - void EntData_ParseInto(const std::string &entdata, std::vector &vector) { parser_t parser(entdata); diff --git a/common/fs.cc b/common/fs.cc index be5fab2b..1769f2e7 100644 --- a/common/fs.cc +++ b/common/fs.cc @@ -140,7 +140,7 @@ struct wad_archive : archive_like auto stream_data() { return std::tie(identification, numlumps, infotableofs); } }; - + static constexpr std::array wad2_ident = {'W', 'A', 'D', '2'}; static constexpr std::array wad3_ident = {'W', 'A', 'D', '3'}; @@ -169,8 +169,7 @@ struct wad_archive : archive_like wadstream >= header; - if (header.identification != wad2_ident && - header.identification != wad3_ident) { + if (header.identification != wad2_ident && header.identification != wad3_ident) { throw std::runtime_error("Bad magic"); } @@ -260,8 +259,7 @@ std::shared_ptr addArchive(const path &p, bool external) } else { logging::funcprint("WARNING: no idea what to do with archive '{}'\n", p); } - } - catch (std::exception e) { + } catch (std::exception e) { logging::funcprint("WARNING: unable to load archive '{}': {}\n", p, e.what()); } } diff --git a/common/imglib.cc b/common/imglib.cc index 95aa236a..f6ba5f54 100644 --- a/common/imglib.cc +++ b/common/imglib.cc @@ -92,7 +92,8 @@ void init_palette(const gamedef_t *game) std::copy(pal.begin(), pal.end(), std::back_inserter(palette)); } -static void convert_paletted_to_32_bit(const std::vector &pixels, std::vector &output, const std::vector &pal) +static void convert_paletted_to_32_bit( + const std::vector &pixels, std::vector &output, const std::vector &pal) { output.resize(pixels.size()); @@ -120,7 +121,8 @@ struct q2_miptex_t auto stream_data() { return std::tie(name, width, height, offsets, animname, flags, contents, value); } }; -std::optional load_wal(const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game) +std::optional load_wal( + const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game) { imemstream stream(file->data(), file->size(), std::ios_base::in | std::ios_base::binary); stream >> endianness; @@ -160,7 +162,8 @@ Quake/Half Life MIP ============================================================================ */ -std::optional load_mip(const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game) +std::optional load_mip( + const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game) { imemstream stream(file->data(), file->size()); stream >> endianness; @@ -178,7 +181,7 @@ std::optional load_mip(const std::string_view &name, const fs::data &fi texture tex; tex.meta.extension = ext::MIP; - + // note: this is a bit of a hack, but the name stored in // the mip is ignored. it's extraneous and well-formed mips // will all match up anyways. @@ -191,7 +194,7 @@ std::optional load_mip(const std::string_view &name, const fs::data &fi if (header.offsets[0] <= 0) { return tex; } - + // convert the data into RGBA. // sanity check if (header.offsets[0] + (header.width * header.height) > file->size()) { @@ -273,7 +276,8 @@ struct targa_t LoadTGA ============= */ -std::optional load_tga(const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game) +std::optional load_tga( + const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game) { imemstream stream(file->data(), file->size(), std::ios_base::in | std::ios_base::binary); stream >> endianness; @@ -325,7 +329,8 @@ std::optional load_tga(const std::string_view &name, const fs::data &fi *pixbuf++ = {red, green, blue, alphabyte}; break; default: - logging::funcprint("TGA {}, unsupported pixel size: {}\n", name, targa_header.pixel_size); // mxd + logging::funcprint( + "TGA {}, unsupported pixel size: {}\n", name, targa_header.pixel_size); // mxd return std::nullopt; } } @@ -347,7 +352,8 @@ std::optional load_tga(const std::string_view &name, const fs::data &fi break; case 32: stream >= blue >= green >= red >= alphabyte; break; default: - logging::funcprint("TGA {}, unsupported pixel size: {}\n", name, targa_header.pixel_size); // mxd + logging::funcprint( + "TGA {}, unsupported pixel size: {}\n", name, targa_header.pixel_size); // mxd return std::nullopt; } @@ -375,7 +381,8 @@ std::optional load_tga(const std::string_view &name, const fs::data &fi *pixbuf++ = {red, green, blue, alphabyte}; break; default: - logging::funcprint("TGA {}, unsupported pixel size: {}\n", name, targa_header.pixel_size); // mxd + logging::funcprint( + "TGA {}, unsupported pixel size: {}\n", name, targa_header.pixel_size); // mxd return std::nullopt; } column++; @@ -428,7 +435,8 @@ qvec3b calculate_average(const std::vector &pixels) return avg /= n; } -std::tuple, fs::resolve_result, fs::data> load_texture(const std::string_view &name, bool meta_only, const gamedef_t *game, const settings::common_settings &options) +std::tuple, fs::resolve_result, fs::data> load_texture( + const std::string_view &name, bool meta_only, const gamedef_t *game, const settings::common_settings &options) { fs::path prefix; @@ -488,10 +496,10 @@ std::tuple, fs::resolve_result, fs::data> load_textu "height": 64 } */ -std::optional load_wal_json_meta(const std::string_view &name, const fs::data &file, const gamedef_t *game) +std::optional load_wal_json_meta( + const std::string_view &name, const fs::data &file, const gamedef_t *game) { - try - { + try { auto json = json::parse(file->begin(), file->end()); texture_meta meta{}; @@ -521,7 +529,7 @@ std::optional load_wal_json_meta(const std::string_view &name, con meta.contents.native |= content.get(); } else if (content.is_string()) { meta.contents.native |= game->contents_from_string(content.get()); - } + } } } } @@ -539,7 +547,7 @@ std::optional load_wal_json_meta(const std::string_view &name, con meta.flags.native |= flag.get(); } else if (flag.is_string()) { meta.flags.native |= game->surfflags_from_string(flag.get()); - } + } } } } @@ -549,15 +557,14 @@ std::optional load_wal_json_meta(const std::string_view &name, con } return meta; - } - catch (json::exception e) - { + } catch (json::exception e) { logging::funcprint("{}, invalid JSON: {}\n", name, e.what()); return std::nullopt; } } -std::tuple, fs::resolve_result, fs::data> load_texture_meta(const std::string_view &name, const gamedef_t *game, const settings::common_settings &options) +std::tuple, fs::resolve_result, fs::data> load_texture_meta( + const std::string_view &name, const gamedef_t *game, const settings::common_settings &options) { fs::path prefix; diff --git a/common/log.cc b/common/log.cc index 8db12955..306536a7 100644 --- a/common/log.cc +++ b/common/log.cc @@ -82,7 +82,7 @@ void print(flag logflag, const char *str) } print_mutex.lock(); - + if (logflag != flag::PERCENT) { // log file, if open if (logfile) { @@ -130,4 +130,4 @@ void percent(uint64_t count, uint64_t max, bool displayElapsed) } } } -}; +}; // namespace logging diff --git a/common/parser.cc b/common/parser.cc index 9bfd29b1..4687a30a 100644 --- a/common/parser.cc +++ b/common/parser.cc @@ -123,7 +123,9 @@ skipspace: *token_p++ = *pos++; } break; - default: logging::print("WARNING: line {}: Unrecognised string escape - \\{}\n", linenum, pos[1]); break; + default: + logging::print("WARNING: line {}: Unrecognised string escape - \\{}\n", linenum, pos[1]); + break; } } *token_p++ = *pos++; diff --git a/common/prtfile.cc b/common/prtfile.cc index a22534fd..7228193a 100644 --- a/common/prtfile.cc +++ b/common/prtfile.cc @@ -43,7 +43,7 @@ prtfile_t LoadPrtFile(const fs::path &name, const bspversion_t *loadversion) FError("unknown header/empty portal file {}\n", name); } - prtfile_t result {}; + prtfile_t result{}; int numportals; if (magic == PORTALFILE) { @@ -87,7 +87,8 @@ prtfile_t LoadPrtFile(const fs::path &name, const bspversion_t *loadversion) FError("reading portal {}", i); if (numpoints > PRT_MAX_WINDING) FError("portal {} has too many points", i); - if ((unsigned)p.leafnums[0] > (unsigned)result.portalleafs || (unsigned)p.leafnums[1] > (unsigned)result.portalleafs) + if ((unsigned)p.leafnums[0] > (unsigned)result.portalleafs || + (unsigned)p.leafnums[1] > (unsigned)result.portalleafs) FError("out of bounds leaf in portal {}", i); auto &w = p.winding; @@ -158,7 +159,8 @@ prtfile_t LoadPrtFile(const fs::path &name, const bspversion_t *loadversion) Error("Unexpected end of cluster map\n"); } if (clusternum < 0 || clusternum >= result.portalleafs) { - FError("Invalid cluster number {} in cluster map, number of clusters: {}\n", clusternum, result.portalleafs); + FError("Invalid cluster number {} in cluster map, number of clusters: {}\n", clusternum, + result.portalleafs); } result.dleafinfos[i + 1].cluster = clusternum; } diff --git a/common/settings.cc b/common/settings.cc index 85d7265a..710a21b9 100644 --- a/common/settings.cc +++ b/common/settings.cc @@ -53,10 +53,10 @@ void setting_container::reset() } } -void setting_container::copyFrom(const setting_container& other) +void setting_container::copyFrom(const setting_container &other) { for (auto setting : _settings) { - const std::string& pri_name = setting->primaryName(); + const std::string &pri_name = setting->primaryName(); const auto *other_setting = other.findSetting(pri_name); if (other_setting) { diff --git a/include/common/bspfile.hh b/include/common/bspfile.hh index 4caa2604..bfeb3ed3 100644 --- a/include/common/bspfile.hh +++ b/include/common/bspfile.hh @@ -111,13 +111,21 @@ struct contentflags_t bool is_detail_solid(const gamedef_t *game) const; bool is_detail_fence(const gamedef_t *game) const; bool is_detail_illusionary(const gamedef_t *game) const; - + bool is_mirrored(const gamedef_t *game) const; - contentflags_t &set_mirrored(const std::optional &mirror_inside_value) { mirror_inside = mirror_inside_value; return *this; } - + contentflags_t &set_mirrored(const std::optional &mirror_inside_value) + { + mirror_inside = mirror_inside_value; + return *this; + } + inline bool will_clip_same_type(const gamedef_t *game) const { return will_clip_same_type(game, *this); } bool will_clip_same_type(const gamedef_t *game, const contentflags_t &other) const; - contentflags_t &set_clips_same_type(const std::optional &clips_same_type_value) { clips_same_type = clips_same_type_value; return *this; } + contentflags_t &set_clips_same_type(const std::optional &clips_same_type_value) + { + clips_same_type = clips_same_type_value; + return *this; + } bool is_empty(const gamedef_t *game) const; bool is_any_solid(const gamedef_t *game) const; @@ -131,9 +139,7 @@ struct contentflags_t void make_valid(const gamedef_t *game); - inline bool is_fence(const gamedef_t *game) const { - return is_detail_fence(game) || is_detail_illusionary(game); - } + inline bool is_fence(const gamedef_t *game) const { return is_detail_fence(game) || is_detail_illusionary(game); } // check if this content's `type` - which is distinct from various // flags that turn things on/off - match. Exactly what the native @@ -208,8 +214,8 @@ struct surfflags_t private: constexpr auto as_tuple() const { - return std::tie(native, is_skip, is_hintskip, is_hint, no_dirt, no_shadow, no_bounce, no_minlight, no_expand, light_ignore, - phong_angle, phong_angle_concave, minlight, minlight_color, light_alpha); + return std::tie(native, is_skip, is_hintskip, is_hint, no_dirt, no_shadow, no_bounce, no_minlight, no_expand, + light_ignore, phong_angle, phong_angle_concave, minlight, minlight_color, light_alpha); } public: @@ -233,7 +239,8 @@ enum gameid_t GAME_TOTAL }; -struct content_stats_base_t { +struct content_stats_base_t +{ virtual ~content_stats_base_t() = default; }; @@ -290,17 +297,19 @@ struct gamedef_t virtual bool contents_are_liquid(const contentflags_t &contents) const = 0; virtual bool contents_are_valid(const contentflags_t &contents, bool strict = true) const = 0; virtual int32_t contents_from_string(const std::string_view &str) const = 0; - virtual bool portal_can_see_through(const contentflags_t &contents0, const contentflags_t &contents1, bool transwater, bool transsky) const = 0; + virtual bool portal_can_see_through( + const contentflags_t &contents0, const contentflags_t &contents1, bool transwater, bool transsky) const = 0; virtual bool contents_seals_map(const contentflags_t &contents) const = 0; virtual contentflags_t contents_remap_for_export(const contentflags_t &contents) const = 0; virtual contentflags_t combine_contents(const contentflags_t &a, const contentflags_t &b) const = 0; // for a portal with contents from `a` to `b`, returns what type of face should be rendered facing `a` and `b` virtual contentflags_t portal_visible_contents(const contentflags_t &a, const contentflags_t &b) const = 0; - // for a brush with the given contents touching a portal with the required `portal_visible_contents`, as determined by - // portal_visible_contents, should the `brushside_side` of the brushside generate a face? - // e.g. liquids generate front and back sides by default, but for q1 detail_wall/detail_illusionary the back side is opt-in - // with _mirrorinside - virtual bool portal_generates_face(const contentflags_t &portal_visible_contents, const contentflags_t &brushcontents, planeside_t brushside_side) const = 0; + // for a brush with the given contents touching a portal with the required `portal_visible_contents`, as determined + // by portal_visible_contents, should the `brushside_side` of the brushside generate a face? e.g. liquids generate + // front and back sides by default, but for q1 detail_wall/detail_illusionary the back side is opt-in with + // _mirrorinside + virtual bool portal_generates_face(const contentflags_t &portal_visible_contents, + const contentflags_t &brushcontents, planeside_t brushside_side) const = 0; virtual std::string get_contents_display(const contentflags_t &contents) const = 0; virtual void contents_make_valid(contentflags_t &contents) const = 0; virtual const std::initializer_list &get_hull_sizes() const = 0; @@ -356,7 +365,8 @@ struct fmt::formatter // Q2-esque BSPs are printed as, ex, IBSP:38 if (v.version.has_value()) { - char ident[5] = { (char) (v.ident & 0xFF), (char) ((v.ident >> 8) & 0xFF), (char) ((v.ident >> 16) & 0xFF), (char) ((v.ident >> 24) & 0xFF), '\0' }; + char ident[5] = {(char)(v.ident & 0xFF), (char)((v.ident >> 8) & 0xFF), (char)((v.ident >> 16) & 0xFF), + (char)((v.ident >> 24) & 0xFF), '\0'}; return format_to(ctx.out(), "{}:{}", ident, v.version.value()); } @@ -429,13 +439,13 @@ struct bspdata_t struct { bspxentries_t entries; - + // transfer ownership of the vector into a BSPX lump inline void transfer(const char *xname, std::vector &xdata) { entries.insert_or_assign(xname, std::move(xdata)); } - + // transfer ownership of the vector into a BSPX lump inline void transfer(const char *xname, std::vector &&xdata) { diff --git a/include/common/bspfile_generic.hh b/include/common/bspfile_generic.hh index fbc282eb..e8aca7f1 100644 --- a/include/common/bspfile_generic.hh +++ b/include/common/bspfile_generic.hh @@ -430,7 +430,7 @@ struct q2_dbrushside_qbism_t struct bspversion_t; - // "generic" bsp - superset of all other supported types +// "generic" bsp - superset of all other supported types struct mbsp_t { // the BSP version that we came from, if any diff --git a/include/common/bspfile_q1.hh b/include/common/bspfile_q1.hh index 347470e9..d02c1f0b 100644 --- a/include/common/bspfile_q1.hh +++ b/include/common/bspfile_q1.hh @@ -173,12 +173,12 @@ struct bsp2rmq_dnode_t }; /* -* Clipnodes need to be stored as a 16-bit offset. Originally, this was a -* signed value and only the positive values up to 32767 were available. Since -* the negative range was unused apart from a few values reserved for flags, -* this has been extended to allow up to 65520 (0xfff0) clipnodes (with a -* suitably modified engine). -*/ + * Clipnodes need to be stored as a 16-bit offset. Originally, this was a + * signed value and only the positive values up to 32767 were available. Since + * the negative range was unused apart from a few values reserved for flags, + * this has been extended to allow up to 65520 (0xfff0) clipnodes (with a + * suitably modified engine). + */ struct bsp29_dclipnode_t { int32_t planenum; @@ -408,7 +408,6 @@ struct bsp2_dleaf_t } }; - // Q1-esque maps can use one of these two. using dmodelq1_vector = std::vector; using dmodelh2_vector = std::vector; diff --git a/include/common/bspfile_q2.hh b/include/common/bspfile_q2.hh index 451e62dd..3cc5ae2d 100644 --- a/include/common/bspfile_q2.hh +++ b/include/common/bspfile_q2.hh @@ -94,7 +94,6 @@ struct q2_dmodel_t auto stream_data() { return std::tie(mins, maxs, origin, headnode, firstface, numfaces); } }; - // Q2 contents (from qfiles.h) // contents flags are seperate bits @@ -280,7 +279,6 @@ struct q2_dface_qbism_t auto stream_data() { return std::tie(planenum, side, firstedge, numedges, texinfo, styles, lightofs); } }; - struct q2_dleaf_t { int32_t contents; // OR of all brushes (not needed?) diff --git a/include/common/bsputils.hh b/include/common/bsputils.hh index 8b64411b..cffc564a 100644 --- a/include/common/bsputils.hh +++ b/include/common/bsputils.hh @@ -55,7 +55,7 @@ bool Light_PointInSolid(const mbsp_t *bsp, const dmodelh2_t *model, const qvec3d bool Light_PointInWorld(const mbsp_t *bsp, const qvec3d &point); std::vector BSP_FindFacesAtPoint( - const mbsp_t *bsp, const dmodelh2_t *model, const qvec3d &point, const qvec3d &wantedNormal = qvec3d(0,0,0)); + const mbsp_t *bsp, const dmodelh2_t *model, const qvec3d &point, const qvec3d &wantedNormal = qvec3d(0, 0, 0)); /** * Searches for a face touching a point and facing a certain way. * Sometimes (water, sky?) there will be 2 overlapping candidates facing opposite ways, the provided normal @@ -64,7 +64,7 @@ std::vector BSP_FindFacesAtPoint( const mface_t *BSP_FindFaceAtPoint( const mbsp_t *bsp, const dmodelh2_t *model, const qvec3d &point, const qvec3d &wantedNormal); /** - * Searches for a decision node in hull0 that contains `point`, and has a plane normal of either + * Searches for a decision node in hull0 that contains `point`, and has a plane normal of either * wanted_normal or -wanted_normal. */ const bsp2_dnode_t *BSP_FindNodeAtPoint( @@ -88,7 +88,6 @@ void Face_DebugPrint(const mbsp_t *bsp, const mface_t *face); void CompressRow(const uint8_t *vis, const size_t numbytes, std::back_insert_iterator> it); void DecompressRow(const uint8_t *in, const int numbytes, uint8_t *decompressed); - /* ======================================================================== */ inline qvec2d WorldToTexCoord(const qvec3d &world, const mtexinfo_t *tex) @@ -171,8 +170,7 @@ public: faceextents_t() = default; - inline faceextents_t(const mface_t &face, const mbsp_t &bsp, float lmshift) : - lightmapshift(lmshift) + inline faceextents_t(const mface_t &face, const mbsp_t &bsp, float lmshift) : lightmapshift(lmshift) { worldToTexCoordMatrix = WorldToTexSpace(&bsp, &face); texCoordToWorldMatrix = TexSpaceToWorld(&bsp, &face); @@ -208,10 +206,11 @@ public: const char *texname = Face_TextureName(&bsp, &face); logging::print("WARNING: Bad surface extents (may not load in vanilla Q1 engines):\n" - " surface {}, {} extents = {}, shift = {}\n" - " texture {} at ({})\n" - " surface normal ({})\n", - Face_GetNum(&bsp, &face), i ? "t" : "s", texextents[i], lightmapshift, texname, point, plane.normal); + " surface {}, {} extents = {}, shift = {}\n" + " texture {} at ({})\n" + " surface normal ({})\n", + Face_GetNum(&bsp, &face), i ? "t" : "s", texextents[i], lightmapshift, texname, point, + plane.normal); } } @@ -243,12 +242,12 @@ public: constexpr qvec2f lightmapCoordToTexCoord(const qvec2f &LMCoord) const { - return { lightmapshift * (texmins[0] + LMCoord[0]), lightmapshift * (texmins[1] + LMCoord[1]) }; + return {lightmapshift * (texmins[0] + LMCoord[0]), lightmapshift * (texmins[1] + LMCoord[1])}; } constexpr qvec2f texCoordToLightmapCoord(const qvec2f &tc) const { - return { (tc[0] / lightmapshift) - texmins[0], (tc[1] / lightmapshift) - texmins[1] }; + return {(tc[0] / lightmapshift) - texmins[0], (tc[1] / lightmapshift) - texmins[1]}; } inline qvec2f worldToTexCoord(qvec3f world) const diff --git a/include/common/bspxfile.hh b/include/common/bspxfile.hh index b0ad450a..628ab5a4 100644 --- a/include/common/bspxfile.hh +++ b/include/common/bspxfile.hh @@ -83,10 +83,10 @@ struct bspxfacenormals_header // if the BSP has 4 faces with 4 vertices each, then what follows is // 4 * 4 * (3 uint32_t); normal/tangent/bitangent per vertex per face. // for each bsp face: - // for each face vertex: - uint32_t normal; - uint32_t tangent; - uint32_t bitangent; + // for each face vertex: + uint32_t normal; + uint32_t tangent; + uint32_t bitangent; }; // BSPX data diff --git a/include/common/cmdlib.hh b/include/common/cmdlib.hh index ce2aaf9e..e2505842 100644 --- a/include/common/cmdlib.hh +++ b/include/common/cmdlib.hh @@ -41,26 +41,26 @@ inline int32_t Q_strncasecmp(const std::string_view &a, const std::string_view & { return #ifdef _WIN32 - _strnicmp + _strnicmp #elif defined(__has_include) && __has_include() - strncasecmp + strncasecmp #else - strnicmp + strnicmp #endif - (a.data(), b.data(), maxcount); + (a.data(), b.data(), maxcount); } inline int32_t Q_strcasecmp(const std::string_view &a, const std::string_view &b) { return #ifdef _WIN32 - _stricmp + _stricmp #elif defined(__has_include) && __has_include() - strcasecmp + strcasecmp #else - stricmp + stricmp #endif - (a.data(), b.data()); + (a.data(), b.data()); } bool string_iequals(const std::string_view &a, const std::string_view &b); // mxd @@ -442,8 +442,7 @@ inline std::enable_if_t -inline std::enable_if_t, std::ostream &> operator<=( - std::ostream &s, const T &obj) +inline std::enable_if_t, std::ostream &> operator<=(std::ostream &s, const T &obj) { s <= reinterpret_cast &>(obj); return s; @@ -599,8 +598,7 @@ inline std::enable_if_t -inline std::enable_if_t, std::istream &> operator>=( - std::istream &s, T &obj) +inline std::enable_if_t, std::istream &> operator>=(std::istream &s, T &obj) { s >= reinterpret_cast &>(obj); return s; @@ -793,13 +791,15 @@ protected: struct memstream : virtual membuf, std::ostream, std::istream { - inline memstream(void *base, size_t size, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out | std::ios_base::binary) + inline memstream(void *base, size_t size, + std::ios_base::openmode which = std::ios_base::in | std::ios_base::out | std::ios_base::binary) : membuf(base, size, which), std::ostream(static_cast(this)), std::istream(static_cast(this)) { } - inline memstream(const void *base, size_t size, std::ios_base::openmode which = std::ios_base::in | std::ios_base::binary) + inline memstream( + const void *base, size_t size, std::ios_base::openmode which = std::ios_base::in | std::ios_base::binary) : membuf(base, size, which), std::ostream(nullptr), std::istream(static_cast(this)) { } @@ -807,7 +807,8 @@ struct memstream : virtual membuf, std::ostream, std::istream struct omemstream : virtual membuf, std::ostream { - inline omemstream(void *base, size_t size, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out | std::ios_base::binary) + inline omemstream(void *base, size_t size, + std::ios_base::openmode which = std::ios_base::in | std::ios_base::out | std::ios_base::binary) : membuf(base, size, which), std::ostream(static_cast(this)) { } @@ -815,7 +816,8 @@ struct omemstream : virtual membuf, std::ostream struct imemstream : virtual membuf, std::istream { - inline imemstream(const void *base, size_t size, std::ios_base::openmode which = std::ios_base::in | std::ios_base::binary) + inline imemstream( + const void *base, size_t size, std::ios_base::openmode which = std::ios_base::in | std::ios_base::binary) : membuf(base, size, which), std::istream(static_cast(this)) { } @@ -875,123 +877,107 @@ template class aligned_allocator { public: - // The following will be the same for virtually all allocators. - using pointer = T*; - using const_pointer = const T*; - using reference = T&; - using const_reference = const T&; - using value_type = T; + // The following will be the same for virtually all allocators. + using pointer = T *; + using const_pointer = const T *; + using reference = T &; + using const_reference = const T &; + using value_type = T; using size_type = std::size_t; - using difference_type = ptrdiff_t; + using difference_type = ptrdiff_t; - T *address(T &r) const - { - return &r; - } + T *address(T &r) const { return &r; } - const T *address(const T& s) const - { - return &s; - } + const T *address(const T &s) const { return &s; } - std::size_t max_size() const - { - // The following has been carefully written to be independent of - // the definition of size_t and to avoid signed/unsigned warnings. - return (static_cast(0) - static_cast(1)) / sizeof(T); - } + std::size_t max_size() const + { + // The following has been carefully written to be independent of + // the definition of size_t and to avoid signed/unsigned warnings. + return (static_cast(0) - static_cast(1)) / sizeof(T); + } - // The following must be the same for all allocators. - template - struct rebind - { - typedef aligned_allocator other; - }; - - bool operator!=(const aligned_allocator &other) const - { - return !(*this == other); - } + // The following must be the same for all allocators. + template + struct rebind + { + typedef aligned_allocator other; + }; - void construct(T *const p, const T &t) const - { - void *const pv = reinterpret_cast(p); - new (pv) T(t); - } + bool operator!=(const aligned_allocator &other) const { return !(*this == other); } - void destroy(T *const p) const - { - p->~T(); - } + void construct(T *const p, const T &t) const + { + void *const pv = reinterpret_cast(p); + new (pv) T(t); + } - // Returns true if and only if storage allocated from *this - // can be deallocated from other, and vice versa. - // Always returns true for stateless allocators. - bool operator==(const aligned_allocator& other) const - { - return true; - } + void destroy(T *const p) const { p->~T(); } - // Default constructor, copy constructor, rebinding constructor, and destructor. - // Empty for stateless allocators. - aligned_allocator() { } - aligned_allocator(const aligned_allocator &) { } - template - aligned_allocator(const aligned_allocator &) { } - ~aligned_allocator() { } + // Returns true if and only if storage allocated from *this + // can be deallocated from other, and vice versa. + // Always returns true for stateless allocators. + bool operator==(const aligned_allocator &other) const { return true; } - // The following will be different for each allocator. - T *allocate(const std::size_t n) const - { - // The return value of allocate(0) is unspecified. - // Mallocator returns NULL in order to avoid depending - // on malloc(0)'s implementation-defined behavior - // (the implementation can define malloc(0) to return NULL, - // in which case the bad_alloc check below would fire). - // All allocators can return NULL in this case. - if (n == 0) { - return nullptr; - } + // Default constructor, copy constructor, rebinding constructor, and destructor. + // Empty for stateless allocators. + aligned_allocator() { } + aligned_allocator(const aligned_allocator &) { } + template + aligned_allocator(const aligned_allocator &) + { + } + ~aligned_allocator() { } - // All allocators should contain an integer overflow check. - // The Standardization Committee recommends that std::length_error - // be thrown in the case of integer overflow. - if (n > max_size()) { - throw std::length_error("aligned_allocator::allocate() - Integer overflow."); - } + // The following will be different for each allocator. + T *allocate(const std::size_t n) const + { + // The return value of allocate(0) is unspecified. + // Mallocator returns NULL in order to avoid depending + // on malloc(0)'s implementation-defined behavior + // (the implementation can define malloc(0) to return NULL, + // in which case the bad_alloc check below would fire). + // All allocators can return NULL in this case. + if (n == 0) { + return nullptr; + } - // Mallocator wraps malloc(). - void *const pv = q_aligned_malloc(Alignment, n * sizeof(T)); + // All allocators should contain an integer overflow check. + // The Standardization Committee recommends that std::length_error + // be thrown in the case of integer overflow. + if (n > max_size()) { + throw std::length_error("aligned_allocator::allocate() - Integer overflow."); + } - // Allocators should throw std::bad_alloc in the case of memory allocation failure. - if (pv == nullptr) { - throw std::bad_alloc(); - } + // Mallocator wraps malloc(). + void *const pv = q_aligned_malloc(Alignment, n * sizeof(T)); - return reinterpret_cast(pv); - } + // Allocators should throw std::bad_alloc in the case of memory allocation failure. + if (pv == nullptr) { + throw std::bad_alloc(); + } - void deallocate(T *const p, const std::size_t n) const - { - q_aligned_free(p); - } + return reinterpret_cast(pv); + } - // The following will be the same for all allocators that ignore hints. - template - T *allocate(const std::size_t n, const U * /* const hint */) const - { - return allocate(n); - } + void deallocate(T *const p, const std::size_t n) const { q_aligned_free(p); } - // Allocators are not required to be assignable, so - // all allocators should have a private unimplemented - // assignment operator. Note that this will trigger the - // off-by-default (enabled under /Wall) warning C4626 - // "assignment operator could not be generated because a - // base class assignment operator is inaccessible" within - // the STL headers, but that warning is useless. + // The following will be the same for all allocators that ignore hints. + template + T *allocate(const std::size_t n, const U * /* const hint */) const + { + return allocate(n); + } + + // Allocators are not required to be assignable, so + // all allocators should have a private unimplemented + // assignment operator. Note that this will trigger the + // off-by-default (enabled under /Wall) warning C4626 + // "assignment operator could not be generated because a + // base class assignment operator is inaccessible" within + // the STL headers, but that warning is useless. private: - aligned_allocator& operator=(const aligned_allocator&); + aligned_allocator &operator=(const aligned_allocator &); }; template diff --git a/include/common/fs.hh b/include/common/fs.hh index dc2bd61a..a58a3aa4 100644 --- a/include/common/fs.hh +++ b/include/common/fs.hh @@ -60,7 +60,7 @@ struct resolve_result std::shared_ptr archive; path filename; - inline explicit operator bool() const { return (bool) archive; } + inline explicit operator bool() const { return (bool)archive; } }; // attempt to resolve the specified file. diff --git a/include/common/imglib.hh b/include/common/imglib.hh index 2b05be03..97e949a1 100644 --- a/include/common/imglib.hh +++ b/include/common/imglib.hh @@ -70,7 +70,7 @@ struct texture // This member is only set before insertion into the table // and not calculated by individual load functions. - qvec3b averageColor { 0 }; + qvec3b averageColor{0}; }; extern std::unordered_map textures; @@ -80,24 +80,29 @@ qvec3b calculate_average(const std::vector &pixels); const texture *find(const std::string_view &str); // Load wal -std::optional load_wal(const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game); +std::optional load_wal( + const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game); // Load TGA -std::optional load_tga(const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game); +std::optional load_tga( + const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game); // Load Quake/Half Life mip (raw data) -std::optional load_mip(const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game); +std::optional load_mip( + const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game); // list of supported extensions and their loaders -constexpr struct { const char *suffix; ext id; decltype(load_wal) *loader; } extension_list[] = { - { ".tga", ext::TGA, load_tga }, - { ".wal", ext::WAL, load_wal }, - { ".mip", ext::MIP, load_mip }, - { "", ext::MIP, load_mip } -}; +constexpr struct +{ + const char *suffix; + ext id; + decltype(load_wal) *loader; +} extension_list[] = { + {".tga", ext::TGA, load_tga}, {".wal", ext::WAL, load_wal}, {".mip", ext::MIP, load_mip}, {"", ext::MIP, load_mip}}; // Attempt to load a texture from the specified name. -std::tuple, fs::resolve_result, fs::data> load_texture(const std::string_view &name, bool meta_only, const gamedef_t *game, const settings::common_settings &options); +std::tuple, fs::resolve_result, fs::data> load_texture( + const std::string_view &name, bool meta_only, const gamedef_t *game, const settings::common_settings &options); enum class meta_ext { @@ -106,7 +111,8 @@ enum class meta_ext }; // Load wal -inline std::optional load_wal_meta(const std::string_view &name, const fs::data &file, const gamedef_t *game) +inline std::optional load_wal_meta( + const std::string_view &name, const fs::data &file, const gamedef_t *game) { if (auto tex = load_wal(name, file, true, game)) { return tex->meta; @@ -115,14 +121,19 @@ inline std::optional load_wal_meta(const std::string_view &name, c return std::nullopt; } -std::optional load_wal_json_meta(const std::string_view &name, const fs::data &file, const gamedef_t *game); +std::optional load_wal_json_meta( + const std::string_view &name, const fs::data &file, const gamedef_t *game); // list of supported meta extensions and their loaders -constexpr struct { const char *suffix; meta_ext id; decltype(load_wal_meta) *loader; } meta_extension_list[] = { - { ".wal", meta_ext::WAL, load_wal_meta }, - { ".wal_json", meta_ext::WAL_JSON, load_wal_json_meta } -}; +constexpr struct +{ + const char *suffix; + meta_ext id; + decltype(load_wal_meta) *loader; +} meta_extension_list[] = { + {".wal", meta_ext::WAL, load_wal_meta}, {".wal_json", meta_ext::WAL_JSON, load_wal_json_meta}}; // Attempt to load a texture meta from the specified name. -std::tuple, fs::resolve_result, fs::data> load_texture_meta(const std::string_view &name, const gamedef_t *game, const settings::common_settings &options); +std::tuple, fs::resolve_result, fs::data> load_texture_meta( + const std::string_view &name, const gamedef_t *game, const settings::common_settings &options); }; // namespace img diff --git a/include/common/log.hh b/include/common/log.hh index bd0cff34..980195cb 100644 --- a/include/common/log.hh +++ b/include/common/log.hh @@ -35,20 +35,20 @@ // forward declaration namespace settings { - class common_settings; +class common_settings; } namespace logging { enum class flag : uint8_t { - NONE = 0, // none of the below (still prints though) - DEFAULT = nth_bit(0), // prints everywhere - VERBOSE = nth_bit(1), // prints everywhere, if enabled - PROGRESS = nth_bit(2), // prints only to stdout - PERCENT = nth_bit(3), // prints everywhere, if enabled - STAT = nth_bit(4), // prints everywhere, if enabled - ALL = 0xFF + NONE = 0, // none of the below (still prints though) + DEFAULT = nth_bit(0), // prints everywhere + VERBOSE = nth_bit(1), // prints everywhere, if enabled + PROGRESS = nth_bit(2), // prints only to stdout + PERCENT = nth_bit(3), // prints everywhere, if enabled + STAT = nth_bit(4), // prints everywhere, if enabled + ALL = 0xFF }; extern bitflags mask; @@ -110,4 +110,4 @@ inline void assert_(bool success, const char *expr, const char *file, int line) // Only use this by hand if you absolutely need to; otherwise, // use 's parallel_for(_each) void percent(uint64_t count, uint64_t max, bool displayElapsed = true); -}; \ No newline at end of file +}; // namespace logging \ No newline at end of file diff --git a/include/common/parallel.hh b/include/common/parallel.hh index eab78654..f3a4f80d 100644 --- a/include/common/parallel.hh +++ b/include/common/parallel.hh @@ -25,45 +25,45 @@ // parallel extensions to logging namespace logging { - template - void parallel_for(const TS &start, const TE &end, const Body &func) - { - auto length = end - start; - std::atomic_uint64_t progress = 0; - - tbb::parallel_for(start, end, [&](const auto &it) { - percent(progress++, length); - func(it); - }); +template +void parallel_for(const TS &start, const TE &end, const Body &func) +{ + auto length = end - start; + std::atomic_uint64_t progress = 0; - percent(progress, length); - } + tbb::parallel_for(start, end, [&](const auto &it) { + percent(progress++, length); + func(it); + }); - template - void parallel_for_each(Container &container, const Body &func) - { - auto length = std::size(container); - std::atomic_uint64_t progress = 0; - - tbb::parallel_for_each(container, [&](auto &f) { - percent(progress++, length); - func(f); - }); + percent(progress, length); +} - percent(progress, length); - } +template +void parallel_for_each(Container &container, const Body &func) +{ + auto length = std::size(container); + std::atomic_uint64_t progress = 0; - template - void parallel_for_each(const Container &container, const Body &func) - { - auto length = std::size(container); - std::atomic_uint64_t progress = 0; - - tbb::parallel_for_each(container, [&](const auto &f) { - percent(progress++, length); - func(f); - }); + tbb::parallel_for_each(container, [&](auto &f) { + percent(progress++, length); + func(f); + }); - percent(progress, length); - } -} \ No newline at end of file + percent(progress, length); +} + +template +void parallel_for_each(const Container &container, const Body &func) +{ + auto length = std::size(container); + std::atomic_uint64_t progress = 0; + + tbb::parallel_for_each(container, [&](const auto &f) { + percent(progress++, length); + func(f); + }); + + percent(progress, length); +} +} // namespace logging \ No newline at end of file diff --git a/include/common/polylib.hh b/include/common/polylib.hh index e7fea2fc..fcd1626c 100644 --- a/include/common/polylib.hh +++ b/include/common/polylib.hh @@ -64,16 +64,13 @@ public: using iterator_category = std::random_access_iterator_tag; using value_type = typename std::conditional_t; using difference_type = ptrdiff_t; - using pointer = value_type*; - using reference = value_type&; + using pointer = value_type *; + using reference = value_type &; iterator_base(const iterator_base &) = default; iterator_base &operator=(const iterator_base &) noexcept = default; - [[nodiscard]] inline reference operator*() const noexcept - { - return (*w)[index]; - } + [[nodiscard]] inline reference operator*() const noexcept { return (*w)[index]; } constexpr iterator_base &operator++() noexcept { @@ -123,10 +120,7 @@ public: return w == _Off.w && index == _Off.index; } - [[nodiscard]] constexpr bool operator!=(const iterator_base &_Off) const noexcept - { - return !(*this == _Off); - } + [[nodiscard]] constexpr bool operator!=(const iterator_base &_Off) const noexcept { return !(*this == _Off); } [[nodiscard]] constexpr difference_type operator-(const iterator_base &_Off) const noexcept { @@ -140,10 +134,7 @@ public: return _Tmp; } - [[nodiscard]] inline reference operator[](const difference_type _Off) const noexcept - { - return *(*this + _Off); - } + [[nodiscard]] inline reference operator[](const difference_type _Off) const noexcept { return *(*this + _Off); } }; // default constructor does nothing @@ -175,7 +166,7 @@ public: } // initializer list constructor - inline winding_base_t(std::initializer_list l) : winding_base_t(l.begin(), l.end()) {} + inline winding_base_t(std::initializer_list l) : winding_base_t(l.begin(), l.end()) { } // copy constructor; uses optimized method of copying // data over. @@ -277,7 +268,8 @@ public: } // un-bounds-checked - inline qvec3d &operator[](const size_t &index) { + inline qvec3d &operator[](const size_t &index) + { if (index >= N) { return vector[index - N]; } @@ -286,7 +278,8 @@ public: } // un-bounds-checked - inline const qvec3d &operator[](const size_t &index) const { + inline const qvec3d &operator[](const size_t &index) const + { if (index >= N) { return vector[index - N]; } @@ -330,9 +323,15 @@ public: return (array[count - 1] = qvec3d(std::forward(vec)...)); } - void push_back(qvec3d &&vec) { emplace_back(std::move(vec)); } + void push_back(qvec3d &&vec) + { + emplace_back(std::move(vec)); + } - void push_back(const qvec3d &vec) { emplace_back(vec); } + void push_back(const qvec3d &vec) + { + emplace_back(vec); + } void resize(const size_t &new_size) { @@ -511,7 +510,10 @@ public: } } - std::vector glm_winding_points() const { return {begin(), end()}; } + std::vector glm_winding_points() const + { + return {begin(), end()}; + } static inline winding_base_t from_winding_points(const std::vector &points) { @@ -720,18 +722,18 @@ public: return result; } - winding_base_t translate(const qvec3d& offset) const + winding_base_t translate(const qvec3d &offset) const { winding_base_t result(*this); - for (qvec3d& p : result) { + for (qvec3d &p : result) { p += offset; } return result; } - bool directional_equal(const winding_base_t& w, const vec_t &equal_epsilon = POINT_EQUAL_EPSILON) const + bool directional_equal(const winding_base_t &w, const vec_t &equal_epsilon = POINT_EQUAL_EPSILON) const { if (this->size() != w.size()) { return false; @@ -762,10 +764,9 @@ public: return false; } - bool undirectional_equal(const winding_base_t& w, const vec_t &equal_epsilon = POINT_EQUAL_EPSILON) const + bool undirectional_equal(const winding_base_t &w, const vec_t &equal_epsilon = POINT_EQUAL_EPSILON) const { - return directional_equal(w, equal_epsilon) - || directional_equal(w.flip(), equal_epsilon); + return directional_equal(w, equal_epsilon) || directional_equal(w.flip(), equal_epsilon); } }; diff --git a/include/common/prtfile.hh b/include/common/prtfile.hh index 16aaf11d..e41d1ce1 100644 --- a/include/common/prtfile.hh +++ b/include/common/prtfile.hh @@ -28,16 +28,19 @@ constexpr size_t PRT_MAX_WINDING_FIXED = 24; using prtfile_winding_t = polylib::winding_base_t; -struct prtfile_portal_t { +struct prtfile_portal_t +{ prtfile_winding_t winding; int leafnums[2]; }; -struct prtfile_dleafinfo_t { +struct prtfile_dleafinfo_t +{ int cluster; }; -struct prtfile_t { +struct prtfile_t +{ int portalleafs; // leafs (PRT1) or clusters (PRT2) int portalleafs_real; // real no. of leafs after expanding PRT2 clusters. Not used for Q2. diff --git a/include/common/qvec.hh b/include/common/qvec.hh index 642e2374..57f08b65 100644 --- a/include/common/qvec.hh +++ b/include/common/qvec.hh @@ -127,15 +127,36 @@ public: v[N - 1] = value; } - [[nodiscard]] constexpr size_t size() const { return N; } + [[nodiscard]] constexpr size_t size() const + { + return N; + } // Sort support - [[nodiscard]] constexpr bool operator<(const qvec &other) const { return v < other.v; } - [[nodiscard]] constexpr bool operator<=(const qvec &other) const { return v <= other.v; } - [[nodiscard]] constexpr bool operator>(const qvec &other) const { return v > other.v; } - [[nodiscard]] constexpr bool operator>=(const qvec &other) const { return v >= other.v; } - [[nodiscard]] constexpr bool operator==(const qvec &other) const { return v == other.v; } - [[nodiscard]] constexpr bool operator!=(const qvec &other) const { return v != other.v; } + [[nodiscard]] constexpr bool operator<(const qvec &other) const + { + return v < other.v; + } + [[nodiscard]] constexpr bool operator<=(const qvec &other) const + { + return v <= other.v; + } + [[nodiscard]] constexpr bool operator>(const qvec &other) const + { + return v > other.v; + } + [[nodiscard]] constexpr bool operator>=(const qvec &other) const + { + return v >= other.v; + } + [[nodiscard]] constexpr bool operator==(const qvec &other) const + { + return v == other.v; + } + [[nodiscard]] constexpr bool operator!=(const qvec &other) const + { + return v != other.v; + } [[nodiscard]] constexpr const T &at(const size_t idx) const { @@ -149,8 +170,14 @@ public: return v[idx]; } - [[nodiscard]] constexpr const T &operator[](const size_t idx) const { return at(idx); } - [[nodiscard]] constexpr T &operator[](const size_t idx) { return at(idx); } + [[nodiscard]] constexpr const T &operator[](const size_t idx) const + { + return at(idx); + } + [[nodiscard]] constexpr T &operator[](const size_t idx) + { + return at(idx); + } template [[nodiscard]] inline auto operator+(const qvec &other) const @@ -273,18 +300,42 @@ public: } // stream support - auto stream_data() { return std::tie(v); } + auto stream_data() + { + return std::tie(v); + } // iterator support - constexpr auto begin() { return v.begin(); } - constexpr auto end() { return v.end(); } - constexpr auto begin() const { return v.begin(); } - constexpr auto end() const { return v.end(); } - constexpr auto cbegin() const { return v.cbegin(); } - constexpr auto cend() const { return v.cend(); } + constexpr auto begin() + { + return v.begin(); + } + constexpr auto end() + { + return v.end(); + } + constexpr auto begin() const + { + return v.begin(); + } + constexpr auto end() const + { + return v.end(); + } + constexpr auto cbegin() const + { + return v.cbegin(); + } + constexpr auto cend() const + { + return v.cend(); + } // for Google Test - friend std::ostream &operator<<(std::ostream &os, const qvec &v) { return os << fmt::format("{}", v); } + friend std::ostream &operator<<(std::ostream &os, const qvec &v) + { + return os << fmt::format("{}", v); + } }; // Fmt support @@ -1172,7 +1223,8 @@ struct twosided constexpr void swap() { std::swap(front, back); } }; -namespace qv { +namespace qv +{ template inline qvec vec_from_mangle(const qvec &m) @@ -1182,4 +1234,4 @@ inline qvec vec_from_mangle(const qvec &m) return {rotations * qvec3d(1, 0, 0)}; } -} +} // namespace qv diff --git a/include/common/settings.hh b/include/common/settings.hh index ff020fde..979b6a63 100644 --- a/include/common/settings.hh +++ b/include/common/settings.hh @@ -53,7 +53,8 @@ public: // (previously, the `--help` code called exit(0); directly which caused // spurious test successes.) struct quit_after_help_exception : public std::exception -{}; +{ +}; enum class source { @@ -111,10 +112,10 @@ public: // } // // is incompatible with the settings_container/setting_base types being copyable. - setting_base(const setting_base& other) = delete; + setting_base(const setting_base &other) = delete; // copy assignment - setting_base& operator=(const setting_base& other) = delete; + setting_base &operator=(const setting_base &other) = delete; inline const std::string &primaryName() const { return _names.at(0); } inline const nameset &names() const { return _names; } @@ -136,7 +137,7 @@ public: } // copies value and source - virtual bool copyFrom(const setting_base& other) = 0; + virtual bool copyFrom(const setting_base &other) = 0; // convenience form of parse() that constructs a temporary parser_t bool parseString(const std::string &string, source source); @@ -163,11 +164,9 @@ public: { } - inline bool copyFrom(const setting_base& other) override { - return true; - } + inline bool copyFrom(const setting_base &other) override { return true; } - inline void reset() override {} + inline void reset() override { } bool parse(const std::string &settingName, parser_base_t &parser, source source) override { @@ -204,7 +203,8 @@ public: } } - inline bool copyFrom(const setting_base& other) override { + inline bool copyFrom(const setting_base &other) override + { if (auto *casted = dynamic_cast *>(&other)) { _value = casted->_value; _source = casted->_source; @@ -213,7 +213,8 @@ public: return false; } - inline void reset() override { + inline void reset() override + { _value = _default; _source = source::DEFAULT; } @@ -305,11 +306,9 @@ public: { } - inline bool copyFrom(const setting_base& other) override { - return true; - } + inline bool copyFrom(const setting_base &other) override { return true; } - inline void reset() override {} + inline void reset() override { } bool parse(const std::string &settingName, parser_base_t &parser, source source) override { @@ -342,6 +341,7 @@ template class setting_numeric : public setting_value { static_assert(!std::is_enum_v, "use setting_enum for enums"); + protected: T _min, _max; @@ -375,10 +375,7 @@ public: this->setting_value::setValue(std::clamp(f, _min, _max), newsource); } - inline bool boolValue() const - { - return this->_value > 0; - } + inline bool boolValue() const { return this->_value > 0; } bool parse(const std::string &settingName, parser_base_t &parser, source source) override { @@ -398,8 +395,7 @@ public: this->setValue(f, source); return true; - } - catch (std::exception &) { + } catch (std::exception &) { return false; } } @@ -520,11 +516,11 @@ public: if (!parser.parse_token()) { return false; } - + setValue(parser.token, source); return true; } - + std::string stringValue() const override { return _value.string(); } std::string format() const override { return "\"relative/path\" or \"C:/absolute/path\""; } @@ -538,14 +534,14 @@ private: public: inline setting_set(setting_container *dictionary, const nameset &names, - const std::string_view &format = "\"str\" ", const setting_group *group = nullptr, const char *description = "") - : setting_base(dictionary, names, group, description), - _format(format) + const std::string_view &format = "\"str\" ", const setting_group *group = nullptr, + const char *description = "") + : setting_base(dictionary, names, group, description), _format(format) { } const std::unordered_set &values() const { return _values; } - + virtual void addValue(const std::string &value, source newSource) { if (changeSource(newSource)) { @@ -563,7 +559,8 @@ public: return true; } - inline bool copyFrom(const setting_base& other) override { + inline bool copyFrom(const setting_base &other) override + { if (auto *casted = dynamic_cast(&other)) { _values = casted->_values; _source = casted->_source; @@ -572,7 +569,8 @@ public: return false; } - inline void reset() override { + inline void reset() override + { _values.clear(); _source = source::DEFAULT; } @@ -623,8 +621,7 @@ public: try { vec[i] = std::stod(parser.token); - } - catch (std::exception &) { + } catch (std::exception &) { return false; } } @@ -667,10 +664,9 @@ protected: std::function _validator; public: - template - inline setting_validator(const decltype(_validator) &validator, Args&&... args) : - T(std::forward(args)...), - _validator(validator) + template + inline setting_validator(const decltype(_validator) &validator, Args &&...args) + : T(std::forward(args)...), _validator(validator) { } @@ -710,19 +706,19 @@ public: std::string remainderName = "filename"; std::string programDescription; - inline setting_container() {} + inline setting_container() { } ~setting_container(); // copy constructor (can't be copyable, see setting_base) - setting_container(const setting_container& other) = delete; + setting_container(const setting_container &other) = delete; // copy assignment - setting_container& operator=(const setting_container& other) = delete; + setting_container &operator=(const setting_container &other) = delete; void reset(); - void copyFrom(const setting_container& other); + void copyFrom(const setting_container &other); inline void registerSetting(setting_base *setting) { @@ -820,28 +816,36 @@ public: // global settings setting_int32 threads{ this, "threads", 0, &performance_group, "number of threads to use, maximum; leave 0 for automatic"}; - setting_bool lowpriority{ - this, "lowpriority", false, &performance_group, "run in a lower priority, to free up headroom for other processes"}; - + setting_bool lowpriority{this, "lowpriority", false, &performance_group, + "run in a lower priority, to free up headroom for other processes"}; + setting_invertible_bool log{this, "log", true, &logging_group, "whether log files are written or not"}; setting_bool verbose{this, {"verbose", "v"}, false, &logging_group, "verbose output"}; setting_bool nopercent{this, "nopercent", false, &logging_group, "don't output percentage messages"}; setting_bool nostat{this, "nostat", false, &logging_group, "don't output statistic messages"}; setting_bool noprogress{this, "noprogress", false, &logging_group, "don't output progress messages"}; - setting_redirect quiet{this, {"quiet", "noverbose"}, {&nopercent, &nostat, &noprogress}, &logging_group, "suppress non-important messages (equivalent to -nopercent -nostat -noprogress)"}; - setting_path gamedir{this, "gamedir", "", &game_group, "override the default mod base directory. if this is not set, or if it is relative, it will be derived from the input file or the basedir if specified."}; - setting_path basedir{this, "basedir", "", &game_group, "override the default game base directory. if this is not set, or if it is relative, it will be derived from the input file or the gamedir if specified."}; - setting_enum filepriority{this, "filepriority", search_priority_t::LOOSE, { { "loose", search_priority_t::LOOSE }, { "archive", search_priority_t::ARCHIVE } }, &game_group, "which types of archives (folders/loose files or packed archives) are higher priority and chosen first for path searching" }; - setting_set paths{this, "path", "\"/path/to/folder\" ", &game_group, "additional paths or archives to add to the search path, mostly for loose files"}; + setting_redirect quiet{this, {"quiet", "noverbose"}, {&nopercent, &nostat, &noprogress}, &logging_group, + "suppress non-important messages (equivalent to -nopercent -nostat -noprogress)"}; + setting_path gamedir{this, "gamedir", "", &game_group, + "override the default mod base directory. if this is not set, or if it is relative, it will be derived from the input file or the basedir if specified."}; + setting_path basedir{this, "basedir", "", &game_group, + "override the default game base directory. if this is not set, or if it is relative, it will be derived from the input file or the gamedir if specified."}; + setting_enum filepriority{this, "filepriority", search_priority_t::LOOSE, + {{"loose", search_priority_t::LOOSE}, {"archive", search_priority_t::ARCHIVE}}, &game_group, + "which types of archives (folders/loose files or packed archives) are higher priority and chosen first for path searching"}; + setting_set paths{this, "path", "\"/path/to/folder\" ", &game_group, + "additional paths or archives to add to the search path, mostly for loose files"}; setting_bool q2rtx{this, "q2rtx", false, &game_group, "adjust settings to best support Q2RTX"}; - setting_invertible_bool defaultpaths{this, "defaultpaths", true, &game_group, "whether the compiler should attempt to automatically derive game/base paths for games that support it"}; + setting_invertible_bool defaultpaths{this, "defaultpaths", true, &game_group, + "whether the compiler should attempt to automatically derive game/base paths for games that support it"}; virtual void setParameters(int argc, const char **argv); // before the parsing routine; set up options, members, etc virtual void preinitialize(int argc, const char **argv) { setParameters(argc, argv); } // do the actual parsing - virtual void initialize(int argc, const char **argv) { + virtual void initialize(int argc, const char **argv) + { token_parser_t p(argc, argv); parse(p); } diff --git a/include/common/vectorutils.hh b/include/common/vectorutils.hh index 88d97de2..36c9df78 100644 --- a/include/common/vectorutils.hh +++ b/include/common/vectorutils.hh @@ -23,8 +23,8 @@ #include #include -template -void sort_and_remove_duplicates(T& v) +template +void sort_and_remove_duplicates(T &v) { std::sort(v.begin(), v.end()); @@ -32,7 +32,7 @@ void sort_and_remove_duplicates(T& v) v.erase(last, v.end()); } -template +template std::vector concat(const std::vector &a, const std::vector &b) { std::vector result; diff --git a/include/light/entities.hh b/include/light/entities.hh index 56e43582..3ee18ea3 100644 --- a/include/light/entities.hh +++ b/include/light/entities.hh @@ -73,7 +73,8 @@ public: settings::setting_scalar light{this, "light", DEFAULTLIGHTLEVEL}; settings::setting_scalar atten{this, "wait", 1.0, 0.0, std::numeric_limits::max()}; settings::setting_enum formula{this, "delay", LF_LINEAR, - {{"linear", LF_LINEAR}, {"inverse", LF_INVERSE}, {"inverse2", LF_INVERSE2}, {"infinite", LF_INFINITE}, {"localmin", LF_LOCALMIN}, {"inverse2a", LF_INVERSE2A}}}; + {{"linear", LF_LINEAR}, {"inverse", LF_INVERSE}, {"inverse2", LF_INVERSE2}, {"infinite", LF_INFINITE}, + {"localmin", LF_LOCALMIN}, {"inverse2a", LF_INVERSE2A}}}; settings::setting_scalar spotangle{this, "angle", 40.0}; settings::setting_scalar spotangle2{this, "softangle", 0.0}; settings::setting_numeric style{this, "style", 0, 0, INVALID_LIGHTSTYLE - 1}; diff --git a/include/light/light.hh b/include/light/light.hh index ed49c85b..1332bc6a 100644 --- a/include/light/light.hh +++ b/include/light/light.hh @@ -132,7 +132,7 @@ struct lightsurf_t fully occluded. dirtgain/dirtscale are not applied yet */ std::vector occlusion; - + /* pvs for the entire light surface. generated by ORing together the pvs at each of the sample points @@ -252,7 +252,8 @@ enum class visapprox_t // worldspawn keys / command-line settings // -enum { +enum +{ // Q1-style surface light copies SURFLIGHT_Q1 = 0, // Q2/Q3-style radiosity @@ -300,8 +301,7 @@ public: setting_scalar bouncecolorscale{this, "bouncecolorscale", 0.0, 0.0, 1.0, &worldspawn_group}; /* Q2 surface lights (mxd) */ - setting_scalar surflightscale{ - this, "surflightscale", 1.0, &worldspawn_group}; + setting_scalar surflightscale{this, "surflightscale", 1.0, &worldspawn_group}; setting_scalar surflightsubdivision{this, {"surflightsubdivision", "choplight"}, 16.0, 1.0, 8192.0, &worldspawn_group}; // "choplight" - arghrad3 name @@ -323,7 +323,8 @@ public: setting_scalar sun_deviance{this, "sunlight_penumbra", 0.0, 0.0, 180.0, &worldspawn_group}; setting_vec3 sky_surface{ this, {"sky_surface", "sun_surface"}, 0, 0, 0, &worldspawn_group} /* arghrad surface lights on sky faces */; - setting_int32 surflight_radiosity{this, "surflight_radiosity", SURFLIGHT_Q1, &worldspawn_group, "whether to use Q1-style surface subdivision (0) or Q2-style surface radiosity"}; + setting_int32 surflight_radiosity{this, "surflight_radiosity", SURFLIGHT_Q1, &worldspawn_group, + "whether to use Q1-style surface subdivision (0) or Q2-style surface radiosity"}; }; extern setting_group output_group; @@ -355,8 +356,7 @@ public: parser.parse_token(); return true; - } - catch (std::exception &) { + } catch (std::exception &) { // if we didn't provide a (valid) number, then // assume it's meant to be the default of -1 setValue(-1, source); @@ -415,9 +415,13 @@ public: this, "lightmap_scale", 0, &experimental_group, "force change lightmap scale; vanilla engines only allow 16"}; setting_extra extra{ this, {"extra", "extra4"}, 1, &performance_group, "supersampling; 2x2 (extra) or 4x4 (extra4) respectively"}; - setting_enum visapprox{ - this, "visapprox", visapprox_t::AUTO, { { "auto", visapprox_t::AUTO }, { "none", visapprox_t::NONE }, { "vis", visapprox_t::VIS }, { "rays", visapprox_t::RAYS } }, &debug_group, "change approximate visibility algorithm. auto = choose default based on format. vis = use BSP vis data (slow but precise). rays = use sphere culling with fired rays (fast but may miss faces)"}; - setting_func lit{this, "lit", [&](source) { write_litfile |= lightfile::external; }, &output_group, "write .lit file"}; + setting_enum visapprox{this, "visapprox", visapprox_t::AUTO, + {{"auto", visapprox_t::AUTO}, {"none", visapprox_t::NONE}, {"vis", visapprox_t::VIS}, + {"rays", visapprox_t::RAYS}}, + &debug_group, + "change approximate visibility algorithm. auto = choose default based on format. vis = use BSP vis data (slow but precise). rays = use sphere culling with fired rays (fast but may miss faces)"}; + setting_func lit{ + this, "lit", [&](source) { write_litfile |= lightfile::external; }, &output_group, "write .lit file"}; setting_func lit2{ this, "lit2", [&](source) { write_litfile = lightfile::lit2; }, &experimental_group, "write .lit2 file"}; setting_func bspxlit{this, "bspxlit", [&](source) { write_litfile |= lightfile::bspx; }, &experimental_group, @@ -441,9 +445,11 @@ public: &experimental_group, "writes both rgb and directions data into the bsp itself"}; setting_bool litonly{this, "litonly", false, &output_group, "only write .lit file, don't modify BSP"}; setting_bool nolights{this, "nolights", false, &output_group, "ignore light entities (only sunlight/minlight)"}; - setting_int32 facestyles{this, "facestyles", 4, &output_group, "max amount of styles per face; requires BSPX lump if > 4"}; + setting_int32 facestyles{ + this, "facestyles", 4, &output_group, "max amount of styles per face; requires BSPX lump if > 4"}; setting_bool exportobj{this, "exportobj", false, &output_group, "export an .OBJ for inspection"}; - setting_int32 lmshift{this, "lmshift", 4, &output_group, "force a specified lmshift to be applied to the entire map; this is useful if you want to re-light a map with higher quality BSPX lighting without the sources. Will add the LMSHIFT lump to the BSP."}; + setting_int32 lmshift{this, "lmshift", 4, &output_group, + "force a specified lmshift to be applied to the entire map; this is useful if you want to re-light a map with higher quality BSPX lighting without the sources. Will add the LMSHIFT lump to the BSP."}; inline void CheckNoDebugModeSet() { diff --git a/include/light/litfile.hh b/include/light/litfile.hh index c7712b2e..77143bc0 100644 --- a/include/light/litfile.hh +++ b/include/light/litfile.hh @@ -27,7 +27,7 @@ struct litheader_t { struct { - std::array ident = { 'Q', 'L', 'I', 'T' }; + std::array ident = {'Q', 'L', 'I', 'T'}; int version; auto stream_data() { return std::tie(ident, version); } diff --git a/include/light/ltface.hh b/include/light/ltface.hh index 834487c1..12fae39f 100644 --- a/include/light/ltface.hh +++ b/include/light/ltface.hh @@ -52,11 +52,11 @@ std::unordered_map GetDirectLighting( void SetupDirt(settings::worldspawn_keys &cfg); float DirtAtPoint(const settings::worldspawn_keys &cfg, raystream_intersection_t *rs, const qvec3d &point, const qvec3d &normal, const modelinfo_t *selfshadow); -std::unique_ptr CreateLightmapSurface(const mbsp_t *bsp, const mface_t *face, const facesup_t *facesup, const settings::worldspawn_keys &cfg); +std::unique_ptr CreateLightmapSurface( + const mbsp_t *bsp, const mface_t *face, const facesup_t *facesup, const settings::worldspawn_keys &cfg); bool Face_IsLightmapped(const mbsp_t *bsp, const mface_t *face); void DirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings::worldspawn_keys &cfg); void IndirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings::worldspawn_keys &cfg); -void FinishLightmapSurface( - const mbsp_t *bsp, lightsurf_t *lightsurf); -void SaveLightmapSurface( - const mbsp_t *bsp, mface_t *face, facesup_t *facesup, const lightsurf_t *lightsurf, const faceextents_t &extents, const faceextents_t &output_extents); +void FinishLightmapSurface(const mbsp_t *bsp, lightsurf_t *lightsurf); +void SaveLightmapSurface(const mbsp_t *bsp, mface_t *face, facesup_t *facesup, const lightsurf_t *lightsurf, + const faceextents_t &extents, const faceextents_t &output_extents); diff --git a/include/light/trace.hh b/include/light/trace.hh index b9901fde..3642d328 100644 --- a/include/light/trace.hh +++ b/include/light/trace.hh @@ -43,7 +43,8 @@ enum class hittype_t : uint8_t }; uint32_t clamp_texcoord(vec_t in, uint32_t width); -qvec4b SampleTexture(const mface_t *face, const mtexinfo_t *tex, const img::texture *texture, const mbsp_t *bsp, const qvec3d &point); // mxd. Palette index -> RGBA +qvec4b SampleTexture(const mface_t *face, const mtexinfo_t *tex, const img::texture *texture, const mbsp_t *bsp, + const qvec3d &point); // mxd. Palette index -> RGBA class modelinfo_t; @@ -67,7 +68,7 @@ struct hitresult_t hitresult_t TestSky(const qvec3d &start, const qvec3d &dirn, const modelinfo_t *self, const mface_t **face_out); hitresult_t TestLight(const qvec3d &start, const qvec3d &stop, const modelinfo_t *self); -const mleaf_t *Light_PointInLeaf( const mbsp_t *bsp, const qvec3d &point ); -int Light_PointContents( const mbsp_t *bsp, const qvec3d &point ); +const mleaf_t *Light_PointInLeaf(const mbsp_t *bsp, const qvec3d &point); +int Light_PointContents(const mbsp_t *bsp, const qvec3d &point); #include "trace_embree.hh" \ No newline at end of file diff --git a/include/light/trace_embree.hh b/include/light/trace_embree.hh index 8d331321..446ae3c3 100644 --- a/include/light/trace_embree.hh +++ b/include/light/trace_embree.hh @@ -91,10 +91,7 @@ public: return _ray_dynamic_styles[j]; } - inline void clearPushedRays() - { - _numrays = 0; - } + inline void clearPushedRays() { _numrays = 0; } }; #include @@ -190,10 +187,7 @@ private: public: inline raystream_intersection_t() = default; - inline raystream_intersection_t(size_t maxRays) - { - resize(maxRays); - } + inline raystream_intersection_t(size_t maxRays) { resize(maxRays); } void resize(size_t size) override { @@ -280,10 +274,7 @@ private: public: inline raystream_occlusion_t() = default; - inline raystream_occlusion_t(size_t maxRays) - { - resize(maxRays); - } + inline raystream_occlusion_t(size_t maxRays) { resize(maxRays); } void resize(size_t size) override { diff --git a/include/qbsp/brush.hh b/include/qbsp/brush.hh index 79978930..d8e680eb 100644 --- a/include/qbsp/brush.hh +++ b/include/qbsp/brush.hh @@ -43,16 +43,17 @@ struct side_t bool visible = true; // can any part of this side be seen from non-void parts of the level? // non-visible means we can discard the brush side // (avoiding generating a BSP spit, so expanding it outwards) - bool bevel; // don't ever use for bsp splitting + bool bevel; // don't ever use for bsp splitting bool tested; - const maptexinfo_t& get_texinfo() const; + const maptexinfo_t &get_texinfo() const; }; class mapbrush_t; -struct bspbrush_t { +struct bspbrush_t +{ /** * The brushes in the mapentity_t::brushes vector are considered originals. Brush fragments created during * the BrushBSP will have this pointing back to the original brush in mapentity_t::brushes. @@ -62,7 +63,7 @@ struct bspbrush_t { bspbrush_t *original; uint32_t file_order; aabb3d bounds; - int side, testside; // side of node during construction + int side, testside; // side of node during construction std::vector sides; contentflags_t contents; /* BSP contents */ short lmshift; /* lightmap scaling (qu/lightmap pixel), passed to the light util */ diff --git a/include/qbsp/csg.hh b/include/qbsp/csg.hh index 2fb1720f..80ff3db7 100644 --- a/include/qbsp/csg.hh +++ b/include/qbsp/csg.hh @@ -33,7 +33,8 @@ struct face_t; struct side_t; std::unique_ptr NewFaceFromFace(const face_t *in); -std::unique_ptr CopyFace(const face_t* in); -std::tuple, std::unique_ptr> SplitFace(std::unique_ptr in, const qplane3d &split); +std::unique_ptr CopyFace(const face_t *in); +std::tuple, std::unique_ptr> SplitFace( + std::unique_ptr in, const qplane3d &split); void UpdateFaceSphere(face_t *in); std::vector> MakeBspBrushList(mapentity_t *entity); diff --git a/include/qbsp/faces.hh b/include/qbsp/faces.hh index 437cad46..861f53ce 100644 --- a/include/qbsp/faces.hh +++ b/include/qbsp/faces.hh @@ -25,5 +25,5 @@ struct node_t; -void MakeMarkFaces(node_t* headnode); +void MakeMarkFaces(node_t *headnode); void MakeFaces(node_t *node); diff --git a/include/qbsp/map.hh b/include/qbsp/map.hh index dcdddc8b..9bdde453 100644 --- a/include/qbsp/map.hh +++ b/include/qbsp/map.hh @@ -130,10 +130,7 @@ struct mapplane_t : qbsp_plane_t { std::optional outputnum; - inline mapplane_t(const qbsp_plane_t ©) : - qbsp_plane_t(copy) - { - } + inline mapplane_t(const qbsp_plane_t ©) : qbsp_plane_t(copy) { } }; struct mapdata_t @@ -154,7 +151,7 @@ struct mapdata_t // hashed vertices; generated by EmitVertices std::map> hashverts; - + // find vector of points in hash closest to vec inline auto find_hash_vector(const qvec3d &vec) { @@ -185,19 +182,16 @@ struct mapdata_t 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[h].push_front({point, num}); } } } } - + // hashed edges; generated by EmitEdges std::map, int64_t> hashedges; - inline void add_hash_edge(size_t v1, size_t v2, int64_t i) - { - hashedges.emplace(std::make_pair(v1, v2), i); - } + inline void add_hash_edge(size_t v1, size_t v2, int64_t i) { hashedges.emplace(std::make_pair(v1, v2), i); } /* Misc other global state for the compile process */ bool leakfile = false; /* Flag once we've written a leak (.por/.pts) file */ @@ -227,7 +221,8 @@ struct mapdata_t const std::string &texinfoTextureName(int texinfo) const { return miptexTextureName(mtexinfos.at(texinfo).miptex); } - inline qbsp_plane_t get_plane(int pnum) { + inline qbsp_plane_t get_plane(int pnum) + { std::shared_lock lock(map_planes_lock); return planes.at(pnum); } @@ -260,7 +255,8 @@ struct quark_tx_info_t std::optional info; }; -int FindMiptex(const char *name, std::optional &extended_info, bool internal = false, bool recursive = true); +int FindMiptex( + const char *name, std::optional &extended_info, bool internal = false, bool recursive = true); inline int FindMiptex(const char *name, bool internal = false, bool recursive = true) { std::optional extended_info; @@ -280,7 +276,8 @@ constexpr int HULL_COLLISION = -1; /* Create BSP brushes from map brushes */ void Brush_LoadEntity(mapentity_t *entity, const int hullnum); -std::list CSGFace(face_t *srcface, const mapentity_t* srcentity, const bspbrush_t *srcbrush, const node_t *srcnode); +std::list CSGFace( + face_t *srcface, const mapentity_t *srcentity, const bspbrush_t *srcbrush, const node_t *srcnode); void TJunc(node_t *headnode); int MakeFaceEdges(node_t *headnode); void EmitVertices(node_t *headnode); diff --git a/include/qbsp/portals.hh b/include/qbsp/portals.hh index b8017af3..2d65f2d2 100644 --- a/include/qbsp/portals.hh +++ b/include/qbsp/portals.hh @@ -40,11 +40,13 @@ struct portal_t std::optional winding; bool sidefound; // false if ->side hasn't been checked - side_t *sides[2]; // [0] = the brush side visible on nodes[0] - it could come from a brush in nodes[1]. NULL = non-visible + side_t *sides[2]; // [0] = the brush side visible on nodes[0] - it could come from a brush in nodes[1]. NULL = + // non-visible face_t *face[2]; // output face in bsp file }; -struct portalstats_t { +struct portalstats_t +{ std::atomic c_tinyportals; }; @@ -58,4 +60,4 @@ void AssertNoPortals(tree_t *tree); void MakeHeadnodePortals(tree_t *tree); void EmitAreaPortals(node_t *headnode); void FloodAreas(mapentity_t *entity, node_t *headnode); -void MarkVisibleSides(tree_t *tree, mapentity_t* entity); +void MarkVisibleSides(tree_t *tree, mapentity_t *entity); diff --git a/include/qbsp/qbsp.hh b/include/qbsp/qbsp.hh index 20afceb6..8deaa0e9 100644 --- a/include/qbsp/qbsp.hh +++ b/include/qbsp/qbsp.hh @@ -104,7 +104,8 @@ public: constexpr const std::set &pathsValue() const { return _paths; } - inline bool copyFrom(const setting_base& other) override { + inline bool copyFrom(const setting_base &other) override + { if (auto *casted = dynamic_cast(&other)) { _paths = casted->_paths; _source = casted->_source; @@ -113,7 +114,8 @@ public: return false; } - inline void reset() override { + inline void reset() override + { _paths = {}; _source = source::DEFAULT; } @@ -200,8 +202,10 @@ public: setting_bool bsp2{this, "bsp2", false, &game_target_group, "target Quake's extended BSP2 format"}; setting_bool bsp2rmq{ this, "2psb", false, &game_target_group, "target Quake's extended 2PSB format (RMQ compatible)"}; - setting_func nosubdivide{this, "nosubdivide", [&](source src) { subdivide.setValue(0, src); }, &common_format_group, "disable subdivision"}; - setting_invertible_bool software{this, "software", true, &common_format_group, "change settings to allow for (or make adjustments to optimize for the lack of) software support"}; + setting_func nosubdivide{this, "nosubdivide", [&](source src) { subdivide.setValue(0, src); }, &common_format_group, + "disable subdivision"}; + setting_invertible_bool software{this, "software", true, &common_format_group, + "change settings to allow for (or make adjustments to optimize for the lack of) software support"}; setting_int32 subdivide{this, "subdivide", 240, &common_format_group, "change the subdivide threshold, in luxels. 0 will disable subdivision entirely"}; setting_bool nofill{this, "nofill", false, &debugging_group, "don't perform outside filling"}; @@ -211,8 +215,8 @@ public: setting_bool nodetail{this, "nodetail", false, &debugging_group, "treat all detail brushes to structural"}; setting_bool onlyents{this, "onlyents", false, &map_development_group, "only updates .MAP entities"}; setting_bool splitsky{this, "splitsky", false, &debugging_group, "doesn't combine sky faces into one large face"}; - setting_bool splitturb{this, {"litwater", "splitturb"}, true, &common_format_group, - "doesn't combine water faces into one large face"}; + setting_bool splitturb{ + this, {"litwater", "splitturb"}, true, &common_format_group, "doesn't combine water faces into one large face"}; setting_redirect splitspecial{this, "splitspecial", {&splitsky, &splitturb}, &debugging_group, "doesn't combine sky and water faces into one large face (splitturb + splitsky)"}; setting_invertible_bool transwater{ @@ -237,16 +241,14 @@ public: this, "oldrottex", false, &debugging_group, "use old rotate_ brush texturing aligned at (0 0 0)"}; setting_scalar epsilon{ this, "epsilon", 0.0001, 0.0, 1.0, &debugging_group, "customize epsilon value for point-on-plane checks"}; - setting_scalar microvolume{ - this, "microvolume", 1.0, 0.0, 1000.0, &debugging_group, "microbrush volume"}; + setting_scalar microvolume{this, "microvolume", 1.0, 0.0, 1000.0, &debugging_group, "microbrush volume"}; setting_bool contenthack{this, "contenthack", false, &debugging_group, "hack to fix leaks through solids. causes missing faces in some cases so disabled by default"}; setting_bool leaktest{this, "leaktest", false, &map_development_group, "make compilation fail if the map leaks"}; - setting_bool outsidedebug{this, "outsidedebug", false, &debugging_group, "write a .map after outside filling showing non-visible brush sides"}; - setting_bool debugchop{this, "debugchop", false, &debugging_group, - "write a .map after ChopBrushes"}; - setting_bool keepprt{this, "keepprt", false, &debugging_group, - "avoid deleting the .prt file on leaking maps"}; + setting_bool outsidedebug{this, "outsidedebug", false, &debugging_group, + "write a .map after outside filling showing non-visible brush sides"}; + setting_bool debugchop{this, "debugchop", false, &debugging_group, "write a .map after ChopBrushes"}; + setting_bool keepprt{this, "keepprt", false, &debugging_group, "avoid deleting the .prt file on leaking maps"}; setting_bool includeskip{this, "includeskip", false, &common_format_group, "don't cull skip faces from the list of renderable surfaces (Q2RTX)"}; setting_scalar worldextent{ @@ -254,8 +256,9 @@ public: setting_int32 leakdist{this, "leakdist", 2, &debugging_group, "space between leakfile points"}; setting_bool forceprt1{ this, "forceprt1", false, &debugging_group, "force a PRT1 output file even if PRT2 is required for vis"}; - setting_tjunc tjunc{this, { "tjunc", "notjunc" }, tjunclevel_t::MWT, - { { "none", tjunclevel_t::NONE }, { "rotate", tjunclevel_t::ROTATE }, { "retopologize", tjunclevel_t::RETOPOLOGIZE }, { "mwt", tjunclevel_t::MWT } }, + setting_tjunc tjunc{this, {"tjunc", "notjunc"}, tjunclevel_t::MWT, + {{"none", tjunclevel_t::NONE}, {"rotate", tjunclevel_t::ROTATE}, {"retopologize", tjunclevel_t::RETOPOLOGIZE}, + {"mwt", tjunclevel_t::MWT}}, &debugging_group, "T-junction fix level"}; setting_bool objexport{ this, "objexport", false, &debugging_group, "export the map file as .OBJ models during various CSG phases"}; @@ -275,23 +278,32 @@ public: this, "expand", false, &common_format_group, "write hull 1 expanded brushes to expanded.map for debugging"}; setting_wadpathset wadpaths{this, {"wadpath", "xwadpath"}, &map_development_group, "add a path to the wad search paths; wads found in xwadpath's will not be embedded, otherwise they will be embedded (if not -notex)"}; - setting_bool notriggermodels{this, "notriggermodels", false, &common_format_group, "for supported game code only: triggers will not write a model\nout, and will instead just write out their mins/maxs."}; - setting_set aliasdefs{this, "aliasdef", "\"path/to/file.def\" ", &map_development_group, "path to an alias definition file, which can transform entities in the .map into other entities."}; - setting_set texturedefs{this, "texturedefs", "\"path/to/file.def\" ", &map_development_group, "path to a texture definition file, which can transform textures in the .map into other textures."}; - setting_numeric lmscale{this, "lmscale", 1.0, &common_format_group, "change global lmscale (force _lmscale key on all entities). outputs the LMSCALE BSPX lump." }; - setting_enum filltype{this, "filltype", filltype_t::AUTO, { { "auto", filltype_t::AUTO }, { "inside", filltype_t::INSIDE }, { "outside", filltype_t::OUTSIDE } }, &common_format_group, + setting_bool notriggermodels{this, "notriggermodels", false, &common_format_group, + "for supported game code only: triggers will not write a model\nout, and will instead just write out their mins/maxs."}; + setting_set aliasdefs{this, "aliasdef", "\"path/to/file.def\" ", &map_development_group, + "path to an alias definition file, which can transform entities in the .map into other entities."}; + setting_set texturedefs{this, "texturedefs", "\"path/to/file.def\" ", &map_development_group, + "path to a texture definition file, which can transform textures in the .map into other textures."}; + setting_numeric lmscale{this, "lmscale", 1.0, &common_format_group, + "change global lmscale (force _lmscale key on all entities). outputs the LMSCALE BSPX lump."}; + setting_enum filltype{this, "filltype", filltype_t::AUTO, + {{"auto", filltype_t::AUTO}, {"inside", filltype_t::INSIDE}, {"outside", filltype_t::OUTSIDE}}, + &common_format_group, "whether to fill the map from the outside in (lenient), from the inside out (aggressive), or to automatically decide based on the hull being used."}; - setting_invertible_bool allow_upgrade{this, "allowupgrade", true, &common_format_group, "allow formats to \"upgrade\" to compatible extended formats when a limit is exceeded (ie Quake BSP to BSP2)"}; + setting_invertible_bool allow_upgrade{this, "allowupgrade", true, &common_format_group, + "allow formats to \"upgrade\" to compatible extended formats when a limit is exceeded (ie Quake BSP to BSP2)"}; setting_validator maxedges{ - [](setting_int32 &setting) { - return setting.value() == 0 || setting.value() >= 3; - }, this, "maxedges", 64, &map_development_group, "the max number of edges/vertices on a single face before it is split into another face"}; - setting_invertible_bool snapvertices{this, "snapvertices", false, &common_format_group, "round vertice locations; this is mainly for compatibility with older Quake II tools."}; + [](setting_int32 &setting) { return setting.value() == 0 || setting.value() >= 3; }, this, "maxedges", 64, + &map_development_group, + "the max number of edges/vertices on a single face before it is split into another face"}; + setting_invertible_bool snapvertices{this, "snapvertices", false, &common_format_group, + "round vertice locations; this is mainly for compatibility with older Quake II tools."}; void setParameters(int argc, const char **argv) override { common_settings::setParameters(argc, argv); - programDescription = "qbsp performs geometric level processing of Quake .MAP files to create\nQuake .BSP files.\n\n"; + programDescription = + "qbsp performs geometric level processing of Quake .MAP files to create\nQuake .BSP files.\n\n"; remainderName = "sourcefile.map [destfile.bsp]"; } void initialize(int argc, const char **argv) override; @@ -412,16 +424,9 @@ protected: public: qbsp_plane_t() = default; qbsp_plane_t(const qbsp_plane_t &) = default; - inline qbsp_plane_t(const qplane3d &plane, bool flip) noexcept : - plane(plane) - { - normalize(flip); - } + inline qbsp_plane_t(const qplane3d &plane, bool flip) noexcept : plane(plane) { normalize(flip); } - inline qbsp_plane_t(const qplane3d &plane) noexcept : - qbsp_plane_t(plane, false) - { - } + inline qbsp_plane_t(const qplane3d &plane) noexcept : qbsp_plane_t(plane, false) { } qbsp_plane_t &operator=(const qbsp_plane_t &) = default; inline qbsp_plane_t &operator=(const qplane3d &plane) noexcept @@ -458,7 +463,10 @@ public: [[nodiscard]] constexpr operator const qplane3d &() const { return plane; } template - [[nodiscard]] inline T distance_to(const qvec &pt) const { return plane.distance_to(pt); } + [[nodiscard]] inline T distance_to(const qvec &pt) const + { + return plane.distance_to(pt); + } // normalize the given plane, optionally flipping it to face // the positive direction. returns whether the plane was flipped or not. @@ -513,14 +521,16 @@ namespace qv { // faster version of epsilonEqual for BSP planes // which have a bit more info in them -[[nodiscard]] inline bool epsilonEqual(const qbsp_plane_t &p1, const qbsp_plane_t &p2, vec_t normalEpsilon = NORMAL_EPSILON, vec_t distEpsilon = DIST_EPSILON) +[[nodiscard]] inline bool epsilonEqual(const qbsp_plane_t &p1, const qbsp_plane_t &p2, + vec_t normalEpsilon = NORMAL_EPSILON, vec_t distEpsilon = DIST_EPSILON) { // axial planes will never match on normal, so we can skip that check entirely if (p1.get_type() < plane_type_t::PLANE_ANYX && p2.get_type() < plane_type_t::PLANE_ANYX) { // if we aren't the same type, we definitely aren't equal if (p1.get_type() != p2.get_type()) { return false; - } else if (p1.get_normal()[static_cast(p1.get_type())] != p2.get_normal()[static_cast(p2.get_type())]) { + } else if (p1.get_normal()[static_cast(p1.get_type())] != + p2.get_normal()[static_cast(p2.get_type())]) { // axials will always be only 1 or -1 return false; } @@ -557,7 +567,8 @@ struct node_t qbsp_plane_t plane; // decision node only int firstface; // decision node only int numfaces; // decision node only - twosided> children; // children[0] = front side, children[1] = back side of plane. only valid for decision nodes + twosided> + children; // children[0] = front side, children[1] = back side of plane. only valid for decision nodes std::list> facelist; // decision nodes only, list for both sides side_t *side; // decision node only, the side that created the node @@ -580,7 +591,7 @@ struct node_t }; void InitQBSP(int argc, const char **argv); -void InitQBSP(const std::vector& args); +void InitQBSP(const std::vector &args); void ProcessFile(); int qbsp_main(int argc, const char **argv); diff --git a/include/vis/leafbits.hh b/include/vis/leafbits.hh index 8b69e093..89763a88 100644 --- a/include/vis/leafbits.hh +++ b/include/vis/leafbits.hh @@ -26,7 +26,7 @@ class leafbits_t { size_t _size = 0; - std::unique_ptr bits {}; + std::unique_ptr bits{}; constexpr size_t block_size() const { return (_size + mask) >> shift; } inline std::unique_ptr allocate() { return std::make_unique(block_size()); } @@ -40,13 +40,13 @@ public: inline leafbits_t(size_t size) : _size(size), bits(allocate()) { } - inline leafbits_t(const leafbits_t ©) : leafbits_t(copy._size) { memcpy(bits.get(), copy.bits.get(), byte_size()); } - - inline leafbits_t(leafbits_t &&move) noexcept : _size(move._size), bits(std::move(move.bits)) + inline leafbits_t(const leafbits_t ©) : leafbits_t(copy._size) { - move._size = 0; + memcpy(bits.get(), copy.bits.get(), byte_size()); } + inline leafbits_t(leafbits_t &&move) noexcept : _size(move._size), bits(std::move(move.bits)) { move._size = 0; } + inline leafbits_t &operator=(leafbits_t &&move) noexcept { _size = move._size; diff --git a/include/vis/vis.hh b/include/vis/vis.hh index 277dd44a..92cef7f7 100644 --- a/include/vis/vis.hh +++ b/include/vis/vis.hh @@ -243,8 +243,10 @@ public: setting_scalar visdist{ this, "visdist", 0.0, &advanced_group, "control the distance required for a portal to be considered seen"}; setting_bool nostate{this, "nostate", false, &advanced_group, "ignore saved state files, for forced re-runs"}; - setting_bool phsonly{this, "phsonly", false, &advanced_group, "re-calculate the PHS of a Quake II BSP without touching the PVS"}; - setting_invertible_bool autoclean{this, "autoclean", true, &output_group, "remove any extra files on successful completion"}; + setting_bool phsonly{ + this, "phsonly", false, &advanced_group, "re-calculate the PHS of a Quake II BSP without touching the PVS"}; + setting_invertible_bool autoclean{ + this, "autoclean", true, &output_group, "remove any extra files on successful completion"}; fs::path sourceMap; diff --git a/light/bounce.cc b/light/bounce.cc index c2725042..c5942416 100644 --- a/light/bounce.cc +++ b/light/bounce.cc @@ -102,8 +102,8 @@ inline bouncelight_t &CreateBounceLight(const mface_t *face, const mbsp_t *bsp) return l; } -static void AddBounceLight(const qvec3d &pos, const std::unordered_map &colorByStyle, const qvec3d &surfnormal, - vec_t area, const mface_t *face, const mbsp_t *bsp) +static void AddBounceLight(const qvec3d &pos, const std::unordered_map &colorByStyle, + const qvec3d &surfnormal, vec_t area, const mface_t *face, const mbsp_t *bsp) { for (const auto &styleColor : colorByStyle) { Q_assert(styleColor.second[0] >= 0); @@ -198,7 +198,7 @@ static void MakeBounceLightsThread(const settings::worldspawn_keys &cfg, const m styleColor.second *= cfg.bouncescale.value(); total += styleColor.second; } - + // no bounced color, we can leave early if (qv::emptyExact(total)) { return; @@ -222,9 +222,7 @@ void MakeBounceLights(const settings::worldspawn_keys &cfg, const mbsp_t *bsp) { logging::print("--- MakeBounceLights ---\n"); - logging::parallel_for_each(bsp->dfaces, [&](const mface_t &face) { - MakeBounceLightsThread(cfg, bsp, face); - }); + logging::parallel_for_each(bsp->dfaces, [&](const mface_t &face) { MakeBounceLightsThread(cfg, bsp, face); }); logging::print("{} bounce lights created\n", bouncelights.size()); } diff --git a/light/entities.cc b/light/entities.cc index d12bd5e1..704108ce 100644 --- a/light/entities.cc +++ b/light/entities.cc @@ -150,13 +150,12 @@ static std::string EntDict_PrettyDescription(const mbsp_t *bsp, const entdict_t const dmodelh2_t *info = BSP_DModelForModelString(bsp, submodel_str); if (info) { - return fmt::format("brush entity with mins [{}] maxs [{}] ({})", info->mins, info->maxs, - entity.get("classname")); + return fmt::format( + "brush entity with mins [{}] maxs [{}] ({})", info->mins, info->maxs, entity.get("classname")); } } - return fmt::format( - "entity at ({}) ({})", entity.get("origin"), entity.get("classname")); + return fmt::format("entity at ({}) ({})", entity.get("origin"), entity.get("classname")); } bool EntDict_CheckNoEmptyValues(const mbsp_t *bsp, const entdict_t &entdict) @@ -215,7 +214,7 @@ static void CheckEntityFields(const settings::worldspawn_keys &cfg, light_t *ent // mxd. Warn about unsupported _falloff / delay combos... if (entity->falloff.value() > 0.0f && entity->getFormula() != LF_LINEAR) { logging::print("WARNING: _falloff is currently only supported on linear (delay 0) lights\n" - " {} at [{}]\n", + " {} at [{}]\n", entity->classname(), entity->origin.value()); entity->falloff.setValue(0.0f, settings::source::MAP); } @@ -489,8 +488,9 @@ static void SetupSkyDomes(const settings::worldspawn_keys &cfg) entity->anglescale.value(), entity->style.value(), entity->suntexture.value(), 0, {}, 0, 0, 0, ""); } else { // Add the lower dome, like sunlight3 (pointing up) - SetupSkyDome(cfg, 0, {}, 0, 0, 0, "", entity->light.value(), entity->color.value(), entity->dirt.value(), - entity->anglescale.value(), entity->style.value(), entity->suntexture.value()); + SetupSkyDome(cfg, 0, {}, 0, 0, 0, "", entity->light.value(), entity->color.value(), + entity->dirt.value(), entity->anglescale.value(), entity->style.value(), + entity->suntexture.value()); } // Disable the light itself... @@ -535,7 +535,7 @@ static std::unique_ptr DuplicateEntity(const light_t &src) * From q3map2 * ============= */ -static void JitterEntity(const light_t& entity) +static void JitterEntity(const light_t &entity) { std::vector> new_lights; @@ -554,7 +554,8 @@ static void JitterEntity(const light_t& entity) } // move the new lights into all_lights - // (don't modify the all_lights vector in the loop above, because it could invalidate the passed in `entity` reference) + // (don't modify the all_lights vector in the loop above, because it could invalidate the passed in `entity` + // reference) for (auto &new_light : new_lights) { all_lights.push_back(std::move(new_light)); } @@ -900,13 +901,13 @@ void LoadEntities(const settings::worldspawn_keys &cfg, const mbsp_t *bsp) if (entity->projectedmip->meta.width > entity->projectedmip->meta.height) Matrix4x4_CM_MakeModelViewProj(entity->projangle.value(), entity->origin.value(), entity->projfov.value(), - CalcFov( - entity->projfov.value(), entity->projectedmip->meta.width, entity->projectedmip->meta.height), + CalcFov(entity->projfov.value(), entity->projectedmip->meta.width, + entity->projectedmip->meta.height), entity->projectionmatrix); else Matrix4x4_CM_MakeModelViewProj(entity->projangle.value(), entity->origin.value(), - CalcFov( - entity->projfov.value(), entity->projectedmip->meta.height, entity->projectedmip->meta.width), + CalcFov(entity->projfov.value(), entity->projectedmip->meta.height, + entity->projectedmip->meta.width), entity->projfov.value(), entity->projectionmatrix); } @@ -1192,8 +1193,7 @@ bool FaceMatchesSurfaceLightTemplate(const mbsp_t *bsp, const mface_t *face, con radiosity_type = light_options.surflight_radiosity.value(); } - return !Q_strcasecmp(texname, surflight.epairs->get("_surface")) && - radiosity_type == surf_type; + return !Q_strcasecmp(texname, surflight.epairs->get("_surface")) && radiosity_type == surf_type; } /* @@ -1409,8 +1409,9 @@ static void MakeSurfaceLights(const mbsp_t *bsp) face_visited.at(facenum) = true; /* Don't bother subdividing if it doesn't match any surface light templates */ - if (!std::any_of(surfacelight_templates.begin(), surfacelight_templates.end(), - [&](const auto &surflight) { return FaceMatchesSurfaceLightTemplate(bsp, surf, *surflight, SURFLIGHT_Q1); })) + if (!std::any_of(surfacelight_templates.begin(), surfacelight_templates.end(), [&](const auto &surflight) { + return FaceMatchesSurfaceLightTemplate(bsp, surf, *surflight, SURFLIGHT_Q1); + })) continue; /* Generate the lights */ diff --git a/light/light.cc b/light/light.cc index 55e1f4e0..1e53df45 100644 --- a/light/light.cc +++ b/light/light.cc @@ -38,7 +38,7 @@ #include #include -#if defined(HAVE_EMBREE) && defined (__SSE2__) +#if defined(HAVE_EMBREE) && defined(__SSE2__) #include //#include #endif @@ -179,11 +179,11 @@ void light_settings::postinitialize(int argc, const char **argv) } } - // upgrade to uint16 if facestyles is specified + // upgrade to uint16 if facestyles is specified if (light_options.facestyles.value() > MAXLIGHTMAPS && !light_options.compilerstyle_max.isChanged()) { light_options.compilerstyle_max.setValue(INVALID_LIGHTSTYLE, settings::source::COMMANDLINE); } - + common_settings::postinitialize(argc, argv); } } // namespace settings @@ -270,7 +270,7 @@ void GetFileSpace(uint8_t **lightdata, uint8_t **colordata, uint8_t **deluxdata, void GetFileSpace_PreserveOffsetInBsp(uint8_t **lightdata, uint8_t **colordata, uint8_t **deluxdata, int lightofs) { Q_assert(lightofs >= 0); - + *lightdata = *colordata = *deluxdata = nullptr; if (!filebase.empty()) { @@ -321,7 +321,7 @@ const img::texture *Face_Texture(const mbsp_t *bsp, const mface_t *face) static void CacheTextures(const mbsp_t &bsp) { face_textures.resize(bsp.dfaces.size()); - + for (size_t i = 0; i < bsp.dfaces.size(); i++) { const char *name = Face_TextureName(&bsp, &bsp.dfaces[i]); @@ -388,7 +388,8 @@ static void SaveLightmapSurfaces(mbsp_t *bsp) } SaveLightmapSurface(bsp, f, &faces_sup[i], surf.get(), surf->extents, surf->extents); for (int j = 0; j < MAXLIGHTMAPS; j++) { - f->styles[j] = faces_sup[i].styles[j] == INVALID_LIGHTSTYLE ? INVALID_LIGHTSTYLE_OLD : faces_sup[i].styles[j]; + f->styles[j] = + faces_sup[i].styles[j] == INVALID_LIGHTSTYLE ? INVALID_LIGHTSTYLE_OLD : faces_sup[i].styles[j]; } } else { SaveLightmapSurface(bsp, f, nullptr, surf.get(), surf->extents, surf->vanilla_extents); @@ -556,7 +557,8 @@ static void LightWorld(bspdata_t *bspdata, bool forcedscale) CreateLightmapSurfaces(&bsp); const bool bouncerequired = - light_options.bounce.value() && (light_options.debugmode == debugmodes::none || light_options.debugmode == debugmodes::bounce || + light_options.bounce.value() && + (light_options.debugmode == debugmodes::none || light_options.debugmode == debugmodes::bounce || light_options.debugmode == debugmodes::bouncelights); // mxd MakeRadiositySurfaceLights(light_options, &bsp); @@ -564,7 +566,7 @@ static void LightWorld(bspdata_t *bspdata, bool forcedscale) logging::print("--- Direct Lighting ---\n"); // mxd logging::parallel_for(static_cast(0), bsp.dfaces.size(), [&bsp](size_t i) { if (light_surfaces[i]) { -#if defined(HAVE_EMBREE) && defined (__SSE2__) +#if defined(HAVE_EMBREE) && defined(__SSE2__) _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); #endif @@ -583,9 +585,9 @@ static void LightWorld(bspdata_t *bspdata, bool forcedscale) logging::print("--- Indirect Lighting ---\n"); // mxd logging::parallel_for(static_cast(0), bsp.dfaces.size(), [&bsp](size_t i) { if (light_surfaces[i]) { - #if defined(HAVE_EMBREE) && defined (__SSE2__) +#if defined(HAVE_EMBREE) && defined(__SSE2__) _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); - #endif +#endif IndirectLightFace(&bsp, *light_surfaces[i].get(), light_options); } @@ -637,16 +639,19 @@ static void LightWorld(bspdata_t *bspdata, bool forcedscale) if (stylesperface < j) stylesperface = j; } - + if (stylesperface >= light_options.facestyles.value()) { - logging::print("WARNING: styles per face {} exceeds compiler-set max styles {}; use `-facestyles` if you need more.\n", stylesperface, light_options.facestyles.value()); + logging::print( + "WARNING: styles per face {} exceeds compiler-set max styles {}; use `-facestyles` if you need more.\n", + stylesperface, light_options.facestyles.value()); stylesperface = light_options.facestyles.value(); } - needstyles |= (stylesperface>4); + needstyles |= (stylesperface > 4); + + logging::print("max {} styles per face, {} used{}\n", light_options.facestyles.value(), stylesperface, + maxstyle >= INVALID_LIGHTSTYLE_OLD ? ", 16bit lightstyles" : ""); - logging::print("max {} styles per face, {} used{}\n", light_options.facestyles.value(), stylesperface, maxstyle >= INVALID_LIGHTSTYLE_OLD ? ", 16bit lightstyles" : ""); - if (needstyles) { if (maxstyle >= INVALID_LIGHTSTYLE_OLD) { /*needs bigger datatype*/ @@ -669,10 +674,11 @@ static void LightWorld(bspdata_t *bspdata, bool forcedscale) for (size_t i = 0, k = 0; i < bsp.dfaces.size(); i++) { for (size_t j = 0; j < stylesperface; j++, k++) { - styles_mem[k] = faces_sup[i].styles[j] == INVALID_LIGHTSTYLE ? INVALID_LIGHTSTYLE_OLD : faces_sup[i].styles[j]; + styles_mem[k] = faces_sup[i].styles[j] == INVALID_LIGHTSTYLE ? INVALID_LIGHTSTYLE_OLD + : faces_sup[i].styles[j]; } } - + logging::print("LMSTYLE BSPX lump written\n"); bspdata->bspx.transfer("LMSTYLE", styles_mem); } @@ -687,7 +693,7 @@ static void LightWorld(bspdata_t *bspdata, bool forcedscale) for (size_t i = 0; i < bsp.dfaces.size(); i++) { offsets <= faces_sup[i].lightofs; } - + logging::print("LMOFFSET BSPX lump written\n"); bspdata->bspx.transfer("LMOFFSET", offsets_mem); } @@ -888,11 +894,11 @@ static void SetLitNeeded() if (light_options.novanilla.value()) { light_options.write_litfile = lightfile::bspx; logging::print("Colored light entities/settings detected: " - "bspxlit output enabled.\n"); + "bspxlit output enabled.\n"); } else { light_options.write_litfile = lightfile::external; logging::print("Colored light entities/settings detected: " - ".lit output enabled.\n"); + ".lit output enabled.\n"); } } } @@ -1036,7 +1042,7 @@ static void AddTextureName(const std::string_view &textureName, const mbsp_t *bs auto &tex = img::textures.emplace(textureName, img::texture{}).first->second; // find texture & meta - auto [ texture, _0, _1 ] = img::load_texture(textureName, false, bsp->loadversion->game, light_options); + auto [texture, _0, _1] = img::load_texture(textureName, false, bsp->loadversion->game, light_options); if (!texture) { logging::funcprint("WARNING: can't find pixel data for {}\n", textureName); @@ -1044,8 +1050,8 @@ static void AddTextureName(const std::string_view &textureName, const mbsp_t *bs tex = std::move(texture.value()); } - auto [ texture_meta, __0, __1 ] = img::load_texture_meta(textureName, bsp->loadversion->game, light_options); - + auto [texture_meta, __0, __1] = img::load_texture_meta(textureName, bsp->loadversion->game, light_options); + if (!texture_meta) { logging::funcprint("WARNING: can't find meta data for {}\n", textureName); } else { @@ -1053,8 +1059,8 @@ static void AddTextureName(const std::string_view &textureName, const mbsp_t *bs } tex.averageColor = img::calculate_average(tex.pixels); - tex.width_scale = (float) tex.width / (float) tex.meta.width; - tex.height_scale = (float) tex.height / (float) tex.meta.height; + tex.width_scale = (float)tex.width / (float)tex.meta.width; + tex.height_scale = (float)tex.height / (float)tex.meta.height; } // Load all of the referenced textures from the BSP texinfos into @@ -1104,7 +1110,8 @@ static void ConvertTextures(const mbsp_t *bsp) } // find replacement texture - if (auto [ texture, _0, _1 ] = img::load_texture(miptex.name, false, bsp->loadversion->game, light_options); texture) { + if (auto [texture, _0, _1] = img::load_texture(miptex.name, false, bsp->loadversion->game, light_options); + texture) { tex.width = texture->width; tex.height = texture->height; tex.pixels = std::move(texture->pixels); @@ -1116,8 +1123,8 @@ static void ConvertTextures(const mbsp_t *bsp) } tex.averageColor = img::calculate_average(tex.pixels); - tex.width_scale = (float) tex.width / (float) tex.meta.width; - tex.height_scale = (float) tex.height / (float) tex.meta.height; + tex.width_scale = (float)tex.width / (float)tex.meta.width; + tex.height_scale = (float)tex.height / (float)tex.meta.height; } } @@ -1150,7 +1157,8 @@ int light_main(int argc, const char **argv) auto start = I_FloatTime(); fs::path source = light_options.sourceMap; - logging::init(fs::path(source).replace_filename(source.stem().string() + "-light").replace_extension("log"), light_options); + logging::init( + fs::path(source).replace_filename(source.stem().string() + "-light").replace_extension("log"), light_options); // delete previous litfile if (!light_options.onlyents.value()) { diff --git a/light/litfile.cc b/light/litfile.cc index 8febdf30..38a2ebfe 100644 --- a/light/litfile.cc +++ b/light/litfile.cc @@ -54,13 +54,12 @@ void WriteLitFile(const mbsp_t *bsp, const std::vector &facesup, cons j = 0; while (nth_bit(j) < facesup[i].lmscale) j++; - litfile <= (uint8_t) j; + litfile <= (uint8_t)j; } - litfile.write((const char *) lit_filebase.data(), bsp->dlightdata.size() * 3); - litfile.write((const char *) lux_filebase.data(), bsp->dlightdata.size() * 3); - } - else - litfile.write((const char *) lit_filebase.data(), bsp->dlightdata.size() * 3); + litfile.write((const char *)lit_filebase.data(), bsp->dlightdata.size() * 3); + litfile.write((const char *)lux_filebase.data(), bsp->dlightdata.size() * 3); + } else + litfile.write((const char *)lit_filebase.data(), bsp->dlightdata.size() * 3); } #include @@ -76,5 +75,5 @@ void WriteLuxFile(const mbsp_t *bsp, const fs::path &filename, int version) std::ofstream luxfile(luxname, std::ios_base::out | std::ios_base::binary); luxfile <= header.v1; - luxfile.write((const char *) lux_filebase.data(), bsp->dlightdata.size() * 3); + luxfile.write((const char *)lux_filebase.data(), bsp->dlightdata.size() * 3); } diff --git a/light/ltface.cc b/light/ltface.cc index 4bb1d5b9..bde5bae9 100644 --- a/light/ltface.cc +++ b/light/ltface.cc @@ -49,7 +49,7 @@ void PrintFaceInfo(const mface_t *face, const mbsp_t *bsp) const char *texname = Face_TextureName(bsp, face); logging::print("face {}, texture {}, {} edges; vectors:\n" - "{: 3.3}\n", + "{: 3.3}\n", Face_GetNum(bsp, face), texname, face->numedges, tex->vecs); for (int i = 0; i < face->numedges; i++) { @@ -275,8 +275,8 @@ static void CalcPoints_Debug(const lightsurf_t *surf, const mbsp_t *bsp) } } - logging::print("wrote face {}'s sample points ({}x{}) to calcpoints.map\n", Face_GetNum(bsp, surf->face), surf->width, - surf->height); + logging::print("wrote face {}'s sample points ({}x{}) to calcpoints.map\n", Face_GetNum(bsp, surf->face), + surf->width, surf->height); PrintFaceInfo(surf->face, bsp); } @@ -454,11 +454,10 @@ static void Mod_Q1BSP_DecompressVis(const uint8_t *in, const uint8_t *inend, uin { int c; uint8_t *outstart = out; - while (out < outend) - { - if (in == inend) - { - logging::print("Mod_Q1BSP_DecompressVis: input underrun (decompressed {} of {} output bytes)\n", (out - outstart), (outend - outstart)); + while (out < outend) { + if (in == inend) { + logging::print("Mod_Q1BSP_DecompressVis: input underrun (decompressed {} of {} output bytes)\n", + (out - outstart), (outend - outstart)); return; } @@ -468,17 +467,17 @@ static void Mod_Q1BSP_DecompressVis(const uint8_t *in, const uint8_t *inend, uin continue; } - if (in == inend) - { - logging::print("Mod_Q1BSP_DecompressVis: input underrun (during zero-run) (decompressed {} of {} output bytes)\n", (out - outstart), (outend - outstart)); + if (in == inend) { + logging::print( + "Mod_Q1BSP_DecompressVis: input underrun (during zero-run) (decompressed {} of {} output bytes)\n", + (out - outstart), (outend - outstart)); return; } - for (c = *in++;c > 0;c--) - { - if (out == outend) - { - logging::print("Mod_Q1BSP_DecompressVis: output overrun (decompressed {} of {} output bytes)\n", (out - outstart), (outend - outstart)); + for (c = *in++; c > 0; c--) { + if (out == outend) { + logging::print("Mod_Q1BSP_DecompressVis: output overrun (decompressed {} of {} output bytes)\n", + (out - outstart), (outend - outstart)); return; } *out++ = 0; @@ -489,10 +488,10 @@ static void Mod_Q1BSP_DecompressVis(const uint8_t *in, const uint8_t *inend, uin static bool Mod_LeafPvs(const mbsp_t *bsp, const mleaf_t *leaf, uint8_t *out) { const size_t num_pvsclusterbytes = DecompressedVisSize(bsp); - + // init to all visible memset(out, 0xFF, num_pvsclusterbytes); - + if (bsp->loadversion->game->id == GAME_QUAKE_II) { if (leaf->cluster < 0) { return false; @@ -505,9 +504,7 @@ static bool Mod_LeafPvs(const mbsp_t *bsp, const mleaf_t *leaf, uint8_t *out) } Mod_Q1BSP_DecompressVis(bsp->dvis.bits.data() + bsp->dvis.get_bit_offset(VIS_PVS, leaf->cluster), - bsp->dvis.bits.data() + bsp->dvis.bits.size(), - out, - out + num_pvsclusterbytes); + bsp->dvis.bits.data() + bsp->dvis.bits.size(), out, out + num_pvsclusterbytes); } else { if (leaf->visofs < 0) { return false; @@ -521,16 +518,14 @@ static bool Mod_LeafPvs(const mbsp_t *bsp, const mleaf_t *leaf, uint8_t *out) if (visleaf < 0 || visleaf >= bsp->dmodels[0].visleafs) { return false; } - + if (leaf->visofs >= bsp->dvis.bits.size()) { logging::print("Mod_LeafPvs: invalid visofs for leaf {}\n", leafnum); return false; } - - Mod_Q1BSP_DecompressVis(bsp->dvis.bits.data() + leaf->visofs, - bsp->dvis.bits.data() + bsp->dvis.bits.size(), - out, - out + num_pvsclusterbytes); + + Mod_Q1BSP_DecompressVis(bsp->dvis.bits.data() + leaf->visofs, bsp->dvis.bits.data() + bsp->dvis.bits.size(), + out, out + num_pvsclusterbytes); } return true; @@ -549,8 +544,8 @@ static bool Pvs_LeafVisible(const mbsp_t *bsp, const std::vector &pvs, logging::print("Pvs_LeafVisible: invalid visofs for cluster {}\n", leaf->cluster); return false; } - - return !!(pvs[leaf->cluster>>3] & (1<<(leaf->cluster&7))); + + return !!(pvs[leaf->cluster >> 3] & (1 << (leaf->cluster & 7))); } else { const int leafnum = (leaf - bsp->dleafs.data()); const int visleaf = leafnum - 1; @@ -559,8 +554,8 @@ static bool Pvs_LeafVisible(const mbsp_t *bsp, const std::vector &pvs, logging::print("WARNING: bad/empty vis data on leaf?"); return false; } - - return !!(pvs[visleaf>>3] & (1<<(visleaf&7))); + + return !!(pvs[visleaf >> 3] & (1 << (visleaf & 7))); } } @@ -571,36 +566,36 @@ static void CalcPvs(const mbsp_t *bsp, lightsurf_t *lightsurf) // set defaults lightsurf->pvs.clear(); - + if (!bsp->dvis.bits.size()) { return; } - + // set lightsurf->pvs - uint8_t *pointpvs = (uint8_t *) alloca(pvssize); + uint8_t *pointpvs = (uint8_t *)alloca(pvssize); lightsurf->pvs.resize(pvssize); - + for (int i = 0; i < lightsurf->points.size(); i++) { - const mleaf_t *leaf = Light_PointInLeaf (bsp, lightsurf->points[i]); - - /* most/all of the surface points are probably in the same leaf */ - if (leaf == lastleaf) - continue; - - lastleaf = leaf; - - /* copy the pvs for this leaf into pointpvs */ + const mleaf_t *leaf = Light_PointInLeaf(bsp, lightsurf->points[i]); + + /* most/all of the surface points are probably in the same leaf */ + if (leaf == lastleaf) + continue; + + lastleaf = leaf; + + /* copy the pvs for this leaf into pointpvs */ Mod_LeafPvs(bsp, leaf, pointpvs); - + /* merge the pvs for this sample point into lightsurf->pvs */ - for (int j=0; jpvs[j] |= pointpvs[j]; } } } -static std::unique_ptr Lightsurf_Init( - const modelinfo_t *modelinfo, const settings::worldspawn_keys &cfg, const mface_t *face, const mbsp_t *bsp, const facesup_t *facesup) +static std::unique_ptr Lightsurf_Init(const modelinfo_t *modelinfo, const settings::worldspawn_keys &cfg, + const mface_t *face, const mbsp_t *bsp, const facesup_t *facesup) { auto spaceToWorld = TexSpaceToWorld(bsp, face); @@ -616,7 +611,7 @@ static std::unique_ptr Lightsurf_Init( lightsurf->modelinfo = modelinfo; lightsurf->bsp = bsp; lightsurf->face = face; - + /* if liquid doesn't have the TEX_SPECIAL flag set, the map was qbsp'ed with * lit water in mind. In that case receive light from both top and bottom. * (lit will only be rendered in compatible engines, but degrades gracefully.) @@ -624,7 +619,8 @@ static std::unique_ptr Lightsurf_Init( lightsurf->twosided = Face_IsTranslucent(bsp, face); // pick the larger of the two scales - lightsurf->lightmapscale = (facesup && facesup->lmscale < modelinfo->lightmapscale) ? facesup->lmscale : modelinfo->lightmapscale; + lightsurf->lightmapscale = + (facesup && facesup->lmscale < modelinfo->lightmapscale) ? facesup->lmscale : modelinfo->lightmapscale; const surfflags_t &extended_flags = extended_texinfo_flags[face->texinfo]; lightsurf->curved = extended_flags.phong_angle != 0 || Q2_FacePhongValue(bsp, face); @@ -1128,7 +1124,8 @@ inline bool CullLight(const light_t *entity, const lightsurf_t *lightsurf) { const settings::worldspawn_keys &cfg = *lightsurf->cfg; - if (light_options.visapprox.value() == visapprox_t::RAYS && entity->bounds.disjoint(lightsurf->extents.bounds, 0.001)) { + if (light_options.visapprox.value() == visapprox_t::RAYS && + entity->bounds.disjoint(lightsurf->extents.bounds, 0.001)) { return true; } @@ -1154,16 +1151,15 @@ static bool VisCullEntity(const mbsp_t *bsp, const std::vector &pvs, co if (entleaf == nullptr) { return false; } - - if (bsp->loadversion->game->contents_are_solid({ entleaf->contents }) || - bsp->loadversion->game->contents_are_sky({ entleaf->contents })) { + + if (bsp->loadversion->game->contents_are_solid({entleaf->contents}) || + bsp->loadversion->game->contents_are_sky({entleaf->contents})) { return false; } return !Pvs_LeafVisible(bsp, pvs, entleaf); } - /* * ================ * LightFace_Entity @@ -1481,8 +1477,8 @@ static void LightFace_Min(const mbsp_t *bsp, const mface_t *face, const qvec3d & vec_t value = entity->light.value(); lightsample_t &sample = lightmap->samples[i]; - value *= - Dirt_GetScaleFactor(cfg, lightsurf->occlusion[i], entity.get(), 0.0 /* TODO: pass distance */, lightsurf); + value *= Dirt_GetScaleFactor( + cfg, lightsurf->occlusion[i], entity.get(), 0.0 /* TODO: pass distance */, lightsurf); if (cfg.addminlight.value()) { sample.color += entity->color.value() * (value / 255.0); } else { @@ -1577,8 +1573,7 @@ static void LightFace_BounceLightsDebug(const lightsurf_t *lightsurf, lightmapdi } // returns color in [0,255] -inline qvec3f BounceLight_ColorAtDist( - const settings::worldspawn_keys &cfg, float area, const qvec3f &color, float dist) +inline qvec3f BounceLight_ColorAtDist(const settings::worldspawn_keys &cfg, float area, const qvec3f &color, float dist) { const float d = max(dist, 128.f); // Clamp away hotspots, also avoid division by 0.. const float scale = (1.0f / (d * d)); @@ -1643,7 +1638,7 @@ inline qvec3f GetSurfaceLighting(const settings::worldspawn_keys &cfg, const sur return {0}; // sample point behind vpl if (dp2 < 0.0f) return {0}; // vpl behind sample face - + // Rescale a bit to brighten the faces nearly-perpendicular to the surface light plane... dp1 = 0.5f + dp1 * 0.5f; dp2 = 0.5f + dp2 * 0.5f; @@ -1668,7 +1663,8 @@ inline bool BounceLight_SphereCull(const mbsp_t *bsp, const bouncelight_t *vpl, { const settings::worldspawn_keys &cfg = *lightsurf->cfg; - if (light_options.visapprox.value() == visapprox_t::RAYS && vpl->bounds.disjoint(lightsurf->extents.bounds, 0.001)) { + if (light_options.visapprox.value() == visapprox_t::RAYS && + vpl->bounds.disjoint(lightsurf->extents.bounds, 0.001)) { return true; } @@ -1684,7 +1680,8 @@ inline bool BounceLight_SphereCull(const mbsp_t *bsp, const bouncelight_t *vpl, static bool // mxd SurfaceLight_SphereCull(const surfacelight_t *vpl, const lightsurf_t *lightsurf) { - if (light_options.visapprox.value() == visapprox_t::RAYS && vpl->bounds.disjoint(lightsurf->extents.bounds, 0.001)) { + if (light_options.visapprox.value() == visapprox_t::RAYS && + vpl->bounds.disjoint(lightsurf->extents.bounds, 0.001)) { return true; } @@ -1725,8 +1722,7 @@ inline qvec3d CosineWeightedHemisphereSample(float u1, float u2) } #endif -static void LightFace_Bounce( - const mbsp_t *bsp, const mface_t *face, lightsurf_t *lightsurf, lightmapdict_t *lightmaps) +static void LightFace_Bounce(const mbsp_t *bsp, const mface_t *face, lightsurf_t *lightsurf, lightmapdict_t *lightmaps) { const settings::worldspawn_keys &cfg = *lightsurf->cfg; // const dmodelh2_t *shadowself = lightsurf->modelinfo->shadowself.boolValue() ? lightsurf->modelinfo->model : NULL; @@ -1826,7 +1822,8 @@ LightFace_SurfaceLight(const mbsp_t *bsp, lightsurf_t *lightsurf, lightmapdict_t raystream_occlusion_t &rs = lightsurf->occlusion_stream; for (int c = 0; c < vpl.points.size(); c++) { - if (light_options.visapprox.value() == visapprox_t::VIS && VisCullEntity(bsp, lightsurf->pvs, vpl.leaves[c])) { + if (light_options.visapprox.value() == visapprox_t::VIS && + VisCullEntity(bsp, lightsurf->pvs, vpl.leaves[c])) { continue; } @@ -2128,7 +2125,7 @@ static void LightFace_CalculateDirt(lightsurf_t *lightsurf) // batch implementation: thread_local static std::vector myUps, myRts; - + myUps.resize(lightsurf->points.size()); myRts.resize(lightsurf->points.size()); @@ -2209,8 +2206,7 @@ inline void LightFace_ScaleAndClamp(lightsurf_t *lightsurf) } } -void FinishLightmapSurface( - const mbsp_t *bsp, lightsurf_t *lightsurf) +void FinishLightmapSurface(const mbsp_t *bsp, lightsurf_t *lightsurf) { /* Apply gamma, rangescale, and clamp */ LightFace_ScaleAndClamp(lightsurf); @@ -2606,7 +2602,8 @@ bool Face_IsLightmapped(const mbsp_t *bsp, const mface_t *face) * - Writes (actual_width * actual_height * 3) bytes to `lux` */ static void WriteSingleLightmap(const mbsp_t *bsp, const mface_t *face, const lightsurf_t *lightsurf, - const lightmap_t *lm, const int actual_width, const int actual_height, uint8_t *out, uint8_t *lit, uint8_t *lux, const faceextents_t &output_extents) + const lightmap_t *lm, const int actual_width, const int actual_height, uint8_t *out, uint8_t *lit, uint8_t *lux, + const faceextents_t &output_extents) { const int oversampled_width = actual_width * light_options.extra.value(); const int oversampled_height = actual_height * light_options.extra.value(); @@ -2632,8 +2629,8 @@ static void WriteSingleLightmap(const mbsp_t *bsp, const mface_t *face, const li std::optional> output_dir; if (lux) { - output_dir = IntegerDownsampleImage( - LightmapNormalsToGLMVector(lightsurf, lm), oversampled_width, oversampled_height, light_options.extra.value()); + output_dir = IntegerDownsampleImage(LightmapNormalsToGLMVector(lightsurf, lm), oversampled_width, + oversampled_height, light_options.extra.value()); } // copy from the float buffers to byte buffers in .bsp / .lit / .lux @@ -2642,8 +2639,8 @@ static void WriteSingleLightmap(const mbsp_t *bsp, const mface_t *face, const li for (int t = 0; t < output_height; t++) { for (int s = 0; s < output_width; s++) { - const int input_sample_s = (s / (float) output_width) * actual_width; - const int input_sample_t = (t / (float) output_height) * actual_height; + const int input_sample_s = (s / (float)output_width) * actual_width; + const int input_sample_t = (t / (float)output_height) * actual_height; const int sampleindex = (input_sample_t * actual_width) + input_sample_s; if (lit || out) { @@ -2693,8 +2690,8 @@ static void WriteSingleLightmap(const mbsp_t *bsp, const mface_t *face, const li } } -void SaveLightmapSurface( - const mbsp_t *bsp, mface_t *face, facesup_t *facesup, const lightsurf_t *lightsurf, const faceextents_t &extents, const faceextents_t &output_extents) +void SaveLightmapSurface(const mbsp_t *bsp, mface_t *face, facesup_t *facesup, const lightsurf_t *lightsurf, + const faceextents_t &extents, const faceextents_t &output_extents) { const lightmapdict_t &lightmaps = lightsurf->lightmapsByStyle; const int actual_width = extents.width(); @@ -2726,7 +2723,8 @@ void SaveLightmapSurface( // see if we have computed lighting for this style for (const lightmap_t &lm : lightmaps) { if (lm.style == style) { - WriteSingleLightmap(bsp, face, lightsurf, &lm, actual_width, actual_height, out, lit, lux, output_extents); + WriteSingleLightmap( + bsp, face, lightsurf, &lm, actual_width, actual_height, out, lit, lux, output_extents); break; } } @@ -2759,17 +2757,18 @@ void SaveLightmapSurface( if (lightmap.style > maxstyle || (facesup && lightmap.style > INVALID_LIGHTSTYLE_OLD)) { if (!warned_about_light_style_overflow) { if (IsOutputtingSupplementaryData()) { - logging::print("INFO: a face has exceeded max light style id ({});\n LMSTYLE16 will be output to hold the non-truncated data.\n Use -verbose to find which faces.\n", + logging::print( + "INFO: a face has exceeded max light style id ({});\n LMSTYLE16 will be output to hold the non-truncated data.\n Use -verbose to find which faces.\n", maxstyle, lightsurf->points[0]); } else { - logging::print("WARNING: a face has exceeded max light style id ({}). Use -verbose to find which faces.\n", + logging::print( + "WARNING: a face has exceeded max light style id ({}). Use -verbose to find which faces.\n", maxstyle, lightsurf->points[0]); } warned_about_light_style_overflow = true; } - logging::print(logging::flag::VERBOSE, "WARNING: Style {} too high on face near {}\n", - lightmap.style, - lightsurf->points[0]); + logging::print(logging::flag::VERBOSE, "WARNING: Style {} too high on face near {}\n", lightmap.style, + lightsurf->points[0]); continue; } @@ -2794,16 +2793,19 @@ void SaveLightmapSurface( if (sorted.size() == maxfstyles) { if (!warned_about_light_map_overflow) { if (IsOutputtingSupplementaryData()) { - logging::print("INFO: a face has exceeded max light styles ({});\n LMSTYLE/LMSTYLE16 will be output to hold the non-truncated data.\n Use -verbose to find which faces.\n", + logging::print( + "INFO: a face has exceeded max light styles ({});\n LMSTYLE/LMSTYLE16 will be output to hold the non-truncated data.\n Use -verbose to find which faces.\n", maxfstyles, lightsurf->points[0]); } else { - logging::print("WARNING: a face has exceeded max light styles ({}). Use -verbose to find which faces.\n", + logging::print( + "WARNING: a face has exceeded max light styles ({}). Use -verbose to find which faces.\n", maxfstyles, lightsurf->points[0]); } warned_about_light_map_overflow = true; } - logging::print(logging::flag::VERBOSE, "WARNING: {} light styles (max {}) on face near {}; styles: ", - sortable.size(), maxfstyles, lightsurf->points[0]); + logging::print(logging::flag::VERBOSE, + "WARNING: {} light styles (max {}) on face near {}; styles: ", sortable.size(), maxfstyles, + lightsurf->points[0]); for (auto &p : sortable) { logging::print(logging::flag::VERBOSE, "{} ", p.second->style); } @@ -2886,7 +2888,8 @@ void SaveLightmapSurface( } } -std::unique_ptr CreateLightmapSurface(const mbsp_t *bsp, const mface_t *face, const facesup_t *facesup, const settings::worldspawn_keys &cfg) +std::unique_ptr CreateLightmapSurface( + const mbsp_t *bsp, const mface_t *face, const facesup_t *facesup, const settings::worldspawn_keys &cfg) { /* Find the correct model offset */ const modelinfo_t *modelinfo = ModelInfoForFace(bsp, Face_GetNum(bsp, face)); @@ -2980,8 +2983,7 @@ void DirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings:: } if (minlight) { - LightFace_Min(bsp, face, minlight_color, minlight, &lightsurf, - lightmaps); + LightFace_Min(bsp, face, minlight_color, minlight, &lightsurf, lightmaps); } /* negative lights */ @@ -3017,7 +3019,6 @@ void DirectLightFace(const mbsp_t *bsp, lightsurf_t &lightsurf, const settings:: LightFace_DebugNeighbours(&lightsurf, lightmaps); } - /* * ============ * LightFace diff --git a/light/main.cc b/light/main.cc index f7563c50..54f8b4c0 100644 --- a/light/main.cc +++ b/light/main.cc @@ -24,7 +24,7 @@ int main(int argc, const char **argv) { try { return light_main(argc, argv); - } catch (const settings::quit_after_help_exception&) { + } catch (const settings::quit_after_help_exception &) { return 0; } } diff --git a/light/phong.cc b/light/phong.cc index 5fced354..96831716 100644 --- a/light/phong.cc +++ b/light/phong.cc @@ -366,9 +366,7 @@ static edgeToFaceMap_t MakeEdgeToFaceMap(const mbsp_t *bsp) static vector Face_VertexNormals(const mbsp_t *bsp, const mface_t *face) { vector normals(face->numedges); - tbb::parallel_for(0, face->numedges, [&](size_t i) { - normals[i] = GetSurfaceVertexNormal(bsp, face, i); - }); + tbb::parallel_for(0, face->numedges, [&](size_t i) { normals[i] = GetSurfaceVertexNormal(bsp, face, i); }); return normals; } diff --git a/light/surflight.cc b/light/surflight.cc index f95847ec..5715e9a2 100644 --- a/light/surflight.cc +++ b/light/surflight.cc @@ -51,7 +51,8 @@ std::vector &GetSurfaceLights() return surfacelights; } -static void MakeSurfaceLight(const mbsp_t *bsp, const settings::worldspawn_keys &cfg, const mface_t *face, std::optional texture_color, bool is_directional, bool is_sky, int32_t style, int32_t light_value) +static void MakeSurfaceLight(const mbsp_t *bsp, const settings::worldspawn_keys &cfg, const mface_t *face, + std::optional texture_color, bool is_directional, bool is_sky, int32_t style, int32_t light_value) { // Create face points... auto poly = GLM_FacePoints(bsp, face); @@ -71,7 +72,8 @@ static void MakeSurfaceLight(const mbsp_t *bsp, const settings::worldspawn_keys // Dice winding... vector points; - winding.dice(cfg.surflightsubdivision.value(), [&points, &facenormal](winding_t &w) { points.push_back(w.center() + facenormal); }); + winding.dice(cfg.surflightsubdivision.value(), + [&points, &facenormal](winding_t &w) { points.push_back(w.center() + facenormal); }); total_surflight_points += points.size(); // Calculate emit color and intensity... @@ -169,15 +171,16 @@ static void MakeSurfaceLightsThread(const mbsp_t *bsp, const settings::worldspaw // first, check if it's a Q2 surface const mtexinfo_t *info = Face_Texinfo(bsp, face); - if (info != nullptr) - { + if (info != nullptr) { if (!(info->flags.native & Q2_SURF_LIGHT) || info->value == 0) { if (info->flags.native & Q2_SURF_LIGHT) { qvec3d wc = winding_t::from_face(bsp, face).center(); - logging::print("WARNING: surface light '{}' at [{}] has 0 intensity.\n", Face_TextureName(bsp, face), wc); + logging::print( + "WARNING: surface light '{}' at [{}] has 0 intensity.\n", Face_TextureName(bsp, face), wc); } } else { - MakeSurfaceLight(bsp, cfg, face, std::nullopt, !(info->flags.native & Q2_SURF_SKY), (info->flags.native & Q2_SURF_SKY), 0, info->value); + MakeSurfaceLight(bsp, cfg, face, std::nullopt, !(info->flags.native & Q2_SURF_SKY), + (info->flags.native & Q2_SURF_SKY), 0, info->value); } } } @@ -191,8 +194,11 @@ static void MakeSurfaceLightsThread(const mbsp_t *bsp, const settings::worldspaw texture_color = surflight->color.value(); } - MakeSurfaceLight(bsp, cfg, face, texture_color, !surflight->epairs->has("_surface_spotlight") ? true : !!surflight->epairs->get_int("_surface_spotlight"), - surflight->epairs->get_int("_surface_is_sky"), surflight->epairs->get_int("style"), surflight->light.value()); + MakeSurfaceLight(bsp, cfg, face, texture_color, + !surflight->epairs->has("_surface_spotlight") ? true + : !!surflight->epairs->get_int("_surface_spotlight"), + surflight->epairs->get_int("_surface_is_sky"), surflight->epairs->get_int("style"), + surflight->light.value()); } } } @@ -213,10 +219,10 @@ MakeRadiositySurfaceLights(const settings::worldspawn_keys &cfg, const mbsp_t *b { logging::print("--- MakeRadiositySurfaceLights ---\n"); - logging::parallel_for(static_cast(0), bsp->dfaces.size(), [&](size_t i) { MakeSurfaceLightsThread(bsp, cfg, i); }); + logging::parallel_for( + static_cast(0), bsp->dfaces.size(), [&](size_t i) { MakeSurfaceLightsThread(bsp, cfg, i); }); if (surfacelights.size()) { - logging::print("{} surface lights ({} light points) in use.\n", - surfacelights.size(), total_surflight_points); + logging::print("{} surface lights ({} light points) in use.\n", surfacelights.size(), total_surflight_points); } } diff --git a/light/trace.cc b/light/trace.cc index 0b44f281..a64aa624 100644 --- a/light/trace.cc +++ b/light/trace.cc @@ -29,17 +29,17 @@ /* ============== Light_PointInLeaf - + from hmap2 ============== */ -const mleaf_t *Light_PointInLeaf( const mbsp_t *bsp, const qvec3d &point ) +const mleaf_t *Light_PointInLeaf(const mbsp_t *bsp, const qvec3d &point) { int num = 0; - - while( num >= 0 ) + + while (num >= 0) num = bsp->dnodes[num].children[bsp->dplanes[bsp->dnodes[num].planenum].distance_to_fast(point) < 0]; - + return &bsp->dleafs[-1 - num]; } @@ -50,7 +50,7 @@ Light_PointContents from hmap2 ============== */ -int Light_PointContents( const mbsp_t *bsp, const qvec3d &point ) +int Light_PointContents(const mbsp_t *bsp, const qvec3d &point) { return Light_PointInLeaf(bsp, point)->contents; } @@ -76,7 +76,8 @@ uint32_t clamp_texcoord(vec_t in, uint32_t width) } } -qvec4b SampleTexture(const mface_t *face, const mtexinfo_t *tex, const img::texture *texture, const mbsp_t *bsp, const qvec3d &point) +qvec4b SampleTexture( + const mface_t *face, const mtexinfo_t *tex, const img::texture *texture, const mbsp_t *bsp, const qvec3d &point) { if (texture == nullptr || !texture->width) { return {}; diff --git a/light/trace_embree.cc b/light/trace_embree.cc index 02556f99..f13394ba 100644 --- a/light/trace_embree.cc +++ b/light/trace_embree.cc @@ -134,8 +134,9 @@ sceneinfo CreateGeometry( // mxd if (bsp->loadversion->game->id == GAME_QUAKE_II) { const int surf_flags = Face_ContentsOrSurfaceFlags(bsp, face); - info.is_fence = ((surf_flags & Q2_SURF_TRANSLUCENT) == - Q2_SURF_TRANSLUCENT); // KMQuake 2-specific. Use texture alpha chanel when both flags are set. + info.is_fence = + ((surf_flags & Q2_SURF_TRANSLUCENT) == + Q2_SURF_TRANSLUCENT); // KMQuake 2-specific. Use texture alpha chanel when both flags are set. info.is_glass = !info.is_fence && (surf_flags & Q2_SURF_TRANSLUCENT); if (info.is_glass) { info.alpha = (surf_flags & Q2_SURF_TRANS33 ? 0.33f : 0.66f); @@ -330,7 +331,8 @@ static void Embree_FilterFuncN(const struct RTCFilterFunctionNArguments *args) qvec3f rayDir = qv::normalize(qvec3f{RTCRayN_dir_x(ray, N, i), RTCRayN_dir_y(ray, N, i), RTCRayN_dir_z(ray, N, i)}); qvec3f hitpoint = Embree_RayEndpoint(ray, rayDir, N, i); - const qvec4b sample = SampleTexture(hit_triinfo.face, hit_triinfo.texinfo, hit_triinfo.texture, bsp_static, hitpoint); // mxd. Palette index -> color_rgba + const qvec4b sample = SampleTexture(hit_triinfo.face, hit_triinfo.texinfo, hit_triinfo.texture, bsp_static, + hitpoint); // mxd. Palette index -> color_rgba if (hit_triinfo.is_glass) { // hit glass... diff --git a/qbsp/brush.cc b/qbsp/brush.cc index fab01fa8..fbe33730 100644 --- a/qbsp/brush.cc +++ b/qbsp/brush.cc @@ -28,7 +28,7 @@ #include #include -const maptexinfo_t& side_t::get_texinfo() const +const maptexinfo_t &side_t::get_texinfo() const { return map.mtexinfos[this->texinfo]; } @@ -95,7 +95,8 @@ static void CheckFace(side_t *face, const mapface_t &sourceface) if (face->w.size() < 3) { if (face->w.size() == 2) { - logging::print("WARNING: line {}: too few points (2): ({}) ({})\n", sourceface.linenum, face->w[0], face->w[1]); + logging::print( + "WARNING: line {}: too few points (2): ({}) ({})\n", sourceface.linenum, face->w[0], face->w[1]); } else if (face->w.size() == 1) { logging::print("WARNING: line {}: too few points (1): ({})\n", sourceface.linenum, face->w[0]); } else { @@ -128,16 +129,16 @@ static void CheckFace(side_t *face, const mapface_t &sourceface) // is this a bug? should `Face_Plane` be used instead? vec_t dist = plane.distance_to(p1); if (dist < -qbsp_options.epsilon.value() || dist > qbsp_options.epsilon.value()) { - logging::print("WARNING: Line {}: Point ({:.3} {:.3} {:.3}) off plane by {:2.4}\n", sourceface.linenum, p1[0], - p1[1], p1[2], dist); + logging::print("WARNING: Line {}: Point ({:.3} {:.3} {:.3}) off plane by {:2.4}\n", sourceface.linenum, + p1[0], p1[1], p1[2], dist); } /* check the edge isn't degenerate */ qvec3d edgevec = p2 - p1; vec_t length = qv::length(edgevec); if (length < qbsp_options.epsilon.value()) { - logging::print("WARNING: Line {}: Healing degenerate edge ({}) at ({:.3f} {:.3} {:.3})\n", sourceface.linenum, - length, p1[0], p1[1], p1[2]); + logging::print("WARNING: Line {}: Healing degenerate edge ({}) at ({:.3f} {:.3} {:.3})\n", + sourceface.linenum, length, p1[0], p1[1], p1[2]); for (size_t j = i + 1; j < face->w.size(); j++) face->w[j - 1] = face->w[j]; face->w.resize(face->w.size() - 1); @@ -155,8 +156,8 @@ static void CheckFace(side_t *face, const mapface_t &sourceface) continue; dist = qv::dot(face->w[j], edgenormal); if (dist > edgedist) { - logging::print("WARNING: line {}: Found a non-convex face (error size {}, point: {})\n", sourceface.linenum, - dist - edgedist, face->w[j]); + logging::print("WARNING: line {}: Found a non-convex face (error size {}, point: {})\n", + sourceface.linenum, dist - edgedist, face->w[j]); face->w.clear(); return; } @@ -610,8 +611,9 @@ static contentflags_t Brush_GetContents(const mapbrush_t *mapbrush) } if (!contents.types_equal(base_contents, qbsp_options.target_game)) { - logging::print("mixed face contents ({} != {}) at line {}\n", base_contents.to_string(qbsp_options.target_game), - contents.to_string(qbsp_options.target_game), mapface.linenum); + logging::print("mixed face contents ({} != {}) at line {}\n", + base_contents.to_string(qbsp_options.target_game), contents.to_string(qbsp_options.target_game), + mapface.linenum); break; } } diff --git a/qbsp/brushbsp.cc b/qbsp/brushbsp.cc index d2874b93..33c3a158 100644 --- a/qbsp/brushbsp.cc +++ b/qbsp/brushbsp.cc @@ -39,15 +39,16 @@ // if a brush just barely pokes onto the other side, // let it slide by without chopping constexpr double PLANESIDE_EPSILON = 0.001; -//0.1 +// 0.1 constexpr int PSIDE_FRONT = 1; constexpr int PSIDE_BACK = 2; -constexpr int PSIDE_BOTH = (PSIDE_FRONT|PSIDE_BACK); +constexpr int PSIDE_BOTH = (PSIDE_FRONT | PSIDE_BACK); // this gets OR'ed in in the return value of QuickTestBrushToPlanenum if one of the brush sides is on the input plane constexpr int PSIDE_FACING = 4; -struct bspstats_t { +struct bspstats_t +{ std::unique_ptr leafstats; // total number of nodes, includes c_nonvis std::atomic c_nodes; @@ -102,8 +103,7 @@ std::unique_ptr BrushFromBounds(const aabb3d &bounds) auto b = std::make_unique(); b->sides.resize(6); - for (int i = 0; i < 3; i++) - { + for (int i = 0; i < 3; i++) { { qplane3d plane{}; plane.normal[i] = 1; @@ -176,7 +176,7 @@ BoxOnPlaneSide Returns PSIDE_FRONT, PSIDE_BACK, or PSIDE_BOTH ============== */ -static int BoxOnPlaneSide(const aabb3d& bounds, const qbsp_plane_t &plane) +static int BoxOnPlaneSide(const aabb3d &bounds, const qbsp_plane_t &plane) { // axial planes are easy if (plane.get_type() < plane_type_t::PLANE_ANYX) { @@ -211,7 +211,7 @@ static int BoxOnPlaneSide(const aabb3d& bounds, const qbsp_plane_t &plane) return side; } -static int SphereOnPlaneSide(const qvec3d& sphere_origin, double sphere_radius, const qplane3d &plane) +static int SphereOnPlaneSide(const qvec3d &sphere_origin, double sphere_radius, const qplane3d &plane) { const double sphere_dist = plane.dist_above(sphere_origin); if (sphere_dist > sphere_radius) { @@ -267,7 +267,8 @@ TestBrushToPlanenum ============ */ -static int TestBrushToPlanenum(const bspbrush_t &brush, const qbsp_plane_t &plane, int *numsplits, bool *hintsplit, int *epsilonbrush) +static int TestBrushToPlanenum( + const bspbrush_t &brush, const qbsp_plane_t &plane, int *numsplits, bool *hintsplit, int *epsilonbrush) { *numsplits = 0; *hintsplit = false; @@ -285,7 +286,7 @@ static int TestBrushToPlanenum(const bspbrush_t &brush, const qbsp_plane_t &plan } // box on plane side - //int s = SphereOnPlaneSide(brush.sphere_origin, brush.sphere_radius, plane); + // int s = SphereOnPlaneSide(brush.sphere_origin, brush.sphere_radius, plane); int s = BoxOnPlaneSide(brush.bounds, plane); if (s != PSIDE_BOTH) return s; @@ -294,19 +295,17 @@ static int TestBrushToPlanenum(const bspbrush_t &brush, const qbsp_plane_t &plan vec_t d_front = 0; vec_t d_back = 0; - for (const side_t &side : brush.sides) - { + for (const side_t &side : brush.sides) { if (side.onnode) - continue; // on node, don't worry about splits + continue; // on node, don't worry about splits if (!side.visible) - continue; // we don't care about non-visible + continue; // we don't care about non-visible auto &w = side.w; if (!w) continue; int front = 0; int back = 0; - for (auto &point : w) - { + for (auto &point : w) { const double d = qv::dot(point, plane.get_normal()) - plane.get_dist(); if (d > d_front) d_front = d; @@ -328,8 +327,7 @@ static int TestBrushToPlanenum(const bspbrush_t &brush, const qbsp_plane_t &plan } } - if ( (d_front > 0.0 && d_front < 1.0) - || (d_back < 0.0 && d_back > -1.0) ) + if ((d_front > 0.0 && d_front < 1.0) || (d_back < 0.0 && d_back > -1.0)) (*epsilonbrush)++; return s; @@ -371,7 +369,7 @@ from basewinding for plane bool WindingIsHuge(const winding_t &w) { for (size_t i = 0; i < w.size(); i++) { - for (size_t j = 0; j < 3; j++) { + for (size_t j = 0; j < 3; j++) { if (fabs(w[i][j]) > qbsp_options.worldextent.value()) return true; } @@ -409,7 +407,6 @@ static void LeafNode(node_t *leafnode, std::vector> //============================================================ - /* ================== BrushMostlyOnSide @@ -449,7 +446,7 @@ https://github.com/id-Software/Quake-2-Tools/blob/master/bsp/qbsp3/brushbsp.c#L9 static twosided> SplitBrush(std::unique_ptr brush, const qplane3d &split) { twosided> result; - + // check all points vec_t d_front = 0; vec_t d_back = 0; @@ -529,7 +526,7 @@ static twosided> SplitBrush(std::unique_ptrtested = false;`, why? @@ -574,9 +571,9 @@ static twosided> SplitBrush(std::unique_ptr>& brushes, node_t *node) +side_t *SelectSplitSide(const std::vector> &brushes, node_t *node) { - side_t* bestside = nullptr; + side_t *bestside = nullptr; int bestvalue = -99999; int bestsplits = 0; @@ -645,32 +642,32 @@ side_t *SelectSplitSide(const std::vector>& brushes, // If any valid plane is available in a pass, no further // passes will be tried. constexpr int numpasses = 4; - for (int pass = 0 ; pass < numpasses ; pass++) { + for (int pass = 0; pass < numpasses; pass++) { for (auto &brush : brushes) { - if ( (pass & 1) && !brush->original->contents.is_any_detail(qbsp_options.target_game) ) + if ((pass & 1) && !brush->original->contents.is_any_detail(qbsp_options.target_game)) continue; - if ( !(pass & 1) && brush->original->contents.is_any_detail(qbsp_options.target_game) ) + if (!(pass & 1) && brush->original->contents.is_any_detail(qbsp_options.target_game)) continue; for (auto &side : brush->sides) { if (side.bevel) - continue; // never use a bevel as a spliter + continue; // never use a bevel as a spliter if (!side.w) - continue; // nothing visible, so it can't split + continue; // nothing visible, so it can't split if (side.onnode) - continue; // allready a node splitter + continue; // allready a node splitter if (side.tested) - continue; // we allready have metrics for this plane + continue; // we allready have metrics for this plane if (side.get_texinfo().flags.is_hintskip) - continue; // skip surfaces are never chosen - if ( side.visible ^ (pass<2) ) - continue; // only check visible faces on first pass + continue; // skip surfaces are never chosen + if (side.visible ^ (pass < 2)) + continue; // only check visible faces on first pass qbsp_plane_t plane(side.plane, true); // always use positive facing plane - CheckPlaneAgainstParents (plane, node); + CheckPlaneAgainstParents(plane, node); - if (!CheckPlaneAgainstVolume (plane, node)) - continue; // would produce a tiny volume + if (!CheckPlaneAgainstVolume(plane, node)) + continue; // would produce a tiny volume int front = 0; int back = 0; @@ -680,20 +677,18 @@ side_t *SelectSplitSide(const std::vector>& brushes, int epsilonbrush = 0; bool hintsplit = false; - for (auto &test : brushes) - { + for (auto &test : brushes) { int bsplits; int s = TestBrushToPlanenum(*test, plane, &bsplits, &hintsplit, &epsilonbrush); splits += bsplits; - if (bsplits && (s&PSIDE_FACING) ) - Error ("PSIDE_FACING with splits"); + if (bsplits && (s & PSIDE_FACING)) + Error("PSIDE_FACING with splits"); test->testside = s; // if the brush shares this face, don't bother // testing that facenum as a splitter again - if (s & PSIDE_FACING) - { + if (s & PSIDE_FACING) { facing++; for (auto &testside : test->sides) { if (qv::epsilonEqual(testside.plane, plane)) { @@ -711,15 +706,15 @@ side_t *SelectSplitSide(const std::vector>& brushes, // give a value estimate for using this plane - int value = 5*facing - 5*splits - abs(front-back); + int value = 5 * facing - 5 * splits - abs(front - back); // value = -5*splits; // value = 5*facing - 5*splits; if (plane.get_type() < plane_type_t::PLANE_ANYX) - value+=5; // axial is better - value -= epsilonbrush*1000; // avoid! + value += 5; // axial is better + value -= epsilonbrush * 1000; // avoid! // never split a hint side except with another hint - if (hintsplit && !(side.get_texinfo().flags.is_hint) ) + if (hintsplit && !(side.get_texinfo().flags.is_hint)) value = -9999999; // save off the side test so we don't need @@ -740,7 +735,7 @@ side_t *SelectSplitSide(const std::vector>& brushes, // other passes if (bestside) { if (pass > 0) - node->detail_separator = true; // not needed for vis + node->detail_separator = true; // not needed for vis break; } } @@ -762,11 +757,12 @@ side_t *SelectSplitSide(const std::vector>& brushes, SplitBrushList ================ */ -static std::array>, 2> SplitBrushList(std::vector> brushes, const node_t *node) +static std::array>, 2> SplitBrushList( + std::vector> brushes, const node_t *node) { std::array>, 2> result; - for (auto& brush : brushes) { + for (auto &brush : brushes) { int sides = brush->side; if (sides == PSIDE_BOTH) { @@ -814,7 +810,7 @@ BuildTree_r Called in parallel. ================== */ -static void BuildTree_r(node_t *node, std::vector> brushes, bspstats_t& stats) +static void BuildTree_r(node_t *node, std::vector> brushes, bspstats_t &stats) { // find the best plane to use as a splitter auto *bestside = const_cast(SelectSplitSide(brushes, node)); @@ -836,13 +832,12 @@ static void BuildTree_r(node_t *node, std::vector> b } node->side = bestside; - node->plane.set_plane(bestside->plane, true); // always use front facing + node->plane.set_plane(bestside->plane, true); // always use front facing auto children = SplitBrushList(std::move(brushes), node); // allocate children before recursing - for (int i = 0; i < 2; i++) - { + for (int i = 0; i < 2; i++) { auto &newnode = node->children[i] = std::make_unique(); newnode->parent = node; } @@ -872,21 +867,18 @@ static std::unique_ptr BrushBSP(mapentity_t *entity, std::vectororiginal->entitynum, b->original->brushnum); + // printf ("WARNING: entity %i, brush %i: microbrush\n", + // b->original->entitynum, b->original->brushnum); } - for (side_t &side : b->sides) - { + for (side_t &side : b->sides) { if (side.bevel) continue; if (!side.w) @@ -911,7 +903,7 @@ static std::unique_ptr BrushBSP(mapentity_t *entity, std::vector(); headnode->bounds = entity->bounds; - headnode->plane = { { 0, 0, 1 }, 0 }; + headnode->plane = {{0, 0, 1}, 0}; headnode->children[0] = std::make_unique(); headnode->children[0]->is_leaf = true; headnode->children[0]->contents = qbsp_options.target_game->create_empty_contents(); diff --git a/qbsp/csg.cc b/qbsp/csg.cc index 484e7f7a..22685e9f 100644 --- a/qbsp/csg.cc +++ b/qbsp/csg.cc @@ -63,7 +63,7 @@ std::unique_ptr NewFaceFromFace(const face_t *in) return newf; } -std::unique_ptr CopyFace(const face_t* in) +std::unique_ptr CopyFace(const face_t *in) { auto temp = NewFaceFromFace(in); temp->w = in->w; @@ -87,7 +87,8 @@ SplitFace Frees in. Returns {front, back} ================== */ -std::tuple, std::unique_ptr> SplitFace(std::unique_ptr in, const qplane3d &split) +std::tuple, std::unique_ptr> SplitFace( + std::unique_ptr in, const qplane3d &split) { if (in->w.size() < 0) Error("Attempting to split freed face"); diff --git a/qbsp/exportobj.cc b/qbsp/exportobj.cc index 21951aeb..ea501126 100644 --- a/qbsp/exportobj.cc +++ b/qbsp/exportobj.cc @@ -70,7 +70,7 @@ static void ExportObjFace(std::ofstream &f, const face_t *face, int *vertcount) // not sure why -v is needed, .obj uses (0, 0) in the top left apparently? fmt::print(f, "vt {:.9} {:.9}\n", uv[0], -uv[1]); } - + // fixme-brushbsp fmt::print(f, "usemtl contents{}\n", face->contents.native); f << 'f'; @@ -110,10 +110,10 @@ void ExportObj_Faces(const std::string &filesuffix, const std::vector &brushes) -{ -} +void ExportObj_Brushes(const std::string &filesuffix, const std::vector &brushes) { } static void ExportObj_Nodes_r(const node_t *node, std::vector *dest) { diff --git a/qbsp/faces.cc b/qbsp/faces.cc index ddd11b49..86be2fe1 100644 --- a/qbsp/faces.cc +++ b/qbsp/faces.cc @@ -31,8 +31,9 @@ #include #include -struct makefaces_stats_t { - int c_nodefaces; +struct makefaces_stats_t +{ + int c_nodefaces; int c_merge; int c_subdivide; }; @@ -242,7 +243,7 @@ static void GrowNodeRegion(node_t *node) node->firstface = static_cast(map.bsp.dfaces.size()); for (auto &face : node->facelist) { - //Q_assert(face->planenum == node->planenum); + // Q_assert(face->planenum == node->planenum); // emit a region for (auto &fragment : face->fragments) { @@ -312,7 +313,7 @@ MakeMarkFaces Populates the `markfaces` vectors of all leafs ================ */ -void MakeMarkFaces(node_t* node) +void MakeMarkFaces(node_t *node) { if (node->is_leaf) { return; @@ -321,7 +322,7 @@ void MakeMarkFaces(node_t* node) // for the faces on this splitting node.. for (auto &face : node->facelist) { // add this face to all descendant leafs it touches - + // make a copy we can clip AddMarksurfaces_r(face.get(), CopyFace(face.get()), node->children[face->plane_flipped].get()); } @@ -424,8 +425,8 @@ static std::list> SubdivideFace(std::unique_ptr std::unique_ptr back; std::tie(front, back) = SplitFace(std::move(f), plane); if (!front || !back) { - //logging::print("didn't split\n"); - // FError("Didn't split the polygon"); + // logging::print("didn't split\n"); + // FError("Didn't split the polygon"); } if (front) { @@ -473,7 +474,7 @@ static std::unique_ptr FaceFromPortal(portal_t *p, bool pside) { side_t *side = p->sides[pside]; if (!side) - return nullptr; // portal does not bridge different visible contents + return nullptr; // portal does not bridge different visible contents auto f = std::make_unique(); @@ -527,11 +528,10 @@ mark the side that originally created it water / water : none =============== */ -static void MakeFaces_r(node_t *node, makefaces_stats_t& stats) +static void MakeFaces_r(node_t *node, makefaces_stats_t &stats) { // recurse down to leafs - if (!node->is_leaf) - { + if (!node->is_leaf) { MakeFaces_r(node->children[0].get(), stats); MakeFaces_r(node->children[1].get(), stats); @@ -553,8 +553,7 @@ static void MakeFaces_r(node_t *node, makefaces_stats_t& stats) // (Note, this is happening per leaf, so we can potentially generate faces // for the same portal once from one leaf, and once from the neighbouring one) bool s; - for (portal_t *p = node->portals; p; p = p->next[s]) - { + for (portal_t *p = node->portals; p; p = p->next[s]) { // true means node is on the back side of planenum s = (p->nodes[1] == node); @@ -581,7 +580,8 @@ void MakeFaces(node_t *node) MakeFaces_r(node, stats); - logging::print(logging::flag::STAT, " {:8} makefaces\n", stats.c_nodefaces); // FIXME: what is "makefaces" exactly + logging::print( + logging::flag::STAT, " {:8} makefaces\n", stats.c_nodefaces); // FIXME: what is "makefaces" exactly logging::print(logging::flag::STAT, " {:8} merged\n", stats.c_merge); logging::print(logging::flag::STAT, " {:8} subdivided\n", stats.c_subdivide); } diff --git a/qbsp/main.cc b/qbsp/main.cc index 6e4a42ad..63f23b88 100644 --- a/qbsp/main.cc +++ b/qbsp/main.cc @@ -25,7 +25,7 @@ int main(int argc, const char **argv) { try { return qbsp_main(argc, argv); - } catch (const settings::quit_after_help_exception&) { + } catch (const settings::quit_after_help_exception &) { return 0; } } diff --git a/qbsp/map.cc b/qbsp/map.cc index 34ca2f74..e274d464 100644 --- a/qbsp/map.cc +++ b/qbsp/map.cc @@ -54,12 +54,13 @@ const std::optional &mapdata_t::load_image_meta(const std::st } // try a meta-only texture first; this is all we really need anyways - if (auto [texture_meta, _0, _1] = img::load_texture_meta(name, qbsp_options.target_game, qbsp_options); texture_meta) { + if (auto [texture_meta, _0, _1] = img::load_texture_meta(name, qbsp_options.target_game, qbsp_options); + texture_meta) { // slight special case: if the meta has no width/height defined, // pull it from the real texture. if (!texture_meta->width || !texture_meta->height) { auto [texture, _0, _1] = img::load_texture(name, true, qbsp_options.target_game, qbsp_options); - + if (texture) { texture_meta->width = texture->meta.width; texture_meta->height = texture->meta.height; @@ -102,7 +103,7 @@ static void EnsureTexturesLoaded(const mapentity_t *entity) return; map.textures_loaded = true; - + // Q2 doesn't need this if (qbsp_options.target_game->id == GAME_QUAKE_II) { return; @@ -119,14 +120,14 @@ static void EnsureTexturesLoaded(const mapentity_t *entity) if (wadstring.empty()) { logging::print("WARNING: No wad or _wad key exists in the worldmodel\n"); } else { - imemstream stream(wadstring.data(), wadstring.size()); + imemstream stream(wadstring.data(), wadstring.size()); std::string wad; - while (std::getline(stream, wad, ';')) { - if (LoadTexturePath(wad)) { + while (std::getline(stream, wad, ';')) { + if (LoadTexturePath(wad)) { loaded_any_archive = true; } - } + } } if (!loaded_any_archive) { @@ -305,8 +306,7 @@ int FindMiptex(const char *name, std::optional &extended_inf int last_i = i; // recursively load animated textures until we loop back to us - while (true) - { + while (true) { // wal for next chain wal = map.load_image_meta(wal->animation.c_str()); @@ -494,7 +494,7 @@ static surfflags_t SurfFlagsForEntity(const maptexinfo_t &texinfo, const mapenti } const vec_t phong_angle_concave = entity->epairs.get_float("_phong_angle_concave"); - flags.phong_angle_concave = clamp(phong_angle_concave, 0.0, 360.0); + flags.phong_angle_concave = clamp(phong_angle_concave, 0.0, 360.0); // handle "_minlight" const vec_t minlight = entity->epairs.get_float("_minlight"); @@ -693,8 +693,8 @@ qvec2f normalizeShift(const std::optional &texture, const qve } /// `texture` is optional. If given, the "shift" values can be normalized -static texdef_quake_ed_t TexDef_BSPToQuakeEd(const qbsp_plane_t &faceplane, const std::optional &texture, - const texvecf &in_vecs, const std::array &facepoints) +static texdef_quake_ed_t TexDef_BSPToQuakeEd(const qbsp_plane_t &faceplane, + const std::optional &texture, const texvecf &in_vecs, const std::array &facepoints) { // First get the un-rotated, un-scaled unit texture vecs (based on the face plane). qvec3d snapped_normal; @@ -1445,9 +1445,10 @@ static void ParseTextureDef(parser_t &parser, mapface_t &mapface, const mapbrush } // if we have texture defs, see if we should remap this one - if (auto it = qbsp_options.loaded_texture_defs.find(mapface.texname); it != qbsp_options.loaded_texture_defs.end()) { + if (auto it = qbsp_options.loaded_texture_defs.find(mapface.texname); + it != qbsp_options.loaded_texture_defs.end()) { mapface.texname = std::get<0>(it->second); - + if (std::get<1>(it->second).has_value()) { mapface.raw_info = extinfo.info = std::get<1>(it->second).value(); } @@ -1494,12 +1495,13 @@ static void ParseTextureDef(parser_t &parser, mapface_t &mapface, const mapbrush tx->flags = mapface.flags = {extinfo.info->flags}; tx->value = mapface.value = extinfo.info->value; - contentflags_t contents { mapface.contents }; + contentflags_t contents{mapface.contents}; if (!contents.is_valid(qbsp_options.target_game, false)) { auto old_contents = contents; qbsp_options.target_game->contents_make_valid(contents); - logging::print("WARNING: line {}: face has invalid contents {}, remapped to {}\n", mapface.linenum, old_contents.to_string(qbsp_options.target_game), contents.to_string(qbsp_options.target_game)); + logging::print("WARNING: line {}: face has invalid contents {}, remapped to {}\n", mapface.linenum, + old_contents.to_string(qbsp_options.target_game), contents.to_string(qbsp_options.target_game)); } switch (tx_type) { @@ -1576,8 +1578,9 @@ inline bool IsValidTextureProjection(const mapface_t &mapface, const maptexinfo_ static void ValidateTextureProjection(mapface_t &mapface, maptexinfo_t *tx) { if (!IsValidTextureProjection(mapface, tx)) { - logging::print("WARNING: repairing invalid texture projection on line {} (\"{}\" near {} {} {})\n", mapface.linenum, - mapface.texname, (int)mapface.planepts[0][0], (int)mapface.planepts[0][1], (int)mapface.planepts[0][2]); + logging::print("WARNING: repairing invalid texture projection on line {} (\"{}\" near {} {} {})\n", + mapface.linenum, mapface.texname, (int)mapface.planepts[0][0], (int)mapface.planepts[0][1], + (int)mapface.planepts[0][2]); // Reset texturing to sensible defaults const std::array shift{0, 0}; @@ -1875,7 +1878,8 @@ static mapentity_t LoadExternalMap(const std::string &filename) FError("Expected at least one brush for external map {}\n", filename); } - logging::print(logging::flag::STAT, " {}: '{}': Loaded {} mapbrushes.\n", __func__, filename, dest.nummapbrushes); + logging::print( + logging::flag::STAT, " {}: '{}': Loaded {} mapbrushes.\n", __func__, filename, dest.nummapbrushes); return dest; } @@ -2120,7 +2124,8 @@ static void ConvertMapFace(std::ofstream &f, const mapface_t &mapface, const con fprintDoubleAndSpc(f, quakeed.scale[1]); if (mapface.raw_info.has_value()) { - f << mapface.raw_info->contents.native << " " << mapface.raw_info->flags.native << " " << mapface.raw_info->value; + f << mapface.raw_info->contents.native << " " << mapface.raw_info->flags.native << " " + << mapface.raw_info->value; } break; @@ -2143,7 +2148,8 @@ static void ConvertMapFace(std::ofstream &f, const mapface_t &mapface, const con fprintDoubleAndSpc(f, valve.scale[1]); if (mapface.raw_info.has_value()) { - f << mapface.raw_info->contents.native << " " << mapface.raw_info->flags.native << " " << mapface.raw_info->value; + f << mapface.raw_info->contents.native << " " << mapface.raw_info->flags.native << " " + << mapface.raw_info->value; } break; @@ -2167,7 +2173,8 @@ static void ConvertMapFace(std::ofstream &f, const mapface_t &mapface, const con fmt::print(f, ") ) {} ", mapface.texname); if (mapface.raw_info.has_value()) { - f << mapface.raw_info->contents.native << " " << mapface.raw_info->flags.native << " " << mapface.raw_info->value; + f << mapface.raw_info->contents.native << " " << mapface.raw_info->flags.native << " " + << mapface.raw_info->value; } else { f << "0 0 0"; } @@ -2422,13 +2429,11 @@ static void TestExpandBrushes(const mapentity_t *src) for (int i = 0; i < src->nummapbrushes; i++) { const mapbrush_t *mapbrush = &src->mapbrush(i); - std::optional hull1brush = LoadBrush( - src, mapbrush, {CONTENTS_SOLID}, {}, rotation_t::none, + std::optional hull1brush = LoadBrush(src, mapbrush, {CONTENTS_SOLID}, {}, rotation_t::none, qbsp_options.target_game->id == GAME_QUAKE_II ? HULL_COLLISION : 1); if (hull1brush) { - hull1brushes.emplace_back( - std::make_unique(std::move(*hull1brush))); + hull1brushes.emplace_back(std::make_unique(std::move(*hull1brush))); } } diff --git a/qbsp/merge.cc b/qbsp/merge.cc index 2ba57f2a..a7aa28a7 100644 --- a/qbsp/merge.cc +++ b/qbsp/merge.cc @@ -68,7 +68,8 @@ static std::unique_ptr TryMerge(const face_t *f1, const face_t *f2) bool keep1, keep2; if (!f1->w.size() || !f2->w.size() || f1->plane_flipped != f2->plane_flipped || f1->texinfo != f2->texinfo || - /*!f1->contents[0].equals(options.target_game, f2->contents[0]) || !f1->contents[1].equals(options.target_game, f2->contents[1]) || */ + /*!f1->contents[0].equals(options.target_game, f2->contents[0]) || !f1->contents[1].equals(options.target_game, + f2->contents[1]) || */ f1->lmshift != f2->lmshift) return NULL; diff --git a/qbsp/outside.cc b/qbsp/outside.cc index 34046641..5ce4dc06 100644 --- a/qbsp/outside.cc +++ b/qbsp/outside.cc @@ -112,14 +112,14 @@ Given that the cluster is reachable from the void, sets outside_distance to the given value on this cluster and all desdcent leafs (if it's a detail cluster). ================== */ -static void MarkClusterOutsideDistance_R(node_t* node, int outside_distance) +static void MarkClusterOutsideDistance_R(node_t *node, int outside_distance) { node->outside_distance = outside_distance; if (!node->is_leaf) { MarkClusterOutsideDistance_R(node->children[0].get(), outside_distance); MarkClusterOutsideDistance_R(node->children[1].get(), outside_distance); - } + } } /* @@ -321,7 +321,7 @@ static void MarkOccupiedClusters(node_t *headnode) } } -static void FindOccupiedClusters_R(node_t *node, std::vector& result) +static void FindOccupiedClusters_R(node_t *node, std::vector &result) { if (node->occupant) { result.push_back(node); @@ -450,7 +450,7 @@ static void OutLeafsToSolid_r(node_t *node, int *outleafs_count, settings::fillt return; } - // Finally, we can fill it in as void. + // Finally, we can fill it in as void. node->contents = qbsp_options.target_game->create_solid_contents(); *outleafs_count += 1; } @@ -621,7 +621,7 @@ bool FillOutside(mapentity_t *entity, tree_t *tree, const int hullnum) std::vector leakline; settings::filltype_t filltype = qbsp_options.filltype.value(); - + if (filltype == settings::filltype_t::AUTO) { filltype = hullnum > 0 ? settings::filltype_t::OUTSIDE : settings::filltype_t::INSIDE; } @@ -695,7 +695,7 @@ bool FillOutside(mapentity_t *entity, tree_t *tree, const int hullnum) const int outleafs = OutLeafsToSolid(node, filltype); // See missing_face_simple.map for a test case with a brush that straddles between void and non-void - + MarkBrushSidesInvisible(entity); MarkVisibleBrushSides_R(node); @@ -711,7 +711,7 @@ bool FillOutside(mapentity_t *entity, tree_t *tree, const int hullnum) return true; } -void FillBrushEntity(mapentity_t* entity, tree_t *tree, const int hullnum) +void FillBrushEntity(mapentity_t *entity, tree_t *tree, const int hullnum) { logging::print(logging::flag::PROGRESS, "---- {} ----\n", __func__); diff --git a/qbsp/portals.cc b/qbsp/portals.cc index d2562ea8..3e333a8c 100644 --- a/qbsp/portals.cc +++ b/qbsp/portals.cc @@ -69,7 +69,8 @@ bool Portal_VisFlood(const portal_t *p) return false; // Check per-game visibility - return qbsp_options.target_game->portal_can_see_through(contents0, contents1, qbsp_options.transwater.value(), qbsp_options.transsky.value()); + return qbsp_options.target_game->portal_can_see_through( + contents0, contents1, qbsp_options.transwater.value(), qbsp_options.transsky.value()); } /* @@ -88,8 +89,8 @@ bool Portal_EntityFlood(const portal_t *p, int32_t s) } // can never cross to a solid - if (p->nodes[0]->contents.is_any_solid(qbsp_options.target_game) - || p->nodes[1]->contents.is_any_solid(qbsp_options.target_game)) { + if (p->nodes[0]->contents.is_any_solid(qbsp_options.target_game) || + p->nodes[1]->contents.is_any_solid(qbsp_options.target_game)) { return false; } @@ -219,17 +220,16 @@ BaseWindingForNode Creates a winding from the given node plane, clipped by all parent nodes. ================ */ -constexpr vec_t BASE_WINDING_EPSILON = 0.001; -constexpr vec_t SPLIT_WINDING_EPSILON = 0.001; +constexpr vec_t BASE_WINDING_EPSILON = 0.001; +constexpr vec_t SPLIT_WINDING_EPSILON = 0.001; std::optional BaseWindingForNode(node_t *node) { std::optional w = BaseWindingForPlane(node->plane); // clip by all the parents - for (node_t *np = node->parent; np && w; ) { - const planeside_t keep = (np->children[0].get() == node) ? - SIDE_FRONT : SIDE_BACK; + for (node_t *np = node->parent; np && w;) { + const planeside_t keep = (np->children[0].get() == node) ? SIDE_FRONT : SIDE_BACK; w = w->clip(np->plane, BASE_WINDING_EPSILON, false)[keep]; @@ -271,13 +271,11 @@ void MakeNodePortal(tree_t *tree, node_t *node, portalstats_t &stats) w = w->clip(plane, 0.1, false)[SIDE_FRONT]; } - if (!w) - { + if (!w) { return; } - if (WindingIsTiny(*w)) - { + if (WindingIsTiny(*w)) { stats.c_tinyportals++; return; } @@ -304,8 +302,7 @@ void SplitNodePortals(tree_t *tree, node_t *node, portalstats_t &stats) node_t *b = node->children[1].get(); portal_t *next_portal = nullptr; - for (portal_t *p = node->portals; p ; p = next_portal) - { + for (portal_t *p = node->portals; p; p = next_portal) { planeside_t side; if (p->nodes[SIDE_FRONT] == node) side = SIDE_FRONT; @@ -324,33 +321,28 @@ void SplitNodePortals(tree_t *tree, node_t *node, portalstats_t &stats) // auto [frontwinding, backwinding] = p->winding->clip(plane, SPLIT_WINDING_EPSILON, true); - if (frontwinding && WindingIsTiny(*frontwinding)) - { + if (frontwinding && WindingIsTiny(*frontwinding)) { frontwinding = {}; stats.c_tinyportals++; } - if (backwinding && WindingIsTiny(*backwinding)) - { + if (backwinding && WindingIsTiny(*backwinding)) { backwinding = {}; stats.c_tinyportals++; } - if (!frontwinding && !backwinding) - { // tiny windings on both sides + if (!frontwinding && !backwinding) { // tiny windings on both sides continue; } - if (!frontwinding) - { + if (!frontwinding) { if (side == SIDE_FRONT) AddPortalToNodes(p, b, other_node); else AddPortalToNodes(p, other_node, b); continue; } - if (!backwinding) - { + if (!backwinding) { if (side == SIDE_FRONT) AddPortalToNodes(p, f, other_node); else @@ -364,13 +356,10 @@ void SplitNodePortals(tree_t *tree, node_t *node, portalstats_t &stats) new_portal->winding = backwinding; p->winding = frontwinding; - if (side == SIDE_FRONT) - { + if (side == SIDE_FRONT) { AddPortalToNodes(p, f, other_node); AddPortalToNodes(new_portal, b, other_node); - } - else - { + } else { AddPortalToNodes(p, other_node, f); AddPortalToNodes(new_portal, other_node, b); } @@ -389,7 +378,7 @@ void CalcNodeBounds(node_t *node) // calc mins/maxs for both leafs and nodes node->bounds = aabb3d{}; - for (portal_t *p = node->portals; p ;) { + for (portal_t *p = node->portals; p;) { int s = (p->nodes[1] == node); for (auto &point : *p->winding) { node->bounds += point; @@ -406,19 +395,16 @@ MakeTreePortals_r void MakeTreePortals_r(tree_t *tree, node_t *node, portalstats_t &stats) { CalcNodeBounds(node); - if (node->bounds.mins()[0] >= node->bounds.maxs()[0]) - { + if (node->bounds.mins()[0] >= node->bounds.maxs()[0]) { logging::print("WARNING: node without a volume\n"); // fixme-brushbsp: added this to work around leafs with no portals showing up in "qbspfeatures.map" among other // test maps. Not sure if correct or there's another underlying problem. - node->bounds = { node->parent->bounds.mins(), node->parent->bounds.mins() }; + node->bounds = {node->parent->bounds.mins(), node->parent->bounds.mins()}; } - for (int i = 0; i < 3; i++) - { - if (fabs(node->bounds.mins()[i]) > qbsp_options.worldextent.value()) - { + for (int i = 0; i < 3; i++) { + if (fabs(node->bounds.mins()[i]) > qbsp_options.worldextent.value()) { logging::print("WARNING: node with unbounded volume\n"); break; } @@ -516,10 +502,8 @@ static void FloodAreas_r(node_t *node) // grab the func_areanode entity mapentity_t *entity = AreanodeEntityForLeaf(node); - if (entity == nullptr) - { - logging::print("WARNING: areaportal contents in node, but no entity found {} -> {}\n", - node->bounds.mins(), + if (entity == nullptr) { + logging::print("WARNING: areaportal contents in node, but no entity found {} -> {}\n", node->bounds.mins(), node->bounds.maxs()); return; } @@ -533,8 +517,7 @@ static void FloodAreas_r(node_t *node) // note the current area as bounding the portal if (entity->portalareas[1]) { logging::print("WARNING: areaportal entity {} touches > 2 areas\n Entity Bounds: {} -> {}\n", - entity - map.entities.data(), entity->bounds.mins(), - entity->bounds.maxs()); + entity - map.entities.data(), entity->bounds.mins(), entity->bounds.maxs()); return; } @@ -621,18 +604,15 @@ static void SetAreaPortalAreas_r(node_t *node) // grab the func_areanode entity mapentity_t *entity = AreanodeEntityForLeaf(node); - if (!entity) - { - logging::print("WARNING: areaportal missing for node: {} -> {}\n", - node->bounds.mins(), node->bounds.maxs()); + if (!entity) { + logging::print("WARNING: areaportal missing for node: {} -> {}\n", node->bounds.mins(), node->bounds.maxs()); return; } node->area = entity->portalareas[0]; if (!entity->portalareas[1]) { logging::print("WARNING: areaportal entity {} doesn't touch two areas\n Entity Bounds: {} -> {}\n", - entity - map.entities.data(), - entity->bounds.mins(), entity->bounds.maxs()); + entity - map.entities.data(), entity->bounds.mins(), entity->bounds.maxs()); return; } } @@ -670,8 +650,7 @@ void EmitAreaPortals(node_t *headnode) size_t j = 0; - for (; j < map.bsp.dareaportals.size(); j++) - { + for (; j < map.bsp.dareaportals.size(); j++) { if (map.bsp.dareaportals[j] == dp) break; } @@ -728,29 +707,28 @@ static void FindPortalSide(portal_t *p) const qbsp_plane_t &p1 = p->onnode->plane; // check brushes on both sides of the portal - for (int j = 0; j < 2; j++) - { + for (int j = 0; j < 2; j++) { node_t *n = p->nodes[j]; // iterate the n->original_brushes vector in reverse order, so later brushes // in the map file order are prioritized - for (auto it = n->original_brushes.rbegin(); it != n->original_brushes.rend(); ++it) - { + for (auto it = n->original_brushes.rbegin(); it != n->original_brushes.rend(); ++it) { auto *brush = *it; - const bool generate_outside_face = qbsp_options.target_game->portal_generates_face(viscontents, brush->contents, SIDE_FRONT); - const bool generate_inside_face = qbsp_options.target_game->portal_generates_face(viscontents, brush->contents, SIDE_BACK); + const bool generate_outside_face = + qbsp_options.target_game->portal_generates_face(viscontents, brush->contents, SIDE_FRONT); + const bool generate_inside_face = + qbsp_options.target_game->portal_generates_face(viscontents, brush->contents, SIDE_BACK); if (!(generate_outside_face || generate_inside_face)) { continue; } - for (auto &side : brush->sides) - { + for (auto &side : brush->sides) { if (side.bevel) continue; // fixme-brushbsp: restore -// if (!side.visible) -// continue; // non-visible + // if (!side.visible) + // continue; // non-visible if (qv::epsilonEqual(side.plane, p1)) { // exact match (undirectional) @@ -762,7 +740,7 @@ static void FindPortalSide(portal_t *p) if (generate_outside_face) { if (!bestside[!j]) { bestside[!j] = &side; - } + } } if (generate_inside_face) { if (!bestside[j]) { @@ -774,12 +752,12 @@ static void FindPortalSide(portal_t *p) } // see how close the match is // fixme-brushbsp: verify that this actually works, restore it -// const auto &p2 = side.plane; -// double dot = qv::dot(p1.normal, p2.normal); -// if (dot > bestdot) { -// bestdot = dot; -// bestside[j] = &side; -// } + // const auto &p2 = side.plane; + // double dot = qv::dot(p1.normal, p2.normal); + // if (dot > bestdot) { + // bestdot = dot; + // bestside[j] = &side; + // } } } } @@ -814,11 +792,10 @@ static void MarkVisibleSides_r(node_t *node) // see if there is a visible face int s; - for (portal_t *p=node->portals ; p ; p = p->next[!s]) - { + for (portal_t *p = node->portals; p; p = p->next[!s]) { s = (p->nodes[0] == node); if (!p->onnode) - continue; // edge of world + continue; // edge of world if (!p->sidefound) FindPortalSide(p); for (int i = 0; i < 2; ++i) { @@ -835,7 +812,7 @@ MarkVisibleSides ============= */ -void MarkVisibleSides(tree_t *tree, mapentity_t* entity) +void MarkVisibleSides(tree_t *tree, mapentity_t *entity) { logging::print(logging::flag::PROGRESS, "--- {} ---\n", __func__); diff --git a/qbsp/qbsp.cc b/qbsp/qbsp.cc index 32a525d5..0179b38c 100644 --- a/qbsp/qbsp.cc +++ b/qbsp/qbsp.cc @@ -71,9 +71,8 @@ void qbsp_settings::initialize(int argc, const char **argv) parser_t p(file->data(), file->size()); parse(p); } - - try - { + + try { token_parser_t p(argc - 1, argv + 1); auto remainder = parse(p); @@ -86,9 +85,7 @@ void qbsp_settings::initialize(int argc, const char **argv) if (remainder.size() == 2) { qbsp_options.bsp_path = remainder[1]; } - } - catch (parse_exception ex) - { + } catch (parse_exception ex) { logging::print(ex.what()); printHelp(); } @@ -113,7 +110,7 @@ void qbsp_settings::load_texture_def(const std::string &pathname) if (!parser.parse_token(PARSE_SAMELINE)) { break; } - + std::string to = std::move(parser.token); std::optional texinfo; @@ -122,20 +119,20 @@ void qbsp_settings::load_texture_def(const std::string &pathname) while (std::isspace(to[to.size() - 1])) { to.resize(to.size() - 1); } - + if (parser.parse_token(PARSE_SAMELINE | PARSE_OPTIONAL)) { - texinfo = extended_texinfo_t { std::stoi(parser.token) }; - + texinfo = extended_texinfo_t{std::stoi(parser.token)}; + if (parser.parse_token(PARSE_SAMELINE | PARSE_OPTIONAL)) { texinfo->flags.native = std::stoi(parser.token); } - + if (parser.parse_token(PARSE_SAMELINE | PARSE_OPTIONAL)) { texinfo->value = std::stoi(parser.token); } } - loaded_texture_defs[from] = { to, texinfo }; + loaded_texture_defs[from] = {to, texinfo}; } } @@ -175,7 +172,8 @@ void qbsp_settings::postinitialize(int argc, const char **argv) qbsp_options.fAllverbose = true; } - if ((logging::mask & (bitflags(logging::flag::PERCENT) | logging::flag::STAT | logging::flag::PROGRESS)) == logging::flag::NONE) { + if ((logging::mask & (bitflags(logging::flag::PERCENT) | logging::flag::STAT | + logging::flag::PROGRESS)) == logging::flag::NONE) { qbsp_options.fNoverbose = true; } @@ -184,8 +182,7 @@ void qbsp_settings::postinitialize(int argc, const char **argv) set_target_version(&bspver_hl); } - if (q2bsp.value() || - (q2rtx.value() && !q2bsp.isChanged() && !qbism.isChanged())) { + if (q2bsp.value() || (q2rtx.value() && !q2bsp.isChanged() && !qbism.isChanged())) { set_target_version(&bspver_q2); } @@ -487,7 +484,7 @@ static bool IsTrigger(const mapentity_t *entity) return trigger_pos == (tex.size() - strlen("trigger")); } -static void CountLeafs_r(node_t *node, content_stats_base_t& stats) +static void CountLeafs_r(node_t *node, content_stats_base_t &stats) { if (node->is_leaf) { qbsp_options.target_game->count_contents_in_stats(node->contents, stats); @@ -526,8 +523,7 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum) return; // for notriggermodels: if we have at least one trigger-like texture, do special trigger stuff - bool discarded_trigger = entity != map.world_entity() && qbsp_options.notriggermodels.value() && - IsTrigger(entity); + bool discarded_trigger = entity != map.world_entity() && qbsp_options.notriggermodels.value() && IsTrigger(entity); // Export a blank model struct, and reserve the index (only do this once, for all hulls) if (!discarded_trigger) { @@ -572,16 +568,16 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum) entity->brushes[i]->file_order = i; } - //entity->brushes = ChopBrushes(entity->brushes); + // entity->brushes = ChopBrushes(entity->brushes); -// if (entity == map.world_entity() && hullnum <= 0) { -// if (options.debugchop.value()) { -// fs::path path = options.bsp_path; -// path.replace_extension(".chop.map"); -// -// WriteBspBrushMap(path, entity->brushes); -// } -// } + // if (entity == map.world_entity() && hullnum <= 0) { + // if (options.debugchop.value()) { + // fs::path path = options.bsp_path; + // path.replace_extension(".chop.map"); + // + // WriteBspBrushMap(path, entity->brushes); + // } + // } // we're discarding the brush if (discarded_trigger) { @@ -671,7 +667,7 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum) ExportObj_Nodes("pre_makefaceedges_plane_faces", tree->headnode.get()); ExportObj_Marksurfaces("pre_makefaceedges_marksurfaces", tree->headnode.get()); } - + Q_assert(entity->firstoutputfacenumber == -1); entity->firstoutputfacenumber = MakeFaceEdges(tree->headnode.get()); @@ -741,7 +737,8 @@ static void UpdateEntLump(void) if (!qbsp_options.fAllverbose) { qbsp_options.fVerbose = false; - logging::mask &= ~(bitflags(logging::flag::STAT) | logging::flag::PROGRESS | logging::flag::PERCENT); + logging::mask &= + ~(bitflags(logging::flag::STAT) | logging::flag::PROGRESS | logging::flag::PERCENT); } } @@ -905,7 +902,8 @@ static void CreateSingleHull(const int hullnum) ProcessEntity(&entity, hullnum); if (!qbsp_options.fAllverbose) { qbsp_options.fVerbose = false; // don't print rest of entities - logging::mask &= ~(bitflags(logging::flag::STAT) | logging::flag::PROGRESS | logging::flag::PERCENT); + logging::mask &= + ~(bitflags(logging::flag::STAT) | logging::flag::PROGRESS | logging::flag::PERCENT); } } } @@ -920,7 +918,8 @@ static void CreateHulls(void) /* create the hulls sequentially */ if (!qbsp_options.fNoverbose) { qbsp_options.fVerbose = true; - logging::mask |= (bitflags(logging::flag::STAT) | logging::flag::PROGRESS | logging::flag::PERCENT); + logging::mask |= + (bitflags(logging::flag::STAT) | logging::flag::PROGRESS | logging::flag::PERCENT); } auto &hulls = qbsp_options.target_game->get_hull_sizes(); @@ -952,7 +951,8 @@ static void LoadTextureData() if (!tex) { if (pos.archive) { - logging::print("WARNING: unable to load texture {} in archive {}\n", map.miptex[i].name, pos.archive->pathname); + logging::print("WARNING: unable to load texture {} in archive {}\n", map.miptex[i].name, + pos.archive->pathname); } else { logging::print("WARNING: unable to find texture {}\n", map.miptex[i].name); } @@ -972,17 +972,17 @@ static void LoadTextureData() // construct fake data that solely contains the header. miptex.data.resize(sizeof(dmiptex_t)); - dmiptex_t header {}; + dmiptex_t header{}; if (miptex.name.size() >= 16) { logging::print("WARNING: texture {} name too long for Quake miptex\n", miptex.name); std::copy_n(miptex.name.begin(), 15, header.name.begin()); } else { std::copy(miptex.name.begin(), miptex.name.end(), header.name.begin()); } - + header.width = miptex.width; header.height = miptex.height; - header.offsets = { -1, -1, -1, -1 }; + header.offsets = {-1, -1, -1, -1}; omemstream stream(miptex.data.data(), miptex.data.size()); stream <= header; @@ -1020,7 +1020,7 @@ static void LoadSecondaryTextures() if (qbsp_options.target_game->id == GAME_QUAKE_II) { return; } - + AddAnimationFrames(); /* Default texture data to store in worldmodel */ @@ -1041,7 +1041,7 @@ static void SnapVertices() if (!qbsp_options.snapvertices.value()) { return; } - + logging::print(logging::flag::PROGRESS, "---- {} ----\n", __func__); for (auto &v : map.bsp.dvertexes) { @@ -1078,7 +1078,8 @@ void ProcessFile() if (!qbsp_options.fAllverbose) { qbsp_options.fVerbose = false; - logging::mask &= ~(bitflags(logging::flag::STAT) | logging::flag::PROGRESS | logging::flag::PERCENT); + logging::mask &= + ~(bitflags(logging::flag::STAT) | logging::flag::PROGRESS | logging::flag::PERCENT); } // calculate extents, if required @@ -1168,7 +1169,7 @@ void InitQBSP(int argc, const char **argv) map.skip_texinfo = MakeSkipTexinfo(); } -void InitQBSP(const std::vector& args) +void InitQBSP(const std::vector &args) { std::vector argPtrs; for (const std::string &arg : args) { diff --git a/qbsp/tjunc.cc b/qbsp/tjunc.cc index dc456196..4061771f 100644 --- a/qbsp/tjunc.cc +++ b/qbsp/tjunc.cc @@ -26,53 +26,54 @@ struct tjunc_stats_t { - // # of degenerate edges reported (with two identical input vertices) - std::atomic degenerate; - // # of new edges created to close a tjunction - // (also technically the # of points detected that lay on other faces' edges) - std::atomic tjunctions; - // # of faces that were created as a result of splitting faces that are too large - // to be contained on a single face - std::atomic faceoverflows; - // # of faces that were degenerate and were just collapsed altogether. - std::atomic facecollapse; - // # of faces that were able to be fixed just by rotating the start point. - std::atomic rotates; - // # of faces that weren't able to be fixed with start point rotation - std::atomic norotates; - // # of faces that could be successfully retopologized - std::atomic retopology; - // # of faces generated by retopologization - std::atomic faceretopology; - // # of faces that were successfully topologized by MWT - std::atomic mwt; - // # of triangles computed by MWT - std::atomic trimwt; - // # of faces added by MWT - std::atomic facemwt; + // # of degenerate edges reported (with two identical input vertices) + std::atomic degenerate; + // # of new edges created to close a tjunction + // (also technically the # of points detected that lay on other faces' edges) + std::atomic tjunctions; + // # of faces that were created as a result of splitting faces that are too large + // to be contained on a single face + std::atomic faceoverflows; + // # of faces that were degenerate and were just collapsed altogether. + std::atomic facecollapse; + // # of faces that were able to be fixed just by rotating the start point. + std::atomic rotates; + // # of faces that weren't able to be fixed with start point rotation + std::atomic norotates; + // # of faces that could be successfully retopologized + std::atomic retopology; + // # of faces generated by retopologization + std::atomic faceretopology; + // # of faces that were successfully topologized by MWT + std::atomic mwt; + // # of triangles computed by MWT + std::atomic trimwt; + // # of faces added by MWT + std::atomic facemwt; }; -inline std::optional PointOnEdge(const qvec3d &p, const qvec3d &edge_start, const qvec3d &edge_dir, float start = 0, float end = 1) +inline std::optional PointOnEdge( + const qvec3d &p, const qvec3d &edge_start, const qvec3d &edge_dir, float start = 0, float end = 1) { - qvec3d delta = p - edge_start; - vec_t dist = qv::dot(delta, edge_dir); + qvec3d delta = p - edge_start; + vec_t dist = qv::dot(delta, edge_dir); - // check if off an end - if (dist <= start || dist >= end) { - return std::nullopt; - } + // check if off an end + if (dist <= start || dist >= end) { + return std::nullopt; + } - qvec3d exact = edge_start + (edge_dir * dist); - qvec3d off = p - exact; - vec_t error = qv::length(off); + qvec3d exact = edge_start + (edge_dir * dist); + qvec3d off = p - exact; + vec_t error = qv::length(off); - // brushbsp-fixme: this was 0.5 in Q2, check? - if (fabs(error) > DEFAULT_ON_EPSILON) { - // not on the edge - return std::nullopt; - } + // brushbsp-fixme: this was 0.5 in Q2, check? + if (fabs(error) > DEFAULT_ON_EPSILON) { + // not on the edge + return std::nullopt; + } - return dist; + return dist; } /* @@ -82,38 +83,39 @@ TestEdge Can be recursively reentered ========== */ -inline void TestEdge(vec_t start, vec_t end, size_t p1, size_t p2, size_t startvert, const std::vector &edge_verts, - const qvec3d &edge_start, const qvec3d &edge_dir, std::vector &superface, tjunc_stats_t &stats) +inline void TestEdge(vec_t start, vec_t end, size_t p1, size_t p2, size_t startvert, + const std::vector &edge_verts, const qvec3d &edge_start, const qvec3d &edge_dir, + std::vector &superface, tjunc_stats_t &stats) { - if (p1 == p2) { - // degenerate edge - stats.degenerate++; - return; - } + if (p1 == p2) { + // degenerate edge + stats.degenerate++; + return; + } - for (size_t k = startvert; k < edge_verts.size(); k++) { - size_t j = edge_verts[k]; + for (size_t k = startvert; k < edge_verts.size(); k++) { + size_t j = edge_verts[k]; - if (j == p1 || j == p2) { - continue; - } + if (j == p1 || j == p2) { + continue; + } - auto dist = PointOnEdge(map.bsp.dvertexes[j], edge_start, edge_dir, start, end); + auto dist = PointOnEdge(map.bsp.dvertexes[j], edge_start, edge_dir, start, end); - if (!dist.has_value()) { - continue; - } + if (!dist.has_value()) { + continue; + } - // break the edge - stats.tjunctions++; + // break the edge + stats.tjunctions++; - TestEdge (start, dist.value(), p1, j, k + 1, edge_verts, edge_start, edge_dir, superface, stats); - TestEdge (dist.value(), end, j, p2, k + 1, edge_verts, edge_start, edge_dir, superface, stats); - return; - } + TestEdge(start, dist.value(), p1, j, k + 1, edge_verts, edge_start, edge_dir, superface, stats); + TestEdge(dist.value(), end, j, p2, k + 1, edge_verts, edge_start, edge_dir, superface, stats); + return; + } - // the edge p1 to p2 is now free of tjunctions - superface.push_back(p1); + // the edge p1 to p2 is now free of tjunctions + superface.push_back(p1); } /* @@ -123,13 +125,14 @@ FindEdgeVerts_BruteForce Force a dumb check of everything ========== */ -static void FindEdgeVerts_BruteForce(const node_t *, const node_t *, const qvec3d &, const qvec3d &, std::vector &verts) +static void FindEdgeVerts_BruteForce( + const node_t *, const node_t *, const qvec3d &, const qvec3d &, std::vector &verts) { - verts.resize(map.bsp.dvertexes.size()); + verts.resize(map.bsp.dvertexes.size()); - for (size_t i = 0; i < verts.size(); i++) { - verts[i] = i; - } + for (size_t i = 0; i < verts.size(); i++) { + verts[i] = i; + } } /* @@ -142,22 +145,22 @@ for vertex checking. */ static void FindEdgeVerts_FaceBounds_R(const node_t *node, const aabb3d &aabb, std::vector &verts) { - if (node->is_leaf) { - return; - } else if (node->bounds.disjoint(aabb, 0.0)) { - return; - } + if (node->is_leaf) { + return; + } else if (node->bounds.disjoint(aabb, 0.0)) { + return; + } - for (auto &face : node->facelist) { - for (auto &v : face->original_vertices) { - if (aabb.containsPoint(map.bsp.dvertexes[v])) { - verts.push_back(v); - } - } - } - - FindEdgeVerts_FaceBounds_R(node->children[0].get(), aabb, verts); - FindEdgeVerts_FaceBounds_R(node->children[1].get(), aabb, verts); + for (auto &face : node->facelist) { + for (auto &v : face->original_vertices) { + if (aabb.containsPoint(map.bsp.dvertexes[v])) { + verts.push_back(v); + } + } + } + + FindEdgeVerts_FaceBounds_R(node->children[0].get(), aabb, verts); + FindEdgeVerts_FaceBounds_R(node->children[1].get(), aabb, verts); } /* @@ -167,12 +170,13 @@ FindEdgeVerts_FaceBounds Use a loose AABB around the line and only capture vertices that intersect it. ========== */ -static void FindEdgeVerts_FaceBounds(const node_t *headnode, const qvec3d &p1, const qvec3d &p2, std::vector &verts) +static void FindEdgeVerts_FaceBounds( + const node_t *headnode, const qvec3d &p1, const qvec3d &p2, std::vector &verts) { - // magic number, average of "usual" points per edge - verts.reserve(8); + // magic number, average of "usual" points per edge + verts.reserve(8); - FindEdgeVerts_FaceBounds_R(headnode, (aabb3d{} + p1 + p2).grow(qvec3d(1.0, 1.0, 1.0)), verts); + FindEdgeVerts_FaceBounds_R(headnode, (aabb3d{} + p1 + p2).grow(qvec3d(1.0, 1.0, 1.0)), verts); } /* @@ -186,36 +190,37 @@ max edge count. Modifies `superface`. Adds the results to the end of `output`. ================== */ -inline void SplitFaceIntoFragments(std::vector &superface, std::list> &output, tjunc_stats_t &stats) +inline void SplitFaceIntoFragments( + std::vector &superface, std::list> &output, tjunc_stats_t &stats) { - const int32_t &maxedges = qbsp_options.maxedges.value(); + const int32_t &maxedges = qbsp_options.maxedges.value(); - // split into multiple fragments, because of vertex overload - while (superface.size() > maxedges) { - stats.faceoverflows++; + // split into multiple fragments, because of vertex overload + while (superface.size() > maxedges) { + stats.faceoverflows++; - // copy MAXEDGES from our current face - std::vector &newf = output.emplace_back(maxedges); - std::copy_n(superface.begin(), maxedges, newf.begin()); + // copy MAXEDGES from our current face + std::vector &newf = output.emplace_back(maxedges); + std::copy_n(superface.begin(), maxedges, newf.begin()); - // remove everything in-between from the superface - // except for the last edge we just wrote (0 and MAXEDGES-1) - std::copy(superface.begin() + maxedges - 1, superface.end(), superface.begin() + 1); + // remove everything in-between from the superface + // except for the last edge we just wrote (0 and MAXEDGES-1) + std::copy(superface.begin() + maxedges - 1, superface.end(), superface.begin() + 1); - // resize superface; we need enough room to store the two extra verts - superface.resize(superface.size() - maxedges + 2); - } + // resize superface; we need enough room to store the two extra verts + superface.resize(superface.size() - maxedges + 2); + } - // move the first face to the end, since that's logically where it belongs now - output.splice(output.end(), output, output.begin()); + // move the first face to the end, since that's logically where it belongs now + output.splice(output.end(), output, output.begin()); } float AngleOfTriangle(const qvec3d &a, const qvec3d &b, const qvec3d &c) { - vec_t num = (b[0]-a[0])*(c[0]-a[0])+(b[1]-a[1])*(c[1]-a[1])+(b[2]-a[2])*(c[2]-a[2]); - vec_t den = sqrt(pow((b[0]-a[0]),2)+pow((b[1]-a[1]),2)+pow((b[2]-a[2]),2))* - sqrt(pow((c[0]-a[0]),2)+pow((c[1]-a[1]),2)+pow((c[2]-a[2]),2)); - + vec_t num = (b[0] - a[0]) * (c[0] - a[0]) + (b[1] - a[1]) * (c[1] - a[1]) + (b[2] - a[2]) * (c[2] - a[2]); + vec_t den = sqrt(pow((b[0] - a[0]), 2) + pow((b[1] - a[1]), 2) + pow((b[2] - a[2]), 2)) * + sqrt(pow((c[0] - a[0]), 2) + pow((c[1] - a[1]), 2) + pow((c[2] - a[2]), 2)); + return acos(num / den) * (180.0 / 3.141592653589793238463); } @@ -224,13 +229,13 @@ float AngleOfTriangle(const qvec3d &a, const qvec3d &b, const qvec3d &c) // intersecting it. inline bool TriangleIsValid(size_t v0, size_t v1, size_t v2, vec_t angle_epsilon) { - if (AngleOfTriangle(map.bsp.dvertexes[v0], map.bsp.dvertexes[v1], map.bsp.dvertexes[v2]) < angle_epsilon || - AngleOfTriangle(map.bsp.dvertexes[v1], map.bsp.dvertexes[v2], map.bsp.dvertexes[v0]) < angle_epsilon || - AngleOfTriangle(map.bsp.dvertexes[v2], map.bsp.dvertexes[v0], map.bsp.dvertexes[v1]) < angle_epsilon) { - return false; - } + if (AngleOfTriangle(map.bsp.dvertexes[v0], map.bsp.dvertexes[v1], map.bsp.dvertexes[v2]) < angle_epsilon || + AngleOfTriangle(map.bsp.dvertexes[v1], map.bsp.dvertexes[v2], map.bsp.dvertexes[v0]) < angle_epsilon || + AngleOfTriangle(map.bsp.dvertexes[v2], map.bsp.dvertexes[v0], map.bsp.dvertexes[v1]) < angle_epsilon) { + return false; + } - return true; + return true; } /* @@ -243,33 +248,33 @@ verts in the world added that lay on the line) and return it */ static std::vector CreateSuperFace(node_t *headnode, face_t *f, tjunc_stats_t &stats) { - std::vector superface; + std::vector superface; - superface.reserve(f->original_vertices.size() * 2); + superface.reserve(f->original_vertices.size() * 2); - // stores all of the verts in the world that are close to - // being on a given edge - std::vector edge_verts; + // stores all of the verts in the world that are close to + // being on a given edge + std::vector edge_verts; - // find all of the extra vertices that lay on edges, - // place them in superface - for (size_t i = 0; i < f->original_vertices.size(); i++) { - auto v1 = f->original_vertices[i]; - auto v2 = f->original_vertices[(i + 1) % f->original_vertices.size()]; + // find all of the extra vertices that lay on edges, + // place them in superface + for (size_t i = 0; i < f->original_vertices.size(); i++) { + auto v1 = f->original_vertices[i]; + auto v2 = f->original_vertices[(i + 1) % f->original_vertices.size()]; - qvec3d edge_start = map.bsp.dvertexes[v1]; - qvec3d e2 = map.bsp.dvertexes[v2]; + qvec3d edge_start = map.bsp.dvertexes[v1]; + qvec3d e2 = map.bsp.dvertexes[v2]; - edge_verts.clear(); - FindEdgeVerts_FaceBounds(headnode, edge_start, e2, edge_verts); + edge_verts.clear(); + FindEdgeVerts_FaceBounds(headnode, edge_start, e2, edge_verts); - vec_t len; - qvec3d edge_dir = qv::normalize(e2 - edge_start, len); + vec_t len; + qvec3d edge_dir = qv::normalize(e2 - edge_start, len); - TestEdge(0, len, v1, v2, 0, edge_verts, edge_start, edge_dir, superface, stats); - } + TestEdge(0, len, v1, v2, 0, edge_verts, edge_start, edge_dir, superface, stats); + } - return superface; + return superface; } #include @@ -281,173 +286,174 @@ using qvectri = qvec; // in any permutation std::optional triangle_exists(const std::vector &triangles, size_t a, size_t b, size_t c) { - for (size_t i = 0; i < triangles.size(); i++) { - auto &tri = triangles[i]; + for (size_t i = 0; i < triangles.size(); i++) { + auto &tri = triangles[i]; - for (size_t s = 0; s < 3; s++) { - if (tri[s] == a && tri[(s + 1) % 3] == b && tri[(s + 2) % 3] == c) { - return i; - } - } - } + for (size_t s = 0; s < 3; s++) { + if (tri[s] == a && tri[(s + 1) % 3] == b && tri[(s + 2) % 3] == c) { + return i; + } + } + } - return std::nullopt; + return std::nullopt; } // find the triangles best suited to create a // fan out of in the given set of triangles. std::vector find_best_fan(const std::vector &triangles, size_t num_vertices) { - // find the triangle with the most fannable vertices. - std::vector best_triangles; + // find the triangle with the most fannable vertices. + std::vector best_triangles; - for (auto &tri : triangles) { - // try all three permutations - for (size_t perm = 0; perm < 3; perm++) { - size_t first = tri[perm]; - size_t mid = tri[(perm + 1) % 3]; - size_t last = tri[(perm + 2) % 3]; + for (auto &tri : triangles) { + // try all three permutations + for (size_t perm = 0; perm < 3; perm++) { + size_t first = tri[perm]; + size_t mid = tri[(perm + 1) % 3]; + size_t last = tri[(perm + 2) % 3]; - std::vector my_tri; + std::vector my_tri; - // find any other that can be wound from this edge - // TODO: can optimize by only looping around the verts - // included in the triangle - for (; last != first; last = (last + 1) % num_vertices) { - auto ftri = triangle_exists(triangles, first, mid, last); + // find any other that can be wound from this edge + // TODO: can optimize by only looping around the verts + // included in the triangle + for (; last != first; last = (last + 1) % num_vertices) { + auto ftri = triangle_exists(triangles, first, mid, last); - // no triangle found for A B C, so try again - // with A B D, etc. - if (ftri == std::nullopt) { - continue; - } + // no triangle found for A B C, so try again + // with A B D, etc. + if (ftri == std::nullopt) { + continue; + } - // found A B C, so go next (A C D) - my_tri.push_back(ftri.value()); - mid = last; - } + // found A B C, so go next (A C D) + my_tri.push_back(ftri.value()); + mid = last; + } - if (best_triangles.empty() || my_tri.size() > best_triangles.size()) { - best_triangles = std::move(my_tri); - } - } - } + if (best_triangles.empty() || my_tri.size() > best_triangles.size()) { + best_triangles = std::move(my_tri); + } + } + } - return best_triangles; + return best_triangles; } // find the seed vertex (vertex referenced by the most edges) of // the fan. size_t find_seed_vertex(const std::vector &triangles, const std::vector &fan) { - std::unordered_set verts{triangles[fan[0]].begin(), triangles[fan[0]].end()}; + std::unordered_set verts{triangles[fan[0]].begin(), triangles[fan[0]].end()}; - for (size_t i = 1; i < fan.size(); i++) - { - auto &tri = triangles[fan[i]]; + for (size_t i = 1; i < fan.size(); i++) { + auto &tri = triangles[fan[i]]; - // produce intersection - for (auto it = verts.begin(); it != verts.end(); ) { - if (std::find(tri.begin(), tri.end(), *it) == tri.end()) { - it = verts.erase(it); - } else { - it++; - } - } + // produce intersection + for (auto it = verts.begin(); it != verts.end();) { + if (std::find(tri.begin(), tri.end(), *it) == tri.end()) { + it = verts.erase(it); + } else { + it++; + } + } - // if there's only one vert left it has to be that one - if (verts.size() == 1) { - return *verts.begin(); - } - } + // if there's only one vert left it has to be that one + if (verts.size() == 1) { + return *verts.begin(); + } + } - // just pick whatever's left - return *verts.begin(); + // just pick whatever's left + return *verts.begin(); } -static std::list> compress_triangles_into_fans(std::vector &triangles, const std::vector &vertices) +static std::list> compress_triangles_into_fans( + std::vector &triangles, const std::vector &vertices) { - std::list> tris_compiled; + std::list> tris_compiled; - while (triangles.size()) { - auto fan = find_best_fan(triangles, vertices.size()); + while (triangles.size()) { + auto fan = find_best_fan(triangles, vertices.size()); - Q_assert(fan.size()); + Q_assert(fan.size()); - // when we run into only 1 triangle fans left, - // just add the rest directly. - if (fan.size() == 1) { - for (auto &tri : triangles) { - tris_compiled.emplace_back(std::vector{ vertices[tri[0]], vertices[tri[1]], vertices[tri[2]] }); - } + // when we run into only 1 triangle fans left, + // just add the rest directly. + if (fan.size() == 1) { + for (auto &tri : triangles) { + tris_compiled.emplace_back(std::vector{vertices[tri[0]], vertices[tri[1]], vertices[tri[2]]}); + } - triangles.clear(); - break; - } + triangles.clear(); + break; + } - // a fan can be made! find the seed vertex - auto seed = find_seed_vertex(triangles, fan); + // a fan can be made! find the seed vertex + auto seed = find_seed_vertex(triangles, fan); - struct tri_verts_less_pred - { - size_t seed, vert_count; + struct tri_verts_less_pred + { + size_t seed, vert_count; - bool operator()(const size_t &a, const size_t &b) const - { - size_t ka = a < seed ? vert_count + a : a; - size_t kb = b < seed ? vert_count + b : b; + bool operator()(const size_t &a, const size_t &b) const + { + size_t ka = a < seed ? vert_count + a : a; + size_t kb = b < seed ? vert_count + b : b; - return ka < kb; - } - }; + return ka < kb; + } + }; - // add all the verts and order them so they match - // the proper winding - std::set verts(tri_verts_less_pred { seed, vertices.size() }); + // add all the verts and order them so they match + // the proper winding + std::set verts(tri_verts_less_pred{seed, vertices.size()}); - for (auto tri_index : fan) { - auto &tri = triangles[tri_index]; + for (auto tri_index : fan) { + auto &tri = triangles[tri_index]; - for (auto &v : tri) { - verts.insert(v); - } - } + for (auto &v : tri) { + verts.insert(v); + } + } - Q_assert(verts.size() >= 3); + Q_assert(verts.size() >= 3); - // add the new winding - auto &out_tri = tris_compiled.emplace_back(verts.begin(), verts.end()); + // add the new winding + auto &out_tri = tris_compiled.emplace_back(verts.begin(), verts.end()); - for (auto &v : out_tri) { - v = vertices[v]; - } + for (auto &v : out_tri) { + v = vertices[v]; + } - // remove all of the fans from the triangle list - std::sort(fan.begin(), fan.end(), [](auto &l, auto &r) { return l > r; }); + // remove all of the fans from the triangle list + std::sort(fan.begin(), fan.end(), [](auto &l, auto &r) { return l > r; }); - for (auto tri_index : fan) { - triangles.erase(triangles.begin() + tri_index); - } - } - - return tris_compiled; + for (auto tri_index : fan) { + triangles.erase(triangles.begin() + tri_index); + } + } + + return tris_compiled; } #include // Function to calculate the weight of optimal triangulation of a convex polygon // represented by a given set of vertices -std::vector minimum_weight_triangulation(const std::vector &indices, const std::vector &vertices) +std::vector minimum_weight_triangulation( + const std::vector &indices, const std::vector &vertices) { // get the number of vertices in the polygon size_t n = vertices.size(); - + // create a table for storing the solutions to subproblems // `T[i][j]` stores the weight of the minimum-weight triangulation // of the polygon below edge `ij` std::vector T(n * n); - std::vector> K(n * n); - + std::vector> K(n * n); + // fill the table diagonally using the recurrence relation for (size_t diagonal = 0; diagonal < n; diagonal++) { for (size_t i = 0, j = diagonal; j < n; i++, j++) { @@ -455,87 +461,87 @@ std::vector minimum_weight_triangulation(const std::vector &ind if (j < i + 2) { continue; } - + T[i + (j * n)] = std::numeric_limits::max(); - + // consider all possible triangles `ikj` within the polygon for (size_t k = i + 1; k <= j - 1; k++) { // The weight of triangulation is the length of its perimeter vec_t weight; - - if (!TriangleIsValid(indices[i], indices[j], indices[k], 0.01)) { - weight = std::nexttoward(std::numeric_limits::max(), 0.0); - } else { - weight = (qv::distance(vertices[i], vertices[j]) + - qv::distance(vertices[j], vertices[k]) + - qv::distance(vertices[k], vertices[i])) - + T[i + (k * n)] + T[k + (j * n)]; - } - vec_t &t_weight = T[i + (j * n)]; - + + if (!TriangleIsValid(indices[i], indices[j], indices[k], 0.01)) { + weight = std::nexttoward(std::numeric_limits::max(), 0.0); + } else { + weight = (qv::distance(vertices[i], vertices[j]) + qv::distance(vertices[j], vertices[k]) + + qv::distance(vertices[k], vertices[i])) + + T[i + (k * n)] + T[k + (j * n)]; + } + vec_t &t_weight = T[i + (j * n)]; + // choose vertex `k` that leads to the minimum total weight - if (weight < t_weight) { - t_weight = weight; - K[i + (j * n)] = k; - } + if (weight < t_weight) { + t_weight = weight; + K[i + (j * n)] = k; + } } } } - std::vector triangles; - std::queue> edge_queue; - edge_queue.emplace(0, n - 1); + std::vector triangles; + std::queue> edge_queue; + edge_queue.emplace(0, n - 1); - while (!edge_queue.empty()) { - auto edge = edge_queue.front(); - edge_queue.pop(); + while (!edge_queue.empty()) { + auto edge = edge_queue.front(); + edge_queue.pop(); - if (edge[0] == edge[1]) { - continue; - } - - auto &c = K[edge[0] + (edge[1] * n)]; - - if (!c.has_value()) { - continue; - } + if (edge[0] == edge[1]) { + continue; + } - qvectri tri { edge[0], edge[1], c.value() }; - std::sort(tri.begin(), tri.end()); - triangles.emplace_back(tri); + auto &c = K[edge[0] + (edge[1] * n)]; - edge_queue.emplace(edge[0], c.value()); - edge_queue.emplace(c.value(), edge[1]); - } + if (!c.has_value()) { + continue; + } - Q_assert(triangles.size() == n - 2); + qvectri tri{edge[0], edge[1], c.value()}; + std::sort(tri.begin(), tri.end()); + triangles.emplace_back(tri); - return triangles; + edge_queue.emplace(edge[0], c.value()); + edge_queue.emplace(c.value(), edge[1]); + } + + Q_assert(triangles.size() == n - 2); + + return triangles; } -static std::list> mwt_face(const face_t *f, const std::vector &vertices, tjunc_stats_t &stats) +static std::list> mwt_face( + const face_t *f, const std::vector &vertices, tjunc_stats_t &stats) { - auto p = f->plane; + auto p = f->plane; - if (f->plane_flipped) { - p = -p; - } + if (f->plane_flipped) { + p = -p; + } - auto [ u, v ] = qv::MakeTangentAndBitangentUnnormalized(p.normal); - qv::normalizeInPlace(u); - qv::normalizeInPlace(v); + auto [u, v] = qv::MakeTangentAndBitangentUnnormalized(p.normal); + qv::normalizeInPlace(u); + qv::normalizeInPlace(v); - std::vector points_2d(vertices.size()); + std::vector points_2d(vertices.size()); - for (size_t i = 0; i < vertices.size(); i++) { - points_2d[i] = { qv::dot(map.bsp.dvertexes[vertices[i]], u), qv::dot(map.bsp.dvertexes[vertices[i]], v) }; - } + for (size_t i = 0; i < vertices.size(); i++) { + points_2d[i] = {qv::dot(map.bsp.dvertexes[vertices[i]], u), qv::dot(map.bsp.dvertexes[vertices[i]], v)}; + } - auto tris = minimum_weight_triangulation(vertices, points_2d); + auto tris = minimum_weight_triangulation(vertices, points_2d); - stats.trimwt += tris.size(); + stats.trimwt += tris.size(); - return compress_triangles_into_fans(tris, vertices); + return compress_triangles_into_fans(tris, vertices); } /* @@ -549,151 +555,153 @@ can split it into several triangle fans. */ static std::list> RetopologizeFace(const face_t *f, const std::vector &vertices) { - std::list> result; - // the copy we're working on - std::vector input(vertices); + std::list> result; + // the copy we're working on + std::vector input(vertices); - while (input.size()) { - // failure if we somehow degenerated a triangle - if (input.size() < 3) { - return {}; - } + while (input.size()) { + // failure if we somehow degenerated a triangle + if (input.size() < 3) { + return {}; + } - size_t seed = 0; - int64_t end = 0; + size_t seed = 0; + int64_t end = 0; - // find seed triangle (allowing a wrap around, - // because it's possible for only the last two triangles - // to be valid). - for (; seed < input.size(); seed++) { - auto v0 = input[seed]; - auto v1 = input[(seed + 1) % input.size()]; - end = (seed + 2) % input.size(); - auto v2 = input[end]; + // find seed triangle (allowing a wrap around, + // because it's possible for only the last two triangles + // to be valid). + for (; seed < input.size(); seed++) { + auto v0 = input[seed]; + auto v1 = input[(seed + 1) % input.size()]; + end = (seed + 2) % input.size(); + auto v2 = input[end]; - if (!TriangleIsValid(v0, v1, v2, 0.01)) { - continue; - } + if (!TriangleIsValid(v0, v1, v2, 0.01)) { + continue; + } - // if the next point lays on the edge of v0-v2, this next - // triangle won't be valid. - float len; - qvec3d dir = qv::normalize(map.bsp.dvertexes[v0] - map.bsp.dvertexes[v2], len); - auto dist = PointOnEdge(map.bsp.dvertexes[input[(end + 1) % input.size()]], map.bsp.dvertexes[v2], dir, 0, len); - - if (dist.has_value()) { - continue; - } + // if the next point lays on the edge of v0-v2, this next + // triangle won't be valid. + float len; + qvec3d dir = qv::normalize(map.bsp.dvertexes[v0] - map.bsp.dvertexes[v2], len); + auto dist = + PointOnEdge(map.bsp.dvertexes[input[(end + 1) % input.size()]], map.bsp.dvertexes[v2], dir, 0, len); - // good one! - break; - } + if (dist.has_value()) { + continue; + } - if (seed == input.size()) { - // can't find a non-zero area triangle; failure - return {}; - } + // good one! + break; + } - // from the seed vertex, keep winding until we hit a zero-area triangle. - // we know that triangle (seed, end - 1, end) is valid, so we wind from - // end + 1 until we fully wrap around. We also can't include a triangle - // that has a point after it laying on the final edge. - size_t wrap = end; - end = (end + 1) % input.size(); + if (seed == input.size()) { + // can't find a non-zero area triangle; failure + return {}; + } - for (; end != wrap; end = (end + 1) % input.size()) { - auto v0 = input[seed]; - auto v1 = input[(end - 1) < 0 ? (input.size() - 1) : (end - 1)]; - auto v2 = input[end]; + // from the seed vertex, keep winding until we hit a zero-area triangle. + // we know that triangle (seed, end - 1, end) is valid, so we wind from + // end + 1 until we fully wrap around. We also can't include a triangle + // that has a point after it laying on the final edge. + size_t wrap = end; + end = (end + 1) % input.size(); - // if the next point lays on the edge of v0-v2, this next - // triangle won't be valid. - float len; - qvec3d dir = qv::normalize(map.bsp.dvertexes[v0] - map.bsp.dvertexes[v2], len); - auto dist = PointOnEdge(map.bsp.dvertexes[input[(end + 1) % input.size()]], map.bsp.dvertexes[v2], dir, 0, len); + for (; end != wrap; end = (end + 1) % input.size()) { + auto v0 = input[seed]; + auto v1 = input[(end - 1) < 0 ? (input.size() - 1) : (end - 1)]; + auto v2 = input[end]; - if (dist.has_value()) { - // the next point lays on this edge, so back up and stop - end = (end - 1) < 0 ? input.size() - 1 : (end - 1); - break; - } - } + // if the next point lays on the edge of v0-v2, this next + // triangle won't be valid. + float len; + qvec3d dir = qv::normalize(map.bsp.dvertexes[v0] - map.bsp.dvertexes[v2], len); + auto dist = + PointOnEdge(map.bsp.dvertexes[input[(end + 1) % input.size()]], map.bsp.dvertexes[v2], dir, 0, len); - // now we have a fan from seed to end that is valid. - // add it to the result, clip off all of the - // points between it and restart the algorithm - // using that edge. - auto &tri = result.emplace_back(); + if (dist.has_value()) { + // the next point lays on this edge, so back up and stop + end = (end - 1) < 0 ? input.size() - 1 : (end - 1); + break; + } + } - // the whole fan can just be moved; we're finished. - if (seed == end) { - tri = std::move(input); - break; - } else if (end == wrap) { - // we successfully wrapped around, but the - // seed vertex isn't at the start, so rotate it. - // copy base -> end - tri.resize(input.size()); - auto out = std::copy(input.begin() + seed, input.end(), tri.begin()); - // copy end -> base - std::copy(input.begin(), input.begin() + seed, out); - break; - } - - if (end < seed) { - // the end point is 'behind' the seed, so we're clipping - // off two sides of the input - size_t x = seed; - bool first = true; + // now we have a fan from seed to end that is valid. + // add it to the result, clip off all of the + // points between it and restart the algorithm + // using that edge. + auto &tri = result.emplace_back(); - while (true) { - if (x == end && !first) { - break; - } + // the whole fan can just be moved; we're finished. + if (seed == end) { + tri = std::move(input); + break; + } else if (end == wrap) { + // we successfully wrapped around, but the + // seed vertex isn't at the start, so rotate it. + // copy base -> end + tri.resize(input.size()); + auto out = std::copy(input.begin() + seed, input.end(), tri.begin()); + // copy end -> base + std::copy(input.begin(), input.begin() + seed, out); + break; + } - tri.emplace_back(input[x]); - x = (x + 1) % input.size(); - first = false; - } - } else { - // simple case where the end point is ahead of the seed; - // copy the range over to the output - std::copy(input.begin() + seed, input.begin() + end + 1, std::back_inserter(tri)); - } + if (end < seed) { + // the end point is 'behind' the seed, so we're clipping + // off two sides of the input + size_t x = seed; + bool first = true; - Q_assert(seed != end); + while (true) { + if (x == end && !first) { + break; + } - if (end < seed) { - // slightly more complex case: the end point is behind the seed point. - // 0 end 2 3 seed 5 6 - // end 2 3 seed - // calculate new size - size_t new_size = (seed + 1) - end; + tri.emplace_back(input[x]); + x = (x + 1) % input.size(); + first = false; + } + } else { + // simple case where the end point is ahead of the seed; + // copy the range over to the output + std::copy(input.begin() + seed, input.begin() + end + 1, std::back_inserter(tri)); + } - // move back the end to the start - std::copy(input.begin() + end, input.begin() + seed + 1, input.begin()); - - // clip - input.resize(new_size); - } else { - // simple case: the end point is ahead of the seed point. - // collapse the range after it backwards over top of the seed - // and clip it off - // 0 1 2 seed 4 5 6 end 8 9 - // 0 1 2 seed end 8 9 - // calculate new size - size_t new_size = input.size() - (end - seed - 1); + Q_assert(seed != end); - // move range - std::copy(input.begin() + end, input.end(), input.begin() + seed + 1); - - // clip - input.resize(new_size); - } - } + if (end < seed) { + // slightly more complex case: the end point is behind the seed point. + // 0 end 2 3 seed 5 6 + // end 2 3 seed + // calculate new size + size_t new_size = (seed + 1) - end; - // finished - return result; + // move back the end to the start + std::copy(input.begin() + end, input.begin() + seed + 1, input.begin()); + + // clip + input.resize(new_size); + } else { + // simple case: the end point is ahead of the seed point. + // collapse the range after it backwards over top of the seed + // and clip it off + // 0 1 2 seed 4 5 6 end 8 9 + // 0 1 2 seed end 8 9 + // calculate new size + size_t new_size = input.size() - (end - seed - 1); + + // move range + std::copy(input.begin() + end, input.end(), input.begin() + seed + 1); + + // clip + input.resize(new_size); + } + } + + // finished + return result; } /* @@ -705,120 +713,120 @@ If the face has any T-junctions, fix them here. */ static void FixFaceEdges(node_t *headnode, face_t *f, tjunc_stats_t &stats) { - // we were asked not to bother fixing any of the faces. - if (qbsp_options.tjunc.value() == settings::tjunclevel_t::NONE) { - f->fragments.emplace_back(face_fragment_t { f->original_vertices }); - return; - } + // we were asked not to bother fixing any of the faces. + if (qbsp_options.tjunc.value() == settings::tjunclevel_t::NONE) { + f->fragments.emplace_back(face_fragment_t{f->original_vertices}); + return; + } - std::vector superface = CreateSuperFace(headnode, f, stats); + std::vector superface = CreateSuperFace(headnode, f, stats); - if (superface.size() < 3) { - // entire face collapsed - stats.facecollapse++; - return; - } else if (superface.size() == 3) { - // no need to adjust this either - f->fragments.emplace_back(face_fragment_t { f->original_vertices }); - return; - } + if (superface.size() < 3) { + // entire face collapsed + stats.facecollapse++; + return; + } else if (superface.size() == 3) { + // no need to adjust this either + f->fragments.emplace_back(face_fragment_t{f->original_vertices}); + return; + } - // faces with 4 or more vertices can be done better. - // temporary storage for result faces; stored as a list - // since a resize may steal references out from underneath us - // as the functions do their work. - std::list> faces; - - // do MWT first; it will generate optimal results for everything. - if (qbsp_options.tjunc.value() >= settings::tjunclevel_t::MWT) { - faces = mwt_face(f, superface, stats); + // faces with 4 or more vertices can be done better. + // temporary storage for result faces; stored as a list + // since a resize may steal references out from underneath us + // as the functions do their work. + std::list> faces; - if (faces.size()) { - stats.mwt++; - stats.facemwt += faces.size() - 1; - } - } - - // brute force rotating the start point until we find a valid winding - // that doesn't have any T-junctions - if (!faces.size() && qbsp_options.tjunc.value() >= settings::tjunclevel_t::ROTATE) { - size_t i = 0; + // do MWT first; it will generate optimal results for everything. + if (qbsp_options.tjunc.value() >= settings::tjunclevel_t::MWT) { + faces = mwt_face(f, superface, stats); - for (; i < superface.size(); i++) { - size_t x = 0; + if (faces.size()) { + stats.mwt++; + stats.facemwt += faces.size() - 1; + } + } - // try vertex i as the base, see if we find any zero-area triangles - for (; x < superface.size() - 2; x++) { - auto v0 = superface[i]; - auto v1 = superface[(i + x + 1) % superface.size()]; - auto v2 = superface[(i + x + 2) % superface.size()]; + // brute force rotating the start point until we find a valid winding + // that doesn't have any T-junctions + if (!faces.size() && qbsp_options.tjunc.value() >= settings::tjunclevel_t::ROTATE) { + size_t i = 0; - if (!TriangleIsValid(v0, v1, v2, 0.01)) { - break; - } - } + for (; i < superface.size(); i++) { + size_t x = 0; - if (x == superface.size() - 2) { - // found one! - break; - } - } + // try vertex i as the base, see if we find any zero-area triangles + for (; x < superface.size() - 2; x++) { + auto v0 = superface[i]; + auto v1 = superface[(i + x + 1) % superface.size()]; + auto v2 = superface[(i + x + 2) % superface.size()]; - if (i == superface.size()) { - // can't simply rotate to eliminate zero-area triangles, so we have - // to do a bit of re-topology. - if (qbsp_options.tjunc.value() >= settings::tjunclevel_t::RETOPOLOGIZE) { - if (auto retopology = RetopologizeFace(f, superface); retopology.size() > 1) { - stats.retopology++; - stats.faceretopology += retopology.size() - 1; - faces = std::move(retopology); - } - } + if (!TriangleIsValid(v0, v1, v2, 0.01)) { + break; + } + } - if (!faces.size()) { - // unable to re-topologize, so just stick with the superface. - // it's got zero-area triangles that fill in the gaps. - stats.norotates++; - } - } else if (i != 0) { - // was able to rotate the superface to eliminate zero-area triangles. - stats.rotates++; + if (x == superface.size() - 2) { + // found one! + break; + } + } - auto &output = faces.emplace_back(superface.size()); - // copy base -> end - auto out = std::copy(superface.begin() + i, superface.end(), output.begin()); - // copy end -> base - std::copy(superface.begin(), superface.begin() + i, out); - } - } + if (i == superface.size()) { + // can't simply rotate to eliminate zero-area triangles, so we have + // to do a bit of re-topology. + if (qbsp_options.tjunc.value() >= settings::tjunclevel_t::RETOPOLOGIZE) { + if (auto retopology = RetopologizeFace(f, superface); retopology.size() > 1) { + stats.retopology++; + stats.faceretopology += retopology.size() - 1; + faces = std::move(retopology); + } + } - // the other techniques all failed, or we asked to not - // try them. just move the superface in directly. - if (!faces.size()) { - faces.emplace_back(std::move(superface)); - } + if (!faces.size()) { + // unable to re-topologize, so just stick with the superface. + // it's got zero-area triangles that fill in the gaps. + stats.norotates++; + } + } else if (i != 0) { + // was able to rotate the superface to eliminate zero-area triangles. + stats.rotates++; - Q_assert(faces.size()); + auto &output = faces.emplace_back(superface.size()); + // copy base -> end + auto out = std::copy(superface.begin() + i, superface.end(), output.begin()); + // copy end -> base + std::copy(superface.begin(), superface.begin() + i, out); + } + } - // split giant superfaces into subfaces if we have an edge limit. - if (qbsp_options.maxedges.value()) { - for (auto &face : faces) { - Q_assert(face.size() >= 3); - SplitFaceIntoFragments(face, faces, stats); - Q_assert(face.size() >= 3); - } - } + // the other techniques all failed, or we asked to not + // try them. just move the superface in directly. + if (!faces.size()) { + faces.emplace_back(std::move(superface)); + } - // move the results into the face - f->fragments.reserve(faces.size()); + Q_assert(faces.size()); - for (auto &face : faces) { - f->fragments.emplace_back(face_fragment_t { std::move(face) }); - } + // split giant superfaces into subfaces if we have an edge limit. + if (qbsp_options.maxedges.value()) { + for (auto &face : faces) { + Q_assert(face.size() >= 3); + SplitFaceIntoFragments(face, faces, stats); + Q_assert(face.size() >= 3); + } + } - for (auto &frag : f->fragments) { - Q_assert(frag.output_vertices.size() >= 3); - } + // move the results into the face + f->fragments.reserve(faces.size()); + + for (auto &face : faces) { + f->fragments.emplace_back(face_fragment_t{std::move(face)}); + } + + for (auto &frag : f->fragments) { + Q_assert(frag.output_vertices.size() >= 3); + } } #include @@ -830,17 +838,17 @@ FixEdges_r */ static void FindFaces_r(node_t *node, std::unordered_set &faces) { - if (node->is_leaf) { - return; - } + if (node->is_leaf) { + return; + } + + for (auto &f : node->facelist) { + // might have been omitted, so `original_vertices` will be empty + if (f->original_vertices.size()) { + faces.insert(f.get()); + } + } - for (auto &f : node->facelist) { - // might have been omitted, so `original_vertices` will be empty - if (f->original_vertices.size()) { - faces.insert(f.get()); - } - } - FindFaces_r(node->children[0].get(), faces); FindFaces_r(node->children[1].get(), faces); } @@ -855,38 +863,37 @@ void TJunc(node_t *headnode) logging::print(logging::flag::PROGRESS, "---- {} ----\n", __func__); tjunc_stats_t stats{}; - std::unordered_set faces; + std::unordered_set faces; - FindFaces_r(headnode, faces); - - logging::parallel_for_each(faces, [&](auto &face) { - FixFaceEdges(headnode, face, stats); - }); + FindFaces_r(headnode, faces); - if (stats.degenerate) { - logging::print (logging::flag::STAT, "{:5} edges degenerated\n", stats.degenerate); - } - if (stats.facecollapse) { - logging::print (logging::flag::STAT, "{:5} faces degenerated\n", stats.facecollapse); - } - if (stats.tjunctions) { - logging::print (logging::flag::STAT, "{:5} edges added by tjunctions\n", stats.tjunctions); - } - if (stats.mwt) { - logging::print (logging::flag::STAT, "{:5} faces ran through MWT\n", stats.mwt); - logging::print (logging::flag::STAT, "{:5} new faces added via MWT (from {} triangles)\n", stats.facemwt, stats.trimwt); - } - if (stats.retopology) { - logging::print (logging::flag::STAT, "{:5} faces re-topologized\n", stats.retopology); - logging::print (logging::flag::STAT, "{:5} new faces added by re-topology\n", stats.faceretopology); - } - if (stats.rotates) { - logging::print (logging::flag::STAT, "{:5} faces rotated\n", stats.rotates); - } - if (stats.norotates) { - logging::print (logging::flag::STAT, "{:5} faces unable to be rotated or re-topologized\n", stats.norotates); - } - if (stats.faceoverflows) { - logging::print (logging::flag::STAT, "{:5} faces added by splitting large faces\n", stats.faceoverflows); - } + logging::parallel_for_each(faces, [&](auto &face) { FixFaceEdges(headnode, face, stats); }); + + if (stats.degenerate) { + logging::print(logging::flag::STAT, "{:5} edges degenerated\n", stats.degenerate); + } + if (stats.facecollapse) { + logging::print(logging::flag::STAT, "{:5} faces degenerated\n", stats.facecollapse); + } + if (stats.tjunctions) { + logging::print(logging::flag::STAT, "{:5} edges added by tjunctions\n", stats.tjunctions); + } + if (stats.mwt) { + logging::print(logging::flag::STAT, "{:5} faces ran through MWT\n", stats.mwt); + logging::print( + logging::flag::STAT, "{:5} new faces added via MWT (from {} triangles)\n", stats.facemwt, stats.trimwt); + } + if (stats.retopology) { + logging::print(logging::flag::STAT, "{:5} faces re-topologized\n", stats.retopology); + logging::print(logging::flag::STAT, "{:5} new faces added by re-topology\n", stats.faceretopology); + } + if (stats.rotates) { + logging::print(logging::flag::STAT, "{:5} faces rotated\n", stats.rotates); + } + if (stats.norotates) { + logging::print(logging::flag::STAT, "{:5} faces unable to be rotated or re-topologized\n", stats.norotates); + } + if (stats.faceoverflows) { + logging::print(logging::flag::STAT, "{:5} faces added by splitting large faces\n", stats.faceoverflows); + } } diff --git a/qbsp/tree.cc b/qbsp/tree.cc index 1c01f8e9..c62bd1e8 100644 --- a/qbsp/tree.cc +++ b/qbsp/tree.cc @@ -62,9 +62,7 @@ void FreeTreePortals(tree_t *tree) static void ConvertNodeToLeaf(node_t *node, const contentflags_t &contents) { // merge the children's brush lists - node->original_brushes = concat( - node->children[0]->original_brushes, - node->children[1]->original_brushes); + node->original_brushes = concat(node->children[0]->original_brushes, node->children[1]->original_brushes); sort_and_remove_duplicates(node->original_brushes); node->is_leaf = true; diff --git a/qbsp/writebsp.cc b/qbsp/writebsp.cc index b64c662b..465c0414 100644 --- a/qbsp/writebsp.cc +++ b/qbsp/writebsp.cc @@ -257,7 +257,8 @@ static void ExportDrawNodes(node_t *node) for (size_t i = 0; i < 2; i++) { if (node->children[i]->is_leaf) { // In Q2, all leaves must have their own ID even if they share solidity. - if (qbsp_options.target_game->id != GAME_QUAKE_II && node->children[i]->contents.is_solid(qbsp_options.target_game)) { + if (qbsp_options.target_game->id != GAME_QUAKE_II && + node->children[i]->contents.is_solid(qbsp_options.target_game)) { dnode->children[i] = PLANENUM_LEAF; } else { int32_t nextLeafIndex = static_cast(map.bsp.dleafs.size()); @@ -316,8 +317,8 @@ void ExportDrawNodes(mapentity_t *entity, node_t *headnode, int firstface) // shrink the bounds in Q1 based games (Q1 engine compensates for this in Mod_LoadSubmodels) if (qbsp_options.target_game->id != GAME_QUAKE_II) { - dmodel.mins += qvec3d(1,1,1); - dmodel.maxs -= qvec3d(1,1,1); + dmodel.mins += qvec3d(1, 1, 1); + dmodel.maxs -= qvec3d(1, 1, 1); } } diff --git a/vis/flow.cc b/vis/flow.cc index 0c665128..a9a8a64f 100644 --- a/vis/flow.cc +++ b/vis/flow.cc @@ -30,8 +30,8 @@ static int c_leafskip; pointer, was measurably faster ============== */ -static void ClipToSeparators(const winding_t *source, const qplane3d src_pl, - const winding_t *pass, winding_t *&target, unsigned int test, pstack_t &stack) +static void ClipToSeparators(const winding_t *source, const qplane3d src_pl, const winding_t *pass, winding_t *&target, + unsigned int test, pstack_t &stack) { int i, j, k, l; qplane3d sep; @@ -144,7 +144,7 @@ static int CheckStack(leaf_t *leaf, threaddata_t *thread) */ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t &prevstack) { - pstack_t stack {}; + pstack_t stack{}; portal_t *p; qplane3d backplane; leaf_t *leaf; @@ -397,7 +397,7 @@ static void BasePortalThread(size_t portalnum) if (i == portalnum) { continue; } - + portal_t &tp = portals[i]; winding_t &tw = tp.winding; diff --git a/vis/main.cc b/vis/main.cc index b86aa2c0..91fc5f0f 100644 --- a/vis/main.cc +++ b/vis/main.cc @@ -24,7 +24,7 @@ int main(int argc, const char **argv) { try { return vis_main(argc, argv); - } catch (const settings::quit_after_help_exception&) { + } catch (const settings::quit_after_help_exception &) { return 0; } } diff --git a/vis/state.cc b/vis/state.cc index 15a2025c..038b9545 100644 --- a/vis/state.cc +++ b/vis/state.cc @@ -167,9 +167,9 @@ void SaveVisState(void) pstate.numcansee = p.numcansee; out <= pstate; - out.write((const char *) might.data(), might_len); + out.write((const char *)might.data(), might_len); if (vis_len) { - out.write((const char *) vis.data(), vis_len); + out.write((const char *)vis.data(), vis_len); } } @@ -252,7 +252,7 @@ bool LoadVisState(void) p.nummightsee = pstate.nummightsee; p.numcansee = pstate.numcansee; - in.read((char *) compressed.data(), pstate.might); + in.read((char *)compressed.data(), pstate.might); p.mightsee.resize(portalleafs); if (pstate.might < numbytes) { @@ -264,7 +264,7 @@ bool LoadVisState(void) p.visbits.resize(portalleafs); if (pstate.vis) { - in.read((char *) compressed.data(), pstate.vis); + in.read((char *)compressed.data(), pstate.vis); if (pstate.vis < numbytes) { DecompressBits(p.visbits, compressed.data()); } else { diff --git a/vis/vis.cc b/vis/vis.cc index 20c4b832..2c235b3f 100644 --- a/vis/vis.cc +++ b/vis/vis.cc @@ -394,8 +394,8 @@ void LeafThread(size_t) PortalCompleted(p); - logging::print(logging::flag::VERBOSE, "portal:{:4} mightsee:{:4} cansee:{:4}\n", (ptrdiff_t)(p - portals.data()), p->nummightsee, - p->numcansee); + logging::print(logging::flag::VERBOSE, "portal:{:4} mightsee:{:4} cansee:{:4}\n", (ptrdiff_t)(p - portals.data()), + p->nummightsee, p->numcansee); } /* @@ -537,10 +537,10 @@ void CalcPortalVis(const mbsp_t *bsp) SaveVisState(); - logging::print( - logging::flag::VERBOSE, "portalcheck: {} portaltest: {} portalpass: {}\n", c_portalcheck, c_portaltest, c_portalpass); - logging::print( - logging::flag::VERBOSE, "c_vistest: {} c_mighttest: {} c_mightseeupdate {}\n", c_vistest, c_mighttest, c_mightseeupdate); + logging::print(logging::flag::VERBOSE, "portalcheck: {} portaltest: {} portalpass: {}\n", c_portalcheck, + c_portaltest, c_portalpass); + logging::print(logging::flag::VERBOSE, "c_vistest: {} c_mighttest: {} c_mightseeupdate {}\n", c_vistest, + c_mighttest, c_mightseeupdate); } /* @@ -643,7 +643,8 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp) auto dest_portal_it = portals.begin(); - for (auto source_portal_it = prtfile.portals.begin(); source_portal_it != prtfile.portals.end(); source_portal_it++) { + for (auto source_portal_it = prtfile.portals.begin(); source_portal_it != prtfile.portals.end(); + source_portal_it++) { const auto &sourceportal = *source_portal_it; qplane3d plane; @@ -665,7 +666,7 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp) p.leaf = sourceportal.leafnums[1]; dest_portal_it++; } - + { auto &p = *dest_portal_it; // create backwards portal @@ -702,7 +703,9 @@ int vis_main(int argc, const char **argv) vis_options.run(argc, argv); - logging::init(fs::path(vis_options.sourceMap).replace_filename(vis_options.sourceMap.stem().string() + "-vis").replace_extension("log"), + logging::init(fs::path(vis_options.sourceMap) + .replace_filename(vis_options.sourceMap.stem().string() + "-vis") + .replace_extension("log"), vis_options); stateinterval = std::chrono::minutes(5); /* 5 minutes */ @@ -717,8 +720,7 @@ int vis_main(int argc, const char **argv) mbsp_t &bsp = std::get(bspdata.bsp); - if (vis_options.phsonly.value()) - { + if (vis_options.phsonly.value()) { if (bsp.loadversion->game->id != GAME_QUAKE_II) { FError("need a Q2-esque BSP for -phsonly"); } @@ -730,9 +732,7 @@ int vis_main(int argc, const char **argv) if (bsp.loadversion->game->id == GAME_QUAKE_II) { originalvismapsize = portalleafs * ((portalleafs + 7) / 8); } - } - else - { + } else { portalfile = fs::path(vis_options.sourceMap).replace_extension("prt"); LoadPortals(portalfile, &bsp);