*Massive cleanup (\n\n -> \n, *\n -> \n, cleanup for(...) to for (...), and some other cleanups by hand)
*Fix a possible crash in Spell::DoAllEffectOnTarget --HG-- branch : trunk
This commit is contained in:
@@ -1,46 +1,34 @@
|
||||
/**
|
||||
@file Quat.h
|
||||
|
||||
Quaternion
|
||||
|
||||
@maintainer Morgan McGuire, [email protected]
|
||||
|
||||
@created 2002-01-23
|
||||
@edited 2006-05-10
|
||||
*/
|
||||
|
||||
#ifndef G3D_QUAT_H
|
||||
#define G3D_QUAT_H
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/g3dmath.h"
|
||||
#include "G3D/Vector3.h"
|
||||
#include "G3D/Matrix3.h"
|
||||
#include <string>
|
||||
|
||||
namespace G3D {
|
||||
|
||||
/**
|
||||
Unit quaternions are used in computer graphics to represent
|
||||
rotation about an axis. Any 3x3 rotation matrix can
|
||||
be stored as a quaternion.
|
||||
|
||||
A quaternion represents the sum of a real scalar and
|
||||
an imaginary vector: ix + jy + kz + w. A unit quaternion
|
||||
representing a rotation by A about axis v has the form
|
||||
[sin(A/2)*v, cos(A/2)]. For a unit quaternion, q.conj() == q.inverse()
|
||||
is a rotation by -A about v. -q is the same rotation as q
|
||||
(negate both the axis and angle).
|
||||
|
||||
A non-unit quaterion q represents the same rotation as
|
||||
q.unitize() (Dam98 pg 28).
|
||||
|
||||
Although quaternion-vector operations (eg. Quat + Vector3) are
|
||||
well defined, they are not supported by this class because
|
||||
they typically are bugs when they appear in code.
|
||||
|
||||
Do not subclass.
|
||||
|
||||
<B>BETA API -- subject to change</B>
|
||||
@cite Erik B. Dam, Martin Koch, Martin Lillholm, Quaternions, Interpolation and Animation. Technical Report DIKU-TR-98/5, Department of Computer Science, University of Copenhagen, Denmark. 1998.
|
||||
*/
|
||||
@@ -51,81 +39,64 @@ private:
|
||||
bool operator>(const Quat&) const;
|
||||
bool operator<=(const Quat&) const;
|
||||
bool operator>=(const Quat&) const;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
q = [sin(angle / 2) * axis, cos(angle / 2)]
|
||||
|
||||
In Watt & Watt's notation, s = w, v = (x, y, z)
|
||||
In the Real-Time Rendering notation, u = (x, y, z), w = w
|
||||
*/
|
||||
float x, y, z, w;
|
||||
|
||||
/**
|
||||
Initializes to a zero degree rotation.
|
||||
*/
|
||||
inline Quat() : x(0), y(0), z(0), w(1) {}
|
||||
|
||||
Quat(
|
||||
const Matrix3& rot);
|
||||
|
||||
inline Quat(float _x, float _y, float _z, float _w) :
|
||||
x(_x), y(_y), z(_z), w(_w) {}
|
||||
|
||||
/** Defaults to a pure vector quaternion */
|
||||
inline Quat(const Vector3& v, float _w = 0) : x(v.x), y(v.y), z(v.z), w(_w) {
|
||||
}
|
||||
|
||||
/**
|
||||
The real part of the quaternion.
|
||||
*/
|
||||
inline const float& real() const {
|
||||
return w;
|
||||
}
|
||||
|
||||
inline float& real() {
|
||||
return w;
|
||||
}
|
||||
|
||||
/** Note: two quats can represent the Quat::sameRotation and not be equal. */
|
||||
bool fuzzyEq(const Quat& q) {
|
||||
return G3D::fuzzyEq(x, q.x) && G3D::fuzzyEq(y, q.y) && G3D::fuzzyEq(z, q.z) && G3D::fuzzyEq(w, q.w);
|
||||
}
|
||||
|
||||
/** True if these quaternions represent the same rotation (note that every rotation is
|
||||
represented by two values; q and -q).
|
||||
*/
|
||||
bool sameRotation(const Quat& q) {
|
||||
return fuzzyEq(q) || fuzzyEq(-q);
|
||||
}
|
||||
|
||||
inline Quat operator-() const {
|
||||
return Quat(-x, -y, -z, -w);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the imaginary part (x, y, z)
|
||||
*/
|
||||
inline const Vector3& imag() const {
|
||||
return *(reinterpret_cast<const Vector3*>(this));
|
||||
}
|
||||
|
||||
inline Vector3& imag() {
|
||||
return *(reinterpret_cast<Vector3*>(this));
|
||||
}
|
||||
|
||||
/** q = [sin(angle/2)*axis, cos(angle/2)] */
|
||||
static Quat fromAxisAngleRotation(
|
||||
const Vector3& axis,
|
||||
float angle);
|
||||
|
||||
/** Returns the axis and angle of rotation represented
|
||||
by this quaternion (i.e. q = [sin(angle/2)*axis, cos(angle/2)]) */
|
||||
void toAxisAngleRotation(
|
||||
Vector3& axis,
|
||||
double& angle) const;
|
||||
|
||||
void toAxisAngleRotation(
|
||||
Vector3& axis,
|
||||
float& angle) const {
|
||||
@@ -133,18 +104,13 @@ public:
|
||||
toAxisAngleRotation(axis, d);
|
||||
angle = (float)d;
|
||||
}
|
||||
|
||||
Matrix3 toRotationMatrix() const;
|
||||
|
||||
void toRotationMatrix(
|
||||
Matrix3& rot) const;
|
||||
|
||||
/**
|
||||
Spherical linear interpolation: linear interpolation along the
|
||||
shortest (3D) great-circle route between two quaternions.
|
||||
|
||||
Note: Correct rotations are expected between 0 and PI in the right order.
|
||||
|
||||
@cite Based on Game Physics -- David Eberly pg 538-540
|
||||
@param threshold Critical angle between between rotations at which
|
||||
the algorithm switches to normalized lerp, which is more
|
||||
@@ -154,72 +120,56 @@ public:
|
||||
const Quat& other,
|
||||
float alpha,
|
||||
float threshold = 0.05f) const;
|
||||
|
||||
/** Normalized linear interpolation of quaternion components. */
|
||||
Quat nlerp(const Quat& other, float alpha) const;
|
||||
|
||||
/**
|
||||
Negates the imaginary part.
|
||||
*/
|
||||
inline Quat conj() const {
|
||||
return Quat(-x, -y, -z, w);
|
||||
}
|
||||
|
||||
inline float sum() const {
|
||||
return x + y + z + w;
|
||||
}
|
||||
|
||||
inline float average() const {
|
||||
return sum() / 4.0f;
|
||||
}
|
||||
|
||||
inline Quat operator*(float s) const {
|
||||
return Quat(x * s, y * s, z * s, w * s);
|
||||
}
|
||||
|
||||
/** @cite Based on Watt & Watt, page 360 */
|
||||
friend Quat operator* (float s, const Quat& q);
|
||||
|
||||
inline Quat operator/(float s) const {
|
||||
return Quat(x / s, y / s, z / s, w / s);
|
||||
}
|
||||
|
||||
inline float dot(const Quat& other) const {
|
||||
return (x * other.x) + (y * other.y) + (z * other.z) + (w * other.w);
|
||||
}
|
||||
|
||||
/** Note that q<SUP>-1</SUP> = q.conj() for a unit quaternion.
|
||||
@cite Dam99 page 13 */
|
||||
inline Quat inverse() const {
|
||||
return conj() / dot(*this);
|
||||
}
|
||||
|
||||
Quat operator-(const Quat& other) const;
|
||||
|
||||
Quat operator+(const Quat& other) const;
|
||||
|
||||
/**
|
||||
Quaternion multiplication (composition of rotations).
|
||||
Note that this does not commute.
|
||||
*/
|
||||
Quat operator*(const Quat& other) const;
|
||||
|
||||
/* (*this) * other.inverse() */
|
||||
Quat operator/(const Quat& other) const {
|
||||
return (*this) * other.inverse();
|
||||
}
|
||||
|
||||
|
||||
/** Is the magnitude nearly 1.0? */
|
||||
inline bool isUnit(float tolerance = 1e-5) const {
|
||||
return abs(dot(*this) - 1.0f) < tolerance;
|
||||
}
|
||||
|
||||
|
||||
inline float magnitude() const {
|
||||
return sqrtf(dot(*this));
|
||||
}
|
||||
|
||||
inline Quat log() const {
|
||||
if ((x == 0) && (y == 0) && (z == 0)) {
|
||||
if (w > 0) {
|
||||
@@ -247,17 +197,14 @@ public:
|
||||
// Solve for A in q = [sin(A)*v, cos(A)]
|
||||
Vector3 u(x, y, z);
|
||||
double len = u.magnitude();
|
||||
|
||||
if (len == 0.0) {
|
||||
return
|
||||
}
|
||||
double A = atan2((double)w, len);
|
||||
Vector3 v = u / len;
|
||||
|
||||
return Quat(v * A, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
/** exp q = [sin(A) * v, cos(A)] where q = [Av, 0].
|
||||
Only defined for pure-vector quaternions */
|
||||
inline Quat exp() const {
|
||||
@@ -268,12 +215,10 @@ public:
|
||||
return Quat(sinf(A) * v, cosf(A));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Raise this quaternion to a power. For a rotation, this is
|
||||
the effect of rotating x times as much as the original
|
||||
quaterion.
|
||||
|
||||
Note that q.pow(a).pow(b) == q.pow(a + b)
|
||||
@cite Dam98 pg 21
|
||||
*/
|
||||
@@ -281,7 +226,6 @@ public:
|
||||
return (log() * x).exp();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@deprecated
|
||||
Use toUnit()
|
||||
@@ -294,7 +238,6 @@ public:
|
||||
return *this / sqrtf(mag2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a unit quaterion obtained by dividing through by
|
||||
the magnitude.
|
||||
@@ -302,7 +245,6 @@ public:
|
||||
inline Quat toUnit() const {
|
||||
return unitize();
|
||||
}
|
||||
|
||||
/**
|
||||
The linear algebra 2-norm, sqrt(q dot q). This matches
|
||||
the value used in Dam's 1998 tech report but differs from the
|
||||
@@ -312,7 +254,6 @@ public:
|
||||
inline float norm() const {
|
||||
return magnitude();
|
||||
}
|
||||
|
||||
// access quaternion as q[0] = q.x, q[1] = q.y, q[2] = q.z, q[3] = q.w
|
||||
//
|
||||
// WARNING. These member functions rely on
|
||||
@@ -320,14 +261,11 @@ public:
|
||||
// (2) the data packed in a 4*sizeof(float) memory block
|
||||
const float& operator[] (int i) const;
|
||||
float& operator[] (int i);
|
||||
|
||||
/** Generate uniform random unit quaternion (i.e. random "direction")
|
||||
@cite From "Uniform Random Rotations", Ken Shoemake, Graphics Gems III.
|
||||
*/
|
||||
static Quat unitRandom();
|
||||
|
||||
// 2-char swizzles
|
||||
|
||||
Vector2 xx() const;
|
||||
Vector2 yx() const;
|
||||
Vector2 zx() const;
|
||||
@@ -344,9 +282,7 @@ public:
|
||||
Vector2 yw() const;
|
||||
Vector2 zw() const;
|
||||
Vector2 ww() const;
|
||||
|
||||
// 3-char swizzles
|
||||
|
||||
Vector3 xxx() const;
|
||||
Vector3 yxx() const;
|
||||
Vector3 zxx() const;
|
||||
@@ -411,9 +347,7 @@ public:
|
||||
Vector3 yww() const;
|
||||
Vector3 zww() const;
|
||||
Vector3 www() const;
|
||||
|
||||
// 4-char swizzles
|
||||
|
||||
Vector4 xxxx() const;
|
||||
Vector4 yxxx() const;
|
||||
Vector4 zxxx() const;
|
||||
@@ -671,33 +605,24 @@ public:
|
||||
Vector4 zwww() const;
|
||||
Vector4 wwww() const;
|
||||
};
|
||||
|
||||
inline Quat exp(const Quat& q) {
|
||||
return q.exp();
|
||||
}
|
||||
|
||||
inline Quat log(const Quat& q) {
|
||||
return q.log();
|
||||
}
|
||||
|
||||
inline G3D::Quat operator*(double s, const G3D::Quat& q) {
|
||||
return q * (float)s;
|
||||
}
|
||||
|
||||
inline G3D::Quat operator*(float s, const G3D::Quat& q) {
|
||||
return q * s;
|
||||
}
|
||||
|
||||
} // Namespace G3D
|
||||
|
||||
// Outside the namespace to avoid overloading confusion for C++
|
||||
inline G3D::Quat pow(const G3D::Quat& q, double x) {
|
||||
return q.pow((float)x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "Quat.inl"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user