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:
parent
4cf81197a3
commit
feb6055b07
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
Loading…
Reference in New Issue