From 3ac1d02624e2d70feb06402734917ea47cea29fa Mon Sep 17 00:00:00 2001 From: Jonathan Date: Thu, 23 Jun 2022 17:02:18 -0400 Subject: [PATCH] fix missing noexcept explicit initialization in some cases for vis winding_t's parameters more vector --- include/common/polylib.hh | 2 +- include/vis/vis.hh | 77 ++++++++++++++++----------- vis/flow.cc | 62 +++++++++++----------- vis/state.cc | 70 ++++++++++++------------ vis/vis.cc | 108 +++++++++++++++++++------------------- 5 files changed, 166 insertions(+), 153 deletions(-) diff --git a/include/common/polylib.hh b/include/common/polylib.hh index b9e5d168..ed0efc42 100644 --- a/include/common/polylib.hh +++ b/include/common/polylib.hh @@ -225,7 +225,7 @@ public: } // assignment move - inline winding_base_t &operator=(winding_base_t &&move) + inline winding_base_t &operator=(winding_base_t &&move) noexcept { count = move.count; diff --git a/include/vis/vis.hh b/include/vis/vis.hh index cf2d9c23..4e5d4f7a 100644 --- a/include/vis/vis.hh +++ b/include/vis/vis.hh @@ -44,37 +44,30 @@ struct winding_t : polylib::winding_base_t qvec3d origin; // Bounding sphere for fast clipping tests vec_t radius; // Not updated, so won't shrink when clipping - using winding_base_t::winding_base_t; + inline winding_t() : polylib::winding_base_t() { } + + // construct winding from range. + // iterators must have operator+ and operator-. + template, int> = 0> + inline winding_t(Iter begin, Iter end) : polylib::winding_base_t(begin, end) + { + set_winding_sphere(); + } + + // initializer list constructor + inline winding_t(std::initializer_list l) : polylib::winding_base_t(l) + { + set_winding_sphere(); + } // copy constructor - winding_t(const winding_t ©) : winding_base_t(copy), origin(copy.origin), radius(copy.radius) { } + inline winding_t(const winding_t ©) : winding_base_t(copy), origin(copy.origin), radius(copy.radius) { } // move constructor - winding_t(winding_t &&move) : winding_base_t(move), origin(move.origin), radius(move.radius) { } + inline winding_t(winding_t &&move) noexcept : winding_base_t(move), origin(move.origin), radius(move.radius) { } - // assignment copy - inline winding_t &operator=(const winding_t ©) - { - origin = copy.origin; - radius = copy.radius; - - winding_base_t::operator=(copy); - - return *this; - } - - // assignment move - inline winding_t &operator=(winding_t &&move) - { - origin = move.origin; - radius = move.radius; - - winding_base_t::operator=(move); - - return *this; - } - - void SetWindingSphere() + // sets origin & radius + inline void set_winding_sphere() { // set origin origin = {}; @@ -90,12 +83,34 @@ struct winding_t : polylib::winding_base_t } } + // assignment copy + inline winding_t &operator=(const winding_t ©) + { + origin = copy.origin; + radius = copy.radius; + + winding_base_t::operator=(copy); + + return *this; + } + + // assignment move + inline winding_t &operator=(winding_t &&move) noexcept + { + origin = move.origin; + radius = move.radius; + + winding_base_t::operator=(move); + + return *this; + } + /* ============================================================================ Used for visdist to get the distance from a winding to a portal ============================================================================ */ - inline float distFromPortal(struct portal_t *p); + inline float distFromPortal(struct portal_t &p); }; struct portal_t @@ -109,12 +124,12 @@ struct portal_t int numcansee; }; -inline float winding_t::distFromPortal(portal_t *p) +inline float winding_t::distFromPortal(portal_t &p) { vec_t mindist = 1e20; for (size_t i = 0; i < size(); ++i) { - mindist = std::min(mindist, fabs(p->plane.distance_to(at(i)))); + mindist = std::min(mindist, fabs(p.plane.distance_to(at(i)))); } return mindist; @@ -175,8 +190,8 @@ extern int numportals; extern int portalleafs; extern int portalleafs_real; -extern portal_t *portals; -extern leaf_t *leafs; +extern std::vector portals; // always numportals * 2; front and back +extern std::vector leafs; extern int c_noclip; extern int c_portaltest, c_portalpass, c_portalcheck; diff --git a/vis/flow.cc b/vis/flow.cc index 9fdaf4d7..e0e4f1ca 100644 --- a/vis/flow.cc +++ b/vis/flow.cc @@ -358,24 +358,21 @@ void PortalFlow(portal_t *p) ============================================================================ */ -static void SimpleFlood(portal_t *srcportal, int leafnum, const leafbits_t &portalsee) +static void SimpleFlood(portal_t &srcportal, int leafnum, const leafbits_t &portalsee) { - int i; - leaf_t *leaf; - portal_t *p; - - if (srcportal->mightsee[leafnum]) + if (srcportal.mightsee[leafnum]) return; - srcportal->mightsee[leafnum] = true; - srcportal->nummightsee++; + srcportal.mightsee[leafnum] = true; + srcportal.nummightsee++; - leaf = &leafs[leafnum]; - for (i = 0; i < leaf->numportals; i++) { - p = leaf->portals[i]; - if (!portalsee[p - portals]) - continue; - SimpleFlood(srcportal, p->leaf, portalsee); + leaf_t &leaf = leafs[leafnum]; + for (size_t i = 0; i < leaf.numportals; i++) { + const portal_t *p = leaf.portals[i]; + + if (portalsee[p - portals.data()]) { + SimpleFlood(srcportal, p->leaf, portalsee); + } } } @@ -386,43 +383,44 @@ static void SimpleFlood(portal_t *srcportal, int leafnum, const leafbits_t &port */ static void BasePortalThread(size_t portalnum) { - int i, j; - portal_t *p, *tp; + int j; float d; leafbits_t portalsee(numportals * 2); - p = portals + portalnum; - winding_t &w = p->winding; + portal_t &p = portals[portalnum]; + winding_t &w = p.winding; - p->mightsee.resize(portalleafs); + p.mightsee.resize(portalleafs); - for (i = 0, tp = portals; i < numportals * 2; i++, tp++) { - if (tp == p) + for (size_t i = 0; i < numportals * 2; i++) { + if (i == portalnum) { continue; - - winding_t &tw = tp->winding; + } + + portal_t &tp = portals[i]; + winding_t &tw = tp.winding; // Quick test - completely at the back? - d = p->plane.distance_to(tw.origin); + d = p.plane.distance_to(tw.origin); if (d < -tw.radius) continue; for (j = 0; j < tw.size(); j++) { - d = p->plane.distance_to(tw[j]); + d = p.plane.distance_to(tw[j]); if (d > -ON_EPSILON) // ericw -- changed from > ON_EPSILON for - // https://github.com/ericwa/ericw-tools/issues/261 + // https://github.com/ericwa/ericw-tools/issues/261 break; } if (j == tw.size()) continue; // no points on front // Quick test - completely on front? - d = tp->plane.distance_to(w.origin); + d = tp.plane.distance_to(w.origin); if (d > w.radius) continue; for (j = 0; j < w.size(); j++) { - d = tp->plane.distance_to(w[j]); + d = tp.plane.distance_to(w[j]); if (d < ON_EPSILON) // ericw -- changed from < -ON_EPSILON for // https://github.com/ericwa/ericw-tools/issues/261 break; @@ -431,16 +429,16 @@ static void BasePortalThread(size_t portalnum) continue; // no points on back if (options.visdist.value() > 0) { - if (tp->winding.distFromPortal(p) > options.visdist.value() || - p->winding.distFromPortal(tp) > options.visdist.value()) + if (tp.winding.distFromPortal(p) > options.visdist.value() || + p.winding.distFromPortal(tp) > options.visdist.value()) continue; } portalsee[i] = 1; } - p->nummightsee = 0; - SimpleFlood(p, p->leaf, portalsee); + p.nummightsee = 0; + SimpleFlood(p, p.leaf, portalsee); portalsee.clear(); } diff --git a/vis/state.cc b/vis/state.cc index 69e30e06..df2ff18c 100644 --- a/vis/state.cc +++ b/vis/state.cc @@ -132,8 +132,7 @@ static void CopyLeafBits(leafbits_t &dst, const uint8_t *src, size_t numleafs) void SaveVisState(void) { - int i, vis_len, might_len; - const portal_t *p; + int vis_len, might_len; dvisstate_t state; dportal_t pstate; @@ -153,23 +152,25 @@ void SaveVisState(void) std::vector might((portalleafs + 7) >> 3); std::vector vis((portalleafs + 7) >> 3); - for (i = 0, p = portals; i < numportals * 2; i++, p++) { - might_len = CompressBits(might.data(), p->mightsee); - if (p->status == pstat_done) - vis_len = CompressBits(vis.data(), p->visbits); - else + for (const auto &p : portals) { + might_len = CompressBits(might.data(), p.mightsee); + if (p.status == pstat_done) { + vis_len = CompressBits(vis.data(), p.visbits); + } else { vis_len = 0; + } - pstate.status = p->status; + pstate.status = p.status; pstate.might = might_len; pstate.vis = vis_len; - pstate.nummightsee = p->nummightsee; - pstate.numcansee = p->numcansee; + pstate.nummightsee = p.nummightsee; + pstate.numcansee = p.numcansee; out <= pstate; out.write((const char *) might.data(), might_len); - if (vis_len) + if (vis_len) { out.write((const char *) vis.data(), vis_len); + } } out.close(); @@ -195,11 +196,9 @@ void CleanVisState(void) bool LoadVisState(void) { fs::file_time_type prt_time, state_time; - int i, numbytes; - portal_t *p; + int numbytes; dvisstate_t state; dportal_t pstate; - uint8_t *compressed; if (options.nostate.value()) { return false; @@ -243,40 +242,41 @@ bool LoadVisState(void) starttime -= duration(state.time_elapsed); numbytes = (portalleafs + 7) >> 3; - compressed = new uint8_t[numbytes]; + std::vector compressed(numbytes); /* Update the portal information */ - for (i = 0, p = portals; i < numportals * 2; i++, p++) { + for (auto &p : portals) { in >= pstate; - p->status = static_cast(pstate.status); - p->nummightsee = pstate.nummightsee; - p->numcansee = pstate.numcansee; + p.status = static_cast(pstate.status); + p.nummightsee = pstate.nummightsee; + p.numcansee = pstate.numcansee; - in.read((char *) compressed, pstate.might); - p->mightsee.resize(portalleafs); + in.read((char *) compressed.data(), pstate.might); + p.mightsee.resize(portalleafs); - if (pstate.might < numbytes) - DecompressBits(p->mightsee, compressed); - else - CopyLeafBits(p->mightsee, compressed, portalleafs); + if (pstate.might < numbytes) { + DecompressBits(p.mightsee, compressed.data()); + } else { + CopyLeafBits(p.mightsee, compressed.data(), portalleafs); + } - p->visbits.resize(portalleafs); + p.visbits.resize(portalleafs); if (pstate.vis) { - in.read((char *) compressed, pstate.vis); - if (pstate.vis < numbytes) - DecompressBits(p->visbits, compressed); - else - CopyLeafBits(p->visbits, compressed, portalleafs); + in.read((char *) compressed.data(), pstate.vis); + if (pstate.vis < numbytes) { + DecompressBits(p.visbits, compressed.data()); + } else { + CopyLeafBits(p.visbits, compressed.data(), portalleafs); + } } /* Portals that were in progress need to be started again */ - if (p->status == pstat_working) - p->status = pstat_none; + if (p.status == pstat_working) { + p.status = pstat_none; + } } - delete[] compressed; - return true; } diff --git a/vis/vis.cc b/vis/vis.cc index 43cab105..223abd0b 100644 --- a/vis/vis.cc +++ b/vis/vis.cc @@ -38,8 +38,8 @@ int numportals; int portalleafs; /* leafs (PRT1) or clusters (PRT2) */ int portalleafs_real; /* real no. of leafs after expanding PRT2 clusters. Not used for Q2. */ -portal_t *portals; -leaf_t *leafs; +std::vector portals; // always numportals * 2; front and back +std::vector leafs; int c_portaltest, c_portalpass, c_portalcheck, c_mightseeupdate; int c_noclip = 0; @@ -248,19 +248,15 @@ static std::atomic_int64_t portalIndex; */ portal_t *GetNextPortal(void) { - int i; - portal_t *p, *ret; - unsigned min; + portal_t *ret = nullptr; + uint32_t min = INT_MAX; portal_mutex.lock(); - min = INT_MAX; - ret = NULL; - - for (i = 0, p = portals; i < numportals * 2; i++, p++) { - if (p->nummightsee < min && p->status == pstat_none) { - min = p->nummightsee; - ret = p; + for (auto &p : portals) { + if (p.nummightsee < min && p.status == pstat_none) { + min = p.nummightsee; + ret = &p; } } @@ -287,7 +283,7 @@ portal_t *GetNextPortal(void) */ static void UpdateMightsee(const leaf_t &source, const leaf_t &dest) { - size_t leafnum = &dest - leafs; + size_t leafnum = &dest - leafs.data(); for (size_t i = 0; i < source.numportals; i++) { portal_t *p = source.portals[i]; if (p->status != pstat_none) { @@ -400,7 +396,7 @@ void LeafThread(size_t) PortalCompleted(p); - logging::print(logging::flag::VERBOSE, "portal:{:4} mightsee:{:4} cansee:{:4}\n", (ptrdiff_t)(p - portals), p->nummightsee, + logging::print(logging::flag::VERBOSE, "portal:{:4} mightsee:{:4} cansee:{:4}\n", (ptrdiff_t)(p - portals.data()), p->nummightsee, p->numcansee); } @@ -519,14 +515,11 @@ static void ClusterFlow(int clusternum, leafbits_t &buffer, mbsp_t *bsp) */ void CalcPortalVis(const mbsp_t *bsp) { - int i; - portal_t *p; - // fastvis just uses mightsee for a very loose bound if (options.fast.value()) { - for (i = 0; i < numportals * 2; i++) { - portals[i].visbits = portals[i].mightsee; - portals[i].status = pstat_done; + for (auto &p : portals) { + p.visbits = p.mightsee; + p.status = pstat_done; } return; } @@ -535,10 +528,12 @@ void CalcPortalVis(const mbsp_t *bsp) * Count the already completed portals in case we loaded previous state */ int32_t startcount = 0; - for (i = 0, p = portals; i < numportals * 2; i++, p++) { - if (p->status == pstat_done) + for (auto &p : portals) { + if (p.status == pstat_done) { startcount++; + } } + portalIndex = startcount; logging::parallel_for(startcount, numportals * 2, LeafThread); @@ -607,7 +602,6 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp) const prtfile_t prtfile = LoadPrtFile(name, bsp->loadversion); int i; - portal_t *p; leaf_t *l; qplane3d plane; @@ -640,9 +634,8 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp) } // each file portal is split into two memory portals - portals = new portal_t[numportals * 2]{}; - - leafs = new leaf_t[portalleafs]{}; + portals.resize(numportals * 2); + leafs.resize(portalleafs); if (bsp->loadversion->game->id == GAME_QUAKE_II) { originalvismapsize = portalleafs * ((portalleafs + 7) / 8); @@ -654,39 +647,46 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp) vismap.reserve(originalvismapsize * 2); - for (i = 0, p = portals; i < numportals; i++) { - const auto &sourceportal = prtfile.portals[i]; - p->winding = winding_t{sourceportal.winding.begin(), sourceportal.winding.end()}; + auto dest_portal_it = portals.begin(); - // calc plane - plane = p->winding.plane(); + for (auto source_portal_it = prtfile.portals.begin(); source_portal_it != prtfile.portals.end(); source_portal_it++) { + const auto &sourceportal = *source_portal_it; - // create forward portal - l = &leafs[sourceportal.leafnums[0]]; - if (l->numportals == MAX_PORTALS_ON_LEAF) - FError("Leaf with too many portals"); - l->portals[l->numportals] = p; - l->numportals++; + { + auto &p = *dest_portal_it; + p.winding = winding_t{sourceportal.winding.begin(), sourceportal.winding.end()}; - p->plane = -plane; - p->leaf = sourceportal.leafnums[1]; - p->winding.SetWindingSphere(); - p++; + // calc plane + plane = p.winding.plane(); - // create backwards portal - l = &leafs[sourceportal.leafnums[1]]; - if (l->numportals == MAX_PORTALS_ON_LEAF) - FError("Leaf with too many portals"); - l->portals[l->numportals] = p; - l->numportals++; + // create forward portal + l = &leafs[sourceportal.leafnums[0]]; + if (l->numportals == MAX_PORTALS_ON_LEAF) + FError("Leaf with too many portals"); + l->portals[l->numportals] = &p; + l->numportals++; - // Create a reverse winding - const auto flipped = sourceportal.winding.flip(); - p->winding = winding_t{flipped.begin(), flipped.end()}; - p->plane = plane; - p->leaf = sourceportal.leafnums[0]; - p->winding.SetWindingSphere(); - p++; + p.plane = -plane; + p.leaf = sourceportal.leafnums[1]; + dest_portal_it++; + } + + { + auto &p = *dest_portal_it; + // create backwards portal + l = &leafs[sourceportal.leafnums[1]]; + if (l->numportals == MAX_PORTALS_ON_LEAF) + FError("Leaf with too many portals"); + l->portals[l->numportals] = &p; + l->numportals++; + + // Create a reverse winding + const auto flipped = sourceportal.winding.flip(); + p.winding = winding_t{flipped.begin(), flipped.end()}; + p.plane = plane; + p.leaf = sourceportal.leafnums[0]; + dest_portal_it++; + } } // Q2 doesn't need this, it's PRT1 has the data we need