| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 | #include <cmath>#include "client/math/Quaternion.h"Quaternion::Quaternion() : xyz(0.0f, 0.0f, 0.0f), w(0.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) {    Vector unit(axis);    xyz.set(unit.normalize());    float sin;    sincosf(angle * (M_PI / 360.0f), &sin, &w);    xyz.mul(sin);}Quaternion Quaternion::lerp(float f, const Quaternion& other) const {    return interpolate(1 - f, f, other);}Quaternion Quaternion::slerp(float f, const Quaternion& other) const {    float angle = xyz.dot(other.xyz) + w * other.w;    if(angle >= 1.0f) {        return *this;    } else if(angle < -1.0f) {        angle = -1.0f;    }    float arccos = acosf(angle);    float sin = 1.0f / sinf(arccos);    return interpolate(sinf((1 - f) * arccos) * sin, sinf(f * arccos) * sin, other);}Quaternion Quaternion::interpolate(float a, float b, const Quaternion& other) const {    Vector interpolated(xyz);    interpolated.mul(a).addMul(other.xyz, b);    return Quaternion(interpolated.getX(), interpolated.getY(), interpolated.getZ(), w * a + other.w * b);}void Quaternion::normalize() {    float f = 1.0f / sqrtf(xyz.dot(xyz) + w * w);    xyz.mul(f);    w *= f;}Matrix Quaternion::toMatrix() const {    float x = xyz.getX();    float y = xyz.getY();    float z = xyz.getZ();    float x2 = 2 * x * x;    float y2 = 2 * y * y;    float z2 = 2 * z * z;    float xy = 2 * x * y;    float xz = 2 * x * z;    float xw = 2 * x * w;    float zw = 2 * z * w;    float yz = 2 * y * z;    float yw = 2 * y * w;    Matrix m;    m.set(0, 1 - y2 - z2).set(1, xy - zw).set(2, xz + yw);    m.set(4, xy + zw).set(5, 1 - x2 - z2).set(6, yz - xw);    m.set(8, xz - yw).set(9, yz + xw).set(10, 1 - x2 - y2);    return m;}void 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);}
 |