clang-format pass

This commit is contained in:
Jonathan 2022-07-28 06:14:54 -04:00
parent e03d99d807
commit 1d8a0c1df3
72 changed files with 1722 additions and 1668 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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");

View File

@ -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<int32_t>(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<const content_stats_t &>(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<std::atomic<size_t>, 32> native_types;
// std::array<std::atomic<size_t>, 32> native_types;
std::unordered_map<int32_t, size_t> native_types;
std::atomic<size_t> total_brushes;
std::atomic<size_t> 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<char *>(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<uint8_t>(file_data->begin() + xlump.fileofs, file_data->begin() + xlump.fileofs + xlump.filelen));
bspdata->bspx.transfer(xlump.lumpname.data(), std::vector<uint8_t>(file_data->begin() + xlump.fileofs,
file_data->begin() + xlump.fileofs + xlump.filelen));
}
}
}

View File

@ -174,7 +174,11 @@ static std::string serialize_image(const std::optional<img::texture> &texture_op
auto &texture = texture_opt.value();
std::vector<uint8_t> buf;
stbi_write_png_to_func([](void *context, void *data, int size) { std::copy(reinterpret_cast<uint8_t *>(data), reinterpret_cast<uint8_t *>(data) + size, std::back_inserter(*reinterpret_cast<decltype(buf) *>(context))); },
stbi_write_png_to_func(
[](void *context, void *data, int size) {
std::copy(reinterpret_cast<uint8_t *>(data), reinterpret_cast<uint8_t *>(data) + size,
std::back_inserter(*reinterpret_cast<decltype(buf) *>(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<img::texture> &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<const char *>(bspx.at("LMSHIFT").data())[&face - bsp.dfaces.data()]) };
return {face, bsp,
(float)nth_bit(reinterpret_cast<const char *>(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());
}
}
}

View File

@ -322,8 +322,8 @@ static bool EdgePlanes_PointInside(const std::vector<qplane3d> &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<const mface_t *> &result)
static void BSP_FindFaceAtPoint_r(const mbsp_t *bsp, const int nodenum, const qvec3d &point, const qvec3d &wantedNormal,
std::vector<const mface_t *> &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<const mface_t *> 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<const mface_t*> Leaf_Markfaces(const mbsp_t* bsp, const mleaf_t* leaf)
std::vector<const mface_t *> Leaf_Markfaces(const mbsp_t *bsp, const mleaf_t *leaf)
{
std::vector<const mface_t *> result;
result.reserve(leaf->nummarksurfaces);
@ -487,7 +485,7 @@ std::vector<const mface_t*> Leaf_Markfaces(const mbsp_t* bsp, const mleaf_t* lea
return result;
}
std::vector<const dbrush_t*> Leaf_Brushes(const mbsp_t* bsp, const mleaf_t* leaf)
std::vector<const dbrush_t *> Leaf_Brushes(const mbsp_t *bsp, const mleaf_t *leaf)
{
std::vector<const dbrush_t *> 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++) {

View File

@ -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)

View File

@ -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<entdict_t> &vector)
{
parser_t parser(entdata);

View File

@ -140,7 +140,7 @@ struct wad_archive : archive_like
auto stream_data() { return std::tie(identification, numlumps, infotableofs); }
};
static constexpr std::array<char, 4> wad2_ident = {'W', 'A', 'D', '2'};
static constexpr std::array<char, 4> 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<archive_like> 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());
}
}

View File

@ -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<uint8_t> &pixels, std::vector<qvec4b> &output, const std::vector<qvec3b> &pal)
static void convert_paletted_to_32_bit(
const std::vector<uint8_t> &pixels, std::vector<qvec4b> &output, const std::vector<qvec3b> &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<texture> load_wal(const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game)
std::optional<texture> 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<std::endian::little>;
@ -160,7 +162,8 @@ Quake/Half Life MIP
============================================================================
*/
std::optional<texture> load_mip(const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game)
std::optional<texture> 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<std::endian::little>;
@ -178,7 +181,7 @@ std::optional<texture> 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<texture> 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<texture> load_tga(const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game)
std::optional<texture> 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<std::endian::little>;
@ -325,7 +329,8 @@ std::optional<texture> 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<texture> 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<texture> 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<qvec4b> &pixels)
return avg /= n;
}
std::tuple<std::optional<img::texture>, 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<std::optional<img::texture>, 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<std::optional<img::texture>, fs::resolve_result, fs::data> load_textu
"height": 64
}
*/
std::optional<texture_meta> load_wal_json_meta(const std::string_view &name, const fs::data &file, const gamedef_t *game)
std::optional<texture_meta> 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<texture_meta> load_wal_json_meta(const std::string_view &name, con
meta.contents.native |= content.get<int32_t>();
} else if (content.is_string()) {
meta.contents.native |= game->contents_from_string(content.get<std::string>());
}
}
}
}
}
@ -539,7 +547,7 @@ std::optional<texture_meta> load_wal_json_meta(const std::string_view &name, con
meta.flags.native |= flag.get<int32_t>();
} else if (flag.is_string()) {
meta.flags.native |= game->surfflags_from_string(flag.get<std::string>());
}
}
}
}
}
@ -549,15 +557,14 @@ std::optional<texture_meta> 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<std::optional<img::texture_meta>, fs::resolve_result, fs::data> load_texture_meta(const std::string_view &name, const gamedef_t *game, const settings::common_settings &options)
std::tuple<std::optional<img::texture_meta>, 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;

