268 lines
9.0 KiB
C
268 lines
9.0 KiB
C
|
/*
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
This source file is part of OGRE
|
|||
|
(Object-oriented Graphics Rendering Engine)
|
|||
|
For the latest info, see http://www.ogre3d.org/
|
|||
|
|
|||
|
Copyright (c) 2000-2009 Torus Knot Software Ltd
|
|||
|
|
|||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|||
|
of this software and associated documentation files (the "Software"), to deal
|
|||
|
in the Software without restriction, including without limitation the rights
|
|||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
|
copies of the Software, and to permit persons to whom the Software is
|
|||
|
furnished to do so, subject to the following conditions:
|
|||
|
|
|||
|
The above copyright notice and this permission notice shall be included in
|
|||
|
all copies or substantial portions of the Software.
|
|||
|
|
|||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
|
THE SOFTWARE.
|
|||
|
-----------------------------------------------------------------------------
|
|||
|
*/
|
|||
|
// This file is based on material originally from:
|
|||
|
// Geometric Tools, LLC
|
|||
|
// Copyright (c) 1998-2010
|
|||
|
// Distributed under the Boost Software License, Version 1.0.
|
|||
|
// http://www.boost.org/LICENSE_1_0.txt
|
|||
|
// http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
|
|||
|
|
|||
|
|
|||
|
#ifndef __Quaternion_H__
|
|||
|
#define __Quaternion_H__
|
|||
|
|
|||
|
#include "OgrePrerequisites.h"
|
|||
|
#include "OgreMath.h"
|
|||
|
|
|||
|
namespace Ogre {
|
|||
|
|
|||
|
/** \addtogroup Core
|
|||
|
* @{
|
|||
|
*/
|
|||
|
/** \addtogroup Math
|
|||
|
* @{
|
|||
|
*/
|
|||
|
/** Implementation of a Quaternion, i.e. a rotation around an axis.
|
|||
|
*/
|
|||
|
class Quaternion
|
|||
|
{
|
|||
|
public:
|
|||
|
inline Quaternion (
|
|||
|
Real fW = 1.0,
|
|||
|
Real fX = 0.0, Real fY = 0.0, Real fZ = 0.0)
|
|||
|
{
|
|||
|
w = fW;
|
|||
|
x = fX;
|
|||
|
y = fY;
|
|||
|
z = fZ;
|
|||
|
}
|
|||
|
/// Construct a quaternion from a rotation matrix
|
|||
|
inline Quaternion(const Matrix3& rot)
|
|||
|
{
|
|||
|
this->FromRotationMatrix(rot);
|
|||
|
}
|
|||
|
/// Construct a quaternion from an angle/axis
|
|||
|
inline Quaternion(const Radian& rfAngle, const Vector3& rkAxis)
|
|||
|
{
|
|||
|
this->FromAngleAxis(rfAngle, rkAxis);
|
|||
|
}
|
|||
|
/// Construct a quaternion from 3 orthonormal local axes
|
|||
|
inline Quaternion(const Vector3& xaxis, const Vector3& yaxis, const Vector3& zaxis)
|
|||
|
{
|
|||
|
this->FromAxes(xaxis, yaxis, zaxis);
|
|||
|
}
|
|||
|
/// Construct a quaternion from 3 orthonormal local axes
|
|||
|
inline Quaternion(const Vector3* akAxis)
|
|||
|
{
|
|||
|
this->FromAxes(akAxis);
|
|||
|
}
|
|||
|
/// Construct a quaternion from 4 manual w/x/y/z values
|
|||
|
inline Quaternion(Real* valptr)
|
|||
|
{
|
|||
|
memcpy(&w, valptr, sizeof(Real)*4);
|
|||
|
}
|
|||
|
|
|||
|
/** Exchange the contents of this quaternion with another.
|
|||
|
*/
|
|||
|
inline void swap(Quaternion& other)
|
|||
|
{
|
|||
|
std::swap(w, other.w);
|
|||
|
std::swap(x, other.x);
|
|||
|
std::swap(y, other.y);
|
|||
|
std::swap(z, other.z);
|
|||
|
}
|
|||
|
|
|||
|
/// Array accessor operator
|
|||
|
inline Real operator [] ( const size_t i ) const
|
|||
|
{
|
|||
|
assert( i < 4 );
|
|||
|
|
|||
|
return *(&w+i);
|
|||
|
}
|
|||
|
|
|||
|
/// Array accessor operator
|
|||
|
inline Real& operator [] ( const size_t i )
|
|||
|
{
|
|||
|
assert( i < 4 );
|
|||
|
|
|||
|
return *(&w+i);
|
|||
|
}
|
|||
|
|
|||
|
/// Pointer accessor for direct copying
|
|||
|
inline Real* ptr()
|
|||
|
{
|
|||
|
return &w;
|
|||
|
}
|
|||
|
|
|||
|
/// Pointer accessor for direct copying
|
|||
|
inline const Real* ptr() const
|
|||
|
{
|
|||
|
return &w;
|
|||
|
}
|
|||
|
|
|||
|
void FromRotationMatrix (const Matrix3& kRot);
|
|||
|
void ToRotationMatrix (Matrix3& kRot) const;
|
|||
|
void FromAngleAxis (const Radian& rfAngle, const Vector3& rkAxis);
|
|||
|
void ToAngleAxis (Radian& rfAngle, Vector3& rkAxis) const;
|
|||
|
inline void ToAngleAxis (Degree& dAngle, Vector3& rkAxis) const {
|
|||
|
Radian rAngle;
|
|||
|
ToAngleAxis ( rAngle, rkAxis );
|
|||
|
dAngle = rAngle;
|
|||
|
}
|
|||
|
void FromAxes (const Vector3* akAxis);
|
|||
|
void FromAxes (const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);
|
|||
|
void ToAxes (Vector3* akAxis) const;
|
|||
|
void ToAxes (Vector3& xAxis, Vector3& yAxis, Vector3& zAxis) const;
|
|||
|
/// Get the local x-axis
|
|||
|
Vector3 xAxis(void) const;
|
|||
|
/// Get the local y-axis
|
|||
|
Vector3 yAxis(void) const;
|
|||
|
/// Get the local z-axis
|
|||
|
Vector3 zAxis(void) const;
|
|||
|
|
|||
|
Quaternion CalRollPitchYaw( float roll , float pitch , float yaw );
|
|||
|
inline Quaternion& operator= (const Quaternion& rkQ)
|
|||
|
{
|
|||
|
w = rkQ.w;
|
|||
|
x = rkQ.x;
|
|||
|
y = rkQ.y;
|
|||
|
z = rkQ.z;
|
|||
|
return *this;
|
|||
|
}
|
|||
|
Quaternion operator+ (const Quaternion& rkQ) const;
|
|||
|
Quaternion operator- (const Quaternion& rkQ) const;
|
|||
|
Quaternion operator* (const Quaternion& rkQ) const;
|
|||
|
Quaternion operator* (Real fScalar) const;
|
|||
|
friend Quaternion operator* (Real fScalar,
|
|||
|
const Quaternion& rkQ);
|
|||
|
Quaternion operator- () const;
|
|||
|
inline bool operator== (const Quaternion& rhs) const
|
|||
|
{
|
|||
|
return (rhs.x == x) && (rhs.y == y) &&
|
|||
|
(rhs.z == z) && (rhs.w == w);
|
|||
|
}
|
|||
|
inline bool operator!= (const Quaternion& rhs) const
|
|||
|
{
|
|||
|
return !operator==(rhs);
|
|||
|
}
|
|||
|
// functions of a quaternion
|
|||
|
Real Dot (const Quaternion& rkQ) const; // dot product
|
|||
|
Real Norm () const; // squared-length
|
|||
|
/// Normalises this quaternion, and returns the previous length
|
|||
|
Real normalise(void);
|
|||
|
Quaternion Inverse () const; // apply to non-zero quaternion
|
|||
|
Quaternion UnitInverse () const; // apply to unit-length quaternion
|
|||
|
Quaternion Exp () const;
|
|||
|
Quaternion Log () const;
|
|||
|
|
|||
|
// rotation of a vector by a quaternion
|
|||
|
Vector3 operator* (const Vector3& rkVector) const;
|
|||
|
|
|||
|
/** Calculate the local roll element of this quaternion.
|
|||
|
@param reprojectAxis By default the method returns the 'intuitive' result
|
|||
|
that is, if you projected the local Y of the quaternion onto the X and
|
|||
|
Y axes, the angle between them is returned. If set to false though, the
|
|||
|
result is the actual yaw that will be used to implement the quaternion,
|
|||
|
which is the shortest possible path to get to the same orientation and
|
|||
|
may involve less axial rotation.
|
|||
|
*/
|
|||
|
Radian getRoll(bool reprojectAxis = true) const;
|
|||
|
/** Calculate the local pitch element of this quaternion
|
|||
|
@param reprojectAxis By default the method returns the 'intuitive' result
|
|||
|
that is, if you projected the local Z of the quaternion onto the X and
|
|||
|
Y axes, the angle between them is returned. If set to true though, the
|
|||
|
result is the actual yaw that will be used to implement the quaternion,
|
|||
|
which is the shortest possible path to get to the same orientation and
|
|||
|
may involve less axial rotation.
|
|||
|
*/
|
|||
|
Radian getPitch(bool reprojectAxis = true) const;
|
|||
|
/** Calculate the local yaw element of this quaternion
|
|||
|
@param reprojectAxis By default the method returns the 'intuitive' result
|
|||
|
that is, if you projected the local Z of the quaternion onto the X and
|
|||
|
Z axes, the angle between them is returned. If set to true though, the
|
|||
|
result is the actual yaw that will be used to implement the quaternion,
|
|||
|
which is the shortest possible path to get to the same orientation and
|
|||
|
may involve less axial rotation.
|
|||
|
*/
|
|||
|
Radian getYaw(bool reprojectAxis = true) const;
|
|||
|
/// Equality with tolerance (tolerance is max angle difference)
|
|||
|
bool equals(const Quaternion& rhs, const Radian& tolerance) const;
|
|||
|
|
|||
|
/// get the yaw <20><>pitch <20><>roll in order XYZ
|
|||
|
void GetYawPitchRoll(Radian& yaw, Radian& pitch, Radian& roll) const;
|
|||
|
|
|||
|
// spherical linear interpolation
|
|||
|
static Quaternion Slerp (Real fT, const Quaternion& rkP,
|
|||
|
const Quaternion& rkQ, bool shortestPath = false);
|
|||
|
|
|||
|
static Quaternion SlerpExtraSpins (Real fT,
|
|||
|
const Quaternion& rkP, const Quaternion& rkQ,
|
|||
|
int iExtraSpins);
|
|||
|
|
|||
|
// setup for spherical quadratic interpolation
|
|||
|
static void Intermediate (const Quaternion& rkQ0,
|
|||
|
const Quaternion& rkQ1, const Quaternion& rkQ2,
|
|||
|
Quaternion& rka, Quaternion& rkB);
|
|||
|
|
|||
|
// spherical quadratic interpolation
|
|||
|
static Quaternion Squad (Real fT, const Quaternion& rkP,
|
|||
|
const Quaternion& rkA, const Quaternion& rkB,
|
|||
|
const Quaternion& rkQ, bool shortestPath = false);
|
|||
|
|
|||
|
// normalised linear interpolation - faster but less accurate (non-constant rotation velocity)
|
|||
|
static Quaternion nlerp(Real fT, const Quaternion& rkP,
|
|||
|
const Quaternion& rkQ, bool shortestPath = false);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// cutoff for sine near zero
|
|||
|
static const Real ms_fEpsilon;
|
|||
|
|
|||
|
// special values
|
|||
|
static const Quaternion ZERO;
|
|||
|
static const Quaternion IDENTITY;
|
|||
|
|
|||
|
Real w, x, y, z;
|
|||
|
|
|||
|
/// Check whether this quaternion contains valid values
|
|||
|
inline bool isNaN() const
|
|||
|
{
|
|||
|
return Math::isNaN(x) || Math::isNaN(y) || Math::isNaN(z) || Math::isNaN(w);
|
|||
|
}
|
|||
|
|
|||
|
};
|
|||
|
/** @} */
|
|||
|
/** @} */
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#endif
|