[692] | 1 | /*
|
---|
| 2 | -----------------------------------------------------------------------------
|
---|
| 3 | This source file is part of OGRE
|
---|
| 4 | (Object-oriented Graphics Rendering Engine)
|
---|
| 5 | For the latest info, see http://www.ogre3d.org/
|
---|
| 6 |
|
---|
| 7 | Copyright (c) 2000-2005 The OGRE Team
|
---|
| 8 | Also see acknowledgements in Readme.html
|
---|
| 9 |
|
---|
| 10 | This program is free software; you can redistribute it and/or modify it under
|
---|
| 11 | the terms of the GNU Lesser General Public License as published by the Free Software
|
---|
| 12 | Foundation; either version 2 of the License, or (at your option) any later
|
---|
| 13 | version.
|
---|
| 14 |
|
---|
| 15 | This program is distributed in the hope that it will be useful, but WITHOUT
|
---|
| 16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
---|
| 17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
---|
| 18 |
|
---|
| 19 | You should have received a copy of the GNU Lesser General Public License along with
|
---|
| 20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
---|
| 21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
---|
| 22 | http://www.gnu.org/copyleft/lesser.txt.
|
---|
| 23 | -----------------------------------------------------------------------------
|
---|
| 24 | */
|
---|
| 25 | // NOTE THAT THIS FILE IS BASED ON MATERIAL FROM:
|
---|
| 26 |
|
---|
| 27 | // Magic Software, Inc.
|
---|
| 28 | // http://www.geometrictools.com/
|
---|
| 29 | // Copyright (c) 2000, All Rights Reserved
|
---|
| 30 | //
|
---|
| 31 | // Source code from Magic Software is supplied under the terms of a license
|
---|
| 32 | // agreement and may not be copied or disclosed except in accordance with the
|
---|
| 33 | // terms of that agreement. The various license agreements may be found at
|
---|
| 34 | // the Magic Software web site. This file is subject to the license
|
---|
| 35 | //
|
---|
| 36 | // FREE SOURCE CODE
|
---|
| 37 | // http://www.geometrictools.com/License/WildMagic3License.pdf
|
---|
| 38 |
|
---|
| 39 | #ifndef __Quaternion_H__
|
---|
| 40 | #define __Quaternion_H__
|
---|
| 41 |
|
---|
| 42 | #include "OgrePrerequisites.h"
|
---|
| 43 | #include "OgreMath.h"
|
---|
| 44 |
|
---|
| 45 | namespace Ogre {
|
---|
| 46 |
|
---|
| 47 | /** Implementation of a Quaternion, i.e. a rotation around an axis.
|
---|
| 48 | */
|
---|
| 49 | class _OgreExport Quaternion
|
---|
| 50 | {
|
---|
| 51 | public:
|
---|
| 52 | inline Quaternion (
|
---|
| 53 | Real fW = 1.0,
|
---|
| 54 | Real fX = 0.0, Real fY = 0.0, Real fZ = 0.0)
|
---|
| 55 | {
|
---|
| 56 | w = fW;
|
---|
| 57 | x = fX;
|
---|
| 58 | y = fY;
|
---|
| 59 | z = fZ;
|
---|
| 60 | }
|
---|
| 61 | inline Quaternion (const Quaternion& rkQ)
|
---|
| 62 | {
|
---|
| 63 | w = rkQ.w;
|
---|
| 64 | x = rkQ.x;
|
---|
| 65 | y = rkQ.y;
|
---|
| 66 | z = rkQ.z;
|
---|
| 67 | }
|
---|
| 68 | /// Construct a quaternion from a rotation matrix
|
---|
| 69 | inline Quaternion(const Matrix3& rot)
|
---|
| 70 | {
|
---|
| 71 | this->FromRotationMatrix(rot);
|
---|
| 72 | }
|
---|
| 73 | /// Construct a quaternion from an angle/axis
|
---|
| 74 | inline Quaternion(const Radian& rfAngle, const Vector3& rkAxis)
|
---|
| 75 | {
|
---|
| 76 | this->FromAngleAxis(rfAngle, rkAxis);
|
---|
| 77 | }
|
---|
| 78 | #ifndef OGRE_FORCE_ANGLE_TYPES
|
---|
| 79 | inline Quaternion(const Real& rfAngle, const Vector3& rkAxis)
|
---|
| 80 | {
|
---|
| 81 | this->FromAngleAxis(rfAngle, rkAxis);
|
---|
| 82 | }
|
---|
| 83 | #endif//OGRE_FORCE_ANGLE_TYPES
|
---|
| 84 | /// Construct a quaternion from 3 orthonormal local axes
|
---|
| 85 | inline Quaternion(const Vector3& xaxis, const Vector3& yaxis, const Vector3& zaxis)
|
---|
| 86 | {
|
---|
| 87 | this->FromAxes(xaxis, yaxis, zaxis);
|
---|
| 88 | }
|
---|
| 89 | /// Construct a quaternion from 3 orthonormal local axes
|
---|
| 90 | inline Quaternion(const Vector3* akAxis)
|
---|
| 91 | {
|
---|
| 92 | this->FromAxes(akAxis);
|
---|
| 93 | }
|
---|
| 94 | /// Construct a quaternion from 4 manual w/x/y/z values
|
---|
| 95 | inline Quaternion(Real* valptr)
|
---|
| 96 | {
|
---|
| 97 | memcpy(val, valptr, sizeof(Real)*4);
|
---|
| 98 | }
|
---|
| 99 |
|
---|
| 100 | void FromRotationMatrix (const Matrix3& kRot);
|
---|
| 101 | void ToRotationMatrix (Matrix3& kRot) const;
|
---|
| 102 | void FromAngleAxis (const Radian& rfAngle, const Vector3& rkAxis);
|
---|
| 103 | void ToAngleAxis (Radian& rfAngle, Vector3& rkAxis) const;
|
---|
| 104 | inline void ToAngleAxis (Degree& dAngle, Vector3& rkAxis) const {
|
---|
| 105 | Radian rAngle;
|
---|
| 106 | ToAngleAxis ( rAngle, rkAxis );
|
---|
| 107 | dAngle = rAngle;
|
---|
| 108 | }
|
---|
| 109 | #ifndef OGRE_FORCE_ANGLE_TYPES
|
---|
| 110 | inline void FromAngleAxis (const Real& rfAngle, const Vector3& rkAxis) {
|
---|
| 111 | FromAngleAxis ( Angle(rfAngle), rkAxis );
|
---|
| 112 | }
|
---|
| 113 | inline void ToAngleAxis (Real& rfAngle, Vector3& rkAxis) const {
|
---|
| 114 | Radian r;
|
---|
| 115 | ToAngleAxis ( r, rkAxis );
|
---|
| 116 | rfAngle = r.valueAngleUnits();
|
---|
| 117 | }
|
---|
| 118 | #endif//OGRE_FORCE_ANGLE_TYPES
|
---|
| 119 | void FromAxes (const Vector3* akAxis);
|
---|
| 120 | void FromAxes (const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);
|
---|
| 121 | void ToAxes (Vector3* akAxis) const;
|
---|
| 122 | void ToAxes (Vector3& xAxis, Vector3& yAxis, Vector3& zAxis) const;
|
---|
| 123 | /// Get the local x-axis
|
---|
| 124 | Vector3 xAxis(void) const;
|
---|
| 125 | /// Get the local y-axis
|
---|
| 126 | Vector3 yAxis(void) const;
|
---|
| 127 | /// Get the local z-axis
|
---|
| 128 | Vector3 zAxis(void) const;
|
---|
| 129 |
|
---|
| 130 | inline Quaternion& operator= (const Quaternion& rkQ)
|
---|
| 131 | {
|
---|
| 132 | w = rkQ.w;
|
---|
| 133 | x = rkQ.x;
|
---|
| 134 | y = rkQ.y;
|
---|
| 135 | z = rkQ.z;
|
---|
| 136 | return *this;
|
---|
| 137 | }
|
---|
| 138 | Quaternion operator+ (const Quaternion& rkQ) const;
|
---|
| 139 | Quaternion operator- (const Quaternion& rkQ) const;
|
---|
| 140 | Quaternion operator* (const Quaternion& rkQ) const;
|
---|
| 141 | Quaternion operator* (Real fScalar) const;
|
---|
| 142 | _OgreExport friend Quaternion operator* (Real fScalar,
|
---|
| 143 | const Quaternion& rkQ);
|
---|
| 144 | Quaternion operator- () const;
|
---|
| 145 | inline bool operator== (const Quaternion& rhs) const
|
---|
| 146 | {
|
---|
| 147 | return (rhs.x == x) && (rhs.y == y) &&
|
---|
| 148 | (rhs.z == z) && (rhs.w == w);
|
---|
| 149 | }
|
---|
| 150 | inline bool operator!= (const Quaternion& rhs) const
|
---|
| 151 | {
|
---|
| 152 | return !operator==(rhs);
|
---|
| 153 | }
|
---|
| 154 | // functions of a quaternion
|
---|
| 155 | Real Dot (const Quaternion& rkQ) const; // dot product
|
---|
| 156 | Real Norm () const; // squared-length
|
---|
| 157 | /// Normalises this quaternion, and returns the previous length
|
---|
| 158 | Real normalise(void);
|
---|
| 159 | Quaternion Inverse () const; // apply to non-zero quaternion
|
---|
| 160 | Quaternion UnitInverse () const; // apply to unit-length quaternion
|
---|
| 161 | Quaternion Exp () const;
|
---|
| 162 | Quaternion Log () const;
|
---|
| 163 |
|
---|
| 164 | // rotation of a vector by a quaternion
|
---|
| 165 | Vector3 operator* (const Vector3& rkVector) const;
|
---|
| 166 |
|
---|
| 167 | /// Calculate the local roll element of this quaternion
|
---|
| 168 | Radian getRoll(void) const;
|
---|
| 169 | /// Calculate the local pitch element of this quaternion
|
---|
| 170 | Radian getPitch(void) const;
|
---|
| 171 | /// Calculate the local yaw element of this quaternion
|
---|
| 172 | Radian getYaw(void) const;
|
---|
| 173 | /// Equality with tolerance (tolerance is max angle difference)
|
---|
| 174 | bool equals(const Quaternion& rhs, const Radian& tolerance) const;
|
---|
| 175 |
|
---|
| 176 | // spherical linear interpolation
|
---|
| 177 | static Quaternion Slerp (Real fT, const Quaternion& rkP,
|
---|
| 178 | const Quaternion& rkQ, bool shortestPath = false);
|
---|
| 179 |
|
---|
| 180 | static Quaternion SlerpExtraSpins (Real fT,
|
---|
| 181 | const Quaternion& rkP, const Quaternion& rkQ,
|
---|
| 182 | int iExtraSpins);
|
---|
| 183 |
|
---|
| 184 | // setup for spherical quadratic interpolation
|
---|
| 185 | static void Intermediate (const Quaternion& rkQ0,
|
---|
| 186 | const Quaternion& rkQ1, const Quaternion& rkQ2,
|
---|
| 187 | Quaternion& rka, Quaternion& rkB);
|
---|
| 188 |
|
---|
| 189 | // spherical quadratic interpolation
|
---|
| 190 | static Quaternion Squad (Real fT, const Quaternion& rkP,
|
---|
| 191 | const Quaternion& rkA, const Quaternion& rkB,
|
---|
| 192 | const Quaternion& rkQ, bool shortestPath = false);
|
---|
| 193 |
|
---|
| 194 | // normalised linear interpolation - faster but less accurate (non-constant rotation velocity)
|
---|
| 195 | static Quaternion nlerp(Real fT, const Quaternion& rkP,
|
---|
| 196 | const Quaternion& rkQ, bool shortestPath = false);
|
---|
| 197 |
|
---|
| 198 | // cutoff for sine near zero
|
---|
| 199 | static const Real ms_fEpsilon;
|
---|
| 200 |
|
---|
| 201 | // special values
|
---|
| 202 | static const Quaternion ZERO;
|
---|
| 203 | static const Quaternion IDENTITY;
|
---|
| 204 |
|
---|
| 205 | union
|
---|
| 206 | {
|
---|
| 207 | struct {
|
---|
| 208 | Real w, x, y, z;
|
---|
| 209 | };
|
---|
| 210 | Real val[4];
|
---|
| 211 | };
|
---|
| 212 |
|
---|
| 213 | /** Function for writing to a stream. Outputs "Quaternion(w, x, y, z)" with w,x,y,z
|
---|
| 214 | being the member values of the quaternion.
|
---|
| 215 | */
|
---|
| 216 | inline _OgreExport friend std::ostream& operator <<
|
---|
| 217 | ( std::ostream& o, const Quaternion& q )
|
---|
| 218 | {
|
---|
| 219 | o << "Quaternion(" << q.w << ", " << q.x << ", " << q.y << ", " << q.z << ")";
|
---|
| 220 | return o;
|
---|
| 221 | }
|
---|
| 222 |
|
---|
| 223 | };
|
---|
| 224 |
|
---|
| 225 | }
|
---|
| 226 |
|
---|
| 227 |
|
---|
| 228 |
|
---|
| 229 |
|
---|
| 230 | #endif
|
---|