qbsp: fix q2 liquids not mirrored
This commit is contained in:
parent
121c6384fe
commit
5372c4a568
|
|
@ -86,6 +86,8 @@ struct gamedef_generic_t : public gamedef_t
|
|||
|
||||
bool contents_are_empty(const contentflags_t &) const { throw std::bad_cast(); }
|
||||
|
||||
bool contents_are_mirrored(const contentflags_t &) const { throw std::bad_cast(); }
|
||||
|
||||
bool contents_are_solid(const contentflags_t &) const { throw std::bad_cast(); }
|
||||
|
||||
bool contents_are_sky(const contentflags_t &) const { throw std::bad_cast(); }
|
||||
|
|
@ -263,6 +265,18 @@ struct gamedef_q1_like_t : public gamedef_t
|
|||
return contents.native == CONTENTS_EMPTY;
|
||||
}
|
||||
|
||||
bool contents_are_mirrored(const contentflags_t &contents) const
|
||||
{
|
||||
if (contents.extended & CFLAGS_BMODEL_MIRROR_INSIDE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the brush is non-solid, mirror faces for the inside view
|
||||
return (contents.native == CONTENTS_WATER)
|
||||
|| (contents.native == CONTENTS_SLIME)
|
||||
|| (contents.native == CONTENTS_LAVA);
|
||||
}
|
||||
|
||||
bool contents_are_solid(const contentflags_t &contents) const
|
||||
{
|
||||
if (contents.extended & CFLAGS_CONTENTS_MASK)
|
||||
|
|
@ -650,6 +664,14 @@ struct gamedef_q2_t : public gamedef_t
|
|||
return !(contents.native & Q2_ALL_VISIBLE_CONTENTS);
|
||||
}
|
||||
|
||||
bool contents_are_mirrored(const contentflags_t &contents) const
|
||||
{
|
||||
// fixme-brushbsp: support some way of opting out of mirrorinside
|
||||
|
||||
// If the brush is non-solid, mirror faces for the inside view
|
||||
return !(contents.native & Q2_CONTENTS_SOLID);
|
||||
}
|
||||
|
||||
bool contents_are_solid(const contentflags_t &contents) const
|
||||
{
|
||||
if (contents.extended & CFLAGS_CONTENTS_MASK)
|
||||
|
|
@ -1124,6 +1146,11 @@ bool contentflags_t::is_empty(const gamedef_t *game) const
|
|||
return game->contents_are_empty(*this);
|
||||
}
|
||||
|
||||
bool contentflags_t::is_mirrored(const gamedef_t *game) const
|
||||
{
|
||||
return game->contents_are_mirrored(*this);
|
||||
}
|
||||
|
||||
bool contentflags_t::is_solid(const gamedef_t *game) const
|
||||
{
|
||||
return game->contents_are_solid(*this);
|
||||
|
|
|
|||
|
|
@ -605,6 +605,8 @@ struct contentflags_t
|
|||
|
||||
bool is_empty(const gamedef_t *game) const;
|
||||
|
||||
bool is_mirrored(const gamedef_t *game) const;
|
||||
|
||||
// detail solid or structural solid
|
||||
bool is_any_solid(const gamedef_t *game) const {
|
||||
return is_solid(game)
|
||||
|
|
@ -1815,6 +1817,7 @@ struct gamedef_t
|
|||
virtual bool contents_are_detail_fence(const contentflags_t &contents) const = 0;
|
||||
virtual bool contents_are_detail_illusionary(const contentflags_t &contents) const = 0;
|
||||
virtual bool contents_are_empty(const contentflags_t &contents) const = 0;
|
||||
virtual bool contents_are_mirrored(const contentflags_t &contents) const = 0;
|
||||
virtual bool contents_are_solid(const contentflags_t &contents) const = 0;
|
||||
virtual bool contents_are_sky(const contentflags_t &contents) const = 0;
|
||||
virtual bool contents_are_liquid(const contentflags_t &contents) const = 0;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,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);
|
||||
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
|
||||
|
|
|
|||
|
|
@ -654,26 +654,10 @@ static void AddFaceToTree_r(mapentity_t* entity, face_t *face, brush_t *srcbrush
|
|||
for (face_t *part : faces) {
|
||||
node->facelist.push_back(part);
|
||||
|
||||
// fixme-brushbsp: move to contentflags_t helper
|
||||
/*
|
||||
* If the brush is non-solid, mirror faces for the inside view
|
||||
*/
|
||||
bool mirror = (srcbrush->contents.extended & CFLAGS_BMODEL_MIRROR_INSIDE);
|
||||
|
||||
if (!(srcbrush->contents.is_solid(options.target_game) ||
|
||||
srcbrush->contents.is_any_detail(options.target_game) ||
|
||||
srcbrush->contents.is_sky(options.target_game))) {
|
||||
mirror = true;
|
||||
}
|
||||
|
||||
if (mirror) {
|
||||
if (srcbrush->contents.is_mirrored(options.target_game)) {
|
||||
node->facelist.push_back(MirrorFace(part));
|
||||
}
|
||||
}
|
||||
|
||||
// fixme-brushbsp: need to continue clipping it down the bsp tree,
|
||||
// this currently leaves bits floating in the void that happen to touch splitting nodes
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1179,6 +1179,7 @@ TEST_CASE("lavawater", "[testmaps_q2]") {
|
|||
|
||||
/**
|
||||
* Weird mystery issue with a func_wall with broken collision
|
||||
* (ended up being a PLANE_X/Y/Z plane with negative facing normal, which is illegal - engine assumes they are positive)
|
||||
*/
|
||||
TEST_CASE("qbsp_q2_bmodel_collision", "[testmaps_q2]") {
|
||||
const mbsp_t bsp = LoadTestmapQ2("qbsp_q2_bmodel_collision.map");
|
||||
|
|
@ -1190,6 +1191,15 @@ TEST_CASE("qbsp_q2_bmodel_collision", "[testmaps_q2]") {
|
|||
CHECK(Q2_CONTENTS_SOLID == BSP_FindLeafAtPoint(&bsp, &bsp.dmodels[1], in_bmodel)->contents);
|
||||
}
|
||||
|
||||
TEST_CASE("q2_liquids", "[testmaps_q2]")
|
||||
{
|
||||
const mbsp_t bsp = LoadTestmapQ2("q2_liquids.map");
|
||||
|
||||
// water is two sided
|
||||
const qvec3d water_top {-116, -168, 144};
|
||||
CHECK(2 == BSP_FindFacesAtPoint(&bsp, &bsp.dmodels[0], water_top).size());
|
||||
}
|
||||
|
||||
TEST_CASE("winding", "[benchmark]") {
|
||||
ankerl::nanobench::Bench bench;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue