qbsp: add very rough pass of building visible faces
- faces are subdivided where neeed - markfaces not calculated accurately - overlaps/clipping not handled
This commit is contained in:
parent
1fbfd199c5
commit
055f865ef0
|
|
@ -25,3 +25,4 @@
|
||||||
|
|
||||||
std::vector<surface_t> GatherNodeFaces(node_t *headnode);
|
std::vector<surface_t> GatherNodeFaces(node_t *headnode);
|
||||||
void FreeNodes(node_t* node);
|
void FreeNodes(node_t* node);
|
||||||
|
void MakeVisibleFaces(mapentity_t *entity, node_t *headnode);
|
||||||
|
|
@ -605,11 +605,15 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum)
|
||||||
else
|
else
|
||||||
nodes = SolidBSP(entity, entity == pWorldEnt());
|
nodes = SolidBSP(entity, entity == pWorldEnt());
|
||||||
|
|
||||||
|
MakeVisibleFaces(entity, nodes);
|
||||||
|
|
||||||
// build all the portals in the bsp tree
|
// build all the portals in the bsp tree
|
||||||
// some portals are solid polygons, and some are paths to other leafs
|
// some portals are solid polygons, and some are paths to other leafs
|
||||||
if (entity == pWorldEnt()) {
|
if (entity == pWorldEnt()) {
|
||||||
// assume non-world bmodels are simple
|
// assume non-world bmodels are simple
|
||||||
PortalizeWorld(entity, nodes, hullnum);
|
PortalizeWorld(entity, nodes, hullnum);
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (!options.fNofill && FillOutside(nodes, hullnum)) {
|
if (!options.fNofill && FillOutside(nodes, hullnum)) {
|
||||||
FreeAllPortals(nodes);
|
FreeAllPortals(nodes);
|
||||||
|
|
||||||
|
|
@ -632,6 +636,7 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum)
|
||||||
TJunc(entity, nodes);
|
TJunc(entity, nodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Area portals
|
// Area portals
|
||||||
if (options.target_game->id == GAME_QUAKE_II) {
|
if (options.target_game->id == GAME_QUAKE_II) {
|
||||||
|
|
|
||||||
|
|
@ -819,47 +819,6 @@ static void CreateLeaf(const std::vector<brush_t> &brushes, node_t *leafnode)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// fixme-brushbsp: move SubdivideFace call somewhere else
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
LinkNodeFaces
|
|
||||||
|
|
||||||
First subdivides surface->faces.
|
|
||||||
Then, duplicates the list of subdivided faces and returns it.
|
|
||||||
|
|
||||||
For each surface->faces, ->original is set to the respective duplicate that
|
|
||||||
is returned here (why?).
|
|
||||||
|
|
||||||
Called in parallel.
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
static std::list<face_t *> LinkNodeFaces(surface_t &surface)
|
|
||||||
{
|
|
||||||
// subdivide large faces
|
|
||||||
for (auto it = surface.faces.begin(); it != surface.faces.end(); it++) {
|
|
||||||
it = SubdivideFace(it, surface.faces);
|
|
||||||
}
|
|
||||||
|
|
||||||
surface.faces.reverse();
|
|
||||||
|
|
||||||
nodefaces += surface.faces.size();
|
|
||||||
|
|
||||||
std::list<face_t *> list;
|
|
||||||
|
|
||||||
// copy
|
|
||||||
for (auto &f : surface.faces) {
|
|
||||||
face_t *newf = new face_t(*f);
|
|
||||||
Q_assert(newf->original == nullptr);
|
|
||||||
|
|
||||||
list.push_front(newf);
|
|
||||||
f->original = newf;
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
PartitionBrushes
|
PartitionBrushes
|
||||||
|
|
|
||||||
|
|
@ -511,3 +511,97 @@ int MakeFaceEdges(mapentity_t *entity, node_t *headnode)
|
||||||
|
|
||||||
return firstface;
|
return firstface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
static int c_nodefaces;
|
||||||
|
|
||||||
|
static void AddMarksurfaces_r(face_t *face, node_t *node)
|
||||||
|
{
|
||||||
|
if (node->planenum == PLANENUM_LEAF) {
|
||||||
|
node->markfaces.push_back(face);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddMarksurfaces_r(face, node->children[0]);
|
||||||
|
AddMarksurfaces_r(face, node->children[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddFaceToTree_r(face_t *face, node_t* node)
|
||||||
|
{
|
||||||
|
if (node->planenum == PLANENUM_LEAF) {
|
||||||
|
if (!face->w.size()) {
|
||||||
|
// spurious
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FError("couldn't find node for face");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (face->planenum == node->planenum) {
|
||||||
|
// found the correct plane - add the face to it.
|
||||||
|
|
||||||
|
++c_nodefaces;
|
||||||
|
|
||||||
|
// subdivide large faces
|
||||||
|
// fixme-brushbsp: weird calling convention
|
||||||
|
auto parts = std::list<face_t *>{face};
|
||||||
|
for (auto it = parts.begin(); it != parts.end(); it++) {
|
||||||
|
it = SubdivideFace(it, parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (face_t *part : parts) {
|
||||||
|
node->facelist.push_back(part);
|
||||||
|
|
||||||
|
// Now that the final face has been added
|
||||||
|
// fixme-brushbsp: do this as a postprocessing step
|
||||||
|
AddMarksurfaces_r(part, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fixme-brushbsp: we need to handle the case of the face being near enough that it gets clipped away,
|
||||||
|
// but not face->planenum == node->planenum
|
||||||
|
auto [frontWinding, backWinding] = face->w.clip(map.planes[node->planenum]);
|
||||||
|
if (frontWinding) {
|
||||||
|
auto *newFace = new face_t{*face};
|
||||||
|
newFace->w = *frontWinding;
|
||||||
|
AddFaceToTree_r(newFace, node->children[0]);
|
||||||
|
}
|
||||||
|
if (backWinding) {
|
||||||
|
auto *newFace = new face_t{*face};
|
||||||
|
newFace->w = *backWinding;
|
||||||
|
AddFaceToTree_r(newFace, node->children[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete face;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
MakeVisibleFaces
|
||||||
|
|
||||||
|
Given a completed BSP tree and a list of brushes (in `entity`),
|
||||||
|
|
||||||
|
- filters the brush faces into the BSP, finding the correct nodes they end up on
|
||||||
|
- clips the faces by other brushes.
|
||||||
|
|
||||||
|
first iteration, we can just do an exhaustive check against all brushes
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void MakeVisibleFaces(mapentity_t* entity, node_t* headnode)
|
||||||
|
{
|
||||||
|
c_nodefaces = 0;
|
||||||
|
|
||||||
|
for (auto &brush : entity->brushes) {
|
||||||
|
for (auto &face : brush.faces) {
|
||||||
|
|
||||||
|
face_t *temp = NewFaceFromFace(&face);
|
||||||
|
temp->w = face.w;
|
||||||
|
|
||||||
|
AddFaceToTree_r(temp, headnode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogPrint("{} nodefaces\n", c_nodefaces);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@
|
||||||
( -80 -96 80 ) ( -81 -96 80 ) ( -80 -96 81 ) orangestuff8 [ -1 0 0 16 ] [ 0 0 -1 0 ] 180 1 1
|
( -80 -96 80 ) ( -81 -96 80 ) ( -80 -96 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
|
( -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 -112 96 ) ( -161 -112 96 ) ( -160 -111 96 ) orangestuff8 [ -1 0 0 16 ] [ 0 -1 0 16 ] 180 1 1
|
||||||
( -160 -32 96 ) ( -160 -32 97 ) ( -161 -32 96 ) orangestuff8 [ 1 0 0 -16 ] [ 0 0 -1 0 ] 180 1 1
|
( -160 128 96 ) ( -160 128 97 ) ( -161 128 96 ) orangestuff8 [ 1 0 0 -16 ] [ 0 0 -1 0 ] 180 1 1
|
||||||
( -64 -432 80 ) ( -64 -432 81 ) ( -64 -431 80 ) orangestuff8 [ 0 -1 0 16 ] [ 0 0 -1 0 ] 0 1 1
|
( 144 -432 80 ) ( 144 -432 81 ) ( 144 -431 80 ) orangestuff8 [ 0 -1 0 16 ] [ 0 0 -1 0 ] 0 1 1
|
||||||
}
|
}
|
||||||
// brush 1
|
// brush 1
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue