diff --git a/include/common/aabb.hh b/include/common/aabb.hh index c5fa6398..ee5a1245 100644 --- a/include/common/aabb.hh +++ b/include/common/aabb.hh @@ -75,6 +75,14 @@ public: { } + template, int> = 0> + constexpr aabb(Iter start, Iter end) : aabb() + { + for (auto it = start; it != end; it++) { + *this += *it; + } + } + constexpr bool operator==(const aabb &other) const { return m_mins == other.m_mins && m_maxs == other.m_maxs; } constexpr const value_type &mins() const { return m_mins; } diff --git a/qbsp/brush.cc b/qbsp/brush.cc index 59ba8f55..59f98c20 100644 --- a/qbsp/brush.cc +++ b/qbsp/brush.cc @@ -95,7 +95,7 @@ static void CheckFace(face_t *face, const mapface_t &sourceface) const qvec3d &p2 = face->w[(i + 1) % face->w.size()]; for (auto &v : p1) - if (v > options.worldextent.value() || v < -options.worldextent.value()) + if (fabs(v) > options.worldextent.value()) FError("line {}: coordinate out of range ({})", sourceface.linenum, v); /* check the point is on the face plane */ diff --git a/qbsp/csg4.cc b/qbsp/csg4.cc index 4ebec62a..69cc4d39 100644 --- a/qbsp/csg4.cc +++ b/qbsp/csg4.cc @@ -300,9 +300,18 @@ static std::list CSGFace_ClipAgainstSingleBrush(std::list in return outside; } -// fixme-brushbsp: determinism: sort `result` set by .map file order +struct brush_ptr_less +{ + constexpr bool operator()(const brush_t *a, const brush_t *b) const + { + return a->file_order < b->file_order; + } +}; + +using brush_result_set_t = std::set; + // fixme-brushbsp: add bounds test -static void GatherPossibleClippingBrushes_R(const node_t *node, const face_t *srcface, std::set &result) +static void GatherPossibleClippingBrushes_R(const node_t *node, const face_t *srcface, brush_result_set_t &result) { if (node->planenum == PLANENUM_LEAF) { for (auto *brush : node->original_brushes) { @@ -322,9 +331,9 @@ GatherPossibleClippingBrushes Starting a search at `node`, returns brushes that possibly intersect `srcface`. ================== */ -static std::set GatherPossibleClippingBrushes(const mapentity_t* srcentity, const node_t *node, const face_t *srcface) +static brush_result_set_t GatherPossibleClippingBrushes(const mapentity_t* srcentity, const node_t *node, const face_t *srcface) { - std::set result; + brush_result_set_t result; GatherPossibleClippingBrushes_R(node, srcface, result); diff --git a/qbsp/portals.cc b/qbsp/portals.cc index 19d46bfb..5724d06a 100644 --- a/qbsp/portals.cc +++ b/qbsp/portals.cc @@ -436,8 +436,7 @@ void MakeTreePortals_r(node_t *node, portalstats_t &stats) for (int i = 0; i < 3; i++) { - // fixme-brushbsp: use proper map bounds - if (node->bounds.mins()[i] < -8000 || node->bounds.mins()[i] > 8000) + if (fabs(node->bounds.mins()[i]) > options.worldextent.value()) { printf ("WARNING: node with unbounded volume\n"); break; diff --git a/qbsp/solidbsp.cc b/qbsp/solidbsp.cc index cbd4fc3e..12916424 100644 --- a/qbsp/solidbsp.cc +++ b/qbsp/solidbsp.cc @@ -558,7 +558,7 @@ bool WindingIsHuge(const winding_t &w) { for (size_t i = 0; i < w.size(); i++) { for (size_t j = 0; j < 3; j++) - if (w[i][j] < -8000 || w[i][j] > 8000) + if (fabs(w[i][j]) > options.worldextent.value()) return true; } return false;