1 /*
2 Copyright (C) 2005-2007 Feeling Software Inc.
3 Portions of the code are:
4 Copyright (C) 2005-2007 Sony Computer Entertainment America
5
6 MIT License: http://www.opensource.org/licenses/mit-license.php
7 */
8
9 /**
10 @file FMQuaternion.h
11 The file containing the class for quaternions.
12 */
13
14 #ifndef _FM_QUATERNION_H_
15 #define _FM_QUATERNION_H_
16
17 /**
18 A quaternion.
19 Used to represent rotations: quaternions have the sole advantage of reduced
20 floating-point error when concatenating rotations.
21
22 @ingroup FMath
23 */
24 class FCOLLADA_EXPORT FMQuaternion
25 {
26 public:
27 float x; /**< The i component. */
28 float y; /**< The j component. */
29 float z; /**< The k component. */
30 float w; /**< The scalar component. */
31
32 #ifndef _DEBUG
33 /** Creates an empty FMQuaternion.
34 The default values are non deterministic. */
FMQuaternion()35 FMQuaternion() {}
36 #else
FMQuaternion()37 FMQuaternion() { x = 123456789.0f; y = 123456789.0f; z = 123456789.0f; w = 123456789.0f; }
38 #endif
39
40 /** Creates the quaternion with the given component values.
41 @param _x The i component.
42 @param _y The j component.
43 @param _z The k component.
44 @param _w The scalar component. */
FMQuaternion(float _x,float _y,float _z,float _w)45 FMQuaternion(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; }
46
47 /** Creates the quaternion with the given component values.
48 @param values A static float array containing at least four elements. */
49 FMQuaternion(const float* values);
50 FMQuaternion(const double* values); /**< See above. */
51
52 /** Creates the quaternion from a given axis and angle of rotation.
53 @param axis The axis of rotation.
54 @param angle The angle of rotation in radians. */
55 FMQuaternion(const FMVector3& axis, float angle);
56
57 /** Retrieves this quaternion as an array of \c floats.
58 @return The \c float array. */
59 inline operator float*() { return &x; }
60 inline operator const float*() const { return &x; } /**< See above. */
61
62 /** Assign this FMQuaternion to the given \c float array.
63 Assigns each coordinate of this FMQuaternion to the elements in the
64 \c float array. The first element to the i component, the second to the
65 j, the third to the k, and the forth to the scalar.
66 @param v The \c float array to assign with.
67 @return This quaternion. */
68 inline FMQuaternion& operator =(const float* v) { x = *v; y = *(v + 1); z = *(v + 2); w = *(v + 3); return *this; }
69
70 /** Retrieves the squared length of the vector.
71 @return The squared length of this vector. */
LengthSquared()72 inline float LengthSquared() const { return x * x + y * y + z * z + w * w; }
73
74 /** Retrieves the length of the vector.
75 @return The length of this vector. */
Length()76 inline float Length() const { return sqrtf(x * x + y * y + z * z + w * w); }
77
78 /** Normalizes this vector. */
NormalizeIt()79 inline void NormalizeIt() { float l = Length(); if (l > 0.0f) { x /= l; y /= l; z /= l; w /= l; }}
80
81 /** Returns a quaternion with a unit length at the same space as this quaternion
82 @return A FMVector3 with length 1 and same direction as this vector. */
Normalize()83 inline FMQuaternion Normalize() const { float l = Length(); return FMQuaternion(x / l, y / l, z / l, w / l); }
84
85 /** Returns the concatonation of this quaternion rotation and the given
86 quaternion rotation.
87 @param q A second quaternion rotation.
88 @return The result of the two quaternion rotation. */
89 FMQuaternion operator*(const FMQuaternion& q) const;
90
91 /** Returns the concatonation of this quaternion rotation applied
92 on the given vector. This concatonation works great on
93 vector but will give strange results for points.
94 @param v A 3D vector to rotate.
95 @return The rotated 3D vector. */
96 FMVector3 operator*(const FMVector3& v) const;
97
98 /** Returns the conjugate of this quaternion.
99 @return The conjugate. */
100 inline FMQuaternion operator~() const { return FMQuaternion(-x, -y, -z, w); }
101
102 /** Applies quaternion multiplication of the given quaternion with this
103 quaternion and returns the value.
104 @param q The quaternion multiplied with.
105 @return The resulting quaternion. */
106 inline FMQuaternion& operator*=(const FMQuaternion& q) { return (*this) = (*this) * q; }
107
108 /** Copy constructor.
109 Clones the given quaternion into this quaternion.
110 @param q A quaternion to clone.
111 @return This quaternion. */
112 inline FMQuaternion& operator=(const FMQuaternion& q) { x = q.x; y = q.y; z = q.z; w = q.w; return (*this); }
113
114 /** Returns the slerp of this quaternion to other at time time
115 @param other The Quaternion to interpolate to
116 @param time The percentage (0 < time < 1) to slerp
117 @return The Quaternion formed by the slerp */
118 FMQuaternion slerp(const FMQuaternion& other, float time) const;
119
120 /** Converts a quaternion to its Euler rotation angles.
121 @param previousAngles To support animated quaternions conversion,
122 you need to pass in the previous quaternion's converted angles.
123 The closest angles to the previous angles will be returned for a smooth animation.
124 If this parameter is NULL, one valid set of angles will be returned.
125 @return A 3D vector containing the Euler rotation angles. */
126 FMVector3 ToEuler(FMVector3* previousAngles = NULL) const;
127
128 /** Converts a quaternion to a angle-axis rotation.
129 @param axis The returned axis for the rotation.
130 @param angle The returned angle for the rotation, in radians. */
131 void ToAngleAxis(FMVector3& axis, float& angle) const;
132
133 /** Converts a quaternion to a transformation matrix.
134 @return The transformation matrix for this quaternion. */
135 FMMatrix44 ToMatrix() const;
136
137 /** Sets the Quaternions transform onto the specified matrix.
138 This will overwrite any existing rotations, but not positions
139 @param m The matrix to set our transform onto */
140 void SetToMatrix(FMMatrix44& m) const;
141
142 /** Get the FMQuaternion representation of the Euler rotation angles.
143 @param x The rotation about the x-axis (roll), in radians.
144 @param y The rotation about the y-axis (pitch), in radians.
145 @param z The rotation about the z-axis (yaw), in radians.
146 */
147 static FMQuaternion EulerRotationQuaternion(float x, float y, float z);
148
149 /** Get the FMQuaternion that represents the FMMatrix44 rotation
150 @param mat The matrix whose rotation we will represent */
151 static FMQuaternion MatrixRotationQuaternion(const FMMatrix44& mat);
152
153 public:
154 static const FMQuaternion Zero; /**< The zero quaternion. */
155
156 /** The identity quaternion.
157 Transforming a vector or a point with this quaternion
158 returns the same vector or point. */
159 static const FMQuaternion Identity;
160 };
161
162 /** Retrieves whether two quaternions are equivalent.
163 @param a A first quaternion.
164 @param b A second quaternion.
165 @return Whether the two quaternions are equivalent. */
IsEquivalent(const FMQuaternion & a,const FMQuaternion & b)166 inline bool IsEquivalent(const FMQuaternion& a, const FMQuaternion& b)
167 {
168 return IsEquivalent(a.x, b.x) && IsEquivalent(a.y, b.y) && IsEquivalent(a.z, b.z) && IsEquivalent(a.w, b.w);
169 }
170
171 #endif // _FM_QUATERNION_H_
172