Fixed CMayaSpline source files not compiling

This commit is contained in:
Aruki 2019-06-18 12:10:04 -07:00
parent ca40d34739
commit cd7937f73c
2 changed files with 70 additions and 67 deletions

View File

@ -1,29 +1,29 @@
#include "CMayaSpline.h" #include "CMayaSpline.h"
#include <Math/MathUtil.h> #include <Common/Math/MathUtil.h>
void ValidateTangent(CVector2f& rTangent) void ValidateTangent(CVector2f& Tangent)
{ {
if (rTangent.X < 0.f) rTangent.X = 0.f; if (Tangent.X < 0.f) Tangent.X = 0.f;
rTangent = rTangent.Normalized(); Tangent = Tangent.Normalized();
if (rTangent.X == 0.f && rTangent.Y != 0.f) if (Tangent.X == 0.f && Tangent.Y != 0.f)
{ {
float Mul = (rTangent.Y >= 0.f ? 1.f : -1.f); float Mul = (Tangent.Y >= 0.f ? 1.f : -1.f);
rTangent.X = 0.0001f; Tangent.X = 0.0001f;
rTangent.Y = 5729578 * rTangent.X * Mul; // not sure where that number comes from! Tangent.Y = 5729578 * Tangent.X * Mul; // not sure where that number comes from!
} }
} }
void CMayaSplineKnot::GetTangents(const CMayaSplineKnot *pkPrev, const CMayaSplineKnot *pkNext, CVector2f& rOutTangentA, CVector2f& rOutTangentB) const void CMayaSplineKnot::GetTangents(const CMayaSplineKnot* pkPrev, const CMayaSplineKnot* pkNext, CVector2f& OutTangentA, CVector2f& OutTangentB) const
{ {
if (Flags & 0x8000) if (Flags & 0x8000)
CalculateTangents(pkPrev, pkNext); CalculateTangents(pkPrev, pkNext);
rOutTangentA = CachedTangentA; OutTangentA = CachedTangentA;
rOutTangentB = CachedTangentB; OutTangentB = CachedTangentB;
} }
void CMayaSplineKnot::CalculateTangents(const CMayaSplineKnot *pkPrev, const CMayaSplineKnot *pkNext) const void CMayaSplineKnot::CalculateTangents(const CMayaSplineKnot* pkPrev, const CMayaSplineKnot* pkNext) const
{ {
// todo: this function is incomplete // todo: this function is incomplete
Flags &= ~0x8000; Flags &= ~0x8000;
@ -40,14 +40,14 @@ void CMayaSplineKnot::CalculateTangents(const CMayaSplineKnot *pkPrev, const CMa
} }
} }
u32 TopFlagByte = (Flags >> 24) & 0xFF; uint32 TopFlagByte = (Flags >> 24) & 0xFF;
if (TopFlagByte == 0) if (TopFlagByte == 0)
{ {
} }
} }
u32 CMayaSpline::GetKnotCount() const uint CMayaSpline::GetKnotCount() const
{ {
return mKnots.size(); return mKnots.size();
} }
@ -78,18 +78,13 @@ float CMayaSpline::EvaluateAt(float Time) const
float Amplitude = EvaluateAtUnclamped(Time); float Amplitude = EvaluateAtUnclamped(Time);
if (mClampMode == 0) if (mClampMode == 0)
return Amplitude;
else if (mClampMode == 1)
{ {
if (Amplitude < mMinAmplitude)
Amplitude = mMinAmplitude;
else if (Amplitude > mMaxAmplitude)
Amplitude = mMaxAmplitude;
return Amplitude; return Amplitude;
} }
else if (mClampMode == 1)
{
return Math::Clamp(mMinAmplitude, mMaxAmplitude, Amplitude);
}
else if (mClampMode == 2) else if (mClampMode == 2)
{ {
if (mMaxAmplitude <= mMinAmplitude) if (mMaxAmplitude <= mMinAmplitude)
@ -98,8 +93,10 @@ float CMayaSpline::EvaluateAt(float Time) const
// todo // todo
return 0.f; return 0.f;
} }
else
else return 0.f; {
return 0.f;
}
} }
float CMayaSpline::EvaluateAtUnclamped(float Time) const float CMayaSpline::EvaluateAtUnclamped(float Time) const
@ -247,21 +244,21 @@ float CMayaSpline::EvaluateHermite(float Time) const
return f1; return f1;
} }
bool CMayaSpline::FindKnot(float Time, int& rOutKnotIndex) const bool CMayaSpline::FindKnot(float Time, int& OutKnotIndex) const
{ {
// Stores the index of the closest knot to Time (without going over). // Stores the index of the closest knot to Time (without going over).
// Returns whether or not the knot found was an exact match. // Returns whether or not the knot found was an exact match.
rOutKnotIndex = 0; OutKnotIndex = 0;
if (mKnots.empty()) if (mKnots.empty())
return false; return false;
u32 Lower = 0; uint Lower = 0;
u32 Upper = mKnots.size(); uint Upper = mKnots.size();
while (Lower < Upper) while (Lower < Upper)
{ {
u32 Index = (Lower + Upper) >> 1; uint Index = (Lower + Upper) >> 1;
if (mKnots[Index].Time > Time) if (mKnots[Index].Time > Time)
Lower = Index + 1; Lower = Index + 1;
@ -270,58 +267,60 @@ bool CMayaSpline::FindKnot(float Time, int& rOutKnotIndex) const
else else
{ {
rOutKnotIndex = Index; OutKnotIndex = Index;
return true; return true;
} }
} }
rOutKnotIndex = Lower; OutKnotIndex = Lower;
return false; return false;
} }
void CMayaSpline::FindControlPoints(int KnotIdx, std::vector<CVector2f>& rOut) const void CMayaSpline::FindControlPoints(int KnotIdx, std::vector<CVector2f>& Out) const
{ {
const CMayaSplineKnot *pkKnot = &mKnots[KnotIdx]; const CMayaSplineKnot* pkKnot = &mKnots[KnotIdx];
CVector2f KnotPos(pkKnot->Time, pkKnot->Amplitude); CVector2f KnotPos(pkKnot->Time, pkKnot->Amplitude);
rOut.push_back(KnotPos); Out.push_back(KnotPos);
CVector2f TangentA(0,0), TangentB(0,0); CVector2f TangentA(0,0), TangentB(0,0);
const CMayaSplineKnot *pkNext = (KnotIdx < (s32) mKnots.size() ? &mKnots[KnotIdx + 1] : nullptr); const CMayaSplineKnot* pkNext = (KnotIdx < mKnots.size() ? &mKnots[KnotIdx + 1] : nullptr);
const CMayaSplineKnot *pkPrev = (KnotIdx > 0 ? &mKnots[KnotIdx - 1] : nullptr); const CMayaSplineKnot* pkPrev = (KnotIdx > 0 ? &mKnots[KnotIdx - 1] : nullptr);
pkKnot->GetTangents(pkPrev, pkNext, TangentA, TangentB); pkKnot->GetTangents(pkPrev, pkNext, TangentA, TangentB);
rOut.push_back(KnotPos + (TangentB * 0.333333f)); Out.push_back(KnotPos + (TangentB * 0.333333f));
// The game doesn't check whether the next knot exists before executing this code, not sure why... // The game doesn't check whether the next knot exists before executing this code, not sure why...
KnotIdx++; KnotIdx++;
pkKnot = pkNext; pkKnot = pkNext;
KnotPos = CVector2f(pkNext->Time, pkNext->Amplitude); KnotPos = CVector2f(pkNext->Time, pkNext->Amplitude);
pkNext = (KnotIdx < (s32) mKnots.size() ? &mKnots[KnotIdx + 1] : nullptr); pkNext = (KnotIdx < mKnots.size() ? &mKnots[KnotIdx + 1] : nullptr);
pkPrev = (KnotIdx > 0 ? &mKnots[KnotIdx - 1] : nullptr); pkPrev = (KnotIdx > 0 ? &mKnots[KnotIdx - 1] : nullptr);
pkKnot->GetTangents(pkPrev, pkNext, TangentA, TangentB); pkKnot->GetTangents(pkPrev, pkNext, TangentA, TangentB);
rOut.push_back(KnotPos - (TangentA * 0.333333f)); Out.push_back(KnotPos - (TangentA * 0.333333f));
rOut.push_back(KnotPos); Out.push_back(KnotPos);
} }
void CMayaSpline::CalculateHermiteCoefficients(const std::vector<CVector2f>& rkControlPoints, float *pOutCoefs) const void CMayaSpline::CalculateHermiteCoefficients(const std::vector<CVector2f>& kControlPoints, float* pOutCoefs) const
{ {
// rkControlPoints should contain 4 elements. // rkControlPoints should contain 4 elements.
const CVector2f& rkKnotA = rkControlPoints[0]; const CVector2f& kKnotA = kControlPoints[0];
const CVector2f& rkTangentA = rkControlPoints[1]; const CVector2f& kTangentA = kControlPoints[1];
const CVector2f& rkTangentB = rkControlPoints[2]; const CVector2f& kTangentB = kControlPoints[2];
const CVector2f& rkKnotB = rkControlPoints[3]; const CVector2f& kKnotB = kControlPoints[3];
CVector2f Range = rkKnotB - rkKnotA; CVector2f Range = kKnotB - kKnotA;
CVector2f KnotAToTangentA = rkTangentA - rkKnotA; CVector2f KnotAToTangentA = kTangentA - kKnotA;
float MulA = (KnotAToTangentA.X == 0 ? 5729578.f : KnotAToTangentA.Y / KnotAToTangentA.X); float MulA = (KnotAToTangentA.X == 0 ? 5729578.f : KnotAToTangentA.Y / KnotAToTangentA.X);
CVector2f KnotBToTangentB = rkKnotB - rkTangentB; CVector2f KnotBToTangentB = kKnotB - kTangentB;
float MulB = (KnotBToTangentB.X == 0 ? 5729578.f : KnotBToTangentB.Y / KnotBToTangentB.X); float MulB = (KnotBToTangentB.X == 0 ? 5729578.f : KnotBToTangentB.Y / KnotBToTangentB.X);
#if 0
// todo: better organization and better variable names // todo: better organization and better variable names
// also this doesn't actually compile, oops! will need to be re-reverse engineered
float f3 = Range.X * Range.X; float f3 = Range.X * Range.X;
float f1 = 1.0f; float f1 = 1.0f;
float f0 = Range.Y * 2; float f0 = Range.Y * 2;
@ -341,6 +340,10 @@ void CMayaSpline::CalculateHermiteCoefficients(const std::vector<CVector2f>& rkC
pOutCoefs[0] = f1; pOutCoefs[0] = f1;
pOutCoefs[1] = f0; pOutCoefs[1] = f0;
#else
pOutCoefs[0] = 0.0f;
pOutCoefs[1] = 0.0f;
#endif
pOutCoefs[2] = MulA; pOutCoefs[2] = MulA;
pOutCoefs[3] = rkKnotA.Y; pOutCoefs[3] = kKnotA.Y;
} }

View File

@ -1,8 +1,8 @@
#ifndef CMAYASPLINE_H #ifndef CMAYASPLINE_H
#define CMAYASPLINE_H #define CMAYASPLINE_H
#include <Common/types.h> #include <Common/Common.h>
#include <Math/CVector2f.h> #include <Common/Math/CVector2f.h>
#include <vector> #include <vector>
// These classes based off Metroid Prime 2's CMayaSpline implementation // These classes based off Metroid Prime 2's CMayaSpline implementation
@ -12,33 +12,33 @@ public:
float Time; float Time;
float Amplitude; float Amplitude;
mutable u32 Flags; mutable uint32 Flags;
mutable CVector2f CachedTangentA; mutable CVector2f CachedTangentA;
mutable CVector2f CachedTangentB; mutable CVector2f CachedTangentB;
void GetTangents(const CMayaSplineKnot *pkPrev, const CMayaSplineKnot *pkNext, CVector2f& rOutTangentA, CVector2f& rOutTangentB) const; void GetTangents(const CMayaSplineKnot* pkPrev, const CMayaSplineKnot* pkNext, CVector2f& OutTangentA, CVector2f& OutTangentB) const;
void CalculateTangents(const CMayaSplineKnot *pkPrev, const CMayaSplineKnot *pkNext) const; void CalculateTangents(const CMayaSplineKnot* pkPrev, const CMayaSplineKnot* pkNext) const;
}; };
class CMayaSpline class CMayaSpline
{ {
u32 mPreInfinity; // 0x00 uint mPreInfinity; // 0x00
u32 mPostInfinity; // 0x04 uint mPostInfinity; // 0x04
std::vector<CMayaSplineKnot> mKnots; // 0x08, 0x0C, 0x10 std::vector<CMayaSplineKnot> mKnots; // 0x08, 0x0C, 0x10
u32 mClampMode; // 0x14 - clamp mode uint mClampMode; // 0x14 - clamp mode
float mMinAmplitude; // 0x18 float mMinAmplitude; // 0x18
float mMaxAmplitude; // 0x1C float mMaxAmplitude; // 0x1C
mutable s32 mCachedKnotIndex; // 0x20 mutable int mCachedKnotIndex; // 0x20
mutable s32 mUnknown1; // 0x24 mutable int mUnknown1; // 0x24
mutable u8 mDirtyFlags; // 0x28 mutable uint8 mDirtyFlags; // 0x28
mutable float mCachedMinTime; // 0x2C mutable float mCachedMinTime; // 0x2C
mutable float mCachedHermiteCoefficients[4]; // 0x30, 0x34, 0x38, 0x3C mutable float mCachedHermiteCoefficients[4]; // 0x30, 0x34, 0x38, 0x3C
public: public:
CMayaSpline() {} CMayaSpline() {}
inline u32 GetKnotCount() const; uint GetKnotCount() const;
inline const std::vector<CMayaSplineKnot>& GetKnots() const; const std::vector<CMayaSplineKnot>& GetKnots() const;
float GetMinTime() const; float GetMinTime() const;
float GetMaxTime() const; float GetMaxTime() const;
float GetDuration() const; float GetDuration() const;
@ -47,9 +47,9 @@ public:
float EvaluateAtUnclamped(float Time) const; float EvaluateAtUnclamped(float Time) const;
float EvaluateInfinities(float Time, bool Pre) const; float EvaluateInfinities(float Time, bool Pre) const;
float EvaluateHermite(float Time) const; float EvaluateHermite(float Time) const;
bool FindKnot(float Time, int& rOutKnotIndex) const; bool FindKnot(float Time, int& OutKnotIndex) const;
void FindControlPoints(int KnotIndex, std::vector<CVector2f>& rOut) const; void FindControlPoints(int KnotIndex, std::vector<CVector2f>& Out) const;
void CalculateHermiteCoefficients(const std::vector<CVector2f>& rkControlPoints, float *pOutCoefs) const; void CalculateHermiteCoefficients(const std::vector<CVector2f>& kControlPoints, float* pOutCoefs) const;
}; };
#endif // CMAYASPLINE_H #endif // CMAYASPLINE_H