qbsp: use unique_ptr for portal_t
This commit is contained in:
parent
de68bee886
commit
4ab4cb7dc8
|
|
@ -28,7 +28,6 @@ class mapentity_t;
|
|||
struct face_t;
|
||||
|
||||
std::list<face_t *> SubdivideFace(face_t *f);
|
||||
void FreeNodes(node_t *node);
|
||||
void MakeVisibleFaces(mapentity_t *entity, node_t *headnode);
|
||||
void MakeMarkFaces(mapentity_t* entity, node_t* headnode);
|
||||
void MakeFaces(node_t *node);
|
||||
|
|
|
|||
|
|
@ -51,11 +51,11 @@ struct portalstats_t {
|
|||
contentflags_t ClusterContents(const node_t *node);
|
||||
bool Portal_VisFlood(const portal_t *p);
|
||||
bool Portal_EntityFlood(const portal_t *p, int32_t s);
|
||||
void MakeNodePortal(node_t *node, portalstats_t &stats);
|
||||
void SplitNodePortals(node_t *node, portalstats_t &stats);
|
||||
void MakeNodePortal(tree_t *tree, node_t *node, portalstats_t &stats);
|
||||
void SplitNodePortals(tree_t *tree, node_t *node, portalstats_t &stats);
|
||||
void MakeTreePortals(tree_t *tree);
|
||||
void FreeTreePortals_r(node_t *node);
|
||||
void AssertNoPortals(node_t *node);
|
||||
void FreeTreePortals(tree_t *tree);
|
||||
void AssertNoPortals(tree_t *tree);
|
||||
void MakeHeadnodePortals(tree_t *tree);
|
||||
void EmitAreaPortals(node_t *headnode);
|
||||
void FloodAreas(mapentity_t *entity, node_t *headnode);
|
||||
|
|
|
|||
|
|
@ -27,14 +27,23 @@
|
|||
#include <common/qvec.hh>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
struct node_t;
|
||||
struct portal_t;
|
||||
|
||||
struct tree_t
|
||||
{
|
||||
std::unique_ptr<node_t> headnode;
|
||||
node_t outside_node = {}; // portals outside the world face this
|
||||
aabb3d bounds;
|
||||
|
||||
// here for ownership/memory management - not intended to be iterated directly
|
||||
std::vector<std::unique_ptr<portal_t>> portals;
|
||||
|
||||
// creates a new portal owned by `this` (stored in the `portals` vector) and
|
||||
// returns a raw pointer to it
|
||||
portal_t *create_portal();
|
||||
};
|
||||
|
||||
void DetailToSolid(node_t *node);
|
||||
|
|
|
|||
|
|
@ -173,24 +173,6 @@ static void SubdivideNodeFaces(node_t *node)
|
|||
node->facelist = result;
|
||||
}
|
||||
|
||||
static void FreeNode(node_t *node)
|
||||
{
|
||||
FreeTreePortals_r(node);
|
||||
for (face_t *f : node->facelist) {
|
||||
delete f;
|
||||
}
|
||||
delete node;
|
||||
}
|
||||
|
||||
void FreeNodes(node_t *node)
|
||||
{
|
||||
if (node->planenum != PLANENUM_LEAF) {
|
||||
FreeNodes(node->children[0].get());
|
||||
FreeNodes(node->children[1].get());
|
||||
}
|
||||
FreeNode(node);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
// This is a kludge. Should be pEdgeFaces[2].
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ void MakeHeadnodePortals(tree_t *tree)
|
|||
for (j = 0; j < 2; j++) {
|
||||
n = j * 3 + i;
|
||||
|
||||
p = new portal_t{};
|
||||
p = tree->create_portal();
|
||||
portals[n] = p;
|
||||
|
||||
qplane3d &pl = bplanes[n] = {};
|
||||
|
|
@ -254,7 +254,7 @@ and clipping it by all of parents of this node, as well as all the other
|
|||
portals in the node.
|
||||
==================
|
||||
*/
|
||||
void MakeNodePortal(node_t *node, portalstats_t &stats)
|
||||
void MakeNodePortal(tree_t *tree, node_t *node, portalstats_t &stats)
|
||||
{
|
||||
const auto lock = std::lock_guard(map_planes_lock);
|
||||
|
||||
|
|
@ -291,7 +291,7 @@ void MakeNodePortal(node_t *node, portalstats_t &stats)
|
|||
return;
|
||||
}
|
||||
|
||||
auto *new_portal = new portal_t{};
|
||||
portal_t *new_portal = tree->create_portal();
|
||||
new_portal->planenum = node->planenum;
|
||||
new_portal->onnode = node;
|
||||
new_portal->winding = w;
|
||||
|
|
@ -306,7 +306,7 @@ Move or split the portals that bound node so that the node's
|
|||
children have portals instead of node.
|
||||
==============
|
||||
*/
|
||||
void SplitNodePortals(node_t *node, portalstats_t &stats)
|
||||
void SplitNodePortals(tree_t *tree, node_t *node, portalstats_t &stats)
|
||||
{
|
||||
const auto lock = std::lock_guard(map_planes_lock);
|
||||
|
||||
|
|
@ -370,7 +370,8 @@ void SplitNodePortals(node_t *node, portalstats_t &stats)
|
|||
}
|
||||
|
||||
// the winding is split
|
||||
auto *new_portal = new portal_t{*p};
|
||||
portal_t *new_portal = tree->create_portal();
|
||||
*new_portal = *p;
|
||||
new_portal->winding = backwinding;
|
||||
p->winding = frontwinding;
|
||||
|
||||
|
|
@ -413,7 +414,7 @@ void CalcNodeBounds(node_t *node)
|
|||
MakeTreePortals_r
|
||||
==================
|
||||
*/
|
||||
void MakeTreePortals_r(node_t *node, portalstats_t &stats)
|
||||
void MakeTreePortals_r(tree_t *tree, node_t *node, portalstats_t &stats)
|
||||
{
|
||||
CalcNodeBounds(node);
|
||||
if (node->bounds.mins()[0] >= node->bounds.maxs()[0])
|
||||
|
|
@ -436,11 +437,11 @@ void MakeTreePortals_r(node_t *node, portalstats_t &stats)
|
|||
if (node->planenum == PLANENUM_LEAF)
|
||||
return;
|
||||
|
||||
MakeNodePortal(node, stats);
|
||||
SplitNodePortals(node, stats);
|
||||
MakeNodePortal(tree, node, stats);
|
||||
SplitNodePortals(tree, node, stats);
|
||||
|
||||
MakeTreePortals_r(node->children[0].get(), stats);
|
||||
MakeTreePortals_r(node->children[1].get(), stats);
|
||||
MakeTreePortals_r(tree, node->children[0].get(), stats);
|
||||
MakeTreePortals_r(tree, node->children[1].get(), stats);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -450,53 +451,57 @@ MakeTreePortals
|
|||
*/
|
||||
void MakeTreePortals(tree_t *tree)
|
||||
{
|
||||
FreeTreePortals_r(tree->headnode.get());
|
||||
FreeTreePortals(tree);
|
||||
|
||||
AssertNoPortals(tree->headnode.get());
|
||||
AssertNoPortals(tree);
|
||||
|
||||
portalstats_t stats{};
|
||||
|
||||
MakeHeadnodePortals(tree);
|
||||
MakeTreePortals_r(tree->headnode.get(), stats);
|
||||
MakeTreePortals_r(tree, tree->headnode.get(), stats);
|
||||
}
|
||||
|
||||
void AssertNoPortals(node_t *node)
|
||||
static void AssertNoPortals_r(node_t *node)
|
||||
{
|
||||
Q_assert(!node->portals);
|
||||
|
||||
if (node->planenum != PLANENUM_LEAF) {
|
||||
AssertNoPortals(node->children[0].get());
|
||||
AssertNoPortals(node->children[1].get());
|
||||
AssertNoPortals_r(node->children[0].get());
|
||||
AssertNoPortals_r(node->children[1].get());
|
||||
}
|
||||
}
|
||||
|
||||
void AssertNoPortals(tree_t *tree)
|
||||
{
|
||||
AssertNoPortals_r(tree->headnode.get());
|
||||
Q_assert(!tree->outside_node.portals);
|
||||
Q_assert(tree->portals.empty());
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
FreeTreePortals_r
|
||||
|
||||
==================
|
||||
*/
|
||||
void FreeTreePortals_r(node_t *node)
|
||||
static void ClearNodePortals_r(node_t *node)
|
||||
{
|
||||
portal_t *p, *nextp;
|
||||
|
||||
if (node->planenum != PLANENUM_LEAF) {
|
||||
FreeTreePortals_r(node->children[0].get());
|
||||
FreeTreePortals_r(node->children[1].get());
|
||||
ClearNodePortals_r(node->children[0].get());
|
||||
ClearNodePortals_r(node->children[1].get());
|
||||
}
|
||||
|
||||
for (p = node->portals; p; p = nextp) {
|
||||
if (p->nodes[0] == node)
|
||||
nextp = p->next[0];
|
||||
else
|
||||
nextp = p->next[1];
|
||||
RemovePortalFromNode(p, p->nodes[0]);
|
||||
RemovePortalFromNode(p, p->nodes[1]);
|
||||
delete p;
|
||||
}
|
||||
node->portals = nullptr;
|
||||
}
|
||||
|
||||
void FreeTreePortals(tree_t *tree)
|
||||
{
|
||||
ClearNodePortals_r(tree->headnode.get());
|
||||
tree->outside_node.portals = nullptr;
|
||||
|
||||
tree->portals.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
=========================================================
|
||||
|
||||
|
|
|
|||
|
|
@ -257,18 +257,18 @@ static void WritePortalfile(node_t *headnode, portal_state_t *state)
|
|||
CreateVisPortals_r
|
||||
================
|
||||
*/
|
||||
void CreateVisPortals_r(node_t *node, portalstats_t &stats)
|
||||
void CreateVisPortals_r(tree_t *tree, node_t *node, portalstats_t &stats)
|
||||
{
|
||||
// stop as soon as we get to a detail_seperator, which
|
||||
// means that everything below is in a single cluster
|
||||
if (node->planenum == PLANENUM_LEAF || node->detail_separator )
|
||||
return;
|
||||
|
||||
MakeNodePortal(node, stats);
|
||||
SplitNodePortals(node, stats);
|
||||
MakeNodePortal(tree, node, stats);
|
||||
SplitNodePortals(tree, node, stats);
|
||||
|
||||
CreateVisPortals_r(node->children[0].get(), stats);
|
||||
CreateVisPortals_r(node->children[1].get(), stats);
|
||||
CreateVisPortals_r(tree, node->children[0].get(), stats);
|
||||
CreateVisPortals_r(tree, node->children[1].get(), stats);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -282,13 +282,13 @@ void WritePortalFile(tree_t *tree)
|
|||
|
||||
portal_state_t state{};
|
||||
|
||||
FreeTreePortals_r(tree->headnode.get());
|
||||
FreeTreePortals(tree);
|
||||
|
||||
AssertNoPortals(tree->headnode.get());
|
||||
AssertNoPortals(tree);
|
||||
MakeHeadnodePortals(tree);
|
||||
|
||||
portalstats_t stats{};
|
||||
CreateVisPortals_r(tree->headnode.get(), stats);
|
||||
CreateVisPortals_r(tree, tree->headnode.get(), stats);
|
||||
|
||||
/* save portal file for vis tracing */
|
||||
WritePortalfile(tree->headnode.get(), &state);
|
||||
|
|
|
|||
|
|
@ -646,7 +646,7 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum)
|
|||
MarkVisibleSides(tree, entity);
|
||||
MakeFaces(tree->headnode.get());
|
||||
|
||||
FreeTreePortals_r(tree->headnode.get());
|
||||
FreeTreePortals(tree);
|
||||
PruneNodes(tree->headnode.get());
|
||||
|
||||
if (hullnum <= 0 && entity == map.world_entity() && (!map.leakfile || options.keepprt.value())) {
|
||||
|
|
|
|||
12
qbsp/tree.cc
12
qbsp/tree.cc
|
|
@ -24,6 +24,18 @@
|
|||
#include <common/vectorutils.hh>
|
||||
#include <qbsp/qbsp.hh>
|
||||
#include <qbsp/brush.hh>
|
||||
#include <qbsp/portals.hh>
|
||||
|
||||
//============================================================================
|
||||
|
||||
portal_t *tree_t::create_portal()
|
||||
{
|
||||
auto *result = new portal_t{};
|
||||
|
||||
portals.push_back(std::unique_ptr<portal_t>(result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue