mirror of
https://github.com/thug1src/thug.git
synced 2025-01-22 05:43:47 +00:00
816 lines
23 KiB
Plaintext
816 lines
23 KiB
Plaintext
|
/*****************************************************************************
|
||
|
** **
|
||
|
** Neversoft Entertainment **
|
||
|
** **
|
||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||
|
** **
|
||
|
******************************************************************************
|
||
|
** **
|
||
|
** Project: Core Library **
|
||
|
** **
|
||
|
** Module: Math (Mth) **
|
||
|
** **
|
||
|
** File name: core/math/Quat.inl **
|
||
|
** **
|
||
|
** Created: 11/23/99 - mjb **
|
||
|
** **
|
||
|
** Description: Quaternion Math Class **
|
||
|
** **
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#ifndef __CORE_MATH_QUAT_INL
|
||
|
#define __CORE_MATH_QUAT_INL
|
||
|
|
||
|
namespace Mth
|
||
|
{
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline const float& Quat::operator[] ( sint i ) const
|
||
|
{
|
||
|
|
||
|
|
||
|
return quat[i];
|
||
|
}
|
||
|
|
||
|
|
||
|
/*****************************************************************************
|
||
|
** Private Inline Functions **
|
||
|
*****************************************************************************/
|
||
|
|
||
|
inline bool quat_equal( const Quat& q1, const Quat& q2, const float tol )
|
||
|
{
|
||
|
|
||
|
|
||
|
return ( Equal( q1.quat, q2.quat, tol ));
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
** Public Inline Functions **
|
||
|
*****************************************************************************/
|
||
|
|
||
|
inline Quat::Quat( float cx, float cy, float cz, float cw )
|
||
|
: quat( cx, cy, cz, cw )
|
||
|
{
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat::Quat( const Vector& axis, float angle )
|
||
|
{
|
||
|
|
||
|
|
||
|
float mod = axis.Length();
|
||
|
float ang = angle / 2.0f;
|
||
|
|
||
|
mod = ( mod > 0.0f ) ? ( 1.0f / mod ) : 0.0f;
|
||
|
mod *= sinf( ang );
|
||
|
|
||
|
SetVector( mod * axis[X], mod * axis[Y], mod * axis[Z] );
|
||
|
SetScalar( cosf ( ang ));
|
||
|
}
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline float& Quat::operator[] ( sint i )
|
||
|
{
|
||
|
|
||
|
|
||
|
return quat[i];
|
||
|
}
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat::Quat( const Matrix& m )
|
||
|
{
|
||
|
|
||
|
|
||
|
float t = m[X][X] + m[Y][Y] + m[Z][Z];
|
||
|
float trace;
|
||
|
|
||
|
if ( t > 0.0f )
|
||
|
{
|
||
|
trace = sqrtf( t + 1.0f );
|
||
|
|
||
|
SetScalar( trace * 0.5f );
|
||
|
trace = 0.5f / trace;
|
||
|
|
||
|
SetVector(( m[Z][Y] - m[Y][Z] ) * trace,
|
||
|
( m[X][Z] - m[Z][X] ) * trace,
|
||
|
( m[Y][X] - m[X][Y] ) * trace );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// find greatest element in Matrix diagonal
|
||
|
sint i = X;
|
||
|
if ( m[Y][Y] > m[X][X] ) i = Y;
|
||
|
if ( m[Z][Z] > m[i][i] ) i = Z;
|
||
|
|
||
|
sint j = ( i + 1 ) % W;
|
||
|
sint k = ( j + 1 ) % W;
|
||
|
|
||
|
trace = sqrtf(( m[i][i] - (m[j][j] + m[k][k] )) + 1.0f );
|
||
|
|
||
|
quat[i] = ( trace * 0.5f );
|
||
|
trace = 0.5f / trace;
|
||
|
quat[j] = ( m[j][i] + m[i][j] ) * trace;
|
||
|
quat[k] = ( m[k][i] + m[i][k] ) * trace;
|
||
|
quat[W] = ( m[k][j] - m[j][k] ) * trace;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat& Quat::Invert( void ) // this = Invert ( this )
|
||
|
{
|
||
|
|
||
|
|
||
|
quat.Negate();
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat& Quat::Invert( const Quat& src ) // this = Invert ( src )
|
||
|
{
|
||
|
|
||
|
|
||
|
quat.Negate( src.quat );
|
||
|
quat[W] = src.quat[W];
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline float Quat::Modulus( void )
|
||
|
{
|
||
|
|
||
|
|
||
|
return sqrtf( ModulusSqr () );
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline float Quat::ModulusSqr ( void ) const
|
||
|
{
|
||
|
|
||
|
|
||
|
return (( quat[X] * quat[X] ) +
|
||
|
( quat[Y] * quat[Y] ) +
|
||
|
( quat[Z] * quat[Z] ) +
|
||
|
( quat[W] * quat[W] ));
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat& Quat::Normalize( float len )
|
||
|
{
|
||
|
|
||
|
|
||
|
float mod = Modulus();
|
||
|
|
||
|
if ( mod > 0.0f )
|
||
|
{
|
||
|
mod = len / mod;
|
||
|
|
||
|
quat *= mod;
|
||
|
}
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Vector Quat::Rotate( const Vector& vec ) const
|
||
|
{
|
||
|
|
||
|
|
||
|
Quat inv;
|
||
|
// Quat pt( vec[X], vec[Y], vec[Z], vec[W] );
|
||
|
Quat pt( vec[X], vec[Y], vec[Z], 1.0f ); // Mick: Setting W to sensible value, otherwise can cause overflow
|
||
|
Quat res = *this;
|
||
|
|
||
|
inv.Invert( *this );
|
||
|
res *= pt;
|
||
|
res *= inv;
|
||
|
|
||
|
return Vector( res[X], res[Y], res[Z], res[W] );
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline void Quat::SetScalar( const float w )
|
||
|
{
|
||
|
|
||
|
|
||
|
quat[W] = w;
|
||
|
};
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline void Quat::SetVector( const float x, const float y, const float z )
|
||
|
{
|
||
|
|
||
|
|
||
|
quat[X] = x;
|
||
|
quat[Y] = y;
|
||
|
quat[Z] = z;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline void Quat::SetVector( const Vector& v )
|
||
|
{
|
||
|
|
||
|
|
||
|
quat[X] = v[X];
|
||
|
quat[Y] = v[Y];
|
||
|
quat[Z] = v[Z];
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat& Quat::operator= ( const Quat& q )
|
||
|
{
|
||
|
|
||
|
|
||
|
quat = q.quat;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat& Quat::operator+= ( const Quat& q )
|
||
|
{
|
||
|
|
||
|
|
||
|
quat += q.quat;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat& Quat::operator-= ( const Quat& q )
|
||
|
{
|
||
|
|
||
|
|
||
|
quat -= q.quat;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
inline const float& Quat::GetScalar ( void ) const
|
||
|
{
|
||
|
return quat[W];
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat& Quat::operator*= ( const Quat& q )
|
||
|
{
|
||
|
|
||
|
|
||
|
float s1 = GetScalar();
|
||
|
float s2 = q.GetScalar();
|
||
|
|
||
|
Vector v1 = GetVector();
|
||
|
Vector v2 = q.GetVector();
|
||
|
|
||
|
SetVector (( v2 * s1 ) + ( v1 * s2 ) + CrossProduct ( v1, v2 ));
|
||
|
SetScalar (( s1 * s2 ) - DotProduct ( v1, v2 ));
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat& Quat::operator*= ( float s )
|
||
|
{
|
||
|
|
||
|
|
||
|
quat *= s;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat& Quat::operator/= ( float s )
|
||
|
{
|
||
|
|
||
|
|
||
|
quat /= s;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline void Quat::GetMatrix ( Matrix& mat ) const
|
||
|
{
|
||
|
|
||
|
|
||
|
float xs, ys, zs,
|
||
|
wx, wy, wz,
|
||
|
xx, xy, xz,
|
||
|
yy, yz, zz, ss;
|
||
|
|
||
|
|
||
|
#if 0
|
||
|
// our original version. Seems essentially broken, as LengthSqr ignores W
|
||
|
ss = 2.0f / quat.LengthSqr();
|
||
|
#else
|
||
|
// version suggested by Andre at Left Field
|
||
|
// uses proper Modulus, and clamps 2.0/0.0f to zero
|
||
|
ss = ModulusSqr();
|
||
|
ss = ( ss>0.0f ? 2.0f/ss : 0.0f);
|
||
|
#endif
|
||
|
|
||
|
xs = quat[X] * ss;
|
||
|
ys = quat[Y] * ss;
|
||
|
zs = quat[Z] * ss;
|
||
|
|
||
|
wx = quat[W] * xs;
|
||
|
wy = quat[W] * ys;
|
||
|
wz = quat[W] * zs;
|
||
|
|
||
|
xx = quat[X] * xs;
|
||
|
xy = quat[X] * ys;
|
||
|
xz = quat[X] * zs;
|
||
|
|
||
|
yy = quat[Y] * ys;
|
||
|
yz = quat[Y] * zs;
|
||
|
|
||
|
zz = quat[Z] * zs;
|
||
|
|
||
|
mat[X][X] = 1.0f - (yy + zz);
|
||
|
mat[Y][X] = xy + wz;
|
||
|
mat[Z][X] = xz - wy;
|
||
|
|
||
|
mat[X][Y] = xy - wz;
|
||
|
mat[Y][Y] = 1.0f - (xx + zz);
|
||
|
mat[Z][Y] = yz + wx;
|
||
|
|
||
|
mat[X][Z] = xz + wy;
|
||
|
mat[Y][Z] = yz - wx;
|
||
|
mat[Z][Z] = 1.0f - (xx + yy );
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat operator+ ( const Quat& q1, const Quat& q2 )
|
||
|
{
|
||
|
|
||
|
|
||
|
Quat sum = q1;
|
||
|
|
||
|
sum += q2;
|
||
|
|
||
|
return sum;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat operator- ( const Quat& q1, const Quat& q2 )
|
||
|
{
|
||
|
|
||
|
|
||
|
Quat diff = q1;
|
||
|
|
||
|
diff -= q2;
|
||
|
|
||
|
return diff;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat operator* ( const Quat& q1, const Quat& q2 )
|
||
|
{
|
||
|
|
||
|
|
||
|
Quat prod = q1;
|
||
|
|
||
|
prod *= q2;
|
||
|
|
||
|
return prod;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat operator* ( const Quat& q, const float s )
|
||
|
{
|
||
|
Quat prod = q;
|
||
|
|
||
|
prod *= s;
|
||
|
|
||
|
return prod;
|
||
|
}
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat operator* ( const float s, const Quat& q )
|
||
|
{
|
||
|
return q * s;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat operator- ( const Quat& q )
|
||
|
{
|
||
|
|
||
|
|
||
|
return Quat ( -q[X], -q[Y], -q[Z], -q[W] );
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline float DotProduct ( const Quat& v1, const Quat& v2 )
|
||
|
{
|
||
|
|
||
|
|
||
|
return ( v1[X] * v2[X] ) + ( v1[Y] * v2[Y] ) + ( v1[Z] * v2[Z] ) + ( v1[W] * v2[W] );
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Quat Slerp ( const Quat& q1, const Quat& q3, float t )
|
||
|
{
|
||
|
float sclp, sclq;
|
||
|
|
||
|
// GJ: Need to possibly negate the second quaternion,
|
||
|
// to avoid spinning in the wrong direction.
|
||
|
Quat q2 = q3;
|
||
|
if ( DotProduct( q1, q3 ) < 0.0f )
|
||
|
{
|
||
|
q2 = -q2;
|
||
|
}
|
||
|
|
||
|
float coso = q1.GetScalar() * q2.GetScalar() +
|
||
|
DotProduct ( q1.GetVector(), q2.GetVector());
|
||
|
|
||
|
Quat q;
|
||
|
|
||
|
if (( 1.0f + coso + 1.0f ) > EPSILON )
|
||
|
{
|
||
|
if (( 1.0f - coso ) > EPSILON ) // slerp
|
||
|
{
|
||
|
float omega = acosf ( coso );
|
||
|
float sino = sinf ( omega );
|
||
|
|
||
|
sclp = sinf (( 1.0f - t ) * omega ) / sino;
|
||
|
sclq = sinf ( t * omega ) / sino;
|
||
|
}
|
||
|
else // lerp ( angle tends to 0 )
|
||
|
{
|
||
|
sclp = 1.0f - t;
|
||
|
sclq = t;
|
||
|
}
|
||
|
|
||
|
q = ( sclp * q1 ) + ( sclq * q2 );
|
||
|
}
|
||
|
else // angle tends to 2*PI
|
||
|
{
|
||
|
q.SetVector ( -q1[Y], q1[X], -q1[W] );
|
||
|
q.SetScalar ( q1[Z] );
|
||
|
|
||
|
sclp = sinf (( 1.0f - t ) * PI / 2.0f );
|
||
|
sclq = sinf ( t * PI / 2.0f );
|
||
|
|
||
|
q.SetVector (( sclp * q1.GetVector()) + ( sclq * q.GetVector()));
|
||
|
}
|
||
|
|
||
|
return q;
|
||
|
}
|
||
|
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline bool Equal ( const Quat& q1, const Quat& q2, const float tol )
|
||
|
{
|
||
|
|
||
|
|
||
|
if (( quat_equal ( q1, q2, tol )) ||
|
||
|
( quat_equal ( -q1, q2, tol )))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline ostream& operator<< ( ostream& os, const Quat& q )
|
||
|
{
|
||
|
return os << "(( " << q[X] << ", " << q[Y] << ", " << q[Z] << ") , " << q[W] << " )";
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline void QuatVecToMatrix( Mth::Quat* pQ, Mth::Vector* pT, Mth::Matrix* pMatrix )
|
||
|
{
|
||
|
Dbg_Assert( pQ );
|
||
|
Dbg_Assert( pT );
|
||
|
Dbg_Assert( pMatrix );
|
||
|
|
||
|
pQ->Invert();
|
||
|
|
||
|
Mth::Vector square;
|
||
|
Mth::Vector cross;
|
||
|
Mth::Vector wimag;
|
||
|
|
||
|
square[X] = (*pQ)[X] * (*pQ)[X];
|
||
|
square[Y] = (*pQ)[Y] * (*pQ)[Y];
|
||
|
square[Z] = (*pQ)[Z] * (*pQ)[Z];
|
||
|
|
||
|
cross[X] = (*pQ)[Y] * (*pQ)[Z];
|
||
|
cross[Y] = (*pQ)[Z] * (*pQ)[X];
|
||
|
cross[Z] = (*pQ)[X] * (*pQ)[Y];
|
||
|
|
||
|
wimag[X] = (*pQ)[W] * (*pQ)[X];
|
||
|
wimag[Y] = (*pQ)[W] * (*pQ)[Y];
|
||
|
wimag[Z] = (*pQ)[W] * (*pQ)[Z];
|
||
|
|
||
|
(*pMatrix)[Mth::RIGHT][X] = 1 - 2 * (square[Y] + square[Z]);
|
||
|
(*pMatrix)[Mth::RIGHT][Y] = 2 * (cross[Z] + wimag[Z]);
|
||
|
(*pMatrix)[Mth::RIGHT][Z] = 2 * (cross[Y] - wimag[Y]);
|
||
|
(*pMatrix)[Mth::RIGHT][W] = 0.0f;
|
||
|
|
||
|
(*pMatrix)[Mth::UP][X] = 2 * (cross[Z] - wimag[Z]);
|
||
|
(*pMatrix)[Mth::UP][Y] = 1 - 2 * (square[X] + square[Z]);
|
||
|
(*pMatrix)[Mth::UP][Z] = 2 * (cross[X] + wimag[X]);
|
||
|
(*pMatrix)[Mth::UP][W] = 0.0f;
|
||
|
|
||
|
(*pMatrix)[Mth::AT][X] = 2 * (cross[Y] + wimag[Y]);
|
||
|
(*pMatrix)[Mth::AT][Y] = 2 * (cross[X] - wimag[X]);
|
||
|
(*pMatrix)[Mth::AT][Z] = 1 - 2 * (square[X] + square[Y]);
|
||
|
(*pMatrix)[Mth::AT][W] = 0.0f;
|
||
|
|
||
|
(*pMatrix)[Mth::POS] = *pT;
|
||
|
(*pMatrix)[Mth::POS][W] = 1.0f;
|
||
|
}
|
||
|
|
||
|
inline void SCacheQuatVecToMatrix( Mth::Quat* pQ, Mth::Vector* pT, Mth::Matrix* pMatrix )
|
||
|
{
|
||
|
Dbg_Assert( pQ );
|
||
|
Dbg_Assert( pT );
|
||
|
Dbg_Assert( pMatrix );
|
||
|
|
||
|
pQ->Invert();
|
||
|
|
||
|
Mth::Vector *p_square = ((Mth::Vector*)0x7000000)+0;
|
||
|
Mth::Vector *p_cross = ((Mth::Vector*)0x7000000)+1;
|
||
|
Mth::Vector *p_wimag = ((Mth::Vector*)0x7000000)+2;
|
||
|
|
||
|
(*p_square)[X] = (*pQ)[X] * (*pQ)[X];
|
||
|
(*p_square)[Y] = (*pQ)[Y] * (*pQ)[Y];
|
||
|
(*p_square)[Z] = (*pQ)[Z] * (*pQ)[Z];
|
||
|
|
||
|
(*p_cross)[X] = (*pQ)[Y] * (*pQ)[Z];
|
||
|
(*p_cross)[Y] = (*pQ)[Z] * (*pQ)[X];
|
||
|
(*p_cross)[Z] = (*pQ)[X] * (*pQ)[Y];
|
||
|
|
||
|
(*p_wimag)[X] = (*pQ)[W] * (*pQ)[X];
|
||
|
(*p_wimag)[Y] = (*pQ)[W] * (*pQ)[Y];
|
||
|
(*p_wimag)[Z] = (*pQ)[W] * (*pQ)[Z];
|
||
|
|
||
|
(*pMatrix)[Mth::RIGHT][X] = 1 - 2 * ((*p_square)[Y] + (*p_square)[Z]);
|
||
|
(*pMatrix)[Mth::RIGHT][Y] = 2 * ((*p_cross)[Z] + (*p_wimag)[Z]);
|
||
|
(*pMatrix)[Mth::RIGHT][Z] = 2 * ((*p_cross)[Y] - (*p_wimag)[Y]);
|
||
|
(*pMatrix)[Mth::RIGHT][W] = 0.0f;
|
||
|
|
||
|
(*pMatrix)[Mth::UP][X] = 2 * ((*p_cross)[Z] - (*p_wimag)[Z]);
|
||
|
(*pMatrix)[Mth::UP][Y] = 1 - 2 * ((*p_square)[X] + (*p_square)[Z]);
|
||
|
(*pMatrix)[Mth::UP][Z] = 2 * ((*p_cross)[X] + (*p_wimag)[X]);
|
||
|
(*pMatrix)[Mth::UP][W] = 0.0f;
|
||
|
|
||
|
(*pMatrix)[Mth::AT][X] = 2 * ((*p_cross)[Y] + (*p_wimag)[Y]);
|
||
|
(*pMatrix)[Mth::AT][Y] = 2 * ((*p_cross)[X] - (*p_wimag)[X]);
|
||
|
(*pMatrix)[Mth::AT][Z] = 1 - 2 * ((*p_square)[X] + (*p_square)[Y]);
|
||
|
(*pMatrix)[Mth::AT][W] = 0.0f;
|
||
|
|
||
|
(*pMatrix)[Mth::POS] = *pT;
|
||
|
(*pMatrix)[Mth::POS][W] = 1.0f;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline void Slerp ( Matrix& result, const Matrix& s1, const Matrix& s2, float t )
|
||
|
{
|
||
|
Slerp ( Quat(s1), Quat(s2), t).GetMatrix ( result );
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline float counter_warp(float t, float cos_alpha)
|
||
|
{
|
||
|
const float ATTENUATION = 0.82279687f;
|
||
|
const float WORST_CASE_SLOPE = 0.58549219f;
|
||
|
|
||
|
float factor = 1.0f - ATTENUATION * cos_alpha;
|
||
|
factor *= factor;
|
||
|
float k = WORST_CASE_SLOPE * factor;
|
||
|
|
||
|
return t*(k*t*(2.0f*t - 3.0f) + 1.0f + k);
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Mth::Quat FastSlerp( Mth::Quat& qIn1, Mth::Quat& qIn2, const float t )
|
||
|
{
|
||
|
if ( Mth::DotProduct( qIn1, qIn2 ) < 0.0f )
|
||
|
{
|
||
|
qIn2 = -qIn2;
|
||
|
}
|
||
|
|
||
|
# if 0
|
||
|
float cos_a = v1[X]*v2[X] + v1[Y]*v2[Y] + v1[Z]*v2[Z] + v1[W]*v2[W];
|
||
|
if (t <= 0.5f)
|
||
|
{
|
||
|
t = counter_warp(t, cos_a);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
t = 1.0f - counter_warp(1.0f - t, cos_a);
|
||
|
}
|
||
|
# endif
|
||
|
|
||
|
float xxx_x = qIn1[X] + ( qIn2[X] - qIn1[X] ) * t;
|
||
|
float xxx_y = qIn1[Y] + ( qIn2[Y] - qIn1[Y] ) * t;
|
||
|
float xxx_z = qIn1[Z] + ( qIn2[Z] - qIn1[Z] ) * t;
|
||
|
float xxx_w = qIn1[W] + ( qIn2[W] - qIn1[W] ) * t;
|
||
|
|
||
|
float len = 1.0f / sqrtf( xxx_x * xxx_x + xxx_y * xxx_y + xxx_z * xxx_z + xxx_w * xxx_w );
|
||
|
|
||
|
qIn2.SetVector( xxx_x * len, xxx_y * len, xxx_z * len );
|
||
|
qIn2.SetScalar( xxx_w * len );
|
||
|
|
||
|
return qIn2;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
inline Mth::Quat EulerToQuat( const Mth::Vector& euler )
|
||
|
{
|
||
|
// This code is a modified version of Left Field's
|
||
|
// MakeQuatFromEuler() function.
|
||
|
|
||
|
Mth::Quat q;
|
||
|
|
||
|
float roll = euler[X];
|
||
|
float pitch = euler[Y];
|
||
|
float yaw = euler[Z];
|
||
|
|
||
|
float cyaw, cpitch, croll, syaw, spitch, sroll;
|
||
|
float cyawcpitch, syawspitch, cyawspitch, syawcpitch;
|
||
|
|
||
|
cyaw = cosf(0.5f * yaw);
|
||
|
cpitch = cosf(0.5f * pitch);
|
||
|
croll = cosf(0.5f * roll);
|
||
|
|
||
|
syaw = sinf(0.5f * yaw);
|
||
|
spitch = sinf(0.5f * pitch);
|
||
|
sroll = sinf(0.5f * roll);
|
||
|
|
||
|
cyawcpitch = cyaw * cpitch;
|
||
|
syawspitch = syaw * spitch;
|
||
|
cyawspitch = cyaw * spitch;
|
||
|
syawcpitch = syaw * cpitch;
|
||
|
|
||
|
q[W] = cyawcpitch * croll + syawspitch * sroll;
|
||
|
q[X] = cyawcpitch * sroll - syawspitch * croll;
|
||
|
q[Y] = cyawspitch * croll + syawcpitch * sroll;
|
||
|
q[Z] = syawcpitch * croll - cyawspitch * sroll;
|
||
|
|
||
|
return q;
|
||
|
}
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* */
|
||
|
/* */
|
||
|
/******************************************************************/
|
||
|
|
||
|
} // namespace Mth
|
||
|
|
||
|
#endif // __CORE_MATH_QUAT_INL
|
||
|
|