mirror of https://github.com/AxioDL/metaforce.git
Finish CMetroidAreaCollider
This commit is contained in:
parent
ec7ac212ef
commit
ff15bfbec3
|
@ -1829,7 +1829,7 @@ void CStateManager::Update(float dt)
|
||||||
|
|
||||||
if (x904_gameState != EGameState::Paused)
|
if (x904_gameState != EGameState::Paused)
|
||||||
{
|
{
|
||||||
PreThinkEffects(dt);
|
PreThinkObjects(dt);
|
||||||
x87c_fluidPlaneManager->Update(dt);
|
x87c_fluidPlaneManager->Update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1961,7 +1961,7 @@ void CStateManager::UpdateHintState(float dt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStateManager::PreThinkEffects(float dt)
|
void CStateManager::PreThinkObjects(float dt)
|
||||||
{
|
{
|
||||||
if (x84c_player->x9f4_deathTime > 0.f)
|
if (x84c_player->x9f4_deathTime > 0.f)
|
||||||
{
|
{
|
||||||
|
@ -1974,7 +1974,7 @@ void CStateManager::PreThinkEffects(float dt)
|
||||||
if (TCastToPtr<CScriptEffect> effect = ent)
|
if (TCastToPtr<CScriptEffect> effect = ent)
|
||||||
effect->PreThink(dt, *this);
|
effect->PreThink(dt, *this);
|
||||||
|
|
||||||
for (CEntity* ent : GetCameraObjectList())
|
for (CEntity* ent : GetAllObjectList())
|
||||||
if (ent && !GetCameraObjectList().GetObjectById(ent->GetUniqueId()))
|
if (ent && !GetCameraObjectList().GetObjectById(ent->GetUniqueId()))
|
||||||
ent->PreThink(dt, *this);
|
ent->PreThink(dt, *this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -354,7 +354,7 @@ public:
|
||||||
void Update(float dt);
|
void Update(float dt);
|
||||||
void UpdateGameState();
|
void UpdateGameState();
|
||||||
void UpdateHintState(float dt);
|
void UpdateHintState(float dt);
|
||||||
void PreThinkEffects(float dt);
|
void PreThinkObjects(float dt);
|
||||||
void MovePlatforms(float dt);
|
void MovePlatforms(float dt);
|
||||||
void MoveDoors(float dt);
|
void MoveDoors(float dt);
|
||||||
void CrossTouchActors();
|
void CrossTouchActors();
|
||||||
|
|
|
@ -140,7 +140,7 @@ public:
|
||||||
u32 GetNumTriangles() const { return x40_polyCount; }
|
u32 GetNumTriangles() const { return x40_polyCount; }
|
||||||
CCollisionSurface GetMasterListTriangle(u16 idx) const;
|
CCollisionSurface GetMasterListTriangle(u16 idx) const;
|
||||||
void GetTriangleVertexIndices(u16 idx, u16 indicesOut[3]) const;
|
void GetTriangleVertexIndices(u16 idx, u16 indicesOut[3]) const;
|
||||||
const u16* GetTriangleEdgeIndices(u16 idx) const { return &x44_polyEdges[idx * 6]; }
|
const u16* GetTriangleEdgeIndices(u16 idx) const { return &x44_polyEdges[idx * 3]; }
|
||||||
|
|
||||||
static std::unique_ptr<CAreaOctTree> MakeFromMemory(const u8* buf, unsigned int size);
|
static std::unique_ptr<CAreaOctTree> MakeFromMemory(const u8* buf, unsigned int size);
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,7 +10,7 @@ u32 CMetroidAreaCollider::g_CalledClip = 0;
|
||||||
u32 CMetroidAreaCollider::g_RejectedByClip = 0;
|
u32 CMetroidAreaCollider::g_RejectedByClip = 0;
|
||||||
u32 CMetroidAreaCollider::g_TrianglesProcessed = 0;
|
u32 CMetroidAreaCollider::g_TrianglesProcessed = 0;
|
||||||
u32 CMetroidAreaCollider::g_DupTrianglesProcessed = 0;
|
u32 CMetroidAreaCollider::g_DupTrianglesProcessed = 0;
|
||||||
s16 CMetroidAreaCollider::g_DupPrimitiveCheckCount = 0;
|
u16 CMetroidAreaCollider::g_DupPrimitiveCheckCount = 0;
|
||||||
u16 CMetroidAreaCollider::g_DupVertexList[0x5000] = {};
|
u16 CMetroidAreaCollider::g_DupVertexList[0x5000] = {};
|
||||||
u16 CMetroidAreaCollider::g_DupEdgeList[0xC000] = {};
|
u16 CMetroidAreaCollider::g_DupEdgeList[0xC000] = {};
|
||||||
u16 CMetroidAreaCollider::g_DupTriangleList[0x4000] = {};
|
u16 CMetroidAreaCollider::g_DupTriangleList[0x4000] = {};
|
||||||
|
@ -25,6 +25,16 @@ CBooleanAABoxAreaCache::CBooleanAABoxAreaCache(const zeus::CAABox& aabb, const C
|
||||||
: x0_aabb(aabb), x4_filter(filter), x8_center(aabb.center()), x14_halfExtent(aabb.extents())
|
: x0_aabb(aabb), x4_filter(filter), x8_center(aabb.center()), x14_halfExtent(aabb.extents())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
CSphereAreaCache::CSphereAreaCache(const zeus::CAABox& aabb, const zeus::CSphere& sphere, const CMaterialFilter& filter,
|
||||||
|
const CMaterialList& material, CCollisionInfoList& collisionList)
|
||||||
|
: x0_aabb(aabb), x4_sphere(sphere), x8_filter(filter), xc_material(material), x10_collisionList(collisionList)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CBooleanSphereAreaCache::CBooleanSphereAreaCache(const zeus::CAABox& aabb, const zeus::CSphere& sphere,
|
||||||
|
const CMaterialFilter& filter)
|
||||||
|
: x0_aabb(aabb), x4_sphere(sphere), x8_filter(filter)
|
||||||
|
{}
|
||||||
|
|
||||||
SBoxEdge::SBoxEdge(const zeus::CAABox& aabb, int idx, const zeus::CVector3f& dir)
|
SBoxEdge::SBoxEdge(const zeus::CAABox& aabb, int idx, const zeus::CVector3f& dir)
|
||||||
: x0_seg(aabb.getEdge(zeus::CAABox::EBoxEdgeId(idx))), x28_dir(x0_seg.dir), x40_end(x0_seg.end),
|
: x0_seg(aabb.getEdge(zeus::CAABox::EBoxEdgeId(idx))), x28_dir(x0_seg.dir), x40_end(x0_seg.end),
|
||||||
x58_start(x40_end - x28_dir), x70_coDir(x58_start.cross(dir).asNormalized()),
|
x58_start(x40_end - x28_dir), x70_coDir(x58_start.cross(dir).asNormalized()),
|
||||||
|
@ -202,6 +212,9 @@ bool CMetroidAreaCollider::ConvexPolyCollision(const zeus::CPlane* planes, const
|
||||||
{
|
{
|
||||||
rstl::reserved_vector<zeus::CVector3f, 20> vecs[2];
|
rstl::reserved_vector<zeus::CVector3f, 20> vecs[2];
|
||||||
|
|
||||||
|
g_CalledClip += 1;
|
||||||
|
g_RejectedByClip -= 1;
|
||||||
|
|
||||||
vecs[0].push_back(verts[0]);
|
vecs[0].push_back(verts[0]);
|
||||||
vecs[0].push_back(verts[1]);
|
vecs[0].push_back(verts[1]);
|
||||||
vecs[0].push_back(verts[2]);
|
vecs[0].push_back(verts[2]);
|
||||||
|
@ -313,13 +326,73 @@ bool CMetroidAreaCollider::AABoxCollisionCheckBoolean(const CAreaOctTree& octTre
|
||||||
bool CMetroidAreaCollider::SphereCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
bool CMetroidAreaCollider::SphereCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
||||||
const zeus::CSphere& sphere, const CMaterialFilter& filter)
|
const zeus::CSphere& sphere, const CMaterialFilter& filter)
|
||||||
{
|
{
|
||||||
|
CBooleanSphereAreaCache cache(aabb, sphere, filter);
|
||||||
|
|
||||||
|
for (const CAreaOctTree::Node& node : leafCache.x4_nodeCache)
|
||||||
|
{
|
||||||
|
if (cache.x0_aabb.intersects(node.GetBoundingBox()))
|
||||||
|
{
|
||||||
|
CAreaOctTree::TriListReference list = node.GetTriangleArray();
|
||||||
|
for (int j=0 ; j<list.GetSize() ; ++j)
|
||||||
|
{
|
||||||
|
++g_TrianglesProcessed;
|
||||||
|
CCollisionSurface surf = node.GetOwner().GetMasterListTriangle(list.GetAt(j));
|
||||||
|
if (cache.x8_filter.Passes(CMaterialList(surf.GetSurfaceFlags())))
|
||||||
|
{
|
||||||
|
if (CollisionUtil::TriSphereOverlap(cache.x4_sphere,
|
||||||
|
surf.GetVert(0), surf.GetVert(1), surf.GetVert(2)))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMetroidAreaCollider::SphereCollisionCheckBoolean_Internal(const CAreaOctTree::Node& node,
|
||||||
|
const CBooleanSphereAreaCache& cache)
|
||||||
|
{
|
||||||
|
for (int i=0 ; i<8 ; ++i)
|
||||||
|
{
|
||||||
|
CAreaOctTree::Node::ETreeType type = node.GetChildType(i);
|
||||||
|
if (type != CAreaOctTree::Node::ETreeType::Invalid)
|
||||||
|
{
|
||||||
|
CAreaOctTree::Node ch = node.GetChild(i);
|
||||||
|
if (cache.x0_aabb.intersects(ch.GetBoundingBox()))
|
||||||
|
{
|
||||||
|
if (type == CAreaOctTree::Node::ETreeType::Leaf)
|
||||||
|
{
|
||||||
|
CAreaOctTree::TriListReference list = ch.GetTriangleArray();
|
||||||
|
for (int j=0 ; j<list.GetSize() ; ++j)
|
||||||
|
{
|
||||||
|
++g_TrianglesProcessed;
|
||||||
|
CCollisionSurface surf = ch.GetOwner().GetMasterListTriangle(list.GetAt(j));
|
||||||
|
if (cache.x8_filter.Passes(CMaterialList(surf.GetSurfaceFlags())))
|
||||||
|
{
|
||||||
|
if (CollisionUtil::TriSphereOverlap(cache.x4_sphere,
|
||||||
|
surf.GetVert(0), surf.GetVert(1), surf.GetVert(2)))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (SphereCollisionCheckBoolean_Internal(ch, cache))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMetroidAreaCollider::SphereCollisionCheckBoolean(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
bool CMetroidAreaCollider::SphereCollisionCheckBoolean(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
||||||
const zeus::CSphere& sphere, const CMaterialFilter& filter)
|
const zeus::CSphere& sphere, const CMaterialFilter& filter)
|
||||||
{
|
{
|
||||||
return false;
|
CAreaOctTree::Node node = octTree.GetRootNode();
|
||||||
|
CBooleanSphereAreaCache cache(aabb, sphere, filter);
|
||||||
|
return SphereCollisionCheckBoolean_Internal(node, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMetroidAreaCollider::AABoxCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
bool CMetroidAreaCollider::AABoxCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
||||||
|
@ -467,16 +540,114 @@ bool CMetroidAreaCollider::AABoxCollisionCheck(const CAreaOctTree& octTree, cons
|
||||||
|
|
||||||
bool CMetroidAreaCollider::SphereCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
bool CMetroidAreaCollider::SphereCollisionCheck_Cached(const COctreeLeafCache& leafCache, 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& clist)
|
||||||
{
|
{
|
||||||
return false;
|
ResetInternalCounters();
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
zeus::CVector3f point, normal;
|
||||||
|
|
||||||
|
for (const CAreaOctTree::Node& node : leafCache.x4_nodeCache)
|
||||||
|
{
|
||||||
|
if (aabb.intersects(node.GetBoundingBox()))
|
||||||
|
{
|
||||||
|
CAreaOctTree::TriListReference list = node.GetTriangleArray();
|
||||||
|
for (int j=0 ; j<list.GetSize() ; ++j)
|
||||||
|
{
|
||||||
|
++g_TrianglesProcessed;
|
||||||
|
u16 triIdx = list.GetAt(j);
|
||||||
|
if (g_DupPrimitiveCheckCount == g_DupTriangleList[triIdx])
|
||||||
|
{
|
||||||
|
g_DupTrianglesProcessed += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_DupTriangleList[triIdx] = g_DupPrimitiveCheckCount;
|
||||||
|
CCollisionSurface surf = node.GetOwner().GetMasterListTriangle(triIdx);
|
||||||
|
CMaterialList material(surf.GetSurfaceFlags());
|
||||||
|
if (filter.Passes(material))
|
||||||
|
{
|
||||||
|
if (CollisionUtil::TriSphereIntersection(sphere,
|
||||||
|
surf.GetVert(0), surf.GetVert(1), surf.GetVert(2),
|
||||||
|
point, normal))
|
||||||
|
{
|
||||||
|
CCollisionInfo collision(point, matList, material, normal);
|
||||||
|
clist.Add(collision, false);
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMetroidAreaCollider::SphereCollisionCheck_Internal(const CAreaOctTree::Node& node,
|
||||||
|
const CSphereAreaCache& cache)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
zeus::CVector3f point, normal;
|
||||||
|
|
||||||
|
for (int i=0 ; i<8 ; ++i)
|
||||||
|
{
|
||||||
|
CAreaOctTree::Node::ETreeType chTp = node.GetChildType(i);
|
||||||
|
if (chTp != CAreaOctTree::Node::ETreeType::Invalid)
|
||||||
|
{
|
||||||
|
CAreaOctTree::Node ch = node.GetChild(i);
|
||||||
|
if (cache.x0_aabb.intersects(ch.GetBoundingBox()))
|
||||||
|
{
|
||||||
|
if (chTp == CAreaOctTree::Node::ETreeType::Leaf)
|
||||||
|
{
|
||||||
|
CAreaOctTree::TriListReference list = ch.GetTriangleArray();
|
||||||
|
for (int j=0 ; j<list.GetSize() ; ++j)
|
||||||
|
{
|
||||||
|
++g_TrianglesProcessed;
|
||||||
|
u16 triIdx = list.GetAt(j);
|
||||||
|
if (g_DupPrimitiveCheckCount == g_DupTriangleList[triIdx])
|
||||||
|
{
|
||||||
|
g_DupTrianglesProcessed += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_DupTriangleList[triIdx] = g_DupPrimitiveCheckCount;
|
||||||
|
CCollisionSurface surf = ch.GetOwner().GetMasterListTriangle(triIdx);
|
||||||
|
CMaterialList material(surf.GetSurfaceFlags());
|
||||||
|
if (cache.x8_filter.Passes(material))
|
||||||
|
{
|
||||||
|
if (CollisionUtil::TriSphereIntersection(cache.x4_sphere,
|
||||||
|
surf.GetVert(0), surf.GetVert(1), surf.GetVert(2),
|
||||||
|
point, normal))
|
||||||
|
{
|
||||||
|
CCollisionInfo collision(point, cache.xc_material, material, normal);
|
||||||
|
cache.x10_collisionList.Add(collision, false);
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (SphereCollisionCheck_Internal(ch, cache))
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMetroidAreaCollider::SphereCollisionCheck(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
bool CMetroidAreaCollider::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)
|
||||||
{
|
{
|
||||||
return false;
|
CSphereAreaCache cache(aabb, sphere, filter, matList, list);
|
||||||
|
ResetInternalCounters();
|
||||||
|
CAreaOctTree::Node node = octTree.GetRootNode();
|
||||||
|
return SphereCollisionCheck_Internal(node, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMetroidAreaCollider::MovingAABoxCollisionCheck_BoxVertexTri(const CCollisionSurface& surf, const zeus::CAABox& aabb,
|
bool CMetroidAreaCollider::MovingAABoxCollisionCheck_BoxVertexTri(const CCollisionSurface& surf, const zeus::CAABox& aabb,
|
||||||
|
@ -730,7 +901,185 @@ bool CMetroidAreaCollider::MovingSphereCollisionCheck_Cached(const COctreeLeafCa
|
||||||
const zeus::CVector3f& dir, float mag, CCollisionInfo& infoOut,
|
const zeus::CVector3f& dir, float mag, CCollisionInfo& infoOut,
|
||||||
double& dOut)
|
double& dOut)
|
||||||
{
|
{
|
||||||
return false;
|
bool ret = false;
|
||||||
|
ResetInternalCounters();
|
||||||
|
dOut = mag;
|
||||||
|
|
||||||
|
zeus::CAABox movedAABB = aabb;
|
||||||
|
zeus::CVector3f moveVec = mag * dir;
|
||||||
|
movedAABB.accumulateBounds(aabb.min + moveVec);
|
||||||
|
movedAABB.accumulateBounds(aabb.max + moveVec);
|
||||||
|
|
||||||
|
zeus::CVector3f center = movedAABB.center();
|
||||||
|
zeus::CVector3f extent = movedAABB.extents();
|
||||||
|
|
||||||
|
for (const CAreaOctTree::Node& node : leafCache.x4_nodeCache)
|
||||||
|
{
|
||||||
|
if (movedAABB.intersects(node.GetBoundingBox()))
|
||||||
|
{
|
||||||
|
CAreaOctTree::TriListReference list = node.GetTriangleArray();
|
||||||
|
for (int j=0 ; j<list.GetSize() ; ++j)
|
||||||
|
{
|
||||||
|
u16 triIdx = list.GetAt(j);
|
||||||
|
if (g_DupPrimitiveCheckCount != g_DupTriangleList[triIdx])
|
||||||
|
{
|
||||||
|
g_TrianglesProcessed += 1;
|
||||||
|
g_DupTriangleList[triIdx] = g_DupPrimitiveCheckCount;
|
||||||
|
CMaterialList triMat(node.GetOwner().GetTriangleMaterial(triIdx));
|
||||||
|
if (filter.Passes(triMat))
|
||||||
|
{
|
||||||
|
u16 vertIndices[3];
|
||||||
|
node.GetOwner().GetTriangleVertexIndices(triIdx, vertIndices);
|
||||||
|
CCollisionSurface surf(node.GetOwner().GetVert(vertIndices[0]),
|
||||||
|
node.GetOwner().GetVert(vertIndices[1]),
|
||||||
|
node.GetOwner().GetVert(vertIndices[2]),
|
||||||
|
triMat.GetValue());
|
||||||
|
|
||||||
|
if (CollisionUtil::TriBoxOverlap(center, extent,
|
||||||
|
surf.GetVert(0), surf.GetVert(1), surf.GetVert(2)))
|
||||||
|
{
|
||||||
|
zeus::CVector3f surfNormal = surf.GetNormal();
|
||||||
|
if ((sphere.position + moveVec - surf.GetVert(0)).dot(surfNormal) <= sphere.radius)
|
||||||
|
{
|
||||||
|
bool triRet = false;
|
||||||
|
|
||||||
|
float mag = (sphere.radius - (sphere.position - surf.GetVert(0)).dot(surfNormal)) / dir.dot(surfNormal);
|
||||||
|
zeus::CVector3f intersectPoint = sphere.position + mag * dir;
|
||||||
|
|
||||||
|
bool outsideEdges[] =
|
||||||
|
{(intersectPoint - surf.GetVert(0)).dot((surf.GetVert(1) - surf.GetVert(0)).cross(surfNormal)) < 0.f,
|
||||||
|
(intersectPoint - surf.GetVert(1)).dot((surf.GetVert(2) - surf.GetVert(1)).cross(surfNormal)) < 0.f,
|
||||||
|
(intersectPoint - surf.GetVert(2)).dot((surf.GetVert(0) - surf.GetVert(2)).cross(surfNormal)) < 0.f};
|
||||||
|
|
||||||
|
if (mag >= 0.f && !outsideEdges[0] && !outsideEdges[1] && !outsideEdges[2] && mag < dOut)
|
||||||
|
{
|
||||||
|
infoOut = CCollisionInfo(intersectPoint - sphere.radius * surfNormal, matList, triMat, surfNormal);
|
||||||
|
dOut = mag;
|
||||||
|
triRet = true;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool intersects = (sphere.position - surf.GetVert(0)).dot(surfNormal) <= sphere.radius;
|
||||||
|
bool x49c[] = {true, true, true};
|
||||||
|
const u16* edgeIndices = node.GetOwner().GetTriangleEdgeIndices(triIdx);
|
||||||
|
for (int k=0 ; k<3 ; ++k)
|
||||||
|
{
|
||||||
|
if (intersects || outsideEdges[k])
|
||||||
|
{
|
||||||
|
u16 edgeIdx = edgeIndices[k];
|
||||||
|
if (g_DupPrimitiveCheckCount != g_DupEdgeList[edgeIdx])
|
||||||
|
{
|
||||||
|
g_DupEdgeList[edgeIdx] = g_DupPrimitiveCheckCount;
|
||||||
|
CMaterialList edgeMat(node.GetOwner().GetEdgeMaterial(edgeIdx));
|
||||||
|
if (!edgeMat.HasMaterial(EMaterialTypes::TwentyFour))
|
||||||
|
{
|
||||||
|
int nextIdx = (k + 1) % 3;
|
||||||
|
zeus::CVector3f edgeVec = surf.GetVert(nextIdx) - surf.GetVert(k);
|
||||||
|
float edgeVecMag = edgeVec.magnitude();
|
||||||
|
edgeVec *= (1.f / edgeVecMag);
|
||||||
|
float dirDotEdge = dir.dot(edgeVec);
|
||||||
|
zeus::CVector3f edgeRej = dir - dirDotEdge * edgeVec;
|
||||||
|
float edgeRejMagSq = edgeRej.magSquared();
|
||||||
|
zeus::CVector3f vertToSphere = sphere.position - surf.GetVert(k);
|
||||||
|
float vtsDotEdge = vertToSphere.dot(edgeVec);
|
||||||
|
zeus::CVector3f vtsRej = vertToSphere - vtsDotEdge * edgeVec;
|
||||||
|
if (edgeRejMagSq > 0.f)
|
||||||
|
{
|
||||||
|
float tmp = 2.f * vtsRej.dot(edgeRej);
|
||||||
|
float tmp2 = 4.f * edgeRejMagSq *
|
||||||
|
(vtsRej.magSquared() - sphere.radius * sphere.radius) - tmp * tmp;
|
||||||
|
if (tmp2 >= 0.f)
|
||||||
|
{
|
||||||
|
float mag = 0.5f / edgeRejMagSq * (-tmp - std::sqrt(tmp2));
|
||||||
|
if (mag >= 0.f)
|
||||||
|
{
|
||||||
|
float t = mag * dirDotEdge + vtsDotEdge;
|
||||||
|
if (t >= 0.f && t <= edgeVecMag && mag < dOut)
|
||||||
|
{
|
||||||
|
zeus::CVector3f point = surf.GetVert(k) + t * edgeVec;
|
||||||
|
infoOut = CCollisionInfo(point, matList, edgeMat,
|
||||||
|
(sphere.position + mag * dir - point).normalized());
|
||||||
|
dOut = mag;
|
||||||
|
triRet = true;
|
||||||
|
ret = true;
|
||||||
|
x49c[k] = false;
|
||||||
|
x49c[nextIdx] = false;
|
||||||
|
}
|
||||||
|
else if (t < -sphere.radius && dirDotEdge <= 0.f)
|
||||||
|
{
|
||||||
|
x49c[k] = false;
|
||||||
|
}
|
||||||
|
else if (t > edgeVecMag + sphere.radius && dirDotEdge >= 0.0)
|
||||||
|
{
|
||||||
|
x49c[nextIdx] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x49c[k] = false;
|
||||||
|
x49c[nextIdx] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int k=0 ; k<3 ; ++k)
|
||||||
|
{
|
||||||
|
u16 vertIdx = vertIndices[k];
|
||||||
|
if (x49c[k])
|
||||||
|
{
|
||||||
|
if (g_DupPrimitiveCheckCount != g_DupVertexList[vertIdx])
|
||||||
|
{
|
||||||
|
g_DupVertexList[vertIdx] = g_DupPrimitiveCheckCount;
|
||||||
|
double d = dOut;
|
||||||
|
if (CollisionUtil::RaySphereIntersection_Double(zeus::CSphere(surf.GetVert(k), sphere.radius),
|
||||||
|
sphere.position, dir, d) && d >= 0.0)
|
||||||
|
{
|
||||||
|
infoOut = CCollisionInfo(surf.GetVert(k), matList, node.GetOwner().GetVertMaterial(vertIdx),
|
||||||
|
(sphere.position + dir * d - surf.GetVert(k)).normalized());
|
||||||
|
dOut = d;
|
||||||
|
triRet = true;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_DupVertexList[vertIdx] = g_DupPrimitiveCheckCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (triRet)
|
||||||
|
{
|
||||||
|
moveVec = float(dOut) * dir;
|
||||||
|
movedAABB = aabb;
|
||||||
|
movedAABB.accumulateBounds(aabb.min + moveVec);
|
||||||
|
movedAABB.accumulateBounds(aabb.max + moveVec);
|
||||||
|
center = movedAABB.center();
|
||||||
|
extent = movedAABB.extents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const u16* edgeIndices = node.GetOwner().GetTriangleEdgeIndices(triIdx);
|
||||||
|
g_DupEdgeList[edgeIndices[0]] = g_DupPrimitiveCheckCount;
|
||||||
|
g_DupEdgeList[edgeIndices[1]] = g_DupPrimitiveCheckCount;
|
||||||
|
g_DupEdgeList[edgeIndices[2]] = g_DupPrimitiveCheckCount;
|
||||||
|
g_DupVertexList[vertIndices[0]] = g_DupPrimitiveCheckCount;
|
||||||
|
g_DupVertexList[vertIndices[1]] = g_DupPrimitiveCheckCount;
|
||||||
|
g_DupVertexList[vertIndices[2]] = g_DupPrimitiveCheckCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMetroidAreaCollider::ResetInternalCounters()
|
void CMetroidAreaCollider::ResetInternalCounters()
|
||||||
|
@ -739,7 +1088,7 @@ void CMetroidAreaCollider::ResetInternalCounters()
|
||||||
g_RejectedByClip = 0;
|
g_RejectedByClip = 0;
|
||||||
g_TrianglesProcessed = 0;
|
g_TrianglesProcessed = 0;
|
||||||
g_DupTrianglesProcessed = 0;
|
g_DupTrianglesProcessed = 0;
|
||||||
if (g_DupPrimitiveCheckCount == -1)
|
if (g_DupPrimitiveCheckCount == 0xffff)
|
||||||
{
|
{
|
||||||
memset(g_DupVertexList, 0, 0x5000);
|
memset(g_DupVertexList, 0, 0x5000);
|
||||||
memset(g_DupEdgeList, 0, 0xC000);
|
memset(g_DupEdgeList, 0, 0xC000);
|
||||||
|
|
|
@ -37,6 +37,30 @@ public:
|
||||||
CBooleanAABoxAreaCache(const zeus::CAABox& aabb, const CMaterialFilter& filter);
|
CBooleanAABoxAreaCache(const zeus::CAABox& aabb, const CMaterialFilter& filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CSphereAreaCache
|
||||||
|
{
|
||||||
|
friend class CMetroidAreaCollider;
|
||||||
|
const zeus::CAABox& x0_aabb;
|
||||||
|
const zeus::CSphere& x4_sphere;
|
||||||
|
const CMaterialFilter& x8_filter;
|
||||||
|
const CMaterialList& xc_material;
|
||||||
|
CCollisionInfoList& x10_collisionList;
|
||||||
|
public:
|
||||||
|
CSphereAreaCache(const zeus::CAABox& aabb, const zeus::CSphere& sphere, const CMaterialFilter& filter,
|
||||||
|
const CMaterialList& material, CCollisionInfoList& collisionList);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CBooleanSphereAreaCache
|
||||||
|
{
|
||||||
|
friend class CMetroidAreaCollider;
|
||||||
|
const zeus::CAABox& x0_aabb;
|
||||||
|
const zeus::CSphere& x4_sphere;
|
||||||
|
const CMaterialFilter& x8_filter;
|
||||||
|
public:
|
||||||
|
CBooleanSphereAreaCache(const zeus::CAABox& aabb, const zeus::CSphere& sphere,
|
||||||
|
const CMaterialFilter& filter);
|
||||||
|
};
|
||||||
|
|
||||||
struct SBoxEdge
|
struct SBoxEdge
|
||||||
{
|
{
|
||||||
zeus::CLineSeg x0_seg;
|
zeus::CLineSeg x0_seg;
|
||||||
|
@ -64,7 +88,7 @@ class CMetroidAreaCollider
|
||||||
static u32 g_RejectedByClip;
|
static u32 g_RejectedByClip;
|
||||||
static u32 g_TrianglesProcessed;
|
static u32 g_TrianglesProcessed;
|
||||||
static u32 g_DupTrianglesProcessed;
|
static u32 g_DupTrianglesProcessed;
|
||||||
static s16 g_DupPrimitiveCheckCount;
|
static u16 g_DupPrimitiveCheckCount;
|
||||||
static u16 g_DupVertexList[0x5000];
|
static u16 g_DupVertexList[0x5000];
|
||||||
static u16 g_DupEdgeList[0xC000];
|
static u16 g_DupEdgeList[0xC000];
|
||||||
static u16 g_DupTriangleList[0x4000];
|
static u16 g_DupTriangleList[0x4000];
|
||||||
|
@ -72,6 +96,12 @@ class CMetroidAreaCollider
|
||||||
const CBooleanAABoxAreaCache& cache);
|
const CBooleanAABoxAreaCache& cache);
|
||||||
static bool AABoxCollisionCheck_Internal(const CAreaOctTree::Node& node,
|
static bool AABoxCollisionCheck_Internal(const CAreaOctTree::Node& node,
|
||||||
const CAABoxAreaCache& cache);
|
const CAABoxAreaCache& cache);
|
||||||
|
|
||||||
|
static bool SphereCollisionCheckBoolean_Internal(const CAreaOctTree::Node& node,
|
||||||
|
const CBooleanSphereAreaCache& cache);
|
||||||
|
static bool SphereCollisionCheck_Internal(const CAreaOctTree::Node& node,
|
||||||
|
const CSphereAreaCache& cache);
|
||||||
|
|
||||||
static bool MovingAABoxCollisionCheck_BoxVertexTri(const CCollisionSurface& surf, const zeus::CAABox& aabb,
|
static bool MovingAABoxCollisionCheck_BoxVertexTri(const CCollisionSurface& surf, const zeus::CAABox& aabb,
|
||||||
const rstl::reserved_vector<u32, 8>& vertIndices,
|
const rstl::reserved_vector<u32, 8>& vertIndices,
|
||||||
const zeus::CVector3f& dir, double& d,
|
const zeus::CVector3f& dir, double& d,
|
||||||
|
@ -100,10 +130,12 @@ public:
|
||||||
CMetroidAreaCollider::COctreeLeafCache& cache);
|
CMetroidAreaCollider::COctreeLeafCache& cache);
|
||||||
static bool ConvexPolyCollision(const zeus::CPlane* planes, const zeus::CVector3f* verts,
|
static bool ConvexPolyCollision(const zeus::CPlane* planes, const zeus::CVector3f* verts,
|
||||||
zeus::CAABox& aabb);
|
zeus::CAABox& aabb);
|
||||||
|
|
||||||
static bool AABoxCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
static bool AABoxCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
||||||
const CMaterialFilter& filter);
|
const CMaterialFilter& filter);
|
||||||
static bool AABoxCollisionCheckBoolean(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
static bool AABoxCollisionCheckBoolean(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
||||||
const CMaterialFilter& filter);
|
const CMaterialFilter& filter);
|
||||||
|
|
||||||
static bool SphereCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
static bool SphereCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
||||||
const zeus::CSphere& sphere, const CMaterialFilter& filter);
|
const zeus::CSphere& sphere, const CMaterialFilter& filter);
|
||||||
static bool SphereCollisionCheckBoolean(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
static bool SphereCollisionCheckBoolean(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
||||||
|
@ -115,12 +147,14 @@ public:
|
||||||
static bool AABoxCollisionCheck(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
static bool AABoxCollisionCheck(const CAreaOctTree& octTree, const zeus::CAABox& aabb,
|
||||||
const CMaterialFilter& filter, const CMaterialList& matList,
|
const CMaterialFilter& filter, const CMaterialList& matList,
|
||||||
CCollisionInfoList& list);
|
CCollisionInfoList& list);
|
||||||
|
|
||||||
static bool SphereCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
static bool SphereCollisionCheck_Cached(const COctreeLeafCache& leafCache, 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 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,
|
static bool MovingAABoxCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb,
|
||||||
const CMaterialFilter& filter, const CMaterialList& matList,
|
const CMaterialFilter& filter, const CMaterialList& matList,
|
||||||
const zeus::CVector3f& dir, float mag, CCollisionInfo& infoOut,
|
const zeus::CVector3f& dir, float mag, CCollisionInfo& infoOut,
|
||||||
|
|
|
@ -212,9 +212,24 @@ u32 RayAABoxIntersection_Double(const zeus::CMRay& ray, const zeus::CAABox& aabb
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 RaySphereIntersection_Double(const zeus::CSphere&, const zeus::CVector3f &, const zeus::CVector3f &, double &)
|
bool RaySphereIntersection_Double(const zeus::CSphere& sphere, const zeus::CVector3f& pos,
|
||||||
|
const zeus::CVector3f& dir, double& T)
|
||||||
{
|
{
|
||||||
return 0;
|
zeus::CVector3d sPosD = sphere.position;
|
||||||
|
zeus::CVector3d posD = pos;
|
||||||
|
zeus::CVector3d sphereToPos = posD - sPosD;
|
||||||
|
double f30 = sphereToPos.dot(zeus::CVector3d(dir)) * 2.0;
|
||||||
|
double f1 = f30 * f30 - 4.0 * (sphereToPos.magSquared() - sphere.radius * sphere.radius);
|
||||||
|
if (f1 >= 0.0)
|
||||||
|
{
|
||||||
|
double intersectT = 0.5 * (-f30 - std::sqrt(f1));
|
||||||
|
if (T == 0 || intersectT < T)
|
||||||
|
{
|
||||||
|
T = intersectT;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RaySphereIntersection(const zeus::CSphere& sphere, const zeus::CVector3f& pos, const zeus::CVector3f& dir,
|
bool RaySphereIntersection(const zeus::CSphere& sphere, const zeus::CVector3f& pos, const zeus::CVector3f& dir,
|
||||||
|
@ -502,5 +517,264 @@ bool TriBoxOverlap(const zeus::CVector3f& boxcenter, const zeus::CVector3f& boxh
|
||||||
return true; /* box and triangle overlaps */
|
return true; /* box and triangle overlaps */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double TriPointSqrDist(const zeus::CVector3f& point,
|
||||||
|
const zeus::CVector3f& trivert0, const zeus::CVector3f& trivert1,
|
||||||
|
const zeus::CVector3f& trivert2, float* baryX, float* baryY)
|
||||||
|
{
|
||||||
|
zeus::CVector3d A = trivert0 - point;
|
||||||
|
zeus::CVector3d B = trivert1 - trivert0;
|
||||||
|
zeus::CVector3d C = trivert2 - trivert0;
|
||||||
|
|
||||||
|
double bMag = B.magSquared();
|
||||||
|
double cMag = C.magSquared();
|
||||||
|
double bDotC = B.dot(C);
|
||||||
|
double aDotB = A.dot(B);
|
||||||
|
double aDotC = A.dot(C);
|
||||||
|
double ret = A.magSquared();
|
||||||
|
|
||||||
|
double rej = std::fabs(bMag * cMag - bDotC * bDotC);
|
||||||
|
double retB = bDotC * aDotC - cMag * aDotB;
|
||||||
|
double retA = bDotC * aDotB - bMag * aDotC;
|
||||||
|
|
||||||
|
if (retB + retA <= rej)
|
||||||
|
{
|
||||||
|
if (retB < 0.0)
|
||||||
|
{
|
||||||
|
if (retA < 0.0)
|
||||||
|
{
|
||||||
|
if (aDotB < 0.0)
|
||||||
|
{
|
||||||
|
retA = 0.0;
|
||||||
|
if (-aDotB >= bMag)
|
||||||
|
{
|
||||||
|
retB = 1.0;
|
||||||
|
ret += 2.0 * aDotB + bMag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retB = -aDotB / bMag;
|
||||||
|
ret += aDotB * retB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retB = 0.0;
|
||||||
|
if (aDotC >= 0.0)
|
||||||
|
{
|
||||||
|
retA = 0.0;
|
||||||
|
}
|
||||||
|
else if (-aDotC >= cMag)
|
||||||
|
{
|
||||||
|
retA = 1.0;
|
||||||
|
ret += 2.0 * aDotC + cMag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retA = -aDotC / cMag;
|
||||||
|
ret += aDotC * retA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retB = 0.0;
|
||||||
|
if (aDotC >= 0.0)
|
||||||
|
{
|
||||||
|
retA = 0.0;
|
||||||
|
}
|
||||||
|
else if (-aDotC >= cMag)
|
||||||
|
{
|
||||||
|
retA = 1.0;
|
||||||
|
ret += 2.0 * aDotC + cMag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retA = -aDotC / cMag;
|
||||||
|
ret += aDotC * retA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (retA < 0.0)
|
||||||
|
{
|
||||||
|
retA = 0.0;
|
||||||
|
if (aDotB >= 0.0)
|
||||||
|
{
|
||||||
|
retB = 0.0;
|
||||||
|
}
|
||||||
|
else if (-aDotB >= bMag)
|
||||||
|
{
|
||||||
|
retB = 1.0;
|
||||||
|
ret += 2.0 * aDotB + bMag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retB = -aDotB / bMag;
|
||||||
|
ret += aDotB * retB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float f3 = 1.0 / rej;
|
||||||
|
retA *= f3;
|
||||||
|
retB *= f3;
|
||||||
|
ret += retB * (2.0 * aDotB + (bMag * retB + bDotC * retA)) +
|
||||||
|
retA * (2.0 * aDotC + (bDotC * retB + cMag * retA));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (retB < 0.0)
|
||||||
|
{
|
||||||
|
retB = bDotC + aDotB;
|
||||||
|
retA = cMag + aDotC;
|
||||||
|
if (retA > retB)
|
||||||
|
{
|
||||||
|
retA -= retB;
|
||||||
|
retB = bMag - 2.0 * bDotC;
|
||||||
|
retB += cMag;
|
||||||
|
if (retA >= retB)
|
||||||
|
{
|
||||||
|
retB = 1.0;
|
||||||
|
retA = 0.0;
|
||||||
|
ret += 2.0 * aDotB + bMag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retB = retA / retB;
|
||||||
|
retA = 1.0 - retB;
|
||||||
|
ret += retB * (2.0 * aDotB + (bMag * retB + bDotC * retA)) +
|
||||||
|
retA * (2.0 * aDotC + (bDotC * retB + cMag * retA));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retB = 0.0;
|
||||||
|
if (retA <= 0.0)
|
||||||
|
{
|
||||||
|
retA = 1.0;
|
||||||
|
ret += 2.0 * aDotC + cMag;
|
||||||
|
}
|
||||||
|
else if (aDotC >= 0.0)
|
||||||
|
{
|
||||||
|
retA = 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retA = -aDotC / cMag;
|
||||||
|
ret += aDotC * retA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (retA < 0.0)
|
||||||
|
{
|
||||||
|
retB = bDotC + aDotC;
|
||||||
|
retA = bMag + aDotB;
|
||||||
|
if (retA > retB)
|
||||||
|
{
|
||||||
|
retA -= retB;
|
||||||
|
retB = bMag - 2.0 * bDotC;
|
||||||
|
retB += cMag;
|
||||||
|
if (retA >= retB)
|
||||||
|
{
|
||||||
|
retA = 1.0;
|
||||||
|
retB = 0.0;
|
||||||
|
ret += 2.0 * aDotC + cMag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retA /= retB;
|
||||||
|
retB = 1.0 - retA;
|
||||||
|
ret += retB * (2.0 * aDotB + (bMag * retB + bDotC * retA)) +
|
||||||
|
retA * (2.0 * aDotC + (bDotC * retB + cMag * retA));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retA = 0.0;
|
||||||
|
if (retA <= 0.0)
|
||||||
|
{
|
||||||
|
retB = 1.0;
|
||||||
|
ret += 2.0 * aDotB + bMag;
|
||||||
|
}
|
||||||
|
else if (aDotB >= 0.0)
|
||||||
|
{
|
||||||
|
retB = 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retB = -aDotB / bMag;
|
||||||
|
ret += aDotB * retB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retB = cMag + aDotC;
|
||||||
|
retB -= bDotC;
|
||||||
|
retA = retB - aDotB;
|
||||||
|
if (retA <= 0.0)
|
||||||
|
{
|
||||||
|
retB = 0.0;
|
||||||
|
retA = 1.0;
|
||||||
|
ret += 2.0 * aDotC + cMag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retB = bMag - 2.0 * bDotC;
|
||||||
|
retB += cMag;
|
||||||
|
if (retA >= retB)
|
||||||
|
{
|
||||||
|
retB = 1.0;
|
||||||
|
retA = 0.0;
|
||||||
|
ret += 2.0 * aDotB + bMag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retB = retA / retB;
|
||||||
|
retA = 1.0 - retB;
|
||||||
|
ret += retB * (2.0 * aDotB + (bMag * retB + bDotC * retA)) +
|
||||||
|
retA * (2.0 * aDotC + (bDotC * retB + cMag * retA));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (baryX)
|
||||||
|
*baryX = retA;
|
||||||
|
if (baryY)
|
||||||
|
*baryY = retB;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TriSphereOverlap(const zeus::CSphere& sphere,
|
||||||
|
const zeus::CVector3f& trivert0, const zeus::CVector3f& trivert1,
|
||||||
|
const zeus::CVector3f& trivert2)
|
||||||
|
{
|
||||||
|
return TriPointSqrDist(sphere.position, trivert0, trivert1, trivert2, nullptr, nullptr) <=
|
||||||
|
sphere.radius * sphere.radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TriSphereIntersection(const zeus::CSphere& sphere,
|
||||||
|
const zeus::CVector3f& trivert0, const zeus::CVector3f& trivert1,
|
||||||
|
const zeus::CVector3f& trivert2, zeus::CVector3f& point, zeus::CVector3f& normal)
|
||||||
|
{
|
||||||
|
float baryX, baryY;
|
||||||
|
if (TriPointSqrDist(sphere.position, trivert0, trivert1, trivert2, &baryX, &baryY) >
|
||||||
|
sphere.radius * sphere.radius)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
zeus::CVector3f barys(baryX, baryY, 1.f - (baryX + baryY));
|
||||||
|
point = zeus::baryToWorld(trivert2, trivert1, trivert0, barys);
|
||||||
|
|
||||||
|
if (baryX == 0.f || baryX == 1.f || baryY == 0.f || baryY == 1.f ||
|
||||||
|
barys.z == 0.f || barys.z == 1.f)
|
||||||
|
normal = -sphere.getSurfaceNormal(point);
|
||||||
|
else
|
||||||
|
normal = (trivert1 - trivert0).cross(trivert2 - trivert0).normalized();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace CollisionUtil
|
||||||
bool LineIntersectsOBBox(const zeus::COBBox&, const zeus::CMRay&, float&);
|
bool LineIntersectsOBBox(const zeus::COBBox&, const zeus::CMRay&, float&);
|
||||||
u32 RayAABoxIntersection(const zeus::CMRay&, const zeus::CAABox&, zeus::CVector3f&, float&);
|
u32 RayAABoxIntersection(const zeus::CMRay&, const zeus::CAABox&, zeus::CVector3f&, float&);
|
||||||
u32 RayAABoxIntersection_Double(const zeus::CMRay&, const zeus::CAABox&, zeus::CVector3f&, double&);
|
u32 RayAABoxIntersection_Double(const zeus::CMRay&, const zeus::CAABox&, zeus::CVector3f&, double&);
|
||||||
u32 RaySphereIntersection_Double(const zeus::CSphere&, const zeus::CVector3f&, const zeus::CVector3f&, double&);
|
bool RaySphereIntersection_Double(const zeus::CSphere&, const zeus::CVector3f&, const zeus::CVector3f&, double&);
|
||||||
bool RaySphereIntersection(const zeus::CSphere& sphere, const zeus::CVector3f& pos, const zeus::CVector3f& dir,
|
bool RaySphereIntersection(const zeus::CSphere& sphere, const zeus::CVector3f& pos, const zeus::CVector3f& dir,
|
||||||
float mag, float& T, zeus::CVector3f& point);
|
float mag, float& T, zeus::CVector3f& point);
|
||||||
bool RayTriangleIntersection_Double(const zeus::CVector3f& point, const zeus::CVector3f& dir,
|
bool RayTriangleIntersection_Double(const zeus::CVector3f& point, const zeus::CVector3f& dir,
|
||||||
|
@ -27,6 +27,15 @@ bool AABoxAABoxIntersection(const zeus::CAABox& aabb0, const zeus::CAABox& aabb1
|
||||||
bool TriBoxOverlap(const zeus::CVector3f& boxcenter, const zeus::CVector3f& boxhalfsize,
|
bool TriBoxOverlap(const zeus::CVector3f& boxcenter, const zeus::CVector3f& boxhalfsize,
|
||||||
const zeus::CVector3f& trivert0, const zeus::CVector3f& trivert1,
|
const zeus::CVector3f& trivert0, const zeus::CVector3f& trivert1,
|
||||||
const zeus::CVector3f& trivert2);
|
const zeus::CVector3f& trivert2);
|
||||||
|
double TriPointSqrDist(const zeus::CVector3f& point,
|
||||||
|
const zeus::CVector3f& trivert0, const zeus::CVector3f& trivert1,
|
||||||
|
const zeus::CVector3f& trivert2, float* baryX, float* baryY);
|
||||||
|
bool TriSphereOverlap(const zeus::CSphere& sphere,
|
||||||
|
const zeus::CVector3f& trivert0, const zeus::CVector3f& trivert1,
|
||||||
|
const zeus::CVector3f& trivert2);
|
||||||
|
bool TriSphereIntersection(const zeus::CSphere& sphere,
|
||||||
|
const zeus::CVector3f& trivert0, const zeus::CVector3f& trivert1,
|
||||||
|
const zeus::CVector3f& trivert2, zeus::CVector3f& point, zeus::CVector3f& normal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // __URDE_COLLISIONUTIL_HPP__
|
#endif // __URDE_COLLISIONUTIL_HPP__
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace urde
|
||||||
CGuiModel::CGuiModel(const CGuiWidgetParms& parms, CSimplePool* sp, ResId modelId, u32 lightMask, bool flag)
|
CGuiModel::CGuiModel(const CGuiWidgetParms& parms, CSimplePool* sp, ResId modelId, u32 lightMask, bool flag)
|
||||||
: CGuiWidget(parms), x108_modelId(modelId), x10c_lightMask(lightMask)
|
: CGuiWidget(parms), x108_modelId(modelId), x10c_lightMask(lightMask)
|
||||||
{
|
{
|
||||||
if (!flag || (modelId & 0xffff) == 0xffff ||
|
if (!flag || modelId == 0xffffffff ||
|
||||||
parms.x0_frame->GetGuiSys().GetUsageMode() == CGuiSys::EUsageMode::Two)
|
parms.x0_frame->GetGuiSys().GetUsageMode() == CGuiSys::EUsageMode::Two)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@ void CGuiTextSupport::CheckAndRebuildTextBuffer()
|
||||||
g_TextExecuteBuf->AddColor(EColorType::Outline, x28_outlineColor);
|
g_TextExecuteBuf->AddColor(EColorType::Outline, x28_outlineColor);
|
||||||
|
|
||||||
std::u16string initStr;
|
std::u16string initStr;
|
||||||
if ((x5c_fontId & 0xffff) != 0xffff)
|
if (x5c_fontId != 0xffffffff)
|
||||||
initStr = hecl::Char16Format(L"&font=%08X;", u32(x5c_fontId));
|
initStr = hecl::Char16Format(L"&font=%08X;", u32(x5c_fontId));
|
||||||
initStr += x0_string;
|
initStr += x0_string;
|
||||||
|
|
||||||
|
|
2
specter
2
specter
|
@ -1 +1 @@
|
||||||
Subproject commit 9ebeb21ade732a0f03542c4507e1d9a3f4040b23
|
Subproject commit 79b00ed327c88c80bece7f7b58e1fc8d02ab52e1
|
Loading…
Reference in New Issue