#pragma once
#include "ofConstants.h"
#include "ofVec3f.h"
#include "ofVec4f.h"
#include <cmath>
#if (_MSC_VER)
#pragma warning(disable : 4244)
#endif
class ofMatrix4x4;
class ofQuaternion {
public:
ofVec4f _v;
inline ofQuaternion();
inline ofQuaternion(float x, float y, float z, float w);
inline ofQuaternion(const ofVec4f& v);
inline ofQuaternion(float angle, const ofVec3f& axis);
inline ofQuaternion(float angle1, const ofVec3f& axis1, float angle2, const ofVec3f& axis2, float angle3, const ofVec3f& axis3);
ofQuaternion(const glm::quat & q);
operator glm::quat() const;
inline void set(float x, float y, float z, float w);
inline void set(const ofVec4f& v);
void set(const ofMatrix4x4& matrix);
inline float& operator [](int i);
inline float operator [](int i) const;
void get(ofMatrix4x4& matrix) const;
inline float& x();
inline float& y();
inline float& z();
inline float& w();
inline float x() const;
inline float y() const;
inline float z() const;
inline float w() const;
inline ofVec4f asVec4() const;
inline ofVec3f asVec3() const;
inline bool zeroRotation() const;
inline float length() const;
inline float length2() const;
inline ofQuaternion conj() const;
inline const ofQuaternion inverse() const;
void makeRotate(float angle, float x, float y, float z);
void makeRotate(float angle, const ofVec3f& vec);
void makeRotate(float angle1, const ofVec3f& axis1, float angle2, const ofVec3f& axis2, float angle3, const ofVec3f& axis3);
void makeRotate(const ofVec3f& vec1, const ofVec3f& vec2);
void makeRotate_original(const ofVec3f& vec1, const ofVec3f& vec2);
void getRotate(float&angle, float& x, float& y, float& z) const;
void getRotate(float& angle, ofVec3f& vec) const;
ofVec3f getEuler() const;
void slerp(float t, const ofQuaternion& from, const ofQuaternion& to);
inline void normalize();
inline ofQuaternion& operator =(const ofQuaternion& q);
inline bool operator ==(const ofQuaternion& q) const;
inline bool operator !=(const ofQuaternion& q) const;
inline const ofQuaternion operator *(float rhs) const;
inline const ofQuaternion operator*(const ofQuaternion& rhs) const;
inline ofVec3f operator*(const ofVec3f& v) const;
inline ofQuaternion& operator *=(float rhs);
inline ofQuaternion& operator*=(const ofQuaternion& rhs);
inline ofQuaternion operator /(float rhs) const;
inline const ofQuaternion operator/(const ofQuaternion& denom) const;
inline ofQuaternion& operator /=(float rhs);
inline ofQuaternion& operator/=(const ofQuaternion& denom);
inline const ofQuaternion operator +(const ofQuaternion& rhs) const;
inline ofQuaternion& operator +=(const ofQuaternion& rhs);
inline ofQuaternion& operator -=(const ofQuaternion& rhs);
inline const ofQuaternion operator -(const ofQuaternion& rhs) const;
inline const ofQuaternion operator -() const;
friend std::ostream& operator<<(std::ostream& os, const ofQuaternion &q);
friend std::istream& operator>>(std::istream& is, ofQuaternion &q);
};
ofQuaternion::ofQuaternion() {
_v.set(0, 0, 0, 1);
}
ofQuaternion::ofQuaternion(float x, float y, float z, float w) {
_v.set(x, y, z, w);
}
ofQuaternion::ofQuaternion(const ofVec4f& v) {
_v = v;
}
ofQuaternion::ofQuaternion(float angle, const ofVec3f& axis) {
makeRotate(angle, axis);
}
ofQuaternion::ofQuaternion(float angle1, const ofVec3f& axis1, float angle2, const ofVec3f& axis2, float angle3, const ofVec3f& axis3) {
makeRotate(angle1, axis1, angle2, axis2, angle3, axis3);
}
ofQuaternion& ofQuaternion::operator =(const ofQuaternion& q) {
_v = q._v;
return *this;
}
bool ofQuaternion::operator ==(const ofQuaternion& q) const {
return _v == q._v;
}
bool ofQuaternion::operator !=(const ofQuaternion& q) const {
return _v != q._v;
}
ofVec4f ofQuaternion::asVec4() const {
return _v;
}
ofVec3f ofQuaternion::asVec3() const {
return ofVec3f(_v);
}
void ofQuaternion::set(float x, float y, float z, float w) {
_v.set(x, y, z, w);
}
void ofQuaternion::set(const ofVec4f& v) {
_v = v;
}
float& ofQuaternion::operator [](int i) {
return _v[i];
}
float ofQuaternion::operator [](int i) const {
return _v[i];
}
float& ofQuaternion::x() {
return _v.x;
}
float& ofQuaternion::y() {
return _v.y;
}
float& ofQuaternion::z() {
return _v.z;
}
float& ofQuaternion::w() {
return _v.w;
}
float ofQuaternion::x() const {
return _v.x;
}
float ofQuaternion::y() const {
return _v.y;
}
float ofQuaternion::z() const {
return _v.z;
}
float ofQuaternion::w() const {
return _v.w;
}
bool ofQuaternion::zeroRotation() const {
return _v.x == 0.0 && _v.y == 0.0 && _v.z == 0.0 && _v.w == 1.0;
}
const ofQuaternion ofQuaternion::operator *(float rhs) const {
return ofQuaternion(_v.x*rhs, _v.y*rhs, _v.z*rhs, _v.w*rhs);
}
ofQuaternion& ofQuaternion::operator *=(float rhs) {
_v.x *= rhs;
_v.y *= rhs;
_v.z *= rhs;
_v.w *= rhs;
return *this;
}
const ofQuaternion ofQuaternion::operator*(const ofQuaternion& rhs) const {
return ofQuaternion(rhs._v.w*_v.x + rhs._v.x*_v.w + rhs._v.y*_v.z - rhs._v.z*_v.y,
rhs._v.w*_v.y - rhs._v.x*_v.z + rhs._v.y*_v.w + rhs._v.z*_v.x,
rhs._v.w*_v.z + rhs._v.x*_v.y - rhs._v.y*_v.x + rhs._v.z*_v.w,
rhs._v.w*_v.w - rhs._v.x*_v.x - rhs._v.y*_v.y - rhs._v.z*_v.z);
}
ofQuaternion& ofQuaternion::operator*=(const ofQuaternion& rhs) {
float x = rhs._v.w * _v.x + rhs._v.x * _v.w + rhs._v.y * _v.z - rhs._v.z * _v.y;
float y = rhs._v.w * _v.y - rhs._v.x * _v.z + rhs._v.y * _v.w + rhs._v.z * _v.x;
float z = rhs._v.w * _v.z + rhs._v.x * _v.y - rhs._v.y * _v.x + rhs._v.z * _v.w;
_v.w = rhs._v.w * _v.w - rhs._v.x * _v.x - rhs._v.y * _v.y - rhs._v.z * _v.z;
_v.z = z;
_v.y = y;
_v.x = x;
return (*this);
}
ofQuaternion ofQuaternion::operator /(float rhs) const {
float div = 1.0f / rhs;
return ofQuaternion(_v.x*div, _v.y*div, _v.z*div, _v.w*div);
}
ofQuaternion& ofQuaternion::operator /=(float rhs) {
float div = 1.0f / rhs;
_v.x *= div;
_v.y *= div;
_v.z *= div;
_v.w *= div;
return *this;
}
const ofQuaternion ofQuaternion::operator/(const ofQuaternion& denom) const {
return ((*this) * denom.inverse());
}
ofQuaternion& ofQuaternion::operator/=(const ofQuaternion& denom) {
(*this) = (*this) * denom.inverse();
return (*this);
}
const ofQuaternion ofQuaternion::operator +(const ofQuaternion& rhs) const {
return ofQuaternion(_v.x + rhs._v.x, _v.y + rhs._v.y,
_v.z + rhs._v.z, _v.w + rhs._v.w);
}
ofQuaternion& ofQuaternion::operator +=(const ofQuaternion& rhs) {
_v.x += rhs._v.x;
_v.y += rhs._v.y;
_v.z += rhs._v.z;
_v.w += rhs._v.w;
return *this;
}
const ofQuaternion ofQuaternion::operator -(const ofQuaternion& rhs) const {
return ofQuaternion(_v.x - rhs._v.x, _v.y - rhs._v.y,
_v.z - rhs._v.z, _v.w - rhs._v.w);
}
ofQuaternion& ofQuaternion::operator -=(const ofQuaternion& rhs) {
_v.x -= rhs._v.x;
_v.y -= rhs._v.y;
_v.z -= rhs._v.z;
_v.w -= rhs._v.w;
return *this;
}
const ofQuaternion ofQuaternion::operator -() const {
return ofQuaternion(-_v.x, -_v.y, -_v.z, -_v.w);
}
float ofQuaternion::length() const {
return sqrt(_v.x*_v.x + _v.y*_v.y + _v.z*_v.z + _v.w*_v.w);
}
float ofQuaternion::length2() const {
return _v.x*_v.x + _v.y*_v.y + _v.z*_v.z + _v.w*_v.w;
}
ofQuaternion ofQuaternion::conj() const {
return ofQuaternion(-_v.x, -_v.y, -_v.z, _v.w);
}
const ofQuaternion ofQuaternion::inverse() const {
return conj() / length2();
}
ofVec3f ofQuaternion::operator*(const ofVec3f& v) const {
ofVec3f uv, uuv;
ofVec3f qvec(_v.x, _v.y, _v.z);
uv = qvec.getCrossed(v);
uuv = qvec.getCrossed(uv);
uv *= (2.0f * _v.w);
uuv *= 2.0f;
return v + uv + uuv;
}
void ofQuaternion::normalize(){
float len = _v.w*_v.w + _v.x*_v.x + _v.y*_v.y + _v.z*_v.z;
float factor = 1.0f / sqrt(len);
_v.x *= factor;
_v.y *= factor;
_v.z *= factor;
_v.w *= factor;
}
Comments