313 lines
7 KiB
C
313 lines
7 KiB
C
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// $Logfile:: /fakk2_code/Utils_Q3A/max2skl/uquat.h $
|
||
|
// $Revision:: 2 $
|
||
|
// $Date:: 10/04/99 7:04p $
|
||
|
//
|
||
|
// Copyright (C) 1999 by Ritual Entertainment, Inc.
|
||
|
// All rights reserved.
|
||
|
//
|
||
|
// This source is may not be distributed and/or modified without
|
||
|
// expressly written permission by Ritual Entertainment, Inc.
|
||
|
//
|
||
|
// $Log:: /fakk2_code/Utils_Q3A/max2skl/uquat.h $
|
||
|
//
|
||
|
// 2 10/04/99 7:04p Jimdose
|
||
|
// added ProjectVector and UnprojectVector
|
||
|
//
|
||
|
// 5 9/15/99 5:38p Morbid
|
||
|
// Added header
|
||
|
//
|
||
|
// DESCRIPTION:
|
||
|
//
|
||
|
|
||
|
#ifndef __UQUAT_H__
|
||
|
#define __UQUAT_H__
|
||
|
|
||
|
#include "ucommon.h"
|
||
|
#include "uvector3.h"
|
||
|
|
||
|
class UMat3;
|
||
|
class UEuler;
|
||
|
|
||
|
class UQuat
|
||
|
{
|
||
|
public:
|
||
|
float
|
||
|
x, y, z, w;
|
||
|
|
||
|
UQuat ();
|
||
|
UQuat ( float xx, float yy, float zz, float ww );
|
||
|
UQuat ( const UVector3 &, float ww = 0.f );
|
||
|
UQuat ( const UEuler & );
|
||
|
|
||
|
void set ( float xx, float yy, float zz, float ww );
|
||
|
|
||
|
UVector3 &vec3 ();
|
||
|
|
||
|
float *vec4 ();
|
||
|
float operator[] ( int index ) const;
|
||
|
float &operator[] ( int index );
|
||
|
|
||
|
friend UQuat operator + ( const UQuat &, const UQuat & );
|
||
|
friend UQuat operator - ( const UQuat &, const UQuat & );
|
||
|
friend UQuat operator * ( const UQuat &, float );
|
||
|
friend UQuat operator * ( float, const UQuat & );
|
||
|
friend UQuat operator * ( const UQuat &, const UQuat & );
|
||
|
inline friend UQuat operator * ( float a, UQuat &b ) { return b * a; }
|
||
|
|
||
|
UQuat &operator += ( const UQuat & );
|
||
|
UQuat &operator -= ( const UQuat & );
|
||
|
UQuat &operator *= ( float );
|
||
|
UQuat &operator *= ( const UQuat & );
|
||
|
|
||
|
bool operator == ( const UQuat & ) const;
|
||
|
bool operator != ( const UQuat &a ) const { return ! ( *this == a ); }
|
||
|
|
||
|
void operator = ( const UMat3 & );
|
||
|
|
||
|
float Length ();
|
||
|
void Normalize ();
|
||
|
UQuat getNormalized ();
|
||
|
void Invert ();
|
||
|
UQuat getInverse ();
|
||
|
void Slerp ( const UQuat &from, const UQuat &to, float t );
|
||
|
void SetupRotation ( float angles );
|
||
|
|
||
|
UVector3 ProjectVector( const UVector3 &b ) const;
|
||
|
UVector3 UnprojectVector( const UVector3 &b ) const;
|
||
|
};
|
||
|
|
||
|
inline UQuat::UQuat () {}
|
||
|
inline UQuat::UQuat ( float xx, float yy, float zz, float ww ) { x = xx; y = yy; z = zz; w = ww; }
|
||
|
inline UQuat::UQuat ( const UVector3 &v, float ww ) { x = v.x; y = v.y; z = v.z; w = ww; }
|
||
|
|
||
|
inline void UQuat::set ( float xx, float yy, float zz, float ww ) { x = xx; y = yy; z = zz; w = ww; }
|
||
|
inline UVector3 &UQuat::vec3 () { return *reinterpret_cast<UVector3 *>(&x); }
|
||
|
|
||
|
inline float *UQuat::vec4 () { return &x; }
|
||
|
|
||
|
inline UQuat &UQuat::operator += ( const UQuat &a ) { x += a.x; y += a.y; z += a.z; w += a.w; return *this; }
|
||
|
inline UQuat &UQuat::operator -= ( const UQuat &a ) { x -= a.x; y -= a.y; z -= a.z; w -= a.w; return *this; }
|
||
|
inline UQuat &UQuat::operator *= ( float f ) { x *= f; y *= f; z *= f; w *= f; return *this; }
|
||
|
inline UQuat &UQuat::operator *= ( const UQuat &a ) { *this = *this * a; return *this; }
|
||
|
inline bool UQuat::operator == ( const UQuat &a ) const { return x == a.x && y == a.y && z == a.z && w == a.w; }
|
||
|
inline UQuat operator * ( float a, const UQuat &b ) { return b * a; }
|
||
|
|
||
|
inline void UQuat::SetupRotation
|
||
|
(
|
||
|
float angles
|
||
|
)
|
||
|
|
||
|
{
|
||
|
float halftheta = Deg2Rad ( angles ) * 0.5f;
|
||
|
|
||
|
w = Cos ( halftheta );
|
||
|
vec3 () *= Sin ( halftheta );
|
||
|
}
|
||
|
|
||
|
inline UQuat operator +
|
||
|
(
|
||
|
const UQuat &a,
|
||
|
const UQuat &b
|
||
|
)
|
||
|
|
||
|
{
|
||
|
UQuat c;
|
||
|
|
||
|
c.x = a.x + b.x;
|
||
|
c.y = a.y + b.y;
|
||
|
c.z = a.z + b.z;
|
||
|
c.w = a.w + b.w;
|
||
|
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
inline UQuat operator -
|
||
|
(
|
||
|
const UQuat &a,
|
||
|
const UQuat &b
|
||
|
)
|
||
|
|
||
|
{
|
||
|
UQuat c;
|
||
|
|
||
|
c.x = a.x - b.x;
|
||
|
c.y = a.y - b.y;
|
||
|
c.z = a.z - b.z;
|
||
|
c.w = a.w - b.w;
|
||
|
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
inline UQuat operator *
|
||
|
(
|
||
|
const UQuat &a,
|
||
|
float b
|
||
|
)
|
||
|
|
||
|
{
|
||
|
UQuat c;
|
||
|
|
||
|
c.x = a.x * b;
|
||
|
c.y = a.y * b;
|
||
|
c.z = a.z * b;
|
||
|
c.w = a.w * b;
|
||
|
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
inline UQuat operator *
|
||
|
(
|
||
|
const UQuat &a,
|
||
|
const UQuat &b
|
||
|
)
|
||
|
|
||
|
{
|
||
|
UQuat c;
|
||
|
/* old one. Way differnt!
|
||
|
c.x = a.x * b.x - a.y * b.y - a.z * b.z - a.w * b.w;
|
||
|
c.y = a.x * b.y + a.y * b.x + a.z * b.w - a.w * b.z;
|
||
|
c.z = a.x * b.z - a.y * b.w + a.z * b.x + a.w * b.y;
|
||
|
c.w = a.x * b.w + a.y * b.z - a.z * b.y + a.w * b.x;
|
||
|
*/
|
||
|
|
||
|
c.x = a.w * b.x + b.w * a.x + a.y * b.z - a.z * b.y;
|
||
|
c.y = a.w * b.y + b.w * a.y + a.z * b.x - a.x * b.z;
|
||
|
c.z = a.w * b.z + b.w * a.z + a.x * b.y - a.y * b.x;
|
||
|
c.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;
|
||
|
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
inline float UQuat::operator[]
|
||
|
(
|
||
|
int index
|
||
|
) const
|
||
|
|
||
|
{
|
||
|
assert( ( index >= 0 ) && ( index < 4 ) );
|
||
|
return ( &x )[ index ];
|
||
|
}
|
||
|
|
||
|
inline float& UQuat::operator[]
|
||
|
(
|
||
|
int index
|
||
|
)
|
||
|
|
||
|
{
|
||
|
assert( ( index >= 0 ) && ( index < 4 ) );
|
||
|
return ( &x )[ index ];
|
||
|
}
|
||
|
|
||
|
inline float UQuat::Length
|
||
|
(
|
||
|
void
|
||
|
)
|
||
|
|
||
|
{
|
||
|
return Sqrt ( x * x + y * y + z * z + w * w );
|
||
|
}
|
||
|
|
||
|
inline void UQuat::Normalize
|
||
|
(
|
||
|
void
|
||
|
)
|
||
|
|
||
|
{
|
||
|
float length, ilength;
|
||
|
|
||
|
length = Length ();
|
||
|
if ( length )
|
||
|
{
|
||
|
ilength = 1.f / length;
|
||
|
x *= ilength;
|
||
|
y *= ilength;
|
||
|
z *= ilength;
|
||
|
w *= ilength;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline UQuat UQuat::getNormalized
|
||
|
(
|
||
|
void
|
||
|
)
|
||
|
|
||
|
{
|
||
|
UQuat q = *this;
|
||
|
|
||
|
q.Normalize ();
|
||
|
return q;
|
||
|
}
|
||
|
|
||
|
inline void UQuat::Invert
|
||
|
(
|
||
|
void
|
||
|
)
|
||
|
|
||
|
{
|
||
|
vec3 () *= -1.f;
|
||
|
}
|
||
|
|
||
|
inline UQuat UQuat::getInverse
|
||
|
(
|
||
|
void
|
||
|
)
|
||
|
|
||
|
{
|
||
|
UQuat u ( *this );
|
||
|
|
||
|
u.vec3 () *= -1.f;
|
||
|
return u;
|
||
|
}
|
||
|
|
||
|
inline UVector3 UQuat::ProjectVector
|
||
|
(
|
||
|
const UVector3 &b
|
||
|
) const
|
||
|
|
||
|
{
|
||
|
// convert b to a quat and multiply (c = this * UQuat( b ))
|
||
|
UQuat c
|
||
|
(
|
||
|
w * b.x + y * b.z - z * b.y,
|
||
|
w * b.y + z * b.x - x * b.z,
|
||
|
w * b.z + x * b.y - y * b.x,
|
||
|
-x * b.x - y * b.y - z * b.z
|
||
|
);
|
||
|
|
||
|
// construct in return memory ( c * this.Inverse ).vec3()
|
||
|
return UVector3
|
||
|
(
|
||
|
c.w * -x - w * c.x - c.y * z + c.z * y,
|
||
|
c.w * -y - w * c.y - c.z * x + c.x * z,
|
||
|
c.w * -z - w * c.z - c.x * y + c.y * x
|
||
|
);
|
||
|
}
|
||
|
|
||
|
inline UVector3 UQuat::UnprojectVector
|
||
|
(
|
||
|
const UVector3 &b
|
||
|
) const
|
||
|
|
||
|
{
|
||
|
// convert b to a quat and multiply (c = this.Inverse * UQuat( b ))
|
||
|
UQuat c
|
||
|
(
|
||
|
w * b.x - y * b.z + z * b.y,
|
||
|
w * b.y - z * b.x + x * b.z,
|
||
|
w * b.z - x * b.y + y * b.x,
|
||
|
x * b.x + y * b.y + z * b.z
|
||
|
);
|
||
|
|
||
|
// construct in return memory ( c * this ).vec3()
|
||
|
return UVector3
|
||
|
(
|
||
|
c.w * x + w * c.x + c.y * z - c.z * y,
|
||
|
c.w * y + w * c.y + c.z * x - c.x * z,
|
||
|
c.w * z + w * c.z + c.x * y - c.y * x
|
||
|
);
|
||
|
}
|
||
|
|
||
|
#endif /* !__UQUAT_H__ */
|