From 1764afb475deb55eb0e4cb8766df1b857f55f2a9 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Mon, 24 Jan 2022 14:55:21 -0500 Subject: [PATCH] Revert "Revert "make brush::faces a vector"" This reverts commit 11d2d5116567b8b04159feabd33831256c9de72b. Fixes implementation - was swapped logic in brush bevels --- include/qbsp/brush.hh | 2 +- qbsp/brush.cc | 91 +++++++++++++++---------------------------- qbsp/csg4.cc | 17 ++++---- qbsp/exportobj.cc | 4 +- qbsp/map.cc | 6 +-- qbsp/qbsp.cc | 61 +++++++++++++++-------------- 6 files changed, 77 insertions(+), 104 deletions(-) diff --git a/include/qbsp/brush.hh b/include/qbsp/brush.hh index 3498a80d..26a93d0a 100644 --- a/include/qbsp/brush.hh +++ b/include/qbsp/brush.hh @@ -27,7 +27,7 @@ struct brush_t { aabb3d bounds; - face_t *faces; + std::vector faces; contentflags_t contents; /* BSP contents */ short lmshift; /* lightmap scaling (qu/lightmap pixel), passed to the light util */ }; diff --git a/qbsp/brush.cc b/qbsp/brush.cc index 9443b576..5cbe00fc 100644 --- a/qbsp/brush.cc +++ b/qbsp/brush.cc @@ -298,14 +298,13 @@ static bool DiscardHintSkipFace_Q2(const mtexinfo_t &texinfo) CreateBrushFaces ================= */ -static face_t *CreateBrushFaces(const mapentity_t *src, hullbrush_t *hullbrush, const int hullnum, - const rotation_t rottype = rotation_t::none, const qvec3d &rotate_offset = {}) +static std::vector CreateBrushFaces(const mapentity_t *src, hullbrush_t *hullbrush, const int hullnum, + const rotation_t rottype = rotation_t::none, const qvec3d &rotate_offset = {}) { vec_t r; - face_t *f; std::optional w; qbsp_plane_t plane; - face_t *facelist = NULL; + std::list facelist; qvec3d point; vec_t max, min; @@ -343,31 +342,31 @@ static face_t *CreateBrushFaces(const mapentity_t *src, hullbrush_t *hullbrush, if (!w) continue; // overconstrained plane - // this face is a keeper - f = new face_t{}; - f->planenum = PLANENUM_LEAF; - if (w->size() > MAXEDGES) FError("face->numpoints > MAXEDGES ({}), source face on line {}", MAXEDGES, mapface.linenum); + + // this face is a keeper + face_t &f = facelist.emplace_front(); + f.planenum = PLANENUM_LEAF; - f->w.resize(w->size()); + f.w.resize(w->size()); for (size_t j = 0; j < w->size(); j++) { for (size_t k = 0; k < 3; k++) { point[k] = w->at(j)[k] - rotate_offset[k]; r = Q_rint(point[k]); if (fabs(point[k] - r) < ZERO_EPSILON) - f->w[j][k] = r; + f.w[j][k] = r; else - f->w[j][k] = point[k]; + f.w[j][k] = point[k]; - if (f->w[j][k] < min) - min = f->w[j][k]; - if (f->w[j][k] > max) - max = f->w[j][k]; + if (f.w[j][k] < min) + min = f.w[j][k]; + if (f.w[j][k] > max) + max = f.w[j][k]; } - hullbrush->bounds += f->w[j]; + hullbrush->bounds += f.w[j]; } // account for texture offset, from txqbsp-xt @@ -386,14 +385,12 @@ static face_t *CreateBrushFaces(const mapentity_t *src, hullbrush_t *hullbrush, point -= rotate_offset; plane.dist = qv::dot(plane.normal, point); - f->texinfo = hullnum > 0 ? 0 : mapface.texinfo; - f->planenum = FindPlane(plane, &f->planeside); - f->src_entity = const_cast(src); // FIXME: get rid of consts on src in the callers? + f.texinfo = hullnum > 0 ? 0 : mapface.texinfo; + f.planenum = FindPlane(plane, &f.planeside); + f.src_entity = const_cast(src); // FIXME: get rid of consts on src in the callers? - f->next = facelist; - facelist = f; - CheckFace(f, mapface); - UpdateFaceSphere(f); + CheckFace(&f, mapface); + UpdateFaceSphere(&f); } // Rotatable objects must have a bounding box big enough to @@ -418,7 +415,7 @@ static face_t *CreateBrushFaces(const mapentity_t *src, hullbrush_t *hullbrush, hullbrush->bounds = {-delta, delta}; } - return facelist; + return { std::make_move_iterator(facelist.begin()), std::make_move_iterator(facelist.end()) }; } /* @@ -446,17 +443,6 @@ void FreeBrushes(mapentity_t *ent) ent->brushes.clear(); } -/* -===================== -FreeBrush -===================== -*/ -void FreeBrush(brush_t *brush) -{ - FreeBrushFaces(brush->faces); - delete brush; -} - /* ============================================================================== @@ -635,10 +621,9 @@ static void AddHullEdge(hullbrush_t *hullbrush, const qvec3d &p1, const qvec3d & ExpandBrush ============= */ -static void ExpandBrush(hullbrush_t *hullbrush, const aabb3d &hull_size, const face_t *facelist) +static void ExpandBrush(hullbrush_t *hullbrush, const aabb3d &hull_size, std::vector &facelist) { int x, s; - const face_t *f; qbsp_plane_t plane; int cBevEdge = 0; @@ -647,9 +632,9 @@ static void ExpandBrush(hullbrush_t *hullbrush, const aabb3d &hull_size, const f hullbrush->edges.clear(); // create all the hull points - for (f = facelist; f; f = f->next) - for (size_t i = 0; i < f->w.size(); i++) { - AddHullPoint(hullbrush, f->w[i], hull_size); + for (auto &f : facelist) + for (size_t i = 0; i < f.w.size(); i++) { + AddHullPoint(hullbrush, f.w[i], hull_size); cBevEdge++; } @@ -681,9 +666,9 @@ static void ExpandBrush(hullbrush_t *hullbrush, const aabb3d &hull_size, const f } // add all of the edge bevels - for (f = facelist; f; f = f->next) - for (size_t i = 0; i < f->w.size(); i++) - AddHullEdge(hullbrush, f->w[i], f->w[(i + 1) % f->w.size()], hull_size); + for (auto &f : facelist) + for (size_t i = 0; i < f.w.size(); i++) + AddHullEdge(hullbrush, f.w[i], f.w[(i + 1) % f.w.size()], hull_size); } //============================================================================ @@ -735,7 +720,7 @@ std::optional LoadBrush(const mapentity_t *src, const mapbrush_t *mapbr const qvec3d &rotate_offset, const rotation_t rottype, const int hullnum) { hullbrush_t hullbrush; - face_t *facelist; + std::vector facelist; // create the faces @@ -758,7 +743,7 @@ std::optional LoadBrush(const mapentity_t *src, const mapbrush_t *mapbr facelist = CreateBrushFaces(src, &hullbrush, hullnum); } - if (!facelist) { + if (facelist.empty()) { LogPrint("WARNING: Couldn't create brush faces\n"); LogPrint("^ brush at line {} of .map file\n", hullbrush.linenum); return std::nullopt; @@ -768,7 +753,6 @@ std::optional LoadBrush(const mapentity_t *src, const mapbrush_t *mapbr auto &hulls = options.target_game->get_hull_sizes(); Q_assert(hullnum < hulls.size()); ExpandBrush(&hullbrush, *(hulls.begin() + hullnum), facelist); - FreeBrushFaces(facelist); facelist = CreateBrushFaces(src, &hullbrush, hullnum, rottype, rotate_offset); } @@ -801,6 +785,8 @@ static brush_stats_t Entity_SortBrushes(mapentity_t *dst, brush_types_t &types) stats.sky = types.sky.size(); stats.solid = types.solid.size(); + dst->brushes.reserve(stats.detail_illusionary + stats.liquid + stats.detail_fence + stats.detail + stats.sky + stats.solid); + dst->brushes.insert(dst->brushes.end(), make_move_iterator(types.detail_illusionary.begin()), make_move_iterator(types.detail_illusionary.end())); dst->brushes.insert(dst->brushes.end(), make_move_iterator(types.liquid.begin()), make_move_iterator(types.liquid.end())); dst->brushes.insert(dst->brushes.end(), make_move_iterator(types.detail_fence.begin()), make_move_iterator(types.detail_fence.end())); @@ -811,19 +797,6 @@ static brush_stats_t Entity_SortBrushes(mapentity_t *dst, brush_types_t &types) return stats; } -static int FaceListCount(const face_t *facelist) -{ - if (facelist) - return 1 + FaceListCount(facelist->next); - else - return 0; -} - -int Brush_NumFaces(const brush_t *brush) -{ - return FaceListCount(brush->faces); -} - static void Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnum, brush_types_t &types) { const char *classname; diff --git a/qbsp/csg4.cc b/qbsp/csg4.cc index 5a1aab99..8d751f12 100644 --- a/qbsp/csg4.cc +++ b/qbsp/csg4.cc @@ -206,9 +206,9 @@ static void RemoveOutsideFaces(const brush_t &brush, face_t **inside, face_t **o while (face) { next = face->next; std::optional w = face->w; - for (const face_t *clipface = brush.faces; clipface; clipface = clipface->next) { - qbsp_plane_t clipplane = map.planes[clipface->planenum]; - if (!clipface->planeside) { + for (auto &clipface : brush.faces) { + qbsp_plane_t clipplane = map.planes[clipface.planenum]; + if (!clipface.planeside) { clipplane = -clipplane; } w = w->clip(clipplane, ON_EPSILON, true)[SIDE_FRONT]; @@ -491,12 +491,12 @@ CopyBrushFaces */ static face_t *CopyBrushFaces(const brush_t &brush) { - face_t *facelist, *face, *newface; + face_t *facelist, *newface; facelist = NULL; - for (face = brush.faces; face; face = face->next) { + for (auto &face : brush.faces) { brushfaces++; - newface = new face_t(*face); + newface = new face_t(face); newface->contents = { options.target_game->create_empty_contents(), brush.contents }; newface->lmshift = { brush.lmshift, brush.lmshift }; newface->next = facelist; @@ -595,9 +595,8 @@ std::list CSGFaces(const mapentity_t *entity) outside = NULL; RemoveOutsideFaces(clipbrush, &inside, &outside); - const face_t *clipface = clipbrush.faces; - for (; clipface; clipface = clipface->next) - ClipInside(clipface, overwrite, &inside, &outside); + for (auto &clipface : clipbrush.faces) + ClipInside(&clipface, overwrite, &inside, &outside); // inside = parts of `brush` that are inside `clipbrush` // outside = parts of `brush` that are outside `clipbrush` diff --git a/qbsp/exportobj.cc b/qbsp/exportobj.cc index f8e4c894..2f402ac3 100644 --- a/qbsp/exportobj.cc +++ b/qbsp/exportobj.cc @@ -122,8 +122,8 @@ void ExportObj_Brushes(const std::string &filesuffix, const std::vector faces; for (const brush_t *brush : brushes) - for (const face_t *face = brush->faces; face; face = face->next) - faces.push_back(face); + for (auto &face : brush->faces) + faces.push_back(&face); ExportObj_Faces(filesuffix, faces); } diff --git a/qbsp/map.cc b/qbsp/map.cc index d4989324..5104bae9 100644 --- a/qbsp/map.cc +++ b/qbsp/map.cc @@ -2182,11 +2182,11 @@ void WriteBspBrushMap(const std::filesystem::path &name, const std::vectornext) { + for (auto &face : brush.faces) { // FIXME: Factor out this mess - qbsp_plane_t plane = map.planes.at(face->planenum); + qbsp_plane_t plane = map.planes.at(face.planenum); - if (face->planeside) { + if (face.planeside) { plane = -plane; } diff --git a/qbsp/qbsp.cc b/qbsp/qbsp.cc index 1c28454f..4aeae9d8 100644 --- a/qbsp/qbsp.cc +++ b/qbsp/qbsp.cc @@ -97,20 +97,20 @@ Adds any additional planes necessary to allow the brush to be expanded against axial bounding boxes ================= */ -static std::vector> AddBrushBevels(const brush_t *b) +static std::vector> AddBrushBevels(const brush_t &b) { // add already-present planes - std::vector> planes; + std::vector> planes; - for (face_t *f = b->faces; f; f = f->next) { - int32_t planenum = f->planenum; + for (auto &f : b.faces) { + int32_t planenum = f.planenum; - if (f->planeside) { - planenum = FindPlane(-map.planes[f->planenum], nullptr); + if (f.planeside) { + planenum = FindPlane(-map.planes[f.planenum], nullptr); } int32_t outputplanenum = ExportMapPlane(planenum); - planes.emplace_back(outputplanenum, f); + planes.emplace_back(outputplanenum, &f); } // @@ -131,13 +131,13 @@ static std::vector> AddBrushBevels(const brush_t *b qplane3d new_plane { }; new_plane.normal[axis] = dir; if (dir == 1) - new_plane.dist = b->bounds.maxs()[axis]; + new_plane.dist = b.bounds.maxs()[axis]; else - new_plane.dist = -b->bounds.mins()[axis]; + new_plane.dist = -b.bounds.mins()[axis]; int32_t planenum = FindPlane(new_plane, nullptr); int32_t outputplanenum = ExportMapPlane(planenum); - planes.emplace_back(outputplanenum, b->faces); + planes.emplace_back(outputplanenum, &b.faces.front()); } // if the plane is not in it canonical order, swap it @@ -185,19 +185,20 @@ static std::vector> AddBrushBevels(const brush_t *b continue; current.dist = qv::dot(w[j], current.normal); - face_t *f; + auto it = b.faces.begin(); // if all the points on all the sides are // behind this plane, it is a proper edge bevel - for (f = b->faces; f; f = f->next) { - auto &plane = map.planes[f->planenum]; - qplane3d temp = f->planeside ? -plane : plane; + for (; it != b.faces.end(); it++) { + auto &f = *it; + auto &plane = map.planes[f.planenum]; + qplane3d temp = f.planeside ? -plane : plane; // if this plane has allready been used, skip it if (qv::epsilonEqual(current, temp)) break; - auto &w2 = f->w; + auto &w2 = f.w; if (!w2.size()) continue; size_t l; @@ -210,13 +211,13 @@ static std::vector> AddBrushBevels(const brush_t *b break; } - if (f) + if (it != b.faces.end()) continue; // wasn't part of the outer hull // add this plane int32_t planenum = FindPlane(current, nullptr); int32_t outputplanenum = ExportMapPlane(planenum); - planes.emplace_back(outputplanenum, b->faces); + planes.emplace_back(outputplanenum, &b.faces.front()); } } } @@ -235,7 +236,7 @@ static void ExportBrushList(const mapentity_t *entity, node_t *node, uint32_t &b dbrush_t &brush = map.bsp.dbrushes.emplace_back( dbrush_t{static_cast(map.bsp.dbrushsides.size()), 0, b.contents.native}); - auto bevels = AddBrushBevels(&b); + auto bevels = AddBrushBevels(b); for (auto &plane : bevels) { map.bsp.dbrushsides.push_back( @@ -752,10 +753,10 @@ static void BSPX_Brushes_AddModel(struct bspxbrushes_s *ctx, int modelnum, std:: for (auto &b : brushes) { permodel.numbrushes++; - for (face_t *f = b.faces; f; f = f->next) { + for (auto &f : b.faces) { /*skip axial*/ - if (fabs(map.planes[f->planenum].normal[0]) == 1 || fabs(map.planes[f->planenum].normal[1]) == 1 || - fabs(map.planes[f->planenum].normal[2]) == 1) + if (fabs(map.planes[f.planenum].normal[0]) == 1 || fabs(map.planes[f.planenum].normal[1]) == 1 || + fabs(map.planes[f.planenum].normal[2]) == 1) continue; permodel.numfaces++; } @@ -773,10 +774,10 @@ static void BSPX_Brushes_AddModel(struct bspxbrushes_s *ctx, int modelnum, std:: for (auto &b : brushes) { bspxbrushes_perbrush perbrush {}; - for (face_t *f = b.faces; f; f = f->next) { + for (auto &f : b.faces) { /*skip axial*/ - if (fabs(map.planes[f->planenum].normal[0]) == 1 || fabs(map.planes[f->planenum].normal[1]) == 1 || - fabs(map.planes[f->planenum].normal[2]) == 1) + if (fabs(map.planes[f.planenum].normal[0]) == 1 || fabs(map.planes[f.planenum].normal[1]) == 1 || + fabs(map.planes[f.planenum].normal[2]) == 1) continue; perbrush.numfaces++; } @@ -814,18 +815,18 @@ static void BSPX_Brushes_AddModel(struct bspxbrushes_s *ctx, int modelnum, std:: str <= perbrush; - for (face_t *f = b.faces; f; f = f->next) { + for (auto &f : b.faces) { /*skip axial*/ - if (fabs(map.planes[f->planenum].normal[0]) == 1 || fabs(map.planes[f->planenum].normal[1]) == 1 || - fabs(map.planes[f->planenum].normal[2]) == 1) + if (fabs(map.planes[f.planenum].normal[0]) == 1 || fabs(map.planes[f.planenum].normal[1]) == 1 || + fabs(map.planes[f.planenum].normal[2]) == 1) continue; bspxbrushes_perface perface; - if (f->planeside) { - perface = -map.planes[f->planenum]; + if (f.planeside) { + perface = -map.planes[f.planenum]; } else { - perface = map.planes[f->planenum]; + perface = map.planes[f.planenum]; } str <= std::tie(perface.normal, perface.dist);