mirror of https://github.com/AxioDL/metaforce.git
Work on collision related implementations
This commit is contained in:
parent
47e73f9f80
commit
71a361f54e
|
@ -0,0 +1,16 @@
|
|||
#include "CAABoxFilter.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
void CAABoxFilter::Filter(const CCollisionInfoList& in, CCollisionInfoList& out) const
|
||||
{
|
||||
FilterBoxFloorCollisions(in, out);
|
||||
}
|
||||
|
||||
void CAABoxFilter::FilterBoxFloorCollisions(const CCollisionInfoList& in, CCollisionInfoList& out)
|
||||
{
|
||||
/* TODO: finish */
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef __URDE_CAABOXFILTER_HPP__
|
||||
#define __URDE_CAABOXFILTER_HPP__
|
||||
|
||||
#include "ICollisionFilter.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
class CAABoxFilter : public ICollisionFilter
|
||||
{
|
||||
public:
|
||||
CAABoxFilter(CActor& actor) : ICollisionFilter(actor) {}
|
||||
void Filter(const CCollisionInfoList& in, CCollisionInfoList& out) const;
|
||||
static void FilterBoxFloorCollisions(const CCollisionInfoList& in, CCollisionInfoList& out);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __URDE_CAABOXFILTER_HPP__
|
|
@ -0,0 +1,11 @@
|
|||
#include "CBallFilter.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
void CBallFilter::Filter(const CCollisionInfoList& in, CCollisionInfoList& out) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef __URDE_CBALLFILTER_HPP__
|
||||
#define __URDE_CBALLFILTER_HPP__
|
||||
|
||||
#include "ICollisionFilter.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CPhysicsActor;
|
||||
|
||||
class CBallFilter : public ICollisionFilter
|
||||
{
|
||||
public:
|
||||
CBallFilter(CActor& actor) : ICollisionFilter(actor) {}
|
||||
void Filter(const CCollisionInfoList& in, CCollisionInfoList& out) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __URDE_CBALLFILTER_HPP__
|
|
@ -1,4 +1,5 @@
|
|||
#include "CCollidableAABox.hpp"
|
||||
#include "CollisionUtil.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -68,14 +69,26 @@ bool CCollidableAABox::CollideMovingSphere(const CInternalCollisionStructure &,
|
|||
namespace Collide
|
||||
{
|
||||
|
||||
bool AABox_AABox(const CInternalCollisionStructure &, CCollisionInfoList &)
|
||||
bool AABox_AABox(const CInternalCollisionStructure& collision, CCollisionInfoList& list)
|
||||
{
|
||||
return false;
|
||||
const CCollidableAABox& box0 = static_cast<const CCollidableAABox&>(collision.GetLeft().GetPrim());
|
||||
const CCollidableAABox& box1 = static_cast<const CCollidableAABox&>(collision.GetRight().GetPrim());
|
||||
|
||||
zeus::CAABox aabb0 = box0.Transform(collision.GetLeft().GetTransform());
|
||||
zeus::CAABox aabb1 = box1.Transform(collision.GetRight().GetTransform());
|
||||
|
||||
return CollisionUtil::AABoxAABoxIntersection(aabb0, box0.GetMaterial(), aabb1, box1.GetMaterial(), list);
|
||||
}
|
||||
|
||||
bool AABox_AABox_Bool(const CInternalCollisionStructure &)
|
||||
bool AABox_AABox_Bool(const CInternalCollisionStructure& collision)
|
||||
{
|
||||
return false;
|
||||
const CCollidableAABox& box0 = static_cast<const CCollidableAABox&>(collision.GetLeft().GetPrim());
|
||||
const CCollidableAABox& box1 = static_cast<const CCollidableAABox&>(collision.GetRight().GetPrim());
|
||||
|
||||
zeus::CAABox aabb0 = box0.Transform(collision.GetLeft().GetTransform());
|
||||
zeus::CAABox aabb1 = box1.Transform(collision.GetRight().GetTransform());
|
||||
|
||||
return CollisionUtil::AABoxAABoxIntersection(aabb0, aabb1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
virtual zeus::CAABox CalculateLocalAABox() const;
|
||||
virtual FourCC GetPrimType() const;
|
||||
virtual CRayCastResult CastRayInternal(const CInternalRayCastStructure&) const;
|
||||
const zeus::CAABox& GetAABB() const { return x10_aabox; }
|
||||
|
||||
static const CCollisionPrimitive::Type& GetType();
|
||||
static void SetStaticTableIndex(u32 index);
|
||||
|
|
|
@ -32,6 +32,11 @@ void CCollidableSphere::SetSphereCenter(const zeus::CVector3f&)
|
|||
|
||||
}
|
||||
|
||||
zeus::CSphere CCollidableSphere::Transform(const zeus::CTransform& xf) const
|
||||
{
|
||||
return zeus::CSphere(xf * x10_sphere.position, x10_sphere.radius);
|
||||
}
|
||||
|
||||
u32 CCollidableSphere::GetTableIndex() const { return sTableIndex; }
|
||||
|
||||
zeus::CAABox CCollidableSphere::CalculateAABox(const zeus::CTransform&) const { return {}; }
|
||||
|
|
|
@ -25,6 +25,7 @@ public:
|
|||
|
||||
const zeus::CSphere& GetSphere() const;
|
||||
void SetSphereCenter(const zeus::CVector3f&);
|
||||
zeus::CSphere Transform(const zeus::CTransform& xf) const;
|
||||
|
||||
virtual u32 GetTableIndex() const;
|
||||
virtual zeus::CAABox CalculateAABox(const zeus::CTransform&) const;
|
||||
|
|
|
@ -3,9 +3,30 @@
|
|||
namespace urde
|
||||
{
|
||||
|
||||
CCollisionInfo CCollisionInfo::GetSwapped() const
|
||||
{
|
||||
CCollisionInfo ret;
|
||||
ret.x0_point = x0_point;
|
||||
ret.xc_ = xc_;
|
||||
ret.x30_valid = x30_valid;
|
||||
ret.x31_ = x31_;
|
||||
ret.x38_materialLeft = x40_materialRight;
|
||||
ret.x40_materialRight = x38_materialLeft;
|
||||
ret.x48_normalLeft = x54_normalRight;
|
||||
ret.x54_normalRight = x48_normalLeft;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CCollisionInfo::Swap()
|
||||
{
|
||||
x48_normalLeft = -x48_normalLeft;
|
||||
x54_normalRight = -x54_normalRight;
|
||||
std::swap(x38_materialLeft, x40_materialRight);
|
||||
}
|
||||
|
||||
zeus::CVector3f CCollisionInfo::GetExtreme() const
|
||||
{
|
||||
return (x18_ + (x0_aabox.min + x0_aabox.max) + x24_);
|
||||
return x0_point + xc_ + x18_ + x24_;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,42 +4,54 @@
|
|||
#include "RetroTypes.hpp"
|
||||
#include "CMaterialList.hpp"
|
||||
#include "zeus/CAABox.hpp"
|
||||
#include "zeus/CMatrix3f.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CCollisionInfo
|
||||
{
|
||||
zeus::CAABox x0_aabox = zeus::CAABox::skNullBox;
|
||||
zeus::CVector3f x0_point;
|
||||
zeus::CVector3f xc_;
|
||||
zeus::CVector3f x18_;
|
||||
zeus::CVector3f x24_;
|
||||
bool x30_ = false;
|
||||
bool x30_valid = false;
|
||||
bool x31_ = false;
|
||||
/* u32 x34_; */
|
||||
CMaterialList x38_;
|
||||
CMaterialList x40_;
|
||||
zeus::CVector3f x48_;
|
||||
zeus::CVector3f x54_;
|
||||
CMaterialList x38_materialLeft;
|
||||
CMaterialList x40_materialRight;
|
||||
zeus::CVector3f x48_normalLeft;
|
||||
zeus::CVector3f x54_normalRight;
|
||||
public:
|
||||
CCollisionInfo() = default;
|
||||
CCollisionInfo(const zeus::CVector3f& v1, const CMaterialList& list1, const CMaterialList& list2,
|
||||
const zeus::CVector3f& v2, const zeus::CVector3f& v3);
|
||||
CCollisionInfo(const zeus::CVector3f& v1, const CMaterialList& list1, const CMaterialList& list2,
|
||||
zeus::CVector3f const& v2);
|
||||
CCollisionInfo(const zeus::CVector3f& point, const CMaterialList& list1, const CMaterialList& list2,
|
||||
const zeus::CVector3f& normalLeft, const zeus::CVector3f& normalRight)
|
||||
: x0_point(point), x30_valid(true), x31_(false), x38_materialLeft(list2), x40_materialRight(list1),
|
||||
x48_normalLeft(normalLeft), x54_normalRight(normalRight) {}
|
||||
CCollisionInfo(const zeus::CVector3f& point, const CMaterialList& list1, const CMaterialList& list2,
|
||||
const zeus::CVector3f& normal)
|
||||
: x0_point(point), x30_valid(true), x31_(false), x38_materialLeft(list2), x40_materialRight(list1),
|
||||
x48_normalLeft(normal), x54_normalRight(-normal) {}
|
||||
CCollisionInfo(const zeus::CAABox& aabox, const CMaterialList& list1, const CMaterialList& list2,
|
||||
const zeus::CVector3f& v1, const zeus::CVector3f& v2)
|
||||
: x0_aabox(aabox)
|
||||
const zeus::CVector3f& normalLeft, const zeus::CVector3f& normalRight)
|
||||
: x0_point(aabox.min),
|
||||
xc_(aabox.max.x - aabox.min.x, 0.f, 0.f),
|
||||
x18_(0.f, aabox.max.y - aabox.min.y, 0.f),
|
||||
x24_(0.f, 0.f, aabox.max.z - aabox.min.z),
|
||||
x30_valid(true), x31_(true), x38_materialLeft(list2),
|
||||
x40_materialRight(list1), x48_normalLeft(normalLeft),
|
||||
x54_normalRight(normalRight)
|
||||
{}
|
||||
|
||||
bool IsValid() const;
|
||||
void GetMaterialLeft() const;
|
||||
void GetMaterialRight() const;
|
||||
CCollisionInfo GetSwapped() const;
|
||||
bool IsValid() const { return x30_valid; }
|
||||
const CMaterialList& GetMaterialLeft() const { return x38_materialLeft; }
|
||||
const CMaterialList& GetMaterialRight() const { return x40_materialRight; }
|
||||
zeus::CVector3f GetExtreme() const;
|
||||
void Swap();
|
||||
void Transform(const zeus::CTransform&);
|
||||
zeus::CVector3f GetNormalLeft() const;
|
||||
zeus::CVector3f GetNormalRight() const;
|
||||
zeus::CVector3f GetNormalLeft() const { return x48_normalLeft; }
|
||||
zeus::CVector3f GetNormalRight() const { return x54_normalRight; }
|
||||
zeus::CVector3f GetOrigin() const;
|
||||
zeus::CVector3f GetPoint() const;
|
||||
zeus::CVector3f GetPoint() const { return x0_point; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
#define __URDE_CCOLLISIONINFOLIST_HPP__
|
||||
|
||||
#include "RetroTypes.hpp"
|
||||
#include "CCollisionInfo.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CCollisionInfo;
|
||||
class CCollisionInfoList
|
||||
{
|
||||
rstl::reserved_vector<CCollisionInfo, 32> x0_list;
|
||||
|
@ -15,15 +15,23 @@ public:
|
|||
void GetAverageLeftNormal() const;
|
||||
void GetAveragePoint() const;
|
||||
void GetUnionOfAllLeftMaterials() const;
|
||||
s32 GetCount() const;
|
||||
s32 GetCount() const { return x0_list.size(); }
|
||||
void Swap(s32);
|
||||
|
||||
void Add(const CCollisionInfo&, bool);
|
||||
void Clear();
|
||||
void End();
|
||||
void End() const;
|
||||
void Begin();
|
||||
void Begin() const;
|
||||
void Add(const CCollisionInfo& info, bool swap)
|
||||
{
|
||||
if (x0_list.size() == 32)
|
||||
return;
|
||||
if (!swap)
|
||||
x0_list.push_back(info);
|
||||
else
|
||||
x0_list.push_back(info.GetSwapped());
|
||||
}
|
||||
void Clear() { x0_list.clear(); }
|
||||
rstl::reserved_vector<CCollisionInfo, 32>::iterator end() { return x0_list.end(); }
|
||||
rstl::reserved_vector<CCollisionInfo, 32>::const_iterator end() const { return x0_list.end(); }
|
||||
rstl::reserved_vector<CCollisionInfo, 32>::iterator begin() { return x0_list.begin(); }
|
||||
rstl::reserved_vector<CCollisionInfo, 32>::const_iterator begin() const { return x0_list.begin(); }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -2,18 +2,23 @@
|
|||
#include "CInternalRayCastStructure.hpp"
|
||||
#include "CMaterialFilter.hpp"
|
||||
#include "InternalColliders.hpp"
|
||||
#include "CCollisionInfoList.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
std::unique_ptr<std::vector<CCollisionPrimitive::Type>> CCollisionPrimitive::sCollisionTypeList;
|
||||
std::unique_ptr<std::vector<ComparisonFunc>> CCollisionPrimitive::sTableOfCollidables;
|
||||
std::unique_ptr<std::vector<BooleanComparisonFunc>> CCollisionPrimitive::sTableOfBooleanCollidables;
|
||||
std::unique_ptr<std::vector<MovingComparisonFunc>> CCollisionPrimitive::sTableOfMovingCollidables;
|
||||
s32 CCollisionPrimitive::sNumTypes = 0;
|
||||
bool CCollisionPrimitive::sInitComplete = false;
|
||||
bool CCollisionPrimitive::sTypesAdded = false;
|
||||
bool CCollisionPrimitive::sTypesAdding = false;
|
||||
bool CCollisionPrimitive::sCollidersAdded = false;
|
||||
bool CCollisionPrimitive::sCollidersAdding = false;
|
||||
std::unique_ptr<std::vector<CCollisionPrimitive::Type>> CCollisionPrimitive::sCollisionTypeList;
|
||||
std::unique_ptr<std::vector<ComparisonFunc>> CCollisionPrimitive::sTableOfCollidables;
|
||||
std::unique_ptr<std::vector<BooleanComparisonFunc>> CCollisionPrimitive::sTableOfBooleanCollidables;
|
||||
std::unique_ptr<std::vector<MovingComparisonFunc>> CCollisionPrimitive::sTableOfMovingCollidables;
|
||||
ComparisonFunc CCollisionPrimitive::sNullCollider = {};
|
||||
BooleanComparisonFunc CCollisionPrimitive::sNullBooleanCollider = {};
|
||||
MovingComparisonFunc CCollisionPrimitive::sNullMovingCollider = {};
|
||||
CCollisionPrimitive::CCollisionPrimitive(const CMaterialList& list) : x8_material(list) {}
|
||||
|
||||
void CCollisionPrimitive::SetMaterial(const CMaterialList& material) { x8_material = material; }
|
||||
|
@ -26,6 +31,119 @@ CRayCastResult CCollisionPrimitive::CastRay(const zeus::CVector3f& start, const
|
|||
return CastRayInternal(CInternalRayCastStructure(start, dir, length, xf, filter));
|
||||
}
|
||||
|
||||
bool CCollisionPrimitive::InternalCollide(const CInternalCollisionStructure& collision,
|
||||
CCollisionInfoList& list)
|
||||
{
|
||||
u32 idx0 = collision.GetLeft().GetPrim().GetTableIndex();
|
||||
u32 idx1 = collision.GetRight().GetPrim().GetTableIndex();
|
||||
|
||||
ComparisonFunc func;
|
||||
if (idx0 == -1 || idx1 == -1)
|
||||
{
|
||||
sNullCollider = nullptr;
|
||||
func = sNullCollider;
|
||||
}
|
||||
else
|
||||
{
|
||||
func = (*sTableOfCollidables)[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, list);
|
||||
}
|
||||
|
||||
if (idx0 == -1 || idx1 == -1)
|
||||
{
|
||||
sNullCollider = nullptr;
|
||||
func = sNullCollider;
|
||||
}
|
||||
else
|
||||
{
|
||||
func = (*sTableOfCollidables)[sNumTypes * idx0 + idx1];
|
||||
}
|
||||
|
||||
if (func)
|
||||
{
|
||||
if (!collision.GetLeft().GetFilter().Passes(collision.GetRight().GetPrim().GetMaterial()) ||
|
||||
!collision.GetRight().GetFilter().Passes(collision.GetLeft().GetPrim().GetMaterial()))
|
||||
return false;
|
||||
CInternalCollisionStructure swappedCollision(collision.GetRight(), collision.GetLeft());
|
||||
u32 startListCount = list.GetCount();
|
||||
if (func(swappedCollision, list))
|
||||
{
|
||||
for (auto it = list.begin() + startListCount ; it != list.end() ; ++it)
|
||||
it->Swap();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCollisionPrimitive::Collide(CInternalCollisionStructure::CPrimDesc& prim0,
|
||||
CInternalCollisionStructure::CPrimDesc& prim1,
|
||||
CCollisionInfoList& list)
|
||||
{
|
||||
return InternalCollide({prim0, prim1}, list);
|
||||
}
|
||||
|
||||
bool CCollisionPrimitive::InternalCollideBoolean(const CInternalCollisionStructure& collision)
|
||||
{
|
||||
u32 idx0 = collision.GetLeft().GetPrim().GetTableIndex();
|
||||
u32 idx1 = collision.GetRight().GetPrim().GetTableIndex();
|
||||
|
||||
BooleanComparisonFunc func;
|
||||
if (idx0 == -1 || idx1 == -1)
|
||||
{
|
||||
sNullBooleanCollider = nullptr;
|
||||
func = sNullBooleanCollider;
|
||||
}
|
||||
else
|
||||
{
|
||||
func = (*sTableOfBooleanCollidables)[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);
|
||||
}
|
||||
|
||||
if (idx0 == -1 || idx1 == -1)
|
||||
{
|
||||
sNullBooleanCollider = nullptr;
|
||||
func = sNullBooleanCollider;
|
||||
}
|
||||
else
|
||||
{
|
||||
func = (*sTableOfBooleanCollidables)[sNumTypes * idx0 + idx1];
|
||||
}
|
||||
|
||||
if (func)
|
||||
{
|
||||
if (!collision.GetLeft().GetFilter().Passes(collision.GetRight().GetPrim().GetMaterial()) ||
|
||||
!collision.GetRight().GetFilter().Passes(collision.GetLeft().GetPrim().GetMaterial()))
|
||||
return false;
|
||||
CInternalCollisionStructure swappedCollision(collision.GetRight(), collision.GetLeft());
|
||||
return func(swappedCollision);
|
||||
}
|
||||
|
||||
CCollisionInfoList list;
|
||||
return InternalCollide(collision, list);
|
||||
}
|
||||
|
||||
bool CCollisionPrimitive::CollideBoolean(CInternalCollisionStructure::CPrimDesc& prim0,
|
||||
CInternalCollisionStructure::CPrimDesc& prim1)
|
||||
{
|
||||
return InternalCollideBoolean({prim0, prim1});
|
||||
}
|
||||
|
||||
void CCollisionPrimitive::InitBeginTypes()
|
||||
{
|
||||
sCollisionTypeList.reset(new std::vector<CCollisionPrimitive::Type>());
|
||||
|
@ -37,67 +155,154 @@ void CCollisionPrimitive::InitBeginTypes()
|
|||
void CCollisionPrimitive::InitAddType(const CCollisionPrimitive::Type& tp)
|
||||
{
|
||||
tp.GetSetter()(sCollisionTypeList->size());
|
||||
|
||||
sCollisionTypeList->reserve(sCollisionTypeList->size() + 1);
|
||||
sCollisionTypeList->push_back(tp);
|
||||
}
|
||||
|
||||
void CCollisionPrimitive::InitEndTypes() { sTypesAdding = false; }
|
||||
void CCollisionPrimitive::InitEndTypes()
|
||||
{
|
||||
sCollisionTypeList->shrink_to_fit();
|
||||
sNumTypes = sCollisionTypeList->size();
|
||||
sTypesAdding = false;
|
||||
sTypesAdded = true;
|
||||
}
|
||||
|
||||
void CCollisionPrimitive::InitBeginColliders()
|
||||
{
|
||||
sTableOfCollidables.reset(new std::vector<ComparisonFunc>());
|
||||
sTableOfBooleanCollidables.reset(new std::vector<BooleanComparisonFunc>());
|
||||
sTableOfMovingCollidables.reset(new std::vector<MovingComparisonFunc>());
|
||||
size_t tableSz = sCollisionTypeList->size() * sCollisionTypeList->size();
|
||||
sTableOfCollidables->resize(tableSz);
|
||||
sTableOfBooleanCollidables->resize(tableSz);
|
||||
sTableOfMovingCollidables->resize(tableSz);
|
||||
sCollidersAdding = true;
|
||||
InternalColliders::AddColliders();
|
||||
}
|
||||
|
||||
void CCollisionPrimitive::InitAddBooleanCollider(const CCollisionPrimitive::BooleanComparison& cmp)
|
||||
{
|
||||
int idx0 = -1;
|
||||
for (int i=0 ; i<sCollisionTypeList->size() ; ++i)
|
||||
{
|
||||
if (!strcmp(cmp.GetType1(), (*sCollisionTypeList)[i].GetInfo()))
|
||||
{
|
||||
idx0 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int idx1 = -1;
|
||||
for (int i=0 ; i<sCollisionTypeList->size() ; ++i)
|
||||
{
|
||||
if (!strcmp(cmp.GetType2(), (*sCollisionTypeList)[i].GetInfo()))
|
||||
{
|
||||
idx1 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx0 < 0 || idx1 < 0 || idx0 >= sNumTypes || idx1 >= sNumTypes)
|
||||
return;
|
||||
|
||||
BooleanComparisonFunc& funcOut =
|
||||
(idx0 == -1 || idx1 == -1) ? sNullBooleanCollider : (*sTableOfBooleanCollidables)[idx1 * sNumTypes + idx0];
|
||||
funcOut = cmp.GetCollider();
|
||||
}
|
||||
|
||||
void CCollisionPrimitive::InitAddBooleanCollider(const BooleanComparisonFunc& cmp, const char* a, const char* b)
|
||||
void CCollisionPrimitive::InitAddBooleanCollider(BooleanComparisonFunc cmp, const char* a, const char* b)
|
||||
{
|
||||
InitAddBooleanCollider({std::move(cmp), a, b});
|
||||
InitAddBooleanCollider({cmp, a, b});
|
||||
}
|
||||
|
||||
void CCollisionPrimitive::InitAddMovingCollider(const CCollisionPrimitive::MovingComparison& cmp) {}
|
||||
|
||||
void CCollisionPrimitive::InitAddMovingCollider(const MovingComparisonFunc& cmp, const char* a, const char* b)
|
||||
void CCollisionPrimitive::InitAddMovingCollider(const CCollisionPrimitive::MovingComparison& cmp)
|
||||
{
|
||||
InitAddMovingCollider({std::move(cmp), a, b});
|
||||
int idx0 = -1;
|
||||
for (int i=0 ; i<sCollisionTypeList->size() ; ++i)
|
||||
{
|
||||
if (!strcmp(cmp.GetType1(), (*sCollisionTypeList)[i].GetInfo()))
|
||||
{
|
||||
idx0 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int idx1 = -1;
|
||||
for (int i=0 ; i<sCollisionTypeList->size() ; ++i)
|
||||
{
|
||||
if (!strcmp(cmp.GetType2(), (*sCollisionTypeList)[i].GetInfo()))
|
||||
{
|
||||
idx1 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx0 < 0 || idx1 < 0 || idx0 >= sNumTypes || idx1 >= sNumTypes)
|
||||
return;
|
||||
|
||||
MovingComparisonFunc& funcOut =
|
||||
(idx0 == -1 || idx1 == -1) ? sNullMovingCollider : (*sTableOfMovingCollidables)[idx1 * sNumTypes + idx0];
|
||||
funcOut = cmp.GetCollider();
|
||||
}
|
||||
|
||||
void CCollisionPrimitive::InitAddMovingCollider(MovingComparisonFunc cmp, const char* a, const char* b)
|
||||
{
|
||||
InitAddMovingCollider({cmp, a, b});
|
||||
}
|
||||
|
||||
void CCollisionPrimitive::InitAddCollider(const CCollisionPrimitive::Comparison& cmp)
|
||||
{
|
||||
int idx0 = -1;
|
||||
for (int i=0 ; i<sCollisionTypeList->size() ; ++i)
|
||||
{
|
||||
if (!strcmp(cmp.GetType1(), (*sCollisionTypeList)[i].GetInfo()))
|
||||
{
|
||||
idx0 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int idx1 = -1;
|
||||
for (int i=0 ; i<sCollisionTypeList->size() ; ++i)
|
||||
{
|
||||
if (!strcmp(cmp.GetType2(), (*sCollisionTypeList)[i].GetInfo()))
|
||||
{
|
||||
idx1 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx0 < 0 || idx1 < 0 || idx0 >= sNumTypes || idx1 >= sNumTypes)
|
||||
return;
|
||||
|
||||
ComparisonFunc& funcOut =
|
||||
(idx0 == -1 || idx1 == -1) ? sNullCollider : (*sTableOfCollidables)[idx1 * sNumTypes + idx0];
|
||||
funcOut = cmp.GetCollider();
|
||||
}
|
||||
|
||||
void CCollisionPrimitive::InitAddCollider(const ComparisonFunc& cmp, const char* a, const char* b)
|
||||
void CCollisionPrimitive::InitAddCollider(ComparisonFunc cmp, const char* a, const char* b)
|
||||
{
|
||||
InitAddCollider({std::move(cmp), a, b});
|
||||
InitAddCollider({cmp, a, b});
|
||||
}
|
||||
|
||||
void CCollisionPrimitive::InitEndColliders()
|
||||
{
|
||||
sCollidersAdding = false;
|
||||
sCollidersAdded = true;
|
||||
sInitComplete = true;
|
||||
}
|
||||
|
||||
void CCollisionPrimitive::Unitialize()
|
||||
void CCollisionPrimitive::Uninitialize()
|
||||
{
|
||||
sInitComplete = false;
|
||||
sCollidersAdding = false;
|
||||
sCollidersAdded = false;
|
||||
sTypesAdding = false;
|
||||
sTypesAdded = false;
|
||||
sNumTypes = 0;
|
||||
sCollisionTypeList.reset();
|
||||
sTableOfCollidables.reset();
|
||||
sTableOfMovingCollidables.reset();
|
||||
sTableOfBooleanCollidables.reset();
|
||||
}
|
||||
|
||||
CCollisionPrimitive::Type::Type(const std::function<void(u32)>& setter, const char* info)
|
||||
: x0_setter(setter), x4_info(info)
|
||||
{
|
||||
}
|
||||
|
||||
const char* CCollisionPrimitive::Type::GetInfo() const { return x4_info; }
|
||||
|
||||
std::function<void(u32)> CCollisionPrimitive::Type::GetSetter() const { return x0_setter; }
|
||||
}
|
||||
|
|
|
@ -9,33 +9,60 @@
|
|||
|
||||
namespace urde
|
||||
{
|
||||
class CCollisionPrimitive;
|
||||
class CMaterialFilter;
|
||||
|
||||
class CInternalCollisionStructure
|
||||
{
|
||||
public:
|
||||
class CPrimDesc
|
||||
{
|
||||
const CCollisionPrimitive& x0_prim;
|
||||
const CMaterialFilter& x4_filter;
|
||||
zeus::CTransform x8_xf;
|
||||
public:
|
||||
CPrimDesc(const CCollisionPrimitive& prim, const CMaterialFilter& filter,
|
||||
const zeus::CTransform& xf)
|
||||
: x0_prim(prim), x4_filter(filter), x8_xf(xf) {}
|
||||
const CCollisionPrimitive& GetPrim() const { return x0_prim; }
|
||||
const CMaterialFilter& GetFilter() const { return x4_filter; }
|
||||
const zeus::CTransform& GetTransform() const { return x8_xf; }
|
||||
};
|
||||
private:
|
||||
CPrimDesc x0_p0;
|
||||
CPrimDesc x38_p1;
|
||||
public:
|
||||
CInternalCollisionStructure(const CPrimDesc& p0, const CPrimDesc& p1)
|
||||
: x0_p0(p0), x38_p1(p1) {}
|
||||
const CPrimDesc& GetLeft() const { return x0_p0; }
|
||||
const CPrimDesc& GetRight() const { return x38_p1; }
|
||||
};
|
||||
|
||||
class COBBTree;
|
||||
class CInternalCollisionStructure;
|
||||
class CCollisionInfo;
|
||||
class CCollisionInfoList;
|
||||
class CInternalRayCastStructure;
|
||||
class CMaterialFilter;
|
||||
using ComparisonFunc = std::function<bool(const CInternalCollisionStructure&, CCollisionInfoList&)>;
|
||||
using MovingComparisonFunc =
|
||||
std::function<bool(const CInternalCollisionStructure&, const zeus::CVector3f&, double&, CCollisionInfo&)>;
|
||||
using BooleanComparisonFunc = std::function<bool(const CInternalCollisionStructure&)>;
|
||||
typedef bool(*ComparisonFunc)(const CInternalCollisionStructure&, CCollisionInfoList&);
|
||||
typedef bool(*MovingComparisonFunc)(const CInternalCollisionStructure&, const zeus::CVector3f&,
|
||||
double&, CCollisionInfo&);
|
||||
typedef bool(*BooleanComparisonFunc)(const CInternalCollisionStructure&);
|
||||
typedef void(*PrimitiveSetter)(u32);
|
||||
|
||||
class CCollisionPrimitive
|
||||
{
|
||||
public:
|
||||
class Type
|
||||
{
|
||||
std::function<void(u32)> x0_setter;
|
||||
PrimitiveSetter x0_setter;
|
||||
const char* x4_info;
|
||||
|
||||
public:
|
||||
Type() = default;
|
||||
Type(const std::function<void(u32)>& setter, const char* info);
|
||||
Type(PrimitiveSetter setter, const char* info)
|
||||
: x0_setter(setter), x4_info(info) {}
|
||||
|
||||
const char* GetInfo() const;
|
||||
|
||||
std::function<void(u32)> GetSetter() const;
|
||||
const char* GetInfo() const { return x4_info; }
|
||||
PrimitiveSetter GetSetter() const { return x0_setter; }
|
||||
};
|
||||
|
||||
class Comparison
|
||||
|
@ -45,12 +72,12 @@ public:
|
|||
const char* x8_type2;
|
||||
|
||||
public:
|
||||
Comparison(const ComparisonFunc& collider, const char* type1, const char* type2)
|
||||
Comparison(ComparisonFunc collider, const char* type1, const char* type2)
|
||||
: x0_collider(collider), x4_type1(type1), x8_type2(type2)
|
||||
{
|
||||
}
|
||||
|
||||
const ComparisonFunc& GetCollider() const { return x0_collider; }
|
||||
ComparisonFunc GetCollider() const { return x0_collider; }
|
||||
const char* GetType1() const { return x4_type1; }
|
||||
const char* GetType2() const { return x8_type2; }
|
||||
};
|
||||
|
@ -62,12 +89,12 @@ public:
|
|||
const char* x8_type2;
|
||||
|
||||
public:
|
||||
MovingComparison(const MovingComparisonFunc& collider, const char* type1, const char* type2)
|
||||
MovingComparison(MovingComparisonFunc collider, const char* type1, const char* type2)
|
||||
: x0_collider(collider), x4_type1(type1), x8_type2(type2)
|
||||
{
|
||||
}
|
||||
|
||||
const MovingComparisonFunc& GetCollider() const { return x0_collider; }
|
||||
MovingComparisonFunc GetCollider() const { return x0_collider; }
|
||||
const char* GetType1() const { return x4_type1; }
|
||||
const char* GetType2() const { return x8_type2; }
|
||||
};
|
||||
|
@ -79,26 +106,33 @@ public:
|
|||
const char* x8_type2;
|
||||
|
||||
public:
|
||||
BooleanComparison(const BooleanComparisonFunc& collider, const char* type1, const char* type2)
|
||||
BooleanComparison(BooleanComparisonFunc collider, const char* type1, const char* type2)
|
||||
: x0_collider(collider), x4_type1(type1), x8_type2(type2)
|
||||
{
|
||||
}
|
||||
|
||||
const BooleanComparisonFunc& GetCollider() const { return x0_collider; }
|
||||
BooleanComparisonFunc GetCollider() const { return x0_collider; }
|
||||
const char* GetType1() const { return x4_type1; }
|
||||
const char* GetType2() const { return x8_type2; }
|
||||
};
|
||||
private:
|
||||
CMaterialList x8_material;
|
||||
static std::unique_ptr<std::vector<Type>> sCollisionTypeList;
|
||||
static std::unique_ptr<std::vector<ComparisonFunc>> sTableOfCollidables;
|
||||
static std::unique_ptr<std::vector<BooleanComparisonFunc>> sTableOfBooleanCollidables;
|
||||
static std::unique_ptr<std::vector<MovingComparisonFunc>> sTableOfMovingCollidables;
|
||||
static s32 sNumTypes;
|
||||
static bool sInitComplete;
|
||||
static bool sTypesAdded;
|
||||
static bool sTypesAdding;
|
||||
static bool sCollidersAdded;
|
||||
static bool sCollidersAdding;
|
||||
static std::unique_ptr<std::vector<Type>> sCollisionTypeList;
|
||||
static std::unique_ptr<std::vector<ComparisonFunc>> sTableOfCollidables;
|
||||
static std::unique_ptr<std::vector<BooleanComparisonFunc>> sTableOfBooleanCollidables;
|
||||
static std::unique_ptr<std::vector<MovingComparisonFunc>> sTableOfMovingCollidables;
|
||||
static ComparisonFunc sNullCollider;
|
||||
static BooleanComparisonFunc sNullBooleanCollider;
|
||||
static MovingComparisonFunc sNullMovingCollider;
|
||||
|
||||
static bool InternalCollide(const CInternalCollisionStructure& collision, CCollisionInfoList& list);
|
||||
static bool InternalCollideBoolean(const CInternalCollisionStructure& collision);
|
||||
|
||||
public:
|
||||
CCollisionPrimitive() = default;
|
||||
|
@ -114,20 +148,26 @@ public:
|
|||
CRayCastResult CastRay(const zeus::CVector3f& start, const zeus::CVector3f& dir, float length,
|
||||
const CMaterialFilter& filter, const zeus::CTransform& xf) const;
|
||||
|
||||
static bool Collide(CInternalCollisionStructure::CPrimDesc& prim0,
|
||||
CInternalCollisionStructure::CPrimDesc& prim1,
|
||||
CCollisionInfoList& list);
|
||||
static bool CollideBoolean(CInternalCollisionStructure::CPrimDesc& prim0,
|
||||
CInternalCollisionStructure::CPrimDesc& prim1);
|
||||
|
||||
static void InitBeginTypes();
|
||||
static void InitAddType(const Type& tp);
|
||||
static void InitEndTypes();
|
||||
|
||||
static void InitBeginColliders();
|
||||
static void InitAddBooleanCollider(const BooleanComparison& cmp);
|
||||
static void InitAddBooleanCollider(const BooleanComparisonFunc&, const char*, const char*);
|
||||
static void InitAddBooleanCollider(BooleanComparisonFunc, const char*, const char*);
|
||||
static void InitAddMovingCollider(const MovingComparison& cmp);
|
||||
static void InitAddMovingCollider(const MovingComparisonFunc&, const char*, const char*);
|
||||
static void InitAddMovingCollider(MovingComparisonFunc, const char*, const char*);
|
||||
static void InitAddCollider(const Comparison& cmp);
|
||||
static void InitAddCollider(const ComparisonFunc&, const char*, const char*);
|
||||
static void InitAddCollider(ComparisonFunc, const char*, const char*);
|
||||
static void InitEndColliders();
|
||||
|
||||
static void Unitialize();
|
||||
static void Uninitialize();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -6,15 +6,24 @@
|
|||
#include "CStateManager.hpp"
|
||||
#include "TCastTo.hpp"
|
||||
#include "World/CWorld.hpp"
|
||||
#include "CAABoxFilter.hpp"
|
||||
#include "CBallFilter.hpp"
|
||||
#include "CMetroidAreaCollider.hpp"
|
||||
#include "CollisionUtil.hpp"
|
||||
#include "World/CScriptPlatform.hpp"
|
||||
#include "CCollidableSphere.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
float CollisionImpulseFiniteVsInfinite(float f1, float f2, float f3) { return f1 * ((1.f / f3) * f2); }
|
||||
|
||||
float CollisionImpulseFiniteVsFinite(float f1, float f2, float f3, float f4)
|
||||
static float CollisionImpulseFiniteVsInfinite(float mass, float velNormDot, float restitution)
|
||||
{
|
||||
return (-(1.f + f4) * f3) / ((1.f / f1) + (1.f / f2));
|
||||
return mass * ((1.f / restitution) * velNormDot);
|
||||
}
|
||||
|
||||
static float CollisionImpulseFiniteVsFinite(float mass, float velNormDot, float restitution, float f4)
|
||||
{
|
||||
return (-(1.f + f4) * restitution) / ((1.f / mass) + (1.f / velNormDot));
|
||||
}
|
||||
|
||||
void CGameCollision::InitCollision()
|
||||
|
@ -47,9 +56,207 @@ void CGameCollision::InitCollision()
|
|||
CCollisionPrimitive::InitEndColliders();
|
||||
}
|
||||
|
||||
void CGameCollision::Move(CStateManager& mgr, CPhysicsActor& actor, float dt, const rstl::reserved_vector<TUniqueId, 1024>*)
|
||||
void CGameCollision::MovePlayer(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList)
|
||||
{
|
||||
actor.SetAngularEnabled(true);
|
||||
actor.AddMotionState(actor.PredictAngularMotion(dt));
|
||||
if (actor.IsUseStandardCollider())
|
||||
{
|
||||
MoveAndCollide(mgr, actor, dt, CBallFilter(actor), colliderList);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (actor.GetMaterialList().HasMaterial(EMaterialTypes::GroundCollider))
|
||||
MoveGroundCollider_New(mgr, actor, dt, colliderList);
|
||||
else
|
||||
MoveAndCollide(mgr, actor, dt, CBallFilter(actor), colliderList);
|
||||
}
|
||||
actor.SetAngularEnabled(false);
|
||||
}
|
||||
|
||||
void CGameCollision::MoveGroundCollider(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList)
|
||||
{
|
||||
CMotionState oldState = actor.GetMotionState();
|
||||
CMotionState newState = actor.PredictMotion_Internal(dt);
|
||||
newState.x0_translation.magnitude();
|
||||
actor.GetMaterialFilter();
|
||||
zeus::CAABox motionVol = actor.GetMotionVolume(dt);
|
||||
rstl::reserved_vector<TUniqueId, 1024> augmentedColliderList;
|
||||
if (colliderList)
|
||||
augmentedColliderList = *colliderList;
|
||||
mgr.BuildColliderList(augmentedColliderList, actor, motionVol);
|
||||
CAreaCollisionCache cache(motionVol);
|
||||
actor.GetCollisionPrimitive()->GetPrimType();
|
||||
// TODO: finish
|
||||
}
|
||||
|
||||
void CGameCollision::MoveGroundCollider_New(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList)
|
||||
{
|
||||
// TODO: finish
|
||||
}
|
||||
|
||||
void CGameCollision::MoveAndCollide(CStateManager& mgr, CPhysicsActor& actor, float dt, const ICollisionFilter& filter,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList)
|
||||
{
|
||||
bool isPlayer = actor.GetMaterialList().HasMaterial(EMaterialTypes::Player);
|
||||
bool r28 = false;
|
||||
bool r27 = false;
|
||||
int r26 = 0;
|
||||
float f31 = dt;
|
||||
float _4AC4 = dt;
|
||||
float _4AC8 = dt;
|
||||
CCollisionInfoList accumList;
|
||||
CMotionState mState = actor.PredictMotion_Internal(dt);
|
||||
float transMag = mState.x0_translation.magnitude();
|
||||
float m1 = 0.0005f / actor.GetCollisionAccuracyModifier();
|
||||
float m2 = transMag / (5.f * actor.GetCollisionAccuracyModifier());
|
||||
float mMax = std::max(m1, m2);
|
||||
float m3 = 0.001f / actor.GetCollisionAccuracyModifier();
|
||||
|
||||
zeus::CAABox motionVol = actor.GetMotionVolume(dt);
|
||||
rstl::reserved_vector<TUniqueId, 1024> useColliderList;
|
||||
if (colliderList)
|
||||
useColliderList = *colliderList;
|
||||
else
|
||||
mgr.BuildColliderList(useColliderList, actor, zeus::CAABox(motionVol.min - 1.f, motionVol.max + 1.f));
|
||||
CAreaCollisionCache cache(motionVol);
|
||||
if (actor.GetCollisionPrimitive()->GetPrimType() != FOURCC('OBTG') &&
|
||||
!actor.GetMaterialFilter().GetExcludeList().HasMaterial(EMaterialTypes::ThirtyEight))
|
||||
{
|
||||
BuildAreaCollisionCache(mgr, cache);
|
||||
zeus::CVector3f pos = actor.GetCollisionPrimitive()->CalculateAABox(actor.GetPrimitiveTransform()).center();
|
||||
float halfExtent = 0.5f * GetMinExtentForCollisionPrimitive(*actor.GetCollisionPrimitive());
|
||||
if (transMag > halfExtent)
|
||||
{
|
||||
TUniqueId id = kInvalidUniqueId;
|
||||
zeus::CVector3f dir = (1.f / transMag) * mState.x0_translation;
|
||||
CRayCastResult intersectRes = mgr.RayWorldIntersection(id, pos, dir, transMag,
|
||||
actor.GetMaterialFilter(), useColliderList);
|
||||
if (intersectRes.IsValid())
|
||||
{
|
||||
f31 = dt * (intersectRes.GetT() / transMag);
|
||||
mState = actor.PredictMotion_Internal(f31);
|
||||
_4AC8 = halfExtent * (dt / transMag);
|
||||
mMax = std::min(mMax, halfExtent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float f27 = f31;
|
||||
while (true)
|
||||
{
|
||||
actor.MoveCollisionPrimitive(mState.x0_translation);
|
||||
if (DetectCollisionBoolean_Cached(mgr, cache, *actor.GetCollisionPrimitive(),
|
||||
actor.GetPrimitiveTransform(), actor.GetMaterialFilter(),
|
||||
useColliderList))
|
||||
{
|
||||
r28 = true;
|
||||
if (mState.x0_translation.magnitude() < mMax)
|
||||
{
|
||||
r27 = true;
|
||||
accumList.Clear();
|
||||
TUniqueId id = kInvalidUniqueId;
|
||||
DetectCollision_Cached(mgr, cache, *actor.GetCollisionPrimitive(), actor.GetPrimitiveTransform(),
|
||||
actor.GetMaterialFilter(), useColliderList, id, accumList);
|
||||
TCastToPtr<CPhysicsActor> otherActor = mgr.ObjectById(id);
|
||||
actor.MoveCollisionPrimitive(zeus::CVector3f::skZero);
|
||||
zeus::CVector3f relVel = GetActorRelativeVelocities(actor, otherActor.GetPtr());
|
||||
CCollisionInfoList filterList0, filterList1;
|
||||
CollisionUtil::FilterOutBackfaces(relVel, accumList, filterList0);
|
||||
if (filterList0.GetCount() > 0)
|
||||
{
|
||||
filter.Filter(filterList0, filterList1);
|
||||
if (!filterList1.GetCount() && actor.GetMaterialList().HasMaterial(EMaterialTypes::Player))
|
||||
{
|
||||
CMotionState mState = actor.GetLastNonCollidingState();
|
||||
mState.x1c_velocity *= 0.5f;
|
||||
mState.x28_angularMomentum *= 0.5f;
|
||||
actor.SetMotionState(mState);
|
||||
}
|
||||
}
|
||||
MakeCollisionCallbacks(mgr, actor, id, filterList1);
|
||||
SendScriptMessages(mgr, actor, otherActor.GetPtr(), filterList1);
|
||||
ResolveCollisions(actor, otherActor.GetPtr(), filterList1);
|
||||
_4AC4 -= f31;
|
||||
f27 = std::min(_4AC4, _4AC8);
|
||||
f31 = f27;
|
||||
}
|
||||
else
|
||||
{
|
||||
f27 *= 0.5f;
|
||||
f31 *= 0.5f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.AddMotionState(mState);
|
||||
_4AC4 -= f31;
|
||||
f31 = f27;
|
||||
actor.ClearImpulses();
|
||||
actor.MoveCollisionPrimitive(zeus::CVector3f::skZero);
|
||||
}
|
||||
|
||||
++r26;
|
||||
if (_4AC4 > 0.f && ((mState.x0_translation.magnitude() > m3 && r27) || !r27) && r26 <= 1000)
|
||||
mState = actor.PredictMotion_Internal(f31);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
f27 = _4AC4 / dt;
|
||||
if (!r28 && !actor.GetMaterialList().HasMaterial(EMaterialTypes::GroundCollider))
|
||||
mgr.SendScriptMsg(&actor, kInvalidUniqueId, EScriptObjectMessage::Falling);
|
||||
|
||||
if (isPlayer)
|
||||
CollisionFailsafe(mgr, cache, actor, *actor.GetCollisionPrimitive(), useColliderList, f27, 2);
|
||||
|
||||
actor.ClearForcesAndTorques();
|
||||
actor.MoveCollisionPrimitive(zeus::CVector3f::skZero);
|
||||
}
|
||||
|
||||
zeus::CVector3f CGameCollision::GetActorRelativeVelocities(const CPhysicsActor& act0, const CPhysicsActor* act1)
|
||||
{
|
||||
zeus::CVector3f ret = act0.GetVelocity();
|
||||
if (act1)
|
||||
{
|
||||
bool rider = false;
|
||||
if (TCastToConstPtr<CScriptPlatform> plat = act1)
|
||||
rider = plat->IsRider(act0.GetUniqueId());
|
||||
if (!rider)
|
||||
ret =- act1->GetVelocity();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CGameCollision::Move(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList)
|
||||
{
|
||||
if (!actor.IsMovable())
|
||||
return;
|
||||
if (actor.GetMaterialList().HasMaterial(EMaterialTypes::GroundCollider) || actor.WillMove(mgr))
|
||||
{
|
||||
if (actor.IsAngularEnabled())
|
||||
actor.AddMotionState(actor.PredictAngularMotion(dt));
|
||||
actor.UseCollisionImpulses();
|
||||
if (actor.GetMaterialList().HasMaterial(EMaterialTypes::Solid))
|
||||
{
|
||||
if (actor.GetMaterialList().HasMaterial(EMaterialTypes::Player))
|
||||
MovePlayer(mgr, actor, dt, colliderList);
|
||||
else if (actor.GetMaterialList().HasMaterial(EMaterialTypes::GroundCollider))
|
||||
MoveGroundCollider(mgr, actor, dt, colliderList);
|
||||
else
|
||||
MoveAndCollide(mgr, actor, dt, CAABoxFilter(actor), colliderList);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.AddMotionState(actor.PredictMotion_Internal(dt));
|
||||
actor.ClearForcesAndTorques();
|
||||
}
|
||||
mgr.UpdateActorInSortedLists(actor);
|
||||
}
|
||||
}
|
||||
|
||||
bool CGameCollision::CanBlock(const CMaterialList& mat, const zeus::CVector3f& v)
|
||||
|
@ -213,4 +420,417 @@ bool CGameCollision::RayStaticIntersectionArea(const CGameArea& area, const zeus
|
|||
zeus::CLine line(pos, dir);
|
||||
return node.LineTest(line, filter, mag);
|
||||
}
|
||||
|
||||
void CGameCollision::BuildAreaCollisionCache(CStateManager& mgr, CAreaCollisionCache& cache)
|
||||
{
|
||||
cache.ClearCache();
|
||||
for (const CGameArea& area : *mgr.GetWorld())
|
||||
{
|
||||
const CAreaOctTree& areaCollision = *area.GetPostConstructed()->x0_collision;
|
||||
CMetroidAreaCollider::COctreeLeafCache octreeCache(areaCollision);
|
||||
CMetroidAreaCollider::BuildOctreeLeafCache(areaCollision.GetRootNode(),
|
||||
cache.GetCacheBounds(), octreeCache);
|
||||
cache.AddOctreeLeafCache(octreeCache);
|
||||
}
|
||||
}
|
||||
|
||||
float CGameCollision::GetMinExtentForCollisionPrimitive(const CCollisionPrimitive& prim)
|
||||
{
|
||||
if (prim.GetPrimType() == FOURCC('SPHR'))
|
||||
{
|
||||
const CCollidableSphere& sphere = static_cast<const CCollidableSphere&>(prim);
|
||||
return 2.f * sphere.GetSphere().radius;
|
||||
}
|
||||
else if (prim.GetPrimType() == FOURCC('AABX'))
|
||||
{
|
||||
const CCollidableAABox& aabx = static_cast<const CCollidableAABox&>(prim);
|
||||
zeus::CVector3f extent = aabx.GetAABB().max - aabx.GetAABB().min;
|
||||
float minExtent = std::min(extent.x, extent.y);
|
||||
minExtent = std::min(minExtent, extent.z);
|
||||
return minExtent;
|
||||
}
|
||||
else if (prim.GetPrimType() == FOURCC('ABSH'))
|
||||
{
|
||||
// Combination AABB / Sphere cut from game
|
||||
}
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
bool CGameCollision::DetectCollisionBoolean_Cached(CStateManager& mgr, CAreaCollisionCache& cache,
|
||||
const CCollisionPrimitive& prim, const zeus::CTransform& xf,
|
||||
const CMaterialFilter& filter,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList)
|
||||
{
|
||||
if (!filter.GetExcludeList().HasMaterial(EMaterialTypes::ThirtyEight) &&
|
||||
DetectStaticCollisionBoolean_Cached(mgr, cache, prim, xf, filter))
|
||||
return true;
|
||||
if (DetectDynamicCollisionBoolean(prim, xf, nearList, mgr))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGameCollision::DetectStaticCollisionBoolean(CStateManager& mgr, const CCollisionPrimitive& prim,
|
||||
const zeus::CTransform& xf, const CMaterialFilter& filter)
|
||||
{
|
||||
if (prim.GetPrimType() == FOURCC('OBTG'))
|
||||
return false;
|
||||
|
||||
if (prim.GetPrimType() == FOURCC('AABX'))
|
||||
{
|
||||
zeus::CAABox aabb = prim.CalculateAABox(xf);
|
||||
for (const CGameArea& area : *mgr.GetWorld())
|
||||
{
|
||||
if (CMetroidAreaCollider::AABoxCollisionCheckBoolean(
|
||||
*area.GetPostConstructed()->x0_collision, aabb, filter))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (prim.GetPrimType() == FOURCC('SPHR'))
|
||||
{
|
||||
const CCollidableSphere& sphere = static_cast<const CCollidableSphere&>(prim);
|
||||
zeus::CAABox aabb = prim.CalculateAABox(xf);
|
||||
zeus::CSphere xfSphere = sphere.Transform(xf);
|
||||
for (const CGameArea& area : *mgr.GetWorld())
|
||||
{
|
||||
if (CMetroidAreaCollider::SphereCollisionCheckBoolean(
|
||||
*area.GetPostConstructed()->x0_collision, aabb, xfSphere, filter))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (prim.GetPrimType() == FOURCC('ABSH'))
|
||||
{
|
||||
// Combination AABB / Sphere cut from game
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGameCollision::DetectStaticCollisionBoolean_Cached(CStateManager& mgr, CAreaCollisionCache& cache,
|
||||
const CCollisionPrimitive& prim, const zeus::CTransform& xf,
|
||||
const CMaterialFilter& filter)
|
||||
{
|
||||
if (prim.GetPrimType() == FOURCC('OBTG'))
|
||||
return false;
|
||||
|
||||
zeus::CAABox aabb = prim.CalculateAABox(xf);
|
||||
if (!aabb.inside(cache.GetCacheBounds()))
|
||||
{
|
||||
zeus::CAABox newAABB(aabb.min - 0.2f, aabb.max + 0.2f);
|
||||
newAABB.accumulateBounds(cache.GetCacheBounds());
|
||||
cache.SetCacheBounds(newAABB);
|
||||
BuildAreaCollisionCache(mgr, cache);
|
||||
}
|
||||
|
||||
if (cache.HasCacheOverflowed())
|
||||
return DetectStaticCollisionBoolean(mgr, prim, xf, filter);
|
||||
|
||||
if (prim.GetPrimType() == FOURCC('AABX'))
|
||||
{
|
||||
for (CMetroidAreaCollider::COctreeLeafCache& leafCache : cache)
|
||||
if (CMetroidAreaCollider::AABoxCollisionCheckBoolean_Cached(leafCache, aabb, filter))
|
||||
return true;
|
||||
}
|
||||
else if (prim.GetPrimType() == FOURCC('SPHR'))
|
||||
{
|
||||
const CCollidableSphere& sphere = static_cast<const CCollidableSphere&>(prim);
|
||||
zeus::CSphere xfSphere = sphere.Transform(xf);
|
||||
for (CMetroidAreaCollider::COctreeLeafCache& leafCache : cache)
|
||||
if (CMetroidAreaCollider::SphereCollisionCheckBoolean_Cached(leafCache, aabb, xfSphere, filter))
|
||||
return true;
|
||||
}
|
||||
else if (prim.GetPrimType() == FOURCC('ABSH'))
|
||||
{
|
||||
// Combination AABB / Sphere cut from game
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGameCollision::DetectDynamicCollisionBoolean(const CCollisionPrimitive& prim, const zeus::CTransform& xf,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
CStateManager& mgr)
|
||||
{
|
||||
for (TUniqueId id : nearList)
|
||||
{
|
||||
if (TCastToPtr<CPhysicsActor> actor = mgr.ObjectById(id))
|
||||
{
|
||||
CInternalCollisionStructure::CPrimDesc p0(prim, CMaterialFilter::skPassEverything, xf);
|
||||
CInternalCollisionStructure::CPrimDesc p1(*actor->GetCollisionPrimitive(),
|
||||
CMaterialFilter::skPassEverything,
|
||||
actor->GetPrimitiveTransform());
|
||||
if (CCollisionPrimitive::CollideBoolean(p0, p1))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGameCollision::DetectCollision_Cached(CStateManager& mgr, CAreaCollisionCache& cache,
|
||||
const CCollisionPrimitive& prim, const zeus::CTransform& xf,
|
||||
const CMaterialFilter& filter,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
TUniqueId& idOut, CCollisionInfoList& infoList)
|
||||
{
|
||||
bool ret = false;
|
||||
if (!filter.GetExcludeList().HasMaterial(EMaterialTypes::ThirtyEight))
|
||||
if (DetectStaticCollision_Cached(mgr, cache, prim, xf, filter, infoList))
|
||||
ret = true;
|
||||
|
||||
TUniqueId id = kInvalidUniqueId;
|
||||
if (DetectDynamicCollision(prim, xf, nearList, id, infoList, mgr))
|
||||
{
|
||||
ret = true;
|
||||
idOut = id;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CGameCollision::DetectStaticCollision(CStateManager& mgr, const CCollisionPrimitive& prim,
|
||||
const zeus::CTransform& xf, const CMaterialFilter& filter,
|
||||
CCollisionInfoList& list)
|
||||
{
|
||||
if (prim.GetPrimType() == FOURCC('OBTG'))
|
||||
return false;
|
||||
|
||||
if (prim.GetPrimType() == FOURCC('AABX'))
|
||||
{
|
||||
zeus::CAABox aabb = prim.CalculateAABox(xf);
|
||||
for (const CGameArea& area : *mgr.GetWorld())
|
||||
{
|
||||
if (CMetroidAreaCollider::AABoxCollisionCheck(
|
||||
*area.GetPostConstructed()->x0_collision, aabb, filter,
|
||||
prim.GetMaterial(), list))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (prim.GetPrimType() == FOURCC('SPHR'))
|
||||
{
|
||||
const CCollidableSphere& sphere = static_cast<const CCollidableSphere&>(prim);
|
||||
zeus::CAABox aabb = prim.CalculateAABox(xf);
|
||||
zeus::CSphere xfSphere = sphere.Transform(xf);
|
||||
for (const CGameArea& area : *mgr.GetWorld())
|
||||
{
|
||||
if (CMetroidAreaCollider::SphereCollisionCheck(
|
||||
*area.GetPostConstructed()->x0_collision, aabb, xfSphere,
|
||||
prim.GetMaterial(), filter, list))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (prim.GetPrimType() == FOURCC('ABSH'))
|
||||
{
|
||||
// Combination AABB / Sphere cut from game
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGameCollision::DetectStaticCollision_Cached(CStateManager& mgr, CAreaCollisionCache& cache,
|
||||
const CCollisionPrimitive& prim, const zeus::CTransform& xf,
|
||||
const CMaterialFilter& filter, CCollisionInfoList& list)
|
||||
{
|
||||
if (prim.GetPrimType() == FOURCC('OBTG'))
|
||||
return false;
|
||||
|
||||
zeus::CAABox calcAABB = prim.CalculateAABox(xf);
|
||||
if (!calcAABB.inside(cache.GetCacheBounds()))
|
||||
{
|
||||
zeus::CAABox newAABB(calcAABB.min - 0.2f, calcAABB.max + 0.2f);
|
||||
newAABB.accumulateBounds(cache.GetCacheBounds());
|
||||
cache.SetCacheBounds(newAABB);
|
||||
BuildAreaCollisionCache(mgr, cache);
|
||||
}
|
||||
|
||||
if (cache.HasCacheOverflowed())
|
||||
return DetectStaticCollision(mgr, prim, xf, filter, list);
|
||||
|
||||
if (prim.GetPrimType() == FOURCC('AABX'))
|
||||
{
|
||||
for (CMetroidAreaCollider::COctreeLeafCache& leafCache : cache)
|
||||
if (CMetroidAreaCollider::AABoxCollisionCheck_Cached(leafCache, calcAABB, filter,
|
||||
prim.GetMaterial(), list))
|
||||
return true;
|
||||
}
|
||||
else if (prim.GetPrimType() == FOURCC('SPHR'))
|
||||
{
|
||||
const CCollidableSphere& sphere = static_cast<const CCollidableSphere&>(prim);
|
||||
zeus::CSphere xfSphere = sphere.Transform(xf);
|
||||
for (CMetroidAreaCollider::COctreeLeafCache& leafCache : cache)
|
||||
if (CMetroidAreaCollider::SphereCollisionCheck_Cached(leafCache, calcAABB, xfSphere,
|
||||
prim.GetMaterial(), filter, list))
|
||||
return true;
|
||||
}
|
||||
else if (prim.GetPrimType() == FOURCC('ABSH'))
|
||||
{
|
||||
// Combination AABB / Sphere cut from game
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGameCollision::DetectDynamicCollision(const CCollisionPrimitive& prim, const zeus::CTransform& xf,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
TUniqueId& idOut, CCollisionInfoList& list, CStateManager& mgr)
|
||||
{
|
||||
for (TUniqueId id : nearList)
|
||||
{
|
||||
if (TCastToPtr<CPhysicsActor> actor = mgr.ObjectById(id))
|
||||
{
|
||||
CInternalCollisionStructure::CPrimDesc p0(prim, CMaterialFilter::skPassEverything, xf);
|
||||
CInternalCollisionStructure::CPrimDesc p1(*actor->GetCollisionPrimitive(),
|
||||
CMaterialFilter::skPassEverything,
|
||||
actor->GetPrimitiveTransform());
|
||||
if (CCollisionPrimitive::Collide(p0, p1, list))
|
||||
{
|
||||
idOut = actor->GetUniqueId();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CGameCollision::MakeCollisionCallbacks(CStateManager& mgr, CPhysicsActor& actor,
|
||||
TUniqueId id, const CCollisionInfoList& list)
|
||||
{
|
||||
actor.CollidedWith(id, list, mgr);
|
||||
if (id != kInvalidUniqueId)
|
||||
{
|
||||
if (TCastToPtr<CPhysicsActor> actor = mgr.ObjectById(id))
|
||||
{
|
||||
CCollisionInfoList swappedList = list;
|
||||
for (CCollisionInfo& info : swappedList)
|
||||
info.Swap();
|
||||
actor->CollidedWith(actor->GetUniqueId(), list, mgr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameCollision::SendScriptMessages(CStateManager& mgr, CActor& a0, CActor* a1, const CCollisionInfoList& list)
|
||||
{
|
||||
bool onFloor = false;
|
||||
bool platform = false;
|
||||
bool platform2 = false;
|
||||
for (const CCollisionInfo& info : list)
|
||||
{
|
||||
if (IsFloor(info.GetMaterialLeft(), info.GetNormalLeft()))
|
||||
{
|
||||
onFloor = true;
|
||||
if (info.GetMaterialLeft().HasMaterial(EMaterialTypes::Platform))
|
||||
platform = true;
|
||||
SendMaterialMessage(mgr, info.GetMaterialLeft(), a0);
|
||||
}
|
||||
}
|
||||
|
||||
if (onFloor)
|
||||
{
|
||||
mgr.SendScriptMsg(&a0, kInvalidUniqueId, EScriptObjectMessage::OnFloor);
|
||||
if (platform)
|
||||
{
|
||||
if (TCastToPtr<CScriptPlatform> plat = a1)
|
||||
{
|
||||
mgr.SendScriptMsg(plat.GetPtr(), a0.GetUniqueId(),
|
||||
EScriptObjectMessage::AddPlatformRider);
|
||||
}
|
||||
}
|
||||
else if (a1)
|
||||
{
|
||||
if (TCastToPtr<CScriptPlatform> plat = a0)
|
||||
{
|
||||
for (const CCollisionInfo& info : list)
|
||||
{
|
||||
if (IsFloor(info.GetMaterialRight(), info.GetNormalRight()))
|
||||
{
|
||||
if (info.GetMaterialRight().HasMaterial(EMaterialTypes::Platform))
|
||||
platform2 = true;
|
||||
SendMaterialMessage(mgr, info.GetMaterialLeft(), a0);
|
||||
}
|
||||
}
|
||||
if (platform2)
|
||||
{
|
||||
mgr.SendScriptMsg(plat.GetPtr(), a1->GetUniqueId(),
|
||||
EScriptObjectMessage::AddPlatformRider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameCollision::ResolveCollisions(CPhysicsActor& a0, CPhysicsActor* a1, const CCollisionInfoList& list)
|
||||
{
|
||||
for (const CCollisionInfo& info : list)
|
||||
{
|
||||
CCollisionInfo infoCopy = info;
|
||||
float restitution = GetCoefficientOfRestitution(infoCopy) + a0.GetCoefficientOfRestitutionModifier();
|
||||
if (a1)
|
||||
{
|
||||
CollideWithDynamicBodyNoRot(a0, *a1, infoCopy, restitution, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
CollideWithStaticBodyNoRot(a0, infoCopy.GetMaterialLeft(), infoCopy.GetMaterialRight(),
|
||||
infoCopy.GetNormalLeft(), restitution, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameCollision::CollideWithDynamicBodyNoRot(CPhysicsActor& a0, CPhysicsActor& a1,
|
||||
const CCollisionInfo& info, float restitution, bool)
|
||||
{
|
||||
/* TODO: Finish */
|
||||
}
|
||||
|
||||
void CGameCollision::CollideWithStaticBodyNoRot(CPhysicsActor& a0, const CMaterialList& m0, const CMaterialList& m1,
|
||||
const zeus::CUnitVector3f& normal, float restitution, bool b)
|
||||
{
|
||||
zeus::CUnitVector3f useNorm = normal;
|
||||
if (b && m0.HasMaterial(EMaterialTypes::Player) && !m1.HasMaterial(EMaterialTypes::Floor))
|
||||
useNorm.z = 0.f;
|
||||
|
||||
if (useNorm.canBeNormalized())
|
||||
{
|
||||
useNorm.normalize();
|
||||
float velNormDot = a0.GetVelocity().dot(useNorm);
|
||||
if (velNormDot < 0.0001f)
|
||||
{
|
||||
a0.ApplyImpulseWR(
|
||||
useNorm * CollisionImpulseFiniteVsInfinite(a0.GetMass(), velNormDot, restitution),
|
||||
zeus::CAxisAngle::sIdentity);
|
||||
a0.UseCollisionImpulses();
|
||||
}
|
||||
else if (velNormDot < 0.001f)
|
||||
{
|
||||
a0.ApplyImpulseWR(0.05f * a0.GetMass() * useNorm, zeus::CAxisAngle::sIdentity);
|
||||
a0.UseCollisionImpulses();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameCollision::CollisionFailsafe(CStateManager& mgr, CAreaCollisionCache& cache,
|
||||
CPhysicsActor& actor, const CCollisionPrimitive& prim,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
float f1, u32 failsafeTicks)
|
||||
{
|
||||
actor.MoveCollisionPrimitive(zeus::CVector3f::skZero);
|
||||
if (f1 > 0.5f)
|
||||
actor.SetNumTicksPartialUpdate(actor.GetNumTicksPartialUpdate() + 1);
|
||||
|
||||
if (actor.GetNumTicksPartialUpdate() > 1 ||
|
||||
DetectCollisionBoolean_Cached(mgr, cache, prim, actor.GetPrimitiveTransform(),
|
||||
actor.GetMaterialFilter(), nearList))
|
||||
{
|
||||
actor.SetNumTicksPartialUpdate(0);
|
||||
actor.SetNumTicksStuck(actor.GetNumTicksStuck() + 1);
|
||||
if (actor.GetNumTicksStuck() < failsafeTicks)
|
||||
return;
|
||||
/* TODO: Finish */
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.SetLastNonCollidingState(actor.GetMotionState());
|
||||
actor.SetNumTicksStuck(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,14 +5,12 @@
|
|||
#include "rstl.hpp"
|
||||
#include "RetroTypes.hpp"
|
||||
#include "CRayCastResult.hpp"
|
||||
#include "CMetroidAreaCollider.hpp"
|
||||
#include "CCollisionPrimitive.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
class CInternalCollisionStructure
|
||||
{
|
||||
};
|
||||
|
||||
class CActor;
|
||||
class CCollisionInfo;
|
||||
class CCollisionInfoList;
|
||||
|
@ -21,10 +19,21 @@ class CStateManager;
|
|||
class CPhysicsActor;
|
||||
class CMaterialFilter;
|
||||
class CGameArea;
|
||||
class ICollisionFilter;
|
||||
|
||||
class CGameCollision
|
||||
{
|
||||
static void MovePlayer(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList);
|
||||
static void MoveGroundCollider(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList);
|
||||
static void MoveGroundCollider_New(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList);
|
||||
static void MoveAndCollide(CStateManager& mgr, CPhysicsActor& actor, float dt, const ICollisionFilter& filter,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList);
|
||||
static zeus::CVector3f GetActorRelativeVelocities(const CPhysicsActor& act0, const CPhysicsActor* act1);
|
||||
public:
|
||||
static float GetCoefficientOfRestitution(const CCollisionInfo&) { return 0.f; }
|
||||
static bool NullMovingCollider(const CInternalCollisionStructure&, const zeus::CVector3f&, double&, CCollisionInfo&)
|
||||
{
|
||||
return false;
|
||||
|
@ -32,11 +41,12 @@ public:
|
|||
static bool NullBooleanCollider(const CInternalCollisionStructure&) { return false; }
|
||||
static bool NullCollisionCollider(const CInternalCollisionStructure&, CCollisionInfoList&) { return false; }
|
||||
static void InitCollision();
|
||||
static void Move(CStateManager& mgr, CPhysicsActor& actor, float dt, const rstl::reserved_vector<TUniqueId, 1024>*);
|
||||
static void Move(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList);
|
||||
|
||||
static bool CanBlock(const CMaterialList&, const zeus::CVector3f&);
|
||||
static bool IsFloor(const CMaterialList&, const zeus::CVector3f&);
|
||||
void SendMaterialMessage(CStateManager&, const CMaterialList&, CActor&);
|
||||
static void SendMaterialMessage(CStateManager&, const CMaterialList&, CActor&);
|
||||
static CRayCastResult RayStaticIntersection(const CStateManager& mgr, const zeus::CVector3f& pos,
|
||||
const zeus::CVector3f& dir, float mag, const CMaterialFilter& filter);
|
||||
static bool RayStaticIntersectionBool(const CStateManager& mgr, const zeus::CVector3f& start,
|
||||
|
@ -55,6 +65,46 @@ public:
|
|||
const rstl::reserved_vector<TUniqueId, 1024>& nearList);
|
||||
static bool RayStaticIntersectionArea(const CGameArea& area, const zeus::CVector3f& pos,
|
||||
const zeus::CVector3f& dir, float mag, const CMaterialFilter& filter);
|
||||
static void BuildAreaCollisionCache(CStateManager& mgr, CAreaCollisionCache& cache);
|
||||
static float GetMinExtentForCollisionPrimitive(const CCollisionPrimitive& prim);
|
||||
static bool DetectCollisionBoolean_Cached(CStateManager& mgr, CAreaCollisionCache& cache,
|
||||
const CCollisionPrimitive& prim, const zeus::CTransform& xf,
|
||||
const CMaterialFilter& filter,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList);
|
||||
static bool DetectStaticCollisionBoolean(CStateManager& mgr, const CCollisionPrimitive& prim,
|
||||
const zeus::CTransform& xf, const CMaterialFilter& filter);
|
||||
static bool DetectStaticCollisionBoolean_Cached(CStateManager& mgr, CAreaCollisionCache& cache,
|
||||
const CCollisionPrimitive& prim, const zeus::CTransform& xf,
|
||||
const CMaterialFilter& filter);
|
||||
static bool DetectDynamicCollisionBoolean(const CCollisionPrimitive& prim, const zeus::CTransform& xf,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
CStateManager& mgr);
|
||||
static bool DetectCollision_Cached(CStateManager& mgr, CAreaCollisionCache& cache,
|
||||
const CCollisionPrimitive& prim, const zeus::CTransform& xf,
|
||||
const CMaterialFilter& filter,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
TUniqueId& idOut, CCollisionInfoList& infoList);
|
||||
static bool DetectStaticCollision(CStateManager& mgr, const CCollisionPrimitive& prim,
|
||||
const zeus::CTransform& xf, const CMaterialFilter& filter,
|
||||
CCollisionInfoList& list);
|
||||
static bool DetectStaticCollision_Cached(CStateManager& mgr, CAreaCollisionCache& cache,
|
||||
const CCollisionPrimitive& prim, const zeus::CTransform& xf,
|
||||
const CMaterialFilter& filter, CCollisionInfoList& list);
|
||||
static bool DetectDynamicCollision(const CCollisionPrimitive& prim, const zeus::CTransform& xf,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
TUniqueId& idOut, CCollisionInfoList& list, CStateManager& mgr);
|
||||
static void MakeCollisionCallbacks(CStateManager& mgr, CPhysicsActor& actor, TUniqueId id,
|
||||
const CCollisionInfoList& list);
|
||||
static void SendScriptMessages(CStateManager& mgr, CActor& a0, CActor* a1, const CCollisionInfoList& list);
|
||||
static void ResolveCollisions(CPhysicsActor& a0, CPhysicsActor* a1, const CCollisionInfoList& list);
|
||||
static void CollideWithDynamicBodyNoRot(CPhysicsActor& a0, CPhysicsActor& a1, const CCollisionInfo& info,
|
||||
float restitution, bool);
|
||||
static void CollideWithStaticBodyNoRot(CPhysicsActor& a0, const CMaterialList& m0, const CMaterialList& m1,
|
||||
const zeus::CUnitVector3f& normal, float restitution, bool);
|
||||
static void CollisionFailsafe(CStateManager& mgr, CAreaCollisionCache& cache,
|
||||
CPhysicsActor& actor, const CCollisionPrimitive& prim,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
float, u32 failsafeTicks);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,9 @@ set(COLLISION_SOURCES
|
|||
CRayCastResult.hpp CRayCastResult.cpp
|
||||
CCollisionActor.hpp CCollisionActor.cpp
|
||||
CCollisionActorManager.hpp CCollisionActorManager.cpp
|
||||
CJointCollisionDescription.hpp CJointCollisionDescription.cpp)
|
||||
CJointCollisionDescription.hpp CJointCollisionDescription.cpp
|
||||
CAABoxFilter.hpp CAABoxFilter.cpp
|
||||
CBallFilter.hpp CBallFilter.cpp
|
||||
ICollisionFilter.hpp)
|
||||
|
||||
runtime_add_list(Collision COLLISION_SOURCES)
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
#include "CMetroidAreaCollider.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
CMetroidAreaCollider::COctreeLeafCache::COctreeLeafCache(const CAreaOctTree& octTree)
|
||||
: x0_octTree(octTree)
|
||||
{
|
||||
x908_24_overflow = false;
|
||||
}
|
||||
|
||||
void CMetroidAreaCollider::COctreeLeafCache::AddLeaf(const CAreaOctTree::Node& node)
|
||||
{
|
||||
if (x4_nodeCache.size() == 64)
|
||||
{
|
||||
x908_24_overflow = true;
|
||||
return;
|
||||
}
|
||||
|
||||
x4_nodeCache.push_back(node);
|
||||
}
|
||||
|
||||
void CMetroidAreaCollider::BuildOctreeLeafCache(const CAreaOctTree::Node& node, const zeus::CAABox& aabb,
|
||||
CMetroidAreaCollider::COctreeLeafCache& cache)
|
||||
{
|
||||
for (int i=0 ; i<8 ; ++i)
|
||||
{
|
||||
u16 flags = (node.GetChildFlags() >> (i * 2)) & 0x3;
|
||||
if (flags)
|
||||
{
|
||||
CAreaOctTree::Node ch = node.GetChild(i);
|
||||
if (aabb.intersects(ch.GetBoundingBox()))
|
||||
{
|
||||
if (flags == 0x2)
|
||||
cache.AddLeaf(ch);
|
||||
else
|
||||
BuildOctreeLeafCache(ch, aabb, cache);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CMetroidAreaCollider::AABoxCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
||||
const CMaterialFilter& filter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMetroidAreaCollider::AABoxCollisionCheckBoolean(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
||||
const CMaterialFilter& filter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMetroidAreaCollider::SphereCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
||||
const zeus::CSphere& sphere, const CMaterialFilter& filter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMetroidAreaCollider::SphereCollisionCheckBoolean(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
||||
const zeus::CSphere& sphere, const CMaterialFilter& filter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMetroidAreaCollider::AABoxCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
||||
const CMaterialFilter& filter, const CMaterialList& matList,
|
||||
CCollisionInfoList& list)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMetroidAreaCollider::AABoxCollisionCheck(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
||||
const CMaterialFilter& filter, const CMaterialList& matList,
|
||||
CCollisionInfoList& list)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMetroidAreaCollider::SphereCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
||||
const zeus::CSphere& sphere, const CMaterialList& matList,
|
||||
const CMaterialFilter& filter, CCollisionInfoList& list)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMetroidAreaCollider::SphereCollisionCheck(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
||||
const zeus::CSphere& sphere, const CMaterialList& matList,
|
||||
const CMaterialFilter& filter, CCollisionInfoList& list)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void CAreaCollisionCache::ClearCache()
|
||||
{
|
||||
x18_leafCaches.clear();
|
||||
x1b40_24_leafOverflow = false;
|
||||
x1b40_25_cacheOverflow = false;
|
||||
}
|
||||
|
||||
void CAreaCollisionCache::AddOctreeLeafCache(const CMetroidAreaCollider::COctreeLeafCache& leafCache)
|
||||
{
|
||||
if (!leafCache.GetNumLeaves())
|
||||
return;
|
||||
|
||||
if (leafCache.HasCacheOverflowed())
|
||||
x1b40_24_leafOverflow = true;
|
||||
|
||||
if (x18_leafCaches.size() < 3)
|
||||
{
|
||||
x18_leafCaches.push_back(leafCache);
|
||||
}
|
||||
else
|
||||
{
|
||||
x1b40_24_leafOverflow = true;
|
||||
x1b40_25_cacheOverflow = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,13 +1,78 @@
|
|||
#ifndef __URDE_CMETROIDAREACOLLIDER_HPP__
|
||||
#define __URDE_CMETROIDAREACOLLIDER_HPP__
|
||||
|
||||
#include "RetroTypes.hpp"
|
||||
#include "zeus/CAABox.hpp"
|
||||
#include "CAreaOctTree.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CCollisionInfoList;
|
||||
class CMaterialList;
|
||||
|
||||
class CMetroidAreaCollider
|
||||
{
|
||||
public:
|
||||
CMetroidAreaCollider();
|
||||
class COctreeLeafCache
|
||||
{
|
||||
const CAreaOctTree& x0_octTree;
|
||||
rstl::reserved_vector<CAreaOctTree::Node, 64> x4_nodeCache;
|
||||
bool x908_24_overflow : 1;
|
||||
public:
|
||||
COctreeLeafCache(const CAreaOctTree& octTree);
|
||||
void AddLeaf(const CAreaOctTree::Node& node);
|
||||
u32 GetNumLeaves() const { return x4_nodeCache.size(); }
|
||||
bool HasCacheOverflowed() const { return x908_24_overflow; }
|
||||
};
|
||||
static void BuildOctreeLeafCache(const CAreaOctTree::Node& root, const zeus::CAABox& aabb,
|
||||
CMetroidAreaCollider::COctreeLeafCache& cache);
|
||||
static bool AABoxCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
||||
const CMaterialFilter& filter);
|
||||
static bool AABoxCollisionCheckBoolean(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
||||
const CMaterialFilter& filter);
|
||||
static bool SphereCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
||||
const zeus::CSphere& sphere, const CMaterialFilter& filter);
|
||||
static bool SphereCollisionCheckBoolean(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
||||
const zeus::CSphere& sphere, const CMaterialFilter& filter);
|
||||
|
||||
static bool AABoxCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
||||
const CMaterialFilter& filter, const CMaterialList& matList,
|
||||
CCollisionInfoList& list);
|
||||
static bool AABoxCollisionCheck(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
||||
const CMaterialFilter& filter, const CMaterialList& matList,
|
||||
CCollisionInfoList& list);
|
||||
static bool SphereCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
||||
const zeus::CSphere& sphere, const CMaterialList& matList,
|
||||
const CMaterialFilter& filter, CCollisionInfoList& list);
|
||||
static bool SphereCollisionCheck(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
||||
const zeus::CSphere& sphere, const CMaterialList& matList,
|
||||
const CMaterialFilter& filter, CCollisionInfoList& list);
|
||||
};
|
||||
|
||||
class CAreaCollisionCache
|
||||
{
|
||||
zeus::CAABox x0_aabb;
|
||||
rstl::reserved_vector<CMetroidAreaCollider::COctreeLeafCache, 3> x18_leafCaches;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
bool x1b40_24_leafOverflow : 1;
|
||||
bool x1b40_25_cacheOverflow : 1;
|
||||
};
|
||||
u32 _dummy = 0;
|
||||
};
|
||||
public:
|
||||
CAreaCollisionCache(const zeus::CAABox& aabb) : x0_aabb(aabb) {}
|
||||
void ClearCache();
|
||||
const zeus::CAABox& GetCacheBounds() const { return x0_aabb; }
|
||||
void SetCacheBounds(const zeus::CAABox& aabb) { x0_aabb = aabb; }
|
||||
void AddOctreeLeafCache(const CMetroidAreaCollider::COctreeLeafCache& leafCache);
|
||||
u32 GetNumCaches() const { return x18_leafCaches.size(); }
|
||||
const CMetroidAreaCollider::COctreeLeafCache& GetOctreeLeafCache(int idx) { return x18_leafCaches[idx]; }
|
||||
bool HasCacheOverflowed() const { return x1b40_24_leafOverflow; }
|
||||
rstl::reserved_vector<CMetroidAreaCollider::COctreeLeafCache, 3>::iterator begin() { return x18_leafCaches.begin(); }
|
||||
rstl::reserved_vector<CMetroidAreaCollider::COctreeLeafCache, 3>::iterator end() { return x18_leafCaches.end(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
#include "CollisionUtil.hpp"
|
||||
#include "CCollisionInfo.hpp"
|
||||
#include "CCollisionInfoList.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
namespace CollisionUtil
|
||||
{
|
||||
|
||||
bool LineIntersectsOBBox(const zeus::COBBox& obb, const zeus::CMRay& ray, float& d)
|
||||
{
|
||||
const zeus::CVector3f transXf = obb.transform.toMatrix4f().vec[0].toVec3f();
|
||||
|
@ -42,5 +46,56 @@ bool RaySphereIntersection(const zeus::CSphere& sphere, const zeus::CVector3f& p
|
|||
return false;
|
||||
}
|
||||
|
||||
void FilterOutBackfaces(const zeus::CVector3f& vec, const CCollisionInfoList& in, CCollisionInfoList& out)
|
||||
{
|
||||
if (vec.canBeNormalized())
|
||||
{
|
||||
zeus::CVector3f norm = vec.normalized();
|
||||
for (const CCollisionInfo& info : in)
|
||||
{
|
||||
if (info.GetNormalLeft().dot(norm) < 0.001f)
|
||||
out.Add(info, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out = in;
|
||||
}
|
||||
}
|
||||
|
||||
static const zeus::CVector3f AABBNormalTable[] =
|
||||
{
|
||||
{-1.f, 0.f, 0.f},
|
||||
{1.f, 0.f, 0.f},
|
||||
{0.f, -1.f, 0.f},
|
||||
{0.f, 1.f, 0.f},
|
||||
{0.f, 0.f, -1.f},
|
||||
{0.f, 0.f, 1.f}
|
||||
};
|
||||
|
||||
bool AABoxAABoxIntersection(const zeus::CAABox& aabb0, const CMaterialList& list0,
|
||||
const zeus::CAABox& aabb1, const CMaterialList& list1,
|
||||
CCollisionInfoList& infoList)
|
||||
{
|
||||
zeus::CAABox boolAABB = aabb0.booleanIntersection(aabb1);
|
||||
if (boolAABB.invalid())
|
||||
return false;
|
||||
|
||||
/* TODO: Finish */
|
||||
|
||||
if (!infoList.GetCount())
|
||||
{
|
||||
infoList.Add(CCollisionInfo(boolAABB, list0, list1, AABBNormalTable[4], -AABBNormalTable[4]), false);
|
||||
infoList.Add(CCollisionInfo(boolAABB, list0, list1, AABBNormalTable[5], -AABBNormalTable[5]), false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AABoxAABoxIntersection(const zeus::CAABox& aabb0, const zeus::CAABox& aabb1)
|
||||
{
|
||||
return aabb0.intersects(aabb1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,15 +3,23 @@
|
|||
|
||||
#include "GCNTypes.hpp"
|
||||
#include "zeus/zeus.hpp"
|
||||
#include "CMaterialList.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CCollisionInfoList;
|
||||
namespace CollisionUtil
|
||||
{
|
||||
bool LineIntersectsOBBox(const zeus::COBBox&, const zeus::CMRay&, float&);
|
||||
u32 RayAABoxIntersection(const zeus::CMRay&, const zeus::CAABox&, const zeus::CVector3f&, float&);
|
||||
u32 RaySphereIntersection_Double(const zeus::CSphere&, const zeus::CVector3f&, const zeus::CVector3f&, double&);
|
||||
bool RaySphereIntersection(const zeus::CSphere&, const zeus::CVector3f&, const zeus::CVector3f&, float, float&, zeus::CVector3f&);
|
||||
bool RaySphereIntersection(const zeus::CSphere& sphere, const zeus::CVector3f& pos, const zeus::CVector3f& dir,
|
||||
float mag, float& T, zeus::CVector3f& point);
|
||||
void FilterOutBackfaces(const zeus::CVector3f& vec, const CCollisionInfoList& in, CCollisionInfoList& out);
|
||||
bool AABoxAABoxIntersection(const zeus::CAABox& aabb0, const CMaterialList& list0,
|
||||
const zeus::CAABox& aabb1, const CMaterialList& list1,
|
||||
CCollisionInfoList& infoList);
|
||||
bool AABoxAABoxIntersection(const zeus::CAABox& aabb0, const zeus::CAABox& aabb1);
|
||||
}
|
||||
}
|
||||
#endif // __URDE_COLLISIONUTIL_HPP__
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef __URDE_ICOLLISIONFILTER_HPP__
|
||||
#define __URDE_ICOLLISIONFILTER_HPP__
|
||||
|
||||
#include "CCollisionInfoList.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CActor;
|
||||
|
||||
class ICollisionFilter
|
||||
{
|
||||
CActor& x4_actor;
|
||||
protected:
|
||||
ICollisionFilter(CActor& actor) : x4_actor(actor) {}
|
||||
public:
|
||||
virtual void Filter(const CCollisionInfoList& in, CCollisionInfoList& out) const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __URDE_ICOLLISIONFILTER_HPP__
|
|
@ -11,10 +11,11 @@ namespace urde
|
|||
class CGrappleArm
|
||||
{
|
||||
CModelData x0_modelData;
|
||||
|
||||
zeus::CTransform x220_;
|
||||
public:
|
||||
CGrappleArm(const zeus::CVector3f& vec);
|
||||
void AsyncLoadSuit(CStateManager& mgr);
|
||||
void SetX220(const zeus::CTransform& xf) { x220_ = xf; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -219,6 +219,8 @@ public:
|
|||
u32 GetSelectedBeam() const { return x310_selectedBeam; }
|
||||
u32 GetPendingSelectedBeam() const { return x314_pendingSelectedBeam; }
|
||||
const CGunMorph& GetGunMorph() const { return x678_morph; }
|
||||
void SetX3e8(const zeus::CTransform& xf) { x3e8_ = xf; }
|
||||
CGrappleArm& GetGrappleArm() { return *x740_grappleArm; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -496,4 +496,12 @@ const CScannableObjectInfo* CActor::GetScannableObjectInfo() const
|
|||
|
||||
return info.GetObj();
|
||||
}
|
||||
|
||||
void CActor::SetCalculateLighting(bool c)
|
||||
{
|
||||
if (!x90_actorLights)
|
||||
x90_actorLights = std::make_unique<CActorLights>(8, zeus::CVector3f::skZero,
|
||||
4, 4, false, false, false, 0.1f);
|
||||
xe4_31_lightsDirty = c;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -170,6 +170,7 @@ public:
|
|||
const CScannableObjectInfo* GetScannableObjectInfo() const;
|
||||
const CHealthInfo* GetHealthInfo() const { return const_cast<CActor*>(this)->HealthInfo(); }
|
||||
bool GetDoTargetDistanceTest() const { return xe7_30_doTargetDistanceTest; }
|
||||
void SetCalculateLighting(bool c);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -12,12 +12,11 @@ CPhysicsActor::CPhysicsActor(TUniqueId uid, bool active, const std::string& name
|
|||
, xec_massRecip(moverData.x30_mass <= 0.f ? 1.f : 1.f / moverData.x30_mass)
|
||||
, x150_momentum(moverData.x18_momentum)
|
||||
, x1c0_collisionPrimitive(box, matList)
|
||||
, x1f4_translation(xf.origin)
|
||||
, x200_orientation(xf.buildMatrix3f())
|
||||
, x1f4_lastNonCollidingState(xf.origin, xf.buildMatrix3f())
|
||||
, x23c_stepUpHeight(stepUp)
|
||||
, x240_stepDownHeight(stepDown)
|
||||
{
|
||||
xf8_24_ = true;
|
||||
xf8_24_movable = true;
|
||||
SetMass(moverData.x30_mass);
|
||||
MoveCollisionPrimitive(zeus::CVector3f::skZero);
|
||||
SetVelocityOR(moverData.x0_velocity);
|
||||
|
@ -37,7 +36,7 @@ zeus::CVector3f CPhysicsActor::GetAimPosition(const CStateManager&, float dt) co
|
|||
return GetBoundingBox().center() + trans;
|
||||
}
|
||||
|
||||
void CPhysicsActor::CollidedWith(const TUniqueId&, const CCollisionInfoList&, CStateManager&) {}
|
||||
void CPhysicsActor::CollidedWith(TUniqueId, const CCollisionInfoList&, CStateManager&) {}
|
||||
|
||||
const CCollisionPrimitive* CPhysicsActor::GetCollisionPrimitive() const { return &x1c0_collisionPrimitive; }
|
||||
|
||||
|
@ -52,9 +51,9 @@ float CPhysicsActor::GetStepDownHeight() const { return x240_stepDownHeight; }
|
|||
|
||||
float CPhysicsActor::GetWeight() const { return 24.525002f * xe8_mass; }
|
||||
|
||||
void CPhysicsActor::sub_8011A4C(float f) { x238_ = f; }
|
||||
void CPhysicsActor::sub_8011A4C(float f) { x238_maximumCollisionVelocity = f; }
|
||||
|
||||
float CPhysicsActor::sub_8011A4B8() const { return x238_; }
|
||||
float CPhysicsActor::sub_8011A4B8() const { return x238_maximumCollisionVelocity; }
|
||||
|
||||
void CPhysicsActor::SetPrimitiveOffset(const zeus::CVector2f& offset) { x1e8_primitiveOffset = offset; }
|
||||
|
||||
|
@ -144,11 +143,6 @@ void CPhysicsActor::SetInertiaTensorScalar(float tensor)
|
|||
xf4_inertiaTensorRecip = 1.0f / tensor;
|
||||
}
|
||||
|
||||
void CPhysicsActor::SetCoefficientOfRestitutionModifier(float mod)
|
||||
{
|
||||
x244_restitutionCoefModifier = mod;
|
||||
}
|
||||
|
||||
void CPhysicsActor::SetMass(float mass)
|
||||
{
|
||||
xe8_mass = mass;
|
||||
|
@ -302,7 +296,7 @@ CPhysicsState CPhysicsActor::GetPhysicsState() const
|
|||
|
||||
CMotionState CPhysicsActor::PredictMotion_Internal(float dt) const
|
||||
{
|
||||
if (xf8_25_)
|
||||
if (xf8_25_angularEnabled)
|
||||
return PredictMotion(dt);
|
||||
|
||||
CMotionState msl = PredictLinearMotion(dt);
|
||||
|
|
|
@ -29,8 +29,10 @@ struct CMotionState
|
|||
CMotionState(const zeus::CVector3f& origin, const zeus::CNUQuaternion& orientation, const zeus::CVector3f& velocity,
|
||||
const zeus::CAxisAngle& angle)
|
||||
: x0_translation(origin), xc_orientation(orientation), x1c_velocity(velocity), x28_angularMomentum(angle)
|
||||
{
|
||||
}
|
||||
{}
|
||||
CMotionState(const zeus::CVector3f& origin, const zeus::CNUQuaternion& orientation)
|
||||
: x0_translation(origin), xc_orientation(orientation)
|
||||
{}
|
||||
};
|
||||
|
||||
class CPhysicsState
|
||||
|
@ -84,12 +86,12 @@ protected:
|
|||
union {
|
||||
struct
|
||||
{
|
||||
bool xf8_24_ : 1;
|
||||
bool xf8_25_ : 1;
|
||||
bool xf8_24_movable : 1;
|
||||
bool xf8_25_angularEnabled : 1;
|
||||
};
|
||||
u8 _dummy = 0;
|
||||
};
|
||||
bool xf9_ = false;
|
||||
bool xf9_standardCollider = false;
|
||||
zeus::CVector3f xfc_constantForce;
|
||||
zeus::CAxisAngle x108_angularMomentum;
|
||||
zeus::CMatrix3f x114_;
|
||||
|
@ -105,18 +107,15 @@ protected:
|
|||
zeus::CAABox x1a4_baseBoundingBox;
|
||||
CCollidableAABox x1c0_collisionPrimitive;
|
||||
zeus::CVector3f x1e8_primitiveOffset;
|
||||
zeus::CVector3f x1f4_translation;
|
||||
zeus::CNUQuaternion x200_orientation;
|
||||
zeus::CAxisAngle x210_;
|
||||
zeus::CAxisAngle x21c_;
|
||||
CMotionState x1f4_lastNonCollidingState;
|
||||
bool x234_ = false;
|
||||
float x238_ = 1000000.0f;
|
||||
float x238_maximumCollisionVelocity = 1000000.0f;
|
||||
float x23c_stepUpHeight;
|
||||
float x240_stepDownHeight;
|
||||
float x244_restitutionCoefModifier = 0.f;
|
||||
float x248_collisionAccuracyModifier = 1.f;
|
||||
u32 x24c_;
|
||||
u32 x250_;
|
||||
u32 x24c_numTicksStuck;
|
||||
u32 x250_numTicksPartialUpdate;
|
||||
|
||||
public:
|
||||
CPhysicsActor(TUniqueId, bool, const std::string&, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
|
||||
|
@ -127,7 +126,7 @@ public:
|
|||
zeus::CVector3f GetAimPosition(const CStateManager&, float val) const;
|
||||
virtual const CCollisionPrimitive* GetCollisionPrimitive() const;
|
||||
virtual zeus::CTransform GetPrimitiveTransform() const;
|
||||
virtual void CollidedWith(const TUniqueId&, const CCollisionInfoList&, CStateManager&);
|
||||
virtual void CollidedWith(TUniqueId, const CCollisionInfoList&, CStateManager&);
|
||||
virtual float GetStepUpHeight() const;
|
||||
virtual float GetStepDownHeight() const;
|
||||
virtual float GetWeight() const;
|
||||
|
@ -145,15 +144,19 @@ public:
|
|||
const zeus::CAABox& GetBaseBoundingBox() const;
|
||||
void AddMotionState(const CMotionState& mst);
|
||||
CMotionState GetMotionState() const;
|
||||
const CMotionState& GetLastNonCollidingState() const { return x1f4_lastNonCollidingState; }
|
||||
void SetLastNonCollidingState(const CMotionState& mst) { x1f4_lastNonCollidingState = mst; }
|
||||
void SetMotionState(const CMotionState& mst);
|
||||
float GetMaximumCollisionVelocity() const { return x238_maximumCollisionVelocity; }
|
||||
void SetMaximumCollisionVelocity(float v) { x238_maximumCollisionVelocity = v; }
|
||||
void SetInertiaTensorScalar(float tensor);
|
||||
void SetCoefficientOfRestitutionModifier(float);
|
||||
void SetMass(float mass);
|
||||
void SetAngularVelocityOR(const zeus::CAxisAngle& angVel);
|
||||
zeus::CAxisAngle GetAngularVelocityOR() const;
|
||||
void SetAngularVelocityWR(const zeus::CAxisAngle& angVel);
|
||||
void SetVelocityWR(const zeus::CVector3f& vel);
|
||||
void SetVelocityOR(const zeus::CVector3f& vel);
|
||||
const zeus::CVector3f& GetVelocity() const { return x138_velocity; }
|
||||
zeus::CVector3f GetTotalForcesWR() const;
|
||||
void RotateInOneFrameOR(const zeus::CQuaternion& q, float d);
|
||||
void MoveInOneFrameOR(const zeus::CVector3f& trans, float d);
|
||||
|
@ -170,6 +173,19 @@ public:
|
|||
bool WillMove(const CStateManager&);
|
||||
void SetPhysicsState(const CPhysicsState& state);
|
||||
CPhysicsState GetPhysicsState() const;
|
||||
bool IsMovable() const { return xf8_24_movable; }
|
||||
void SetMovable(bool m) { xf8_24_movable = m; }
|
||||
bool IsAngularEnabled() const { return xf8_25_angularEnabled; }
|
||||
void SetAngularEnabled(bool e) { xf8_25_angularEnabled = e; }
|
||||
float GetCollisionAccuracyModifier() const { return x248_collisionAccuracyModifier; }
|
||||
void SetCollisionAccuracyModifier(float m) { x248_collisionAccuracyModifier = m; }
|
||||
float GetCoefficientOfRestitutionModifier() const { return x244_restitutionCoefModifier; }
|
||||
void SetCoefficientOfRestitutionModifier(float m) { x244_restitutionCoefModifier = m; }
|
||||
bool IsUseStandardCollider() const { return xf9_standardCollider; }
|
||||
u32 GetNumTicksPartialUpdate() const { return x250_numTicksPartialUpdate; }
|
||||
void SetNumTicksPartialUpdate(u32 t) { x250_numTicksPartialUpdate = t; }
|
||||
u32 GetNumTicksStuck() const { return x24c_numTicksStuck; }
|
||||
void SetNumTicksStuck(u32 t) { x24c_numTicksStuck = t; }
|
||||
|
||||
CMotionState PredictMotion_Internal(float) const;
|
||||
CMotionState PredictMotion(float dt) const;
|
||||
|
|
|
@ -24,7 +24,7 @@ static CModelData MakePlayerAnimRes(ResId resId, const zeus::CVector3f& scale)
|
|||
return {CAnimRes(resId, 0, scale, 0, true), 1};
|
||||
}
|
||||
|
||||
CPlayer::CPlayer(TUniqueId uid, const zeus::CTransform& xf, const zeus::CAABox& aabb, unsigned int resId,
|
||||
CPlayer::CPlayer(TUniqueId uid, const zeus::CTransform& xf, const zeus::CAABox& aabb, ResId resId,
|
||||
const zeus::CVector3f& playerScale, float mass, float stepUp, float stepDown, float f4,
|
||||
const CMaterialList& ml)
|
||||
: CPhysicsActor(uid, true, "CPlayer", CEntityInfo(kInvalidAreaId, CEntity::NullConnectionList), xf,
|
||||
|
@ -34,7 +34,6 @@ CPlayer::CPlayer(TUniqueId uid, const zeus::CTransform& xf, const zeus::CAABox&
|
|||
x490_gun.reset(new CPlayerGun(uid));
|
||||
x49c_gunNotFiringTimeout = g_tweakPlayerGun->GetGunNotFiringTime();
|
||||
x4a0_inputFilter.reset(new CInputFilter());
|
||||
x768_morphball.reset(new CMorphBall(*this, f4));
|
||||
x76c_cameraBob.reset(new CPlayerCameraBob(CPlayerCameraBob::ECameraBobType::One,
|
||||
zeus::CVector2f{CPlayerCameraBob::kCameraBobExtentX,
|
||||
CPlayerCameraBob::kCameraBobExtentY},
|
||||
|
@ -43,8 +42,43 @@ CPlayer::CPlayer(TUniqueId uid, const zeus::CTransform& xf, const zeus::CAABox&
|
|||
x9c4_27_ = true;
|
||||
x9c4_28_ = true;
|
||||
x9c5_31_ = true;
|
||||
ResId beamId = g_tweakPlayerRes->GetBeamBallTransitionModel(x7ec_);
|
||||
ResId beamId = g_tweakPlayerRes->GetBeamBallTransitionModel(x7ec_beam);
|
||||
x7f0_ballTransitionBeamModel = std::make_unique<CModelData>(CStaticRes(beamId, playerScale));
|
||||
x730_.reserve(3);
|
||||
x768_morphball.reset(new CMorphBall(*this, f4));
|
||||
|
||||
SetInertiaTensorScalar(xe8_mass);
|
||||
x1f4_lastNonCollidingState = GetMotionState();
|
||||
x490_gun->SetX3e8(x34_transform);
|
||||
x490_gun->GetGrappleArm().SetX220(x34_transform);
|
||||
|
||||
InitializeBallTransition();
|
||||
zeus::CAABox ballTransAABB = x64_modelData->GetBounds();
|
||||
x2f0_ballTransHeight = ballTransAABB.max.z - ballTransAABB.min.z;
|
||||
|
||||
SetCalculateLighting(true);
|
||||
|
||||
x90_actorLights->SetCastShadows(true);
|
||||
x50c_.z = 0.f;
|
||||
if (x50c_.canBeNormalized())
|
||||
x50c_.normalize();
|
||||
x2b4_.push_back(20.f);
|
||||
x2b4_.push_back(80.f);
|
||||
x2b4_.push_back(80.f);
|
||||
x2b4_.push_back(270.f);
|
||||
SetMaximumCollisionVelocity(25.f);
|
||||
x354_onScreenOrbitObjects.reserve(64);
|
||||
x344_nearbyOrbitObjects.reserve(64);
|
||||
x364_offScreenOrbitObjects.reserve(64);
|
||||
x64_modelData->SetScale(playerScale);
|
||||
x7f0_ballTransitionBeamModel->SetScale(playerScale);
|
||||
LoadAnimationTokens();
|
||||
}
|
||||
|
||||
void CPlayer::InitializeBallTransition()
|
||||
{
|
||||
if (x64_modelData && x64_modelData->HasAnimData())
|
||||
x64_modelData->AnimationData()->SetAnimation(CAnimPlaybackParms(2, -1, 1.f, true), false);
|
||||
}
|
||||
|
||||
bool CPlayer::IsTransparent() const { return x588_alpha < 1.f; }
|
||||
|
@ -246,7 +280,7 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState
|
|||
{
|
||||
switch (msg)
|
||||
{
|
||||
case EScriptObjectMessage::OnGround:
|
||||
case EScriptObjectMessage::OnFloor:
|
||||
if (x258_movementState != EPlayerMovementState::OnGround &&
|
||||
x2f8_morphTransState != EPlayerMorphBallState::Morphed &&
|
||||
x300_fallingTime > 0.3f)
|
||||
|
@ -834,7 +868,7 @@ const CCollisionPrimitive* CPlayer::GetCollisionPrimitive() const { return CPhys
|
|||
|
||||
zeus::CTransform CPlayer::GetPrimitiveTransform() const { return {}; }
|
||||
|
||||
bool CPlayer::CollidedWith(TUniqueId, const CCollisionInfoList&, CStateManager& mgr) { return false; }
|
||||
void CPlayer::CollidedWith(TUniqueId, const CCollisionInfoList&, CStateManager& mgr) {}
|
||||
|
||||
float CPlayer::GetActualFirstPersonMaxVelocity() const { return 0.f; }
|
||||
|
||||
|
|
|
@ -178,11 +178,11 @@ private:
|
|||
float x2a8_ = 1000.f;
|
||||
EPlayerMovementSurface x2ac_movementSurface = EPlayerMovementSurface::Normal;
|
||||
u32 x2b0_ = 2;
|
||||
u32 x2b4_ = 0;
|
||||
rstl::reserved_vector<float, 6> x2b4_;
|
||||
u32 x2d0_ = 3;
|
||||
float x2d4_ = 0.f;
|
||||
zeus::CAABox x2d8_;
|
||||
float x2f0_ = 0.f;
|
||||
float x2f0_ballTransHeight = 0.f;
|
||||
EPlayerCameraState x2f4_cameraState = EPlayerCameraState::Zero;
|
||||
EPlayerMorphBallState x2f8_morphTransState = EPlayerMorphBallState::Unmorphed;
|
||||
u32 x2fc_ = 0;
|
||||
|
@ -247,7 +247,14 @@ private:
|
|||
u32 x4a4_ = 0;
|
||||
float x4f8_ = 0.f;
|
||||
float x4fc_ = 0.f;
|
||||
float x53c_ = 0.f;
|
||||
zeus::CVector3f x500_ = x34_transform.basis[1];
|
||||
zeus::CVector3f x50c_ = x34_transform.basis[1];
|
||||
zeus::CVector3f x518_ = x34_transform.basis[1];
|
||||
zeus::CVector3f x524_ = x34_transform.basis[1];
|
||||
zeus::CVector3f x530_ = x34_transform.basis[1];
|
||||
zeus::CVector3f x53c_ = x34_transform.basis[1];
|
||||
zeus::CVector3f x548_ = x34_transform.basis[1];
|
||||
float x554_ = x34_transform.basis[1].x;
|
||||
bool x558_ = false;
|
||||
float x55c_ = 0.f;
|
||||
float x560_ = 0.f;
|
||||
|
@ -287,7 +294,7 @@ private:
|
|||
CVisorSteam x7a0_visorSteam = CVisorSteam(0.f, 0.f, 0.f, -1);
|
||||
ResId x7cc_ = -1;
|
||||
CAnimRes x7d0_animRes;
|
||||
CPlayerState::EBeamId x7ec_ = CPlayerState::EBeamId::Power;
|
||||
CPlayerState::EBeamId x7ec_beam = CPlayerState::EBeamId::Power;
|
||||
std::unique_ptr<CModelData> x7f0_ballTransitionBeamModel;
|
||||
zeus::CTransform x7f4_;
|
||||
float x824_ = 0.f;
|
||||
|
@ -365,9 +372,10 @@ private:
|
|||
void ProcessFrozenInput(float dt, CStateManager& mgr);
|
||||
bool CheckSubmerged() const;
|
||||
void UpdateSubmerged(CStateManager& mgr);
|
||||
void InitializeBallTransition();
|
||||
|
||||
public:
|
||||
CPlayer(TUniqueId, const zeus::CTransform&, const zeus::CAABox&, unsigned int w1, const zeus::CVector3f&, float, float,
|
||||
CPlayer(TUniqueId, const zeus::CTransform&, const zeus::CAABox&, ResId w1, const zeus::CVector3f&, float, float,
|
||||
float, float, const CMaterialList&);
|
||||
|
||||
bool IsTransparent() const;
|
||||
|
@ -493,7 +501,7 @@ public:
|
|||
zeus::CTransform CreateTransformFromMovementDirection() const;
|
||||
const CCollisionPrimitive* GetCollisionPrimitive() const;
|
||||
zeus::CTransform GetPrimitiveTransform() const;
|
||||
bool CollidedWith(TUniqueId, const CCollisionInfoList&, CStateManager& mgr);
|
||||
void CollidedWith(TUniqueId, const CCollisionInfoList&, CStateManager& mgr);
|
||||
float GetActualFirstPersonMaxVelocity() const;
|
||||
void SetMoveState(EPlayerMovementState, CStateManager& mgr);
|
||||
float JumpInput(const CFinalInput& input, CStateManager& mgr);
|
||||
|
|
|
@ -45,4 +45,12 @@ rstl::optional_object<zeus::CAABox> CScriptPlatform::GetTouchBounds() const
|
|||
|
||||
return {CPhysicsActor::GetBoundingBox()};
|
||||
}
|
||||
|
||||
bool CScriptPlatform::IsRider(TUniqueId id) const
|
||||
{
|
||||
for (const SRiders& rider : x318_riders)
|
||||
if (rider.x0_uid == id)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ public:
|
|||
|
||||
void Accept(IVisitor& visitor);
|
||||
rstl::optional_object<zeus::CAABox> GetTouchBounds() const;
|
||||
bool IsRider(TUniqueId id) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -200,7 +200,7 @@ enum class EScriptObjectMessage
|
|||
Play = 20,
|
||||
Alert = 21,
|
||||
InternalMessage00 = 22,
|
||||
OnGround = 23,
|
||||
OnFloor = 23,
|
||||
InternalMessage02 = 24,
|
||||
InternalMessage03 = 25,
|
||||
Falling = 26,
|
||||
|
|
Loading…
Reference in New Issue