remove errors pertaining to MAXEDGES (except on output) since we dynamically expand now

allow command line to specify maxedges
default maxedges to 0 (no limit) for Quake II
This commit is contained in:
Jonathan 2022-07-14 04:57:52 -04:00
parent 4cf81197a3
commit feb6055b07
8 changed files with 25 additions and 23 deletions

View File

@ -253,6 +253,7 @@ public:
setting_enum<filltype_t> filltype{this, "filltype", filltype_t::AUTO, { { "auto", filltype_t::AUTO }, { "inside", filltype_t::INSIDE }, { "outside", filltype_t::OUTSIDE } }, &common_format_group,
"whether to fill the map from the outside in (lenient), from the inside out (aggressive), or to automatically decide based on the hull being used."};
setting_invertible_bool allow_upgrade{this, "allowupgrade", true, &common_format_group, "allow formats to \"upgrade\" to compatible extended formats when a limit is exceeded (ie Quake BSP to BSP2)"};
setting_int32 maxedges{this, "maxedges", 64, &map_development_group, "the max number of edges/vertices on a single face before it is split into another face"};
void setParameters(int argc, const char **argv) override
{

View File

@ -23,8 +23,10 @@
#include "common/polylib.hh"
constexpr size_t MAXEDGES = 64;
// now much a winding will use on the stack
// before needing an overflow.
constexpr size_t STACK_WINDING_SIZE = 64;
using winding_t = polylib::winding_base_t<MAXEDGES>;
using winding_t = polylib::winding_base_t<STACK_WINDING_SIZE>;
winding_t BaseWindingForPlane(const qplane3d &p);

View File

@ -434,10 +434,6 @@ static std::vector<side_t> CreateBrushFaces(const mapentity_t *src, hullbrush_t
continue; // overconstrained plane
}
if (w->size() > MAXEDGES) {
FError("face->numpoints > MAXEDGES ({}), source face on line {}", MAXEDGES, mapface.linenum);
}
// this face is a keeper
side_t &f = facelist.emplace_back();
f.planenum = PLANENUM_LEAF;

View File

@ -118,9 +118,6 @@ std::tuple<std::unique_ptr<face_t>, std::unique_ptr<face_t>> SplitFace(std::uniq
auto new_back = NewFaceFromFace(in.get());
new_back->w = std::move(back_winding.value());
if (new_front->w.size() > MAXEDGES || new_back->w.size() > MAXEDGES)
FError("Internal error: numpoints > MAXEDGES");
return {std::move(new_front), std::move(new_back)};
}

View File

@ -140,8 +140,8 @@ static void FindFaceFragmentEdges(face_t *face, face_fragment_t *fragment)
{
Q_assert(fragment->outputnumber == std::nullopt);
if (fragment->output_vertices.size() > MAXEDGES) {
FError("Internal error: face->numpoints > MAXEDGES");
if (qbsp_options.maxedges.value() && fragment->output_vertices.size() > qbsp_options.maxedges.value()) {
FError("Internal error: face->numpoints > max edges ({})", qbsp_options.maxedges.value());
}
fragment->edges.resize(fragment->output_vertices.size());

View File

@ -127,11 +127,6 @@ static std::unique_ptr<face_t> TryMerge(const face_t *f1, const face_t *f2)
keep2 = dot < -CONTINUOUS_EPSILON;
// build the new polygon
if (f1->w.size() + f2->w.size() > MAXEDGES) {
logging::funcprint("WARNING: Too many edges\n");
return NULL;
}
std::unique_ptr<face_t> newf = NewFaceFromFace(f1);
// copy first polygon

View File

@ -245,6 +245,13 @@ void qbsp_settings::postinitialize(int argc, const char **argv)
}
}
// side effects from Quake II
if (qbsp_options.target_game->id == GAME_QUAKE_II) {
if (!maxedges.isChanged()) {
maxedges.setValueLocked(0);
}
}
// load texture defs
for (auto &def : texturedefs.values()) {
load_texture_def(def);

View File

@ -164,20 +164,22 @@ Modifies `superface`. Adds the results to the end of `output`.
*/
inline void SplitFaceIntoFragments(std::vector<size_t> &superface, std::list<std::vector<size_t>> &output)
{
const int32_t &maxedges = qbsp_options.maxedges.value();
// split into multiple fragments, because of vertex overload
while (superface.size() > MAXEDGES) {
while (superface.size() > maxedges) {
c_faceoverflows++;
// copy MAXEDGES from our current face
std::vector<size_t> &newf = output.emplace_back(MAXEDGES);
std::copy_n(superface.begin(), MAXEDGES, newf.begin());
std::vector<size_t> &newf = output.emplace_back(maxedges);
std::copy_n(superface.begin(), maxedges, newf.begin());
// remove everything in-between from the superface
// except for the last edge we just wrote (0 and MAXEDGES-1)
std::copy(superface.begin() + MAXEDGES - 1, superface.end(), superface.begin() + 1);
std::copy(superface.begin() + maxedges - 1, superface.end(), superface.begin() + 1);
// resize superface; we need enough room to store the two extra verts
superface.resize(superface.size() - MAXEDGES + 2);
superface.resize(superface.size() - maxedges + 2);
}
// move the first face to the end, since that's logically where it belongs now
@ -482,9 +484,11 @@ static void FixFaceEdges(node_t *headnode, face_t *f)
Q_assert(faces.size());
// split giant superfaces into subfaces
if (qbsp_options.maxedges.value()) {
for (auto &face : faces) {
SplitFaceIntoFragments(face, faces);
}
}
// move the results into the face
f->output_vertices = std::move(faces.front());