View File

@ -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

View File

@ -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++;

View File

@ -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;
}

View File

@ -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) {

View File

@ -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<bool> &mirror_inside_value) { mirror_inside = mirror_inside_value; return *this; }
contentflags_t &set_mirrored(const std::optional<bool> &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<bool> &clips_same_type_value) { clips_same_type = clips_same_type_value; return *this; }
contentflags_t &set_clips_same_type(const std::optional<bool> &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<aabb3d> &get_hull_sizes() const = 0;
@ -356,7 +365,8 @@ struct fmt::formatter<bspversion_t>
// 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<uint8_t> &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<uint8_t> &&xdata)
{

View File

@ -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

View File

@ -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<dmodelq1_t>;
using dmodelh2_vector = std::vector<dmodelh2_t>;

View File

@ -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?)

View File

@ -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<const mface_t *> 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<const mface_t *> 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<std::vector<uint8_t>> 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

View File

@ -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

View File

@ -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(<strings.h>)
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(<strings.h>)
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<std::is_member_function_pointer_v<decltype(&T::stream_wr
}
template<typename T>
inline std::enable_if_t<std::is_enum_v<T>, std::ostream &> operator<=(
std::ostream &s, const T &obj)
inline std::enable_if_t<std::is_enum_v<T>, std::ostream &> operator<=(std::ostream &s, const T &obj)
{
s <= reinterpret_cast<const std::underlying_type_t<T> &>(obj);
return s;
@ -599,8 +598,7 @@ inline std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::stream_re
}
template<typename T>
inline std::enable_if_t<std::is_enum_v<T>, std::istream &> operator>=(
std::istream &s, T &obj)
inline std::enable_if_t<std::is_enum_v<T>, std::istream &> operator>=(std::istream &s, T &obj)
{
s >= reinterpret_cast<std::underlying_type_t<T> &>(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<std::streambuf *>(this)),
std::istream(static_cast<std::streambuf *>(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<std::streambuf *>(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<std::streambuf *>(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<std::streambuf *>(this))
{
}
@ -875,123 +877,107 @@ template<typename T, std::size_t Alignment>
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<std::size_t>(0) - static_cast<std::size_t>(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<std::size_t>(0) - static_cast<std::size_t>(1)) / sizeof(T);
}
// The following must be the same for all allocators.
template <typename U>
struct rebind
{
typedef aligned_allocator<U, Alignment> other;
};
bool operator!=(const aligned_allocator &other) const
{
return !(*this == other);
}
// The following must be the same for all allocators.
template<typename U>
struct rebind
{
typedef aligned_allocator<U, Alignment> other;
};
void construct(T *const p, const T &t) const
{
void *const pv = reinterpret_cast<void *>(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<void *>(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<typename U>
aligned_allocator(const aligned_allocator<U, Alignment> &) { }
~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<typename U>
aligned_allocator(const aligned_allocator<U, Alignment> &)
{
}
~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<T>::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<T>::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<T *>(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<T *>(pv);
}
// The following will be the same for all allocators that ignore hints.
template <typename U>
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<typename U>
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<typename T>

View File

@ -60,7 +60,7 @@ struct resolve_result
std::shared_ptr<archive_like> 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.

View File

@ -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<std::string, texture, case_insensitive_hash, case_insensitive_equal> textures;
@ -80,24 +80,29 @@ qvec3b calculate_average(const std::vector<qvec4b> &pixels);
const texture *find(const std::string_view &str);
// Load wal
std::optional<texture> load_wal(const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game);
std::optional<texture> load_wal(
const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game);
// Load TGA
std::optional<texture> load_tga(const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game);
std::optional<texture> 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<texture> load_mip(const std::string_view &name, const fs::data &file, bool meta_only, const gamedef_t *game);
std::optional<texture> 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<std::optional<texture>, 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<std::optional<texture>, 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<texture_meta> load_wal_meta(const std::string_view &name, const fs::data &file, const gamedef_t *game)
inline std::optional<texture_meta> 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<texture_meta> load_wal_meta(const std::string_view &name, c
return std::nullopt;
}
std::optional<texture_meta> load_wal_json_meta(const std::string_view &name, const fs::data &file, const gamedef_t *game);
std::optional<texture_meta> 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<std::optional<texture_meta>, fs::resolve_result, fs::data> load_texture_meta(const std::string_view &name, const gamedef_t *game, const settings::common_settings &options);
std::tuple<std::optional<texture_meta>, fs::resolve_result, fs::data> load_texture_meta(
const std::string_view &name, const gamedef_t *game, const settings::common_settings &options);
}; // namespace img

View File

@ -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<flag> 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 <common/parallel.h>'s parallel_for(_each)
void percent(uint64_t count, uint64_t max, bool displayElapsed = true);
};
}; // namespace logging

View File

@ -25,45 +25,45 @@
// parallel extensions to logging
namespace logging
{
template<typename TS, typename TE, typename Body>
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<typename TS, typename TE, typename Body>
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<typename Container, typename Body>
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<typename Container, typename Body>
void parallel_for_each(Container &container, const Body &func)
{
auto length = std::size(container);
std::atomic_uint64_t progress = 0;
template<typename Container, typename Body>
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);
}
}
percent(progress, length);
}
template<typename Container, typename Body>
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

View File

@ -64,16 +64,13 @@ public:
using iterator_category = std::random_access_iterator_tag;
using value_type = typename std::conditional_t<is_const, const qvec3d, qvec3d>;
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<qvec3d> l) : winding_base_t(l.begin(), l.end()) {}
inline winding_base_t(std::initializer_list<qvec3d> 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<Args>(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<qvec3f> glm_winding_points() const { return {begin(), end()}; }
std::vector<qvec3f> glm_winding_points() const
{
return {begin(), end()};
}
static inline winding_base_t from_winding_points(const std::vector<qvec3f> &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);
}
};

View File

@ -28,16 +28,19 @@ constexpr size_t PRT_MAX_WINDING_FIXED = 24;
using prtfile_winding_t = polylib::winding_base_t<PRT_MAX_WINDING_FIXED>;
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.

View File

@ -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<typename F>
[[nodiscard]] inline auto operator+(const qvec<F, N> &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<typename T>
inline qvec<T, 3> vec_from_mangle(const qvec<T, 3> &m)
@ -1182,4 +1234,4 @@ inline qvec<T, 3> vec_from_mangle(const qvec<T, 3> &m)
return {rotations * qvec3d(1, 0, 0)};
}
}
} // namespace qv

