fix missing noexcept

explicit initialization in some cases for vis winding_t's parameters
more vector
This commit is contained in:
Jonathan 2022-06-23 17:02:18 -04:00
parent ee596f3ff1
commit 3ac1d02624
5 changed files with 166 additions and 153 deletions

View File

@ -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;

View File

@ -44,37 +44,30 @@ struct winding_t : polylib::winding_base_t<MAX_WINDING_FIXED>
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<MAX_WINDING_FIXED>() { }
// construct winding from range.
// iterators must have operator+ and operator-.
template<typename Iter, std::enable_if_t<is_iterator_v<Iter>, int> = 0>
inline winding_t(Iter begin, Iter end) : polylib::winding_base_t<MAX_WINDING_FIXED>(begin, end)
{
set_winding_sphere();
}
// initializer list constructor
inline winding_t(std::initializer_list<qvec3d> l) : polylib::winding_base_t<MAX_WINDING_FIXED>(l)
{
set_winding_sphere();
}
// copy constructor
winding_t(const winding_t &copy) : winding_base_t(copy), origin(copy.origin), radius(copy.radius) { }
inline winding_t(const winding_t &copy) : 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 &copy)
{
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<MAX_WINDING_FIXED>
}
}
// assignment copy
inline winding_t &operator=(const winding_t &copy)
{
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<portal_t> portals; // always numportals * 2; front and back
extern std::vector<leaf_t> leafs;
extern int c_noclip;
extern int c_portaltest, c_portalpass, c_portalcheck;

View File

@ -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();
}

View File

@ -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<uint8_t> might((portalleafs + 7) >> 3);
std::vector<uint8_t> 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<uint8_t> 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<pstatus_t>(pstate.status);
p->nummightsee = pstate.nummightsee;
p->numcansee = pstate.numcansee;
p.status = static_cast<pstatus_t>(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;
}

View File

@ -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<portal_t> portals; // always numportals * 2; front and back
std::vector<leaf_t> 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