mirror of https://github.com/AxioDL/metaforce.git
FONT serialization fix; implement CPathFindSpline functions
This commit is contained in:
parent
d8eb8abc48
commit
48c285be11
|
@ -14,7 +14,7 @@ struct GlyphRect : BigDNA
|
|||
Value<float> right;
|
||||
Value<float> bottom;
|
||||
};
|
||||
struct IGlyph : BigDNAV
|
||||
struct IGlyph : BigDNAVYaml
|
||||
{
|
||||
AT_DECL_DNA_YAML
|
||||
Value<atUint16> m_character;
|
||||
|
|
|
@ -18,7 +18,7 @@ set(WORLD_SOURCES
|
|||
CPathFindArea.hpp CPathFindArea.cpp
|
||||
CPathFindRegion.hpp CPathFindRegion.cpp
|
||||
CPathFindSearch.hpp CPathFindSearch.cpp
|
||||
CPathFindSpline.hpp CPathFindSpline.cpp
|
||||
CPathFindSpline.cpp
|
||||
CPathFindDraw.hpp CPathFindDraw.cpp
|
||||
CPhysicsActor.hpp CPhysicsActor.cpp
|
||||
CEntity.hpp CEntity.cpp
|
||||
|
|
|
@ -44,12 +44,63 @@ CPathFindSearch::FindClosestReachablePoint(const zeus::CVector3f& p1, zeus::CVec
|
|||
return EResult::Success;
|
||||
}
|
||||
|
||||
CPathFindSearch::EResult CPathFindSearch::PathExists(const zeus::CVector3f& p1, const zeus::CVector3f& p2) const
|
||||
{
|
||||
if (!x0_area)
|
||||
return EResult::InvalidArea;
|
||||
|
||||
/* Work in local PFArea coordinates */
|
||||
zeus::CVector3f localP1 = x0_area->x188_transform.transposeRotate(p1 - x0_area->x188_transform.origin);
|
||||
zeus::CVector3f localP2 = x0_area->x188_transform.transposeRotate(p2 - x0_area->x188_transform.origin);
|
||||
|
||||
/* Raise a bit above ground for step-up resolution */
|
||||
if (!(xdc_flags & 0x2) && !(xdc_flags & 0x4))
|
||||
{
|
||||
localP2.z += 0.3f;
|
||||
localP1.z += 0.3f;
|
||||
}
|
||||
|
||||
rstl::reserved_vector<CPFRegion*, 4> regions1;
|
||||
if (x0_area->FindRegions(regions1, localP1, xdc_flags, xe0_indexMask) == 0)
|
||||
return EResult::NoSourcePoint;
|
||||
|
||||
rstl::reserved_vector<CPFRegion*, 4> regions2;
|
||||
if (x0_area->FindRegions(regions2, localP2, xdc_flags, xe0_indexMask) == 0)
|
||||
return EResult::NoDestPoint;
|
||||
|
||||
for (CPFRegion* reg1 : regions1)
|
||||
for (CPFRegion* reg2 : regions2)
|
||||
if (reg1 == reg2 || x0_area->PathExists(reg1, reg2, xdc_flags))
|
||||
return EResult::Success;
|
||||
|
||||
return EResult::NoPath;
|
||||
}
|
||||
|
||||
CPathFindSearch::EResult CPathFindSearch::OnPath(const zeus::CVector3f& p1) const
|
||||
{
|
||||
if (!x0_area)
|
||||
return EResult::InvalidArea;
|
||||
|
||||
/* Work in local PFArea coordinates */
|
||||
zeus::CVector3f localP1 = x0_area->x188_transform.transposeRotate(p1 - x0_area->x188_transform.origin);
|
||||
|
||||
/* Raise a bit above ground for step-up resolution */
|
||||
if (!(xdc_flags & 0x2) && !(xdc_flags & 0x4))
|
||||
localP1.z += 0.3f;
|
||||
|
||||
rstl::reserved_vector<CPFRegion*, 4> regions1;
|
||||
if (x0_area->FindRegions(regions1, localP1, xdc_flags, xe0_indexMask) == 0)
|
||||
return EResult::NoSourcePoint;
|
||||
|
||||
return EResult::Success;
|
||||
}
|
||||
|
||||
CPathFindSearch::EResult CPathFindSearch::Search(const zeus::CVector3f& p1, const zeus::CVector3f& p2)
|
||||
{
|
||||
u32 firstPoint = 0;
|
||||
u32 flyToOutsidePoint = 0;
|
||||
x4_waypoints.clear();
|
||||
xc8_ = 0;
|
||||
xc8_curWaypoint = 0;
|
||||
|
||||
if (!x0_area || x0_area->x150_regions.size() > 512)
|
||||
{
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
private:
|
||||
CPFArea* x0_area;
|
||||
rstl::reserved_vector<zeus::CVector3f, 16> x4_waypoints;
|
||||
u32 xc8_ = 0;
|
||||
u32 xc8_curWaypoint = 0;
|
||||
EResult xcc_result;
|
||||
float xd0_chHeight;
|
||||
float xd4_chRadius;
|
||||
|
@ -30,10 +30,18 @@ private:
|
|||
u32 xe0_indexMask;
|
||||
bool Search(rstl::reserved_vector<CPFRegion*, 4>& regs1, const zeus::CVector3f& p1,
|
||||
rstl::reserved_vector<CPFRegion*, 4>& regs2, const zeus::CVector3f& p2);
|
||||
void GetSplinePoint(zeus::CVector3f& pOut, const zeus::CVector3f& p1, u32 wpIdx) const;
|
||||
void GetSplinePointWithLookahead(zeus::CVector3f& pOut, const zeus::CVector3f& p1,
|
||||
u32 wpIdx, float lookahead) const;
|
||||
public:
|
||||
CPathFindSearch(CPFArea* area, u32 flags, u32 index, float chRadius, float chHeight);
|
||||
EResult Search(const zeus::CVector3f& p1, const zeus::CVector3f& p2);
|
||||
EResult FindClosestReachablePoint(const zeus::CVector3f& p1, zeus::CVector3f& p2) const;
|
||||
EResult PathExists(const zeus::CVector3f& p1, const zeus::CVector3f& p2) const;
|
||||
EResult OnPath(const zeus::CVector3f& p1) const;
|
||||
bool SegmentOver(const zeus::CVector3f& p1) const;
|
||||
void GetSplinePoint(zeus::CVector3f& pOut, const zeus::CVector3f& p1) const;
|
||||
void GetSplinePointWithLookahead(zeus::CVector3f& pOut, const zeus::CVector3f& p1, float lookahead) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
#include "CPathFindSearch.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
bool CPathFindSearch::SegmentOver(const zeus::CVector3f& p1) const
|
||||
{
|
||||
if (x4_waypoints.size() > 1 && xc8_curWaypoint < x4_waypoints.size() - 1)
|
||||
{
|
||||
const zeus::CVector3f& wp0 = x4_waypoints[xc8_curWaypoint];
|
||||
const zeus::CVector3f& wp1 = x4_waypoints[xc8_curWaypoint + 1];
|
||||
const zeus::CVector3f& wp2 = x4_waypoints[std::min(u32(x4_waypoints.size()) - 1, xc8_curWaypoint + 2)];
|
||||
return (p1 - wp1).dot(wp2 - wp0) >= 0.f;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPathFindSearch::GetSplinePoint(zeus::CVector3f& pOut, const zeus::CVector3f& p1, u32 wpIdx) const
|
||||
{
|
||||
if (x4_waypoints.size() > 1 && wpIdx < x4_waypoints.size() - 1)
|
||||
{
|
||||
zeus::CVector3f a = (wpIdx == 0) ? x4_waypoints[0] * 2.f - x4_waypoints[1] : x4_waypoints[wpIdx-1];
|
||||
const zeus::CVector3f& b = x4_waypoints[wpIdx];
|
||||
const zeus::CVector3f& c = x4_waypoints[wpIdx+1];
|
||||
zeus::CVector3f d = (wpIdx + 2 >= x4_waypoints.size()) ?
|
||||
x4_waypoints[x4_waypoints.size()-1] * 2.f - x4_waypoints[x4_waypoints.size()-2] : x4_waypoints[wpIdx+2];
|
||||
zeus::CVector3f delta = c - b;
|
||||
if (delta.isMagnitudeSafe())
|
||||
pOut = zeus::getCatmullRomSplinePoint(a, b, c, d, (p1 - b).dot(delta) / delta.magSquared());
|
||||
else
|
||||
pOut = b;
|
||||
}
|
||||
}
|
||||
|
||||
void CPathFindSearch::GetSplinePoint(zeus::CVector3f& pOut, const zeus::CVector3f& p1) const
|
||||
{
|
||||
GetSplinePoint(pOut, p1, xc8_curWaypoint);
|
||||
}
|
||||
|
||||
void CPathFindSearch::GetSplinePointWithLookahead(zeus::CVector3f& pOut, const zeus::CVector3f& p1,
|
||||
u32 wpIdx, float lookahead) const
|
||||
{
|
||||
if (x4_waypoints.size() > 1 && wpIdx < x4_waypoints.size() - 1)
|
||||
{
|
||||
const zeus::CVector3f& wp0 = x4_waypoints[wpIdx];
|
||||
const zeus::CVector3f& wp1 = x4_waypoints[wpIdx+1];
|
||||
zeus::CVector3f delta = wp1 - wp0;
|
||||
if (delta.isMagnitudeSafe())
|
||||
{
|
||||
float deltaMag = delta.magnitude();
|
||||
delta = delta * (1.f / deltaMag);
|
||||
float bToPtProj = (p1 - wp0).dot(delta);
|
||||
if (bToPtProj + lookahead <= deltaMag)
|
||||
GetSplinePoint(pOut, delta * lookahead + p1, wpIdx);
|
||||
else if (wpIdx < x4_waypoints.size() - 2)
|
||||
GetSplinePointWithLookahead(pOut, wp1, wpIdx + 1, lookahead - (deltaMag - bToPtProj));
|
||||
else
|
||||
pOut = delta * (lookahead - (deltaMag - bToPtProj)) + wp1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pOut = wp1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPathFindSearch::GetSplinePointWithLookahead(zeus::CVector3f& pOut, const zeus::CVector3f& p1,
|
||||
float lookahead) const
|
||||
{
|
||||
GetSplinePointWithLookahead(pOut, p1, xc8_curWaypoint, lookahead);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#ifndef __URDE_CPATHFINDSPLINE_HPP__
|
||||
#define __URDE_CPATHFINDSPLINE_HPP__
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
class CPathFindSpline
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __URDE_CPATHFINDSPLINE_HPP__
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit fabd0ee3caa9d8362d23ffac418556fbb949efba
|
||||
Subproject commit 7e911dc13b1e8075d056f63720139fd7c6cd7496
|
2
specter
2
specter
|
@ -1 +1 @@
|
|||
Subproject commit c6069bbf540ebe2ca1f1f112c33e5a169214f18d
|
||||
Subproject commit 8ff49e190761583b120b0510b0de3dda13fd68c0
|
Loading…
Reference in New Issue