math.h

Go to the documentation of this file.
00001 //**************************************************************************/
00002 // Copyright (c) 2008 Autodesk, Inc.
00003 // All rights reserved.
00004 
00005 // Use of this software is subject to the terms of the Autodesk license
00006 // agreement provided at the time of installation or download, or which
00007 // otherwise accompanies this software in either electronic or hard copy form.
00008 //
00009 
00010 //**************************************************************************/                      
00011 // DESCRIPTION:
00012 // CREATED: October 2008
00013 //**************************************************************************/
00014 
00015 #if defined(_MSC_VER)
00016 #pragma warning(push)
00017 #pragma warning(disable : 4201)
00018 #endif
00019 
00020 
00021 #include <xmmintrin.h>
00022 
00023 #if defined(WIN32) || defined(WIN64)
00024 #include <intrin.h>
00025 #endif
00026 
00027 #if (defined(_WIN32) && !defined(_WIN64))
00028 #define OS_32BIT true
00029 #endif
00030 
00031 
00032 namespace mudbox {
00033 
00035 class MBDLL_DECL Vector
00036 {
00037 public:
00039     inline Vector( void ) throw() { x = y = z = 0.0f; };
00040 
00042     inline Vector( float fX, float fY, float fZ = 0.0f ) throw() 
00043     { x = fX; y = fY; z = fZ; };
00044 
00046     inline Vector( const Vector &vVector ) throw() 
00047     { x = vVector.x; y = vVector.y; z = vVector.z; };
00048 
00052     inline Vector( const char *pVector ) throw()
00053     { x = pVector[0]*(1.0f/127.0f); y = pVector[1]*(1.0f/127.0f); z = pVector[2]*(1.0f/127.0f); };
00054 
00057     inline Vector( const short *pVector ) throw() 
00058     { x = pVector[0]*(1.0f/32767.0f); y = pVector[1]*(1.0f/32767.0f); z = pVector[2]*(1.0f/32767.0f); };
00059 
00061     inline Vector &Set( float fX, float fY, float fZ ) throw() 
00062     { x = fX; y = fY; z = fZ; return *this; };
00063 
00065     inline Vector &Clear( void ) throw () 
00066     { return Set( 0.0f, 0.0f, 0.0f ); };
00067 
00071     Vector &Normalize( void ) throw();
00072 
00077     Vector &NormalizeApprox( void ) throw();
00078 
00080     Vector Normalized( void ) const throw();
00081 
00087     Vector &MakeOrthogonal( const Vector &vBase );
00088 
00094     inline Vector &SetLength( float fLength ) 
00095     { Normalize(); operator *=( fLength ); return *this; };
00096 
00097 
00103     inline Vector &RotateOrthogonal( const Vector &vBase ) 
00104     { float fLen = Length(); MakeOrthogonal( vBase ); SetLength( fLen ); return *this; };
00105 
00106     
00108     inline float LengthSquare( void ) const { return x*x+y*y+z*z; };
00109     
00111     float Length() const throw();
00112 
00114     float Length2D() const throw();
00115 
00118     inline float DistanceFrom( const Vector &v ) const { return operator -(v).Length(); };
00119 
00122     float DistanceFromLine( const Vector &v0, const Vector &v1 ) const;
00123 
00126     float DistanceFromSegment( const Vector &v0, const Vector &v1 ) const;
00127 
00134     float DistanceFromTriangleSquared( const Vector& v0, const Vector& v1, const Vector& v2, 
00135                                        float* aBaryCoords = 0 ) const;
00136 
00149     const Vector &Relocate2D( const Vector &v0, const Vector &v1 );
00150 
00160     void Relocate( const Vector &v0, const Vector &v1, const Vector &v2 );
00161 
00162 
00183     bool Relocate2DQuad( const Vector &v0, const Vector &v1, 
00184                          const Vector &v2, const Vector &v3 );
00185 
00191     bool RelocateQuad( const Vector &v0, const Vector &v1, 
00192                          const Vector &v2, const Vector &v3 );
00193     
00195     float AngleCos( const Vector &v1 ) const throw() 
00196     { return Vector(*this).Normalize()|Vector(v1).Normalize(); };
00197     
00198 
00201     inline Vector Minimum( const Vector &o ) 
00202     { return Vector( Min(x, o.x), Min(y, o.y), Min(z, o.z) ); };
00203 
00206     inline Vector Maximum( const Vector &o ) 
00207     { return Vector( Max(x, o.x), Max(y, o.y), Max(z, o.z) ); };
00208 
00210     inline Vector operator -( void ) const throw() 
00211     { return Vector( -x, -y, -z ); };
00212 
00215     inline Vector operator +( float f ) const throw() 
00216     { return Vector( x+f, y+f, z+f ); };
00217 
00219     inline Vector operator +( const Vector &v ) const throw() 
00220     { return Vector( x+v.x, y+v.y, z+v.z ); };
00221 
00223     inline Vector operator -( const Vector &v ) const throw() 
00224     { return Vector( x-v.x, y-v.y, z-v.z ); };
00225 
00227     inline Vector operator *( const Vector &v ) const throw() 
00228     { return Vector( x*v.x, y*v.y, z*v.z ); };
00229 
00231     inline Vector operator *( float f ) const throw() 
00232     { return Vector( x*f, y*f, z*f ); };
00233     
00235     inline Vector operator /( const Vector &v ) const throw() 
00236     { return Vector( x/v.x, y/v.y, z/v.z ); };
00237 
00239     inline Vector operator /( float f ) const throw() 
00240     { return operator *( 1.0f/f ); };
00241 
00243     inline Vector operator *( int i ) const throw() 
00244     { return operator *( float(i) ); };
00245 
00247     inline Vector operator /( int i ) const throw() 
00248     { return operator /( float(i) ); };
00249 
00251     inline Vector operator /( unsigned int i ) const throw() 
00252     { return operator /( float(i) ); };
00253 
00255     inline float operator |( const Vector &v ) const throw() 
00256     { return x*v.x+y*v.y+z*v.z; };
00257 
00259     Vector operator &( const Vector &v ) const
00260     {
00261         Vector vR;
00262         vR.m_fX = m_fY*v.m_fZ-m_fZ*v.m_fY;
00263         vR.m_fY = m_fZ*v.m_fX-m_fX*v.m_fZ;
00264         vR.m_fZ = m_fX*v.m_fY-m_fY*v.m_fX;
00265         return vR;
00266     };
00267 
00268 
00271     inline bool operator ==( const Vector &v ) const throw() 
00272     { return x == v.x && y == v.y && z == v.z; };
00273 
00275     inline bool operator !=( const Vector &v ) const throw() 
00276     { return !operator ==( v ); };
00277 
00279     inline operator bool( void ) const throw() { return x || y || z; };
00280     
00282     inline bool operator !( void ) const throw() { return !operator bool(); };
00283 
00285     inline Vector &operator =( const Vector &v ) 
00286     { x = v.x; y = v.y; z = v.z; return *this; };
00287 
00289     inline Vector &operator <<( const Vector &v ) 
00290     { x = v.x; y = v.y; z = v.z; return *this; };
00291 
00294     inline Vector &operator -=( const Vector &v ) throw() 
00295     { x-=v.x; y-=v.y; z-=v.z; return *this; };
00296     
00298     inline Vector &operator +=( const Vector &v ) throw() 
00299         { x+=v.x; y+=v.y; z+=v.z; return *this; };
00300 
00303     inline Vector &operator *=( float f ) { x *= f; y *= f; z *= f; return *this; };
00304 
00307     inline Vector &operator *=( const Vector &v ) 
00308         { x *= v.x; y *= v.y; z *= v.z; return *this; };
00309 
00311     inline Vector &operator /=( float f ) { return operator *=( 1.0f/f ); };
00312 
00314     inline float &operator [] (
00315         int i   
00316         ) throw() { return m_aCoors[i]; };
00317 
00319     inline float &operator [](
00320         unsigned int i  
00321         ) throw() { return m_aCoors[i]; };
00322         
00324     inline operator const float *( void ) const { return &x; };
00325     union 
00326     {
00327         struct { float m_fX, m_fY, m_fZ; };
00328         struct { float x, y, z; };
00329         float m_aCoors[3];
00330     };
00331 };
00332 
00333 
00334 
00336 class MBDLL_DECL DblVector
00337 {
00338 public:
00340     inline DblVector( void ) throw() { x = y = z = 0.0; };
00341 
00342 
00343     Vector Vec() const {
00344         return Vector((float)x, (float)y, (float)z);
00345     }
00346 
00348     inline DblVector( double fX, double  fY, double  fZ = 0.0 ) throw() 
00349     { x = fX; y = fY; z = fZ; };
00350 
00352     inline DblVector( const DblVector &vVector ) throw() 
00353     { x = vVector.x; y = vVector.y; z = vVector.z; };
00354 
00356     inline DblVector( const Vector &vVector ) throw() 
00357     { x = vVector.x; y = vVector.y; z = vVector.z; };
00358 
00362     inline DblVector( const char *pVector ) throw()
00363     { x = pVector[0]*(1.0/127.0); y = pVector[1]*(1.0/127.0); z = pVector[2]*(1.0/127.0); };
00364 
00367     inline DblVector( const short *pVector ) throw() 
00368     { x = pVector[0]*(1.0/32767.0); y = pVector[1]*(1.0/32767.0); z = pVector[2]*(1.0/32767.0); };
00369 
00371     inline DblVector &Set( double fX, double fY, double fZ ) throw() 
00372     { x = fX; y = fY; z = fZ; return *this; };
00373 
00375     inline DblVector &Clear( void ) throw () 
00376     { return Set( 0.0, 0.0, 0.0 ); };
00377 
00381     DblVector &Normalize( void ) throw();
00382 
00384     DblVector Normalized( void ) const throw();
00385 
00391     DblVector &MakeOrthogonal( const DblVector &vBase );
00392 
00398     inline DblVector &SetLength( double fLength ) 
00399     { Normalize(); operator *=( fLength ); return *this; };
00400 
00401     
00403     inline double LengthSquare( void ) const { return x*x+y*y+z*z; };
00404     
00406     double Length() const throw();
00407 
00409     double Length2D() const throw();
00410 
00413     inline double DistanceFrom( const DblVector &v ) const { return operator -(v).Length(); };
00414 
00417     double DistanceFromLine( const DblVector &v0, const DblVector &v1 ) const;
00418 
00421     double DistanceFromSegment( const DblVector &v0, const DblVector &v1 ) const;
00422 
00423     
00425     double AngleCos( const DblVector &v1 ) const throw() 
00426     { return DblVector(*this).Normalize()|DblVector(v1).Normalize(); };
00427     
00430     inline DblVector Minimum( const DblVector &o ) 
00431     { return DblVector( Min(x, o.x), Min(y, o.y), Min(z, o.z) ); };
00432 
00435     inline DblVector Maximum( const DblVector &o ) 
00436     { return DblVector( Max(x, o.x), Max(y, o.y), Max(z, o.z) ); };
00437 
00439     inline DblVector operator -( void ) const throw() 
00440     { return DblVector( -x, -y, -z ); };
00441 
00444     inline DblVector operator +( double f ) const throw() 
00445     { return DblVector( x+f, y+f, z+f ); };
00446 
00448     inline DblVector operator +( const DblVector &v ) const throw() 
00449     { return DblVector( x+v.x, y+v.y, z+v.z ); };
00450 
00452     inline DblVector operator -( const DblVector &v ) const throw() 
00453     { return DblVector( x-v.x, y-v.y, z-v.z ); };
00454 
00456     inline DblVector operator *( const DblVector &v ) const throw() 
00457     { return DblVector( x*v.x, y*v.y, z*v.z ); };
00458 
00460     inline DblVector operator *( double f ) const throw() 
00461     { return DblVector( x*f, y*f, z*f ); };
00462     
00464     inline DblVector operator /( const DblVector &v ) const throw() 
00465     { return DblVector( x/v.x, y/v.y, z/v.z ); };
00466 
00468     inline DblVector operator /( double f ) const throw() 
00469     { return operator *( 1.0/f ); };
00470 
00472     inline DblVector operator *( int i ) const throw() 
00473     { return operator *( double(i) ); };
00474 
00476     inline DblVector operator /( int i ) const throw() 
00477     { return operator /( double(i) ); };
00478 
00480     inline DblVector operator /( unsigned int i ) const throw() 
00481     { return operator /( double(i) ); };
00482 
00484     inline double operator |( const DblVector &v ) const throw() 
00485     { return x*v.x+y*v.y+z*v.z; };
00486 
00488     DblVector operator &( const DblVector &v ) const
00489     {
00490         DblVector vR;
00491         vR.m_fX = m_fY*v.m_fZ-m_fZ*v.m_fY;
00492         vR.m_fY = m_fZ*v.m_fX-m_fX*v.m_fZ;
00493         vR.m_fZ = m_fX*v.m_fY-m_fY*v.m_fX;
00494         return vR;
00495     };
00496 
00499     inline bool operator ==( const DblVector &v ) const throw() 
00500     { return x == v.x && y == v.y && z == v.z; };
00501 
00503     inline bool operator !=( const DblVector &v ) const throw() 
00504     { return !operator ==( v ); };
00505 
00507     inline operator bool( void ) const throw() { return x || y || z; };
00508     
00510     inline bool operator !( void ) const throw() { return !operator bool(); };
00511 
00513     inline DblVector &operator =( const DblVector &v ) 
00514     { x = v.x; y = v.y; z = v.z; return *this; };
00515 
00517     inline DblVector &operator <<( const DblVector &v ) 
00518     { x = v.x; y = v.y; z = v.z; return *this; };
00519 
00522     inline DblVector &operator -=( const DblVector &v ) throw() 
00523     { x-=v.x; y-=v.y; z-=v.z; return *this; };
00524     
00526     inline DblVector &operator +=( const DblVector &v ) throw() 
00527         { x+=v.x; y+=v.y; z+=v.z; return *this; };
00528 
00531     inline DblVector &operator *=( double f ) { x *= f; y *= f; z *= f; return *this; };
00532 
00535     inline DblVector &operator *=( const DblVector &v ) 
00536         { x *= v.x; y *= v.y; z *= v.z; return *this; };
00537 
00539     inline DblVector &operator /=( double f ) { return operator *=( 1.0/f ); };
00540 
00542     inline double &operator [] (
00543         int i   
00544         ) throw() { return m_aCoors[i]; };
00545 
00547     inline double &operator [](
00548         unsigned int i  
00549         ) throw() { return m_aCoors[i]; };
00550         
00552     inline operator const double *( void ) const { return &x; };
00553     union 
00554     {
00555         struct { double m_fX, m_fY, m_fZ; };
00556         struct { double x, y, z; };
00557         double m_aCoors[3];
00558     };
00559 };
00560 
00561 
00563 inline MBDLL_DECL Vector operator *( float f, const Vector &v ) throw() 
00564 { return v*f; };
00565 
00567 inline MBDLL_DECL Vector operator *( int i, const Vector &v ) throw() 
00568 { return float(i)*v; };
00569 
00571 inline MBDLL_DECL DblVector operator *( double f, const DblVector &v ) throw() 
00572 { return v*f; };
00573 
00575 inline MBDLL_DECL DblVector operator *( int i, const DblVector &v ) throw() 
00576 { return double(i)*v; };
00577 
00578 typedef AttributeInstance<Vector> avector;
00579 
00580 MBDLL_DECL AttributeWidget *CreateNewVectorWidget( QWidget *pParent, 
00581                                                    int      iWidth, 
00582                                                    avector *pAttribute );
00583 
00584 template <> inline
00585 AttributeWidget *avector::CreateEditorWidget( QWidget *pParent, int iWidth ) 
00586 { return CreateNewVectorWidget( pParent, iWidth, this ); };
00587 
00588 template <> inline
00589 QString avector::AsString( bool /*bLocalized*/ ) const 
00590 { return QString("%1 %2 %3").arg(m_cValue.x).arg(m_cValue.y).arg(m_cValue.z); };
00591 
00592 template <> inline
00593 void avector::SetFromString( const QString &s, bool /*bInternal*/, bool /*bLocalized*/ ) 
00594 { 
00595     m_cValue.x = s.section( ' ', 0,0 ).toFloat();
00596     m_cValue.y = s.section( ' ', 1,1 ).toFloat(); 
00597     m_cValue.z = s.section( ' ', 2,2 ).toFloat(); 
00598 };
00599 
00600 template <> inline
00601 Attribute::AttributeType avector::Type( void ) const { return typeVector; };
00602 
00603 
00605 class MBDLL_DECL Vector4
00606 {
00607 public:
00608     Vector4() { x=y=z=w=0.0f; }
00609 
00610     Vector4(float X, float Y, float Z, float W) {x=X; y=Y; z=Z; w=W;}
00611 
00612     inline bool operator ==( const Vector4 &v ) const throw() 
00613     { return x == v.x && y == v.y && z == v.z; };
00614 
00615     inline bool operator !=( const Vector4 &v ) const throw() 
00616     { return !operator ==( v ); };
00617 
00618     union {
00619         struct {
00620             float x, y, z, w;
00621         };
00622         double  m_dAlignDummy;    // try for 8 byte alignment.
00623 #if !defined  OS_32BIT 
00624         __m128  m_VecSSE;         // get 16 byte alignment.
00625 #endif
00626     };
00627 };
00628 
00629 
00630 
00631 typedef AttributeInstance<Vector4> avector4;
00632 
00633 MBDLL_DECL AttributeWidget *CreateNewVector4Widget( QWidget *pParent, int iWidth, avector4 *pAttribute );
00634 
00635 template <> inline
00636 
00637 AttributeWidget *avector4::CreateEditorWidget( QWidget *pParent, int iWidth ) 
00638 { return CreateNewVector4Widget( pParent, iWidth, this ); };
00639 
00640 template <> inline
00641 QString avector4::AsString( bool /*bLocalized*/ ) const 
00642 { return QString("%1 %2 %3 %4").arg(m_cValue.x).arg(m_cValue.y).arg(m_cValue.z).arg(m_cValue.w); };
00643 
00644 template <> inline
00645 void avector4::SetFromString( const QString &s, bool /*bInternal*/, bool /*bLocalized*/ ) 
00646 {
00647     m_cValue.x = s.section( ' ', 0, 0 ).toFloat(); 
00648     m_cValue.y = s.section( ' ', 1, 1 ).toFloat(); 
00649     m_cValue.z = s.section( ' ', 2, 2 ).toFloat(); 
00650     m_cValue.w = s.section( ' ', 3, 3 ).toFloat();
00651 };
00652 
00653 template <> inline
00654 Attribute::AttributeType avector4::Type( void ) const { return typeVector; };
00655 
00656 
00657 
00661 
00662 class MBDLL_DECL Color
00663 
00664 {
00665 public:
00666 
00669     Color( float fRed = 1.0f, float fGreen = 1.0f, float fBlue = 1.0f, float fAlpha = 1.0f ) 
00670     { m_fRed = fRed; m_fGreen = fGreen; m_fBlue = fBlue, m_fAlpha = fAlpha; };
00671 
00672 #ifdef QT_VERSION
00673 
00674     Color( const QColor &c ) 
00675     { r = c.redF(); 
00676       g = c.greenF(); 
00677       b = c.blueF(); 
00678       a = 1.0f; };
00679 
00680 #endif
00681 
00683     inline void Set( float fRed, float fGreen, float fBlue, float fAlpha = 1.0f ) 
00684     { r = fRed; g = fGreen; b = fBlue; a = fAlpha; };
00685 
00686 
00689     inline operator const float *( void ) const { return &m_fRed; };
00690 
00692     inline float &operator[]( unsigned int iChannel ) 
00693     { MB_ASSERT( iChannel < 4 ); return m_fData[iChannel]; };
00694 
00697     inline operator unsigned int( void ) const 
00698         { return (unsigned int)(0xff*m_fRed)+(((unsigned int)(0xff*m_fGreen))<<8)+
00699             (((unsigned int)(0xff*m_fBlue))<<16)+(((unsigned int)(0xff*m_fAlpha))<<24); };
00700 
00701 
00704     Color &operator *=(const float f) { r*=f; g*=f; b*=f; return *this; };
00705 
00707     Color operator *( float f ) const 
00708         { return Color( r*f, g*f, b*f, a*f ); };
00709 
00711     Color operator /( float f ) const 
00712         { return operator *( 1/f ); };
00713 
00715     Color operator *( const Color &c ) const 
00716         { return Color( r*c.r, g*c.g, b*c.b, a*c.a ); };
00717 
00720     Color &operator *=( const Color &c ) 
00721     { r *= c.r; g *= c.g; b *= c.b; a *= c.a; return *this; };
00722 
00724     Color operator +( const Color &c ) const 
00725         { return Color( r+c.r, g+c.g, b+c.b, a+c.a ); };
00726 
00728     Color operator -( const Color &c ) const 
00729         { return Color( r-c.r, g-c.g, b-c.b, a-c.a ); };
00730 
00732     Color &operator +=( const Color &c ) 
00733     { r += c.r; g += c.g; b += c.b; a += c.a; return *this; };
00734 
00736     bool operator ==( const Color &c ) const 
00737         { return r == c.r && g == c.g && b == c.b && a == c.a; };
00738 
00740     inline bool operator !=( const Color &c ) const { return !operator ==( c ); };
00741     
00742 
00750     Color Mix( const Color &c, float f ) const
00751     { return Color( r*f+c.r*(1-f), g*f+c.g*(1-f), b*f+c.b*(1-f), a*f+c.a*(1-f) ); };
00752 
00754     inline float Luminance() const 
00755         { return 0.299f * r + 0.587f * g + 0.114f * b; }
00756 
00757     
00758 
00759 #ifdef QT_VERSION
00760     operator QColor( void ) const { QColor col; col.setRgbF( r, g, b ); return col; };
00761     QColor ToQColor( void ) const { QColor col; col.setRgbF( r, g, b ); return col; };
00762 #endif
00763 
00764     union {
00765         struct { float m_fRed, m_fGreen, m_fBlue, m_fAlpha; };
00766         struct { float r, g, b, a; };
00767         float  m_fData[4];
00768 
00769         double m_dAlignDummy;   // try for 8 byte alignment.
00770 #if !defined  OS_32BIT 
00771         __m128 m_vAlignDummy;   // try for 16 byte alignment....
00772 #endif
00773     };
00774 
00775     static Color black;
00776     static Color white;
00777     static Color red;
00778     static Color green;
00779     static Color blue;
00780     static Color gray;
00781     static Color transparent;
00782 };
00783 
00784 
00785 
00787 inline Color operator *( float f, const Color &c ) 
00788 { return Color( c.r*f, c.g*f, c.b*f, c.a*f ); };
00789 
00790 
00791 typedef AttributeInstance<Color> acolor;
00792 
00793 MBDLL_DECL AttributeWidget *CreateNewColorWidget( QWidget *pParent, int iWidth, acolor *pAttribute );
00794 
00795 template <> inline
00796 AttributeWidget *acolor::CreateEditorWidget( QWidget *pParent, int iWidth ) 
00797 { return CreateNewColorWidget( pParent, iWidth, this ); };
00798 
00799 template <> inline
00800 Attribute::AttributeType acolor::Type( void ) const { return typeColor; };
00801 
00802 template <> inline
00803 QString acolor::AsString( bool /*bLocalized*/ ) 
00804 const { return QString("%1 %2 %3 %4").arg(m_cValue.r).arg(m_cValue.g).arg(m_cValue.b).arg(m_cValue.a); };
00805 
00806 template <> inline
00807 void acolor::SetFromString( const QString &s, bool /*bInternal*/, bool /*bLocalized*/ ) 
00808 {
00809     m_cValue.r = s.section( ' ', 0, 0 ).toFloat(); 
00810     m_cValue.g = s.section( ' ', 1, 1 ).toFloat(); 
00811     m_cValue.b = s.section( ' ', 2, 2 ).toFloat(); 
00812     m_cValue.a = s.section( ' ', 3, 3 ).toFloat();
00813 };
00814 
00815 
00816 
00820 class MBDLL_DECL AxisAlignedBoundingBox
00821 {
00822 public:
00824     AxisAlignedBoundingBox( void ) { Reset(); };
00825 
00827     AxisAlignedBoundingBox( const Vector &vStart, const Vector &vEnd ) :
00828         m_vStart( vStart ),
00829         m_vEnd( vEnd ) {};
00830 
00833     AxisAlignedBoundingBox( const Vector &vCenter, float fSize )
00834     {
00835         Vector v( fSize, fSize, fSize );
00836         m_vStart = vCenter-v;
00837         m_vEnd   = vCenter+v;
00838     };
00839 
00841     AxisAlignedBoundingBox( const AxisAlignedBoundingBox &cA ) :
00842     m_vStart( cA.m_vStart ),
00843     m_vEnd( cA.m_vEnd ) {};
00844 
00846     AxisAlignedBoundingBox &operator =( const AxisAlignedBoundingBox &cBB )
00847     {
00848         m_vStart = cBB.m_vStart;
00849         m_vEnd = cBB.m_vEnd;
00850         return *this;
00851     };
00852 
00854     AxisAlignedBoundingBox &operator +=( const AxisAlignedBoundingBox &cBB )
00855     {
00856         for ( int i = 0; i < 8; i++ ) Extend( cBB[i] );
00857         return *this;
00858     };
00859 
00861     bool operator ==( const AxisAlignedBoundingBox &cBB ) const
00862     {
00863         return m_vStart == cBB.m_vStart && m_vEnd == cBB.m_vEnd;
00864     };
00865 
00867     void Reset( void )
00868     {
00869         m_vStart.Set( 0, 0, 0 );
00870         m_vEnd.Set( -1, -1, -1 );
00871     };
00872 
00874     void Serialize( Stream &s );
00875 
00876 
00878     bool operator !=( const AxisAlignedBoundingBox &cBox ) const 
00879         { return !(operator ==(cBox)); };
00880 
00881 
00883     void Extend( const Vector & );
00884 
00886     void Extend( const AxisAlignedBoundingBox &bb )
00887     {
00888         if ( !bb.IsEmpty() ) {
00889             Extend( bb.m_vStart );
00890             Extend( bb.m_vEnd );
00891         };
00892     };
00893 
00894     
00899     void Transform( const class Matrix &mMatrix );
00900 
00902     Vector operator []( int iCornerIndex ) const;
00903 
00905     float Size( void ) const { return Max( Max( XSize(), YSize() ), ZSize() ); };
00906 
00908     float XSize( void ) const { return m_vEnd.m_fX-m_vStart.m_fX; };
00909 
00911     float YSize( void ) const { return m_vEnd.m_fY-m_vStart.m_fY; };
00912 
00914     float ZSize( void ) const { return m_vEnd.m_fZ-m_vStart.m_fZ; };
00915 
00917     float Volume( void ) const { return XSize()*YSize()*ZSize(); };
00918 
00920     Vector Center( void ) const { return (m_vStart+m_vEnd)*0.5f; };
00921 
00923     bool IsPartOf( const AxisAlignedBoundingBox &cBB ) const
00924     {
00925         return (
00926             m_vStart.m_fX >= cBB.m_vStart.m_fX && m_vEnd.m_fX <= cBB.m_vEnd.m_fX &&
00927             m_vStart.m_fY >= cBB.m_vStart.m_fY && m_vEnd.m_fY <= cBB.m_vEnd.m_fY &&
00928             m_vStart.m_fZ >= cBB.m_vStart.m_fZ && m_vEnd.m_fZ <= cBB.m_vEnd.m_fZ );
00929     };
00930 
00932     bool IsTouching( const AxisAlignedBoundingBox &cBB ) const
00933     {
00934         return (
00935             m_vStart.m_fX < cBB.m_vEnd.m_fX && m_vEnd.m_fX > cBB.m_vStart.m_fX &&
00936             m_vStart.m_fY < cBB.m_vEnd.m_fY && m_vEnd.m_fY > cBB.m_vStart.m_fY &&
00937             m_vStart.m_fZ < cBB.m_vEnd.m_fZ && m_vEnd.m_fZ > cBB.m_vStart.m_fZ );
00938     };
00939     
00940 
00947     bool IsTouching(
00948         const Vector &vStart,   
00949         const Vector &vEnd,     
00950         float &fPlace           
00951 
00952         ) const;
00953 
00955     bool IsContaining( const Vector &cV ) const
00956     {
00957         return (
00958             m_vStart.m_fX <= cV.m_fX && m_vEnd.m_fX >= cV.m_fX &&
00959             m_vStart.m_fY <= cV.m_fY && m_vEnd.m_fY >= cV.m_fY &&
00960             m_vStart.m_fZ <= cV.m_fZ && m_vEnd.m_fZ >= cV.m_fZ );
00961     };
00962     
00963 
00965     bool IsContaining( const AxisAlignedBoundingBox &b ) const 
00966         { return IsContaining( b.m_vStart ) && IsContaining( b.m_vEnd ); };
00967     
00968 
00971     bool IsEmpty( void ) const { return m_vStart.x > m_vEnd.x; };
00972 
00974     AxisAlignedBoundingBox operator *( float fFactor )
00975     {
00976         return AxisAlignedBoundingBox( m_vStart*fFactor, m_vEnd*fFactor );
00977     };
00978 
00979     Vector m_vStart;
00980     Vector m_vEnd;
00981 };
00982 
00983 
00984 
00988 class MBDLL_DECL Base
00989 {
00990 
00991 public:
00993     Base( void );
00994 
00996     Base( const Vector &vA, const Vector &vB, const Vector &vC );
00997 
00999     bool operator !=( const Base &o ) const { return a != o.a || b != o.b || c != o.c; };
01000 
01002     void Derive(
01003         unsigned int iIndex,    
01004         bool bRightHand = true  
01005         );
01006 
01007 
01009 
01010     void Orthogonalize(
01011         unsigned int iIndex,        
01012         unsigned int iSource = (unsigned int)-1   
01013 
01014         );
01015 
01017     void Normalize( void ) { a.Normalize(); b.Normalize(); c.Normalize(); };
01018 
01019 
01021     Vector TransformFrom( const Vector &cSource ) const;
01022 
01024     Vector TransformTo( const Vector &cSource ) const;
01025 
01027     Base operator *( float fFactor ) const;
01028 
01030     Base operator +( const Base &bOther ) const;
01031 
01033     Base operator -( const Base &bOther ) const;
01034     
01036     Vector& Axis(
01037         unsigned int iIndex 
01038         );
01039 
01040 
01042     const Vector& Axis(
01043         unsigned int iIndex 
01044         ) const;
01045 
01046     Vector a, b, c;
01047 };
01048 
01049 
01050 
01052 class SubSpace : public Node
01053 
01054 {
01055     DECLARE_CLASS;
01056 
01057 public:
01058     virtual void Initialize( const class Mesh *pMesh, Store<unsigned int> aFaceList, float fAClip, float fBClip );
01059     virtual bool IsOutside( const Vector &vPos, float fRange ) const;
01060     virtual AxisAlignedBoundingBox BoundingBox( void ) const;
01061 };
01062 
01063 
01064 
01066 class MBDLL_DECL Matrix
01067 {
01068 public:
01069 
01071     Matrix( void ) {};
01072 
01073     Matrix( const Matrix &m ) :
01074         _11(m._11), _12(m._12), _13(m._13), _14(m._14), 
01075         _21(m._21), _22(m._22), _23(m._23), _24(m._24), 
01076         _31(m._31), _32(m._32), _33(m._33), _34(m._34), 
01077         _41(m._41), _42(m._42), _43(m._43), _44(m._44) {};
01078 
01080     Matrix( float f11, float f12, float f13, float f14,
01081             float f21, float f22, float f23, float f24,
01082             float f31, float f32, float f33, float f34,
01083             float f41, float f42, float f43, float f44 ) :
01084         _11(f11), _12(f12), _13(f13), _14(f14), 
01085         _21(f21), _22(f22), _23(f23), _24(f24), 
01086         _31(f31), _32(f32), _33(f33), _34(f34), 
01087         _41(f41), _42(f42), _43(f43), _44(f44) {};
01088 
01090     Matrix( const double *pMatrix );
01091 
01093     float &operator()( int iRow, int iColumn ) 
01094     { 
01095         return m_fData[iRow*4+iColumn]; 
01096     };
01097     
01099     float operator()( int iRow, int iColumn ) const 
01100     { 
01101         return m_fData[iRow*4+iColumn]; 
01102     };
01103     
01106     operator const float *( void ) const { return m_fData; };
01107     
01110     operator float *( void ) { return m_fData; };
01111 
01113     Matrix &SetIdentity( void );
01114 
01116     bool IsIdentity( void ) const;
01117 
01119     bool IsRigid( void ) const;
01120     
01122     Matrix &operator *=( float );
01123 
01125     Matrix operator *( const Matrix &m ) const;
01126 
01128     Matrix operator *( float ) const;
01129 
01131     Matrix operator +( const Matrix & ) const;
01132 
01134     Matrix &operator *=( const Matrix &m );
01135 
01137     bool operator ==( const Matrix &m ) const;
01138 
01141     void SetRow( int iRowIndex, const Vector &vValue );
01142 
01144     Matrix &Transpose( void );
01145 
01147     Matrix &Invert( void );
01148 
01151     Matrix &FromEuler( const Vector &vAngles );
01152 
01154     Vector ToEuler( void ) const;
01155     
01157     Matrix &FromAxisAngle( const Vector &vAxis, float fAngle );
01158 
01162     Vector Transform(
01163         const Vector &v,    
01164         float fW = 1.0f     
01165         ) const
01166     {
01167         return Vector( 
01168             v.m_fX*_11+v.m_fY*_21+v.m_fZ*_31+fW*_41,
01169             v.m_fX*_12+v.m_fY*_22+v.m_fZ*_32+fW*_42,
01170             v.m_fX*_13+v.m_fY*_23+v.m_fZ*_33+fW*_43 );
01171     };
01172 
01177     Vector ProjectedTransform(
01178         const Vector &v,    
01179         float fW = 1.0f     
01180         ) const
01181     {
01182         float fRW = v.m_fX*_14+v.m_fY*_24+v.m_fZ*_34+fW*_44;
01183         return (1/fRW)*Vector( 
01184             v.m_fX*_11+v.m_fY*_21+v.m_fZ*_31+fW*_41,
01185             v.m_fX*_12+v.m_fY*_22+v.m_fZ*_32+fW*_42,
01186             v.m_fX*_13+v.m_fY*_23+v.m_fZ*_33+fW*_43 );
01187     };
01188 
01189 
01195     Vector Transform(
01196         const Vector &v,    
01197         float fW,           
01198         float &fRW          
01199         ) const
01200     {
01201         fRW = v.m_fX*_14+v.m_fY*_24+v.m_fZ*_34+fW*_44;
01202         return Vector( 
01203             v.m_fX*_11+v.m_fY*_21+v.m_fZ*_31+fW*_41,
01204             v.m_fX*_12+v.m_fY*_22+v.m_fZ*_32+fW*_42,
01205             v.m_fX*_13+v.m_fY*_23+v.m_fZ*_33+fW*_43 );
01206     };
01207 
01212     Vector TransformDirection( const Vector &v ) const
01213     {
01214         return Vector( 
01215             v.m_fX*_11+v.m_fY*_21+v.m_fZ*_31,
01216             v.m_fX*_12+v.m_fY*_22+v.m_fZ*_32,
01217             v.m_fX*_13+v.m_fY*_23+v.m_fZ*_33 );
01218     };
01219 
01220     union {
01221         float  m_fData[16];
01222         struct {
01223             float _11, _12, _13, _14;
01224             float _21, _22, _23, _24;
01225             float _31, _32, _33, _34;
01226             float _41, _42, _43, _44;
01227         };
01228         double  m_fAlignDummy[8];   // at least get it 8 byte aligned.
01229 #if !defined  OS_32BIT 
01230         __m128  m_vAlignDummy[4];   // try for 16 byte....
01231 #endif
01232     };
01233 };
01235 typedef AttributeInstance<Matrix> amatrix;
01243 class MBDLL_DECL Quaternion
01244 {
01245 public:
01247     inline Quaternion( void ) { SetIdentity(); };
01248 
01250     inline Quaternion( 
01251         float fW, 
01252         const Vector &vXYZ 
01253         )
01254     { m_fW = fW; m_fX = vXYZ.x; m_fY = vXYZ.y; m_fZ = vXYZ.z; };
01255 
01257     inline Quaternion( float fW, float fX, float fY, float fZ )
01258     { m_fW = fW; m_fX = fX; m_fY = fY; m_fZ = fZ; };
01259 
01261     Quaternion( 
01262         const Vector &vAxis, 
01263         float fAngle 
01264         );
01265 
01267     Quaternion( const Matrix &mRotation );
01268 
01270     float LengthSquare( void ) const;
01271 
01274     float Length( void ) const;
01275 
01277     Matrix ToMatrix( void ) const;
01278 
01280     Vector Transform( 
01281         const Vector &vPoint 
01282         ) const;
01283 
01285     inline Quaternion operator *( float fMultiplier ) const
01286     { return Quaternion( m_fW*fMultiplier, m_fX*fMultiplier, m_fY*fMultiplier, m_fZ*fMultiplier ); };
01287 
01289     inline Quaternion &operator *=( float fMultiplier ) 
01290     { *this = operator *( fMultiplier ); return *this; };
01291 
01293     inline Quaternion operator -( void ) const 
01294     { return Quaternion( -m_fW, -m_fX, -m_fY, -m_fZ ); };
01295 
01297     Quaternion operator +( const Quaternion &vAddition ) const;
01298 
01300     Quaternion &operator +=( const Quaternion &vAddition );
01301 
01303     Quaternion operator -( const Quaternion &vAddition ) const;
01304 
01306     Quaternion &operator -=( const Quaternion &vAddition );
01307 
01310     Quaternion operator *( const Quaternion &vMultiplier ) const;
01311 
01313     Quaternion &operator *=( const Quaternion &vMultiplier );
01314 
01316     float operator |( const Quaternion &vMultiplier ) const;
01317 
01320     Quaternion &Normalize( void );
01321 
01323     Quaternion &Conjugate( void );
01324 
01327     Quaternion &Invert( void );
01328 
01330     Quaternion Slerp( const Quaternion &vTarget, float fWeight ) const;
01331 
01333     inline void SetIdentity( void ) 
01334     { m_fW = 1.0; m_fX = m_fY = m_fZ = 0.0f; };
01335 
01337     void SetZero( void ) { m_fW = m_fX = m_fY = m_fZ = 0.0f; };
01338 
01340     float operator []( 
01341         int iIndex 
01342         ) const;
01343 
01348     float m_fW, m_fX, m_fY, m_fZ;
01349 };
01350 
01358 class MBDLL_DECL DualQuaternion
01359 {
01360 public:
01362     inline DualQuaternion( void ) { SetIdentity(); };
01363 
01365     inline DualQuaternion( 
01366         const Quaternion &vReal, 
01367         const Quaternion &vDual  
01368         )
01369     { m_vReal = vReal; m_vDual = vDual; };
01370 
01373     DualQuaternion( 
01374         const Vector &vPivot, 
01375         const Vector &vAxis, 
01376         float fAngle 
01377         );
01378 
01380     DualQuaternion(
01381         float fAngle, 
01382         float fPitch, 
01383         const Vector &vDirection,
01384         const Vector &vMoment 
01385         );
01386 
01388     DualQuaternion( 
01389         const Vector &vTranslation, 
01390         const Quaternion &vRotation 
01391         );
01392 
01394     DualQuaternion( const Matrix &mRigid );
01395 
01397     Matrix ToMatrix( void ) const;
01398 
01400     Vector Translation( void ) const;
01401 
01403     Vector Transform( const Vector &vPoint ) const;
01404 
01406     DualQuaternion operator +( const DualQuaternion &vAddition ) const;
01407 
01409     DualQuaternion &operator +=( const DualQuaternion &vAddition );
01410 
01412     DualQuaternion operator -( const DualQuaternion &vAddition ) const;
01413 
01415     DualQuaternion &operator -=( const DualQuaternion &vAddition );
01416 
01419     DualQuaternion operator *( const DualQuaternion &vMultiplier ) const;
01420 
01422     DualQuaternion &operator *=( const DualQuaternion &vMultiplier );
01423 
01425     DualQuaternion operator *( float fMultiplier ) const;
01426 
01429     DualQuaternion &Normalize( void );
01430 
01432     void ToScrew( float &fAngle, float &fPitch, Vector &vDirection, Vector &vMoment ) const;
01433 
01435     DualQuaternion &Power( float fExponent );
01436 
01439     DualQuaternion Slerp( const DualQuaternion &vTarget, float fWeight ) const;
01440 
01442     DualQuaternion &Conjugate( void );
01443 
01445     DualQuaternion &DualConjugate( void );
01446 
01449     inline DualQuaternion &DoubleConjugate( void ) { Conjugate(); DualConjugate(); return *this; };
01450 
01453     DualQuaternion &Invert( void );
01454 
01456     void SetIdentity( void ) { m_vReal.SetIdentity(); m_vDual.SetZero(); };
01457 
01459     float operator []( 
01460         int iIndex 
01461         ) const;
01462 
01468     Quaternion m_vReal, m_vDual;
01469 
01470 private:
01473     DualQuaternion( const Vector &vPoint );
01474 
01475 };
01476 
01478 class MBDLL_DECL Line
01479 {
01480     Vector m_vStart, m_vEnd, m_vDirection;
01481     float m_fFactor;
01482 
01483 public:
01484 
01486     Line( const Vector &vStart, const Vector &vEnd );
01487 
01493 
01495 
01496     float RangeFrom( const Vector &vPoint );
01497 
01499     enum IntersectionResult
01500     {
01501         PARALLEL,
01502         COINCIDENT,
01503         NOT_INTERSECTING,
01504         INTERSECTING
01505     };
01506 
01510     IntersectionResult Intersection2D( const Line& cOther, Vector &vResult, bool bSegmentOnly = false );
01511 };
01512 
01513 
01520 
01522 
01526 
01527 class MBDLL_DECL Selector : virtual public Node
01528 {
01529     DECLARE_CLASS;
01530 
01531 public:
01532     enum EState
01533     {
01534         eInside,
01535         eOutside,
01536         eTouching
01537     };
01538 
01540     virtual EState IsTouchedBy( const AxisAlignedBoundingBox &cArea ) const;
01541 };
01542 
01543 
01544 inline MBDLL_DECL Vector operator *( const Vector &v, const Matrix &m )
01545 {
01546     return Vector( 
01547         v.m_fX*m._11+v.m_fY*m._21+v.m_fZ*m._31+m._41,
01548         v.m_fX*m._12+v.m_fY*m._22+v.m_fZ*m._32+m._42,
01549         v.m_fX*m._13+v.m_fY*m._23+v.m_fZ*m._33+m._43 );
01550 };
01551 
01552 inline MBDLL_DECL Vector operator *( const Matrix &m, const Vector &v ) 
01553 {
01554     return Vector( 
01555         v.m_fX*m._11+v.m_fY*m._12+v.m_fZ*m._13+m._14,
01556         v.m_fX*m._21+v.m_fY*m._22+v.m_fZ*m._23+m._24,
01557         v.m_fX*m._31+v.m_fY*m._32+v.m_fZ*m._33+m._34 );
01558 };
01559 
01560 
01565 class CheckableFloat
01566 {
01567 public:
01568     CheckableFloat( void ) { m_bState = true; m_fValue = 0.0f; };
01569     CheckableFloat( bool bState, float fValue ) { m_bState = bState; m_fValue = fValue; };
01570     
01572     void SetValue( float f ) { m_fValue = f; };
01573     
01575     float Value( void ) const { return m_fValue; };
01576     
01578     void SetState( bool b ) { m_bState = b; };
01579     
01581     bool State( void ) const { return m_bState; };
01582     
01583     inline bool operator ==( const CheckableFloat &cf ) const throw() { return State() == cf.State() && Value() == cf.Value(); };
01584     inline bool operator !=( const CheckableFloat &cf ) const throw() { return !operator ==( cf ); };
01585     inline CheckableFloat &operator =( const CheckableFloat &cf ) { m_bState = cf.m_bState; m_fValue = cf.m_fValue; return *this; };
01586 
01587     void Serialize( Stream &s )
01588     {
01589         s == m_bState == m_fValue;
01590     };
01591 
01592 
01593 protected:
01594     bool m_bState;
01595     float m_fValue;
01596 };
01597 
01598 class AttributeCheckableFloat;
01599 
01600 MBDLL_DECL AttributeWidget *CreateNewCheckableFloatWidget( QWidget *pParent, int iWidth, AttributeCheckableFloat *pAttribute );
01601 
01602 class AttributeCheckableFloat : public AttributeInstance<CheckableFloat>
01603 {
01604 public:
01605     AttributeCheckableFloat( Node *pOwner = 0, const QString &sID = "", const QString &sValueName = "" ) : AttributeInstance<CheckableFloat>( pOwner, sID )
01606         { m_iSize = sizeof(CheckableFloat); m_sValueName = sValueName; };
01607     void SetValueName( const QString &sValueName ) { m_sValueName = sValueName; };
01608     QString ValueName( void ) const { return m_sValueName; };
01609 
01610     Attribute::AttributeType Type( void ) const { return typeUnknown; };
01611     AttributeWidget *CreateEditorWidget( QWidget *pParent, int iWidth ) { return CreateNewCheckableFloatWidget( pParent, iWidth, (AttributeCheckableFloat *)this ); };
01612     QString AsString( bool /*bLocalized*/ ) const { return QString("%1 %2").arg(m_cValue.State() ? "true" : "false").arg(m_cValue.Value()); };
01613     void SetFromString( const QString &s, bool /*bInternal*/ = true, bool /*bLocalized*/ = false )
01614     {
01615         m_cValue.SetState( s.section( ' ', 0, 0 ) == "true" ? true : false );
01616         m_cValue.SetValue( s.section( ' ', 1, 1 ).toFloat() );
01617     };
01618 
01619 protected:
01620     QString m_sValueName;
01621 };
01622 
01623 typedef AttributeCheckableFloat acheckablefloat;
01624 // data structure, references: StampConfiguration and CheckableFloat.
01625 struct MBDLL_DECL CheckableFloatArray  
01626 {
01627 
01628     CheckableFloatArray()
01629     {
01630         m_iSize = 2;
01631         m_aValue[0] = 0; m_aValue[1] = 1;
01632         m_bComplementary = false;
01633     }
01634 
01636     void SetState( bool b ) { s_bActive = b; }; 
01638     bool State( void ) const { return s_bActive; };
01639 
01640     float Value(unsigned int i) const { MB_ASSERT(i < m_iSize); return m_aValue[i]; } 
01641     void SetValue(unsigned int i, float v) { MB_ASSERT(i < m_iSize); m_aValue[i] = v; }
01642 
01643     void AddElement(unsigned int i, QString sLabel, float fMin, float fMax, float fValue)
01644     {
01645         MB_ASSERT(i < m_iSize); 
01646         MB_ASSERT(fValue > fMin && fValue < fMax); 
01647         m_aLabel[i] = sLabel;
01648         m_aMin[i] = fMin;
01649         m_aMax[i] = fMax;
01650         m_aValue[i] = fValue; 
01651     }
01652     
01653     unsigned int Size() const { return m_iSize; }
01654 
01657     bool IsComplementary() const { return m_bComplementary; }
01658     void SetComplementary(bool b) { m_bComplementary = b; }
01659 
01660     inline bool operator ==( const CheckableFloatArray & ) const throw() { return false; };
01661     inline bool operator !=( const CheckableFloatArray &v ) const throw() { return !operator ==( v ); };
01662 
01663     void Serialize( Stream &s )
01664     {
01665         s == s_bActive == m_iSize == m_bComplementary;
01666         for (unsigned int i = 0; i < m_iSize; ++i)
01667             s == m_aLabel[i] == m_aMin[i] == m_aMax[i] == m_aValue[i];
01668     };
01669 
01670     static bool s_bActive;
01671     unsigned int m_iSize;
01672     QString m_aLabel[2];
01673     float m_aMin[2];
01674     float m_aMax[2];         
01675     float m_aValue[2];  
01676     bool m_bComplementary;
01677 };
01678 
01679 class AttributeCheckableFloatArray;
01680 
01681 MBDLL_DECL AttributeWidget *CreateNewCheckableFloatArrayWidget( QWidget *pParent, int iWidth, class AttributeCheckableFloatArray *pAttribute );
01682 
01683 class AttributeCheckableFloatArray : public AttributeInstance<CheckableFloatArray>
01684 {
01685 public:
01686     AttributeCheckableFloatArray( Node *pOwner = 0, const QString &sID = "" ) 
01687         : AttributeInstance<CheckableFloatArray>( pOwner, sID )
01688     { m_iSize = sizeof(CheckableFloat); }; 
01689 
01690     Attribute::AttributeType Type( void ) const { return typeUnknown; };
01691     AttributeWidget *CreateEditorWidget( QWidget *pParent, int iWidth ) 
01692     { 
01693         return CreateNewCheckableFloatArrayWidget( pParent, iWidth, (AttributeCheckableFloatArray *)this ); 
01694     };
01695     // the data structure of this attribute 
01696     //QString AsString( unsigned int /*options*/ ) const { return QString("%1 %2").arg(m_cValue.State() ? "true" : "false").arg(m_cValue.Value()); };
01697     //void SetFromString( const QString &s, bool /*bInternal*/ = true, bool /*bLocalized*/ = false )
01698     //{
01699     //  m_cValue.SetState( s.section( ' ', 0, 0 ) == "true" ? true : false );
01700     //  m_cValue.SetValue( s.section( ' ', 1, 1 ).toFloat() );
01701     //};
01702 
01703 protected:                
01704 };
01705 
01706 //-----------------------------------------------------------------------------
01710 static inline bool FloatEqual(float A, float B, const int max_ulps = 4)
01711 {   
01712     int a = *(int*)&A; // load the float bits into integers
01713     int b = *(int*)&B;
01714     // floats have a sign bit, convert to 2's compliment
01715     if (a < 0) a = 0x80000000 - a; // correctly handles 0 vs -0 and
01716     if (b < 0) b = 0x80000000 - b; // positive and negative denormals
01717     return (abs(a - b) <= max_ulps);
01718 }
01719 
01720 //-----------------------------------------------------------------------------
01724 static inline bool FloatGreaterOrEqual(float A, float B, const int max_ulps = 4)
01725 {   
01726     int a = *(int*)&A; // load the float bits into integers
01727     int b = *(int*)&B;
01728     // floats have a sign bit, convert to 2's compliment
01729     if (a < 0) a = 0x80000000 - a; // correctly handles 0 vs -0 and
01730     if (b < 0) b = 0x80000000 - b; // positive and negative denormals
01731     return (a - b) >= -max_ulps;
01732 }
01733 
01734 //-----------------------------------------------------------------------------
01738 static inline bool FloatLessOrEqual(float A, float B, const int max_ulps = 4)
01739 {   
01740     return FloatGreaterOrEqual(B, A, max_ulps);
01741 }
01742 
01743 
01744 }; // end of namespace mudbox
01745 
01746 
01747 #if defined(_MSC_VER)
01748 #pragma warning(pop)
01749 #endif