home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************************
- * DXVector.h *
- *------------*
- * Description:
- * This is the header file for the vector and matrix classes.
- *-------------------------------------------------------------------------------
- * Created By: Mike Arnstein Date: 04/11/97
- * Copyright (C) 1997 Microsoft Corporation
- * All Rights Reserved
- *
- *-------------------------------------------------------------------------------
- * Revisions:
- *
- *******************************************************************************/
- #ifndef DXVector_h
- #pragma option push -b -a8 -pc -A- /*P_O_Push*/
- #define DXVector_h
-
- #ifndef _INC_MATH
- #include <math.h>
- #endif
-
- #ifndef _INC_CRTDBG
- #include <crtdbg.h>
- #endif
-
- //=== Constants ====================================================
-
-
- //=== Class, Enum, Struct and Union Declarations ===================
- class CDXMatrix4x4F;
-
- //=== Enumerated Set Definitions ===================================
-
- //=== Function Type Definitions ====================================
- float det4x4( CDXMatrix4x4F *pIn );
- float det3x3( float a1, float a2, float a3, float b1, float b2, float b3,
- float c1, float c2, float c3 );
- float det2x2( float a, float b, float c, float d );
-
- //=== Class, Struct and Union Definitions ==========================
-
- /*** CDXVec ************
- * This template implements basic vector operations for each of the
- * union types
- */
- #define CDXV_C CDXVec<TYPE, eBndType>
- #define CDXV_T ((TYPE*)u.D)
- #define CDXV_O( OtherVec ) ((TYPE*)OtherVec.u.D)
-
- template<class TYPE, DXBNDTYPE eBndType>
- class CDXVec : public DXVEC
- {
- /*=== Methods =======*/
- public:
- /*--- Constructors ---*/
- CDXVec() { eType = eBndType; ZeroVector(); }
- CDXVec(BOOL bInit) { eType = eBndType; if (bInit) ZeroVector(); }
- CDXVec( TYPE x, TYPE y, TYPE z, TYPE t )
- { eType = eBndType; CDXV_T[DXB_X] = x; CDXV_T[DXB_Y] = y;
- CDXV_T[DXB_Z] = z; CDXV_T[DXB_T] = t; }
- CDXVec( const CDXVec& Other ) { memcpy( this, (void *)&Other, sizeof(DXVEC) ); }
- CDXVec( const DXVEC Other ) { memcpy( this, &Other, sizeof(DXVEC) ); }
- operator TYPE *() { return CDXV_T; }
- operator const TYPE *() { return CDXV_T; }
-
- /*--- operations ---*/
- void ZeroVector( void ) { memset( u.D, 0, sizeof(TYPE) * 4); }
-
- /*--- operators ---*/
- TYPE& operator[]( int index ) const { return CDXV_T[index]; }
- TYPE& operator[]( long index ) const { return CDXV_T[index]; }
- TYPE& operator[]( USHORT index ) const { return CDXV_T[index]; }
- TYPE& operator[]( DWORD index ) const { return CDXV_T[index]; }
- CDXV_C operator+(const CDXV_C& v);
- CDXV_C operator-(const CDXV_C& v);
- void operator=(const CDXV_C& srcVector);
- void operator+=(const CDXV_C& vOther);
- void operator-=(const CDXV_C& vOther);
- BOOL operator==(const CDXV_C& otherVector) const;
- BOOL operator!=(const CDXV_C& otherVector) const;
- };
-
- template<class TYPE, DXBNDTYPE eBndType>
- CDXV_C CDXV_C::operator+( const CDXV_C& srcVector )
- {
- CDXV_C Result( this );
- CDXV_O( Result )[DXB_X] += CDXV_O( srcVector )[DXB_X];
- CDXV_O( Result )[DXB_Y] += CDXV_O( srcVector )[DXB_Y];
- CDXV_O( Result )[DXB_Z] += CDXV_O( srcVector )[DXB_Z];
- CDXV_O( Result )[DXB_T] += CDXV_O( srcVector )[DXB_T];
- return Result;
- } /* CDXVec::operator+ */
-
- template<class TYPE, DXBNDTYPE eBndType>
- CDXV_C CDXV_C::operator-( const CDXV_C& srcVector )
- {
- CDXV_C Result( this );
- CDXV_O( Result )[DXB_X] -= CDXV_O( srcVector )[DXB_X];
- CDXV_O( Result )[DXB_Y] -= CDXV_O( srcVector )[DXB_Y];
- CDXV_O( Result )[DXB_Z] -= CDXV_O( srcVector )[DXB_Z];
- CDXV_O( Result )[DXB_T] -= CDXV_O( srcVector )[DXB_T];
- return Result;
- } /* CDXVec::operator- */
-
- template<class TYPE, DXBNDTYPE eBndType>
- void CDXV_C::operator=( const CDXV_C& srcVector )
- {
- memcpy( this, &srcVector, sizeof(CDXVec) );
- } /* CDXVec::operator= */
-
- template<class TYPE, DXBNDTYPE eBndType>
- BOOL CDXV_C::operator==(const CDXV_C& otherVector) const
- {
- return !memcmp( this, &otherVector, sizeof(otherVector) );
- } /* CDXVec::operator== */
-
- template<class TYPE, DXBNDTYPE eBndType>
- BOOL CDXV_C::operator!=(const CDXV_C& otherVector) const
- {
- return memcmp( this, &otherVector, sizeof(otherVector) );
- } /* CDXVec::operator!= */
-
- template<class TYPE, DXBNDTYPE eBndType>
- void CDXV_C::operator+=(const CDXV_C& vOther)
- {
- CDXV_T[DXB_X] += CDXV_O( vOther )[DXB_X];
- CDXV_T[DXB_Y] += CDXV_O( vOther )[DXB_Y];
- CDXV_T[DXB_Z] += CDXV_O( vOther )[DXB_Z];
- CDXV_T[DXB_T] += CDXV_O( vOther )[DXB_T];
- } /* CDXVec::operator+= */
-
- template<class TYPE, DXBNDTYPE eBndType>
- void CDXV_C::operator-=(const CDXVec& vOther)
- {
- CDXV_T[DXB_X] -= CDXV_O( vOther )[DXB_X];
- CDXV_T[DXB_Y] -= CDXV_O( vOther )[DXB_Y];
- CDXV_T[DXB_Z] -= CDXV_O( vOther )[DXB_Z];
- CDXV_T[DXB_T] -= CDXV_O( vOther )[DXB_T];
- } /* CDXVec::operator-= */
-
- typedef CDXVec<long, DXBT_DISCRETE> CDXDVec;
- typedef CDXVec<LONGLONG, DXBT_DISCRETE64> CDXDVec64;
- typedef CDXVec<float, DXBT_CONTINUOUS> CDXCVec;
- typedef CDXVec<double, DXBT_CONTINUOUS64> CDXCVec64;
-
- /*** CDX2DXForm ************
- * This class implements basic matrix operation based on the GDI XFORM
- * structure.
- */
- //const DX2DXFORM g_DX2DXFORMIdentity = { 1., 0., 0., 1., 0., 0., DX2DXO_IDENTITY };
-
- class CDX2DXForm : public DX2DXFORM
- {
- /*=== Methods =======*/
- public:
- /*--- Constructors ---*/
- CDX2DXForm() { SetIdentity(); }
- CDX2DXForm( const CDX2DXForm& Other ) { memcpy( this, &Other, sizeof(*this) ); }
- CDX2DXForm( const DX2DXFORM& Other ) { memcpy( this, &Other, sizeof(*this) ); }
-
- /*--- methods ---*/
- void DetermineOp( void );
- void Set( const DX2DXFORM& Other ) { memcpy( this, &Other, sizeof(*this) ); DetermineOp(); }
- void ZeroMatrix( void ) { memset( this, 0, sizeof( *this ) ); }
- void SetIdentity( void ) {
- eM11 = 1.;
- eM12 = 0.;
- eM21 = 0.;
- eM22 = 1.;
- eDx = 0.;
- eDy = 0.;
- eOp = DX2DXO_IDENTITY;
- }
- BOOL IsIdentity() const { return eOp == DX2DXO_IDENTITY; }
- void Scale( float sx, float sy );
- void Rotate( float Rotation );
- void Translate( float dx, float dy );
- BOOL Invert();
- void TransformBounds( const DXBNDS& Bnds, DXBNDS& ResultBnds ) const;
- void TransformPoints( const DXFPOINT InPnts[], DXFPOINT OutPnts[], ULONG ulCount ) const;
- void GetMinMaxScales( float& MinScale, float& MaxScale );
-
- /*--- operators ---*/
- DXFPOINT operator*( const DXFPOINT& v ) const;
- CDX2DXForm operator*( const CDX2DXForm& Other ) const;
- };
-
- //=== CDX2DXForm methods ==============================================================
- inline void CDX2DXForm::DetermineOp( void )
- {
- if( ( eM12 == 0. ) && ( eM21 == 0. ) )
- {
- if( ( eM11 == 1. ) && ( eM22 == 1. ) )
- {
- eOp = ( ( eDx == 0 ) && ( eDy == 0 ) )?(DX2DXO_IDENTITY):(DX2DXO_TRANSLATE);
- }
- else
- {
- eOp = ( ( eDx == 0 ) && ( eDy == 0 ) )?(DX2DXO_SCALE):(DX2DXO_SCALE_AND_TRANS);
- }
- }
- else
- {
- eOp = ( ( eDx == 0 ) && ( eDy == 0 ) )?(DX2DXO_GENERAL):(DX2DXO_GENERAL_AND_TRANS);
- }
- } /* CDX2DXForm::DetermineOp */
-
- inline float DXSq( float f ) { return f * f; }
-
- // This function computes the Min and Max scale that a matrix represents.
- // In other words, what is the maximum/minimum length that a line of length 1
- // could get stretched/shrunk to if the line was transformed by this matrix.
- //
- // The function uses eigenvalues; and returns two float numbers. Both are
- // non-negative; and MaxScale >= MinScale.
- //
- inline void CDX2DXForm::GetMinMaxScales( float& MinScale, float& MaxScale )
- {
- if( ( eM12 == 0. ) && ( eM21 == 0. ) )
- {
- // Let MinScale = abs(eM11)
- if (eM11 < 0)
- MinScale = -eM11;
- else
- MinScale = eM11;
-
- // Let MaxScale = abs(eM22)
- if (eM22 < 0)
- MaxScale = -eM22;
- else
- MaxScale = eM22;
-
- // Swap Min/Max if necessary
- if (MinScale > MaxScale)
- {
- float flTemp = MinScale;
- MinScale = MaxScale;
- MaxScale = flTemp;
- }
- }
- else
- {
- float t1 = DXSq(eM11) + DXSq(eM12) + DXSq(eM21) + DXSq(eM22);
- if( t1 == 0. )
- {
- MinScale = MaxScale = 0;
- }
- else
- {
- float t2 = (float)sqrt( (DXSq(eM12 + eM21) + DXSq(eM11 - eM22)) *
- (DXSq(eM12 - eM21) + DXSq(eM11 + eM22)) );
-
- // Due to floating point error; t1 may end up less than t2;
- // but that would mean that the min scale was small (relative
- // to max scale)
- if (t1 <= t2)
- MinScale = 0;
- else
- MinScale = (float)sqrt( (t1 - t2) * .5f );
-
- MaxScale = (float)sqrt( (t1 + t2) * .5f );
- }
- }
- } /* CDX2DXForm::GetMinMaxScales */
-
- inline void CDX2DXForm::Rotate( float Rotation )
- {
- double Angle = Rotation * (3.1415926535/180.0);
- float CosZ = (float)cos( Angle );
- float SinZ = (float)sin( Angle );
- if (CosZ > 0.0F && CosZ < 0.0000005F)
- {
- CosZ = .0F;
- }
- if (SinZ > -0.0000005F && SinZ < .0F)
- {
- SinZ = .0F;
- }
-
- float M11 = ( CosZ * eM11 ) + ( SinZ * eM21 );
- float M21 = (-SinZ * eM11 ) + ( CosZ * eM21 );
- float M12 = ( CosZ * eM12 ) + ( SinZ * eM22 );
- float M22 = (-SinZ * eM12 ) + ( CosZ * eM22 );
- eM11 = M11; eM21 = M21; eM12 = M12; eM22 = M22;
- DetermineOp();
- } /* CDX2DXForm::Rotate */
-
- inline void CDX2DXForm::Scale( float sx, float sy )
- {
- eM11 *= sx;
- eM12 *= sx;
- eDx *= sx;
- eM21 *= sy;
- eM22 *= sy;
- eDy *= sy;
- DetermineOp();
- } /* CDX2DXForm::Scale */
-
- inline void CDX2DXForm::Translate( float dx, float dy )
- {
- eDx += dx;
- eDy += dy;
- DetermineOp();
- } /* CDX2DXForm::Translate */
-
- inline void CDX2DXForm::TransformBounds( const DXBNDS& Bnds, DXBNDS& ResultBnds ) const
- {
- ResultBnds = Bnds;
- if( eOp != DX2DXO_IDENTITY )
- {
- ResultBnds.u.D[DXB_X].Min = (long)(( eM11 * Bnds.u.D[DXB_X].Min ) + ( eM12 * Bnds.u.D[DXB_Y].Min ) + eDx);
- ResultBnds.u.D[DXB_X].Max = (long)(( eM11 * Bnds.u.D[DXB_X].Max ) + ( eM12 * Bnds.u.D[DXB_Y].Max ) + eDx);
- ResultBnds.u.D[DXB_Y].Min = (long)(( eM21 * Bnds.u.D[DXB_X].Min ) + ( eM22 * Bnds.u.D[DXB_Y].Min ) + eDy);
- ResultBnds.u.D[DXB_Y].Max = (long)(( eM21 * Bnds.u.D[DXB_X].Max ) + ( eM22 * Bnds.u.D[DXB_Y].Max ) + eDy);
- }
- } /* CDX2DXForm::TransformBounds */
-
- inline void CDX2DXForm::TransformPoints( const DXFPOINT InPnts[], DXFPOINT OutPnts[], ULONG ulCount ) const
- {
- ULONG i;
- switch( eOp )
- {
- case DX2DXO_IDENTITY:
- memcpy( OutPnts, InPnts, ulCount * sizeof( DXFPOINT ) );
- break;
- case DX2DXO_TRANSLATE:
- for( i = 0; i < ulCount; ++i )
- {
- OutPnts[i].x = InPnts[i].x + eDx;
- OutPnts[i].y = InPnts[i].y + eDy;
- }
- break;
- case DX2DXO_SCALE:
- for( i = 0; i < ulCount; ++i )
- {
- OutPnts[i].x = InPnts[i].x * eM11;
- OutPnts[i].y = InPnts[i].y * eM22;
- }
- break;
- case DX2DXO_SCALE_AND_TRANS:
- for( i = 0; i < ulCount; ++i )
- {
- OutPnts[i].x = (InPnts[i].x * eM11) + eDx;
- OutPnts[i].y = (InPnts[i].y * eM22) + eDy;
- }
- break;
- case DX2DXO_GENERAL:
- for( i = 0; i < ulCount; ++i )
- {
- OutPnts[i].x = ( InPnts[i].x * eM11 ) + ( InPnts[i].y * eM12 );
- OutPnts[i].y = ( InPnts[i].x * eM21 ) + ( InPnts[i].y * eM22 );
- }
- break;
- case DX2DXO_GENERAL_AND_TRANS:
- for( i = 0; i < ulCount; ++i )
- {
- OutPnts[i].x = ( InPnts[i].x * eM11 ) + ( InPnts[i].y * eM12 ) + eDx;
- OutPnts[i].y = ( InPnts[i].x * eM21 ) + ( InPnts[i].y * eM22 ) + eDy;
- }
- break;
- default:
- _ASSERT( 0 ); // invalid operation id
- }
- } /* CDX2DXForm::TransformPoints */
-
- inline DXFPOINT CDX2DXForm::operator*( const DXFPOINT& v ) const
- {
- DXFPOINT NewPnt;
- NewPnt.x = ( v.x * eM11 ) + ( v.y * eM12 ) + eDx;
- NewPnt.y = ( v.x * eM21 ) + ( v.y * eM22 ) + eDy;
- return NewPnt;
- } /* CDX2DXForm::operator* */
-
- inline CDX2DXForm CDX2DXForm::operator*( const CDX2DXForm& Other ) const
- {
- DX2DXFORM x;
- x.eM11 = ( eM11 * Other.eM11 ) + ( eM12 * Other.eM21 );
- x.eM12 = ( eM11 * Other.eM12 ) + ( eM12 * Other.eM22 );
- x.eDx = ( eM11 * Other.eDx ) + ( eM12 * Other.eDy ) + eDx;
-
- x.eM21 = ( eM21 * Other.eM11 ) + ( eM22 * Other.eM21 );
- x.eM22 = ( eM21 * Other.eM12 ) + ( eM22 * Other.eM22 );
- x.eDy = ( eM21 * Other.eDx ) + ( eM22 * Other.eDy ) + eDy;
- return x;
- } /* CDX2DXForm::operator*= */
-
- inline BOOL CDX2DXForm::Invert()
- {
- switch( eOp )
- {
- case DX2DXO_IDENTITY:
- break;
- case DX2DXO_TRANSLATE:
- eDx = -eDx;
- eDy = -eDy;
- break;
- case DX2DXO_SCALE:
-
- if (eM11 == 0.0 || eM22 == 0.0)
- return false;
- eM11 = 1.0f / eM11;
- eM22 = 1.0f / eM22;
- break;
-
- case DX2DXO_SCALE_AND_TRANS:
- {
- if (eM11 == 0.0f || eM22 == 0.0f)
- return false;
-
- // Our old equation was F = aG + b
- // The inverse is G = F/a - b/a where a is eM11 and b is eDx
- float flOneOverA = 1.0f / eM11;
- eDx = -eDx * flOneOverA;
- eM11 = flOneOverA;
-
- // Our old equation was F = aG + b
- // The inverse is G = F/a - b/a where a is eM22 and b is eDy
-
- flOneOverA = 1.0f / eM22;
- eDy = -eDy * flOneOverA;
- eM22 = flOneOverA;
- break;
- }
-
- case DX2DXO_GENERAL:
- case DX2DXO_GENERAL_AND_TRANS:
- {
- // The inverse of A= |a b| is | d -c|*(1/Det) where Det is the determinant of A
- // |c d| |-b a|
- // Det(A) = ad - bc
-
- // Compute determininant
- float flDet = (eM11 * eM22 - eM12 * eM21);
- if (flDet == 0.0f)
- return FALSE;
-
- float flCoef = 1.0f / flDet;
-
- // Remember old value of eM11
- float flM11Original = eM11;
-
- eM11 = flCoef * eM22;
- eM12 = -flCoef * eM12;
- eM21 = -flCoef * eM21;
- eM22 = flCoef * flM11Original;
-
- // If we have a translation; then we need to
- // compute new values for that translation
- if (eOp == DX2DXO_GENERAL_AND_TRANS)
- {
- // Remember original value of eDx
- float eDxOriginal = eDx;
-
- eDx = -eM11 * eDx - eM12 * eDy;
- eDy = -eM21 * eDxOriginal - eM22 * eDy;
- }
- }
- break;
-
- default:
- _ASSERT( 0 ); // invalid operation id
- }
-
- // We don't need to call DetermineOp here
- // because the op doesn't change when inverted
- // i.e. a scale remains a scale, etc.
-
- return true;
- } /* CDX2DXForm::Invert */
-
- /*** CDXMatrix4x4F ************
- * This class implements basic matrix operation based on a 4x4 array.
- */
- //const float g_DXMat4X4Identity[4][4] =
- //{
- // { 1.0, 0. , 0. , 0. },
- // { 0. , 1.0, 0. , 0. },
- // { 0. , 0. , 1.0, 0. },
- // { 0. , 0. , 0. , 1.0 }
- //};
-
- class CDXMatrix4x4F
- {
- public:
- /*=== Member Data ===*/
- float m_Coeff[4][4];
-
- /*=== Methods =======*/
- public:
- /*--- Constructors ---*/
- CDXMatrix4x4F() { SetIdentity(); }
- CDXMatrix4x4F( const CDXMatrix4x4F& Other )
- { CopyMemory( (void *)&m_Coeff, (void *)&Other.m_Coeff, sizeof(m_Coeff) ); }
- CDXMatrix4x4F( DX2DXFORM& XForm );
-
- /*--- operations ---*/
- void ZeroMatrix( void ) { memset( m_Coeff, 0, sizeof( m_Coeff ) ); }
- void SetIdentity( void ) {
- memset( m_Coeff, 0, sizeof( m_Coeff ) );
- m_Coeff[0][0] = m_Coeff[1][1] = m_Coeff[2][2] = m_Coeff[3][3] = 1.0;
- }
- void SetCoefficients( float Coeff[4][4] ) { memcpy( m_Coeff, Coeff, sizeof( m_Coeff )); }
- void GetCoefficients( float Coeff[4][4] ) { memcpy( Coeff, m_Coeff, sizeof( m_Coeff )); }
-
- //BOOL IsIdentity();
- void Scale( float sx, float sy, float sz );
- void Rotate( float rx, float ry, float rz );
- void Translate( float dx, float dy, float dz );
- BOOL Invert();
- BOOL GetInverse( CDXMatrix4x4F *pIn );
- void Transpose();
- void GetTranspose( CDXMatrix4x4F *pIn );
- void GetAdjoint( CDXMatrix4x4F *pIn );
- HRESULT InitFromSafeArray( SAFEARRAY *psa );
- HRESULT GetSafeArray( SAFEARRAY **ppsa ) const;
- void TransformBounds( DXBNDS& Bnds, DXBNDS& ResultBnds );
-
- /*--- operators ---*/
- CDXDVec operator*( CDXDVec& v) const;
- CDXCVec operator*( CDXCVec& v) const;
- CDXMatrix4x4F operator*(CDXMatrix4x4F Matrix) const;
- void operator*=(CDXMatrix4x4F Matrix) const;
- void CDXMatrix4x4F::operator=(const CDXMatrix4x4F srcMatrix);
- void CDXMatrix4x4F::operator+=(const CDXMatrix4x4F otherMatrix);
- void CDXMatrix4x4F::operator-=(const CDXMatrix4x4F otherMatrix);
- BOOL CDXMatrix4x4F::operator==(const CDXMatrix4x4F otherMatrix) const;
- BOOL CDXMatrix4x4F::operator!=(const CDXMatrix4x4F otherMatrix) const;
- };
-
- inline CDXMatrix4x4F::CDXMatrix4x4F( DX2DXFORM& XForm )
- {
- SetIdentity();
- m_Coeff[0][0] = XForm.eM11;
- m_Coeff[0][1] = XForm.eM12;
- m_Coeff[1][0] = XForm.eM21;
- m_Coeff[1][1] = XForm.eM22;
- m_Coeff[0][3] = XForm.eDx;
- m_Coeff[1][3] = XForm.eDy;
- }
-
- // Additional Operations
-
- inline void CDXMatrix4x4F::operator=(const CDXMatrix4x4F srcMatrix)
- {
- CopyMemory( (void *)m_Coeff, (const void *)srcMatrix.m_Coeff, sizeof(srcMatrix.m_Coeff) );
- } /* CDXMatrix4x4F::operator= */
-
- inline BOOL CDXMatrix4x4F::operator==(const CDXMatrix4x4F otherMatrix) const
- {
- return !memcmp( (void *)m_Coeff, (const void *)otherMatrix.m_Coeff, sizeof(otherMatrix.m_Coeff) );
- } /* CDXMatrix4x4F::operator== */
-
- inline BOOL CDXMatrix4x4F::operator!=(const CDXMatrix4x4F otherMatrix) const
- {
- return memcmp( (void *)m_Coeff, (const void *)otherMatrix.m_Coeff, sizeof(otherMatrix.m_Coeff) );
- } /* CDXMatrix4x4F::operator!= */
-
- inline void CDXMatrix4x4F::operator+=(const CDXMatrix4x4F otherMatrix)
- {
- for( int i = 0; i < 4; i++ )
- for( int j = 0; j < 4; j++ )
- m_Coeff[i][j] += otherMatrix.m_Coeff[i][j];
- } /* CDXMatrix4x4F::operator+= */
-
- inline void CDXMatrix4x4F::operator-=(const CDXMatrix4x4F otherMatrix)
- {
- for( int i = 0; i < 4; i++ )
- for( int j = 0; j < 4; j++ )
- m_Coeff[i][j] -= otherMatrix.m_Coeff[i][j];
- } /* CDXMatrix4x4F::operator-= */
-
- inline CDXDVec CDXMatrix4x4F::operator*(CDXDVec& v) const
- {
- CDXDVec t;
- float temp;
- temp = v[0]*m_Coeff[0][0]+v[1]*m_Coeff[1][0]+v[2]*m_Coeff[2][0]+v[3]*m_Coeff[3][0];
- t[0] = (long)((temp < 0) ? temp -= .5 : temp += .5);
- temp = v[0]*m_Coeff[0][1]+v[1]*m_Coeff[1][1]+v[2]*m_Coeff[2][1]+v[3]*m_Coeff[3][1];
- t[1] = (long)((temp < 0) ? temp -= .5 : temp += .5);
- temp = v[0]*m_Coeff[0][2]+v[1]*m_Coeff[1][2]+v[2]*m_Coeff[2][2]+v[3]*m_Coeff[3][2];
- t[2] = (long)((temp < 0) ? temp -= .5 : temp += .5);
- temp = v[0]*m_Coeff[0][3]+v[1]*m_Coeff[1][3]+v[2]*m_Coeff[2][3]+v[3]*m_Coeff[3][3];
- t[3] = (long)((temp < 0) ? temp -= .5 : temp += .5);
- return t;
- } /* CDXMatrix4x4F::operator*(DXDVEC) */
-
- inline CDXCVec CDXMatrix4x4F::operator*(CDXCVec& v) const
- {
- CDXCVec t;
- t[0] = v[0]*m_Coeff[0][0]+v[1]*m_Coeff[1][0]+v[2]*m_Coeff[2][0]+v[3]*m_Coeff[3][0];
- t[1] = v[0]*m_Coeff[0][1]+v[1]*m_Coeff[1][1]+v[2]*m_Coeff[2][1]+v[3]*m_Coeff[3][1];
- t[2] = v[0]*m_Coeff[0][2]+v[1]*m_Coeff[1][2]+v[2]*m_Coeff[2][2]+v[3]*m_Coeff[3][2];
- t[3] = v[0]*m_Coeff[0][3]+v[1]*m_Coeff[1][3]+v[2]*m_Coeff[2][3]+v[3]*m_Coeff[3][3];
- return t;
- } /* CDXMatrix4x4F::operator*(DXCVEC) */
-
- inline CDXMatrix4x4F CDXMatrix4x4F::operator*(CDXMatrix4x4F Mx) const
- {
- CDXMatrix4x4F t;
- int i, j;
-
- for( i = 0; i < 4; i++ )
- {
- for( j = 0; j < 4; j++ )
- {
- t.m_Coeff[i][j] = m_Coeff[i][0] * Mx.m_Coeff[0][j] +
- m_Coeff[i][1] * Mx.m_Coeff[1][j] +
- m_Coeff[i][2] * Mx.m_Coeff[2][j] +
- m_Coeff[i][3] * Mx.m_Coeff[3][j];
- }
- }
-
- return t;
- } /* CDXMatrix4x4F::operator*(CDXMatrix4x4F) */
-
- inline void CDXMatrix4x4F::operator*=(CDXMatrix4x4F Mx) const
- {
- CDXMatrix4x4F t;
- int i, j;
-
- for( i = 0; i < 4; i++ )
- {
- for( j = 0; j < 4; j++ )
- {
- t.m_Coeff[i][j] = m_Coeff[i][0] * Mx.m_Coeff[0][j] +
- m_Coeff[i][1] * Mx.m_Coeff[1][j] +
- m_Coeff[i][2] * Mx.m_Coeff[2][j] +
- m_Coeff[i][3] * Mx.m_Coeff[3][j];
- }
- }
-
- CopyMemory( (void *)m_Coeff, (void *)t.m_Coeff, sizeof(m_Coeff) );
- } /* CDXMatrix4x4F::operator*=(CDXMatrix4x4F) */
-
-
- inline void CDXMatrix4x4F::Scale( float sx, float sy, float sz )
- {
- if( sx != 1. )
- {
- m_Coeff[0][0] *= sx;
- m_Coeff[0][1] *= sx;
- m_Coeff[0][2] *= sx;
- m_Coeff[0][3] *= sx;
- }
- if( sy != 1. )
- {
- m_Coeff[1][0] *= sy;
- m_Coeff[1][1] *= sy;
- m_Coeff[1][2] *= sy;
- m_Coeff[1][3] *= sy;
- }
- if( sz != 1. )
- {
- m_Coeff[2][0] *= sz;
- m_Coeff[2][1] *= sz;
- m_Coeff[2][2] *= sz;
- m_Coeff[2][3] *= sz;
- }
- } /* CDXMatrix4x4F::Scale */
-
- inline void CDXMatrix4x4F::Translate( float dx, float dy, float dz )
- {
- float a, b, c, d;
- a = b = c = d = 0;
- if( dx != 0. )
- {
- a += m_Coeff[0][0]*dx;
- b += m_Coeff[0][1]*dx;
- c += m_Coeff[0][2]*dx;
- d += m_Coeff[0][3]*dx;
- }
- if( dy != 0. )
- {
- a += m_Coeff[1][0]*dy;
- b += m_Coeff[1][1]*dy;
- c += m_Coeff[1][2]*dy;
- d += m_Coeff[1][3]*dy;
- }
- if( dz != 0. )
- {
- a += m_Coeff[2][0]*dz;
- b += m_Coeff[2][1]*dz;
- c += m_Coeff[2][2]*dz;
- d += m_Coeff[2][3]*dz;
- }
- m_Coeff[3][0] += a;
- m_Coeff[3][1] += b;
- m_Coeff[3][2] += c;
- m_Coeff[3][3] += d;
- } /* CDXMatrix4x4F::Translate */
-
- inline void CDXMatrix4x4F::Rotate( float rx, float ry, float rz )
- {
- const float l_dfCte = (const float)(3.1415926535/180.0);
-
- float lAngleY = 0.0;
- float lAngleX = 0.0;
- float lAngleZ = 0.0;
- float lCosX = 1.0;
- float lSinX = 0.0;
- float lCosY = 1.0;
- float lSinY = 0.0;
- float lCosZ = 1.0;
- float lSinZ = 0.0;
-
- // calculate rotation angle sines and cosines
- if( rx != 0 )
- {
- lAngleX = rx * l_dfCte;
- lCosX = (float)cos(lAngleX);
- lSinX = (float)sin(lAngleX);
- if (lCosX > 0.0F && lCosX < 0.0000005F)
- {
- lCosX = .0F;
- }
- if (lSinX > -0.0000005F && lSinX < .0F)
- {
- lSinX = .0F;
- }
- }
- if( ry != 0 )
- {
- lAngleY = ry * l_dfCte;
- lCosY = (float)cos(lAngleY);
- lSinY = (float)sin(lAngleY);
- if (lCosY > 0.0F && lCosY < 0.0000005F)
- {
- lCosY = .0F;
- }
- if (lSinY > -0.0000005F && lSinY < .0F)
- {
- lSinY = .0F;
- }
- }
- if( rz != 0 )
- {
- lAngleZ = rz * l_dfCte;
- lCosZ = (float)cos(lAngleZ);
- lSinZ = (float)sin(lAngleZ);
- if (lCosZ > 0.0F && lCosZ < 0.0000005F)
- {
- lCosZ = .0F;
- }
- if (lSinZ > -0.0000005F && lSinZ < .0F)
- {
- lSinZ = .0F;
- }
- }
-
- float u, v;
- int i;
-
- //--- X Rotation
- for( i = 0; i < 4; i++ )
- {
- u = m_Coeff[1][i];
- v = m_Coeff[2][i];
- m_Coeff[1][i] = lCosX*u+lSinX*v;
- m_Coeff[2][i] = -lSinX*u+lCosX*v;
- }
-
- //--- Y Rotation
- for( i = 0; i < 4; i++ )
- {
- u = m_Coeff[0][i];
- v = m_Coeff[2][i];
- m_Coeff[0][i] = lCosY*u-lSinY*v;
- m_Coeff[2][i] = lSinY*u+lCosY*v;
- }
-
- //--- Z Rotation
- for( i = 0; i < 4; i++ )
- {
- u = m_Coeff[0][i];
- v = m_Coeff[1][i];
- m_Coeff[0][i] = lCosZ*u+lSinZ*v;
- m_Coeff[1][i] = -lSinZ*u+lCosZ*v;
- }
- }
-
- /*
- inline BOOL CDXMatrix4x4F::IsIdentity()
- {
- return !memcmp( m_Coeff, g_DXMat4X4Identity, sizeof(g_DXMat4X4Identity) );
- } /* CDXMatrix4x4F::IsIdentity */
-
-
- /*
- Uses Gaussian elimination to invert the 4 x 4 non-linear matrix in t and
- return the result in Mx. The matrix t is destroyed in the process.
- */
- inline BOOL CDXMatrix4x4F::Invert()
- {
- int i,j,k,Pivot;
- float PValue;
- CDXMatrix4x4F Mx;
- Mx.SetIdentity();
-
- /* Find pivot element. Use partial pivoting by row */
- for( i = 0;i < 4; i++ )
- {
- Pivot = 0;
- for( j = 0; j < 4; j++ )
- {
- if( fabs(m_Coeff[i][j]) > fabs(m_Coeff[i][Pivot]) ) Pivot = j;
- }
-
- if( m_Coeff[i][Pivot] == 0.0 )
- {
- ZeroMatrix(); /* Singular Matrix */
- return FALSE;
- }
-
- /* Normalize */
- PValue = m_Coeff[i][Pivot];
- for( j = 0; j < 4; j++ )
- {
- m_Coeff[i][j] /= PValue;
- Mx.m_Coeff[i][j] /= PValue;
- }
-
- /* Zeroing */
- for( j = 0; j < 4; j++ )
- {
- if( j != i )
- {
- PValue = m_Coeff[j][Pivot];
- for( k = 0; k < 4; k++ )
- {
- m_Coeff[j][k] -= PValue*m_Coeff[i][k];
- Mx.m_Coeff[j][k] -= PValue*Mx.m_Coeff[i][k];
- }
- }
- }
- }
-
- /* Reorder rows */
- for( i = 0; i < 4; i++ )
- {
- if( m_Coeff[i][i] != 1.0 )
- {
- for( j = i + 1; j < 4; j++ )
- if( m_Coeff[j][i] == 1.0 ) break;
- if( j >= 4 )
- {
- ZeroMatrix();
- return FALSE;
- }
-
- //--- swap rows i and j of original
- for( k = 0; k < 4; k++ )
- {
- m_Coeff[i][k] += m_Coeff[j][k];
- m_Coeff[j][k] = m_Coeff[i][k] - m_Coeff[j][k];
- m_Coeff[i][k] -= m_Coeff[j][k];
- }
-
- //--- swap rows i and j of result
- for( k = 0; k < 4; k++ )
- {
- Mx.m_Coeff[i][k] += Mx.m_Coeff[j][k];
- Mx.m_Coeff[j][k] = Mx.m_Coeff[i][k] - Mx.m_Coeff[j][k];
- Mx.m_Coeff[i][k] -= Mx.m_Coeff[j][k];
- }
- }
- }
- *this = Mx;
- return TRUE;
- } /* CDXMatrix4x4F::Invert */
-
- inline void CDXMatrix4x4F::Transpose()
- {
- float temp;
-
- temp = m_Coeff[0][1];
- m_Coeff[0][1] = m_Coeff[1][0];
- m_Coeff[1][0] = temp;
-
- temp = m_Coeff[0][2];
- m_Coeff[0][2] = m_Coeff[2][0];
- m_Coeff[2][0] = temp;
-
- temp = m_Coeff[0][3];
- m_Coeff[0][3] = m_Coeff[3][0];
- m_Coeff[3][0] = temp;
-
- temp = m_Coeff[1][2];
- m_Coeff[1][2] = m_Coeff[2][1];
- m_Coeff[2][1] = temp;
-
- temp = m_Coeff[1][3];
- m_Coeff[1][3] = m_Coeff[3][1];
- m_Coeff[3][1] = temp;
-
- temp = m_Coeff[2][3];
- m_Coeff[2][3] = m_Coeff[3][2];
- m_Coeff[3][2] = temp;
-
- } /* CDXMatrix4x4F::Transpose */
-
- inline void CDXMatrix4x4F::GetTranspose( CDXMatrix4x4F *m )
- {
- float temp;
-
- (*this) = *m;
-
- temp = m_Coeff[0][1];
- m_Coeff[0][1] = m_Coeff[1][0];
- m_Coeff[1][0] = temp;
-
- temp = m_Coeff[0][2];
- m_Coeff[0][2] = m_Coeff[2][0];
- m_Coeff[2][0] = temp;
-
- temp = m_Coeff[0][3];
- m_Coeff[0][3] = m_Coeff[3][0];
- m_Coeff[3][0] = temp;
-
- temp = m_Coeff[1][2];
- m_Coeff[1][2] = m_Coeff[2][1];
- m_Coeff[2][1] = temp;
-
- temp = m_Coeff[1][3];
- m_Coeff[1][3] = m_Coeff[3][1];
- m_Coeff[3][1] = temp;
-
- temp = m_Coeff[2][3];
- m_Coeff[2][3] = m_Coeff[3][2];
- m_Coeff[3][2] = temp;
-
- } /* CDXMatrix4x4F::Transpose */
-
-
- /*
- Matrix Inversion
- by Richard Carling
- from "Graphics Gems", Academic Press, 1990
- */
-
- #define SMALL_NUMBER 1.e-8
- /*
- * inverse( original_matrix, inverse_matrix )
- *
- * calculate the inverse of a 4x4 matrix
- *
- * -1
- * A = ___1__ adjoint A
- * det A
- */
-
- inline BOOL CDXMatrix4x4F::GetInverse( CDXMatrix4x4F *pIn )
- {
- int i, j;
- float det;
-
- /* calculate the adjoint matrix */
-
- GetAdjoint( pIn );
-
- /* calculate the 4x4 determinant
- * if the determinant is zero,
- * then the inverse matrix is not unique.
- */
-
- det = det4x4( pIn );
-
- if( fabs( det ) < SMALL_NUMBER )
- {
- // Non-singular matrix, no inverse!
- return FALSE;;
- }
-
- /* scale the adjoint matrix to get the inverse */
-
- for( i = 0; i < 4; i++ )
- for( j = 0; j < 4; j++ )
- m_Coeff[i][j] = m_Coeff[i][j] / det;
-
- return TRUE;
- }
-
-
- /*
- * adjoint( original_matrix, inverse_matrix )
- *
- * calculate the adjoint of a 4x4 matrix
- *
- * Let a denote the minor determinant of matrix A obtained by
- * ij
- *
- * deleting the ith row and jth column from A.
- *
- * i+j
- * Let b = (-1) a
- * ij ji
- *
- * The matrix B = (b ) is the adjoint of A
- * ij
- */
- inline void CDXMatrix4x4F::GetAdjoint( CDXMatrix4x4F *pIn )
- {
- float a1, a2, a3, a4, b1, b2, b3, b4;
- float c1, c2, c3, c4, d1, d2, d3, d4;
-
- /* assign to individual variable names to aid */
- /* selecting correct values */
-
- a1 = pIn->m_Coeff[0][0]; b1 = pIn->m_Coeff[0][1];
- c1 = pIn->m_Coeff[0][2]; d1 = pIn->m_Coeff[0][3];
-
- a2 = pIn->m_Coeff[1][0]; b2 = pIn->m_Coeff[1][1];
- c2 = pIn->m_Coeff[1][2]; d2 = pIn->m_Coeff[1][3];
-
- a3 = pIn->m_Coeff[2][0]; b3 = pIn->m_Coeff[2][1];
- c3 = pIn->m_Coeff[2][2]; d3 = pIn->m_Coeff[2][3];
-
- a4 = pIn->m_Coeff[3][0]; b4 = pIn->m_Coeff[3][1];
- c4 = pIn->m_Coeff[3][2]; d4 = pIn->m_Coeff[3][3];
-
-
- /* row column labeling reversed since we transpose rows & columns */
-
- m_Coeff[0][0] = det3x3( b2, b3, b4, c2, c3, c4, d2, d3, d4);
- m_Coeff[1][0] = - det3x3( a2, a3, a4, c2, c3, c4, d2, d3, d4);
- m_Coeff[2][0] = det3x3( a2, a3, a4, b2, b3, b4, d2, d3, d4);
- m_Coeff[3][0] = - det3x3( a2, a3, a4, b2, b3, b4, c2, c3, c4);
-
- m_Coeff[0][1] = - det3x3( b1, b3, b4, c1, c3, c4, d1, d3, d4);
- m_Coeff[1][1] = det3x3( a1, a3, a4, c1, c3, c4, d1, d3, d4);
- m_Coeff[2][1] = - det3x3( a1, a3, a4, b1, b3, b4, d1, d3, d4);
- m_Coeff[3][1] = det3x3( a1, a3, a4, b1, b3, b4, c1, c3, c4);
-
- m_Coeff[0][2] = det3x3( b1, b2, b4, c1, c2, c4, d1, d2, d4);
- m_Coeff[1][2] = - det3x3( a1, a2, a4, c1, c2, c4, d1, d2, d4);
- m_Coeff[2][2] = det3x3( a1, a2, a4, b1, b2, b4, d1, d2, d4);
- m_Coeff[3][2] = - det3x3( a1, a2, a4, b1, b2, b4, c1, c2, c4);
-
- m_Coeff[0][3] = - det3x3( b1, b2, b3, c1, c2, c3, d1, d2, d3);
- m_Coeff[1][3] = det3x3( a1, a2, a3, c1, c2, c3, d1, d2, d3);
- m_Coeff[2][3] = - det3x3( a1, a2, a3, b1, b2, b3, d1, d2, d3);
- m_Coeff[3][3] = det3x3( a1, a2, a3, b1, b2, b3, c1, c2, c3);
- }
- /*
- * float = det4x4( matrix )
- *
- * calculate the determinant of a 4x4 matrix.
- */
- inline float det4x4( CDXMatrix4x4F *pIn )
- {
- float ans;
- float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
-
- /* assign to individual variable names to aid selecting */
- /* correct elements */
-
- a1 = pIn->m_Coeff[0][0]; b1 = pIn->m_Coeff[0][1];
- c1 = pIn->m_Coeff[0][2]; d1 = pIn->m_Coeff[0][3];
-
- a2 = pIn->m_Coeff[1][0]; b2 = pIn->m_Coeff[1][1];
- c2 = pIn->m_Coeff[1][2]; d2 = pIn->m_Coeff[1][3];
-
- a3 = pIn->m_Coeff[2][0]; b3 = pIn->m_Coeff[2][1];
- c3 = pIn->m_Coeff[2][2]; d3 = pIn->m_Coeff[2][3];
-
- a4 = pIn->m_Coeff[3][0]; b4 = pIn->m_Coeff[3][1];
- c4 = pIn->m_Coeff[3][2]; d4 = pIn->m_Coeff[3][3];
-
- ans = a1 * det3x3( b2, b3, b4, c2, c3, c4, d2, d3, d4 )
- - b1 * det3x3( a2, a3, a4, c2, c3, c4, d2, d3, d4 )
- + c1 * det3x3( a2, a3, a4, b2, b3, b4, d2, d3, d4 )
- - d1 * det3x3( a2, a3, a4, b2, b3, b4, c2, c3, c4 );
- return ans;
- }
-
- /*
- * float = det3x3( a1, a2, a3, b1, b2, b3, c1, c2, c3 )
- *
- * calculate the determinant of a 3x3 matrix
- * in the form
- *
- * | a1, b1, c1 |
- * | a2, b2, c2 |
- * | a3, b3, c3 |
- */
-
- inline float det3x3( float a1, float a2, float a3,
- float b1, float b2, float b3,
- float c1, float c2, float c3 )
- {
- float ans;
-
- ans = a1 * det2x2( b2, b3, c2, c3 )
- - b1 * det2x2( a2, a3, c2, c3 )
- + c1 * det2x2( a2, a3, b2, b3 );
- return ans;
- }
-
- /*
- * float = det2x2( float a, float b, float c, float d )
- *
- * calculate the determinant of a 2x2 matrix.
- */
- inline float det2x2( float a, float b, float c, float d )
- {
- float ans = a * d - b * c;
- return ans;
- }
-
- inline HRESULT CDXMatrix4x4F::InitFromSafeArray( SAFEARRAY * /*pSA*/ )
- {
- HRESULT hr = S_OK;
- #if 0
- long *pData;
-
- if( !pSA || ( pSA->cDims != 1 ) ||
- ( pSA->cbElements != sizeof(float) ) ||
- ( pSA->rgsabound->lLbound != 1 ) ||
- ( pSA->rgsabound->cElements != 8 )
- )
- {
- hr = E_INVALIDARG;
- }
- else
- {
- hr = SafeArrayAccessData(pSA, (void **)&pData);
-
- if( SUCCEEDED( hr ) )
- {
- for( int i = 0; i < 4; ++i )
- {
- m_Bounds[i].Min = pData[i];
- m_Bounds[i].Max = pData[i+4];
- m_Bounds[i].SampleRate = SampleRate;
- }
-
- hr = SafeArrayUnaccessData( pSA );
- }
- }
- #endif
- return hr;
- } /* CDXMatrix4x4F::InitFromSafeArray */
-
- inline HRESULT CDXMatrix4x4F::GetSafeArray( SAFEARRAY ** /*ppSA*/ ) const
- {
- HRESULT hr = S_OK;
- #if 0
- SAFEARRAY *pSA;
-
- if( !ppSA )
- {
- hr = E_POINTER;
- }
- else
- {
- SAFEARRAYBOUND rgsabound;
- rgsabound.lLbound = 1;
- rgsabound.cElements = 16;
-
- if( !(pSA = SafeArrayCreate( VT_I4, 1, &rgsabound ) ) )
- {
- hr = E_OUTOFMEMORY;
- }
- else
- {
- long *pData;
- hr = SafeArrayAccessData( pSA, (void **)&pData );
-
- if( SUCCEEDED( hr ) )
- {
- for( int i = 0; i < 4; ++i )
- {
- pData[i] = m_Bounds[i].Min;
- pData[i+4] = m_Bounds[i].Max;
- }
-
- hr = SafeArrayUnaccessData( pSA );
- }
- }
-
- if( SUCCEEDED( hr ) )
- {
- *ppSA = pSA;
- }
- }
- #endif
- return hr;
- } /* CDXMatrix4x4F::GetSafeArray */
-
- inline void CDXMatrix4x4F::TransformBounds( DXBNDS& /*Bnds*/, DXBNDS& /*ResultBnds*/ )
- {
-
- } /* CDXMatrix4x4F::TransformBounds */
-
- #pragma option pop /*P_O_Pop*/
- #endif // DXVector_h
-
-