6e8fbca745
match the genesis editor version 1.3.0.653.
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
|