2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-09 12:27:43 +00:00

Finish pathfinding implementations

This commit is contained in:
Jack Andersen
2018-03-02 19:49:13 -10:00
parent 2018ef17d2
commit cb2988c9a4
6 changed files with 562 additions and 129 deletions

View File

@@ -33,6 +33,11 @@ CPFRegion::CPFRegion(CMemoryInStream& in)
x4c_regionData = reinterpret_cast<CPFRegionData*>(in.readUint32Big());
}
const CPFLink* CPFRegion::GetPathLink() const
{
return &xc_startLink[x4c_regionData->GetPathLink()];
}
void CPFRegion::Fixup(CPFArea& area, u32& maxRegionNodes)
{
if (x0_numNodes)
@@ -48,6 +53,24 @@ void CPFRegion::Fixup(CPFArea& area, u32& maxRegionNodes)
maxRegionNodes = x0_numNodes;
}
bool CPFRegion::IsPointInside(const zeus::CVector3f& point) const
{
if (!x34_aabb.pointInside(point))
return false;
int i;
for (i=0 ; i<x0_numNodes ; ++i)
{
CPFNode& node = x4_startNode[i];
if ((point - node.GetPos()).dot(node.GetNormal()) < 0.f)
break;
}
zeus::CVector3f nodeToPoint = point - x4_startNode->GetPos();
if (i == x0_numNodes && nodeToPoint.dot(x18_normal) >= 0.f)
if ((nodeToPoint - x14_height * zeus::CVector3f::skUp).dot(x18_normal) <= 0.f)
return true;
return false;
}
float CPFRegion::PointHeight(const zeus::CVector3f& point) const
{
return (point - x4_startNode->GetPos()).dot(x18_normal);
@@ -170,14 +193,38 @@ bool CPFRegion::FindBestPoint(std::vector<zeus::CVector3f>& polyPoints, const ze
return found;
}
void CPFRegion::SetLinkTo(s32 idx)
{
if (x8_numLinks <= 0)
return;
for (s32 i=0 ; i<x8_numLinks ; ++i)
if (xc_startLink[i].GetRegion() == idx)
{
Data()->SetPathLink(i);
return;
}
}
void CPFRegion::DropToGround(zeus::CVector3f& point) const
{
point.z -= (point - x4_startNode->GetPos()).dot(x18_normal) / x18_normal.z;
}
zeus::CVector3f CPFRegion::GetLinkMidPoint(const CPFLink& link) const
{
const CPFNode& node = x4_startNode[link.GetNode()];
const CPFNode& nextNode = x4_startNode[(link.GetNode() + 1) % x0_numNodes];
return (node.GetPos() + nextNode.GetPos()) * 0.5f;
}
zeus::CVector3f CPFRegion::FitThroughLink2d(const zeus::CVector3f& p1, const CPFLink& link,
const zeus::CVector3f& p2, float f1) const
const zeus::CVector3f& p2, float chRadius) const
{
CPFNode& node = x4_startNode[link.GetNode()];
CPFNode& nextNode = x4_startNode[(link.GetNode() + 1) % x0_numNodes];
zeus::CVector3f nodeDelta = nextNode.GetPos() - node.GetPos();
float t = 0.5f;
if (f1 < 0.5f * link.Get2dWidth())
if (chRadius < 0.5f * link.Get2dWidth())
{
zeus::CVector2f delta2d(nodeDelta.x, nodeDelta.y);
delta2d *= link.GetOO2dWidth();
@@ -189,13 +236,15 @@ zeus::CVector3f CPFRegion::FitThroughLink2d(const zeus::CVector3f& p1, const CPF
float f1b = delta2d.dot(zeus::CVector2f(nodeToP2.y, nodeToP2.y));
float f3 = f27 + f26;
if (f3 > FLT_EPSILON)
t = zeus::clamp(f1, 1.f / f3 * (f26 * f31 + f27 * f1b), link.Get2dWidth() - f1) * link.GetOO2dWidth();
t = zeus::clamp(chRadius, 1.f / f3 * (f26 * f31 + f27 * f1b), link.Get2dWidth() - chRadius) *
link.GetOO2dWidth();
}
return nodeDelta * t + node.GetPos();
}
zeus::CVector3f CPFRegion::FitThroughLink3d(const zeus::CVector3f& p1, const CPFLink& link,
float f1, const zeus::CVector3f& p2, float f2, float f3) const
float regionHeight, const zeus::CVector3f& p2,
float chRadius, float chHalfHeight) const
{
CPFNode& node = x4_startNode[link.GetNode()];
CPFNode& nextNode = x4_startNode[(link.GetNode() + 1) % x0_numNodes];
@@ -204,7 +253,7 @@ zeus::CVector3f CPFRegion::FitThroughLink3d(const zeus::CVector3f& p1, const CPF
float f24 = (node.GetPos() - p2).dot(node.GetNormal());
float f23 = f25 + f24;
# if 0
if (f2 < 0.5f * link.Get2dWidth())
if (chRadius < 0.5f * link.Get2dWidth())
{
zeus::CVector2f delta2d(nodeDelta.x, nodeDelta.y);
delta2d *= link.GetOO2dWidth();
@@ -214,19 +263,20 @@ zeus::CVector3f CPFRegion::FitThroughLink3d(const zeus::CVector3f& p1, const CPF
float f1b = delta2d.dot(zeus::CVector2f(nodeToP2.y, nodeToP2.y));
if (f23 > FLT_EPSILON)
{
zeus::clamp(f2, 1.f / f23 * f24 * f29 + f25 * f1b, link.Get2dWidth() - f2) * link.GetOO2dWidth();
zeus::clamp(chRadius, 1.f / f23 * f24 * f29 + f25 * f1b, link.Get2dWidth() - chRadius) *
link.GetOO2dWidth();
}
}
#endif
zeus::CVector3f midPoint = nodeDelta * 0.5f + node.GetPos();
float z;
if (f3 < 0.5f * f1)
if (chHalfHeight < 0.5f * regionHeight)
{
float minZ = f3 + midPoint.z;
float minZ = chHalfHeight + midPoint.z;
z = 0.5f * (p1.z + p2.z);
if (f23 > FLT_EPSILON)
z = 1.f / f23 * (f24 * p1.z + f25 * p2.z);
z = zeus::clamp(minZ, z, f1 + midPoint.z - f3);
z = zeus::clamp(minZ, z, regionHeight + midPoint.z - chHalfHeight);
}
else
{