Fix a few messages (missing newlines, period in wrong place)

Use fragments to store TJunction bits instead of having them in separate-but-chained faces
This commit is contained in:
Jonathan 2022-01-25 03:23:39 -05:00
parent dfd31d7441
commit 674be0c812
5 changed files with 89 additions and 67 deletions

View File

@ -204,7 +204,15 @@ struct mtexinfo_t
class mapentity_t;
struct face_t
struct face_fragment_t
{
winding_t w;
std::vector<size_t> edges; // only filled in MakeFaceEdges
std::optional<size_t> outputnumber; // only valid for original faces after
// write surfaces
};
struct face_t : face_fragment_t
{
face_t *next;
@ -216,14 +224,12 @@ struct face_t
mapentity_t *src_entity; // source entity
face_t *original; // face on node
std::optional<size_t> outputnumber; // only valid for original faces after
// write surfaces
bool touchesOccupiedLeaf; // internal use in outside.cc
qvec3d origin;
vec_t radius;
std::vector<size_t> edges; // only filled in MakeFaceEdges
winding_t w;
// filled by TJunc
std::list<face_fragment_t> fragments;
};
struct surface_t

View File

@ -1543,13 +1543,13 @@ mapbrush_t ParseBrush(parser_t &parser, const mapentity_t *entity)
for (int i = 0; i < brush.numfaces; i++) {
const mapface_t &check = brush.face(i);
if (qv::epsilonEqual(check.plane, face->plane)) {
LogPrint("line {}: Brush with duplicate plane", parser.linenum);
LogPrint("line {}: Brush with duplicate plane\n", parser.linenum);
discardFace = true;
continue;
}
if (qv::epsilonEqual(-check.plane, face->plane)) {
/* FIXME - this is actually an invalid brush */
LogPrint("line {}: Brush with duplicate plane", parser.linenum);
LogPrint("line {}: Brush with duplicate plane\n", parser.linenum);
continue;
}
}
@ -1874,7 +1874,7 @@ void LoadMapFile(void)
auto file = fs::load(options.szMapName);
if (!file) {
FError("Couldn't load map file \"{}.\"\n", options.szMapName);
FError("Couldn't load map file \"{}\".\n", options.szMapName);
return;
}

View File

