|
@@ -1,12 +1,12 @@
|
|
|
#include <cmath>
|
|
|
+#include <iostream>
|
|
|
|
|
|
#include "client/math/Quaternion.h"
|
|
|
|
|
|
-Quaternion::Quaternion() : xyz(0.0f, 0.0f, 0.0f), w(0.0f) {
|
|
|
+Quaternion::Quaternion() : xyz(0.0f, 0.0f, 0.0f), w(1.0f) {
|
|
|
}
|
|
|
|
|
|
Quaternion::Quaternion(float x, float y, float z, float w) : xyz(x, y, z), w(w) {
|
|
|
- normalize();
|
|
|
}
|
|
|
|
|
|
Quaternion::Quaternion(const Vector& axis, float angle) {
|
|
@@ -18,7 +18,7 @@ Quaternion::Quaternion(const Vector& axis, float angle) {
|
|
|
}
|
|
|
|
|
|
Quaternion Quaternion::lerp(float f, const Quaternion& other) const {
|
|
|
- return interpolate(1 - f, f, other);
|
|
|
+ return interpolate(1 - f, f, other).normalize();
|
|
|
}
|
|
|
|
|
|
Quaternion Quaternion::slerp(float f, const Quaternion& other) const {
|
|
@@ -39,10 +39,25 @@ Quaternion Quaternion::interpolate(float a, float b, const Quaternion& other) co
|
|
|
return Quaternion(interpolated.getX(), interpolated.getY(), interpolated.getZ(), w * a + other.w * b);
|
|
|
}
|
|
|
|
|
|
-void Quaternion::normalize() {
|
|
|
+Quaternion Quaternion::squad(float f, const Quaternion& prev, const Quaternion& next, const Quaternion& nextNext) const {
|
|
|
+ Quaternion s1 = squadControl(prev, next);
|
|
|
+ Quaternion s2 = next.squadControl(*this, nextNext);
|
|
|
+ return slerp(f, next).slerp(2.0f * f * (1.0f - f), s1.slerp(f, s2));
|
|
|
+}
|
|
|
+
|
|
|
+Quaternion Quaternion::squadControl(const Quaternion& prev, const Quaternion& next) const {
|
|
|
+ Quaternion conjugate(*this);
|
|
|
+ conjugate.conjugate();
|
|
|
+ Quaternion s1(next);
|
|
|
+ s1.mul(conjugate).log().add(Quaternion(prev).mul(conjugate).log()).mul(-0.25f).exp().mul(*this);
|
|
|
+ return s1;
|
|
|
+}
|
|
|
+
|
|
|
+Quaternion& Quaternion::normalize() {
|
|
|
float f = 1.0f / sqrtf(xyz.dot(xyz) + w * w);
|
|
|
xyz.mul(f);
|
|
|
w *= f;
|
|
|
+ return *this;
|
|
|
}
|
|
|
|
|
|
Matrix Quaternion::toMatrix() const {
|
|
@@ -68,9 +83,54 @@ Matrix Quaternion::toMatrix() const {
|
|
|
return m;
|
|
|
}
|
|
|
|
|
|
-void Quaternion::mul(const Quaternion& other) {
|
|
|
+Quaternion& Quaternion::mul(const Quaternion& other) {
|
|
|
Vector v;
|
|
|
v.addMul(other.xyz, w).addMul(xyz, other.w).add(Vector(xyz).cross(other.xyz));
|
|
|
w = w * other.w - xyz.dot(other.xyz);
|
|
|
xyz.set(v);
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Quaternion& Quaternion::mul(float f) {
|
|
|
+ xyz.mul(f);
|
|
|
+ w *= f;
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Quaternion& Quaternion::add(const Quaternion& other) {
|
|
|
+ xyz.add(other.xyz);
|
|
|
+ w += other.w;
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Quaternion& Quaternion::conjugate() {
|
|
|
+ xyz.setInverse(xyz);
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Quaternion& Quaternion::log() {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ xyz.normalize().mul(acos(w));
|
|
|
+ w = 0.0f;
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Quaternion& Quaternion::exp() {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ float length = xyz.length();
|
|
|
+ w = cosf(length);
|
|
|
+ xyz.mul((sin(length)) / length);
|
|
|
+ return *this;
|
|
|
}
|