View File

@ -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<const setting_value<T> *>(&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<typename T>
class setting_numeric : public setting_value<T>
{
static_assert(!std::is_enum_v<T>, "use setting_enum for enums");
protected:
T _min, _max;
@ -375,10 +375,7 @@ public:
this->setting_value<T>::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\" <multiple allowed>", const setting_group *group = nullptr, const char *description = "")
: setting_base(dictionary, names, group, description),
_format(format)
const std::string_view &format = "\"str\" <multiple allowed>", const setting_group *group = nullptr,
const char *description = "")
: setting_base(dictionary, names, group, description), _format(format)
{
}
const std::unordered_set<std::string> &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<const setting_set *>(&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<bool(T &)> _validator;
public:
template<typename ...Args>
inline setting_validator(const decltype(_validator) &validator, Args&&... args) :
T(std::forward<Args>(args)...),
_validator(validator)
template<typename... Args>
inline setting_validator(const decltype(_validator) &validator, Args &&...args)
: T(std::forward<Args>(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<search_priority_t> 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\" <multiple allowed>", &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<search_priority_t> 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\" <multiple allowed>", &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);
}

View File

@ -23,8 +23,8 @@
#include <iterator>
#include <vector>
template <class T>
void sort_and_remove_duplicates(T& v)
template<class T>
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 <class E>
template<class E>
std::vector<E> concat(const std::vector<E> &a, const std::vector<E> &b)
{
std::vector<E> result;

View File

@ -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<vec_t>::max()};
settings::setting_enum<light_formula_t> 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<int32_t> style{this, "style", 0, 0, INVALID_LIGHTSTYLE - 1};

View File

@ -132,7 +132,7 @@ struct lightsurf_t
fully occluded. dirtgain/dirtscale are not applied yet
*/
std::vector<float> 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_t> 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_t> 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()
{

View File

@ -27,7 +27,7 @@ struct litheader_t
{
struct
{
std::array<char, 4> ident = { 'Q', 'L', 'I', 'T' };
std::array<char, 4> ident = {'Q', 'L', 'I', 'T'};
int version;
auto stream_data() { return std::tie(ident, version); }

View File

@ -52,11 +52,11 @@ std::unordered_map<int, qvec3f> 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<lightsurf_t> CreateLightmapSurface(const mbsp_t *bsp, const mface_t *face, const facesup_t *facesup, const settings::worldspawn_keys &cfg);
std::unique_ptr<lightsurf_t> 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);

View File

@ -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"

View File

@ -91,10 +91,7 @@ public:
return _ray_dynamic_styles[j];
}
inline void clearPushedRays()
{
_numrays = 0;
}
inline void clearPushedRays() { _numrays = 0; }
};
#include <embree3/rtcore.h>
@ -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
{

View File

@ -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<side_t> sides;
contentflags_t contents; /* BSP contents */
short lmshift; /* lightmap scaling (qu/lightmap pixel), passed to the light util */

View File

@ -33,7 +33,8 @@ struct face_t;
struct side_t;
std::unique_ptr<face_t> NewFaceFromFace(const face_t *in);
std::unique_ptr<face_t> CopyFace(const face_t* in);
std::tuple<std::unique_ptr<face_t>, std::unique_ptr<face_t>> SplitFace(std::unique_ptr<face_t> in, const qplane3d &split);
std::unique_ptr<face_t> CopyFace(const face_t *in);
std::tuple<std::unique_ptr<face_t>, std::unique_ptr<face_t>> SplitFace(
std::unique_ptr<face_t> in, const qplane3d &split);
void UpdateFaceSphere(face_t *in);
std::vector<std::unique_ptr<bspbrush_t>> MakeBspBrushList(mapentity_t *entity);

View File

@ -25,5 +25,5 @@
struct node_t;
void MakeMarkFaces(node_t* headnode);
void MakeMarkFaces(node_t *headnode);
void MakeFaces(node_t *node);

View File

@ -130,10 +130,7 @@ struct mapplane_t : qbsp_plane_t
{
std::optional<size_t> outputnum;
inline mapplane_t(const qbsp_plane_t &copy) :
qbsp_plane_t(copy)
{
}
inline mapplane_t(const qbsp_plane_t &copy) : qbsp_plane_t(copy) { }
};
struct mapdata_t
@ -154,7 +151,7 @@ struct mapdata_t
// hashed vertices; generated by EmitVertices
std::map<qvec3i, std::list<hashvert_t>> 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<std::pair<size_t, size_t>, 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<extended_texinfo_t> info;
};
int FindMiptex(const char *name, std::optional<extended_texinfo_t> &extended_info, bool internal = false, bool recursive = true);
int FindMiptex(
const char *name, std::optional<extended_texinfo_t> &extended_info, bool internal = false, bool recursive = true);
inline int FindMiptex(const char *name, bool internal = false, bool recursive = true)
{
std::optional<extended_texinfo_t> 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<face_t *> CSGFace(face_t *srcface, const mapentity_t* srcentity, const bspbrush_t *srcbrush, const node_t *srcnode);
std::list<face_t *> 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);

View File

@ -40,11 +40,13 @@ struct portal_t
std::optional<winding_t> 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<int> 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);