@ -317,6 +317,23 @@ inline size_t GetEdge(mapentity_t *entity, const qvec3d &p1, const qvec3d &p2, c
return i;
}
static void FindFaceFragmentEdges(mapentity_t *entity, face_t *face, face_fragment_t *fragment)
{
fragment->outputnumber = std::nullopt;
if (fragment->w.size() > MAXEDGES) {
FError("Internal error: face->numpoints > MAXEDGES");
}
fragment->edges.resize(fragment->w.size());
for (size_t i = 0; i < fragment->w.size(); i++) {
const qvec3d &p1 = fragment->w[i];
const qvec3d &p2 = fragment->w[(i + 1) % fragment->w.size()];
fragment->edges[i] = GetEdge(entity, p1, p2, face);
}
}
/*
==================
FindFaceEdges
@ -329,16 +346,10 @@ static void FindFaceEdges(mapentity_t *entity, face_t *face)
if (map.mtexinfos.at(face->texinfo).flags.is_hint)
return;
face->outputnumber = std::nullopt;
if (face->w.size() > MAXEDGES)
FError("Internal error: face->numpoints > MAXEDGES");
FindFaceFragmentEdges(entity, face, face);
face->edges.resize(face->w.size());
for (size_t i = 0; i < face->w.size(); i++) {
const qvec3d &p1 = face->w[i];
const qvec3d &p2 = face->w[(i + 1) % face->w.size()];
face->edges[i] = GetEdge(entity, p1, p2, face);
for (auto &fragment : face->fragments) {
FindFaceFragmentEdges(entity, face, &fragment);
}
}
@ -365,21 +376,16 @@ static int MakeFaceEdges_r(mapentity_t *entity, node_t *node, int progress)
/*
==============
EmitFace
EmitFaceFragment
==============
*/
static void EmitFace(mapentity_t *entity, face_t *face)
static void EmitFaceFragment(mapentity_t *entity, face_t *face, face_fragment_t *fragment)
{
int i;
if (!options.includeSkip && map.mtexinfos.at(face->texinfo).flags.is_skip)
return;
if (map.mtexinfos.at(face->texinfo).flags.is_hint)
return;
// emit a region
Q_assert(!face->outputnumber.has_value());
face->outputnumber = map.bsp.dfaces.size();
Q_assert(!fragment->outputnumber.has_value());
fragment->outputnumber = map.bsp.dfaces.size();
mface_t &out = map.bsp.dfaces.emplace_back();
@ -396,12 +402,31 @@ static void EmitFace(mapentity_t *entity, face_t *face)
// emit surfedges
out.firstedge = static_cast<int32_t>(map.bsp.dsurfedges.size());
std::copy(face->edges.cbegin(), face->edges.cbegin() + face->w.size(), std::back_inserter(map.bsp.dsurfedges));
face->edges.clear();
std::copy(fragment->edges.cbegin(), fragment->edges.cbegin() + fragment->w.size(), std::back_inserter(map.bsp.dsurfedges));
fragment->edges.clear();
out.numedges = static_cast<int32_t>(map.bsp.dsurfedges.size()) - out.firstedge;
}
/*
==============
EmitFace
==============
*/
static void EmitFace(mapentity_t *entity, face_t *face)
{
if (!options.includeSkip && map.mtexinfos.at(face->texinfo).flags.is_skip)
return;
if (map.mtexinfos.at(face->texinfo).flags.is_hint)
return;
EmitFaceFragment(entity, face, face);
for (auto &fragment : face->fragments) {
EmitFaceFragment(entity, face, &fragment);
}
}
/*
==============
GrowNodeRegion

View File

@ -238,25 +238,20 @@ static void AddFaceEdges(face_t *f)
*/
#define MAX_SUPERFACE_POINTS 8192
static void SplitFaceForTjunc(face_t *face, face_t *original, face_t **facelist)
static void SplitFaceForTjunc(face_t *face, face_t *original)
{
winding_t &w = face->w;
face_t *newf, *chain;
qvec3d edgevec[2];
vec_t angle;
int i, firstcorner, lastcorner;
chain = NULL;
do {
if (w.size() <= MAXPOINTS) {
/*
* the face is now small enough without more cutting so
* copy it back to the original
*/
*original = *face;
original->original = chain;
original->next = *facelist;
*facelist = original;
*original = std::move(*face);
return;
}
@ -298,27 +293,23 @@ restart:
* cut off as big a piece as possible, less than MAXPOINTS, and not
* past lastcorner
*/
newf = NewFaceFromFace(face);
if (face->original)
FError("original face still exists");
winding_t neww(face->w);
newf->original = chain;
chain = newf;
newf->next = *facelist;
*facelist = newf;
if (w.size() - firstcorner <= MAXPOINTS)
newf->w.resize(firstcorner + 2);
neww.resize(firstcorner + 2);
else if (lastcorner + 2 < MAXPOINTS && w.size() - lastcorner <= MAXPOINTS)
newf->w.resize(lastcorner + 2);
neww.resize(lastcorner + 2);
else
newf->w.resize(MAXPOINTS);
neww.resize(MAXPOINTS);
for (i = 0; i < newf->w.size(); i++)
newf->w[i] = w[i];
for (i = newf->w.size() - 1; i < w.size(); i++)
w[i - (newf->w.size() - 2)] = w[i];
for (i = 0; i < neww.size(); i++)
Q_assert(qv::equalExact(neww[i], w[i]));
for (i = neww.size() - 1; i < w.size(); i++)
w[i - (neww.size() - 2)] = w[i];
w.resize(w.size() - (newf->w.size() - 2));
w.resize(w.size() - (neww.size() - 2));
face->fragments.emplace_front(face_fragment_t { std::move(neww) });
} while (1);
}
@ -328,14 +319,14 @@ FixFaceEdges
===============
*/
static void FixFaceEdges(face_t *face, face_t *superface, face_t **facelist)
static void FixFaceEdges(face_t *face, face_t *superface)
{
int i, j;
wedge_t *edge;
wvert_t *v;
vec_t t1, t2;
*superface = *face;
*superface = std::move(*face);
restart:
for (i = 0; i < superface->w.size(); i++) {
@ -366,14 +357,12 @@ restart:
}
if (superface->w.size() <= MAXPOINTS) {
*face = *superface;
face->next = *facelist;
*facelist = face;
*face = std::move(*superface);
return;
}
/* Too many edges - needs to be split into multiple faces */
SplitFaceForTjunc(superface, face, facelist);
SplitFaceForTjunc(superface, face);
}
//============================================================================
@ -408,19 +397,19 @@ static void tjunc_find_r(node_t *node)
static void tjunc_fix_r(node_t *node, face_t *superface)
{
face_t *face, *next, *facelist;
if (node->planenum == PLANENUM_LEAF)
return;
facelist = NULL;
for (face = node->faces; face; face = next) {
face_t *root = nullptr, *next;
for (face_t *face = node->faces; face; face = next) {
next = face->next;
FixFaceEdges(face, superface, &facelist);
FixFaceEdges(face, superface);
face->next = root;
root = face;
}
node->faces = facelist;
node->faces = root;
tjunc_fix_r(node->children[0], superface);
tjunc_fix_r(node->children[1], superface);

View File

@ -193,10 +193,12 @@ static void ExportLeaf(mapentity_t *entity, node_t *node)
continue;
/* emit a marksurface */
do {
map.bsp.dleaffaces.push_back(face->outputnumber.value());
face = face->original; /* grab tjunction split faces */
} while (face);
map.bsp.dleaffaces.push_back(face->outputnumber.value());
/* grab tjunction split faces */
for (auto &fragment : face->fragments) {
map.bsp.dleaffaces.push_back(fragment.outputnumber.value());
}
}
dleaf.nummarksurfaces = static_cast<int>(map.bsp.dleaffaces.size()) - dleaf.firstmarksurface;