Add some moving collision implementations

This commit is contained in:
Jack Andersen 2017-06-22 07:56:51 -10:00
parent 59771cf630
commit a2c462529f
9 changed files with 130 additions and 18 deletions

View File

@ -27,7 +27,7 @@ CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, co
SetCoefficientOfRestitutionModifier(0.5f); SetCoefficientOfRestitutionModifier(0.5f);
SetCallTouch(false); SetCallTouch(false);
SetMaterialFilter(CMaterialFilter::MakeIncludeExclude( SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(
{EMaterialTypes::Solid}, {EMaterialTypes::CollisionActor, EMaterialTypes::ThirtyEight})); {EMaterialTypes::Solid}, {EMaterialTypes::CollisionActor, EMaterialTypes::StaticCollision}));
} }
CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, const zeus::CVector3f& boxSize, CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, const zeus::CVector3f& boxSize,
@ -39,12 +39,12 @@ CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, co
, x25c_owner(uid2) , x25c_owner(uid2)
, x260_boxSize(boxSize) , x260_boxSize(boxSize)
, x280_aaboxPrimitive(new CCollidableAABox(zeus::CAABox(-0.5f * boxSize, 0.5f * boxSize), , x280_aaboxPrimitive(new CCollidableAABox(zeus::CAABox(-0.5f * boxSize, 0.5f * boxSize),
CMaterialList(EMaterialTypes::Solid, EMaterialTypes::ThirtyEight))) CMaterialList(EMaterialTypes::Solid, EMaterialTypes::StaticCollision)))
{ {
SetCoefficientOfRestitutionModifier(0.5f); SetCoefficientOfRestitutionModifier(0.5f);
SetCallTouch(false); SetCallTouch(false);
SetMaterialFilter(CMaterialFilter::MakeIncludeExclude( SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(
{EMaterialTypes::Solid}, {EMaterialTypes::CollisionActor, EMaterialTypes::ThirtyEight})); {EMaterialTypes::Solid}, {EMaterialTypes::CollisionActor, EMaterialTypes::StaticCollision}));
} }
CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, bool active, float radius, float mass) CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, bool active, float radius, float mass)
@ -54,13 +54,13 @@ CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, bo
, x258_primitiveType(EPrimitiveType::Sphere) , x258_primitiveType(EPrimitiveType::Sphere)
, x25c_owner(uid2) , x25c_owner(uid2)
, x284_spherePrimitive(new CCollidableSphere(zeus::CSphere(zeus::CVector3f::skZero, radius), , x284_spherePrimitive(new CCollidableSphere(zeus::CSphere(zeus::CVector3f::skZero, radius),
CMaterialList(EMaterialTypes::ThirtyEight, EMaterialTypes::Solid))) CMaterialList(EMaterialTypes::StaticCollision, EMaterialTypes::Solid)))
, x288_sphereRadius(radius) , x288_sphereRadius(radius)
{ {
SetCoefficientOfRestitutionModifier(0.5f); SetCoefficientOfRestitutionModifier(0.5f);
SetCallTouch(false); SetCallTouch(false);
SetMaterialFilter(CMaterialFilter::MakeIncludeExclude( SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(
{EMaterialTypes::Solid}, {EMaterialTypes::CollisionActor, EMaterialTypes::ThirtyEight})); {EMaterialTypes::Solid}, {EMaterialTypes::CollisionActor, EMaterialTypes::StaticCollision}));
} }
void CCollisionActor::Accept(IVisitor& visitor) { visitor.Visit(this); } void CCollisionActor::Accept(IVisitor& visitor) { visitor.Visit(this); }

View File

@ -144,6 +144,16 @@ bool CCollisionPrimitive::CollideBoolean(CInternalCollisionStructure::CPrimDesc&
return InternalCollideBoolean({prim0, prim1}); return InternalCollideBoolean({prim0, prim1});
} }
bool CCollisionPrimitive::CollideMoving(CInternalCollisionStructure::CPrimDesc& prim0,
CInternalCollisionStructure::CPrimDesc& prim1,
const zeus::CVector3f& vec,
double& dOut,
CCollisionInfo& infoOut)
{
// TODO: Finish
return false;
}
void CCollisionPrimitive::InitBeginTypes() void CCollisionPrimitive::InitBeginTypes()
{ {
sCollisionTypeList.reset(new std::vector<CCollisionPrimitive::Type>()); sCollisionTypeList.reset(new std::vector<CCollisionPrimitive::Type>());

View File

@ -153,6 +153,11 @@ public:
CCollisionInfoList& list); CCollisionInfoList& list);
static bool CollideBoolean(CInternalCollisionStructure::CPrimDesc& prim0, static bool CollideBoolean(CInternalCollisionStructure::CPrimDesc& prim0,
CInternalCollisionStructure::CPrimDesc& prim1); CInternalCollisionStructure::CPrimDesc& prim1);
static bool CollideMoving(CInternalCollisionStructure::CPrimDesc& prim0,
CInternalCollisionStructure::CPrimDesc& prim1,
const zeus::CVector3f& vec,
double& dOut,
CCollisionInfo& infoOut);
static void InitBeginTypes(); static void InitBeginTypes();
static void InitAddType(const Type& tp); static void InitAddType(const Type& tp);

