mirror of https://github.com/AxioDL/metaforce.git
CMetroidAreaCollider: Make use of std::array where applicable
Makes arrays strongly typed and allows eliminating some hardcoded array sizes. We can also use it to make input data to some data types and functions significantly more informative. This also makes it easier for static analysis tools to track out of bounds accesses if they ever occur.
This commit is contained in:
parent
d708337e90
commit
f0eadfe56c
|
@ -509,7 +509,7 @@ bool CCollidableOBBTree::SphereCollision(const COBBTree::CNode& node, const zeus
|
||||||
|
|
||||||
bool CCollidableOBBTree::AABoxCollideWithLeaf(const COBBTree::CLeafData& leaf, const zeus::CTransform& xf,
|
bool CCollidableOBBTree::AABoxCollideWithLeaf(const COBBTree::CLeafData& leaf, const zeus::CTransform& xf,
|
||||||
const zeus::CAABox& aabb, const CMaterialList& material,
|
const zeus::CAABox& aabb, const CMaterialList& material,
|
||||||
const CMaterialFilter& filter, const zeus::CPlane* planes,
|
const CMaterialFilter& filter, const std::array<zeus::CPlane, 6>& planes,
|
||||||
CCollisionInfoList& infoList) const {
|
CCollisionInfoList& infoList) const {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
zeus::CVector3f center = aabb.center();
|
zeus::CVector3f center = aabb.center();
|
||||||
|
@ -538,7 +538,7 @@ bool CCollidableOBBTree::AABoxCollideWithLeaf(const COBBTree::CLeafData& leaf, c
|
||||||
bool CCollidableOBBTree::AABoxCollision(const COBBTree::CNode& node, const zeus::CTransform& xf,
|
bool CCollidableOBBTree::AABoxCollision(const COBBTree::CNode& node, const zeus::CTransform& xf,
|
||||||
const zeus::CAABox& aabb, const zeus::COBBox& obb,
|
const zeus::CAABox& aabb, const zeus::COBBox& obb,
|
||||||
const CMaterialList& material, const CMaterialFilter& filter,
|
const CMaterialList& material, const CMaterialFilter& filter,
|
||||||
const zeus::CPlane* planes, CCollisionInfoList& infoList) const {
|
const std::array<zeus::CPlane, 6>& planes, CCollisionInfoList& infoList) const {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
const_cast<CCollidableOBBTree&>(*this).x14_tries += 1;
|
const_cast<CCollidableOBBTree&>(*this).x14_tries += 1;
|
||||||
|
|
|
@ -68,11 +68,11 @@ class CCollidableOBBTree : public CCollisionPrimitive {
|
||||||
const zeus::COBBox& obb, const CMaterialList& material, const CMaterialFilter& filter,
|
const zeus::COBBox& obb, const CMaterialList& material, const CMaterialFilter& filter,
|
||||||
CCollisionInfoList& infoList) const;
|
CCollisionInfoList& infoList) const;
|
||||||
bool AABoxCollideWithLeaf(const COBBTree::CLeafData& leaf, const zeus::CTransform& xf, const zeus::CAABox& aabb,
|
bool AABoxCollideWithLeaf(const COBBTree::CLeafData& leaf, const zeus::CTransform& xf, const zeus::CAABox& aabb,
|
||||||
const CMaterialList& material, const CMaterialFilter& filter, const zeus::CPlane* planes,
|
const CMaterialList& material, const CMaterialFilter& filter,
|
||||||
CCollisionInfoList& infoList) const;
|
const std::array<zeus::CPlane, 6>& planes, CCollisionInfoList& infoList) const;
|
||||||
bool AABoxCollision(const COBBTree::CNode& node, const zeus::CTransform& xf, const zeus::CAABox& aabb,
|
bool AABoxCollision(const COBBTree::CNode& node, const zeus::CTransform& xf, const zeus::CAABox& aabb,
|
||||||
const zeus::COBBox& obb, const CMaterialList& material, const CMaterialFilter& filter,
|
const zeus::COBBox& obb, const CMaterialList& material, const CMaterialFilter& filter,
|
||||||
const zeus::CPlane* planes, CCollisionInfoList& infoList) const;
|
const std::array<zeus::CPlane, 6>& planes, CCollisionInfoList& infoList) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CCollidableOBBTree(const COBBTree* tree, const CMaterialList& material);
|
CCollidableOBBTree(const COBBTree* tree, const CMaterialList& material);
|
||||||
|
|
|
@ -150,26 +150,29 @@ bool CCollidableOBBTreeGroup::CollideMovingSphere(const CInternalCollisionStruct
|
||||||
|
|
||||||
bool CCollidableOBBTreeGroup::AABoxCollide(const CInternalCollisionStructure& collision, CCollisionInfoList& list) {
|
bool CCollidableOBBTreeGroup::AABoxCollide(const CInternalCollisionStructure& collision, CCollisionInfoList& list) {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
const CCollidableAABox& p0 = static_cast<const CCollidableAABox&>(collision.GetLeft().GetPrim());
|
const auto& p0 = static_cast<const CCollidableAABox&>(collision.GetLeft().GetPrim());
|
||||||
const CCollidableOBBTreeGroup& p1 = static_cast<const CCollidableOBBTreeGroup&>(collision.GetRight().GetPrim());
|
const auto& p1 = static_cast<const CCollidableOBBTreeGroup&>(collision.GetRight().GetPrim());
|
||||||
|
|
||||||
zeus::CAABox b0 = p0.CalculateAABox(collision.GetLeft().GetTransform());
|
const zeus::CAABox b0 = p0.CalculateAABox(collision.GetLeft().GetTransform());
|
||||||
zeus::COBBox p0Obb = zeus::COBBox::FromAABox(p0.CalculateLocalAABox(), collision.GetRight().GetTransform().inverse() *
|
const zeus::COBBox p0Obb = zeus::COBBox::FromAABox(
|
||||||
collision.GetLeft().GetTransform());
|
p0.CalculateLocalAABox(), collision.GetRight().GetTransform().inverse() * collision.GetLeft().GetTransform());
|
||||||
|
|
||||||
zeus::CPlane planes[] = {{zeus::skRight, b0.min.dot(zeus::skRight)},
|
const std::array<zeus::CPlane, 6> planes{{
|
||||||
|
{zeus::skRight, b0.min.dot(zeus::skRight)},
|
||||||
{zeus::skLeft, b0.max.dot(zeus::skLeft)},
|
{zeus::skLeft, b0.max.dot(zeus::skLeft)},
|
||||||
{zeus::skForward, b0.min.dot(zeus::skForward)},
|
{zeus::skForward, b0.min.dot(zeus::skForward)},
|
||||||
{zeus::skBack, b0.max.dot(zeus::skBack)},
|
{zeus::skBack, b0.max.dot(zeus::skBack)},
|
||||||
{zeus::skUp, b0.min.dot(zeus::skUp)},
|
{zeus::skUp, b0.min.dot(zeus::skUp)},
|
||||||
{zeus::skDown, b0.max.dot(zeus::skDown)}};
|
{zeus::skDown, b0.max.dot(zeus::skDown)},
|
||||||
|
}};
|
||||||
|
|
||||||
for (const std::unique_ptr<COBBTree>& tree : p1.x10_container->x0_trees) {
|
for (const std::unique_ptr<COBBTree>& tree : p1.x10_container->x0_trees) {
|
||||||
CCollidableOBBTree obbTree(tree.get(), p1.GetMaterial());
|
CCollidableOBBTree obbTree(tree.get(), p1.GetMaterial());
|
||||||
if (obbTree.AABoxCollision(obbTree.x10_tree->GetRoot(), collision.GetRight().GetTransform(), b0, p0Obb,
|
if (obbTree.AABoxCollision(obbTree.x10_tree->GetRoot(), collision.GetRight().GetTransform(), b0, p0Obb,
|
||||||
p0.GetMaterial(), collision.GetLeft().GetFilter(), planes, list))
|
p0.GetMaterial(), collision.GetLeft().GetFilter(), planes, list)) {
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,13 @@ u32 CMetroidAreaCollider::g_RejectedByClip = 0;
|
||||||
u32 CMetroidAreaCollider::g_TrianglesProcessed = 0;
|
u32 CMetroidAreaCollider::g_TrianglesProcessed = 0;
|
||||||
u32 CMetroidAreaCollider::g_DupTrianglesProcessed = 0;
|
u32 CMetroidAreaCollider::g_DupTrianglesProcessed = 0;
|
||||||
u16 CMetroidAreaCollider::g_DupPrimitiveCheckCount = 0;
|
u16 CMetroidAreaCollider::g_DupPrimitiveCheckCount = 0;
|
||||||
u16 CMetroidAreaCollider::g_DupVertexList[0x5000] = {};
|
std::array<u16, 0x5000> CMetroidAreaCollider::g_DupVertexList{};
|
||||||
u16 CMetroidAreaCollider::g_DupEdgeList[0xC000] = {};
|
std::array<u16, 0xC000> CMetroidAreaCollider::g_DupEdgeList{};
|
||||||
u16 CMetroidAreaCollider::g_DupTriangleList[0x4000] = {};
|
std::array<u16, 0x4000> CMetroidAreaCollider::g_DupTriangleList{};
|
||||||
|
|
||||||
CAABoxAreaCache::CAABoxAreaCache(const zeus::CAABox& aabb, const zeus::CPlane* pl, const CMaterialFilter& filter,
|
CAABoxAreaCache::CAABoxAreaCache(const zeus::CAABox& aabb, const std::array<zeus::CPlane, 6>& pl,
|
||||||
const CMaterialList& material, CCollisionInfoList& collisionList)
|
const CMaterialFilter& filter, const CMaterialList& material,
|
||||||
|
CCollisionInfoList& collisionList)
|
||||||
: x0_aabb(aabb)
|
: x0_aabb(aabb)
|
||||||
, x4_planes(pl)
|
, x4_planes(pl)
|
||||||
, x8_filter(filter)
|
, x8_filter(filter)
|
||||||
|
@ -44,7 +45,7 @@ SBoxEdge::SBoxEdge(const zeus::CAABox& aabb, int idx, const zeus::CVector3f& dir
|
||||||
, x70_coDir(x58_delta.cross(dir).asNormalized())
|
, x70_coDir(x58_delta.cross(dir).asNormalized())
|
||||||
, x88_dirCoDirDot(x28_start.dot(x70_coDir)) {}
|
, x88_dirCoDirDot(x28_start.dot(x70_coDir)) {}
|
||||||
|
|
||||||
static void FlagEdgeIndicesForFace(int face, bool edgeFlags[12]) {
|
static void FlagEdgeIndicesForFace(int face, std::array<bool, 12>& edgeFlags) {
|
||||||
switch (face) {
|
switch (face) {
|
||||||
case 0:
|
case 0:
|
||||||
edgeFlags[10] = true;
|
edgeFlags[10] = true;
|
||||||
|
@ -87,7 +88,7 @@ static void FlagEdgeIndicesForFace(int face, bool edgeFlags[12]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FlagVertexIndicesForFace(int face, bool vertFlags[8]) {
|
static void FlagVertexIndicesForFace(int face, std::array<bool, 8>& vertFlags) {
|
||||||
switch (face) {
|
switch (face) {
|
||||||
case 0:
|
case 0:
|
||||||
vertFlags[1] = true;
|
vertFlags[1] = true;
|
||||||
|
@ -131,26 +132,30 @@ static void FlagVertexIndicesForFace(int face, bool vertFlags[8]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CMovingAABoxComponents::CMovingAABoxComponents(const zeus::CAABox& aabb, const zeus::CVector3f& dir) : x6e8_aabb(aabb) {
|
CMovingAABoxComponents::CMovingAABoxComponents(const zeus::CAABox& aabb, const zeus::CVector3f& dir) : x6e8_aabb(aabb) {
|
||||||
bool edgeFlags[12] = {};
|
std::array<bool, 12> edgeFlags{};
|
||||||
bool vertFlags[8] = {};
|
std::array<bool, 8> vertFlags{};
|
||||||
int useFaces = 0;
|
int useFaces = 0;
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
if (dir[i] != 0.f) {
|
if (dir[i] != 0.f) {
|
||||||
int face = i * 2 + (dir[i] < 0.f);
|
const int face = i * 2 + (dir[i] < 0.f);
|
||||||
FlagEdgeIndicesForFace(face, edgeFlags);
|
FlagEdgeIndicesForFace(face, edgeFlags);
|
||||||
FlagVertexIndicesForFace(face, vertFlags);
|
FlagVertexIndicesForFace(face, vertFlags);
|
||||||
useFaces += 1;
|
useFaces += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 12; ++i)
|
for (size_t i = 0; i < edgeFlags.size(); ++i) {
|
||||||
if (edgeFlags[i])
|
if (edgeFlags[i]) {
|
||||||
x0_edges.push_back(SBoxEdge(aabb, i, dir));
|
x0_edges.emplace_back(aabb, s32(i), dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 8; ++i)
|
for (size_t i = 0; i < vertFlags.size(); ++i) {
|
||||||
if (vertFlags[i])
|
if (vertFlags[i]) {
|
||||||
x6c4_vertIdxs.push_back(i);
|
x6c4_vertIdxs.push_back(u32(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (useFaces == 1) {
|
if (useFaces == 1) {
|
||||||
x6e8_aabb = zeus::CAABox();
|
x6e8_aabb = zeus::CAABox();
|
||||||
|
@ -194,9 +199,9 @@ static zeus::CVector3f ClipRayToPlane(const zeus::CVector3f& a, const zeus::CVec
|
||||||
return (1.f - -plane.pointToPlaneDist(a) / (b - a).dot(plane.normal())) * (a - b) + b;
|
return (1.f - -plane.pointToPlaneDist(a) / (b - a).dot(plane.normal())) * (a - b) + b;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMetroidAreaCollider::ConvexPolyCollision(const zeus::CPlane* planes, const zeus::CVector3f* verts,
|
bool CMetroidAreaCollider::ConvexPolyCollision(const std::array<zeus::CPlane, 6>& planes, const zeus::CVector3f* verts,
|
||||||
zeus::CAABox& aabb) {
|
zeus::CAABox& aabb) {
|
||||||
rstl::reserved_vector<zeus::CVector3f, 20> vecs[2];
|
std::array<rstl::reserved_vector<zeus::CVector3f, 20>, 2> vecs;
|
||||||
|
|
||||||
g_CalledClip += 1;
|
g_CalledClip += 1;
|
||||||
g_RejectedByClip -= 1;
|
g_RejectedByClip -= 1;
|
||||||
|
@ -354,22 +359,24 @@ bool CMetroidAreaCollider::AABoxCollisionCheck_Cached(const COctreeLeafCache& le
|
||||||
const CMaterialFilter& filter, const CMaterialList& matList,
|
const CMaterialFilter& filter, const CMaterialList& matList,
|
||||||
CCollisionInfoList& list) {
|
CCollisionInfoList& list) {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
zeus::CPlane planes[] = {{zeus::skRight, aabb.min.dot(zeus::skRight)},
|
const std::array<zeus::CPlane, 6> planes{{
|
||||||
|
{zeus::skRight, aabb.min.dot(zeus::skRight)},
|
||||||
{zeus::skLeft, aabb.max.dot(zeus::skLeft)},
|
{zeus::skLeft, aabb.max.dot(zeus::skLeft)},
|
||||||
{zeus::skForward, aabb.min.dot(zeus::skForward)},
|
{zeus::skForward, aabb.min.dot(zeus::skForward)},
|
||||||
{zeus::skBack, aabb.max.dot(zeus::skBack)},
|
{zeus::skBack, aabb.max.dot(zeus::skBack)},
|
||||||
{zeus::skUp, aabb.min.dot(zeus::skUp)},
|
{zeus::skUp, aabb.min.dot(zeus::skUp)},
|
||||||
{zeus::skDown, aabb.max.dot(zeus::skDown)}};
|
{zeus::skDown, aabb.max.dot(zeus::skDown)},
|
||||||
|
}};
|
||||||
CAABoxAreaCache cache(aabb, planes, filter, matList, list);
|
CAABoxAreaCache cache(aabb, planes, filter, matList, list);
|
||||||
|
|
||||||
ResetInternalCounters();
|
ResetInternalCounters();
|
||||||
|
|
||||||
for (const CAreaOctTree::Node& node : leafCache.x4_nodeCache) {
|
for (const CAreaOctTree::Node& node : leafCache.x4_nodeCache) {
|
||||||
if (aabb.intersects(node.GetBoundingBox())) {
|
if (aabb.intersects(node.GetBoundingBox())) {
|
||||||
CAreaOctTree::TriListReference list = node.GetTriangleArray();
|
CAreaOctTree::TriListReference listRef = node.GetTriangleArray();
|
||||||
for (int j = 0; j < list.GetSize(); ++j) {
|
for (int j = 0; j < listRef.GetSize(); ++j) {
|
||||||
++g_TrianglesProcessed;
|
++g_TrianglesProcessed;
|
||||||
u16 triIdx = list.GetAt(j);
|
u16 triIdx = listRef.GetAt(j);
|
||||||
if (g_DupPrimitiveCheckCount == g_DupTriangleList[triIdx]) {
|
if (g_DupPrimitiveCheckCount == g_DupTriangleList[triIdx]) {
|
||||||
g_DupTrianglesProcessed += 1;
|
g_DupTrianglesProcessed += 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -379,10 +386,10 @@ bool CMetroidAreaCollider::AABoxCollisionCheck_Cached(const COctreeLeafCache& le
|
||||||
if (cache.x8_filter.Passes(material)) {
|
if (cache.x8_filter.Passes(material)) {
|
||||||
if (CollisionUtil::TriBoxOverlap(cache.x14_center, cache.x20_halfExtent, surf.GetVert(0), surf.GetVert(1),
|
if (CollisionUtil::TriBoxOverlap(cache.x14_center, cache.x20_halfExtent, surf.GetVert(0), surf.GetVert(1),
|
||||||
surf.GetVert(2))) {
|
surf.GetVert(2))) {
|
||||||
zeus::CAABox aabb = zeus::CAABox();
|
zeus::CAABox aabb2 = zeus::CAABox();
|
||||||
if (ConvexPolyCollision(cache.x4_planes, surf.GetVerts(), aabb)) {
|
if (ConvexPolyCollision(cache.x4_planes, surf.GetVerts(), aabb2)) {
|
||||||
zeus::CPlane plane = surf.GetPlane();
|
zeus::CPlane plane = surf.GetPlane();
|
||||||
CCollisionInfo collision(aabb, cache.xc_material, material, plane.normal(), -plane.normal());
|
CCollisionInfo collision(aabb2, cache.xc_material, material, plane.normal(), -plane.normal());
|
||||||
cache.x10_collisionList.Add(collision, false);
|
cache.x10_collisionList.Add(collision, false);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
@ -448,17 +455,19 @@ bool CMetroidAreaCollider::AABoxCollisionCheck_Internal(const CAreaOctTree::Node
|
||||||
bool CMetroidAreaCollider::AABoxCollisionCheck(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
bool CMetroidAreaCollider::AABoxCollisionCheck(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
||||||
const CMaterialFilter& filter, const CMaterialList& matList,
|
const CMaterialFilter& filter, const CMaterialList& matList,
|
||||||
CCollisionInfoList& list) {
|
CCollisionInfoList& list) {
|
||||||
zeus::CPlane planes[] = {{zeus::skRight, aabb.min.dot(zeus::skRight)},
|
const std::array<zeus::CPlane, 6> planes{{
|
||||||
|
{zeus::skRight, aabb.min.dot(zeus::skRight)},
|
||||||
{zeus::skLeft, aabb.max.dot(zeus::skLeft)},
|
{zeus::skLeft, aabb.max.dot(zeus::skLeft)},
|
||||||
{zeus::skForward, aabb.min.dot(zeus::skForward)},
|
{zeus::skForward, aabb.min.dot(zeus::skForward)},
|
||||||
{zeus::skBack, aabb.max.dot(zeus::skBack)},
|
{zeus::skBack, aabb.max.dot(zeus::skBack)},
|
||||||
{zeus::skUp, aabb.min.dot(zeus::skUp)},
|
{zeus::skUp, aabb.min.dot(zeus::skUp)},
|
||||||
{zeus::skDown, aabb.max.dot(zeus::skDown)}};
|
{zeus::skDown, aabb.max.dot(zeus::skDown)},
|
||||||
CAABoxAreaCache cache(aabb, planes, filter, matList, list);
|
}};
|
||||||
|
const CAABoxAreaCache cache(aabb, planes, filter, matList, list);
|
||||||
|
|
||||||
ResetInternalCounters();
|
ResetInternalCounters();
|
||||||
|
|
||||||
CAreaOctTree::Node node = octTree.GetRootNode();
|
const CAreaOctTree::Node node = octTree.GetRootNode();
|
||||||
return AABoxCollisionCheck_Internal(node, cache);
|
return AABoxCollisionCheck_Internal(node, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -674,8 +683,8 @@ bool CMetroidAreaCollider::MovingAABoxCollisionCheck_Cached(const COctreeLeafCac
|
||||||
g_DupTriangleList[triIdx] = g_DupPrimitiveCheckCount;
|
g_DupTriangleList[triIdx] = g_DupPrimitiveCheckCount;
|
||||||
CMaterialList triMat(node.GetOwner().GetTriangleMaterial(triIdx));
|
CMaterialList triMat(node.GetOwner().GetTriangleMaterial(triIdx));
|
||||||
if (filter.Passes(triMat)) {
|
if (filter.Passes(triMat)) {
|
||||||
u16 vertIndices[3];
|
std::array<u16, 3> vertIndices;
|
||||||
node.GetOwner().GetTriangleVertexIndices(triIdx, vertIndices);
|
node.GetOwner().GetTriangleVertexIndices(triIdx, vertIndices.data());
|
||||||
CCollisionSurface surf(node.GetOwner().GetVert(vertIndices[0]), node.GetOwner().GetVert(vertIndices[1]),
|
CCollisionSurface surf(node.GetOwner().GetVert(vertIndices[0]), node.GetOwner().GetVert(vertIndices[1]),
|
||||||
node.GetOwner().GetVert(vertIndices[2]), triMat.GetValue());
|
node.GetOwner().GetVert(vertIndices[2]), triMat.GetValue());
|
||||||
|
|
||||||
|
@ -690,8 +699,7 @@ bool CMetroidAreaCollider::MovingAABoxCollisionCheck_Cached(const COctreeLeafCac
|
||||||
dOut = d;
|
dOut = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int k = 0; k < 3; ++k) {
|
for (const u16 vertIdx : vertIndices) {
|
||||||
u16 vertIdx = vertIndices[k];
|
|
||||||
zeus::CVector3f vtx = node.GetOwner().GetVert(vertIdx);
|
zeus::CVector3f vtx = node.GetOwner().GetVert(vertIdx);
|
||||||
if (g_DupPrimitiveCheckCount != g_DupVertexList[vertIdx]) {
|
if (g_DupPrimitiveCheckCount != g_DupVertexList[vertIdx]) {
|
||||||
g_DupVertexList[vertIdx] = g_DupPrimitiveCheckCount;
|
g_DupVertexList[vertIdx] = g_DupPrimitiveCheckCount;
|
||||||
|
@ -783,8 +791,8 @@ bool CMetroidAreaCollider::MovingSphereCollisionCheck_Cached(const COctreeLeafCa
|
||||||
g_DupTriangleList[triIdx] = g_DupPrimitiveCheckCount;
|
g_DupTriangleList[triIdx] = g_DupPrimitiveCheckCount;
|
||||||
CMaterialList triMat(node.GetOwner().GetTriangleMaterial(triIdx));
|
CMaterialList triMat(node.GetOwner().GetTriangleMaterial(triIdx));
|
||||||
if (filter.Passes(triMat)) {
|
if (filter.Passes(triMat)) {
|
||||||
u16 vertIndices[3];
|
std::array<u16, 3> vertIndices;
|
||||||
node.GetOwner().GetTriangleVertexIndices(triIdx, vertIndices);
|
node.GetOwner().GetTriangleVertexIndices(triIdx, vertIndices.data());
|
||||||
CCollisionSurface surf(node.GetOwner().GetVert(vertIndices[0]), node.GetOwner().GetVert(vertIndices[1]),
|
CCollisionSurface surf(node.GetOwner().GetVert(vertIndices[0]), node.GetOwner().GetVert(vertIndices[1]),
|
||||||
node.GetOwner().GetVert(vertIndices[2]), triMat.GetValue());
|
node.GetOwner().GetVert(vertIndices[2]), triMat.GetValue());
|
||||||
|
|
||||||
|
@ -796,11 +804,11 @@ bool CMetroidAreaCollider::MovingSphereCollisionCheck_Cached(const COctreeLeafCa
|
||||||
float mag = (sphere.radius - (sphere.position - surf.GetVert(0)).dot(surfNormal)) / dir.dot(surfNormal);
|
float mag = (sphere.radius - (sphere.position - surf.GetVert(0)).dot(surfNormal)) / dir.dot(surfNormal);
|
||||||
zeus::CVector3f intersectPoint = sphere.position + mag * dir;
|
zeus::CVector3f intersectPoint = sphere.position + mag * dir;
|
||||||
|
|
||||||
bool outsideEdges[] = {
|
const std::array<bool, 3> outsideEdges{
|
||||||
(intersectPoint - surf.GetVert(0)).dot(surfNormal.cross(surf.GetVert(1) - surf.GetVert(0))) < 0.f,
|
(intersectPoint - surf.GetVert(0)).dot(surfNormal.cross(surf.GetVert(1) - surf.GetVert(0))) < 0.f,
|
||||||
(intersectPoint - surf.GetVert(1)).dot(surfNormal.cross(surf.GetVert(2) - surf.GetVert(1))) < 0.f,
|
(intersectPoint - surf.GetVert(1)).dot(surfNormal.cross(surf.GetVert(2) - surf.GetVert(1))) < 0.f,
|
||||||
(intersectPoint - surf.GetVert(2)).dot(surfNormal.cross(surf.GetVert(0) - surf.GetVert(2))) <
|
(intersectPoint - surf.GetVert(2)).dot(surfNormal.cross(surf.GetVert(0) - surf.GetVert(2))) < 0.f,
|
||||||
0.f};
|
};
|
||||||
|
|
||||||
if (mag >= 0.f && !outsideEdges[0] && !outsideEdges[1] && !outsideEdges[2] && mag < dOut) {
|
if (mag >= 0.f && !outsideEdges[0] && !outsideEdges[1] && !outsideEdges[2] && mag < dOut) {
|
||||||
infoOut = CCollisionInfo(intersectPoint - sphere.radius * surfNormal, matList, triMat, surfNormal);
|
infoOut = CCollisionInfo(intersectPoint - sphere.radius * surfNormal, matList, triMat, surfNormal);
|
||||||
|
@ -810,7 +818,7 @@ bool CMetroidAreaCollider::MovingSphereCollisionCheck_Cached(const COctreeLeafCa
|
||||||
}
|
}
|
||||||
|
|
||||||
bool intersects = (sphere.position - surf.GetVert(0)).dot(surfNormal) <= sphere.radius;
|
bool intersects = (sphere.position - surf.GetVert(0)).dot(surfNormal) <= sphere.radius;
|
||||||
bool testVert[] = {true, true, true};
|
std::array<bool, 3> testVert{true, true, true};
|
||||||
const u16* edgeIndices = node.GetOwner().GetTriangleEdgeIndices(triIdx);
|
const u16* edgeIndices = node.GetOwner().GetTriangleEdgeIndices(triIdx);
|
||||||
for (int k = 0; k < 3; ++k) {
|
for (int k = 0; k < 3; ++k) {
|
||||||
if (intersects || outsideEdges[k]) {
|
if (intersects || outsideEdges[k]) {
|
||||||
|
@ -916,9 +924,9 @@ void CMetroidAreaCollider::ResetInternalCounters() {
|
||||||
g_TrianglesProcessed = 0;
|
g_TrianglesProcessed = 0;
|
||||||
g_DupTrianglesProcessed = 0;
|
g_DupTrianglesProcessed = 0;
|
||||||
if (g_DupPrimitiveCheckCount == 0xffff) {
|
if (g_DupPrimitiveCheckCount == 0xffff) {
|
||||||
std::fill(std::begin(g_DupVertexList), std::end(g_DupVertexList), 0);
|
g_DupVertexList.fill(0);
|
||||||
std::fill(std::begin(g_DupEdgeList), std::end(g_DupEdgeList), 0);
|
g_DupEdgeList.fill(0);
|
||||||
std::fill(std::begin(g_DupTriangleList), std::end(g_DupTriangleList), 0);
|
g_DupTriangleList.fill(0);
|
||||||
g_DupPrimitiveCheckCount += 1;
|
g_DupPrimitiveCheckCount += 1;
|
||||||
}
|
}
|
||||||
g_DupPrimitiveCheckCount += 1;
|
g_DupPrimitiveCheckCount += 1;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include "Runtime/RetroTypes.hpp"
|
#include "Runtime/RetroTypes.hpp"
|
||||||
#include "Runtime/rstl.hpp"
|
#include "Runtime/rstl.hpp"
|
||||||
#include "Runtime/Collision/CAreaOctTree.hpp"
|
#include "Runtime/Collision/CAreaOctTree.hpp"
|
||||||
|
@ -17,7 +19,7 @@ class CMaterialList;
|
||||||
class CAABoxAreaCache {
|
class CAABoxAreaCache {
|
||||||
friend class CMetroidAreaCollider;
|
friend class CMetroidAreaCollider;
|
||||||
const zeus::CAABox& x0_aabb;
|
const zeus::CAABox& x0_aabb;
|
||||||
const zeus::CPlane* x4_planes;
|
const std::array<zeus::CPlane, 6>& x4_planes;
|
||||||
const CMaterialFilter& x8_filter;
|
const CMaterialFilter& x8_filter;
|
||||||
const CMaterialList& xc_material;
|
const CMaterialList& xc_material;
|
||||||
CCollisionInfoList& x10_collisionList;
|
CCollisionInfoList& x10_collisionList;
|
||||||
|
@ -25,7 +27,7 @@ class CAABoxAreaCache {
|
||||||
zeus::CVector3f x20_halfExtent;
|
zeus::CVector3f x20_halfExtent;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CAABoxAreaCache(const zeus::CAABox& aabb, const zeus::CPlane* pl, const CMaterialFilter& filter,
|
CAABoxAreaCache(const zeus::CAABox& aabb, const std::array<zeus::CPlane, 6>& pl, const CMaterialFilter& filter,
|
||||||
const CMaterialList& material, CCollisionInfoList& collisionList);
|
const CMaterialList& material, CCollisionInfoList& collisionList);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -91,9 +93,9 @@ class CMetroidAreaCollider {
|
||||||
static u32 g_TrianglesProcessed;
|
static u32 g_TrianglesProcessed;
|
||||||
static u32 g_DupTrianglesProcessed;
|
static u32 g_DupTrianglesProcessed;
|
||||||
static u16 g_DupPrimitiveCheckCount;
|
static u16 g_DupPrimitiveCheckCount;
|
||||||
static u16 g_DupVertexList[0x5000];
|
static std::array<u16, 0x5000> g_DupVertexList;
|
||||||
static u16 g_DupEdgeList[0xC000];
|
static std::array<u16, 0xC000> g_DupEdgeList;
|
||||||
static u16 g_DupTriangleList[0x4000];
|
static std::array<u16, 0x4000> g_DupTriangleList;
|
||||||
static bool AABoxCollisionCheckBoolean_Internal(const CAreaOctTree::Node& node, const CBooleanAABoxAreaCache& cache);
|
static bool AABoxCollisionCheckBoolean_Internal(const CAreaOctTree::Node& node, const CBooleanAABoxAreaCache& cache);
|
||||||
static bool AABoxCollisionCheck_Internal(const CAreaOctTree::Node& node, const CAABoxAreaCache& cache);
|
static bool AABoxCollisionCheck_Internal(const CAreaOctTree::Node& node, const CAABoxAreaCache& cache);
|
||||||
|
|
||||||
|
@ -131,7 +133,8 @@ public:
|
||||||
};
|
};
|
||||||
static void BuildOctreeLeafCache(const CAreaOctTree::Node& root, const zeus::CAABox& aabb,
|
static void BuildOctreeLeafCache(const CAreaOctTree::Node& root, const zeus::CAABox& aabb,
|
||||||
CMetroidAreaCollider::COctreeLeafCache& cache);
|
CMetroidAreaCollider::COctreeLeafCache& cache);
|
||||||
static bool ConvexPolyCollision(const zeus::CPlane* planes, const zeus::CVector3f* verts, zeus::CAABox& aabb);
|
static bool ConvexPolyCollision(const std::array<zeus::CPlane, 6>& planes, const zeus::CVector3f* verts,
|
||||||
|
zeus::CAABox& aabb);
|
||||||
|
|
||||||
static bool AABoxCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
static bool AABoxCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
||||||
const CMaterialFilter& filter);
|
const CMaterialFilter& filter);
|
||||||
|
|
Loading…
Reference in New Issue