node_t planenum
This commit is contained in:
parent
46a643c3f0
commit
a75f4239e3
|
|
@ -630,7 +630,10 @@ struct node_t
|
||||||
bool is_leaf = false;
|
bool is_leaf = false;
|
||||||
|
|
||||||
// information for decision nodes
|
// information for decision nodes
|
||||||
qbsp_plane_t plane; // decision node only
|
size_t planenum; // decision node only
|
||||||
|
|
||||||
|
const qbsp_plane_t &get_plane() const;
|
||||||
|
|
||||||
int firstface; // decision node only
|
int firstface; // decision node only
|
||||||
int numfaces; // decision node only
|
int numfaces; // decision node only
|
||||||
twosided<std::unique_ptr<node_t>>
|
twosided<std::unique_ptr<node_t>>
|
||||||
|
|
|
||||||
|
|
@ -621,10 +621,10 @@ static twosided<std::unique_ptr<bspbrush_t>> SplitBrush(std::unique_ptr<bspbrush
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CheckPlaneAgainstParents(const qbsp_plane_t &plane, node_t *node)
|
inline void CheckPlaneAgainstParents(size_t planenum, node_t *node)
|
||||||
{
|
{
|
||||||
for (node_t *p = node->parent; p; p = p->parent) {
|
for (node_t *p = node->parent; p; p = p->parent) {
|
||||||
if (qv::epsilonEqual(p->plane, plane)) {
|
if (p->planenum == planenum) {
|
||||||
Error("Tried parent");
|
Error("Tried parent");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -875,9 +875,10 @@ static std::optional<size_t> SelectSplitPlane(const std::vector<std::unique_ptr<
|
||||||
if (side.visible ^ (pass < 2))
|
if (side.visible ^ (pass < 2))
|
||||||
continue; // only check visible faces on first pass
|
continue; // only check visible faces on first pass
|
||||||
|
|
||||||
|
size_t positive_planenum = side.planenum & ~1;
|
||||||
const qbsp_plane_t &plane = side.get_positive_plane(); // always use positive facing plane
|
const qbsp_plane_t &plane = side.get_positive_plane(); // always use positive facing plane
|
||||||
|
|
||||||
CheckPlaneAgainstParents(plane, node);
|
CheckPlaneAgainstParents(positive_planenum, node);
|
||||||
|
|
||||||
if (!CheckPlaneAgainstVolume(plane, node, stats))
|
if (!CheckPlaneAgainstVolume(plane, node, stats))
|
||||||
continue; // would produce a tiny volume
|
continue; // would produce a tiny volume
|
||||||
|
|
@ -892,7 +893,7 @@ static std::optional<size_t> SelectSplitPlane(const std::vector<std::unique_ptr<
|
||||||
|
|
||||||
for (auto &test : brushes) {
|
for (auto &test : brushes) {
|
||||||
int bsplits;
|
int bsplits;
|
||||||
int s = TestBrushToPlanenum(*test, side.planenum & ~1, &bsplits, &hintsplit, &epsilonbrush);
|
int s = TestBrushToPlanenum(*test, positive_planenum, &bsplits, &hintsplit, &epsilonbrush);
|
||||||
|
|
||||||
splits += bsplits;
|
splits += bsplits;
|
||||||
if (bsplits && (s & PSIDE_FACING))
|
if (bsplits && (s & PSIDE_FACING))
|
||||||
|
|
@ -1054,10 +1055,10 @@ static void BuildTree_r(node_t *node, std::vector<std::unique_ptr<bspbrush_t>> b
|
||||||
// make sure this was a positive-facing split
|
// make sure this was a positive-facing split
|
||||||
Q_assert(!(bestplane.value() & 1));
|
Q_assert(!(bestplane.value() & 1));
|
||||||
|
|
||||||
auto &plane = map.get_plane(bestplane.value());
|
node->planenum = bestplane.value();
|
||||||
node->plane.set_plane(plane);
|
|
||||||
|
|
||||||
auto children = SplitBrushList(std::move(brushes), node->plane, stats);
|
auto &plane = map.get_plane(bestplane.value());
|
||||||
|
auto children = SplitBrushList(std::move(brushes), plane, stats);
|
||||||
|
|
||||||
// allocate children before recursing
|
// allocate children before recursing
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
|
|
@ -1074,7 +1075,7 @@ static void BuildTree_r(node_t *node, std::vector<std::unique_ptr<bspbrush_t>> b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto children_volumes = SplitBrush(node->volume->copy_unique(), node->plane, stats);
|
auto children_volumes = SplitBrush(node->volume->copy_unique(), plane, stats);
|
||||||
node->children[0]->volume = std::move(children_volumes[0]);
|
node->children[0]->volume = std::move(children_volumes[0]);
|
||||||
node->children[1]->volume = std::move(children_volumes[1]);
|
node->children[1]->volume = std::move(children_volumes[1]);
|
||||||
|
|
||||||
|
|
@ -1135,9 +1136,9 @@ static std::unique_ptr<tree_t> BrushBSP(mapentity_t *entity, std::vector<std::un
|
||||||
*/
|
*/
|
||||||
auto headnode = std::make_unique<node_t>();
|
auto headnode = std::make_unique<node_t>();
|
||||||
headnode->bounds = entity->bounds;
|
headnode->bounds = entity->bounds;
|
||||||
// The choice of plane is mostly unimportant, but having it at (0, 0, 0) was affecting
|
// The choice of plane is mostly unimportant, but having it at (0, 0, 0) affects
|
||||||
// the node bounds calculation. So to be safe, put the plane on the top of the entity bounding box.
|
// the node bounds calculation.
|
||||||
headnode->plane = {{0, 0, 1}, headnode->bounds.maxs()[2]};
|
headnode->planenum = 0;
|
||||||
headnode->children[0] = std::make_unique<node_t>();
|
headnode->children[0] = std::make_unique<node_t>();
|
||||||
headnode->children[0]->is_leaf = true;
|
headnode->children[0]->is_leaf = true;
|
||||||
headnode->children[0]->contents = qbsp_options.target_game->create_empty_contents();
|
headnode->children[0]->contents = qbsp_options.target_game->create_empty_contents();
|
||||||
|
|
|
||||||
|
|
@ -295,7 +295,7 @@ static void AddMarksurfaces_r(face_t *face, std::unique_ptr<face_t> face_copy, n
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const qplane3d &splitplane = node->plane;
|
const qplane3d &splitplane = node->get_plane();
|
||||||
|
|
||||||
auto [frontFragment, backFragment] = SplitFace(std::move(face_copy), splitplane);
|
auto [frontFragment, backFragment] = SplitFace(std::move(face_copy), splitplane);
|
||||||
if (frontFragment) {
|
if (frontFragment) {
|
||||||
|
|
@ -479,7 +479,7 @@ static std::unique_ptr<face_t> FaceFromPortal(portal_t *p, bool pside)
|
||||||
auto f = std::make_unique<face_t>();
|
auto f = std::make_unique<face_t>();
|
||||||
|
|
||||||
f->texinfo = side->texinfo;
|
f->texinfo = side->texinfo;
|
||||||
f->planenum = (side->planenum & ~1) | pside;
|
f->planenum = (side->planenum & ~1) | (pside ? 1 : 0);
|
||||||
f->portal = p;
|
f->portal = p;
|
||||||
f->lmshift = side->lmshift;
|
f->lmshift = side->lmshift;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ static node_t *PointInLeaf(node_t *node, const qvec3d &point)
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec_t dist = node->plane.distance_to(point);
|
vec_t dist = node->get_plane().distance_to(point);
|
||||||
|
|
||||||
if (dist > 0) {
|
if (dist > 0) {
|
||||||
// point is on the front of the node plane
|
// point is on the front of the node plane
|
||||||
|
|
|
||||||
|
|
@ -197,13 +197,13 @@ constexpr vec_t SPLIT_WINDING_EPSILON = 0.001;
|
||||||
|
|
||||||
static std::optional<winding_t> BaseWindingForNode(const node_t *node)
|
static std::optional<winding_t> BaseWindingForNode(const node_t *node)
|
||||||
{
|
{
|
||||||
std::optional<winding_t> w = BaseWindingForPlane(node->plane);
|
std::optional<winding_t> w = BaseWindingForPlane(node->get_plane());
|
||||||
|
|
||||||
// clip by all the parents
|
// clip by all the parents
|
||||||
for (auto *np = node->parent; np && w;) {
|
for (auto *np = node->parent; np && w;) {
|
||||||
const planeside_t keep = (np->children[0].get() == node) ? SIDE_FRONT : SIDE_BACK;
|
const planeside_t keep = (np->children[0].get() == node) ? SIDE_FRONT : SIDE_BACK;
|
||||||
|
|
||||||
w = w->clip(np->plane, BASE_WINDING_EPSILON, false)[keep];
|
w = w->clip(np->get_plane(), BASE_WINDING_EPSILON, false)[keep];
|
||||||
|
|
||||||
node = np;
|
node = np;
|
||||||
np = np->parent;
|
np = np->parent;
|
||||||
|
|
@ -250,7 +250,7 @@ std::unique_ptr<buildportal_t> MakeNodePortal(node_t *node, const std::list<std:
|
||||||
}
|
}
|
||||||
|
|
||||||
auto new_portal = std::make_unique<buildportal_t>();
|
auto new_portal = std::make_unique<buildportal_t>();
|
||||||
new_portal->plane = node->plane;
|
new_portal->plane = node->get_plane();
|
||||||
new_portal->onnode = node;
|
new_portal->onnode = node;
|
||||||
new_portal->winding = std::make_unique<winding_t>(*w);
|
new_portal->winding = std::make_unique<winding_t>(*w);
|
||||||
new_portal->set_nodes(node->children[0].get(), node->children[1].get());
|
new_portal->set_nodes(node->children[0].get(), node->children[1].get());
|
||||||
|
|
@ -268,7 +268,7 @@ children have portals instead of node.
|
||||||
*/
|
*/
|
||||||
twosided<std::list<std::unique_ptr<buildportal_t>>> SplitNodePortals(const node_t *node, std::list<std::unique_ptr<buildportal_t>> boundary_portals, portalstats_t &stats)
|
twosided<std::list<std::unique_ptr<buildportal_t>>> SplitNodePortals(const node_t *node, std::list<std::unique_ptr<buildportal_t>> boundary_portals, portalstats_t &stats)
|
||||||
{
|
{
|
||||||
const auto &plane = node->plane;
|
const auto &plane = node->get_plane();
|
||||||
node_t *f = node->children[0].get();
|
node_t *f = node->children[0].get();
|
||||||
node_t *b = node->children[1].get();
|
node_t *b = node->children[1].get();
|
||||||
|
|
||||||
|
|
@ -791,7 +791,7 @@ static void FindPortalSide(portal_t *p)
|
||||||
// bestside[0] is the brushside visible on portal side[0] which is the positive side of the plane, always
|
// bestside[0] is the brushside visible on portal side[0] which is the positive side of the plane, always
|
||||||
side_t *bestside[2] = {nullptr, nullptr};
|
side_t *bestside[2] = {nullptr, nullptr};
|
||||||
float bestdot = 0;
|
float bestdot = 0;
|
||||||
const qbsp_plane_t &p1 = p->onnode->plane;
|
const qbsp_plane_t &p1 = p->onnode->get_plane();
|
||||||
|
|
||||||
// check brushes on both sides of the portal
|
// check brushes on both sides of the portal
|
||||||
for (int j = 0; j < 2; j++) {
|
for (int j = 0; j < 2; j++) {
|
||||||
|
|
@ -816,7 +816,7 @@ static void FindPortalSide(portal_t *p)
|
||||||
// fixme-brushbsp: restore
|
// fixme-brushbsp: restore
|
||||||
// if (!side.visible)
|
// if (!side.visible)
|
||||||
// continue; // non-visible
|
// continue; // non-visible
|
||||||
if (qv::epsilonEqual(side.get_positive_plane(), p1)) {
|
if ((side.planenum & ~1) == p->onnode->planenum) {
|
||||||
// exact match (undirectional)
|
// exact match (undirectional)
|
||||||
|
|
||||||
// because the brush is on j of the positive plane, the brushside must be facing away from j
|
// because the brush is on j of the positive plane, the brushside must be facing away from j
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,11 @@ const qbsp_plane_t &face_t::get_positive_plane() const
|
||||||
return map.get_plane(planenum & ~1);
|
return map.get_plane(planenum & ~1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const qbsp_plane_t &node_t::get_plane() const
|
||||||
|
{
|
||||||
|
return map.get_plane(planenum);
|
||||||
|
}
|
||||||
|
|
||||||
// command line flags
|
// command line flags
|
||||||
namespace settings
|
namespace settings
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ static size_t ExportClipNodes(node_t *node)
|
||||||
|
|
||||||
// Careful not to modify the vector while using this clipnode pointer
|
// Careful not to modify the vector while using this clipnode pointer
|
||||||
bsp2_dclipnode_t &clipnode = map.bsp.dclipnodes[nodenum];
|
bsp2_dclipnode_t &clipnode = map.bsp.dclipnodes[nodenum];
|
||||||
clipnode.planenum = ExportMapPlane(node->plane);
|
clipnode.planenum = ExportMapPlane(node->get_plane());
|
||||||
clipnode.children[0] = child0;
|
clipnode.children[0] = child0;
|
||||||
clipnode.children[1] = child1;
|
clipnode.children[1] = child1;
|
||||||
|
|
||||||
|
|
@ -249,7 +249,7 @@ static void ExportDrawNodes(node_t *node)
|
||||||
dnode->mins = qv::floor(node->bounds.mins());
|
dnode->mins = qv::floor(node->bounds.mins());
|
||||||
dnode->maxs = qv::ceil(node->bounds.maxs());
|
dnode->maxs = qv::ceil(node->bounds.maxs());
|
||||||
|
|
||||||
dnode->planenum = ExportMapPlane(node->plane);
|
dnode->planenum = ExportMapPlane(node->get_plane());
|
||||||
dnode->firstface = node->firstface;
|
dnode->firstface = node->firstface;
|
||||||
dnode->numfaces = node->numfaces;
|
dnode->numfaces = node->numfaces;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue