![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
#include <Quaternion.hpp>
Public Types | |
| typedef Quaternion< Scalar, Double > | mytype |
| typedef Vector< 3, Scalar, Double > | vectype |
Public Member Functions | |
| mytype & | conjugate () const |
| Scalar | getAngle () |
| vectype | getAxis () |
| void | getMatrix4x4 (Matrix< 4, 4, Scalar > &result) |
| mytype | operator* (const mytype &u) |
| mytype & | operator*= (const mytype &u) |
| mytype & | operator= (const mytype &u) |
| mytype | operator~ () const |
| mytype & | postMultiply (const mytype &u) |
| Quaternion () | |
| Quaternion (const mytype &u) | |
| Quaternion (Scalar x, Scalar y, Scalar z, Scalar w) | |
| Quaternion (const vectype &v, Scalar w) | |
| vectype | Quaternion::getEulerAngles () |
| void | rotate (vectype &u) |
| void | setFromAxisAngle (const vectype &axis, f32 angle) |
| void | setFromEulerAngles (f32 xroll, f32 ypitch, f32 zyaw) |
Protected Attributes | |
| Vector< 4, Scalar, Double > | _v |
Friends | |
| void | nlerp (const mytype &q1, const mytype &q2, Scalar t, mytype &result) |
| void | slerp (const mytype &q1, const mytype &q2, Scalar t, mytype &result) |
Definition at line 47 of file Quaternion.hpp.
| typedef Quaternion<Scalar, Double> cat::Quaternion< Scalar, Double >::mytype |
Definition at line 55 of file Quaternion.hpp.
| typedef Vector<3, Scalar, Double> cat::Quaternion< Scalar, Double >::vectype |
Definition at line 58 of file Quaternion.hpp.
| cat::Quaternion< Scalar, Double >::Quaternion | ( | ) | [inline] |
Definition at line 61 of file Quaternion.hpp.
{ }
| cat::Quaternion< Scalar, Double >::Quaternion | ( | const mytype & | u | ) | [inline] |
Definition at line 64 of file Quaternion.hpp.
: _v(u._v) { }
| cat::Quaternion< Scalar, Double >::Quaternion | ( | const vectype & | v, |
| Scalar | w | ||
| ) | [inline] |
Definition at line 70 of file Quaternion.hpp.
: _v(v) { }
| cat::Quaternion< Scalar, Double >::Quaternion | ( | Scalar | x, |
| Scalar | y, | ||
| Scalar | z, | ||
| Scalar | w | ||
| ) | [inline] |
Definition at line 76 of file Quaternion.hpp.
: _v(x, y, z, w) { }
| mytype& cat::Quaternion< Scalar, Double >::conjugate | ( | ) | const [inline] |
Definition at line 134 of file Quaternion.hpp.
References cat::Quaternion< Scalar, Double >::_v.
| Scalar cat::Quaternion< Scalar, Double >::getAngle | ( | ) | [inline] |
Definition at line 291 of file Quaternion.hpp.
References cat::Quaternion< Scalar, Double >::_v.
{
return static_cast<Scalar>( 2 ) * static_cast<Scalar>( acos(_v(3)) );
}
| vectype cat::Quaternion< Scalar, Double >::getAxis | ( | ) | [inline] |
Definition at line 297 of file Quaternion.hpp.
References cat::Quaternion< Scalar, Double >::_v.
| void cat::Quaternion< Scalar, Double >::getMatrix4x4 | ( | Matrix< 4, 4, Scalar > & | result | ) | [inline] |
Definition at line 303 of file Quaternion.hpp.
References cat::Quaternion< Scalar, Double >::_v.
{
Double dx = _v(0);
Double dy = _v(1);
Double dz = _v(2);
Double dw = _v(3);
Double x2 = dx * dx;
Double y2 = dy * dy;
Double z2 = dz * dz;
Double xy = dx * dy;
Double yz = dy * dz;
Double zx = dz * dx;
Double xw = dx * dw;
Double yw = dy * dw;
Double zw = dz * dw;
const Double ONE = static_cast<Double>( 1 );
const Double TWO = static_cast<Double>( 2 );
// Result is written in OpenGL column-major matrix order:
result( 0) = static_cast<Scalar>( ONE - TWO * (y2 + z2) );
result( 1) = static_cast<Scalar>( TWO * (xy - zw) );
result( 2) = static_cast<Scalar>( TWO * (zx + yw) );
result( 3) = static_cast<Scalar>( 0 );
result( 4) = static_cast<Scalar>( TWO * (xy + zw) );
result( 5) = static_cast<Scalar>( ONE - TWO * (x2 + z2) );
result( 6) = static_cast<Scalar>( TWO * (yz - xw) );
result( 7) = static_cast<Scalar>( 0 );
result( 8) = static_cast<Scalar>( TWO * (zx - yw) );
result( 9) = static_cast<Scalar>( TWO * (yz + xw) );
result(10) = static_cast<Scalar>( ONE - TWO * (x2 + y2) );
result(11) = static_cast<Scalar>( 0 );
result(12) = static_cast<Scalar>( 0 );
result(13) = static_cast<Scalar>( 0 );
result(14) = static_cast<Scalar>( 0 );
result(15) = static_cast<Scalar>( ONE );
}
| mytype cat::Quaternion< Scalar, Double >::operator* | ( | const mytype & | u | ) | [inline] |
Definition at line 144 of file Quaternion.hpp.
References cat::Quaternion< Scalar, Double >::_v.
{
// Cache each of the elements since each is used 4 times
Double x1 = _v(0), x2 = u._v(0);
Double y1 = _v(1), y2 = u._v(1);
Double z1 = _v(2), z2 = u._v(2);
Double w1 = _v(3), w2 = u._v(3);
// Quaternion multiplication formula:
Scalar x3 = static_cast<Scalar>( w1*x2 + x1*w2 + y1*z2 - z1*y2 );
Scalar y3 = static_cast<Scalar>( w1*y2 - x1*z2 + y1*w2 + z1*x2 );
Scalar z3 = static_cast<Scalar>( w1*z2 + x1*y2 - y1*x2 + z1*w2 );
Scalar w3 = static_cast<Scalar>( w1*w2 - x1*x2 - y1*y2 - z1*z2 );
return mytype(x3, y3, z3, w3);
}
| mytype& cat::Quaternion< Scalar, Double >::operator*= | ( | const mytype & | u | ) | [inline] |
Definition at line 162 of file Quaternion.hpp.
References cat::Quaternion< Scalar, Double >::_v.
{
// Cache each of the elements since each is used 4 times
Double x1 = _v(0), x2 = u._v(0);
Double y1 = _v(1), y2 = u._v(1);
Double z1 = _v(2), z2 = u._v(2);
Double w1 = _v(3), w2 = u._v(3);
// Quaternion multiplication formula:
_v(0) = static_cast<Scalar>( w1*x2 + x1*w2 + y1*z2 - z1*y2 );
_v(1) = static_cast<Scalar>( w1*y2 - x1*z2 + y1*w2 + z1*x2 );
_v(2) = static_cast<Scalar>( w1*z2 + x1*y2 - y1*x2 + z1*w2 );
_v(3) = static_cast<Scalar>( w1*w2 - x1*x2 - y1*y2 - z1*z2 );
return *this;
}
| mytype& cat::Quaternion< Scalar, Double >::operator= | ( | const mytype & | u | ) | [inline] |
Definition at line 82 of file Quaternion.hpp.
References cat::Quaternion< Scalar, Double >::_v, and cat::Vector< DIM, Scalar, Double >::copy().
{
_v.copy(u._v);
return *this;
}
| mytype cat::Quaternion< Scalar, Double >::operator~ | ( | ) | const [inline] |
Definition at line 128 of file Quaternion.hpp.
References cat::Quaternion< Scalar, Double >::_v.
| mytype& cat::Quaternion< Scalar, Double >::postMultiply | ( | const mytype & | u | ) | [inline] |
Definition at line 180 of file Quaternion.hpp.
References cat::Quaternion< Scalar, Double >::_v.
{
// Cache each of the elements since each is used 4 times
Double x2 = _v(0), x1 = u._v(0);
Double y2 = _v(1), y1 = u._v(1);
Double z2 = _v(2), z1 = u._v(2);
Double w2 = _v(3), w1 = u._v(3);
// Quaternion multiplication formula:
_v(0) = static_cast<Scalar>( w1*x2 + x1*w2 + y1*z2 - z1*y2 );
_v(1) = static_cast<Scalar>( w1*y2 - x1*z2 + y1*w2 + z1*x2 );
_v(2) = static_cast<Scalar>( w1*z2 + x1*y2 - y1*x2 + z1*w2 );
_v(3) = static_cast<Scalar>( w1*w2 - x1*x2 - y1*y2 - z1*z2 );
return *this;
}
| vectype cat::Quaternion< Scalar, Double >::Quaternion::getEulerAngles | ( | ) | [inline] |
Definition at line 346 of file Quaternion.hpp.
References cat::Quaternion< Scalar, Double >::_v, CAT_HALF_PI_64, and cat::Quaternion< Scalar, Double >::Quaternion::getEulerAngles().
Referenced by cat::Quaternion< Scalar, Double >::Quaternion::getEulerAngles().
{
Double dx = _v(0);
Double dy = _v(1);
Double dz = _v(2);
Double dw = _v(3);
Double x2 = dx * dx;
Double y2 = dy * dy;
Double z2 = dz * dz;
Double w2 = dw * dw;
Double xy = dx * dy;
Double yz = dy * dz;
Double xw = dx * dw;
Double yw = dy * dw;
Double zw = dz * dw;
const Double TWO = static_cast<Double>( 2 );
Double r11 = w2 + x2 - y2 - z2;
Double r21 = TWO * (xy + zw);
Double r31 = TWO * (xy - yw);
Double r32 = TWO * (yz + xw);
Double r33 = w2 - x2 - y2 + z2;
Double tmp = fabs(r31);
const Double LIMIT = static_cast<Double>( 0.999999 );
if (tmp > LIMIT)
{
Double xz = dx * dz;
Double r12 = TWO * (yz - zw);
Double r13 = TWO * (xz + yw);
return vectype(static_cast<Scalar>( 0 ),
static_cast<Scalar>( -CAT_HALF_PI_64 * r31 / tmp ),
static_cast<Scalar>( atan2(-r12, -r31 * r13) ));
}
return vectype(static_cast<Scalar>( atan2(r32, r33) ),
static_cast<Scalar>( asin(-r31) ),
static_cast<Scalar>( atan2(r21, r11) ));
}
| void cat::Quaternion< Scalar, Double >::rotate | ( | vectype & | u | ) | [inline] |
Definition at line 198 of file Quaternion.hpp.
References cat::Quaternion< Scalar, Double >::_v.
{
// Implements the simple formula: (q1 * u2 * ~q1).getVector()
// Cache each of the elements since each is used 4 times
Double x1 = _v(0), x2 = u(0);
Double y1 = _v(1), y2 = u(1);
Double z1 = _v(2), z2 = u(2);
Double w1 = _v(3);
// Quaternion-vector multiplication formula (q3 = q1 * u2):
Double x3 = w1*x2 + y1*z2 - z1*y2;
Double y3 = w1*y2 - x1*z2 + z1*x2;
Double z3 = w1*z2 + x1*y2 - y1*x2;
Double w3 = -(x1*x2 + y1*y2 + z1*z2);
// Quaternion multiplication formula (q2' = q3 * ~q1):
u(0) = static_cast<Scalar>( w1*x3 - x1*w3 + y1*z3 - z1*y3 );
u(1) = static_cast<Scalar>( w1*y3 - x1*z3 - y1*w3 + z1*x3 );
u(2) = static_cast<Scalar>( w1*z3 + x1*y3 - y1*x3 - z1*w3 );
}
| void cat::Quaternion< Scalar, Double >::setFromAxisAngle | ( | const vectype & | axis, |
| f32 | angle | ||
| ) | [inline] |
Definition at line 115 of file Quaternion.hpp.
References cat::Quaternion< Scalar, Double >::_v.
| void cat::Quaternion< Scalar, Double >::setFromEulerAngles | ( | f32 | xroll, |
| f32 | ypitch, | ||
| f32 | zyaw | ||
| ) | [inline] |
Definition at line 91 of file Quaternion.hpp.
References cat::Quaternion< Scalar, Double >::_v, and cat::Vector< DIM, Scalar, Double >::normalize().
{
f64 croll = cos(0.5f * xroll);
f64 cpitch = cos(0.5f * ypitch);
f64 cyaw = cos(0.5f * zyaw);
f64 sroll = sin(0.5f * xroll);
f64 spitch = sin(0.5f * ypitch);
f64 syaw = sin(0.5f * zyaw);
f64 cyawcpitch = cyaw * cpitch;
f64 syawspitch = syaw * spitch;
f64 cyawspitch = cyaw * spitch;
f64 syawcpitch = syaw * cpitch;
_v(0) = static_cast<Scalar>( cyawcpitch * sroll - syawspitch * croll );
_v(1) = static_cast<Scalar>( cyawspitch * croll + syawcpitch * sroll );
_v(2) = static_cast<Scalar>( syawcpitch * croll - cyawspitch * sroll );
_v(3) = static_cast<Scalar>( cyawcpitch * croll + syawspitch * sroll );
_v.normalize();
}
| void nlerp | ( | const mytype & | q1, |
| const mytype & | q2, | ||
| Scalar | t, | ||
| mytype & | result | ||
| ) | [friend] |
Definition at line 222 of file Quaternion.hpp.
{
// Linearly interpolate and normalize result
// This formula is a little more work than "q1 + (q2 - q1) * t"
// but less likely to lose precision when it matters
// Cosine of phi, the angle between the two vectors
Double cos_phi = q1._v.dotProduct(q2._v);
// I have read this may try to rotate around the "long way" sometimes and to
// fix that we check if cos(phi) is negative and invert one of the inputs.
if (cos_phi < 0.0)
{
result._v = -q1._v;
}
else
{
result._v = q1._v;
}
// Simple linear interpolation
Scalar scale0 = static_cast<Scalar>(1) - t;
Scalar scale1 = t;
result._v *= scale0;
result._v += q2._v * scale1;
result._v.normalize();
}
| void slerp | ( | const mytype & | q1, |
| const mytype & | q2, | ||
| Scalar | t, | ||
| mytype & | result | ||
| ) | [friend] |
Definition at line 253 of file Quaternion.hpp.
{
// Cosine of phi, the angle between the two vectors
Double cos_phi = q1._v.dotProduct(q2._v);
// I have read this may try to rotate around the "long way" sometimes and to
// fix that we check if cos(phi) is negative and invert one of the inputs.
if (cos_phi < 0.0)
{
cos_phi = -cos_phi;
result._v = -q1._v;
}
else
{
result._v = q1._v;
}
// Default to simple linear interpolation
Scalar scale0 = static_cast<Scalar>(1) - t;
Scalar scale1 = t;
// If the distance is not small we need to do full slerp:
if (cos_phi < 0.9995)
{
// cos_phi is guaranteed to be within the domain of acos(), 0..1
Double phi = static_cast<Double>( acos(cos_phi) );
Double inv_sin_phi = static_cast<Double>(1) / sin(phi);
scale0 = static_cast<Scalar>( sin(scale0 * phi) * inv_sin_phi );
scale1 = static_cast<Scalar>( sin(scale1 * phi) * inv_sin_phi );
}
result._v *= scale0;
result._v += q2._v * scale1;
result._v.normalize();
}
Vector<4, Scalar, Double> cat::Quaternion< Scalar, Double >::_v [protected] |
Definition at line 51 of file Quaternion.hpp.
Referenced by cat::Quaternion< Scalar, Double >::conjugate(), cat::Quaternion< Scalar, Double >::getAngle(), cat::Quaternion< Scalar, Double >::getAxis(), cat::Quaternion< Scalar, Double >::getMatrix4x4(), cat::Quaternion< Scalar, Double >::operator*(), cat::Quaternion< Scalar, Double >::operator*=(), cat::Quaternion< Scalar, Double >::operator=(), cat::Quaternion< Scalar, Double >::operator~(), cat::Quaternion< Scalar, Double >::postMultiply(), cat::Quaternion< Scalar, Double >::Quaternion::getEulerAngles(), cat::Quaternion< Scalar, Double >::rotate(), cat::Quaternion< Scalar, Double >::setFromAxisAngle(), and cat::Quaternion< Scalar, Double >::setFromEulerAngles().
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.