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:
parent
dfd31d7441
commit
674be0c812
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue