Minor cleanups in Collision code

This commit is contained in:
Phillip Stephens 2021-07-24 17:54:26 -07:00
parent e331c5d5c6
commit 30f17812cd
Signed by: Antidote
GPG Key ID: F8BEE4C83DACA60D
4 changed files with 48 additions and 33 deletions

View File

@ -13,6 +13,9 @@
#include "../version.h" #include "../version.h"
//#include <fenv.h>
//#pragma STDC FENV_ACCESS ON
/* Static reference to dataspec additions /* Static reference to dataspec additions
* (used by MSVC to definitively link DataSpecs) */ * (used by MSVC to definitively link DataSpecs) */
#include "DataSpecRegistry.hpp" #include "DataSpecRegistry.hpp"
@ -578,6 +581,10 @@ int wmain(int argc, const boo::SystemChar** argv)
int main(int argc, const boo::SystemChar** argv) int main(int argc, const boo::SystemChar** argv)
#endif #endif
{ {
//TODO: This seems to fix a lot of weird issues with rounding
// but breaks animations, need to research why this is the case
// for now it's disabled
//fesetround(FE_TOWARDZERO);
if (argc > 1 && !hecl::StrCmp(argv[1], _SYS_STR("--dlpackage"))) { if (argc > 1 && !hecl::StrCmp(argv[1], _SYS_STR("--dlpackage"))) {
fmt::print(FMT_STRING("{}\n"), METAFORCE_DLPACKAGE); fmt::print(FMT_STRING("{}\n"), METAFORCE_DLPACKAGE);
return 100; return 100;

View File

@ -64,7 +64,7 @@ CRayCastResult CCollidableOBBTreeGroup::CastRayInternal(const CInternalRayCastSt
CCollidableOBBTree obbTree(tree.get(), GetMaterial()); CCollidableOBBTree obbTree(tree.get(), GetMaterial());
float tMin = 0.f; float tMin = 0.f;
float tMax = 0.f; float tMax = 0.f;
if (CollisionUtil::RayAABoxIntersection(xfRay, *aabbIt++, tMin, tMax)) { if (CollisionUtil::RayAABoxIntersection(xfRay, *aabbIt++, tMin, tMax) != 0u) {
CInternalRayCastStructure localCast(xfRay.start, xfRay.dir, mag, zeus::CTransform(), rayCast.GetFilter()); CInternalRayCastStructure localCast(xfRay.start, xfRay.dir, mag, zeus::CTransform(), rayCast.GetFilter());
CRayCastResult localResult = obbTree.CastRayInternal(localCast); CRayCastResult localResult = obbTree.CastRayInternal(localCast);
if (localResult.IsValid()) { if (localResult.IsValid()) {
@ -86,8 +86,8 @@ void CCollidableOBBTreeGroup::SetStaticTableIndex(u32 index) { sTableIndex = ind
bool CCollidableOBBTreeGroup::SphereCollide(const CInternalCollisionStructure& collision, CCollisionInfoList& list) { bool CCollidableOBBTreeGroup::SphereCollide(const CInternalCollisionStructure& collision, CCollisionInfoList& list) {
bool ret = false; bool ret = false;
const CCollidableSphere& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim()); const auto& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim());
const CCollidableOBBTreeGroup& p1 = static_cast<const CCollidableOBBTreeGroup&>(collision.GetRight().GetPrim()); const auto& p1 = static_cast<const CCollidableOBBTreeGroup&>(collision.GetRight().GetPrim());
zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform()); zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform());
zeus::COBBox obb1 = zeus::COBBox::FromAABox(p0.CalculateLocalAABox(), collision.GetRight().GetTransform().inverse() * zeus::COBBox obb1 = zeus::COBBox::FromAABox(p0.CalculateLocalAABox(), collision.GetRight().GetTransform().inverse() *
@ -96,16 +96,17 @@ bool CCollidableOBBTreeGroup::SphereCollide(const CInternalCollisionStructure& c
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.SphereCollision(obbTree.x10_tree->GetRoot(), collision.GetRight().GetTransform(), s0, obb1, if (obbTree.SphereCollision(obbTree.x10_tree->GetRoot(), collision.GetRight().GetTransform(), s0, obb1,
p0.GetMaterial(), collision.GetLeft().GetFilter(), list)) p0.GetMaterial(), collision.GetLeft().GetFilter(), list)) {
ret = true; ret = true;
} }
}
return ret; return ret;
} }
bool CCollidableOBBTreeGroup::SphereCollideBoolean(const CInternalCollisionStructure& collision) { bool CCollidableOBBTreeGroup::SphereCollideBoolean(const CInternalCollisionStructure& collision) {
const CCollidableSphere& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim()); const auto& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim());
const CCollidableOBBTreeGroup& p1 = static_cast<const CCollidableOBBTreeGroup&>(collision.GetRight().GetPrim()); const auto& p1 = static_cast<const CCollidableOBBTreeGroup&>(collision.GetRight().GetPrim());
zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform()); zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform());
zeus::COBBox obb1 = zeus::COBBox::FromAABox(p0.CalculateLocalAABox(), collision.GetRight().GetTransform().inverse() * zeus::COBBox obb1 = zeus::COBBox::FromAABox(p0.CalculateLocalAABox(), collision.GetRight().GetTransform().inverse() *
@ -114,9 +115,10 @@ bool CCollidableOBBTreeGroup::SphereCollideBoolean(const CInternalCollisionStruc
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.SphereCollisionBoolean(obbTree.x10_tree->GetRoot(), collision.GetRight().GetTransform(), s0, obb1, if (obbTree.SphereCollisionBoolean(obbTree.x10_tree->GetRoot(), collision.GetRight().GetTransform(), s0, obb1,
collision.GetLeft().GetFilter())) collision.GetLeft().GetFilter())) {
return true; return true;
} }
}
return false; return false;
} }
@ -124,8 +126,8 @@ bool CCollidableOBBTreeGroup::SphereCollideBoolean(const CInternalCollisionStruc
bool CCollidableOBBTreeGroup::CollideMovingSphere(const CInternalCollisionStructure& collision, bool CCollidableOBBTreeGroup::CollideMovingSphere(const CInternalCollisionStructure& collision,
const zeus::CVector3f& dir, double& mag, CCollisionInfo& info) { const zeus::CVector3f& dir, double& mag, CCollisionInfo& info) {
bool ret = false; bool ret = false;
const CCollidableSphere& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim()); const auto& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim());
const CCollidableOBBTreeGroup& p1 = static_cast<const CCollidableOBBTreeGroup&>(collision.GetRight().GetPrim()); const auto& p1 = static_cast<const CCollidableOBBTreeGroup&>(collision.GetRight().GetPrim());
zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform()); zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform());
@ -141,9 +143,10 @@ bool CCollidableOBBTreeGroup::CollideMovingSphere(const CInternalCollisionStruct
CCollidableOBBTree obbTree(tree.get(), p1.GetMaterial()); CCollidableOBBTree obbTree(tree.get(), p1.GetMaterial());
CMetroidAreaCollider::ResetInternalCounters(); CMetroidAreaCollider::ResetInternalCounters();
if (obbTree.SphereCollisionMoving(obbTree.x10_tree->GetRoot(), collision.GetRight().GetTransform(), s0, p0Obb, if (obbTree.SphereCollisionMoving(obbTree.x10_tree->GetRoot(), collision.GetRight().GetTransform(), s0, p0Obb,
p0.GetMaterial(), collision.GetLeft().GetFilter(), dir, mag, info)) p0.GetMaterial(), collision.GetLeft().GetFilter(), dir, mag, info)) {
ret = true; ret = true;
} }
}
return ret; return ret;
} }
@ -178,8 +181,8 @@ bool CCollidableOBBTreeGroup::AABoxCollide(const CInternalCollisionStructure& co
} }
bool CCollidableOBBTreeGroup::AABoxCollideBoolean(const CInternalCollisionStructure& collision) { bool CCollidableOBBTreeGroup::AABoxCollideBoolean(const CInternalCollisionStructure& collision) {
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()); zeus::CAABox b0 = p0.CalculateAABox(collision.GetLeft().GetTransform());
zeus::COBBox p0Obb = zeus::COBBox::FromAABox(p0.CalculateLocalAABox(), collision.GetRight().GetTransform().inverse() * zeus::COBBox p0Obb = zeus::COBBox::FromAABox(p0.CalculateLocalAABox(), collision.GetRight().GetTransform().inverse() *
@ -188,9 +191,10 @@ bool CCollidableOBBTreeGroup::AABoxCollideBoolean(const CInternalCollisionStruct
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.AABoxCollisionBoolean(obbTree.x10_tree->GetRoot(), collision.GetRight().GetTransform(), b0, p0Obb, if (obbTree.AABoxCollisionBoolean(obbTree.x10_tree->GetRoot(), collision.GetRight().GetTransform(), b0, p0Obb,
collision.GetLeft().GetFilter())) collision.GetLeft().GetFilter())) {
return true; return true;
} }
}
return false; return false;
} }
@ -198,8 +202,8 @@ bool CCollidableOBBTreeGroup::AABoxCollideBoolean(const CInternalCollisionStruct
bool CCollidableOBBTreeGroup::CollideMovingAABox(const CInternalCollisionStructure& collision, bool CCollidableOBBTreeGroup::CollideMovingAABox(const CInternalCollisionStructure& collision,
const zeus::CVector3f& dir, double& mag, CCollisionInfo& info) { const zeus::CVector3f& dir, double& mag, CCollisionInfo& info) {
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()); zeus::CAABox b0 = p0.CalculateAABox(collision.GetLeft().GetTransform());
@ -217,9 +221,10 @@ bool CCollidableOBBTreeGroup::CollideMovingAABox(const CInternalCollisionStructu
CCollidableOBBTree obbTree(tree.get(), p1.GetMaterial()); CCollidableOBBTree obbTree(tree.get(), p1.GetMaterial());
CMetroidAreaCollider::ResetInternalCounters(); CMetroidAreaCollider::ResetInternalCounters();
if (obbTree.AABoxCollisionMoving(obbTree.x10_tree->GetRoot(), collision.GetRight().GetTransform(), b0, p0Obb, if (obbTree.AABoxCollisionMoving(obbTree.x10_tree->GetRoot(), collision.GetRight().GetTransform(), b0, p0Obb,
p0.GetMaterial(), collision.GetLeft().GetFilter(), components, dir, mag, info)) p0.GetMaterial(), collision.GetLeft().GetFilter(), components, dir, mag, info)) {
ret = true; ret = true;
} }
}
return ret; return ret;
} }

View File

@ -11,8 +11,8 @@ constexpr CCollisionPrimitive::Type sType(CCollidableSphere::SetStaticTableIndex
namespace Collide { namespace Collide {
bool Sphere_AABox(const CInternalCollisionStructure& collision, CCollisionInfoList& list) { bool Sphere_AABox(const CInternalCollisionStructure& collision, CCollisionInfoList& list) {
const CCollidableSphere& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim()); const auto& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim());
const CCollidableAABox& p1 = static_cast<const CCollidableAABox&>(collision.GetRight().GetPrim()); const auto& p1 = static_cast<const CCollidableAABox&>(collision.GetRight().GetPrim());
zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform()); zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform());
zeus::CAABox b1 = p1.Transform(collision.GetRight().GetTransform()); zeus::CAABox b1 = p1.Transform(collision.GetRight().GetTransform());
@ -39,7 +39,7 @@ bool Sphere_AABox(const CInternalCollisionStructure& collision, CCollisionInfoLi
} }
} }
if (!flags) { if (flags == 0) {
zeus::CVector3f normal = (s0.position - b1.center()).normalized(); zeus::CVector3f normal = (s0.position - b1.center()).normalized();
zeus::CVector3f point = s0.position + normal * s0.radius; zeus::CVector3f point = s0.position + normal * s0.radius;
CCollisionInfo info(point, p0.GetMaterial(), p1.GetMaterial(), normal); CCollisionInfo info(point, p0.GetMaterial(), p1.GetMaterial(), normal);
@ -47,8 +47,9 @@ bool Sphere_AABox(const CInternalCollisionStructure& collision, CCollisionInfoLi
return true; return true;
} }
if (distSq > s0.radius * s0.radius) if (distSq > s0.radius * s0.radius) {
return false; return false;
}
zeus::CVector3f point; zeus::CVector3f point;
switch (flags) { switch (flags) {
@ -140,8 +141,8 @@ bool Sphere_AABox(const CInternalCollisionStructure& collision, CCollisionInfoLi
} }
bool Sphere_AABox_Bool(const CInternalCollisionStructure& collision) { bool Sphere_AABox_Bool(const CInternalCollisionStructure& collision) {
const CCollidableSphere& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim()); const auto& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim());
const CCollidableAABox& p1 = static_cast<const CCollidableAABox&>(collision.GetRight().GetPrim()); const auto& p1 = static_cast<const CCollidableAABox&>(collision.GetRight().GetPrim());
zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform()); zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform());
zeus::CAABox b1 = p1.Transform(collision.GetRight().GetTransform()); zeus::CAABox b1 = p1.Transform(collision.GetRight().GetTransform());
@ -150,8 +151,8 @@ bool Sphere_AABox_Bool(const CInternalCollisionStructure& collision) {
} }
bool Sphere_Sphere(const CInternalCollisionStructure& collision, CCollisionInfoList& list) { bool Sphere_Sphere(const CInternalCollisionStructure& collision, CCollisionInfoList& list) {
const CCollidableSphere& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim()); const auto& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim());
const CCollidableSphere& p1 = static_cast<const CCollidableSphere&>(collision.GetRight().GetPrim()); const auto& p1 = static_cast<const CCollidableSphere&>(collision.GetRight().GetPrim());
zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform()); zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform());
zeus::CSphere s1 = p1.Transform(collision.GetRight().GetTransform()); zeus::CSphere s1 = p1.Transform(collision.GetRight().GetTransform());
@ -172,8 +173,8 @@ bool Sphere_Sphere(const CInternalCollisionStructure& collision, CCollisionInfoL
} }
bool Sphere_Sphere_Bool(const CInternalCollisionStructure& collision) { bool Sphere_Sphere_Bool(const CInternalCollisionStructure& collision) {
const CCollidableSphere& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim()); const auto& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim());
const CCollidableSphere& p1 = static_cast<const CCollidableSphere&>(collision.GetRight().GetPrim()); const auto& p1 = static_cast<const CCollidableSphere&>(collision.GetRight().GetPrim());
zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform()); zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform());
zeus::CSphere s1 = p1.Transform(collision.GetRight().GetTransform()); zeus::CSphere s1 = p1.Transform(collision.GetRight().GetTransform());
@ -205,8 +206,9 @@ zeus::CAABox CCollidableSphere::CalculateLocalAABox() const {
FourCC CCollidableSphere::GetPrimType() const { return SBIG('SPHR'); } FourCC CCollidableSphere::GetPrimType() const { return SBIG('SPHR'); }
CRayCastResult CCollidableSphere::CastRayInternal(const CInternalRayCastStructure& rayCast) const { CRayCastResult CCollidableSphere::CastRayInternal(const CInternalRayCastStructure& rayCast) const {
if (!rayCast.GetFilter().Passes(GetMaterial())) if (!rayCast.GetFilter().Passes(GetMaterial())) {
return {}; return {};
}
zeus::CSphere xfSphere = Transform(rayCast.GetTransform()); zeus::CSphere xfSphere = Transform(rayCast.GetTransform());
float t = 0.f; float t = 0.f;
@ -227,14 +229,15 @@ const CCollisionPrimitive::Type& CCollidableSphere::GetType() { return sType; }
bool CCollidableSphere::CollideMovingAABox(const CInternalCollisionStructure& collision, const zeus::CVector3f& dir, bool CCollidableSphere::CollideMovingAABox(const CInternalCollisionStructure& collision, const zeus::CVector3f& dir,
double& dOut, CCollisionInfo& infoOut) { double& dOut, CCollisionInfo& infoOut) {
const CCollidableSphere& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim()); const auto& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim());
const CCollidableAABox& p1 = static_cast<const CCollidableAABox&>(collision.GetRight().GetPrim()); const auto& p1 = static_cast<const CCollidableAABox&>(collision.GetRight().GetPrim());
zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform()); zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform());
zeus::CAABox b1 = p1.CalculateAABox(collision.GetRight().GetTransform()); zeus::CAABox b1 = p1.CalculateAABox(collision.GetRight().GetTransform());
double d = dOut; double d = dOut;
zeus::CVector3f point, normal; zeus::CVector3f point;
zeus::CVector3f normal;
if (CollisionUtil::MovingSphereAABox(s0, b1, dir, d, point, normal) && d < dOut) { if (CollisionUtil::MovingSphereAABox(s0, b1, dir, d, point, normal) && d < dOut) {
dOut = d; dOut = d;
infoOut = CCollisionInfo(point, p0.GetMaterial(), p1.GetMaterial(), normal); infoOut = CCollisionInfo(point, p0.GetMaterial(), p1.GetMaterial(), normal);
@ -246,8 +249,8 @@ bool CCollidableSphere::CollideMovingAABox(const CInternalCollisionStructure& co
bool CCollidableSphere::CollideMovingSphere(const CInternalCollisionStructure& collision, const zeus::CVector3f& dir, bool CCollidableSphere::CollideMovingSphere(const CInternalCollisionStructure& collision, const zeus::CVector3f& dir,
double& dOut, CCollisionInfo& infoOut) { double& dOut, CCollisionInfo& infoOut) {
const CCollidableSphere& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim()); const auto& p0 = static_cast<const CCollidableSphere&>(collision.GetLeft().GetPrim());
const CCollidableSphere& p1 = static_cast<const CCollidableSphere&>(collision.GetRight().GetPrim()); const auto& p1 = static_cast<const CCollidableSphere&>(collision.GetRight().GetPrim());
zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform()); zeus::CSphere s0 = p0.Transform(collision.GetLeft().GetTransform());
zeus::CSphere s1 = p1.Transform(collision.GetRight().GetTransform()); zeus::CSphere s1 = p1.Transform(collision.GetRight().GetTransform());

View File

@ -27,7 +27,7 @@ CCollisionActorManager::CCollisionActorManager(CStateManager& mgr, TUniqueId own
if (modDesc.GetNextId().IsInvalid()) { if (modDesc.GetNextId().IsInvalid()) {
// We only have the pivot id // We only have the pivot id
const TUniqueId newId = mgr.AllocateUniqueId(); const TUniqueId newId = mgr.AllocateUniqueId();
CCollisionActor* newAct; CCollisionActor* newAct = nullptr;
if (modDesc.GetType() == CJointCollisionDescription::ECollisionType::Sphere) { if (modDesc.GetType() == CJointCollisionDescription::ECollisionType::Sphere) {
newAct = new CCollisionActor(newId, area, x10_ownerId, active, modDesc.GetRadius(), modDesc.GetMass(), newAct = new CCollisionActor(newId, area, x10_ownerId, active, modDesc.GetRadius(), modDesc.GetMass(),