View File

@ -104,7 +104,8 @@ public:
constexpr const std::set<wadpath> &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<const setting_wadpathset *>(&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\" <multiple allowed>", &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\" <multiple allowed>", &map_development_group, "path to a texture definition file, which can transform textures in the .map into other textures."};
setting_numeric<vec_t> 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_t> 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\" <multiple allowed>", &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\" <multiple allowed>", &map_development_group,
"path to a texture definition file, which can transform textures in the .map into other textures."};
setting_numeric<vec_t> 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_t> 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<setting_int32> 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<typename T>
[[nodiscard]] inline T distance_to(const qvec<T, 3> &pt) const { return plane.distance_to(pt); }
[[nodiscard]] inline T distance_to(const qvec<T, 3> &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<int32_t>(p1.get_type())] != p2.get_normal()[static_cast<int32_t>(p2.get_type())]) {
} else if (p1.get_normal()[static_cast<int32_t>(p1.get_type())] !=
p2.get_normal()[static_cast<int32_t>(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<std::unique_ptr<node_t>> children; // children[0] = front side, children[1] = back side of plane. only valid for decision nodes
twosided<std::unique_ptr<node_t>>
children; // children[0] = front side, children[1] = back side of plane. only valid for decision nodes
std::list<std::unique_ptr<face_t>> 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<std::string>& args);
void InitQBSP(const std::vector<std::string> &args);
void ProcessFile();
int qbsp_main(int argc, const char **argv);

View File

@ -26,7 +26,7 @@
class leafbits_t
{
size_t _size = 0;
std::unique_ptr<uint32_t[]> bits {};
std::unique_ptr<uint32_t[]> bits{};
constexpr size_t block_size() const { return (_size + mask) >> shift; }
inline std::unique_ptr<uint32_t[]> allocate() { return std::make_unique<uint32_t[]>(block_size()); }
@ -40,13 +40,13 @@ public:
inline leafbits_t(size_t size) : _size(size), bits(allocate()) { }
inline leafbits_t(const leafbits_t &copy) : 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 &copy) : 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;

View File

@ -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;

View File

@ -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<int, qvec3d> &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<int, qvec3d> &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());
}