View File

@ -102,7 +102,7 @@ void CGameCollision::MoveAndCollide(CStateManager& mgr, CPhysicsActor& actor, fl
mgr.BuildColliderList(useColliderList, actor, zeus::CAABox(motionVol.min - 1.f, motionVol.max + 1.f)); mgr.BuildColliderList(useColliderList, actor, zeus::CAABox(motionVol.min - 1.f, motionVol.max + 1.f));
CAreaCollisionCache cache(motionVol); CAreaCollisionCache cache(motionVol);
if (actor.GetCollisionPrimitive()->GetPrimType() != FOURCC('OBTG') && if (actor.GetCollisionPrimitive()->GetPrimType() != FOURCC('OBTG') &&
!actor.GetMaterialFilter().GetExcludeList().HasMaterial(EMaterialTypes::ThirtyEight)) !actor.GetMaterialFilter().GetExcludeList().HasMaterial(EMaterialTypes::StaticCollision))
{ {
BuildAreaCollisionCache(mgr, cache); BuildAreaCollisionCache(mgr, cache);
zeus::CVector3f pos = actor.GetCollisionPrimitive()->CalculateAABox(actor.GetPrimitiveTransform()).center(); zeus::CVector3f pos = actor.GetCollisionPrimitive()->CalculateAABox(actor.GetPrimitiveTransform()).center();
@ -439,7 +439,7 @@ bool CGameCollision::DetectCollisionBoolean_Cached(CStateManager& mgr, CAreaColl
const CMaterialFilter& filter, const CMaterialFilter& filter,
const rstl::reserved_vector<TUniqueId, 1024>& nearList) const rstl::reserved_vector<TUniqueId, 1024>& nearList)
{ {
if (!filter.GetExcludeList().HasMaterial(EMaterialTypes::ThirtyEight) && if (!filter.GetExcludeList().HasMaterial(EMaterialTypes::StaticCollision) &&
DetectStaticCollisionBoolean_Cached(mgr, cache, prim, xf, filter)) DetectStaticCollisionBoolean_Cached(mgr, cache, prim, xf, filter))
return true; return true;
if (DetectDynamicCollisionBoolean(prim, xf, nearList, mgr)) if (DetectDynamicCollisionBoolean(prim, xf, nearList, mgr))
@ -552,7 +552,7 @@ bool CGameCollision::DetectCollision_Cached(CStateManager& mgr, CAreaCollisionCa
{ {
idOut = kInvalidUniqueId; idOut = kInvalidUniqueId;
bool ret = false; bool ret = false;
if (!filter.GetExcludeList().HasMaterial(EMaterialTypes::ThirtyEight)) if (!filter.GetExcludeList().HasMaterial(EMaterialTypes::StaticCollision))
if (DetectStaticCollision_Cached(mgr, cache, prim, xf, filter, infoList)) if (DetectStaticCollision_Cached(mgr, cache, prim, xf, filter, infoList))
ret = true; ret = true;
@ -574,7 +574,7 @@ bool CGameCollision::DetectCollision_Cached_Moving(CStateManager& mgr, CAreaColl
TUniqueId& idOut, CCollisionInfo& infoOut, double& d) TUniqueId& idOut, CCollisionInfo& infoOut, double& d)
{ {
idOut = kInvalidUniqueId; idOut = kInvalidUniqueId;
if (!filter.GetExcludeList().HasMaterial(EMaterialTypes::ThirtyEight)) if (!filter.GetExcludeList().HasMaterial(EMaterialTypes::StaticCollision))
{ {
if (CGameCollision::DetectStaticCollision_Cached_Moving(mgr, cache, prim, xf, filter, vec, infoOut, d)) if (CGameCollision::DetectStaticCollision_Cached_Moving(mgr, cache, prim, xf, filter, vec, infoOut, d))
return true; return true;
@ -668,10 +668,59 @@ bool CGameCollision::DetectStaticCollision_Cached(CStateManager& mgr, CAreaColli
bool CGameCollision::DetectStaticCollision_Cached_Moving(CStateManager& mgr, CAreaCollisionCache& cache, bool CGameCollision::DetectStaticCollision_Cached_Moving(CStateManager& mgr, CAreaCollisionCache& cache,
const CCollisionPrimitive& prim, const zeus::CTransform& xf, const CCollisionPrimitive& prim, const zeus::CTransform& xf,
const CMaterialFilter& filter, const zeus::CVector3f& vec, const CMaterialFilter& filter, const zeus::CVector3f& vec,
CCollisionInfo& infoOut, double d) CCollisionInfo& infoOut, double& dOut)
{ {
// TODO: Finish if (prim.GetPrimType() == FOURCC('OBTG'))
return false; return false;
zeus::CVector3f offset = float(dOut) * vec;
zeus::CAABox aabb = prim.CalculateAABox(xf);
zeus::CAABox offsetAABB = aabb;
offsetAABB.accumulateBounds(offset + offsetAABB.min);
offsetAABB.accumulateBounds(offset + offsetAABB.max);
if (!offsetAABB.inside(cache.GetCacheBounds()))
{
zeus::CAABox newAABB(offsetAABB.min - 0.2f, offsetAABB.max + 0.2f);
newAABB.accumulateBounds(cache.GetCacheBounds());
cache.SetCacheBounds(newAABB);
BuildAreaCollisionCache(mgr, cache);
}
if (prim.GetPrimType() == FOURCC('AABX'))
{
for (CMetroidAreaCollider::COctreeLeafCache& leafCache : cache)
{
CCollisionInfo info;
double d = dOut;
if (CMetroidAreaCollider::MovingAABoxCollisionCheck_Cached(leafCache, aabb, filter,
CMaterialList(EMaterialTypes::Solid), vec,
dOut, info, d) && d < dOut)
{
infoOut = info;
dOut = d;
}
}
}
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)
{
CCollisionInfo info;
double d = dOut;
if (CMetroidAreaCollider::MovingSphereCollisionCheck_Cached(leafCache, aabb, xfSphere, filter,
CMaterialList(EMaterialTypes::Solid), vec,
dOut, info, d) && d < dOut)
{
infoOut = info;
dOut = d;
}
}
}
return infoOut.IsValid();
} }
bool CGameCollision::DetectDynamicCollision(const CCollisionPrimitive& prim, const zeus::CTransform& xf, bool CGameCollision::DetectDynamicCollision(const CCollisionPrimitive& prim, const zeus::CTransform& xf,
@ -700,10 +749,31 @@ bool CGameCollision::DetectDynamicCollision(const CCollisionPrimitive& prim, con
bool CGameCollision::DetectDynamicCollisionMoving(const CCollisionPrimitive& prim, const zeus::CTransform& xf, bool CGameCollision::DetectDynamicCollisionMoving(const CCollisionPrimitive& prim, const zeus::CTransform& xf,
const rstl::reserved_vector<TUniqueId, 1024>& nearList, const rstl::reserved_vector<TUniqueId, 1024>& nearList,
const zeus::CVector3f& vec, TUniqueId& idOut, const zeus::CVector3f& vec, TUniqueId& idOut,
CCollisionInfo& infoOut, double& d, CStateManager& mgr) CCollisionInfo& infoOut, double& dOut, CStateManager& mgr)
{ {
// TODO: Finish bool ret = false;
return false; for (TUniqueId id : nearList)
{
double d = dOut;
CCollisionInfo info;
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::CollideMoving(p0, p1, vec, d, info) && d < dOut)
{
ret = true;
infoOut = info;
dOut = d;
idOut = actor->GetUniqueId();
return true;
}
}
}
return ret;
} }
void CGameCollision::MakeCollisionCallbacks(CStateManager& mgr, CPhysicsActor& actor, void CGameCollision::MakeCollisionCallbacks(CStateManager& mgr, CPhysicsActor& actor,

View File

@ -95,7 +95,7 @@ public:
static bool DetectStaticCollision_Cached_Moving(CStateManager& mgr, CAreaCollisionCache& cache, static bool DetectStaticCollision_Cached_Moving(CStateManager& mgr, CAreaCollisionCache& cache,
const CCollisionPrimitive& prim, const zeus::CTransform& xf, const CCollisionPrimitive& prim, const zeus::CTransform& xf,
const CMaterialFilter& filter, const zeus::CVector3f& vec, const CMaterialFilter& filter, const zeus::CVector3f& vec,
CCollisionInfo& infoOut, double d); CCollisionInfo& infoOut, double& d);
static bool DetectDynamicCollision(const CCollisionPrimitive& prim, const zeus::CTransform& xf, static bool DetectDynamicCollision(const CCollisionPrimitive& prim, const zeus::CTransform& xf,
const rstl::reserved_vector<TUniqueId, 1024>& nearList, const rstl::reserved_vector<TUniqueId, 1024>& nearList,
TUniqueId& idOut, CCollisionInfoList& list, CStateManager& mgr); TUniqueId& idOut, CCollisionInfoList& list, CStateManager& mgr);

View File

@ -45,7 +45,7 @@ enum class EMaterialTypes
Projectile = 35, Projectile = 35,
Bomb = 36, Bomb = 36,
GroundCollider = 37, GroundCollider = 37,
ThirtyEight = 38, StaticCollision = 38,
Scannable = 39, Scannable = 39,
Target = 40, Target = 40,
Orbit = 41, Orbit = 41,

View File

@ -92,6 +92,23 @@ bool CMetroidAreaCollider::SphereCollisionCheck(const CAreaOctTree& octTree, con
return false; return false;
} }
bool CMetroidAreaCollider::MovingAABoxCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
const CMaterialFilter& filter, const CMaterialList& matList,
const zeus::CVector3f& vec, float mag, CCollisionInfo& infoOut,
double& dOut)
{
return false;
}
bool CMetroidAreaCollider::MovingSphereCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
const zeus::CSphere& sphere,
const CMaterialFilter& filter, const CMaterialList& matList,
const zeus::CVector3f& vec, float mag, CCollisionInfo& infoOut,
double& dOut)
{
return false;
}
void CAreaCollisionCache::ClearCache() void CAreaCollisionCache::ClearCache()
{ {
x18_leafCaches.clear(); x18_leafCaches.clear();

View File

@ -8,6 +8,7 @@
namespace urde namespace urde
{ {
class CCollisionInfoList; class CCollisionInfoList;
class CCollisionInfo;
class CMaterialList; class CMaterialList;
class CMetroidAreaCollider class CMetroidAreaCollider
@ -47,6 +48,15 @@ public:
static bool SphereCollisionCheck(const CAreaOctTree& octTree, const zeus::CAABox& aabb, static bool SphereCollisionCheck(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
const zeus::CSphere& sphere, const CMaterialList& matList, const zeus::CSphere& sphere, const CMaterialList& matList,
const CMaterialFilter& filter, CCollisionInfoList& list); const CMaterialFilter& filter, CCollisionInfoList& list);
static bool MovingAABoxCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
const CMaterialFilter& filter, const CMaterialList& matList,
const zeus::CVector3f& vec, float mag, CCollisionInfo& infoOut,
double& dOut);
static bool MovingSphereCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
const zeus::CSphere& sphere,
const CMaterialFilter& filter, const CMaterialList& matList,
const zeus::CVector3f& vec, float mag, CCollisionInfo& infoOut,
double& dOut);
}; };
class CAreaCollisionCache class CAreaCollisionCache

View File

@ -31,7 +31,7 @@ CScriptPlatform::CScriptPlatform(TUniqueId uid, const std::string& name, const C
{ {
CActor::SetMaterialFilter(CMaterialFilter::MakeIncludeExclude( CActor::SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(
CMaterialList(EMaterialTypes::Solid), CMaterialList(EMaterialTypes::Solid),
CMaterialList(EMaterialTypes::ThirtyEight, EMaterialTypes::Twenty, EMaterialTypes::Platform))); CMaterialList(EMaterialTypes::StaticCollision, EMaterialTypes::Twenty, EMaterialTypes::Platform)));
if (x304_treeGroupContainer) if (x304_treeGroupContainer)
x314_treeGroup = std::make_unique<CCollidableOBBTreeGroup>(x304_treeGroupContainer->GetObj(), x68_material); x314_treeGroup = std::make_unique<CCollidableOBBTreeGroup>(x304_treeGroupContainer->GetObj(), x68_material);
} }