fakk2-sdk/source/utils/max2skl/uquat.h
2000-09-17 00:00:00 +00:00

312 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__ */