00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef __NEMATH_H
00028 #define __NEMATH_H
00029
00030
00037 #include "base.h"
00038 #include "util.h"
00039
00040 #include <math.h>
00041 #include <assert.h>
00042
00043 #include "logstream.h"
00044
00045
00046 namespace NeoEngine
00047 {
00048
00049
00051 extern const NEOENGINE_API float SQRT_3;
00052
00054 extern const NEOENGINE_API float HALF_SQRT_3;
00055
00057 extern const NEOENGINE_API float PI;
00058
00060 extern const NEOENGINE_API float TWO_PI;
00061
00063 extern const NEOENGINE_API float HALF_PI;
00064
00066 extern const NEOENGINE_API float EPSILON;
00067
00069 extern const NEOENGINE_API float SQREPSILON;
00070
00076 template <class T> inline const T &MIN( const T &a, const T &b ) { return( ( a < b ) ? a : b ); }
00077
00083 template <class T> inline const T &MAX( const T &a, const T &b ) { return( ( a > b ) ? a : b ); }
00084
00091 template <class T> inline const T &MIN3( const T &a, const T &b, const T &c ) { return( ( a < b ) ? ( ( a < c ) ? a : c ) : ( ( b < c ) ? b : c ) ); }
00092
00099 template <class T> inline const T &MAX3( const T &a, const T &b, const T &c ) { return( ( a > b ) ? ( ( a > c ) ? a : c ) : ( ( b > c ) ? b : c ) ); }
00100
00107 template <class T> inline void MINMAX( const T &a, const T &b, T &min, T &max ) { if( a < b ) { min = a; max = b; } else { min = b; max = a; } }
00108
00116 template <class T> inline void MINMAX3( const T &a, const T &b, const T &c, T &min, T &max ) { min = MIN3( a, b, c ); max = MAX3( a, b, c ); }
00117
00125 template <class T> inline const T CLAMP( const T &val, const T &min, const T &max ) { if( val <= min ) return min; else if( val >= max ) return max; return val; }
00126
00132 inline float NEOENGINE_API DEGTORAD( float fA ) { return fA * 0.017453292519943295769236907684886f; }
00133
00140 inline int NEOENGINE_API RoundFloat( float fNum );
00141
00148 inline int NEOENGINE_API TruncFloat( float fNum );
00149
00155 inline float NEOENGINE_API FastInvSqrt( float fN );
00156
00157
00158
00159 class Matrix;
00160 class Quaternion;
00161 class ODE;
00162
00163
00164
00170 class NEOENGINE_API Vector3d
00171 {
00172 public:
00173
00175 float x, y, z;
00176
00180 inline Vector3d();
00181
00188 inline Vector3d( float fX, float fY, float fZ );
00189
00194 inline Vector3d( float afComponents[] );
00195
00203 inline Vector3d &Set( float fX, float fY, float fZ );
00204
00210 inline Vector3d &Set( float afComponents[] );
00211
00216 inline Vector3d &Reset();
00217
00222 inline float Len() const;
00223
00228 inline float Len2() const;
00229
00234 inline Vector3d &Normalize();
00235
00241 inline Vector3d &ScaleTo( float fLen );
00242
00243
00244
00245
00251 inline bool operator ==( const Vector3d &rkVector ) const;
00252
00258 inline bool operator !=( const Vector3d &rkVector ) const;
00259
00265 inline float operator *( const Vector3d &rkVector ) const;
00266
00272 inline Vector3d operator %( const Vector3d &rkVector ) const;
00273
00279 inline Vector3d &operator %=( const Vector3d &rkVector );
00280
00286 inline Vector3d operator *( float fScalar ) const;
00287
00293 inline Vector3d &operator *=( float fScalar );
00294
00300 inline Vector3d operator +( const Vector3d &rkVector ) const;
00301
00307 inline Vector3d &operator +=( const Vector3d &rkVector );
00308
00314 inline Vector3d operator -( const Vector3d &rkVector ) const;
00315
00321 inline Vector3d &operator -=( const Vector3d &rkVector );
00322
00327 inline Vector3d operator -() const;
00328
00333 inline float &operator []( int iComponent );
00334
00339 inline const float &operator []( int iComponent ) const;
00340
00346 inline bool operator < ( const Vector3d &rkVector ) const { return false; }
00347
00349 static const NE_STATIC Vector3d ZERO;
00351 static const NE_STATIC Vector3d ORIGO;
00353 static const NE_STATIC Vector3d AXES[3];
00354 };
00355
00356
00363 NEOENGINE_API std::ostream &operator<<( std::ostream &rkStream, const Vector3d &rkVector );
00364
00365
00366 #define GETEULERORDER( i, p, r, f ) ( ( ( ( ( ( i << 1 ) + p ) << 1 ) + r ) << 1 ) + f )
00367
00368
00373 class NEOENGINE_API EulerAngles
00374 {
00375 public:
00376
00377
00378 enum EULERDEFS
00379 {
00380 X = 0,
00381 Y = 1,
00382 Z = 2,
00383
00384 STATICFRAME = 0,
00385 ROTATEFRAME = 1,
00386
00387 NOREPEAT = 0,
00388 REPEAT = 1,
00389
00390 EVEN = 0,
00391 ODD = 1,
00392 };
00393
00394
00395 enum ORDER
00396 {
00397 XYZs = GETEULERORDER( X, EVEN, NOREPEAT, STATICFRAME ),
00398 XYXs = GETEULERORDER( X, EVEN, REPEAT, STATICFRAME ),
00399 XZYs = GETEULERORDER( X, ODD, NOREPEAT, STATICFRAME ),
00400 XZXs = GETEULERORDER( X, ODD, REPEAT, STATICFRAME ),
00401 YZXs = GETEULERORDER( Y, EVEN, NOREPEAT, STATICFRAME ),
00402 YZYs = GETEULERORDER( Y, EVEN, REPEAT, STATICFRAME ),
00403 YXZs = GETEULERORDER( Y, ODD, NOREPEAT, STATICFRAME ),
00404 YXYs = GETEULERORDER( Y, ODD, REPEAT, STATICFRAME ),
00405 ZXYs = GETEULERORDER( Z, EVEN, NOREPEAT, STATICFRAME ),
00406 ZXZs = GETEULERORDER( Z, EVEN, REPEAT, STATICFRAME ),
00407 ZYXs = GETEULERORDER( Z, ODD, NOREPEAT, STATICFRAME ),
00408 ZYZs = GETEULERORDER( Z, ODD, REPEAT, STATICFRAME ),
00409
00410 ZYXr = GETEULERORDER( X, EVEN, NOREPEAT, ROTATEFRAME ),
00411 XYXr = GETEULERORDER( X, EVEN, REPEAT, ROTATEFRAME ),
00412 YZXr = GETEULERORDER( X, ODD, NOREPEAT, ROTATEFRAME ),
00413 XZXr = GETEULERORDER( X, ODD, REPEAT, ROTATEFRAME ),
00414 XZYr = GETEULERORDER( Y, EVEN, NOREPEAT, ROTATEFRAME ),
00415 YZYr = GETEULERORDER( Y, EVEN, REPEAT, ROTATEFRAME ),
00416 ZXYr = GETEULERORDER( Y, ODD, NOREPEAT, ROTATEFRAME ),
00417 YXYr = GETEULERORDER( Y, ODD, REPEAT, ROTATEFRAME ),
00418 YXZr = GETEULERORDER( Z, EVEN, NOREPEAT, ROTATEFRAME ),
00419 ZXZr = GETEULERORDER( Z, EVEN, REPEAT, ROTATEFRAME ),
00420 XYZr = GETEULERORDER( Z, ODD, NOREPEAT, ROTATEFRAME ),
00421 ZYZr = GETEULERORDER( Z, ODD, REPEAT, ROTATEFRAME )
00422 };
00423
00424
00426 Vector3d m_kAngle;
00427
00429 unsigned int m_uiOrder;
00430
00435 EulerAngles( const Vector3d &rkAngle, unsigned int uiOrder = XYZs ) : m_kAngle( rkAngle ), m_uiOrder( uiOrder ) {}
00436
00443 EulerAngles( float fRot0, float fRot1, float fRot2, unsigned int uiOrder = XYZs ) : m_kAngle( fRot0, fRot1, fRot2 ), m_uiOrder( uiOrder ) {}
00444 };
00445
00446
00451 class AxisAngle
00452 {
00453 public:
00454
00456 Vector3d m_kAxis;
00457
00459 float m_fAngle;
00460
00465 AxisAngle( const Vector3d &rkAxis, float fAngle ) : m_kAxis( rkAxis ), m_fAngle( fAngle ) {}
00466 };
00467
00468
00474 class NEOENGINE_API Quaternion
00475 {
00476 public:
00477
00478
00480 float qx, qy, qz, qw;
00481
00482
00486 inline Quaternion();
00487
00495 inline Quaternion( float fX, float fY, float fZ, float fW );
00496
00501 inline Quaternion( const Matrix &rkMatrix );
00502
00508 inline Quaternion( const AxisAngle &rkAxisAngle );
00509
00514 inline Quaternion( const EulerAngles &rkAngles );
00515
00520 inline Quaternion &Reset();
00521
00530 inline Quaternion &Set( float fX, float fY, float fZ, float fW );
00531
00536 inline Quaternion &Normalize();
00537
00543 inline Matrix &ToMatrix( Matrix *pkMatrix ) const;
00544
00549 inline AxisAngle ToAxisAngle() const;
00550
00556 EulerAngles ToEulerAngles( unsigned int uiOrder = EulerAngles::XYZs ) const;
00557
00562 inline Quaternion &Inverse();
00563
00571 inline Quaternion &Slerp( float fT, const Quaternion &rkDest, bool bActuteAngle = false );
00572
00573
00574
00575
00576
00582 inline Quaternion &operator =( const Matrix &rkMatrix );
00583
00589 inline Quaternion &operator =( const AxisAngle &rkAxisAngle );
00590
00596 Quaternion &operator =( const EulerAngles &rkEulerAngles );
00597
00603 inline Quaternion operator *( const Quaternion &rkQuat ) const;
00604
00610 inline Quaternion operator *( float fScalar ) const;
00611
00617 inline Quaternion &operator *=( const Quaternion &rkQuat );
00618
00624 inline Quaternion &operator *=( float fScalar );
00625
00630 inline Quaternion operator ~() const;
00631
00637 inline Vector3d operator *( const Vector3d &rkVector ) const;
00638
00644 inline Quaternion operator +( const Quaternion &rkQuat ) const;
00645
00651 inline bool operator ==( const Quaternion &rkQuat ) const;
00652
00658 inline bool operator !=( const Quaternion &rkQuat ) const;
00659
00661 static const NE_STATIC Quaternion IDENTITY;
00662 };
00663
00664
00671 NEOENGINE_API std::ostream &operator << ( std::ostream &rkStream, const Quaternion &rkQuat );
00672
00673
00679 class NEOENGINE_API Matrix
00680 {
00681 private:
00682
00684 static const NE_STATIC float g_afIdentityMatrix[16];
00685
00686
00687 public:
00688
00690 float m_aafMatrix[4][4];
00691
00692
00693
00694
00698 inline Matrix();
00699
00704 inline Matrix( const Matrix &rkMatrix );
00705
00710 inline Matrix( const float afComponents[] );
00711
00716 inline Matrix( const Quaternion &rkQuat );
00717
00723 inline Matrix( const Quaternion &rkQuat, const Vector3d &rkTranslation );
00724
00729 inline Matrix( const Vector3d &rkVector );
00730
00735 inline Matrix &Reset();
00736
00742 inline Matrix &Set( float afComponents[] );
00743
00750 inline Matrix &Set( const Quaternion &rkQuat, const Vector3d &rkTranslation );
00751
00757 inline Matrix &Set( const Vector3d &rkVector );
00758
00764 inline Matrix &SetRotation( const Quaternion &rkQuat );
00765
00771 inline Matrix &SetTranslation( const Vector3d &rkTranslation );
00772
00777 inline Matrix &Transpose();
00778
00784 inline Matrix &TransposeTo( Matrix *pkMatrix );
00785
00791 inline Vector3d GetColumn( int iColumn ) const;
00792
00793
00794
00795
00801 inline Matrix &operator =( const Matrix &rkMatrix );
00802
00808 inline Matrix &operator =( const Quaternion &rkQuat );
00809
00815 inline Matrix operator *( const Matrix &rkMatrix ) const;
00816
00822 inline Matrix &operator *=( const Matrix &rkMatrix );
00823
00829 inline Matrix operator * ( float fScale ) const;
00830
00836 inline Matrix &operator *= ( float fScale );
00837
00843 inline Matrix operator - ( const Matrix &rkMatrix ) const;
00844
00850 inline Matrix &operator -= ( const Matrix &rkMatrix );
00851
00857 inline Matrix operator + ( const Matrix &rkMatrix ) const;
00858
00864 inline Matrix &operator += ( const Matrix &rkMatrix );
00865
00871 inline Vector3d operator *( const Vector3d &rkVector ) const;
00872
00878 inline bool operator ==( const Matrix &rkMatrix ) const;
00879
00885 inline bool operator !=( const Matrix &rkMatrix ) const;
00886
00892 inline float *operator []( int iRow );
00893
00897 inline operator float*() { return &m_aafMatrix[0][0]; }
00898
00904 inline const float *operator []( int iRow ) const;
00905
00909 inline operator const float*() const { return &m_aafMatrix[0][0]; }
00910
00912 static const NE_STATIC Matrix IDENTITY;
00913
00917 bool operator < ( const Matrix &rkMatrix ) const { return false; }
00918 };
00919
00920
00927 NEOENGINE_API std::ostream &operator << ( std::ostream &rkStream, const Matrix &rkMatrix );
00928
00929
00930
00931
00938 class NEOENGINE_API ODE
00939 {
00940 protected:
00941
00943 float **m_ppfState;
00944
00946 float *m_pfDerive;
00947
00949 int m_iStateSize;
00950
00951
00952 public:
00953
00957 ODE();
00958
00962 virtual ~ODE();
00963
00968 void SetStateSize( int iStateSize );
00969
00975 void EulerODE( float fDeltaTime, int iSteps );
00976
00980 virtual void Derive() = 0;
00981
00986 virtual void CalcAuxiliary( float fStepTime ) = 0;
00987
00991 virtual void PostODE() = 0;
00992 };
00993
00994
00995
00996
00997 #include "nemath_inl.h"
00998
00999
01000 };
01001
01002
01003 #endif // __NEMATH_H