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 {
|
||||
class CVector3d;
|
||||
class CRelAngle;
|
||||
|
||||
class CVector3f {
|
||||
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 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; }
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include "zeus/Math.hpp"
|
||||
#include "zeus/CRelAngle.hpp"
|
||||
|
||||
namespace zeus {
|
||||
const CVector3f CVector3f::skOne(1.f);
|
||||
|
@ -33,30 +34,7 @@ float CVector3f::getAngleDiff(const CVector3f& a, const CVector3f& b) {
|
|||
return theta;
|
||||
}
|
||||
|
||||
CVector3f CVector3f::slerp(const CVector3f& a, const CVector3f& b, float t) {
|
||||
if (t <= 0.0f)
|
||||
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;
|
||||
CVector3f CVector3f::slerp(const CVector3f& a, const CVector3f& b, CRelAngle clampAngle) {
|
||||
return a * std::cos(clampAngle) + a.cross(b).normalized().cross(a) * std::sin(clampAngle);
|
||||
}
|
||||
} // namespace zeus
|
||||
|
|
Loading…
Reference in New Issue