View File

@ -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<light_t> DuplicateEntity(const light_t &src)
* From q3map2
* =============
*/
static void JitterEntity(const light_t& entity)
static void JitterEntity(const light_t &entity)
{
std::vector<std::unique_ptr<light_t>> 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 */

View File

@ -38,7 +38,7 @@
#include <common/imglib.hh>
#include <common/parallel.hh>
#if defined(HAVE_EMBREE) && defined (__SSE2__)
#if defined(HAVE_EMBREE) && defined(__SSE2__)
#include <xmmintrin.h>
//#include <pmmintrin.h>
#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<size_t>(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<size_t>(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()) {

View File

@ -54,13 +54,12 @@ void WriteLitFile(const mbsp_t *bsp, const std::vector<facesup_t> &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 <fstream>
@ -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);
}

View File

@ -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<uint8_t> &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<uint8_t> &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; j<pvssize; j++) {
for (int j = 0; j < pvssize; j++) {
lightsurf->pvs[j] |= pointpvs[j];
}
}
}
static std::unique_ptr<lightsurf_t> 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_t> 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_t> 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_t> 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<uint8_t> &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<qvec3d> 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<std::vector<qvec4f>> 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<lightsurf_t> CreateLightmapSurface(const mbsp_t *bsp, const mface_t *face, const facesup_t *facesup, const settings::worldspawn_keys &cfg)
std::unique_ptr<lightsurf_t> 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

View File

@ -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;
}
}

View File

@ -366,9 +366,7 @@ static edgeToFaceMap_t MakeEdgeToFaceMap(const mbsp_t *bsp)
static vector<face_normal_t> Face_VertexNormals(const mbsp_t *bsp, const mface_t *face)
{
vector<face_normal_t> 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;
}

View File

@ -51,7 +51,8 @@ std::vector<surfacelight_t> &GetSurfaceLights()
return surfacelights;
}
static void MakeSurfaceLight(const mbsp_t *bsp, const settings::worldspawn_keys &cfg, const mface_t *face, std::optional<qvec3f> 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<qvec3f> 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<qvec3f> 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<size_t>(0), bsp->dfaces.size(), [&](size_t i) { MakeSurfaceLightsThread(bsp, cfg, i); });
logging::parallel_for(
static_cast<size_t>(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);
}
}

View File

@ -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 {};

View File

@ -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...

View File

@ -28,7 +28,7 @@
#include <qbsp/map.hh>
#include <qbsp/qbsp.hh>
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;
}
}

View File

@ -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<content_stats_base_t> leafstats;
// total number of nodes, includes c_nonvis
std::atomic<int> c_nodes;
@ -102,8 +103,7 @@ std::unique_ptr<bspbrush_t> BrushFromBounds(const aabb3d &bounds)
auto b = std::make_unique<bspbrush_t>();
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<std::unique_ptr<bspbrush_t>>
//============================================================
/*
==================
BrushMostlyOnSide
@ -449,7 +446,7 @@ https://github.com/id-Software/Quake-2-Tools/blob/master/bsp/qbsp3/brushbsp.c#L9
static twosided<std::unique_ptr<bspbrush_t>> SplitBrush(std::unique_ptr<bspbrush_t> brush, const qplane3d &split)
{
twosided<std::unique_ptr<bspbrush_t>> result;
// check all points
vec_t d_front = 0;
vec_t d_back = 0;
@ -529,7 +526,7 @@ static twosided<std::unique_ptr<bspbrush_t>> SplitBrush(std::unique_ptr<bspbrush
// add the clipped face to result[j]
side_t faceCopy = face;
faceCopy.w = *cw[j];
// fixme-brushbsp: configure any settings on the faceCopy?
// Q2 does `cs->tested = false;`, why?
@ -574,9 +571,9 @@ static twosided<std::unique_ptr<bspbrush_t>> SplitBrush(std::unique_ptr<bspbrush
// add the midwinding to both sides
for (int i = 0; i < 2; i++) {
side_t cs{};
const bool brushOnFront = (i == 0);
// for the brush on the front side of the plane, the `midwinding`
// (the face that is touching the plane) should have a normal opposite the plane's normal
cs.plane_flipped = cs.plane.set_plane(brushOnFront ? -split : split, true);
@ -634,9 +631,9 @@ to partition the brushes with.
Returns NULL if there are no valid planes to split with..
================
*/
side_t *SelectSplitSide(const std::vector<std::unique_ptr<bspbrush_t>>& brushes, node_t *node)
side_t *SelectSplitSide(const std::vector<std::unique_ptr<bspbrush_t>> &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<std::unique_ptr<bspbrush_t>>& 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<std::unique_ptr<bspbrush_t>>& 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<std::unique_ptr<bspbrush_t>>& 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<std::unique_ptr<bspbrush_t>>& 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<std::unique_ptr<bspbrush_t>>& brushes,
SplitBrushList
================
*/
static std::array<std::vector<std::unique_ptr<bspbrush_t>>, 2> SplitBrushList(std::vector<std::unique_ptr<bspbrush_t>> brushes, const node_t *node)
static std::array<std::vector<std::unique_ptr<bspbrush_t>>, 2> SplitBrushList(
std::vector<std::unique_ptr<bspbrush_t>> brushes, const node_t *node)
{
std::array<std::vector<std::unique_ptr<bspbrush_t>>, 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<std::unique_ptr<bspbrush_t>> brushes, bspstats_t& stats)
static void BuildTree_r(node_t *node, std::vector<std::unique_ptr<bspbrush_t>> brushes, bspstats_t &stats)
{
// find the best plane to use as a splitter
auto *bestside = const_cast<side_t *>(SelectSplitSide(brushes, node));
@ -836,13 +832,12 @@ static void BuildTree_r(node_t *node, std::vector<std::unique_ptr<bspbrush_t>> 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<node_t>();
newnode->parent = node;
}
@ -872,21 +867,18 @@ static std::unique_ptr<tree_t> BrushBSP(mapentity_t *entity, std::vector<std::un
size_t c_faces = 0;
size_t c_nonvisfaces = 0;
size_t c_brushes = 0;
for (const auto &b : brushlist)
{
for (const auto &b : brushlist) {
c_brushes++;
double volume = BrushVolume(*b);
if (volume < qbsp_options.microvolume.value())
{
if (volume < qbsp_options.microvolume.value()) {
logging::print("WARNING: microbrush\n");
// fixme-brushbsp: add entitynum, brushnum in mapbrush_t
// printf ("WARNING: entity %i, brush %i: microbrush\n",
// b->original->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<tree_t> BrushBSP(mapentity_t *entity, std::vector<std::un
*/
auto headnode = std::make_unique<node_t>();
headnode->bounds = entity->bounds;
headnode->plane = { { 0, 0, 1 }, 0 };
headnode->plane = {{0, 0, 1}, 0};
headnode->children[0] = std::make_unique<node_t>();
headnode->children[0]->is_leaf = true;
headnode->children[0]->contents = qbsp_options.target_game->create_empty_contents();

View File

@ -63,7 +63,7 @@ std::unique_ptr<face_t> NewFaceFromFace(const face_t *in)
return newf;
}
std::unique_ptr<face_t> CopyFace(const face_t* in)
std::unique_ptr<face_t> 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<face_t>, std::unique_ptr<face_t>> SplitFace(std::unique_ptr<face_t> in, const qplane3d &split)
std::tuple<std::unique_ptr<face_t>, std::unique_ptr<face_t>> SplitFace(
std::unique_ptr<face_t> in, const qplane3d &split)
{
if (in->w.size() < 0)
Error("Attempting to split freed face");

View File

@ -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<const face
WriteContentsMaterial(mtlfile, {CONTENTS_SKY}, 0.8, 0.8, 1.0);
// fixme-brushbsp
//WriteContentsMaterial(mtlfile, {CONTENTS_SOLID, CFLAGS_CLIP}, 1, 0.8, 0.8);
//WriteContentsMaterial(mtlfile, {CONTENTS_EMPTY, CFLAGS_HINT}, 1, 1, 1);
// WriteContentsMaterial(mtlfile, {CONTENTS_SOLID, CFLAGS_CLIP}, 1, 0.8, 0.8);
// WriteContentsMaterial(mtlfile, {CONTENTS_EMPTY, CFLAGS_HINT}, 1, 1, 1);
//WriteContentsMaterial(mtlfile, {CONTENTS_SOLID, CFLAGS_DETAIL}, 0.5, 0.5, 0.5);
// WriteContentsMaterial(mtlfile, {CONTENTS_SOLID, CFLAGS_DETAIL}, 0.5, 0.5, 0.5);
int vertcount = 0;
for (const face_t *face : faces) {
@ -121,9 +121,7 @@ void ExportObj_Faces(const std::string &filesuffix, const std::vector<const face
}
}
void ExportObj_Brushes(const std::string &filesuffix, const std::vector<const bspbrush_t *> &brushes)
{
}
void ExportObj_Brushes(const std::string &filesuffix, const std::vector<const bspbrush_t *> &brushes) { }
static void ExportObj_Nodes_r(const node_t *node, std::vector<const face_t *> *dest)
{

View File

@ -31,8 +31,9 @@
#include <map>
#include <list>
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<int>(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<std::unique_ptr<face_t>> SubdivideFace(std::unique_ptr<face_t>
std::unique_ptr<face_t> 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<face_t> 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<face_t>();
@ -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);
}

View File

@ -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;
}
}

View File

@ -54,12 +54,13 @@ const std::optional<img::texture_meta> &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_texinfo_t> &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<img::texture_meta> &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<img::texture_meta> &texture,
const texvecf &in_vecs, const std::array<qvec3d, 3> &facepoints)
static texdef_quake_ed_t TexDef_BSPToQuakeEd(const qbsp_plane_t &faceplane,
const std::optional<img::texture_meta> &texture, const texvecf &in_vecs, const std::array<qvec3d, 3> &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<vec_t, 2> 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<bspbrush_t> hull1brush = LoadBrush(
src, mapbrush, {CONTENTS_SOLID}, {}, rotation_t::none,
std::optional<bspbrush_t> 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<bspbrush_t>(std::move(*hull1brush)));
hull1brushes.emplace_back(std::make_unique<bspbrush_t>(std::move(*hull1brush)));
}
}

View File

@ -68,7 +68,8 @@ static std::unique_ptr<face_t> 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;

View File

@ -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<node_t *>& result)
static void FindOccupiedClusters_R(node_t *node, std::vector<node_t *> &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<portal_t *> 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__);

View File

@ -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<winding_t> BaseWindingForNode(node_t *node)
{
std::optional<winding_t> 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__);

View File

@ -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<extended_texinfo_t> 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>(logging::flag::PERCENT) | logging::flag::STAT | logging::flag::PROGRESS)) == logging::flag::NONE) {
if ((logging::mask & (bitflags<logging::flag>(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>(logging::flag::STAT) | logging::flag::PROGRESS | logging::flag::PERCENT);
logging::mask &=
~(bitflags<logging::flag>(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>(logging::flag::STAT) | logging::flag::PROGRESS | logging::flag::PERCENT);
logging::mask &=
~(bitflags<logging::flag>(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>(logging::flag::STAT) | logging::flag::PROGRESS | logging::flag::PERCENT);
logging::mask |=
(bitflags<logging::flag>(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>(logging::flag::STAT) | logging::flag::PROGRESS | logging::flag::PERCENT);
logging::mask &=
~(bitflags<logging::flag>(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<std::string>& args)
void InitQBSP(const std::vector<std::string> &args)
{
std::vector<const char *> argPtrs;
for (const std::string &arg : args) {

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -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<int32_t>(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);
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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 {

View File

@ -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<mbsp_t>(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);