Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre_src_v1-9-0/OgreMain/include/OgreQuaternion.h @ 148

Last change on this file since 148 was 148, checked in by patricwi, 6 years ago

Added new dependencies for ogre1.9 and cegui0.8

File size: 12.0 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2013 Torus Knot Software Ltd
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25THE SOFTWARE.
26-----------------------------------------------------------------------------
27*/
28// This file is based on material originally from:
29// Geometric Tools, LLC
30// Copyright (c) 1998-2010
31// Distributed under the Boost Software License, Version 1.0.
32// http://www.boost.org/LICENSE_1_0.txt
33// http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
34
35
36#ifndef __Quaternion_H__
37#define __Quaternion_H__
38
39#include "OgrePrerequisites.h"
40#include "OgreMath.h"
41
42namespace Ogre {
43
44        /** \addtogroup Core
45        *  @{
46        */
47        /** \addtogroup Math
48        *  @{
49        */
50        /** Implementation of a Quaternion, i.e. a rotation around an axis.
51                For more information about Quaternions and the theory behind it, we recommend reading:
52                http://www.ogre3d.org/tikiwiki/Quaternion+and+Rotation+Primer
53                http://www.cprogramming.com/tutorial/3d/quaternions.html
54                http://www.gamedev.net/page/resources/_/reference/programming/math-and-physics/
55                quaternions/quaternion-powers-r1095
56    */
57    class _OgreExport Quaternion
58    {
59    public:
60                /// Default constructor, initializes to identity rotation (aka 0°)
61                inline Quaternion ()
62                        : w(1), x(0), y(0), z(0)
63                {
64                }
65                /// Construct from an explicit list of values
66                inline Quaternion (
67                        Real fW,
68                        Real fX, Real fY, Real fZ)
69                        : w(fW), x(fX), y(fY), z(fZ)
70                {
71                }
72        /// Construct a quaternion from a rotation matrix
73        inline Quaternion(const Matrix3& rot)
74        {
75            this->FromRotationMatrix(rot);
76        }
77        /// Construct a quaternion from an angle/axis
78        inline Quaternion(const Radian& rfAngle, const Vector3& rkAxis)
79        {
80            this->FromAngleAxis(rfAngle, rkAxis);
81        }
82        /// Construct a quaternion from 3 orthonormal local axes
83        inline Quaternion(const Vector3& xaxis, const Vector3& yaxis, const Vector3& zaxis)
84        {
85            this->FromAxes(xaxis, yaxis, zaxis);
86        }
87        /// Construct a quaternion from 3 orthonormal local axes
88        inline Quaternion(const Vector3* akAxis)
89        {
90            this->FromAxes(akAxis);
91        }
92                /// Construct a quaternion from 4 manual w/x/y/z values
93                inline Quaternion(Real* valptr)
94                {
95                        memcpy(&w, valptr, sizeof(Real)*4);
96                }
97
98                /** Exchange the contents of this quaternion with another.
99                */
100                inline void swap(Quaternion& other)
101                {
102                        std::swap(w, other.w);
103                        std::swap(x, other.x);
104                        std::swap(y, other.y);
105                        std::swap(z, other.z);
106                }
107
108                /// Array accessor operator
109                inline Real operator [] ( const size_t i ) const
110                {
111                        assert( i < 4 );
112
113                        return *(&w+i);
114                }
115
116                /// Array accessor operator
117                inline Real& operator [] ( const size_t i )
118                {
119                        assert( i < 4 );
120
121                        return *(&w+i);
122                }
123
124                /// Pointer accessor for direct copying
125                inline Real* ptr()
126                {
127                        return &w;
128                }
129
130                /// Pointer accessor for direct copying
131                inline const Real* ptr() const
132                {
133                        return &w;
134                }
135
136                void FromRotationMatrix (const Matrix3& kRot);
137        void ToRotationMatrix (Matrix3& kRot) const;
138                /** Setups the quaternion using the supplied vector, and "roll" around
139                        that vector by the specified radians.
140                */
141        void FromAngleAxis (const Radian& rfAngle, const Vector3& rkAxis);
142        void ToAngleAxis (Radian& rfAngle, Vector3& rkAxis) const;
143        inline void ToAngleAxis (Degree& dAngle, Vector3& rkAxis) const {
144            Radian rAngle;
145            ToAngleAxis ( rAngle, rkAxis );
146            dAngle = rAngle;
147        }
148                /** Constructs the quaternion using 3 axes, the axes are assumed to be orthonormal
149                        @see FromAxes
150                */
151        void FromAxes (const Vector3* akAxis);
152        void FromAxes (const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);
153                /** Gets the 3 orthonormal axes defining the quaternion. @see FromAxes */
154        void ToAxes (Vector3* akAxis) const;
155        void ToAxes (Vector3& xAxis, Vector3& yAxis, Vector3& zAxis) const;
156
157                /** Returns the X orthonormal axis defining the quaternion. Same as doing
158                        xAxis = Vector3::UNIT_X * this. Also called the local X-axis
159                */
160        Vector3 xAxis(void) const;
161
162        /** Returns the Y orthonormal axis defining the quaternion. Same as doing
163                        yAxis = Vector3::UNIT_Y * this. Also called the local Y-axis
164                */
165        Vector3 yAxis(void) const;
166
167                /** Returns the Z orthonormal axis defining the quaternion. Same as doing
168                        zAxis = Vector3::UNIT_Z * this. Also called the local Z-axis
169                */
170        Vector3 zAxis(void) const;
171
172        inline Quaternion& operator= (const Quaternion& rkQ)
173                {
174                        w = rkQ.w;
175                        x = rkQ.x;
176                        y = rkQ.y;
177                        z = rkQ.z;
178                        return *this;
179                }
180        Quaternion operator+ (const Quaternion& rkQ) const;
181        Quaternion operator- (const Quaternion& rkQ) const;
182        Quaternion operator* (const Quaternion& rkQ) const;
183        Quaternion operator* (Real fScalar) const;
184        _OgreExport friend Quaternion operator* (Real fScalar,
185            const Quaternion& rkQ);
186        Quaternion operator- () const;
187        inline bool operator== (const Quaternion& rhs) const
188                {
189                        return (rhs.x == x) && (rhs.y == y) &&
190                                (rhs.z == z) && (rhs.w == w);
191                }
192        inline bool operator!= (const Quaternion& rhs) const
193                {
194                        return !operator==(rhs);
195                }
196        // functions of a quaternion
197        /// Returns the dot product of the quaternion
198        Real Dot (const Quaternion& rkQ) const;
199        /* Returns the normal length of this quaternion.
200            @note This does <b>not</b> alter any values.
201        */
202        Real Norm () const;
203        /// Normalises this quaternion, and returns the previous length
204        Real normalise(void); 
205        Quaternion Inverse () const;  /// Apply to non-zero quaternion
206        Quaternion UnitInverse () const;  /// Apply to unit-length quaternion
207        Quaternion Exp () const;
208        Quaternion Log () const;
209
210        /// Rotation of a vector by a quaternion
211        Vector3 operator* (const Vector3& rkVector) const;
212
213                /** Calculate the local roll element of this quaternion.
214                @param reprojectAxis By default the method returns the 'intuitive' result
215                        that is, if you projected the local Y of the quaternion onto the X and
216                        Y axes, the angle between them is returned. If set to false though, the
217                        result is the actual yaw that will be used to implement the quaternion,
218                        which is the shortest possible path to get to the same orientation and
219             may involve less axial rotation.  The co-domain of the returned value is
220             from -180 to 180 degrees.
221                */
222                Radian getRoll(bool reprojectAxis = true) const;
223                /** Calculate the local pitch element of this quaternion
224                @param reprojectAxis By default the method returns the 'intuitive' result
225                        that is, if you projected the local Z of the quaternion onto the X and
226                        Y axes, the angle between them is returned. If set to true though, the
227                        result is the actual yaw that will be used to implement the quaternion,
228                        which is the shortest possible path to get to the same orientation and
229            may involve less axial rotation.  The co-domain of the returned value is
230            from -180 to 180 degrees.
231                */
232                Radian getPitch(bool reprojectAxis = true) const;
233                /** Calculate the local yaw element of this quaternion
234                @param reprojectAxis By default the method returns the 'intuitive' result
235                        that is, if you projected the local Y of the quaternion onto the X and
236                        Z axes, the angle between them is returned. If set to true though, the
237                        result is the actual yaw that will be used to implement the quaternion,
238                        which is the shortest possible path to get to the same orientation and
239                        may involve less axial rotation. The co-domain of the returned value is
240            from -180 to 180 degrees.
241                */
242                Radian getYaw(bool reprojectAxis = true) const;         
243                /// Equality with tolerance (tolerance is max angle difference)
244                bool equals(const Quaternion& rhs, const Radian& tolerance) const;
245               
246            /** Performs Spherical linear interpolation between two quaternions, and returns the result.
247                        Slerp ( 0.0f, A, B ) = A
248                        Slerp ( 1.0f, A, B ) = B
249                        @return Interpolated quaternion
250                        @remarks
251                        Slerp has the proprieties of performing the interpolation at constant
252                        velocity, and being torque-minimal (unless shortestPath=false).
253                        However, it's NOT commutative, which means
254                        Slerp ( 0.75f, A, B ) != Slerp ( 0.25f, B, A );
255                        therefore be careful if your code relies in the order of the operands.
256                        This is specially important in IK animation.
257                */
258        static Quaternion Slerp (Real fT, const Quaternion& rkP,
259            const Quaternion& rkQ, bool shortestPath = false);
260
261                /** @see Slerp. It adds extra "spins" (i.e. rotates several times) specified
262                        by parameter 'iExtraSpins' while interpolating before arriving to the
263                        final values
264                */
265        static Quaternion SlerpExtraSpins (Real fT,
266            const Quaternion& rkP, const Quaternion& rkQ,
267            int iExtraSpins);
268
269        /// Setup for spherical quadratic interpolation
270        static void Intermediate (const Quaternion& rkQ0,
271            const Quaternion& rkQ1, const Quaternion& rkQ2,
272            Quaternion& rka, Quaternion& rkB);
273
274        /// Spherical quadratic interpolation
275        static Quaternion Squad (Real fT, const Quaternion& rkP,
276            const Quaternion& rkA, const Quaternion& rkB,
277            const Quaternion& rkQ, bool shortestPath = false);
278
279        /** Performs Normalised linear interpolation between two quaternions, and returns the result.
280                        nlerp ( 0.0f, A, B ) = A
281                        nlerp ( 1.0f, A, B ) = B
282                        @remarks
283                        Nlerp is faster than Slerp.
284                        Nlerp has the proprieties of being commutative (@see Slerp;
285                        commutativity is desired in certain places, like IK animation), and
286                        being torque-minimal (unless shortestPath=false). However, it's performing
287                        the interpolation at non-constant velocity; sometimes this is desired,
288                        sometimes it is not. Having a non-constant velocity can produce a more
289                        natural rotation feeling without the need of tweaking the weights; however
290                        if your scene relies on the timing of the rotation or assumes it will point
291                        at a specific angle at a specific weight value, Slerp is a better choice.
292                */
293        static Quaternion nlerp(Real fT, const Quaternion& rkP, 
294            const Quaternion& rkQ, bool shortestPath = false);
295
296        /// Cutoff for sine near zero
297        static const Real msEpsilon;
298
299        // special values
300        static const Quaternion ZERO;
301        static const Quaternion IDENTITY;
302
303                Real w, x, y, z;
304
305                /// Check whether this quaternion contains valid values
306                inline bool isNaN() const
307                {
308                        return Math::isNaN(x) || Math::isNaN(y) || Math::isNaN(z) || Math::isNaN(w);
309                }
310
311        /** Function for writing to a stream. Outputs "Quaternion(w, x, y, z)" with w,x,y,z
312            being the member values of the quaternion.
313        */
314        inline _OgreExport friend std::ostream& operator <<
315            ( std::ostream& o, const Quaternion& q )
316        {
317            o << "Quaternion(" << q.w << ", " << q.x << ", " << q.y << ", " << q.z << ")";
318            return o;
319        }
320
321    };
322        /** @} */
323        /** @} */
324
325}
326
327
328
329
330#endif
Note: See TracBrowser for help on using the repository browser.