Merge remote-tracking branch 'remotes/origin/qbsp-contentflags' into type-cleanup
# Conflicts: # bspinfo/bspinfo.cc # common/bspfile.cc # include/common/bspfile.hh # qbsp/brush.cc # qbsp/csg4.cc # qbsp/portals.cc # qbsp/qbsp.cc # qbsp/solidbsp.cc # qbsp/surfaces.cc # qbsp/writebsp.cc # vis/vis.cc
This commit is contained in:
commit
7590230111
|
|
@ -192,6 +192,33 @@ static void serialize_bsp(const bspdata_t &bspdata, const mbsp_t &bsp, const std
|
|||
}
|
||||
}
|
||||
|
||||
if (bsp.numfaces) {
|
||||
json &faces = (j.emplace("faces", json::array())).first.value();
|
||||
|
||||
for (int32_t i = 0; i < bsp.numfaces; i++) {
|
||||
json &face = faces.insert(faces.end(), json::object()).value();
|
||||
auto &src_face = bsp.dfaces[i];
|
||||
|
||||
face.push_back({ "planenum", src_face.planenum });
|
||||
face.push_back({ "side", src_face.side });
|
||||
face.push_back({ "firstedge", src_face.firstedge });
|
||||
face.push_back({ "numedges", src_face.numedges });
|
||||
face.push_back({ "texinfo", src_face.texinfo });
|
||||
face.push_back({ "styles", json::array({ src_face.styles[0], src_face.styles[1], src_face.styles[2], src_face.styles[3] }) });
|
||||
face.push_back({ "lightofs", src_face.lightofs });
|
||||
|
||||
// for readibility, also output the actual vertices
|
||||
auto verts = json::array();
|
||||
for (int32_t k = 0; k < src_face.numedges; ++k) {
|
||||
auto se = bsp.dsurfedges[src_face.firstedge + k];
|
||||
uint32_t v = (se < 0) ? bsp.dedges[-se].v[1] : bsp.dedges[se].v[0];
|
||||
auto dv = bsp.dvertexes[v];
|
||||
verts.push_back(json::array({ dv.point[0], dv.point[1], dv.point[2] }));
|
||||
}
|
||||
face.push_back({ "vertices", verts });
|
||||
}
|
||||
}
|
||||
|
||||
if (!bsp.dclipnodes.empty()) {
|
||||
json &clipnodes = (j.emplace("clipnodes", json::array())).first.value();
|
||||
|
||||
|
|
@ -203,6 +230,32 @@ static void serialize_bsp(const bspdata_t &bspdata, const mbsp_t &bsp, const std
|
|||
}
|
||||
}
|
||||
|
||||
if (bsp.numedges) {
|
||||
json &edges = (j.emplace("edges", json::array())).first.value();
|
||||
|
||||
for (int32_t i = 0; i < bsp.numedges; i++) {
|
||||
auto &src_edge = bsp.dedges[i];
|
||||
|
||||
edges.insert(edges.end(), json::array({src_edge.v[0], src_edge.v[1]}));
|
||||
}
|
||||
}
|
||||
|
||||
if (bsp.numleaffaces) {
|
||||
json &leaffaces = (j.emplace("leaffaces", json::array())).first.value();
|
||||
|
||||
for (int32_t i = 0; i < bsp.numleaffaces; i++) {
|
||||
leaffaces.insert(leaffaces.end(), bsp.dleaffaces[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (bsp.numsurfedges) {
|
||||
json &surfedges = (j.emplace("surfedges", json::array())).first.value();
|
||||
|
||||
for (int32_t i = 0; i < bsp.numsurfedges; i++) {
|
||||
surfedges.insert(surfedges.end(), bsp.dsurfedges[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!bsp.dbrushsides.empty()) {
|
||||
json &brushsides = (j.emplace("brushsides", json::array())).first.value();
|
||||
|
||||
|
|
|
|||
|
|
@ -195,13 +195,25 @@ struct gamedef_generic_t : public gamedef_t
|
|||
|
||||
bool surf_is_subdivided(const surfflags_t &) const { throw std::bad_cast(); }
|
||||
|
||||
contentflags_t cluster_contents(const contentflags_t &, const contentflags_t &) const { throw std::bad_cast(); }
|
||||
surfflags_t surf_remap_for_export(const surfflags_t& flags) const {
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
contentflags_t cluster_contents(const contentflags_t &, const contentflags_t &) const {
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
int32_t get_content_type(const contentflags_t &) const { throw std::bad_cast(); }
|
||||
|
||||
int32_t contents_priority(const contentflags_t &) const { throw std::bad_cast(); }
|
||||
|
||||
contentflags_t create_empty_contents(const int32_t &) const { throw std::bad_cast(); }
|
||||
contentflags_t create_extended_contents(const int32_t&) const {
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
contentflags_t create_empty_contents(const int32_t &) const {
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
contentflags_t create_solid_contents(const int32_t &) const { throw std::bad_cast(); }
|
||||
|
||||
|
|
@ -209,7 +221,21 @@ struct gamedef_generic_t : public gamedef_t
|
|||
|
||||
contentflags_t create_liquid_contents(const int32_t &, const int32_t &) const { throw std::bad_cast(); }
|
||||
|
||||
bool contents_are_liquid(const contentflags_t &) const { throw std::bad_cast(); }
|
||||
bool contents_are_empty(const contentflags_t& contents) const {
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
bool contents_are_solid(const contentflags_t& contents) const {
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
bool contents_are_sky(const contentflags_t& contents) const {
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
bool contents_are_liquid(const contentflags_t &) const {
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
bool contents_are_valid(const contentflags_t &, bool) const { throw std::bad_cast(); }
|
||||
|
||||
|
|
@ -234,28 +260,31 @@ struct gamedef_q1_like_t : public gamedef_t
|
|||
|
||||
bool surf_is_subdivided(const surfflags_t &flags) const { return !(flags.native & TEX_SPECIAL); }
|
||||
|
||||
contentflags_t cluster_contents(const contentflags_t &contents0, const contentflags_t &contents1) const
|
||||
{
|
||||
surfflags_t surf_remap_for_export(const surfflags_t& flags) const {
|
||||
auto remapped = flags;
|
||||
remapped.native &= TEX_SPECIAL;
|
||||
return remapped;
|
||||
}
|
||||
|
||||
contentflags_t cluster_contents(const contentflags_t &contents0, const contentflags_t &contents1) const {
|
||||
if (contents0 == contents1)
|
||||
return contents0;
|
||||
|
||||
const int32_t merged_flags = contents0.extended | contents1.extended;
|
||||
|
||||
/*
|
||||
* Clusters may be partially solid but still be seen into
|
||||
* ?? - Should we do something more explicit with mixed liquid contents?
|
||||
*/
|
||||
if (contents0.native == CONTENTS_EMPTY || contents1.native == CONTENTS_EMPTY)
|
||||
return create_empty_contents(merged_flags);
|
||||
return create_empty_contents();
|
||||
|
||||
if (contents0.native >= CONTENTS_LAVA && contents0.native <= CONTENTS_WATER)
|
||||
return create_liquid_contents(contents0.native, merged_flags);
|
||||
return create_liquid_contents(contents0.native);
|
||||
if (contents1.native >= CONTENTS_LAVA && contents1.native <= CONTENTS_WATER)
|
||||
return create_liquid_contents(contents1.native, merged_flags);
|
||||
return create_liquid_contents(contents1.native);
|
||||
if (contents0.native == CONTENTS_SKY || contents1.native == CONTENTS_SKY)
|
||||
return create_sky_contents(merged_flags);
|
||||
return create_sky_contents();
|
||||
|
||||
return create_solid_contents(merged_flags);
|
||||
return create_solid_contents();
|
||||
}
|
||||
|
||||
int32_t get_content_type(const contentflags_t &contents) const { return contents.native; }
|
||||
|
|
@ -264,10 +293,10 @@ struct gamedef_q1_like_t : public gamedef_t
|
|||
{
|
||||
if (contents.extended & CFLAGS_DETAIL) {
|
||||
return 5;
|
||||
} else if (contents.extended & CFLAGS_DETAIL_ILLUSIONARY) {
|
||||
return 3;
|
||||
} else if (contents.extended & CFLAGS_DETAIL_FENCE) {
|
||||
return 4;
|
||||
} else if (contents.extended & CFLAGS_DETAIL_ILLUSIONARY) {
|
||||
return 3;
|
||||
} else if (contents.extended & CFLAGS_ILLUSIONARY_VISBLOCKER) {
|
||||
return 2;
|
||||
} else {
|
||||
|
|
@ -286,16 +315,32 @@ struct gamedef_q1_like_t : public gamedef_t
|
|||
default: FError("Bad contents in face"); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
contentflags_t create_extended_contents(const int32_t &cflags) const {
|
||||
return { 0, cflags };
|
||||
}
|
||||
|
||||
contentflags_t create_empty_contents(const int32_t &cflags) const { return {CONTENTS_EMPTY, cflags}; }
|
||||
contentflags_t create_empty_contents(const int32_t &cflags = 0) const {
|
||||
Q_assert(!(cflags & CFLAGS_CONTENTS_MASK));
|
||||
|
||||
contentflags_t create_solid_contents(const int32_t &cflags) const { return {CONTENTS_SOLID, cflags}; }
|
||||
return { CONTENTS_EMPTY, cflags };
|
||||
}
|
||||
|
||||
contentflags_t create_sky_contents(const int32_t &cflags) const { return {CONTENTS_SKY, cflags}; }
|
||||
contentflags_t create_solid_contents(const int32_t &cflags = 0) const {
|
||||
Q_assert(!(cflags & CFLAGS_CONTENTS_MASK));
|
||||
|
||||
return { CONTENTS_SOLID, cflags };
|
||||
}
|
||||
|
||||
contentflags_t create_sky_contents(const int32_t &cflags = 0) const {
|
||||
Q_assert(!(cflags & CFLAGS_CONTENTS_MASK));
|
||||
|
||||
return { CONTENTS_SKY, cflags };
|
||||
}
|
||||
|
||||
contentflags_t create_liquid_contents(const int32_t &liquid_type, const int32_t &cflags = 0) const {
|
||||
Q_assert(!(cflags & CFLAGS_CONTENTS_MASK));
|
||||
|
||||
contentflags_t create_liquid_contents(const int32_t &liquid_type, const int32_t &cflags) const
|
||||
{
|
||||
return {liquid_type, cflags};
|
||||
}
|
||||
|
||||
|
|
@ -304,12 +349,28 @@ struct gamedef_q1_like_t : public gamedef_t
|
|||
return contents.native <= CONTENTS_WATER && contents.native >= CONTENTS_LAVA;
|
||||
}
|
||||
|
||||
bool contents_are_valid(const contentflags_t &contents, bool strict) const { return contents.native <= 0; }
|
||||
bool contents_are_valid(const contentflags_t &contents, bool strict) const {
|
||||
if (!contents.native && !strict) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool portal_can_see_through(const contentflags_t &contents0, const contentflags_t &contents1) const
|
||||
{
|
||||
switch (contents.native) {
|
||||
case CONTENTS_EMPTY:
|
||||
case CONTENTS_SOLID:
|
||||
case CONTENTS_WATER:
|
||||
case CONTENTS_SLIME:
|
||||
case CONTENTS_LAVA:
|
||||
case CONTENTS_SKY:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool portal_can_see_through(const contentflags_t &contents0, const contentflags_t &contents1) const {
|
||||
/* If contents values are the same and not solid, can see through */
|
||||
return !(contents0.is_structural_solid(this) || contents1.is_structural_solid(this)) && contents0 == contents1;
|
||||
return !(contents0.is_solid(this) || contents1.is_solid(this)) &&
|
||||
contents0 == contents1;
|
||||
}
|
||||
|
||||
std::string get_contents_display(const contentflags_t &contents) const
|
||||
|
|
@ -394,8 +455,13 @@ struct gamedef_q2_t : public gamedef_t
|
|||
|
||||
bool surf_is_subdivided(const surfflags_t &flags) const { return !(flags.native & (Q2_SURF_WARP | Q2_SURF_SKY)); }
|
||||
|
||||
contentflags_t cluster_contents(const contentflags_t &contents0, const contentflags_t &contents1) const
|
||||
{
|
||||
surfflags_t surf_remap_for_export(const surfflags_t& flags) const {
|
||||
auto remapped = flags;
|
||||
// TODO: strip any illegal flags off remapped.native
|
||||
return remapped;
|
||||
}
|
||||
|
||||
contentflags_t cluster_contents(const contentflags_t &contents0, const contentflags_t &contents1) const {
|
||||
contentflags_t c = {contents0.native | contents1.native, contents0.extended | contents1.extended};
|
||||
|
||||
// a cluster may include some solid detail areas, but
|
||||
|
|
@ -435,7 +501,13 @@ struct gamedef_q2_t : public gamedef_t
|
|||
}
|
||||
}
|
||||
|
||||
contentflags_t create_empty_contents(const int32_t &cflags) const { return {0, cflags}; }
|
||||
contentflags_t create_extended_contents(const int32_t &cflags) const {
|
||||
return { 0, cflags };
|
||||
}
|
||||
|
||||
contentflags_t create_empty_contents(const int32_t &cflags) const {
|
||||
return { 0, cflags };
|
||||
}
|
||||
|
||||
contentflags_t create_solid_contents(const int32_t &cflags) const { return {Q2_CONTENTS_SOLID, cflags}; }
|
||||
|
||||
|
|
@ -558,7 +630,7 @@ const bspversion_t bspver_qbism{Q2_QBISMIDENT, Q2_BSPVERSION, "qbism", "Quake II
|
|||
|
||||
bool contentflags_t::types_equal(const contentflags_t &other, const gamedef_t *game) const
|
||||
{
|
||||
return (extended & CFLAGS_DETAIL_MASK) == (other.extended & CFLAGS_DETAIL_MASK) &&
|
||||
return (extended & CFLAGS_CONTENTS_MASK) == (other.extended & CFLAGS_CONTENTS_MASK) &&
|
||||
game->get_content_type(*this) == game->get_content_type(other);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -564,6 +564,8 @@ struct dplane_t
|
|||
#define CFLAGS_ILLUSIONARY_VISBLOCKER (1 << 11)
|
||||
// all of the detail values
|
||||
#define CFLAGS_DETAIL_MASK (CFLAGS_DETAIL | CFLAGS_DETAIL_ILLUSIONARY | CFLAGS_DETAIL_FENCE)
|
||||
// all of the special content types
|
||||
#define CFLAGS_CONTENTS_MASK (CFLAGS_HINT | CFLAGS_CLIP | CFLAGS_ORIGIN | CFLAGS_DETAIL_MASK | CFLAGS_ILLUSIONARY_VISBLOCKER)
|
||||
|
||||
struct gamedef_t;
|
||||
|
||||
|
|
@ -575,13 +577,6 @@ struct contentflags_t
|
|||
// extra flags, specific to BSP only
|
||||
int32_t extended;
|
||||
|
||||
// merge these content flags with other, and use
|
||||
// their native contents.
|
||||
constexpr contentflags_t merge(const contentflags_t &other) const
|
||||
{
|
||||
return {other.native, extended | other.extended};
|
||||
}
|
||||
|
||||
constexpr bool operator==(const contentflags_t &other) const
|
||||
{
|
||||
return native == other.native && extended == other.extended;
|
||||
|
|
@ -596,25 +591,30 @@ struct contentflags_t
|
|||
}
|
||||
|
||||
bool is_empty(const gamedef_t *game) const;
|
||||
|
||||
// solid, not detail or any other extended content types
|
||||
bool is_solid(const gamedef_t *game) const;
|
||||
bool is_sky(const gamedef_t *game) const;
|
||||
bool is_liquid(const gamedef_t *game) const;
|
||||
bool is_valid(const gamedef_t *game, bool strict = true) const;
|
||||
|
||||
bool is_structural_solid(const gamedef_t *game) const { return is_solid(game) && !is_detail(); }
|
||||
|
||||
bool is_structural_sky(const gamedef_t *game) const { return is_sky(game) && !is_detail(); }
|
||||
|
||||
bool is_structural_sky_or_solid(const gamedef_t *game) const
|
||||
{
|
||||
return (is_sky(game) || is_solid(game)) && !is_detail();
|
||||
constexpr bool is_hint() const {
|
||||
return extended & CFLAGS_HINT;
|
||||
}
|
||||
|
||||
constexpr bool is_hint() const { return extended & CFLAGS_HINT; }
|
||||
constexpr bool is_clip() const {
|
||||
return extended & CFLAGS_CLIP;
|
||||
}
|
||||
|
||||
constexpr bool is_origin() const {
|
||||
return extended & CFLAGS_ORIGIN;
|
||||
}
|
||||
|
||||
constexpr bool clips_same_type() const { return !(extended & CFLAGS_NO_CLIPPING_SAME_TYPE); }
|
||||
|
||||
constexpr bool is_fence() const { return is_detail(CFLAGS_DETAIL_FENCE | CFLAGS_DETAIL_ILLUSIONARY); }
|
||||
constexpr bool is_fence() const {
|
||||
return (extended & (CFLAGS_DETAIL_FENCE | CFLAGS_DETAIL_ILLUSIONARY)) != 0;
|
||||
}
|
||||
|
||||
// check if this content's `type` - which is distinct from various
|
||||
// flags that turn things on/off - match. Exactly what the native
|
||||
|
|
@ -1911,9 +1911,11 @@ struct gamedef_t
|
|||
|
||||
virtual bool surf_is_lightmapped(const surfflags_t &flags) const = 0;
|
||||
virtual bool surf_is_subdivided(const surfflags_t &flags) const = 0;
|
||||
virtual surfflags_t surf_remap_for_export(const surfflags_t &flags) const = 0;
|
||||
virtual contentflags_t cluster_contents(const contentflags_t &contents0, const contentflags_t &contents1) const = 0;
|
||||
virtual int32_t get_content_type(const contentflags_t &contents) const = 0;
|
||||
virtual int32_t contents_priority(const contentflags_t &contents) const = 0;
|
||||
virtual contentflags_t create_extended_contents(const int32_t &cflags = 0) const = 0;
|
||||
virtual contentflags_t create_empty_contents(const int32_t &cflags = 0) const = 0;
|
||||
virtual contentflags_t create_solid_contents(const int32_t &cflags = 0) const = 0;
|
||||
virtual contentflags_t create_sky_contents(const int32_t &cflags = 0) const = 0;
|
||||
|
|
|
|||
134
qbsp/brush.cc
134
qbsp/brush.cc
|
|
@ -765,36 +765,10 @@ static bool Brush_IsDetail(const mapbrush_t *mapbrush)
|
|||
return false;
|
||||
}
|
||||
|
||||
// adjust the given content flags from the texture name input.
|
||||
// this is where special names are transformed into game-specific
|
||||
// contents.
|
||||
static bool AdjustContentsFromName(const char *texname, contentflags_t &flags)
|
||||
{
|
||||
if (!Q_strcasecmp(texname, "origin"))
|
||||
flags = flags.merge(options.target_game->create_empty_contents(CFLAGS_ORIGIN));
|
||||
else if (!Q_strcasecmp(texname, "hint"))
|
||||
flags = flags.merge(options.target_game->create_empty_contents(CFLAGS_HINT));
|
||||
else if (!Q_strcasecmp(texname, "clip"))
|
||||
flags = flags.merge(options.target_game->create_solid_contents(CFLAGS_CLIP));
|
||||
else if (texname[0] == '*') {
|
||||
if (!Q_strncasecmp(texname + 1, "lava", 4))
|
||||
flags = flags.merge(options.target_game->create_liquid_contents(CONTENTS_LAVA));
|
||||
else if (!Q_strncasecmp(texname + 1, "slime", 5))
|
||||
flags = flags.merge(options.target_game->create_liquid_contents(CONTENTS_SLIME));
|
||||
else
|
||||
flags = flags.merge(options.target_game->create_liquid_contents(CONTENTS_WATER));
|
||||
} else if (!Q_strncasecmp(texname, "sky", 3))
|
||||
flags = flags.merge(options.target_game->create_sky_contents());
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static contentflags_t Brush_GetContents_Q1(const mapbrush_t *mapbrush, const contentflags_t &base_contents)
|
||||
static contentflags_t
|
||||
Brush_GetContents_Q1(const mapbrush_t *mapbrush)
|
||||
{
|
||||
const char *texname;
|
||||
contentflags_t contents = base_contents;
|
||||
|
||||
// check for strong content indicators
|
||||
for (int i = 0; i < mapbrush->numfaces; i++) {
|
||||
|
|
@ -802,20 +776,34 @@ static contentflags_t Brush_GetContents_Q1(const mapbrush_t *mapbrush, const con
|
|||
const mtexinfo_t &texinfo = map.mtexinfos.at(mapface.texinfo);
|
||||
texname = map.miptexTextureName(texinfo.miptex).c_str();
|
||||
|
||||
if (AdjustContentsFromName(texname, contents)) {
|
||||
return contents;
|
||||
if (!Q_strcasecmp(texname, "origin"))
|
||||
return options.target_game->create_extended_contents(CFLAGS_ORIGIN);
|
||||
else if (!Q_strcasecmp(texname, "hint"))
|
||||
return options.target_game->create_extended_contents(CFLAGS_HINT);
|
||||
else if (!Q_strcasecmp(texname, "clip"))
|
||||
return options.target_game->create_extended_contents(CFLAGS_CLIP);
|
||||
else if (texname[0] == '*') {
|
||||
if (!Q_strncasecmp(texname + 1, "lava", 4))
|
||||
return options.target_game->create_liquid_contents(CONTENTS_LAVA);
|
||||
else if (!Q_strncasecmp(texname + 1, "slime", 5))
|
||||
return options.target_game->create_liquid_contents(CONTENTS_SLIME);
|
||||
else
|
||||
return options.target_game->create_liquid_contents(CONTENTS_WATER);
|
||||
}
|
||||
else if (!Q_strncasecmp(texname, "sky", 3))
|
||||
return options.target_game->create_sky_contents();
|
||||
}
|
||||
|
||||
// and anything else is assumed to be a regular solid.
|
||||
return contents.merge(options.target_game->create_solid_contents());
|
||||
return options.target_game->create_solid_contents();
|
||||
}
|
||||
|
||||
static contentflags_t Brush_GetContents_Q2(const mapbrush_t *mapbrush, const contentflags_t &base_contents)
|
||||
static contentflags_t
|
||||
Brush_GetContents_Q2 (const mapbrush_t *mapbrush)
|
||||
{
|
||||
bool is_trans = false;
|
||||
bool is_hint = false;
|
||||
contentflags_t contents = base_contents.merge({mapbrush->face(0).contents});
|
||||
contentflags_t contents = { mapbrush->face(0).contents };
|
||||
|
||||
for (int i = 0; i < mapbrush->numfaces; i++) {
|
||||
const mapface_t &mapface = mapbrush->face(i);
|
||||
|
|
@ -1058,21 +1046,13 @@ void Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnu
|
|||
/* Origin brush support */
|
||||
rotation_t rottype = rotation_t::none;
|
||||
|
||||
const bool func_illusionary_visblocker = (0 == Q_strcasecmp(classname, "func_illusionary_visblocker"));
|
||||
|
||||
contentflags_t base_contents = options.target_game->create_empty_contents();
|
||||
|
||||
if (func_illusionary_visblocker) {
|
||||
base_contents.extended |= CFLAGS_ILLUSIONARY_VISBLOCKER;
|
||||
}
|
||||
|
||||
// TODO: move to game
|
||||
auto Brush_GetContents = (options.target_game->id == GAME_QUAKE_II) ? Brush_GetContents_Q2 : Brush_GetContents_Q1;
|
||||
|
||||
for (int i = 0; i < src->nummapbrushes; i++) {
|
||||
const mapbrush_t *mapbrush = &src->mapbrush(i);
|
||||
const contentflags_t contents = Brush_GetContents(mapbrush, base_contents);
|
||||
if (contents.extended & CFLAGS_ORIGIN) {
|
||||
const contentflags_t contents = Brush_GetContents(mapbrush);
|
||||
if (contents.is_origin()) {
|
||||
if (dst == pWorldEnt()) {
|
||||
LogPrint("WARNING: Ignoring origin brush in worldspawn\n");
|
||||
continue;
|
||||
|
|
@ -1127,18 +1107,17 @@ void Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnu
|
|||
}
|
||||
|
||||
/* _mirrorinside key (for func_water etc.) */
|
||||
if (atoi(ValueForKey(src, "_mirrorinside"))) {
|
||||
base_contents.extended |= CFLAGS_BMODEL_MIRROR_INSIDE;
|
||||
}
|
||||
const bool mirrorinside = !!atoi(ValueForKey(src, "_mirrorinside"));
|
||||
|
||||
/* _noclipfaces */
|
||||
if (atoi(ValueForKey(src, "_noclipfaces"))) {
|
||||
base_contents.extended |= CFLAGS_NO_CLIPPING_SAME_TYPE;
|
||||
}
|
||||
const bool noclipfaces = !!atoi(ValueForKey(src, "_noclipfaces"));
|
||||
|
||||
const bool func_illusionary_visblocker =
|
||||
(0 == Q_strcasecmp(classname, "func_illusionary_visblocker"));
|
||||
|
||||
for (i = 0; i < src->nummapbrushes; i++, mapbrush++) {
|
||||
mapbrush = &src->mapbrush(i);
|
||||
contentflags_t contents = Brush_GetContents(mapbrush, base_contents);
|
||||
contentflags_t contents = Brush_GetContents(mapbrush);
|
||||
|
||||
// per-brush settings
|
||||
bool detail = Brush_IsDetail(mapbrush);
|
||||
|
|
@ -1151,7 +1130,7 @@ void Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnu
|
|||
detail_fence |= all_detail_fence;
|
||||
|
||||
/* "origin" brushes always discarded */
|
||||
if (contents.extended & CFLAGS_ORIGIN)
|
||||
if (contents.is_origin())
|
||||
continue;
|
||||
|
||||
/* -omitdetail option omits all types of detail */
|
||||
|
|
@ -1165,12 +1144,11 @@ void Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnu
|
|||
/* turn solid brushes into detail, if we're in hull0 */
|
||||
if (hullnum <= 0 && contents.is_solid(options.target_game)) {
|
||||
if (detail) {
|
||||
contents.extended |= CFLAGS_DETAIL;
|
||||
contents = options.target_game->create_extended_contents(CFLAGS_DETAIL);
|
||||
} else if (detail_illusionary) {
|
||||
contents = contents.merge(options.target_game->create_empty_contents(CFLAGS_DETAIL_ILLUSIONARY));
|
||||
contents = options.target_game->create_extended_contents(CFLAGS_DETAIL_ILLUSIONARY);
|
||||
} else if (detail_fence) {
|
||||
contents = contents.merge(
|
||||
options.target_game->create_empty_contents(CFLAGS_DETAIL_FENCE)); // fences need to generate leaves
|
||||
contents = options.target_game->create_extended_contents(CFLAGS_DETAIL_FENCE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1185,7 +1163,7 @@ void Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnu
|
|||
* include them in the model bounds so collision detection works
|
||||
* correctly.
|
||||
*/
|
||||
if (contents.extended & CFLAGS_CLIP) {
|
||||
if (contents.is_clip()) {
|
||||
if (hullnum == 0) {
|
||||
brush_t *brush = LoadBrush(src, mapbrush, contents, rotate_offset, rottype, hullnum);
|
||||
if (brush) {
|
||||
|
|
@ -1196,8 +1174,7 @@ void Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnu
|
|||
}
|
||||
// for hull1, 2, etc., convert clip to CONTENTS_SOLID
|
||||
if (hullnum > 0) {
|
||||
contents = contents.merge(options.target_game->create_solid_contents());
|
||||
contents.extended &= ~CFLAGS_CLIP;
|
||||
contents = options.target_game->create_solid_contents();
|
||||
}
|
||||
// if hullnum is -1 (bspx brush export), leave it as CONTENTS_CLIP
|
||||
}
|
||||
|
|
@ -1206,16 +1183,12 @@ void Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnu
|
|||
if (contents.is_hint()) {
|
||||
if (hullnum > 0)
|
||||
continue;
|
||||
contents = contents.merge(options.target_game->create_empty_contents());
|
||||
contents = options.target_game->create_empty_contents();
|
||||
}
|
||||
|
||||
/* entities never use water merging */
|
||||
if (dst != pWorldEnt()) {
|
||||
// FIXME: the old code here was just `contents = CONTENTS_SOLID`.
|
||||
// which would also clear CONTENTS_CLIP. Now CONTENTS_CLIP is an extended flag
|
||||
// so we need to unset it explicitly.
|
||||
contents = contents.merge(options.target_game->create_solid_contents());
|
||||
contents.extended &= ~CFLAGS_CLIP;
|
||||
contents = options.target_game->create_solid_contents();
|
||||
}
|
||||
|
||||
/* Hack to turn bmodels with "_mirrorinside" into func_detail_fence in hull 0.
|
||||
|
|
@ -1226,19 +1199,28 @@ void Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnu
|
|||
before writing the bsp, and bmodels normally have CONTENTS_SOLID as their
|
||||
contents type.
|
||||
*/
|
||||
if (dst != pWorldEnt() && hullnum <= 0 && (contents.extended & CFLAGS_BMODEL_MIRROR_INSIDE)) {
|
||||
contents = contents.merge(options.target_game->create_empty_contents(CFLAGS_DETAIL_FENCE));
|
||||
if (dst != pWorldEnt() && hullnum <= 0 && mirrorinside) {
|
||||
contents = options.target_game->create_extended_contents(CFLAGS_DETAIL_FENCE);
|
||||
}
|
||||
|
||||
/* nonsolid brushes don't show up in clipping hulls */
|
||||
// TODO: will this statement need to be modified since clip
|
||||
// detail etc aren't native types any more?
|
||||
if (hullnum > 0 && !contents.is_solid(options.target_game) && !contents.is_sky(options.target_game))
|
||||
continue;
|
||||
|
||||
/* sky brushes are solid in the collision hulls */
|
||||
if (hullnum > 0 && contents.is_sky(options.target_game))
|
||||
contents = contents.merge(options.target_game->create_solid_contents());
|
||||
contents = options.target_game->create_solid_contents();
|
||||
|
||||
// apply extended flags
|
||||
if (mirrorinside) {
|
||||
contents.extended |= CFLAGS_BMODEL_MIRROR_INSIDE;
|
||||
}
|
||||
if (noclipfaces) {
|
||||
contents.extended |= CFLAGS_NO_CLIPPING_SAME_TYPE;
|
||||
}
|
||||
if (func_illusionary_visblocker) {
|
||||
contents.extended |= CFLAGS_ILLUSIONARY_VISBLOCKER;
|
||||
}
|
||||
|
||||
brush_t *brush = LoadBrush(src, mapbrush, contents, rotate_offset, rottype, hullnum);
|
||||
if (!brush)
|
||||
|
|
@ -1247,7 +1229,13 @@ void Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnu
|
|||
dst->numbrushes++;
|
||||
brush->lmshift = lmshift;
|
||||
|
||||
if (brush->contents.is_detail(CFLAGS_DETAIL)) {
|
||||
if (brush->contents.is_solid(options.target_game)) {
|
||||
brush->next = dst->solid;
|
||||
dst->solid = brush;
|
||||
} else if (brush->contents.is_sky(options.target_game)) {
|
||||
brush->next = dst->sky;
|
||||
dst->sky = brush;
|
||||
} else if (brush->contents.is_detail(CFLAGS_DETAIL)) {
|
||||
brush->next = dst->detail;
|
||||
dst->detail = brush;
|
||||
} else if (brush->contents.is_detail(CFLAGS_DETAIL_ILLUSIONARY)) {
|
||||
|
|
@ -1256,12 +1244,6 @@ void Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnu
|
|||
} else if (brush->contents.is_detail(CFLAGS_DETAIL_FENCE)) {
|
||||
brush->next = dst->detail_fence;
|
||||
dst->detail_fence = brush;
|
||||
} else if (brush->contents.is_solid(options.target_game) && !(contents.extended & CFLAGS_CLIP)) {
|
||||
brush->next = dst->solid;
|
||||
dst->solid = brush;
|
||||
} else if (brush->contents.is_sky(options.target_game)) {
|
||||
brush->next = dst->sky;
|
||||
dst->sky = brush;
|
||||
} else {
|
||||
brush->next = dst->liquid;
|
||||
dst->liquid = brush;
|
||||
|
|
|
|||
47
qbsp/csg4.cc
47
qbsp/csg4.cc
|
|
@ -352,8 +352,8 @@ void SaveFacesToPlaneList(face_t *facelist, bool mirror, std::map<int, face_t *>
|
|||
// HACK: We only want this mirrored face for CONTENTS_DETAIL
|
||||
// to force the right content type for the leaf, but we don't actually
|
||||
// want the face. So just set the texinfo to "skip" so it gets deleted.
|
||||
if ((face->contents[1].is_detail() || (face->contents[1].extended & CFLAGS_WAS_ILLUSIONARY)) ||
|
||||
(options.fContentHack && face->contents[1].is_structural_solid(options.target_game))) {
|
||||
if ((face->contents[1].is_detail() || (face->contents[1].extended & CFLAGS_WAS_ILLUSIONARY))
|
||||
|| (options.fContentHack && face->contents[1].is_solid(options.target_game))) {
|
||||
|
||||
// if CFLAGS_BMODEL_MIRROR_INSIDE is set, never change to skip
|
||||
if (!(face->contents[1].extended & CFLAGS_BMODEL_MIRROR_INSIDE)) {
|
||||
|
|
@ -397,7 +397,7 @@ contents override the face inside contents.
|
|||
*/
|
||||
static void SaveInsideFaces(face_t *face, const brush_t *clipbrush, face_t **savelist)
|
||||
{
|
||||
Q_assert(!clipbrush->contents.is_structural_solid(options.target_game));
|
||||
Q_assert(!clipbrush->contents.is_solid(options.target_game));
|
||||
|
||||
face_t *next;
|
||||
|
||||
|
|
@ -408,8 +408,8 @@ static void SaveInsideFaces(face_t *face, const brush_t *clipbrush, face_t **sav
|
|||
next = face->next;
|
||||
face->contents[0] = clipbrush->contents;
|
||||
|
||||
if (face->contents[1].is_structural_sky_or_solid(options.target_game) &&
|
||||
clipbrush->contents.is_detail(CFLAGS_DETAIL)) {
|
||||
if ((face->contents[1].is_solid(options.target_game) || face->contents[1].is_sky(options.target_game))
|
||||
&& clipbrush->contents.is_detail(CFLAGS_DETAIL)) {
|
||||
// This case is when a structural and detail brush are touching,
|
||||
// and we want to save the sturctural face that is
|
||||
// touching detail.
|
||||
|
|
@ -424,27 +424,32 @@ static void SaveInsideFaces(face_t *face, const brush_t *clipbrush, face_t **sav
|
|||
// marked as empty here, and the detail faces have their "back"
|
||||
// marked as detail.
|
||||
|
||||
face->contents[0] = options.target_game->create_empty_contents(CFLAGS_STRUCTURAL_COVERED_BY_DETAIL);
|
||||
face->contents[0] = options.target_game->create_empty_contents();
|
||||
face->contents[0].extended |= CFLAGS_STRUCTURAL_COVERED_BY_DETAIL;
|
||||
face->texinfo = MakeSkipTexinfo();
|
||||
}
|
||||
|
||||
// N.B.: We don't need a hack like above for when clipbrush->contents == CONTENTS_DETAIL_ILLUSIONARY.
|
||||
|
||||
// These would create leaks
|
||||
Q_assert(!(face->contents[1].is_structural_sky_or_solid(options.target_game) &&
|
||||
face->contents[0].is_detail(CFLAGS_DETAIL)));
|
||||
Q_assert(!(face->contents[1].is_solid(options.target_game) && face->contents[0].is_detail(CFLAGS_DETAIL)));
|
||||
Q_assert(!(face->contents[1].is_sky(options.target_game) && face->contents[0].is_detail(CFLAGS_DETAIL)));
|
||||
|
||||
/*
|
||||
* If the inside brush is empty space, inherit the outside contents.
|
||||
* The only brushes with empty contents currently are hint brushes.
|
||||
*/
|
||||
if (face->contents[1].is_detail(CFLAGS_DETAIL_ILLUSIONARY)) {
|
||||
face->contents[1] = {clipbrush->contents.native,
|
||||
(face->contents[1].extended & ~CFLAGS_DETAIL_ILLUSIONARY) | CFLAGS_WAS_ILLUSIONARY};
|
||||
}
|
||||
if (face->contents[1].is_empty(options.target_game)) {
|
||||
face->contents[1] = clipbrush->contents;
|
||||
}
|
||||
if (face->contents[1].is_detail(CFLAGS_DETAIL_ILLUSIONARY)) {
|
||||
bool wasMirrorInside = !!(face->contents[1].extended & CFLAGS_BMODEL_MIRROR_INSIDE);
|
||||
face->contents[1] = clipbrush->contents;
|
||||
face->contents[1].extended |= CFLAGS_WAS_ILLUSIONARY;
|
||||
if (wasMirrorInside) {
|
||||
face->contents[1].extended |= CFLAGS_BMODEL_MIRROR_INSIDE;
|
||||
}
|
||||
}
|
||||
|
||||
face->next = *savelist;
|
||||
*savelist = face;
|
||||
|
|
@ -569,7 +574,7 @@ surface_t *CSGFaces(const mapentity_t *entity)
|
|||
overwrite = true;
|
||||
continue;
|
||||
}
|
||||
if (clipbrush->contents.is_hint()) {
|
||||
if (clipbrush->contents.is_empty(options.target_game)) {
|
||||
/* Ensure hint never clips anything */
|
||||
continue;
|
||||
}
|
||||
|
|
@ -585,8 +590,6 @@ surface_t *CSGFaces(const mapentity_t *entity)
|
|||
continue;
|
||||
}
|
||||
|
||||
// TODO: this might break because this == won't catch the extended types now.
|
||||
// might need a specific function for this one.
|
||||
if (clipbrush->contents.types_equal(brush->contents, options.target_game) &&
|
||||
!clipbrush->contents.clips_same_type()) {
|
||||
/* _noclipfaces key */
|
||||
|
|
@ -630,16 +633,14 @@ surface_t *CSGFaces(const mapentity_t *entity)
|
|||
*
|
||||
* FIXME: clean this up, the predicate seems to be "can you see 'brush' from inside 'clipbrush'"
|
||||
*/
|
||||
if ((brush->contents.is_structural_solid(options.target_game) &&
|
||||
!clipbrush->contents.is_structural_solid(options.target_game))
|
||||
if ((brush->contents.is_solid(options.target_game) && !clipbrush->contents.is_solid(options.target_game))
|
||||
|
||||
|| (brush->contents.is_structural_sky(options.target_game) &&
|
||||
!clipbrush->contents.is_structural_sky_or_solid(options.target_game))
|
||||
|| (brush->contents.is_sky(options.target_game) && (!clipbrush->contents.is_solid(options.target_game)
|
||||
&& !clipbrush->contents.is_sky(options.target_game)))
|
||||
|
||||
|| ((brush->contents.is_solid(options.target_game) && brush->contents.is_detail(CFLAGS_DETAIL)) &&
|
||||
(!clipbrush->contents.is_solid(options.target_game) &&
|
||||
!clipbrush->contents.is_sky(options.target_game) &&
|
||||
!clipbrush->contents.is_detail(CFLAGS_DETAIL)))
|
||||
|| (brush->contents.is_detail(CFLAGS_DETAIL) && (!clipbrush->contents.is_solid(options.target_game)
|
||||
&& !clipbrush->contents.is_sky(options.target_game)
|
||||
&& !clipbrush->contents.is_detail(CFLAGS_DETAIL)))
|
||||
|
||||
|| (brush->contents.is_liquid(options.target_game) &&
|
||||
clipbrush->contents.is_detail(CFLAGS_DETAIL_ILLUSIONARY))
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ static void ClearOutFaces(node_t *node)
|
|||
}
|
||||
|
||||
// visit the leaf
|
||||
if (!node->contents.is_structural_solid(options.target_game)) {
|
||||
if (!node->contents.is_solid(options.target_game)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -348,7 +348,8 @@ static void OutLeafsToSolid_r(node_t *node, int *outleafs_count)
|
|||
return;
|
||||
|
||||
// Don't fill sky, or count solids as outleafs
|
||||
if (node->contents.is_structural_sky_or_solid(options.target_game))
|
||||
if (node->contents.is_solid(options.target_game)
|
||||
|| node->contents.is_sky(options.target_game))
|
||||
return;
|
||||
|
||||
// Now check all faces touching the leaf. If any of them are partially going into the occupied part of the map,
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ static void NumberLeafs_r(node_t *node, portal_state_t *state, int cluster)
|
|||
return;
|
||||
}
|
||||
|
||||
if (node->contents.is_structural_solid(options.target_game)) {
|
||||
if (node->contents.is_solid(options.target_game)) {
|
||||
/* solid block, viewpoint never inside */
|
||||
node->visleafnum = -1;
|
||||
node->viscluster = -1;
|
||||
|
|
|
|||
10
qbsp/qbsp.cc
10
qbsp/qbsp.cc
|
|
@ -38,7 +38,8 @@ options_t options;
|
|||
|
||||
bool node_t::opaque() const
|
||||
{
|
||||
return contents.is_structural_sky_or_solid(options.target_game);
|
||||
return contents.is_sky(options.target_game)
|
||||
|| contents.is_solid(options.target_game);
|
||||
}
|
||||
|
||||
// a simple tree structure used for leaf brush
|
||||
|
|
@ -894,10 +895,15 @@ void BSPX_Brushes_AddModel(struct bspxbrushes_s *ctx, int modelnum, brush_t *bru
|
|||
// case CONTENTS_LADDER:
|
||||
// perbrush.contents = -16;
|
||||
// break;
|
||||
default:
|
||||
default: {
|
||||
if (b->contents.is_clip()) {
|
||||
perbrush.contents = -8;
|
||||
} else {
|
||||
LogPrint("WARNING: Unknown contents: {}. Translating to solid.\n", b->contents.to_string(options.target_game));
|
||||
perbrush.contents = CONTENTS_SOLID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
perbrush.contents = LittleShort(perbrush.contents);
|
||||
perbrush.numfaces = LittleShort(perbrush.numfaces);
|
||||
|
|
|
|||
|
|
@ -62,15 +62,30 @@ void ConvertNodeToLeaf(node_t *node, const contentflags_t &contents)
|
|||
|
||||
void DetailToSolid(node_t *node)
|
||||
{
|
||||
if (node->planenum != PLANENUM_LEAF) {
|
||||
if (node->planenum == PLANENUM_LEAF) {
|
||||
if (options.target_game->id == GAME_QUAKE_II) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to remap CONTENTS_DETAIL to a standard quake content type
|
||||
if (node->contents.is_detail(CFLAGS_DETAIL)) {
|
||||
node->contents = options.target_game->create_solid_contents();
|
||||
} else if (node->contents.is_detail(CFLAGS_DETAIL_ILLUSIONARY)) {
|
||||
node->contents = options.target_game->create_empty_contents();
|
||||
}
|
||||
/* N.B.: CONTENTS_DETAIL_FENCE is not remapped to CONTENTS_SOLID until the very last moment,
|
||||
* because we want to generate a leaf (if we set it to CONTENTS_SOLID now it would use leaf 0).
|
||||
*/
|
||||
return;
|
||||
} else {
|
||||
DetailToSolid(node->children[0]);
|
||||
DetailToSolid(node->children[1]);
|
||||
|
||||
// If both children are solid, we can merge the two leafs into one.
|
||||
// DarkPlaces has an assertion that fails if both children are
|
||||
// solid.
|
||||
if (node->children[0]->contents.is_structural_solid(options.target_game) &&
|
||||
node->children[1]->contents.is_structural_solid(options.target_game)) {
|
||||
if (node->children[0]->contents.is_solid(options.target_game)
|
||||
&& node->children[1]->contents.is_solid(options.target_game)) {
|
||||
// This discards any faces on-node. Should be safe (?)
|
||||
ConvertNodeToLeaf(node, options.target_game->create_solid_contents());
|
||||
}
|
||||
|
|
@ -670,7 +685,7 @@ static void LinkConvexFaces(surface_t *planelist, node_t *leafnode)
|
|||
if (f->contents[0].extended & CFLAGS_STRUCTURAL_COVERED_BY_DETAIL) {
|
||||
Q_assert(f->contents[0].is_empty(options.target_game));
|
||||
|
||||
const contentflags_t solid_detail = options.target_game->create_solid_contents(CFLAGS_DETAIL);
|
||||
const contentflags_t solid_detail = options.target_game->create_extended_contents(CFLAGS_DETAIL);
|
||||
|
||||
if (solid_detail.priority(options.target_game) > currentpri) {
|
||||
contents = solid_detail;
|
||||
|
|
|
|||
|
|
@ -283,7 +283,9 @@ inline size_t GetEdge(mapentity_t *entity, const qvec3d &p1, const qvec3d &p2, c
|
|||
auto it = hashedges.find(edge_hash_key);
|
||||
if (it != hashedges.end()) {
|
||||
for (const int i : it->second) {
|
||||
if (pEdgeFaces1[i] == NULL && pEdgeFaces0[i]->contents[0] == face->contents[0]) {
|
||||
edge = &map.exported_edges.at(i);
|
||||
if (pEdgeFaces1[i] == NULL
|
||||
&& pEdgeFaces0[i]->contents[0].native == face->contents[0].native) {
|
||||
pEdgeFaces1[i] = face;
|
||||
return -i;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,10 +83,13 @@ size_t ExportMapTexinfo(size_t texinfonum)
|
|||
|
||||
gtexinfo_t &dest = map.bsp.texinfo.emplace_back();
|
||||
|
||||
dest.flags = src.flags;
|
||||
dest.miptex = src.miptex;
|
||||
dest.vecs = src.vecs;
|
||||
// make sure we don't write any non-native flags.
|
||||
// e.g. Quake only accepts 0 or TEX_SPECIAL.
|
||||
dest->flags = options.target_game->surf_remap_for_export(src->flags);
|
||||
// TODO: warn if dest->flags.native != src->flags.native
|
||||
|
||||
dest->miptex = src->miptex;
|
||||
dest.vecs = src.vecs;
|
||||
strcpy(dest.texture.data(), map.texinfoTextureName(texinfonum).c_str());
|
||||
dest.value = map.miptex[src.miptex].value;
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,9 @@ light invalid_texture_axes.map || exit 1
|
|||
# regenerate the expected hashes, but check that the .bsp's still
|
||||
# work in game at the same time.
|
||||
|
||||
HASH_CHECK_BSPS="e1m1-bsp29.bsp \
|
||||
HASH_CHECK_BSPS="qbsp_func_detail.bsp \
|
||||
qbsp_func_detail_illusionary_plus_water.bsp \
|
||||
e1m1-bsp29.bsp \
|
||||
e1m1-bsp2.bsp \
|
||||
e1m1-2psb.bsp \
|
||||
e1m1-hexen2.bsp \
|
||||
|
|
@ -46,6 +48,12 @@ e1m1-bspxbrushes.bsp \
|
|||
e1m1-bsp29-onlyents.bsp \
|
||||
qbspfeatures.bsp"
|
||||
|
||||
HASH_CHECK_PRTS=${HASH_CHECK_BSPS//.bsp/.prt}
|
||||
|
||||
# smaller test maps for specific features/combinations
|
||||
qbsp -noverbose qbsp_func_detail.map || exit 1
|
||||
qbsp -noverbose qbsp_func_detail_illusionary_plus_water.bsp || exit 1
|
||||
|
||||
qbsp -noverbose quake_map_source/E1M1.map e1m1-bsp29.bsp || exit 1
|
||||
qbsp -noverbose -bsp2 quake_map_source/E1M1.map e1m1-bsp2.bsp || exit 1
|
||||
qbsp -noverbose -2psb quake_map_source/E1M1.map e1m1-2psb.bsp || exit 1
|
||||
|
|
@ -66,18 +74,22 @@ qbsp -onlyents E1M1-edited-ents.map e1m1-bsp29-onlyents.bsp || exit 1
|
|||
qbsp -noverbose qbspfeatures.map || exit 1
|
||||
|
||||
if [[ $UPDATE_HASHES -ne 0 ]]; then
|
||||
sha256sum ${HASH_CHECK_BSPS} > qbsp.sha256sum || exit 1
|
||||
sha256sum ${HASH_CHECK_BSPS} ${HASH_CHECK_PRTS} > qbsp.sha256sum || exit 1
|
||||
else
|
||||
sha256sum --strict --check qbsp.sha256sum || exit 1
|
||||
fi
|
||||
|
||||
# now run vis
|
||||
# FIXME: vis output is nondeterministic when run with multiple threads!
|
||||
# since vis is slower, launch all as background processes, and then wait for all of them to finish
|
||||
# FIXME: vis output is nondeterministic when run with multiple threads, so force 1 thread per process
|
||||
|
||||
for bsp in ${HASH_CHECK_BSPS}; do
|
||||
vis -nostate -threads 1 ${bsp} || exit 1
|
||||
vis -nostate -threads 1 ${bsp} &
|
||||
done
|
||||
|
||||
# we don't get the exit status this way, but the hash check will test the resulting visdata
|
||||
wait
|
||||
|
||||
if [[ $UPDATE_HASHES -ne 0 ]]; then
|
||||
sha256sum ${HASH_CHECK_BSPS} > qbsp-vis.sha256sum || exit 1
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
416e68cd92c817f206c11006db21bd6b0cbc330eee63bdfc66afc5152b406760 *qbsp_func_detail.bsp
|
||||
c338b813b6529e5cd790720e3bc6a9e8f74e02e3348db04756174403f3331b8c *qbsp_func_detail_illusionary_plus_water.bsp
|
||||
c9683e945bb01528a768653cdb79584dfbc8be6f76b712cbf0d24482a4ae3cc3 *e1m1-bsp29.bsp
|
||||
a8024b07d48abc0553ff3628d6d4cb62138f67808b425b833e5643068231c2e4 *e1m1-bsp2.bsp
|
||||
cb11d4f40d92c9d349fd11f9e4901e9cd9aa82db9971181a615c197f75f4b4a6 *e1m1-2psb.bsp
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
45d60368c37ee3523f9a1dbc140f34ae7728fc13d3cb8a43e7b22caefe46edb1 *qbsp_func_detail.bsp
|
||||
565e9aef399341eef99fc37212d7ab314df8f6dd850a8ca5a471661088d7d3bc *qbsp_func_detail_illusionary_plus_water.bsp
|
||||
d289427e3c8a7046dce509a83401f6732a9c5f8194f8beb3eee431e33215656c *e1m1-bsp29.bsp
|
||||
85002a12afa023d850199e205f01fc58de2743f97aea9b2a22a3b0ac3ce8f7ad *e1m1-bsp2.bsp
|
||||
832ec9aff302ddfcc5ab4fe0911afec0b4d57c60e02dc1c8f61e1edbf8f53eda *e1m1-2psb.bsp
|
||||
|
|
@ -8,3 +10,15 @@ d289427e3c8a7046dce509a83401f6732a9c5f8194f8beb3eee431e33215656c *e1m1-bsp29.bsp
|
|||
015c5fb3f350dfb10c031ed3ae44b3e094fbde38c48dec0897d0710fcbc7666c *e1m1-bspxbrushes.bsp
|
||||
af7bc468d76aa1b11d1881a3378877059c6fd33fb37bea555d332e17d0e1e23c *e1m1-bsp29-onlyents.bsp
|
||||
9f6db65a0c8a3eaa369deb3bb3168b5da69f23eb80a12788ff50d3c30b8a469a *qbspfeatures.bsp
|
||||
abf3633d5a6d0e167ce9bacec476d3408c8240df5f3d72d14867cd201d4e3674 *qbsp_func_detail.prt
|
||||
c0995c6b92256fa048c1a755ebe7e07f5fae33cb64e3c53adc234380fe44f267 *qbsp_func_detail_illusionary_plus_water.prt
|
||||
08349ab23c97120c41493d8fb00b9a6c41553aba64b1710ba11cc5bdfbe51e45 *e1m1-bsp29.prt
|
||||
08349ab23c97120c41493d8fb00b9a6c41553aba64b1710ba11cc5bdfbe51e45 *e1m1-bsp2.prt
|
||||
08349ab23c97120c41493d8fb00b9a6c41553aba64b1710ba11cc5bdfbe51e45 *e1m1-2psb.prt
|
||||
08349ab23c97120c41493d8fb00b9a6c41553aba64b1710ba11cc5bdfbe51e45 *e1m1-hexen2.prt
|
||||
08349ab23c97120c41493d8fb00b9a6c41553aba64b1710ba11cc5bdfbe51e45 *e1m1-hexen2-bsp2.prt
|
||||
08349ab23c97120c41493d8fb00b9a6c41553aba64b1710ba11cc5bdfbe51e45 *e1m1-hexen2-2psb.prt
|
||||
08349ab23c97120c41493d8fb00b9a6c41553aba64b1710ba11cc5bdfbe51e45 *e1m1-hlbsp.prt
|
||||
08349ab23c97120c41493d8fb00b9a6c41553aba64b1710ba11cc5bdfbe51e45 *e1m1-bspxbrushes.prt
|
||||
08349ab23c97120c41493d8fb00b9a6c41553aba64b1710ba11cc5bdfbe51e45 *e1m1-bsp29-onlyents.prt
|
||||
15361b57e8a0e8a3a9d949133eb53dadca91f03f1697997a9d36bad687edd2ab *qbspfeatures.prt
|
||||
|
|
|
|||
|
|
@ -0,0 +1,97 @@
|
|||
// Game: Quake
|
||||
// Format: Valve
|
||||
// entity 0
|
||||
{
|
||||
"mapversion" "220"
|
||||
"classname" "worldspawn"
|
||||
"wad" "deprecated/free_wad.wad;deprecated/fence.wad;deprecated/origin.wad;deprecated/hintskip.wad"
|
||||
"_wateralpha" "0.5"
|
||||
"_tb_def" "builtin:Quoth2.fgd"
|
||||
// brush 0
|
||||
{
|
||||
( -176 -256 64 ) ( -176 -255 64 ) ( -176 -256 65 ) tsl_wall1 [ 0 -1 0 0 ] [ 0 0 -1 -32 ] 0 1 1
|
||||
( -176 -432 64 ) ( -176 -432 65 ) ( -175 -432 64 ) tsl_wall1 [ 1 0 0 16 ] [ 0 0 -1 -32 ] 0 1 1
|
||||
( -176 -256 96 ) ( -175 -256 96 ) ( -176 -255 96 ) tsl_wall1 [ -1 0 0 -16 ] [ 0 -1 0 0 ] 0 1 1
|
||||
( -160 192 352 ) ( -160 193 352 ) ( -159 192 352 ) tsl_wall1 [ 1 0 0 16 ] [ 0 -1 0 0 ] 0 1 1
|
||||
( -160 176 80 ) ( -159 176 80 ) ( -160 176 81 ) tsl_wall1 [ -1 0 0 -16 ] [ 0 0 -1 -32 ] 0 1 1
|
||||
( -160 192 80 ) ( -160 192 81 ) ( -160 193 80 ) tsl_wall1 [ 0 1 0 0 ] [ 0 0 -1 -32 ] 0 1 1
|
||||
}
|
||||
// brush 1
|
||||
{
|
||||
( -160 176 88 ) ( -160 177 88 ) ( -160 176 89 ) tsl_wall1 [ 0 1.0000000000000002 0 -32 ] [ 0 0 -1.0000000000000002 -32 ] 0 1 1
|
||||
( -160 176 88 ) ( -160 176 89 ) ( -159 176 88 ) tsl_wall1 [ -1 0 0 -16 ] [ 0 0 -1 -32 ] 0 1 1
|
||||
( -160 176 96 ) ( -159 176 96 ) ( -160 177 96 ) tsl_wall1 [ -1.0000000000000002 0 0 -16 ] [ 0 1.0000000000000002 0 -40 ] 0 1 1
|
||||
( 288 192 352 ) ( 288 193 352 ) ( 289 192 352 ) tsl_wall1 [ -1.0000000000000002 0 0 -16 ] [ 0 -1.0000000000000002 0 48 ] 0 1 1
|
||||
( 288 192 96 ) ( 289 192 96 ) ( 288 192 97 ) tsl_wall1 [ -1 0 0 -16 ] [ 0 0 -1 -32 ] 0 1 1
|
||||
( 288 192 96 ) ( 288 192 97 ) ( 288 193 96 ) tsl_wall1 [ 0 -1.0000000000000002 0 0 ] [ 0 0 -1.0000000000000002 -32 ] 0 1 1
|
||||
}
|
||||
// brush 2
|
||||
{
|
||||
( -160 -112 96 ) ( -160 -111 96 ) ( -160 -112 97 ) orangestuff8 [ 0 1 0 -16 ] [ 0 0 -1 0 ] 0 1 1
|
||||
( -80 -432 80 ) ( -81 -432 80 ) ( -80 -432 81 ) orangestuff8 [ -1 0 0 16 ] [ 0 0 -1 0 ] 180 1 1
|
||||
( -80 -432 80 ) ( -80 -431 80 ) ( -81 -432 80 ) orangestuff8 [ 1 0 0 -16 ] [ 0 -1 0 16 ] 180 1 1
|
||||
( -160 -112 96 ) ( -161 -112 96 ) ( -160 -111 96 ) orangestuff8 [ -1 0 0 16 ] [ 0 -1 0 16 ] 180 1 1
|
||||
( -160 176 96 ) ( -160 176 97 ) ( -161 176 96 ) orangestuff8 [ 1 0 0 -16 ] [ 0 0 -1 0 ] 180 1 1
|
||||
( 288 -432 80 ) ( 288 -432 81 ) ( 288 -431 80 ) orangestuff8 [ 0 -1 0 16 ] [ 0 0 -1 0 ] 0 1 1
|
||||
}
|
||||
// brush 3
|
||||
{
|
||||
( -160 -448 88 ) ( -160 -447 88 ) ( -160 -448 89 ) tsl_wall1 [ 0 1.0000000000000002 0 80 ] [ 0 0 -1.0000000000000002 -32 ] 0 1 1
|
||||
( -160 -448 88 ) ( -160 -448 89 ) ( -159 -448 88 ) tsl_wall1 [ -1 0 0 -16 ] [ 0 0 -1 -32 ] 0 1 1
|
||||
( -160 -448 96 ) ( -159 -448 96 ) ( -160 -447 96 ) tsl_wall1 [ -1.0000000000000002 0 0 -16 ] [ 0 1.0000000000000002 0 72 ] 0 1 1
|
||||
( 288 -432 352 ) ( 288 -431 352 ) ( 289 -432 352 ) tsl_wall1 [ -1.0000000000000002 0 0 -16 ] [ 0 -1.0000000000000002 0 -64 ] 0 1 1
|
||||
( 288 -432 96 ) ( 289 -432 96 ) ( 288 -432 97 ) tsl_wall1 [ -1 0 0 -16 ] [ 0 0 -1 -32 ] 0 1 1
|
||||
( 288 -432 96 ) ( 288 -432 97 ) ( 288 -431 96 ) tsl_wall1 [ 0 -1.0000000000000002 0 -112 ] [ 0 0 -1.0000000000000002 -32 ] 0 1 1
|
||||
}
|
||||
// brush 4
|
||||
{
|
||||
( -160 -256 352 ) ( -160 -255 352 ) ( -160 -256 353 ) orangestuff8 [ 0 0 -1.0000000000000002 0 ] [ 0 -1.0000000000000002 0 0 ] 180 1 1
|
||||
( 288 -432 360 ) ( 288 -432 361 ) ( 289 -432 360 ) orangestuff8 [ -1.0000000000000002 0 0 0 ] [ 0 0 1.0000000000000002 -16 ] 180 1 1
|
||||
( -160 -256 352 ) ( -159 -256 352 ) ( -160 -255 352 ) orangestuff8 [ -1 0 0 0 ] [ 0 -1 0 0 ] 180 1 1
|
||||
( 288 176 368 ) ( 288 177 368 ) ( 289 176 368 ) orangestuff8 [ -1 0 0 0 ] [ 0 -1 0 0 ] 180 1 1
|
||||
( 288 176 360 ) ( 289 176 360 ) ( 288 176 361 ) orangestuff8 [ -1.0000000000000002 0 0 0 ] [ 0 0 1.0000000000000002 -16 ] 180 1 1
|
||||
( 288 176 360 ) ( 288 176 361 ) ( 288 177 360 ) orangestuff8 [ 0 0 1.0000000000000002 0 ] [ 0 -1.0000000000000002 0 0 ] 180 1 1
|
||||
}
|
||||
// brush 5
|
||||
{
|
||||
( 288 192 80 ) ( 288 193 80 ) ( 288 192 81 ) tsl_wall1 [ 0 1 0 0 ] [ 0 0 -1 -32 ] 0 1 1
|
||||
( 304 -432 64 ) ( 303 -432 64 ) ( 304 -432 65 ) tsl_wall1 [ -1 0 0 16 ] [ 0 0 -1 -32 ] 180 1 1
|
||||
( 304 -256 96 ) ( 304 -255 96 ) ( 303 -256 96 ) tsl_wall1 [ 1 0 0 -16 ] [ 0 -1 0 0 ] 180 1 1
|
||||
( 304 -256 352 ) ( 303 -256 352 ) ( 304 -255 352 ) tsl_wall1 [ 1 0 0 -16 ] [ 0 -1 0 0 ] 180 1 1
|
||||
( 288 176 80 ) ( 288 176 81 ) ( 287 176 80 ) tsl_wall1 [ 1 0 0 -16 ] [ 0 0 -1 -32 ] 180 1 1
|
||||
( 304 -256 64 ) ( 304 -256 65 ) ( 304 -255 64 ) tsl_wall1 [ 0 -1 0 0 ] [ 0 0 -1 -32 ] 0 1 1
|
||||
}
|
||||
// brush 6
|
||||
{
|
||||
( 56 -8 96 ) ( 56 -7 96 ) ( 56 -8 97 ) tsl_wall1 [ 0 1.0000000000000002 0 -120 ] [ 0 0 -1.0000000000000002 -32 ] 0 1 1
|
||||
( 56 -8 96 ) ( 56 -8 97 ) ( 57 -8 96 ) tsl_wall1 [ -1 0 0 -16 ] [ 0 0 -1 -32 ] 0 1 1
|
||||
( 56 -8 96 ) ( 57 -8 96 ) ( 56 -7 96 ) tsl_wall1 [ -1.0000000000000002 0 0 -16 ] [ 0 1.0000000000000002 0 -48 ] 0 1 1
|
||||
( 72 176 168 ) ( 72 177 168 ) ( 73 176 168 ) tsl_wall1 [ -1.0000000000000002 0 0 -16 ] [ 0 -1.0000000000000002 0 40 ] 0 1 1
|
||||
( 72 176 104 ) ( 73 176 104 ) ( 72 176 105 ) tsl_wall1 [ -1 0 0 -16 ] [ 0 0 -1 -32 ] 0 1 1
|
||||
( 72 176 104 ) ( 72 176 105 ) ( 72 177 104 ) tsl_wall1 [ 0 -1.0000000000000002 0 88 ] [ 0 0 -1.0000000000000002 -32 ] 0 1 1
|
||||
}
|
||||
}
|
||||
// entity 1
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "72 -136 168"
|
||||
"light" "3000"
|
||||
}
|
||||
// entity 2
|
||||
{
|
||||
"classname" "info_player_start"
|
||||
"origin" "-88 -64 120"
|
||||
}
|
||||
// entity 3
|
||||
{
|
||||
"classname" "func_detail"
|
||||
// brush 0
|
||||
{
|
||||
( 32 -120 96 ) ( 32 -119 96 ) ( 32 -120 97 ) orangestuff8 [ 0 0 -1.0000000000000002 48 ] [ 0 -1.0000000000000002 0 -24 ] 180 1 1
|
||||
( 16 -88 96 ) ( 16 -88 97 ) ( 17 -88 96 ) orangestuff8 [ -1.0000000000000002 0 0 -32 ] [ 0 0 -1.0000000000000002 48 ] 180 1 1
|
||||
( 16 -120 96 ) ( 17 -120 96 ) ( 16 -119 96 ) orangestuff8 [ -1 0 0 -32 ] [ 0 -1 0 -24 ] 180 1 1
|
||||
( 80 -40 104 ) ( 80 -39 104 ) ( 81 -40 104 ) +0fan [ -1 0 0 -32 ] [ 0 -1 0 -24 ] 180 1 1
|
||||
( 80 -24 112 ) ( 81 -24 112 ) ( 80 -24 113 ) orangestuff8 [ -1.0000000000000002 0 0 -32 ] [ 0 0 1.0000000000000002 -16 ] 180 1 1
|
||||
( 96 -40 112 ) ( 96 -40 113 ) ( 96 -39 112 ) orangestuff8 [ 0 0 1.0000000000000002 -16 ] [ 0 -1.0000000000000002 0 -24 ] 180 1 1
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
// Game: Quake
|
||||
// Format: Valve
|
||||
// entity 0
|
||||
{
|
||||
"mapversion" "220"
|
||||
"classname" "worldspawn"
|
||||
"wad" "deprecated/fence.wad;deprecated/free_wad.wad"
|
||||
// brush 0
|
||||
{
|
||||
( -160 -256 80 ) ( -160 64 16 ) ( -160 64 80 ) *swater4 [ 0 -1 0 -16 ] [ 0 0 -1 0 ] 0 6 6
|
||||
( 192 -432 80 ) ( -64 -432 16 ) ( -64 -432 80 ) *swater4 [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 6 6
|
||||
( 192 64 16 ) ( -64 -256 16 ) ( 192 -256 16 ) *swater4 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 6 6
|
||||
( 192 64 80 ) ( -64 -256 80 ) ( -64 64 80 ) *swater4 [ 1 0 0 0 ] [ 0 -1 0 -16 ] 0 6 6
|
||||
( 192 176 80 ) ( -64 176 16 ) ( 192 176 16 ) *swater4 [ -1 0 0 0 ] [ 0 0 -1 0 ] 0 6 6
|
||||
( 288 64 80 ) ( 288 -256 16 ) ( 288 -256 80 ) *swater4 [ 0 -1 0 -16 ] [ 0 0 -1 0 ] 0 6 6
|
||||
}
|
||||
// brush 1
|
||||
{
|
||||
( -176 -256 -16 ) ( -176 -255 -16 ) ( -176 -256 -15 ) tsl_wall1 [ 0 -1 0 0 ] [ 0 0 -1 16 ] 0 6 6
|
||||
( -176 -432 -16 ) ( -176 -432 -15 ) ( -175 -432 -16 ) tsl_wall1 [ 1 0 0 16 ] [ 0 0 -1 16 ] 0 6 6
|
||||
( -176 -256 16 ) ( -175 -256 16 ) ( -176 -255 16 ) tsl_wall1 [ -1 0 0 -16 ] [ 0 -1 0 0 ] 0 6 6
|
||||
( -160 192 272 ) ( -160 193 272 ) ( -159 192 272 ) tsl_wall1 [ 1 0 0 16 ] [ 0 -1 0 0 ] 0 6 6
|
||||
( -160 176 0 ) ( -159 176 0 ) ( -160 176 1 ) tsl_wall1 [ -1 0 0 -16 ] [ 0 0 -1 16 ] 0 6 6
|
||||
( -160 192 0 ) ( -160 192 1 ) ( -160 193 0 ) tsl_wall1 [ 0 1 0 0 ] [ 0 0 -1 16 ] 0 6 6
|
||||
}
|
||||
// brush 2
|
||||
{
|
||||
( -160 176 8 ) ( -160 177 8 ) ( -160 176 9 ) tsl_wall1 [ 0 1.0000000000000002 0 -32 ] [ 0 0 -1.0000000000000002 16 ] 0 6 6
|
||||
( -160 176 8 ) ( -160 176 9 ) ( -159 176 8 ) tsl_wall1 [ -1 0 0 -16 ] [ 0 0 -1 16 ] 0 6 6
|
||||
( -160 176 16 ) ( -159 176 16 ) ( -160 177 16 ) tsl_wall1 [ -1.0000000000000002 0 0 -16 ] [ 0 1.0000000000000002 0 -40 ] 0 6 6
|
||||
( 288 192 272 ) ( 288 193 272 ) ( 289 192 272 ) tsl_wall1 [ -1.0000000000000002 0 0 -16 ] [ 0 -1.0000000000000002 0 48 ] 0 6 6
|
||||
( 288 192 16 ) ( 289 192 16 ) ( 288 192 17 ) tsl_wall1 [ -1 0 0 -16 ] [ 0 0 -1 16 ] 0 6 6
|
||||
( 288 192 16 ) ( 288 192 17 ) ( 288 193 16 ) tsl_wall1 [ 0 -1.0000000000000002 0 0 ] [ 0 0 -1.0000000000000002 16 ] 0 6 6
|
||||
}
|
||||
// brush 3
|
||||
{
|
||||
( -160 -112 16 ) ( -160 -111 16 ) ( -160 -112 17 ) orangestuff8 [ 0 1 0 -16 ] [ 0 0 -1 -16 ] 0 6 6
|
||||
( -80 -432 0 ) ( -81 -432 0 ) ( -80 -432 1 ) orangestuff8 [ -1 0 0 16 ] [ 0 0 -1 -16 ] 180 6 6
|
||||
( -80 -432 0 ) ( -80 -431 0 ) ( -81 -432 0 ) orangestuff8 [ 1 0 0 -16 ] [ 0 -1 0 16 ] 180 6 6
|
||||
( -160 -112 16 ) ( -161 -112 16 ) ( -160 -111 16 ) orangestuff8 [ -1 0 0 16 ] [ 0 -1 0 16 ] 180 6 6
|
||||
( -160 176 16 ) ( -160 176 17 ) ( -161 176 16 ) orangestuff8 [ 1 0 0 -16 ] [ 0 0 -1 -16 ] 180 6 6
|
||||
( 288 -432 0 ) ( 288 -432 1 ) ( 288 -431 0 ) orangestuff8 [ 0 -1 0 16 ] [ 0 0 -1 -16 ] 0 6 6
|
||||
}
|
||||
// brush 4
|
||||
{
|
||||
( -160 -448 8 ) ( -160 -447 8 ) ( -160 -448 9 ) tsl_wall1 [ 0 1.0000000000000002 0 80 ] [ 0 0 -1.0000000000000002 16 ] 0 6 6
|
||||
( -160 -448 8 ) ( -160 -448 9 ) ( -159 -448 8 ) tsl_wall1 [ -1 0 0 -16 ] [ 0 0 -1 16 ] 0 6 6
|
||||
( -160 -448 16 ) ( -159 -448 16 ) ( -160 -447 16 ) tsl_wall1 [ -1.0000000000000002 0 0 -16 ] [ 0 1.0000000000000002 0 72 ] 0 6 6
|
||||
( 288 -432 272 ) ( 288 -431 272 ) ( 289 -432 272 ) tsl_wall1 [ -1.0000000000000002 0 0 -16 ] [ 0 -1.0000000000000002 0 -64 ] 0 6 6
|
||||
( 288 -432 16 ) ( 289 -432 16 ) ( 288 -432 17 ) tsl_wall1 [ -1 0 0 -16 ] [ 0 0 -1 16 ] 0 6 6
|
||||
( 288 -432 16 ) ( 288 -432 17 ) ( 288 -431 16 ) tsl_wall1 [ 0 -1.0000000000000002 0 -112 ] [ 0 0 -1.0000000000000002 16 ] 0 6 6
|
||||
}
|
||||
// brush 5
|
||||
{
|
||||
( -160 -256 272 ) ( -160 -255 272 ) ( -160 -256 273 ) orangestuff8 [ 0 0 -1.0000000000000002 -16 ] [ 0 -1.0000000000000002 0 0 ] 180 6 6
|
||||
( 288 -432 280 ) ( 288 -432 281 ) ( 289 -432 280 ) orangestuff8 [ -1.0000000000000002 0 0 0 ] [ 0 0 1.0000000000000002 0 ] 180 6 6
|
||||
( -160 -256 272 ) ( -159 -256 272 ) ( -160 -255 272 ) orangestuff8 [ -1 0 0 0 ] [ 0 -1 0 0 ] 180 6 6
|
||||
( 288 176 288 ) ( 288 177 288 ) ( 289 176 288 ) orangestuff8 [ -1 0 0 0 ] [ 0 -1 0 0 ] 180 6 6
|
||||
( 288 176 280 ) ( 289 176 280 ) ( 288 176 281 ) orangestuff8 [ -1.0000000000000002 0 0 0 ] [ 0 0 1.0000000000000002 0 ] 180 6 6
|
||||
( 288 176 280 ) ( 288 176 281 ) ( 288 177 280 ) orangestuff8 [ 0 0 1.0000000000000002 16 ] [ 0 -1.0000000000000002 0 0 ] 180 6 6
|
||||
}
|
||||
// brush 6
|
||||
{
|
||||
( 288 192 0 ) ( 288 193 0 ) ( 288 192 1 ) tsl_wall1 [ 0 1 0 0 ] [ 0 0 -1 16 ] 0 6 6
|
||||
( 304 -432 -16 ) ( 303 -432 -16 ) ( 304 -432 -15 ) tsl_wall1 [ -1 0 0 16 ] [ 0 0 -1 16 ] 180 6 6
|
||||
( 304 -256 16 ) ( 304 -255 16 ) ( 303 -256 16 ) tsl_wall1 [ 1 0 0 -16 ] [ 0 -1 0 0 ] 180 6 6
|
||||
( 304 -256 272 ) ( 303 -256 272 ) ( 304 -255 272 ) tsl_wall1 [ 1 0 0 -16 ] [ 0 -1 0 0 ] 180 6 6
|
||||
( 288 176 0 ) ( 288 176 1 ) ( 287 176 0 ) tsl_wall1 [ 1 0 0 -16 ] [ 0 0 -1 16 ] 180 6 6
|
||||
( 304 -256 -16 ) ( 304 -256 -15 ) ( 304 -255 -16 ) tsl_wall1 [ 0 -1 0 0 ] [ 0 0 -1 16 ] 0 6 6
|
||||
}
|
||||
}
|
||||
// entity 1
|
||||
{
|
||||
"classname" "func_detail_illusionary"
|
||||
"_mirrorinside" "1"
|
||||
// brush 0
|
||||
{
|
||||
( 16 -144 48 ) ( 16 -143 48 ) ( 16 -144 49 ) {trigger [ 0 1.0000000000000002 0 42.666664 ] [ 0 0 -1.0000000000000002 -32 ] 0 6 6
|
||||
( 16 -104 48 ) ( 16 -104 49 ) ( 17 -104 48 ) {trigger [ -1 0 0 32 ] [ 0 0 -1 -32 ] 0 6 6
|
||||
( 16 -144 16 ) ( 17 -144 16 ) ( 16 -143 16 ) {trigger [ -1.0000000000000002 0 0 32 ] [ 0 1.0000000000000002 0 -21.333336 ] 0 6 6
|
||||
( 96 -128 128 ) ( 96 -127 128 ) ( 97 -128 128 ) {trigger [ -1.0000000000000002 0 0 32 ] [ 0 -1.0000000000000002 0 -8 ] 0 6 6
|
||||
( 96 -80 64 ) ( 97 -80 64 ) ( 96 -80 65 ) {trigger [ -1 0 0 32 ] [ 0 0 -1 -32 ] 0 6 6
|
||||
( 40 -128 64 ) ( 40 -128 65 ) ( 40 -127 64 ) {trigger [ 0 -1.0000000000000002 0 12.000002 ] [ 0 0 -1.0000000000000002 -32 ] 0 6 6
|
||||
}
|
||||
}
|
||||
// entity 2
|
||||
{
|
||||
"classname" "light"
|
||||
"origin" "72 -136 168"
|
||||
"light" "3000"
|
||||
}
|
||||
// entity 3
|
||||
{
|
||||
"classname" "info_player_start"
|
||||
"origin" "-88 -64 120"
|
||||
}
|
||||
10
vis/vis.cc
10
vis/vis.cc
|
|
@ -608,11 +608,11 @@ static void ClusterFlow(int clusternum, leafbits_t &buffer, mbsp_t *bsp)
|
|||
bsp->dvis.set_bit_offset(VIS_PVS, clusternum, visofs);
|
||||
|
||||
// Set pointers
|
||||
// TODO: get rid of, we'll copy this data over from dvis
|
||||
// during conversion
|
||||
for (i = 1; i < bsp->dleafs.size(); i++) {
|
||||
if (bsp->dleafs[i].cluster == clusternum) {
|
||||
bsp->dleafs[i].visofs = visofs;
|
||||
if (bsp->loadversion->game->id == GAME_QUAKE_II) {
|
||||
for (i = 1; i < bsp->numleafs; i++) {
|
||||
if (bsp->dleafs[i].cluster == clusternum) {
|
||||
bsp->dleafs[i].visofs = leaf->visofs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue