#ifndef LERP_FUNCTIONS_H #define LERP_FUNCTIONS_H #ifdef _WIN32 #pragma once #endif template inline T LoopingLerp(float flPercent, T flFrom, T flTo) { T s = flTo * flPercent + flFrom * (1.0f - flPercent); return s; } template <> inline float LoopingLerp(float flPercent, float flFrom, float flTo) { if (fabs(flTo - flFrom) >= 0.5f) { if (flFrom < flTo) flFrom += 1.0f; else flTo += 1.0f; } float s = flTo * flPercent + flFrom * (1.0f - flPercent); s = s - (int)(s); if (s < 0.0f) s = s + 1.0f; return s; } template inline T Lerp_Hermite(const T& , float t, const T& p0, const T& p1, const T& p2) { T d1 = p1 - p0; T d2 = p2 - p1; T output; float tSqr = t * t; float tCube = t * tSqr; output = p1 * (2 * tCube - 3 * tSqr + 1); output += p2 * (-2 * tCube + 3 * tSqr); output += d1 * (tCube - 2 * tSqr + t); output += d2 * (tCube - tSqr); return output; } template inline T Derivative_Hermite(float t, const T& p0, const T& p1, const T& p2) { T d1 = p1 - p0; T d2 = p2 - p1; T output; float tSqr = t * t; output = p1 * (6 * tSqr - 6 * t); output += p2 * (-6 * tSqr + 6 * t); output += d1 * (3 * tSqr - 4 * t + 1); output += d2 * (3 * tSqr - 2 * t); return output; } inline void Lerp_Clamp(int val) { } inline void Lerp_Clamp(float val) { } inline void Lerp_Clamp(const Vector& val) { } inline void Lerp_Clamp(const QAngle& val) { } template< class T, int minValue, int maxValue, int startValue > inline void Lerp_Clamp(CRangeCheckedVar& val) { val.Clamp(); } template<> inline QAngle Lerp_Hermite(const QAngle&, float t, const QAngle& p0, const QAngle& p1, const QAngle& p2) { return Lerp(t, p1, p2); } template inline T LoopingLerp_Hermite(T current, float t, T p0, T p1, T p2) { return Lerp_Hermite(current, t, p0, p1, p2); } template <> inline float LoopingLerp_Hermite(float , float t, float p0, float p1, float p2) { if (fabs(p1 - p0) > 0.5f) { if (p0 < p1) p0 += 1.0f; else p1 += 1.0f; } if (fabs(p2 - p1) > 0.5f) { if (p1 < p2) { p1 += 1.0f; if (abs(p1 - p0) > 0.5) { if (p0 < p1) p0 += 1.0f; else p1 += 1.0f; } } else { p2 += 1.0f; } } float s = Lerp_Hermite( 0.0f, t, p0, p1, p2); s = s - (int)(s); if (s < 0.0f) { s = s + 1.0f; } return s; } template< int minValue, int maxValue, int startValue > inline CRangeCheckedVar LoopingLerp_Hermite(CRangeCheckedVar current, float t, CRangeCheckedVar p0, CRangeCheckedVar p1, CRangeCheckedVar p2) { return LoopingLerp_Hermite((float)current, t, (float)p0, (float)p1, (float)p2); } #endif