FONT serialization fix; implement CPathFindSpline functions

This commit is contained in:
Jack Andersen 2018-03-03 18:25:57 -10:00
parent d8eb8abc48
commit 48c285be11
8 changed files with 138 additions and 20 deletions

View File

@ -14,7 +14,7 @@ struct GlyphRect : BigDNA
Value<float> right; Value<float> right;
Value<float> bottom; Value<float> bottom;
}; };
struct IGlyph : BigDNAV struct IGlyph : BigDNAVYaml
{ {
AT_DECL_DNA_YAML AT_DECL_DNA_YAML
Value<atUint16> m_character; Value<atUint16> m_character;

View File

@ -18,7 +18,7 @@ set(WORLD_SOURCES
CPathFindArea.hpp CPathFindArea.cpp CPathFindArea.hpp CPathFindArea.cpp
CPathFindRegion.hpp CPathFindRegion.cpp CPathFindRegion.hpp CPathFindRegion.cpp
CPathFindSearch.hpp CPathFindSearch.cpp CPathFindSearch.hpp CPathFindSearch.cpp
CPathFindSpline.hpp CPathFindSpline.cpp CPathFindSpline.cpp
CPathFindDraw.hpp CPathFindDraw.cpp CPathFindDraw.hpp CPathFindDraw.cpp
CPhysicsActor.hpp CPhysicsActor.cpp CPhysicsActor.hpp CPhysicsActor.cpp
CEntity.hpp CEntity.cpp CEntity.hpp CEntity.cpp

View File

@ -44,12 +44,63 @@ CPathFindSearch::FindClosestReachablePoint(const zeus::CVector3f& p1, zeus::CVec
return EResult::Success; 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) CPathFindSearch::EResult CPathFindSearch::Search(const zeus::CVector3f& p1, const zeus::CVector3f& p2)
{ {
u32 firstPoint = 0; u32 firstPoint = 0;
u32 flyToOutsidePoint = 0; u32 flyToOutsidePoint = 0;
x4_waypoints.clear(); x4_waypoints.clear();
xc8_ = 0; xc8_curWaypoint = 0;
if (!x0_area || x0_area->x150_regions.size() > 512) if (!x0_area || x0_area->x150_regions.size() > 512)
{ {

View File

@ -21,7 +21,7 @@ public:
private: private:
CPFArea* x0_area; CPFArea* x0_area;
rstl::reserved_vector<zeus::CVector3f, 16> x4_waypoints; rstl::reserved_vector<zeus::CVector3f, 16> x4_waypoints;
u32 xc8_ = 0; u32 xc8_curWaypoint = 0;
EResult xcc_result; EResult xcc_result;
float xd0_chHeight; float xd0_chHeight;
float xd4_chRadius; float xd4_chRadius;
@ -30,10 +30,18 @@ private:
u32 xe0_indexMask; u32 xe0_indexMask;
bool Search(rstl::reserved_vector<CPFRegion*, 4>& regs1, const zeus::CVector3f& p1, bool Search(rstl::reserved_vector<CPFRegion*, 4>& regs1, const zeus::CVector3f& p1,
rstl::reserved_vector<CPFRegion*, 4>& regs2, const zeus::CVector3f& p2); 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: public:
CPathFindSearch(CPFArea* area, u32 flags, u32 index, float chRadius, float chHeight); CPathFindSearch(CPFArea* area, u32 flags, u32 index, float chRadius, float chHeight);
EResult Search(const zeus::CVector3f& p1, const zeus::CVector3f& p2); EResult Search(const zeus::CVector3f& p1, const zeus::CVector3f& p2);
EResult FindClosestReachablePoint(const zeus::CVector3f& p1, zeus::CVector3f& p2) const; 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;
}; };
} }

View File

@ -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);
}
}

View File

@ -1,14 +0,0 @@
#ifndef __URDE_CPATHFINDSPLINE_HPP__
#define __URDE_CPATHFINDSPLINE_HPP__
namespace urde
{
class CPathFindSpline
{
};
}
#endif // __URDE_CPATHFINDSPLINE_HPP__

2
hecl

@ -1 +1 @@
Subproject commit fabd0ee3caa9d8362d23ffac418556fbb949efba Subproject commit 7e911dc13b1e8075d056f63720139fd7c6cd7496

@ -1 +1 @@
Subproject commit c6069bbf540ebe2ca1f1f112c33e5a169214f18d Subproject commit 8ff49e190761583b120b0510b0de3dda13fd68c0