Fixed CMayaSpline source files not compiling
This commit is contained in:
parent
ca40d34739
commit
cd7937f73c
|
@ -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;
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue