1 /* Copyright Jukka Jyl�nki
2
3    Licensed under the Apache License, Version 2.0 (the "License");
4    you may not use this file except in compliance with the License.
5    You may obtain a copy of the License at
6
7        http://www.apache.org/licenses/LICENSE-2.0
8
9    Unless required by applicable law or agreed to in writing, software
10    distributed under the License is distributed on an "AS IS" BASIS,
11    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12    See the License for the specific language governing permissions and
13    limitations under the License. */
14
15 /** @file Quat.h
16         @author Jukka Jyl�nki
17         @brief Quaternions represent rotations and orientations of 3D objects. */
18 #pragma once
19
20 #include "../MathBuildConfig.h"
21 #include "SSEMath.h"
22
23 #ifdef MATH_ENABLE_STL_SUPPORT
24 #include <string>
25 #endif
26 #include "../MathGeoLibFwd.h"
27
28 #ifdef MATH_QT_INTEROP
29 #include <QQuaternion>
30 #endif
31 #ifdef MATH_OGRE_INTEROP
32 #include <OgreQuaternion.h>
33 #endif
34 #ifdef MATH_BULLET_INTEROP
35 #include <LinearMath/btQuaternion.h>
36 #endif
37 #ifdef MATH_URHO3D_INTEROP
38 #include <Urho3D/Math/Quaternion.h>
39 #endif
40
41 MATH_BEGIN_NAMESPACE
42
43 /// Represents a rotation or an orientation of a 3D object.
44 class ALIGN16 Quat
45 {
46 public:
47
48 #ifdef MATH_SIMD
49         NAMELESS_UNION_BEGIN // Allow nonstandard nameless struct in union extension on MSC.
50
51         union
52         {
53                 struct
54                 {
55 #endif
56                         
57                         float x///< The factor of i.
58                         float y///< The factor of j. [similarOverload: x]
59                         float z///< The factor of k. [similarOverload: x]
60                         float w///< The scalar part. Sometimes also referred to as 'r'. [similarOverload: x]
61 #ifdef MATH_SIMD
62                 };
63                 simd4f q;
64         };
65
66         NAMELESS_UNION_END
67
68         Quat(simd4f quat):q(quat) {}
69         inline Quat &operator =(simd4f quat) { q = quat; return *this; }
70         inline operator simd4f() const return q; }
71 #endif
72
73         /// @note The default ctor does not initialize any member values.
74         Quat() {}
75
76 #ifdef MATH_EXPLICIT_COPYCTORS
77         /// The copy-ctor for Quat is the trivial copy-ctor, but it is explicitly written to be able to automatically pick up
78         /// this function for QtScript bindings.
79         Quat(const Quat &rhs) { x = rhs.x; y = rhs.y; z = rhs.z; w = rhs.w; }
80 #endif
81
82         /// Constructs a quaternion from the given data buffer.
83         /// @param data An array of four floats to use for the quaternion, in the order 'x, y, z, w'. (== 'i, j, k, r')
84         /// @note The input data is not normalized after construction, this has to be done manually.
85         explicit Quat(const float *data);
86
87         explicit Quat(const float3x3 &rotationMatrix) { Set(rotationMatrix); }
88         explicit Quat(const float3x4 &rotationMatrix) { Set(rotationMatrix); }
89         explicit Quat(const float4x4 &rotationMatrix) { Set(rotationMatrix); }
90
91         /// @param x The factor of i.
92         /// @param y The factor of j.
93         /// @param z The factor of k.
94         /// @param w The scalar factor (or 'w').
95         /// @note The input data is not normalized after construction, this has to be done manually.
96         Quat(float x, float y, float z, float w);
97
98         /// Constructs this quaternion by specifying a rotation axis and the amount of rotation to be performed
99         /// about that axis.
100         /** @param rotationAxis The normalized rotation axis to rotate about. If using the float4 version of the constructor, the w component of this vector must be 0.
101                 @param rotationAngleRadians The angle to rotate by, in radians. For example, Pi/4.f equals to 45 degrees, Pi/2.f is 90 degrees, and Pi is 180 degrees.
102                 @see DegToRad(). */
103         Quat(const float3 &rotationAxis, float rotationAngleRadians) { SetFromAxisAngle(rotationAxis, rotationAngleRadians); }
104         Quat(const float4 &rotationAxis, float rotationAngleRadians) { SetFromAxisAngle(rotationAxis, rotationAngleRadians); }
105
106         /// Returns the local +X axis in the post-transformed coordinate space. This is the same as transforming the vector (1,0,0) by this quaternion.
107         vec WorldX() const;
108         /// Returns the local +Y axis in the post-transformed coordinate space. This is the same as transforming the vector (0,1,0) by this quaternion.
109         vec WorldY() const;
110         /// Returns the local +Z axis in the post-transformed coordinate space. This is the same as transforming the vector (0,0,1) by this quaternion.
111         vec WorldZ() const;
112
113         /// Returns the axis of rotation for this quaternion.
114         vec Axis() const;
115
116         /// Returns the angle of rotation for this quaternion, in radians.
117         float Angle() const;
118
119         /// Computes the dot product of this and the given quaternion.
120         /// Dot product is commutative.
121         float Dot(const Quat &rhs) const;
122
123         float LengthSq() const;
124
125         float Length() const;
126
127         /// Normalizes this quaternion in-place.
128         /// Returns the old length of this quaternion, or 0 if normalization failed.
129         float Normalize();
130
131         /// Returns a normalized copy of this quaternion.
132         Quat Normalized() const;
133
134         /// Returns true if the length of this quaternion is one.
135         bool IsNormalized(float epsilon = 1e-5f) const;
136
137         bool IsInvertible(float epsilon = 1e-3f) const;
138
139         /// Returns true if the entries of this quaternion are all finite.
140         bool IsFinite() const;
141
142         /// Returns true if this quaternion equals rhs, up to the given epsilon.
143         bool Equals(const Quat &rhs, float epsilon = 1e-3f) const;
144
145         /// Compares whether this Quat and the given Quat are identical bit-by-bit in the underlying representation.
146         /** @note Prefer using this over e.g. memcmp, since there can be SSE-related padding in the structures. */
147         bool BitEquals(const Quat &other) const;
148
149         /// @return A pointer to the first element (x). The data is contiguous in memory.
150         /// ptr[0] gives x, ptr[1] is y, ptr[2] is z and ptr[3] is w.
151         FORCE_INLINE float *ptr() { return &x; }
152         FORCE_INLINE const float *ptr() const return &x; }
153
154         /// Inverses this quaternion in-place.
155         /// @note For optimization purposes, this function assumes that the quaternion is unitary, in which
156         ///        case the inverse of the quaternion is simply just the same as its conjugate. This function
157         ///        does not detect whether the operation succeeded or failed.
158         void Inverse();
159
160         /// Returns an inverted copy of this quaternion.
161         MUST_USE_RESULT Quat Inverted() const;
162
163         /// Inverses this quaternion in-place.
164         /// Call this function when the quaternion is not known beforehand to be normalized. This function
165         /// computes the inverse proper, and normalizes the result.
166         /// @note Because of the normalization, it does not necessarily hold that q * q.InverseAndNormalize() == id.
167         /// @return Returns the old length of this quaternion (not the old length of the inverse quaternion).
168         float InverseAndNormalize();
169
170         /// Computes the conjugate of this quaternion in-place.
171         void Conjugate();
172
173         /// Returns a conjugated copy of this quaternion.
174         MUST_USE_RESULT Quat Conjugated() const;
175
176         /// Rotates the given vector by this quaternion.
177         MUST_USE_RESULT float3 Transform(float x, float y, float z) const;
178         MUST_USE_RESULT float3 Transform(const float3 &vec) const;
179
180         /// Rotates the given vector by this quaternion. The w component of the vector is assumed to be zero or one.
181         MUST_USE_RESULT float4 Transform(const float4 &vec) const;
182
183         MUST_USE_RESULT Quat Lerp(const Quat &target, float t) const;
184         static FORCE_INLINE MUST_USE_RESULT Quat Lerp(const Quat &source, const Quat &target, float t) { return source.Lerp(target, t); }
185         MUST_USE_RESULT Quat Slerp(const Quat &target, float t) const;
186         static FORCE_INLINE MUST_USE_RESULT Quat Slerp(const Quat &source, const Quat &target, float t) { return source.Slerp(target, t); }
187
188         /// Returns the 'from' vector rotated towards the 'to' vector by the given normalized time parameter.
189         /** This function slerps the given 'from' vector towards the 'to' vector.
190                 @param from A normalized direction vector specifying the direction of rotation at t=0.
191                 @param to A normalized direction vector specifying the direction of rotation at t=1.
192                 @param t The interpolation time parameter, in the range [0,1]. Input values outside this range are
193                         silently clamped to the [0, 1] interval.
194                 @return A spherical linear interpolation of the vector 'from' towards the vector 'to'. */
195         static MUST_USE_RESULT float3 SlerpVector(const float3 &from, const float3 &to, float t);
196
197         /// Returns the 'from' vector rotated towards the 'to' vector by the given absolute angle, in radians.
198         /** This function slerps the given 'from' vector towards the 'to' vector.
199                 @param from A normalized direction vector specifying the direction of rotation at angleRadians=0.
200                 @param to A normalized direction vector specifying the target direction to rotate towards.
201                 @param angleRadians The maximum angle to rotate the 'from' vector by, in the range [0, pi]. If the
202                         angle between 'from' and 'to' is smaller than this angle, then the vector 'to' is returned.
203                         Input values outside this range are silently clamped to the [0, pi] interval.
204                 @return A spherical linear interpolation of the vector 'from' towards the vector 'to'. */
205         static MUST_USE_RESULT float3 SlerpVectorAbs(const float3 &from, const float3 &to, float angleRadians);
206
207         /// Returns the angle between this and the target orientation (the shortest route) in radians.
208         MUST_USE_RESULT float AngleBetween(const Quat &target) const;
209         /// Returns the axis of rotation to get from this orientation to target orientation (the shortest route).
210         MUST_USE_RESULT vec AxisFromTo(const Quat &target) const;
211
212         /// Returns the rotation axis and angle of this quaternion.
213         /// @param rotationAxis [out] Received the normalized axis of the rotation.
214         /// @param rotationAngleRadians [out] Receives the angle of rotation around the given axis. This parameter is returned in the range [0, 2pi].
215         void ToAxisAngle(float3 &rotationAxis, float &rotationAngleRadians) const;
216         void ToAxisAngle(float4 &rotationAxis, float &rotationAngleRadians) const;
217         /// Sets this quaternion by specifying the axis about which the rotation is performed, and the angle of rotation.
218         /** @param rotationAxis The axis of rotation. This vector must be normalized to call this function. If using the float4 version of this function, 
219                 then the w component must be zero.
220                 @param rotationAngleRadians The angle of rotation in radians. */
221         void SetFromAxisAngle(const float3 &rotationAxis, float rotationAngleRadians);
222         void SetFromAxisAngle(const float4 &rotationAxis, float rotationAngleRadians);
223
224         /// Sets this quaternion to represent the same rotation as the given matrix.
225         void Set(const float3x3 &matrix);
226         void Set(const float3x4 &matrix);
227         void Set(const float4x4 &matrix);
228         /// Sets all elements of this quaternion.
229         /// @note This sets the raw elements, which do *not* correspond directly to the axis and angle of the rotation. Use
230         ///        SetFromAxisAngle to define this Quat using a rotation axis and an angle.
231         void Set(float x, float y, float z, float w);
232
233         /// Creates a LookAt quaternion.
234         /** A LookAt quaternion is a quaternion that orients an object to face towards a specified target direction.
235                 @param localForward Specifies the forward direction in the local space of the object. This is the direction
236                         the model is facing at in its own local/object space, often +X (1,0,0), +Y (0,1,0) or +Z (0,0,1). The
237                         vector to pass in here depends on the conventions you or your modeling software is using, and it is best
238                         pick one convention for all your objects, and be consistent.                    
239                         This input parameter must be a normalized vector.
240                 @param targetDirection Specifies the desired world space direction the object should look at. This function
241                         will compute a quaternion which will rotate the localForward vector to orient towards this targetDirection
242                         vector. This input parameter must be a normalized vector.
243                 @param localUp Specifies the up direction in the local space of the object. This is the up direction the model
244                         was authored in, often +Y (0,1,0) or +Z (0,0,1). The vector to pass in here depends on the conventions you
245                         or your modeling software is using, and it is best to pick one convention for all your objects, and be
246                         consistent. This input parameter must be a normalized vector. This vector must be perpendicular to the
247                         vector localForward, i.e. localForward.Dot(localUp) == 0.
248                 @param worldUp Specifies the global up direction of the scene in world space. Simply rotating one vector to
249                         coincide with another (localForward->targetDirection) would cause the up direction of the resulting
250                         orientation to drift (e.g. the model could be looking at its target its head slanted sideways). To keep
251                         the up direction straight, this function orients the localUp direction of the model to point towards the
252                         specified worldUp direction (as closely as possible). The worldUp and targetDirection vectors cannot be
253                         collinear, but they do not need to be perpendicular either.
254                 @return A quaternion that maps the given local space forward direction vector to point towards the given target
255                         direction, and the given local up direction towards the given target world up direction. For the returned
256                         quaternion Q it holds that M * localForward = targetDirection, and M * localUp lies in the plane spanned
257                         by the vectors targetDirection and worldUp.
258                 @see RotateFromTo(). */
259         static MUST_USE_RESULT Quat LookAt(const float3 &localForward, const float3 &targetDirection, const float3 &localUp, const float3 &worldUp);
260
261         /// Creates a new quaternion that rotates about the positive X axis by the given angle.
262         static MUST_USE_RESULT Quat RotateX(float angleRadians);
263         /// Creates a new quaternion that rotates about the positive Y axis by the given angle.
264         static MUST_USE_RESULT Quat RotateY(float angleRadians);
265         /// Creates a new quaternion that rotates about the positive Z axis by the given angle.
266         static MUST_USE_RESULT Quat RotateZ(float angleRadians);
267
268         /// Creates a new Quat that rotates about the given axis by the given angle.
269         static MUST_USE_RESULT Quat RotateAxisAngle(const float3 &axisDirection, float angleRadians);
270
271         /// Creates a new quaternion that rotates sourceDirection vector (in world space) to coincide with the
272         /// targetDirection vector (in world space).
273         /// Rotation is performed around the origin.
274         /// The vectors sourceDirection and targetDirection are assumed to be normalized.
275         /// @note There are multiple such rotations - this function returns the rotation that has the shortest angle
276         /// (when decomposed to axis-angle notation).
277         static MUST_USE_RESULT Quat RotateFromTo(const float3 &sourceDirection, const float3 &targetDirection);
278         static MUST_USE_RESULT Quat RotateFromTo(const float4 &sourceDirection, const float4 &targetDirection);
279
280         /// Creates a new quaternion that
281         /// 1. rotates sourceDirection vector to coincide with the targetDirection vector, and then
282         /// 2. rotates sourceDirection2 (which was transformed by 1.) to targetDirection2, but keeping the constraint that
283         ///     sourceDirection must look at targetDirection.
284         static MUST_USE_RESULT Quat RotateFromTo(const float3 &sourceDirection, const float3 &targetDirection,
285                 const float3 &sourceDirection2, const float3 &targetDirection2);
286
287         /// Creates a new Quat from the given sequence of Euler rotation angles (in radians).
288         /** The FromEulerABC function returns a matrix M = A(a) * B(b) * C(c). Rotation
289                 C is applied first, followed by B and then A. [indexTitle: FromEuler***] */
290         static MUST_USE_RESULT Quat FromEulerXYX(float x2, float y, float x);
291         static MUST_USE_RESULT Quat FromEulerXZX(float x2, float z, float x); ///< [similarOverload: FromEulerXYX] [hideIndex]
292         static MUST_USE_RESULT Quat FromEulerYXY(float y2, float x, float y); ///< [similarOverload: FromEulerXYX] [hideIndex]
293         static MUST_USE_RESULT Quat FromEulerYZY(float y2, float z, float y); ///< [similarOverload: FromEulerXYX] [hideIndex]
294         static MUST_USE_RESULT Quat FromEulerZXZ(float z2, float x, float z); ///< [similarOverload: FromEulerXYX] [hideIndex]
295         static MUST_USE_RESULT Quat FromEulerZYZ(float z2, float y, float z); ///< [similarOverload: FromEulerXYX] [hideIndex]
296         static MUST_USE_RESULT Quat FromEulerXYZ(float x, float y, float z); ///< [similarOverload: FromEulerXYX] [hideIndex]
297         static MUST_USE_RESULT Quat FromEulerXZY(float x, float z, float y); ///< [similarOverload: FromEulerXYX] [hideIndex]
298         static MUST_USE_RESULT Quat FromEulerYXZ(float y, float x, float z); ///< [similarOverload: FromEulerXYX] [hideIndex]
299         static MUST_USE_RESULT Quat FromEulerYZX(float y, float z, float x); ///< [similarOverload: FromEulerXYX] [hideIndex]
300         static MUST_USE_RESULT Quat FromEulerZXY(float z, float x, float y); ///< [similarOverload: FromEulerXYX] [hideIndex]
301         static MUST_USE_RESULT Quat FromEulerZYX(float z, float y, float x); ///< [similarOverload: FromEulerXYX] [hideIndex]
302
303         /// Returns a uniformly random unitary quaternion.
304         static MUST_USE_RESULT Quat RandomRotation(LCG &lcg);
305
306         /// Extracts the rotation part of this quaternion into Euler rotation angles (in radians).
307         /** @note It is better to think about the returned float3 as an array of three floats, and
308                         not as a triple of xyz, because e.g. the .y component returned by ToEulerYXZ() does
309                         not return the amount of rotation about the y axis, but contains the amount of rotation
310                         in the second axis, in this case the x axis.
311                 @return A float3 which specifies the rotation of this quaternion in radian Euler angles.
312                         The function ToEulerABC returns a float3 where the first
313                         element ([0], or x) specifies the rotation about the axis A (not necessarily the X axis!),
314                         [1] or y specifies the rotation about the B axis (not necessarily the Y axis!) and
315                         [2] or z specifies the rotation about the C axis (not necessarily the Z axis!). The
316                         order of rotations follows the M*v convention, meaning that ToEulerXYZ returns the Euler
317                         angles for rotating a vector v in the order X * (Y * (Z * v))), i.e. right-to-left. */
318         float3 MUST_USE_RESULT ToEulerXYX() const;
319         float3 MUST_USE_RESULT ToEulerXZX() const///< [similarOverload: ToEulerXYX] [hideIndex]
320         float3 MUST_USE_RESULT ToEulerYXY() const///< [similarOverload: ToEulerXYX] [hideIndex]
321         float3 MUST_USE_RESULT ToEulerYZY() const///< [similarOverload: ToEulerXYX] [hideIndex]
322         float3 MUST_USE_RESULT ToEulerZXZ() const///< [similarOverload: ToEulerXYX] [hideIndex]
323         float3 MUST_USE_RESULT ToEulerZYZ() const///< [similarOverload: ToEulerXYX] [hideIndex]
324         float3 MUST_USE_RESULT ToEulerXYZ() const///< [similarOverload: ToEulerXYX] [hideIndex]
325         float3 MUST_USE_RESULT ToEulerXZY() const///< [similarOverload: ToEulerXYX] [hideIndex]
326         float3 MUST_USE_RESULT ToEulerYXZ() const///< [similarOverload: ToEulerXYX] [hideIndex]
327         float3 MUST_USE_RESULT ToEulerYZX() const///< [similarOverload: ToEulerXYX] [hideIndex]
328         float3 MUST_USE_RESULT ToEulerZXY() const///< [similarOverload: ToEulerXYX] [hideIndex]
329         float3 MUST_USE_RESULT ToEulerZYX() const///< [similarOverload: ToEulerXYX] [hideIndex]
330
331         float3x3 MUST_USE_RESULT ToFloat3x3() const;
332         float3x4 MUST_USE_RESULT ToFloat3x4() const;
333         float4x4 MUST_USE_RESULT ToFloat4x4() const;
334         float4x4 MUST_USE_RESULT ToFloat4x4(const float3 &translation) const;
335         float4x4 MUST_USE_RESULT ToFloat4x4(const float4 &translation) const;
336
337 #ifdef MATH_ENABLE_STL_SUPPORT
338         /// Returns "(x,y,z,w)".
339         std::string MUST_USE_RESULT ToString() const;
340
341         /// Returns "Quat(axis:(x,y,z) angle:degrees)".
342         std::string MUST_USE_RESULT ToString2() const;
343
344         /// Returns "x,y,z,w". This is the preferred format for the quaternion if it has to be serialized to a string for machine transfer.
345         std::string MUST_USE_RESULT SerializeToString() const;
346
347         /// Returns a string of C++ code that can be used to construct this object. Useful for generating test cases from badly behaving objects.
348         std::string SerializeToCodeString() const;
349 #endif
350         /// Parses a string that is of form "x,y,z,w" or "(x,y,z,w)" or "(x;y;z;w)" or "x y z w" to a new quaternion.
351         static MUST_USE_RESULT Quat FromString(const char *str, const char **outEndStr = 0);
352 #ifdef MATH_ENABLE_STL_SUPPORT
353         static MUST_USE_RESULT Quat FromString(const std::string &str) { return FromString(str.c_str()); }
354 #endif
355
356         /// Multiplies two quaternions together.
357         /// The product q1 * q2 returns a quaternion that concatenates the two orientation rotations. The rotation
358         /// q2 is applied first before q1.
359         Quat operator *(const Quat &rhs) const;
360
361         /// Transforms the given vector by this Quaternion.
362         /// @note Technically, this function does not perform a simple multiplication of 'q * v',
363         /// but instead performs a conjugation operation 'q*v*q^-1'. This corresponds to transforming
364         /// the given vector by this Quaternion.
365         float3 operator *(const float3 &rhs) const;
366         float4 operator *(const float4 &rhs) const;
367
368         /// The identity quaternion performs no rotation when applied to a vector.
369         /// For quaternions, the identity has the value r = 1, i,j,k = 0.
370         static const Quat identity;
371         /// A compile-time constant Quat with value (NaN, NaN, NaN, NaN).
372         /// For this constant, each element has the value of quiet NaN, or Not-A-Number.
373         /// @note Never compare a Quat to this value! Due to how IEEE floats work, "nan == nan" returns false!
374         ///        That is, nothing is equal to NaN, not even NaN itself!
375         static const Quat nan;
376
377         /// Divides a quaternion by another. Division "a / b" results in a quaternion that rotates the orientation b to coincide with the orientation a.
378         Quat operator /(const Quat &rhs) const;
379
380         /// Unary operator + allows this structure to be used in an expression '+x'.
381         Quat operator +() const return *this; }
382
383 #ifdef MATH_OGRE_INTEROP
384         Quat(const Ogre::Quaternion &other):x(other.x), y(other.y), z(other.z), w(other.w) {}
385         operator Ogre::Quaternion() const return Ogre::Quaternion(w, x, y, z); }
386 #endif
387 #ifdef MATH_QT_INTEROP
388         Quat(const QQuaternion &other):x(other.x()), y(other.y()), z(other.z()), w(other.w()) {}
389         operator QQuaternion() const return QQuaternion(w, x, y, z); }
390         operator QString() const return toString(); }
391         QString toString() const return ToString2().c_str(); }
392         QQuaternion ToQQuaternion() const return (QQuaternion)*this; }
393         static MUST_USE_RESULT Quat FromQQuaternion(const QQuaternion &q) { return (Quat)q; }
394         static MUST_USE_RESULT Quat FromString(const QString &str) { return FromString(str.toStdString()); }
395 #endif
396 #ifdef MATH_BULLET_INTEROP
397         Quat(const btQuaternion &other):x(other.x()), y(other.y()), z(other.z()), w(other.w()) {}
398         operator btQuaternion() const return btQuaternion(x, y, z, w); }
399 #endif
400 #ifdef MATH_URHO3D_INTEROP
401         Quat(const Urho3D::Quaternion &other) : x(other.x_), y(other.y_), z(other.z_), w(other.w_) {}
402         operator Urho3D::Quaternion() const return Urho3D::Quaternion(w, x, y, z); }
403 #endif
404
405         /// Multiplies two quaternions in the order 'this * rhs'.
406         /// This corresponds to the concatenation of the two operations ('this * rhs * vector' applies the rotation 'rhs' first, followed by the rotation 'this'.
407         Quat MUST_USE_RESULT Mul(const Quat &rhs) const;
408         /// Converts the given matrix to a quaternion and computes the concatenated transform 'this * rhs'.
409         Quat MUST_USE_RESULT Mul(const float3x3 &rhs) const;
410         /// Transforms the given vector by this Quaternion.
411         /// @note Technically, this function does not perform a simple multiplication of 'q * v',
412         /// but instead performs a conjugation operation 'q*v*q^-1'. This corresponds to transforming
413         /// the given vector by this Quaternion.
414         float3 MUST_USE_RESULT Mul(const float3 &vector) const;
415         float4 MUST_USE_RESULT Mul(const float4 &vector) const;
416
417         /// Negates the quaternion.
418         /// @note Negating a quaternion will not produce the inverse rotation. Call Quat::Inverse() to generate the inverse rotation.
419         Quat Neg() const return -*this; }
420
421 private// Hide the unsafe operations from the user, so that he doesn't accidentally invoke an unintended operation.
422
423         /// Multiplies a quaternion by a scalar.
424         /// @note Technically, multiplication by scalar would not affect the rotation this quaternion represents, but since
425         /// Quat uses conjugation to compute the inverse (to optimize), an unnormalized quaternion will not produce a proper rotation transform.
426         /// @note Multiplication by a scalar does not "accumulate" rotations, e.g. "quat * 5.f" will not produce a quaternion that would rotate
427         ///                     "5 times more".
428         Quat operator *(float scalar) const;
429
430         Quat operator /(float scalar) const;
431
432         /// Adds two quaternions.
433         /// @note Adding two quaternions does not concatenate the two rotation operations. Use quaternion multiplication to achieve that.
434         Quat operator +(const Quat &rhs) const;
435
436         Quat operator -(const Quat &rhs) const;
437
438         /// Negates the quaternion.
439         /// @note Negating a quaternion will not produce the inverse rotation. Call Quat::Inverse() to generate the inverse rotation.
440         Quat operator -() const;
441 };
442
443 #ifdef MATH_ENABLE_STL_SUPPORT
444 /// Prints this Quat to the given stream.
445 std::ostream &operator <<(std::ostream &out, const Quat &rhs);
446 #endif
447
448 FORCE_INLINE Quat Lerp(const Quat &a, const Quat &b, float t) { return a.Lerp(b, t); }
449 FORCE_INLINE Quat Slerp(const Quat &a, const Quat &b, float t) { return a.Slerp(b, t); }
450
451 #ifdef MATH_QT_INTEROP
452 Q_DECLARE_METATYPE(Quat)
453 Q_DECLARE_METATYPE(Quat*)
454 #endif
455
456 MATH_END_NAMESPACE

Go back to previous page