CMapWorld: Move internally linked entities into an anonymous namespace

Same behavior, but prevents any potential ODR violations from occurring.
This commit is contained in:
Lioncash 2020-03-31 06:16:04 -04:00
parent 91f75a4c60
commit 92833b185a
1 changed files with 248 additions and 242 deletions

View File

@ -9,6 +9,254 @@
#include "Runtime/World/CWorld.hpp" #include "Runtime/World/CWorld.hpp"
namespace urde { namespace urde {
namespace {
struct Support {
int x0_;
int x4_[3];
};
struct Circle2 {
zeus::CVector2f x0_point;
float x8_radiusSq;
};
struct Circle {
zeus::CVector2f x0_point;
float x8_radius;
Circle(const Circle2& circ2) : x0_point(circ2.x0_point), x8_radius(std::sqrt(circ2.x8_radiusSq)) {}
};
Circle2 ExactCircle1(const zeus::CVector2f* a) { return {*a, 0.f}; }
Circle2 ExactCircle2(const zeus::CVector2f* a, const zeus::CVector2f* b) {
Circle2 ret = {};
ret.x0_point = 0.5f * (*a + *b);
ret.x8_radiusSq = (*b - *a).magSquared() * 0.25f;
return ret;
}
Circle2 ExactCircle3(const zeus::CVector2f* a, const zeus::CVector2f* b, const zeus::CVector2f* c) {
Circle2 ret = {};
zeus::CVector2f d1 = *b - *a;
zeus::CVector2f d2 = *c - *a;
float cross = d1.cross(d2);
zeus::CVector2f magVec(d1.magSquared() * 0.5f, d2.magSquared() * 0.5f);
if (std::fabs(cross) > 0.01f) {
zeus::CVector2f tmp((d2.y() * magVec.x() - d1.y() * magVec.y()) / cross,
(d1.x() * magVec.y() - d2.x() * magVec.x()) / cross);
ret.x0_point = *a + tmp;
ret.x8_radiusSq = tmp.magSquared();
} else {
ret.x8_radiusSq = FLT_MAX;
}
return ret;
}
bool PointInsideCircle(const zeus::CVector2f& point, const Circle2& circ, float& intersect) {
intersect = (point - circ.x0_point).magSquared() - circ.x8_radiusSq;
return intersect <= 0.f;
}
Circle2 UpdateSupport1(int idx, const zeus::CVector2f** list, Support& support) {
Circle2 ret = ExactCircle2(list[support.x4_[0]], list[idx]);
support.x0_ = 2;
support.x4_[1] = idx;
return ret;
}
Circle2 UpdateSupport2(int idx, const zeus::CVector2f** list, Support& support) {
Circle2 circs[3] = {};
float intersect;
int circIdx = -1;
float minRad = FLT_MAX;
circs[0] = ExactCircle2(list[support.x4_[0]], list[idx]);
if (PointInsideCircle(*list[support.x4_[1]], circs[0], intersect)) {
minRad = circs[0].x8_radiusSq;
circIdx = 0;
}
circs[1] = ExactCircle2(list[support.x4_[1]], list[idx]);
if (circs[1].x8_radiusSq < minRad && PointInsideCircle(*list[support.x4_[0]], circs[1], intersect)) {
circIdx = 1;
}
Circle2 ret;
if (circIdx != -1) {
ret = circs[circIdx];
support.x4_[1 - circIdx] = idx;
} else {
ret = ExactCircle3(list[support.x4_[0]], list[support.x4_[1]], list[idx]);
support.x0_ = 3;
support.x4_[2] = idx;
}
return ret;
}
Circle2 UpdateSupport3(int idx, const zeus::CVector2f** list, Support& support) {
Circle2 circs[6] = {};
float intersect;
int circIdxA = -1;
int circIdxB = -1;
float minRadA = FLT_MAX;
float minRadB = FLT_MAX;
circs[0] = ExactCircle2(list[support.x4_[0]], list[idx]);
if (PointInsideCircle(*list[support.x4_[1]], circs[0], intersect)) {
if (PointInsideCircle(*list[support.x4_[2]], circs[0], intersect)) {
minRadA = circs[0].x8_radiusSq;
circIdxA = 0;
} else {
minRadB = intersect;
circIdxB = 0;
}
} else {
minRadB = intersect;
circIdxB = 0;
}
circs[1] = ExactCircle2(list[support.x4_[1]], list[idx]);
if (circs[1].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[0]], circs[1], intersect)) {
if (PointInsideCircle(*list[support.x4_[2]], circs[1], intersect)) {
minRadA = circs[1].x8_radiusSq;
circIdxA = 1;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 1;
}
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 1;
}
}
circs[2] = ExactCircle2(list[support.x4_[2]], list[idx]);
if (circs[2].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[0]], circs[2], intersect)) {
if (PointInsideCircle(*list[support.x4_[1]], circs[2], intersect)) {
minRadA = circs[2].x8_radiusSq;
circIdxA = 2;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 2;
}
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 2;
}
}
circs[3] = ExactCircle3(list[support.x4_[0]], list[support.x4_[1]], list[idx]);
if (circs[3].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[2]], circs[3], intersect)) {
minRadA = circs[3].x8_radiusSq;
circIdxA = 3;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 3;
}
}
circs[4] = ExactCircle3(list[support.x4_[0]], list[support.x4_[2]], list[idx]);
if (circs[4].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[1]], circs[4], intersect)) {
minRadA = circs[4].x8_radiusSq;
circIdxA = 4;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 4;
}
}
circs[5] = ExactCircle3(list[support.x4_[1]], list[support.x4_[2]], list[idx]);
if (circs[5].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[0]], circs[5], intersect)) {
circIdxA = 5;
} else if (intersect < minRadB) {
circIdxB = 5;
}
}
if (circIdxA == -1)
circIdxA = circIdxB;
switch (circIdxA) {
case 0:
support.x0_ = 2;
support.x4_[1] = idx;
break;
case 1:
support.x0_ = 2;
support.x4_[0] = idx;
break;
case 2:
support.x0_ = 2;
support.x4_[0] = support.x4_[2];
support.x4_[1] = idx;
break;
case 3:
support.x4_[2] = idx;
break;
case 4:
support.x4_[1] = idx;
break;
case 5:
support.x4_[0] = idx;
break;
default:
break;
}
return circs[circIdxA];
}
using FSupport = Circle2 (*)(int idx, const zeus::CVector2f** list, Support& support);
constexpr FSupport SupportFuncs[] = {
nullptr,
UpdateSupport1,
UpdateSupport2,
UpdateSupport3,
};
Circle MinCircle(const std::vector<zeus::CVector2f>& coords) {
Circle2 ret = {};
if (coords.size() >= 1) {
std::unique_ptr<const zeus::CVector2f*[]> randArr(new const zeus::CVector2f*[coords.size()]);
for (size_t i = 0; i < coords.size(); ++i)
randArr[i] = &coords[i];
for (int i = coords.size() - 1; i >= 0; --i) {
int shuf = rand() % (i + 1);
if (shuf != i)
std::swap(randArr[i], randArr[shuf]);
}
ret = ExactCircle1(randArr[0]);
Support support = {};
support.x0_ = 1;
for (size_t i = 1; i < coords.size();) {
bool broke = false;
for (int j = 0; j < support.x0_; ++j) {
if ((*randArr[i] - *randArr[support.x4_[j]]).magSquared() < 0.01f) {
broke = true;
break;
}
}
float intersect;
if (!broke && !PointInsideCircle(*randArr[i], ret, intersect)) {
Circle2 circ = SupportFuncs[support.x0_](i, randArr.get(), support);
if (circ.x8_radiusSq > ret.x8_radiusSq) {
i = 0;
ret = circ;
continue;
}
}
++i;
}
}
return ret;
}
} // Anonymous namespace
CMapWorld::CMapAreaData::CMapAreaData(CAssetId areaRes, EMapAreaList list, CMapAreaData* next) CMapWorld::CMapAreaData::CMapAreaData(CAssetId areaRes, EMapAreaList list, CMapAreaData* next)
: x0_area(g_SimplePool->GetObj(SObjectTag{FOURCC('MAPA'), areaRes})), x10_list(list), x14_next(next) {} : x0_area(g_SimplePool->GetObj(SObjectTag{FOURCC('MAPA'), areaRes})), x10_list(list), x14_next(next) {}
@ -378,248 +626,6 @@ void CMapWorld::DrawAreas(const CMapWorld::CMapWorldDrawParms& parms, int selAre
} }
} }
struct Support {
int x0_;
int x4_[3];
};
struct Circle2 {
zeus::CVector2f x0_point;
float x8_radiusSq;
};
struct Circle {
zeus::CVector2f x0_point;
float x8_radius;
Circle(const Circle2& circ2) : x0_point(circ2.x0_point), x8_radius(std::sqrt(circ2.x8_radiusSq)) {}
};
static Circle2 ExactCircle1(const zeus::CVector2f* a) { return {*a, 0.f}; }
static Circle2 ExactCircle2(const zeus::CVector2f* a, const zeus::CVector2f* b) {
Circle2 ret = {};
ret.x0_point = 0.5f * (*a + *b);
ret.x8_radiusSq = (*b - *a).magSquared() * 0.25f;
return ret;
}
static Circle2 ExactCircle3(const zeus::CVector2f* a, const zeus::CVector2f* b, const zeus::CVector2f* c) {
Circle2 ret = {};
zeus::CVector2f d1 = *b - *a;
zeus::CVector2f d2 = *c - *a;
float cross = d1.cross(d2);
zeus::CVector2f magVec(d1.magSquared() * 0.5f, d2.magSquared() * 0.5f);
if (std::fabs(cross) > 0.01f) {
zeus::CVector2f tmp((d2.y() * magVec.x() - d1.y() * magVec.y()) / cross,
(d1.x() * magVec.y() - d2.x() * magVec.x()) / cross);
ret.x0_point = *a + tmp;
ret.x8_radiusSq = tmp.magSquared();
} else {
ret.x8_radiusSq = FLT_MAX;
}
return ret;
}
static bool PointInsideCircle(const zeus::CVector2f& point, const Circle2& circ, float& intersect) {
intersect = (point - circ.x0_point).magSquared() - circ.x8_radiusSq;
return intersect <= 0.f;
}
static Circle2 UpdateSupport1(int idx, const zeus::CVector2f** list, Support& support) {
Circle2 ret = ExactCircle2(list[support.x4_[0]], list[idx]);
support.x0_ = 2;
support.x4_[1] = idx;
return ret;
}
static Circle2 UpdateSupport2(int idx, const zeus::CVector2f** list, Support& support) {
Circle2 circs[3] = {};
float intersect;
int circIdx = -1;
float minRad = FLT_MAX;
circs[0] = ExactCircle2(list[support.x4_[0]], list[idx]);
if (PointInsideCircle(*list[support.x4_[1]], circs[0], intersect)) {
minRad = circs[0].x8_radiusSq;
circIdx = 0;
}
circs[1] = ExactCircle2(list[support.x4_[1]], list[idx]);
if (circs[1].x8_radiusSq < minRad && PointInsideCircle(*list[support.x4_[0]], circs[1], intersect)) {
circIdx = 1;
}
Circle2 ret;
if (circIdx != -1) {
ret = circs[circIdx];
support.x4_[1 - circIdx] = idx;
} else {
ret = ExactCircle3(list[support.x4_[0]], list[support.x4_[1]], list[idx]);
support.x0_ = 3;
support.x4_[2] = idx;
}
return ret;
}
static Circle2 UpdateSupport3(int idx, const zeus::CVector2f** list, Support& support) {
Circle2 circs[6] = {};
float intersect;
int circIdxA = -1;
int circIdxB = -1;
float minRadA = FLT_MAX;
float minRadB = FLT_MAX;
circs[0] = ExactCircle2(list[support.x4_[0]], list[idx]);
if (PointInsideCircle(*list[support.x4_[1]], circs[0], intersect)) {
if (PointInsideCircle(*list[support.x4_[2]], circs[0], intersect)) {
minRadA = circs[0].x8_radiusSq;
circIdxA = 0;
} else {
minRadB = intersect;
circIdxB = 0;
}
} else {
minRadB = intersect;
circIdxB = 0;
}
circs[1] = ExactCircle2(list[support.x4_[1]], list[idx]);
if (circs[1].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[0]], circs[1], intersect)) {
if (PointInsideCircle(*list[support.x4_[2]], circs[1], intersect)) {
minRadA = circs[1].x8_radiusSq;
circIdxA = 1;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 1;
}
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 1;
}
}
circs[2] = ExactCircle2(list[support.x4_[2]], list[idx]);
if (circs[2].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[0]], circs[2], intersect)) {
if (PointInsideCircle(*list[support.x4_[1]], circs[2], intersect)) {
minRadA = circs[2].x8_radiusSq;
circIdxA = 2;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 2;
}
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 2;
}
}
circs[3] = ExactCircle3(list[support.x4_[0]], list[support.x4_[1]], list[idx]);
if (circs[3].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[2]], circs[3], intersect)) {
minRadA = circs[3].x8_radiusSq;
circIdxA = 3;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 3;
}
}
circs[4] = ExactCircle3(list[support.x4_[0]], list[support.x4_[2]], list[idx]);
if (circs[4].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[1]], circs[4], intersect)) {
minRadA = circs[4].x8_radiusSq;
circIdxA = 4;
} else if (intersect < minRadB) {
minRadB = intersect;
circIdxB = 4;
}
}
circs[5] = ExactCircle3(list[support.x4_[1]], list[support.x4_[2]], list[idx]);
if (circs[5].x8_radiusSq < minRadA) {
if (PointInsideCircle(*list[support.x4_[0]], circs[5], intersect)) {
circIdxA = 5;
} else if (intersect < minRadB) {
circIdxB = 5;
}
}
if (circIdxA == -1)
circIdxA = circIdxB;
switch (circIdxA) {
case 0:
support.x0_ = 2;
support.x4_[1] = idx;
break;
case 1:
support.x0_ = 2;
support.x4_[0] = idx;
break;
case 2:
support.x0_ = 2;
support.x4_[0] = support.x4_[2];
support.x4_[1] = idx;
break;
case 3:
support.x4_[2] = idx;
break;
case 4:
support.x4_[1] = idx;
break;
case 5:
support.x4_[0] = idx;
break;
default:
break;
}
return circs[circIdxA];
}
typedef Circle2 (*FSupport)(int idx, const zeus::CVector2f** list, Support& support);
static const FSupport SupportFuncs[] = {nullptr, UpdateSupport1, UpdateSupport2, UpdateSupport3};
static Circle MinCircle(const std::vector<zeus::CVector2f>& coords) {
Circle2 ret = {};
if (coords.size() >= 1) {
std::unique_ptr<const zeus::CVector2f*[]> randArr(new const zeus::CVector2f*[coords.size()]);
for (size_t i = 0; i < coords.size(); ++i)
randArr[i] = &coords[i];
for (int i = coords.size() - 1; i >= 0; --i) {
int shuf = rand() % (i + 1);
if (shuf != i)
std::swap(randArr[i], randArr[shuf]);
}
ret = ExactCircle1(randArr[0]);
Support support = {};
support.x0_ = 1;
for (size_t i = 1; i < coords.size();) {
bool broke = false;
for (int j = 0; j < support.x0_; ++j) {
if ((*randArr[i] - *randArr[support.x4_[j]]).magSquared() < 0.01f) {
broke = true;
break;
}
}
float intersect;
if (!broke && !PointInsideCircle(*randArr[i], ret, intersect)) {
Circle2 circ = SupportFuncs[support.x0_](i, randArr.get(), support);
if (circ.x8_radiusSq > ret.x8_radiusSq) {
i = 0;
ret = circ;
continue;
}
}
++i;
}
}
return ret;
}
void CMapWorld::RecalculateWorldSphere(const CMapWorldInfo& mwInfo, const IWorld& wld) { void CMapWorld::RecalculateWorldSphere(const CMapWorldInfo& mwInfo, const IWorld& wld) {
std::vector<zeus::CVector2f> coords; std::vector<zeus::CVector2f> coords;
coords.reserve(x0_areas.size() * 8); coords.reserve(x0_areas.size() * 8);