mirror of https://github.com/AxioDL/zeus.git
Correct CVector3f::slerp implementation
This commit is contained in:
parent
9799353b35
commit
7df9f9b7ec
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
namespace zeus {
|
namespace zeus {
|
||||||
class CVector3d;
|
class CVector3d;
|
||||||
|
class CRelAngle;
|
||||||
|
|
||||||
class CVector3f {
|
class CVector3f {
|
||||||
public:
|
public:
|
||||||
|
@ -145,7 +146,7 @@ public:
|
||||||
|
|
||||||
static CVector3f nlerp(const CVector3f& a, const CVector3f& b, float t) { return lerp(a, b, t).normalized(); }
|
static CVector3f nlerp(const CVector3f& a, const CVector3f& b, float t) { return lerp(a, b, t).normalized(); }
|
||||||
|
|
||||||
static CVector3f slerp(const CVector3f& a, const CVector3f& b, float t);
|
static CVector3f slerp(const CVector3f& a, const CVector3f& b, CRelAngle clampAngle);
|
||||||
|
|
||||||
bool isNormalized() const { return std::fabs(1.f - magSquared()) < 0.01f; }
|
bool isNormalized() const { return std::fabs(1.f - magSquared()) < 0.01f; }
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include "zeus/Math.hpp"
|
#include "zeus/Math.hpp"
|
||||||
|
#include "zeus/CRelAngle.hpp"
|
||||||
|
|
||||||
namespace zeus {
|
namespace zeus {
|
||||||
const CVector3f CVector3f::skOne(1.f);
|
const CVector3f CVector3f::skOne(1.f);
|
||||||
|
@ -33,30 +34,7 @@ float CVector3f::getAngleDiff(const CVector3f& a, const CVector3f& b) {
|
||||||
return theta;
|
return theta;
|
||||||
}
|
}
|
||||||
|
|
||||||
CVector3f CVector3f::slerp(const CVector3f& a, const CVector3f& b, float t) {
|
CVector3f CVector3f::slerp(const CVector3f& a, const CVector3f& b, CRelAngle clampAngle) {
|
||||||
if (t <= 0.0f)
|
return a * std::cos(clampAngle) + a.cross(b).normalized().cross(a) * std::sin(clampAngle);
|
||||||
return a;
|
|
||||||
if (t >= 1.0f)
|
|
||||||
return b;
|
|
||||||
|
|
||||||
CVector3f ret;
|
|
||||||
|
|
||||||
float mag = std::sqrt(a.dot(a) * b.dot(b));
|
|
||||||
|
|
||||||
float prod = a.dot(b) / mag;
|
|
||||||
|
|
||||||
if (std::fabs(prod) < 1.0f) {
|
|
||||||
const double sign = (prod < 0.0f) ? -1.0f : 1.0f;
|
|
||||||
|
|
||||||
const double theta = acos(sign * prod);
|
|
||||||
const double s1 = sin(sign * t * theta);
|
|
||||||
const double d = 1.0 / sin(theta);
|
|
||||||
const double s0 = sin((1.0 - t) * theta);
|
|
||||||
|
|
||||||
ret = (a * s0 + b * s1) * d;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
} // namespace zeus
|
} // namespace zeus
|
||||||
|
|
Loading…
Reference in New Issue