mirror of https://github.com/AxioDL/metaforce.git
Implement final dynamic collision tests
This commit is contained in:
parent
12646ae23d
commit
6f9e6712ce
|
@ -2,6 +2,7 @@
|
||||||
#include "CollisionUtil.hpp"
|
#include "CollisionUtil.hpp"
|
||||||
#include "CCollidableSphere.hpp"
|
#include "CCollidableSphere.hpp"
|
||||||
#include "CCollisionInfo.hpp"
|
#include "CCollisionInfo.hpp"
|
||||||
|
#include "CInternalRayCastStructure.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -43,9 +44,26 @@ FourCC CCollidableAABox::GetPrimType() const
|
||||||
return SBIG('AABX');
|
return SBIG('AABX');
|
||||||
}
|
}
|
||||||
|
|
||||||
CRayCastResult CCollidableAABox::CastRayInternal(const CInternalRayCastStructure &) const
|
CRayCastResult CCollidableAABox::CastRayInternal(const CInternalRayCastStructure& rayCast) const
|
||||||
{
|
{
|
||||||
return {};
|
if (!rayCast.GetFilter().Passes(GetMaterial()))
|
||||||
|
return {};
|
||||||
|
zeus::CTransform rayCastXfInv = rayCast.GetTransform().inverse();
|
||||||
|
zeus::CVector3f localRayStart = rayCastXfInv * rayCast.GetRay().start;
|
||||||
|
zeus::CVector3f localRayDir = rayCastXfInv.rotate(rayCast.GetRay().dir);
|
||||||
|
float tMin, tMax;
|
||||||
|
int axis;
|
||||||
|
bool sign;
|
||||||
|
if (!CollisionUtil::BoxLineTest(x10_aabox, localRayStart, localRayDir, tMin, tMax, axis, sign) ||
|
||||||
|
tMin < 0.f || (rayCast.GetMaxTime() > 0.f && tMin > rayCast.GetMaxTime()))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
zeus::CVector3f planeNormal;
|
||||||
|
planeNormal[axis] = sign ? 1.f : -1.f;
|
||||||
|
float planeD = axis ? x10_aabox.min[axis] : -x10_aabox.max[axis];
|
||||||
|
CRayCastResult result(tMin, localRayStart + tMin * localRayDir, zeus::CPlane(planeNormal, planeD), GetMaterial());
|
||||||
|
result.Transform(rayCast.GetTransform());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CCollisionPrimitive::Type& CCollidableAABox::GetType()
|
const CCollisionPrimitive::Type& CCollidableAABox::GetType()
|
||||||
|
|
|
@ -26,7 +26,7 @@ bool CCollidableOBBTree::LineIntersectsLeaf(const COBBTree::CLeafData& leaf, CRa
|
||||||
if (CollisionUtil::RayTriangleIntersection(info.GetRay().start, info.GetRay().dir,
|
if (CollisionUtil::RayTriangleIntersection(info.GetRay().start, info.GetRay().dir,
|
||||||
surface.GetVerts(), info.Magnitude()))
|
surface.GetVerts(), info.Magnitude()))
|
||||||
{
|
{
|
||||||
intersectIdx = i;
|
intersectIdx = surfIdx;
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "CCollisionInfoList.hpp"
|
#include "CCollisionInfoList.hpp"
|
||||||
#include "CCollidableAABox.hpp"
|
#include "CCollidableAABox.hpp"
|
||||||
#include "CollisionUtil.hpp"
|
#include "CollisionUtil.hpp"
|
||||||
|
#include "CInternalRayCastStructure.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -211,7 +212,7 @@ const zeus::CSphere& CCollidableSphere::GetSphere() const { return x10_sphere; }
|
||||||
|
|
||||||
void CCollidableSphere::SetSphereCenter(const zeus::CVector3f&)
|
void CCollidableSphere::SetSphereCenter(const zeus::CVector3f&)
|
||||||
{
|
{
|
||||||
|
/* Remove me? */
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CSphere CCollidableSphere::Transform(const zeus::CTransform& xf) const
|
zeus::CSphere CCollidableSphere::Transform(const zeus::CTransform& xf) const
|
||||||
|
@ -221,13 +222,40 @@ zeus::CSphere CCollidableSphere::Transform(const zeus::CTransform& xf) const
|
||||||
|
|
||||||
u32 CCollidableSphere::GetTableIndex() const { return sTableIndex; }
|
u32 CCollidableSphere::GetTableIndex() const { return sTableIndex; }
|
||||||
|
|
||||||
zeus::CAABox CCollidableSphere::CalculateAABox(const zeus::CTransform&) const { return {}; }
|
zeus::CAABox CCollidableSphere::CalculateAABox(const zeus::CTransform& xf) const
|
||||||
|
{
|
||||||
|
zeus::CVector3f xfPos = xf * x10_sphere.position;
|
||||||
|
return {xfPos - x10_sphere.radius, xfPos + x10_sphere.radius};
|
||||||
|
}
|
||||||
|
|
||||||
zeus::CAABox CCollidableSphere::CalculateLocalAABox() const { return {}; }
|
zeus::CAABox CCollidableSphere::CalculateLocalAABox() const
|
||||||
|
{
|
||||||
|
return {x10_sphere.position - x10_sphere.radius, x10_sphere.position + x10_sphere.radius};
|
||||||
|
}
|
||||||
|
|
||||||
FourCC CCollidableSphere::GetPrimType() const { return SBIG('SPHR'); }
|
FourCC CCollidableSphere::GetPrimType() const { return SBIG('SPHR'); }
|
||||||
|
|
||||||
CRayCastResult CCollidableSphere::CastRayInternal(const CInternalRayCastStructure&) const { return {}; }
|
CRayCastResult CCollidableSphere::CastRayInternal(const CInternalRayCastStructure& rayCast) const
|
||||||
|
{
|
||||||
|
if (!rayCast.GetFilter().Passes(GetMaterial()))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
zeus::CSphere xfSphere = Transform(rayCast.GetTransform());
|
||||||
|
float t = 0.f;
|
||||||
|
zeus::CVector3f point;
|
||||||
|
if (CollisionUtil::RaySphereIntersection(xfSphere, rayCast.GetRay().start, rayCast.GetRay().dir,
|
||||||
|
rayCast.GetMaxTime(), t, point))
|
||||||
|
{
|
||||||
|
zeus::CVector3f delta = point - xfSphere.position;
|
||||||
|
float deltaMag = delta.magnitude();
|
||||||
|
zeus::CUnitVector3f planeNormal =
|
||||||
|
(deltaMag > 0.01f) ? delta * (1.f / deltaMag) : rayCast.GetRay().dir;
|
||||||
|
float planeD = point.dot(planeNormal);
|
||||||
|
return CRayCastResult(t, point, zeus::CPlane(planeNormal, planeD), GetMaterial());
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
const CCollisionPrimitive::Type& CCollidableSphere::GetType() { return sType; }
|
const CCollisionPrimitive::Type& CCollidableSphere::GetType() { return sType; }
|
||||||
|
|
||||||
|
|
|
@ -144,14 +144,42 @@ bool CCollisionPrimitive::CollideBoolean(CInternalCollisionStructure::CPrimDesc&
|
||||||
return InternalCollideBoolean({prim0, prim1});
|
return InternalCollideBoolean({prim0, prim1});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CCollisionPrimitive::InternalCollideMoving(const CInternalCollisionStructure& collision,
|
||||||
|
const zeus::CVector3f& dir,
|
||||||
|
double& dOut, CCollisionInfo& infoOut)
|
||||||
|
{
|
||||||
|
u32 idx0 = collision.GetLeft().GetPrim().GetTableIndex();
|
||||||
|
u32 idx1 = collision.GetRight().GetPrim().GetTableIndex();
|
||||||
|
|
||||||
|
MovingComparisonFunc func;
|
||||||
|
if (idx0 == -1 || idx1 == -1)
|
||||||
|
{
|
||||||
|
sNullMovingCollider = nullptr;
|
||||||
|
func = sNullMovingCollider;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
func = (*sTableOfMovingCollidables)[sNumTypes * idx1 + idx0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (func)
|
||||||
|
{
|
||||||
|
if (!collision.GetLeft().GetFilter().Passes(collision.GetRight().GetPrim().GetMaterial()) ||
|
||||||
|
!collision.GetRight().GetFilter().Passes(collision.GetLeft().GetPrim().GetMaterial()))
|
||||||
|
return false;
|
||||||
|
return func(collision, dir, dOut, infoOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool CCollisionPrimitive::CollideMoving(CInternalCollisionStructure::CPrimDesc& prim0,
|
bool CCollisionPrimitive::CollideMoving(CInternalCollisionStructure::CPrimDesc& prim0,
|
||||||
CInternalCollisionStructure::CPrimDesc& prim1,
|
CInternalCollisionStructure::CPrimDesc& prim1,
|
||||||
const zeus::CVector3f& dir,
|
const zeus::CVector3f& dir,
|
||||||
double& dOut,
|
double& dOut,
|
||||||
CCollisionInfo& infoOut)
|
CCollisionInfo& infoOut)
|
||||||
{
|
{
|
||||||
// TODO: Finish
|
return InternalCollideMoving({prim0, prim1}, dir, dOut, infoOut);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCollisionPrimitive::InitBeginTypes()
|
void CCollisionPrimitive::InitBeginTypes()
|
||||||
|
|
|
@ -133,6 +133,8 @@ private:
|
||||||
|
|
||||||
static bool InternalCollide(const CInternalCollisionStructure& collision, CCollisionInfoList& list);
|
static bool InternalCollide(const CInternalCollisionStructure& collision, CCollisionInfoList& list);
|
||||||
static bool InternalCollideBoolean(const CInternalCollisionStructure& collision);
|
static bool InternalCollideBoolean(const CInternalCollisionStructure& collision);
|
||||||
|
static bool InternalCollideMoving(const CInternalCollisionStructure& collision, const zeus::CVector3f& dir,
|
||||||
|
double& dOut, CCollisionInfo& infoOut);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CCollisionPrimitive() = default;
|
CCollisionPrimitive() = default;
|
||||||
|
@ -155,7 +157,7 @@ public:
|
||||||
CInternalCollisionStructure::CPrimDesc& prim1);
|
CInternalCollisionStructure::CPrimDesc& prim1);
|
||||||
static bool CollideMoving(CInternalCollisionStructure::CPrimDesc& prim0,
|
static bool CollideMoving(CInternalCollisionStructure::CPrimDesc& prim0,
|
||||||
CInternalCollisionStructure::CPrimDesc& prim1,
|
CInternalCollisionStructure::CPrimDesc& prim1,
|
||||||
const zeus::CVector3f& vec,
|
const zeus::CVector3f& dir,
|
||||||
double& dOut,
|
double& dOut,
|
||||||
CCollisionInfo& infoOut);
|
CCollisionInfo& infoOut);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue