Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1195 lines
35 KiB

  1. /*******************************************************************************
  2. * DXVector.h *
  3. *------------*
  4. * Description:
  5. * This is the header file for the vector and matrix classes.
  6. *-------------------------------------------------------------------------------
  7. * Created By: Mike Arnstein Date: 04/11/97
  8. * Copyright (C) 1997 Microsoft Corporation
  9. * All Rights Reserved
  10. *
  11. *-------------------------------------------------------------------------------
  12. * Revisions:
  13. *
  14. *******************************************************************************/
  15. #ifndef DXVector_h
  16. #define DXVector_h
  17. #ifndef _INC_MATH
  18. #include <math.h>
  19. #endif
  20. #ifndef _INC_CRTDBG
  21. #include <crtdbg.h>
  22. #endif
  23. //=== Constants ====================================================
  24. //=== Class, Enum, Struct and Union Declarations ===================
  25. class CDXMatrix4x4F;
  26. //=== Enumerated Set Definitions ===================================
  27. //=== Function Type Definitions ====================================
  28. float det4x4( CDXMatrix4x4F *pIn );
  29. float det3x3( float a1, float a2, float a3, float b1, float b2, float b3,
  30. float c1, float c2, float c3 );
  31. float det2x2( float a, float b, float c, float d );
  32. //=== Class, Struct and Union Definitions ==========================
  33. /*** CDXVec ************
  34. * This template implements basic vector operations for each of the
  35. * union types
  36. */
  37. #define CDXV_C CDXVec<TYPE, eBndType>
  38. #define CDXV_T ((TYPE*)u.D)
  39. #define CDXV_O( OtherVec ) ((TYPE*)OtherVec.u.D)
  40. template<class TYPE, DXBNDTYPE eBndType>
  41. class CDXVec : public DXVEC
  42. {
  43. /*=== Methods =======*/
  44. public:
  45. /*--- Constructors ---*/
  46. CDXVec() { eType = eBndType; ZeroVector(); }
  47. CDXVec(BOOL bInit) { eType = eBndType; if (bInit) ZeroVector(); }
  48. CDXVec( TYPE x, TYPE y, TYPE z, TYPE t )
  49. { eType = eBndType; CDXV_T[DXB_X] = x; CDXV_T[DXB_Y] = y;
  50. CDXV_T[DXB_Z] = z; CDXV_T[DXB_T] = t; }
  51. CDXVec( const CDXVec& Other ) { memcpy( this, (void *)&Other, sizeof(DXVEC) ); }
  52. CDXVec( const DXVEC Other ) { memcpy( this, &Other, sizeof(DXVEC) ); }
  53. operator TYPE *() { return CDXV_T; }
  54. operator const TYPE *() { return CDXV_T; }
  55. /*--- operations ---*/
  56. void ZeroVector( void ) { memset( u.D, 0, sizeof(TYPE) * 4); }
  57. /*--- operators ---*/
  58. TYPE& operator[]( int index ) const { return CDXV_T[index]; }
  59. TYPE& operator[]( long index ) const { return CDXV_T[index]; }
  60. TYPE& operator[]( USHORT index ) const { return CDXV_T[index]; }
  61. TYPE& operator[]( DWORD index ) const { return CDXV_T[index]; }
  62. CDXV_C operator+(const CDXV_C& v);
  63. CDXV_C operator-(const CDXV_C& v);
  64. void operator=(const CDXV_C& srcVector);
  65. void operator+=(const CDXV_C& vOther);
  66. void operator-=(const CDXV_C& vOther);
  67. BOOL operator==(const CDXV_C& otherVector) const;
  68. BOOL operator!=(const CDXV_C& otherVector) const;
  69. };
  70. template<class TYPE, DXBNDTYPE eBndType>
  71. CDXV_C CDXV_C::operator+( const CDXV_C& srcVector )
  72. {
  73. CDXV_C Result( this );
  74. CDXV_O( Result )[DXB_X] += CDXV_O( srcVector )[DXB_X];
  75. CDXV_O( Result )[DXB_Y] += CDXV_O( srcVector )[DXB_Y];
  76. CDXV_O( Result )[DXB_Z] += CDXV_O( srcVector )[DXB_Z];
  77. CDXV_O( Result )[DXB_T] += CDXV_O( srcVector )[DXB_T];
  78. return Result;
  79. } /* CDXVec::operator+ */
  80. template<class TYPE, DXBNDTYPE eBndType>
  81. CDXV_C CDXV_C::operator-( const CDXV_C& srcVector )
  82. {
  83. CDXV_C Result( this );
  84. CDXV_O( Result )[DXB_X] -= CDXV_O( srcVector )[DXB_X];
  85. CDXV_O( Result )[DXB_Y] -= CDXV_O( srcVector )[DXB_Y];
  86. CDXV_O( Result )[DXB_Z] -= CDXV_O( srcVector )[DXB_Z];
  87. CDXV_O( Result )[DXB_T] -= CDXV_O( srcVector )[DXB_T];
  88. return Result;
  89. } /* CDXVec::operator- */
  90. template<class TYPE, DXBNDTYPE eBndType>
  91. void CDXV_C::operator=( const CDXV_C& srcVector )
  92. {
  93. memcpy( this, &srcVector, sizeof(CDXVec) );
  94. } /* CDXVec::operator= */
  95. template<class TYPE, DXBNDTYPE eBndType>
  96. BOOL CDXV_C::operator==(const CDXV_C& otherVector) const
  97. {
  98. return !memcmp( this, &otherVector, sizeof(otherVector) );
  99. } /* CDXVec::operator== */
  100. template<class TYPE, DXBNDTYPE eBndType>
  101. BOOL CDXV_C::operator!=(const CDXV_C& otherVector) const
  102. {
  103. return memcmp( this, &otherVector, sizeof(otherVector) );
  104. } /* CDXVec::operator!= */
  105. template<class TYPE, DXBNDTYPE eBndType>
  106. void CDXV_C::operator+=(const CDXV_C& vOther)
  107. {
  108. CDXV_T[DXB_X] += CDXV_O( vOther )[DXB_X];
  109. CDXV_T[DXB_Y] += CDXV_O( vOther )[DXB_Y];
  110. CDXV_T[DXB_Z] += CDXV_O( vOther )[DXB_Z];
  111. CDXV_T[DXB_T] += CDXV_O( vOther )[DXB_T];
  112. } /* CDXVec::operator+= */
  113. template<class TYPE, DXBNDTYPE eBndType>
  114. void CDXV_C::operator-=(const CDXVec& vOther)
  115. {
  116. CDXV_T[DXB_X] -= CDXV_O( vOther )[DXB_X];
  117. CDXV_T[DXB_Y] -= CDXV_O( vOther )[DXB_Y];
  118. CDXV_T[DXB_Z] -= CDXV_O( vOther )[DXB_Z];
  119. CDXV_T[DXB_T] -= CDXV_O( vOther )[DXB_T];
  120. } /* CDXVec::operator-= */
  121. typedef CDXVec<long, DXBT_DISCRETE> CDXDVec;
  122. typedef CDXVec<LONGLONG, DXBT_DISCRETE64> CDXDVec64;
  123. typedef CDXVec<float, DXBT_CONTINUOUS> CDXCVec;
  124. typedef CDXVec<double, DXBT_CONTINUOUS64> CDXCVec64;
  125. /*** CDX2DXForm ************
  126. * This class implements basic matrix operation based on the GDI XFORM
  127. * structure.
  128. */
  129. //const DX2DXFORM g_DX2DXFORMIdentity = { 1., 0., 0., 1., 0., 0., DX2DXO_IDENTITY };
  130. class CDX2DXForm : public DX2DXFORM
  131. {
  132. /*=== Methods =======*/
  133. public:
  134. /*--- Constructors ---*/
  135. CDX2DXForm() { SetIdentity(); }
  136. CDX2DXForm( const CDX2DXForm& Other ) { memcpy( this, &Other, sizeof(*this) ); }
  137. CDX2DXForm( const DX2DXFORM& Other ) { memcpy( this, &Other, sizeof(*this) ); }
  138. /*--- methods ---*/
  139. void DetermineOp( void );
  140. void Set( const DX2DXFORM& Other ) { memcpy( this, &Other, sizeof(*this) ); DetermineOp(); }
  141. void ZeroMatrix( void ) { memset( this, 0, sizeof( *this ) ); }
  142. void SetIdentity( void ) {
  143. eM11 = 1.;
  144. eM12 = 0.;
  145. eM21 = 0.;
  146. eM22 = 1.;
  147. eDx = 0.;
  148. eDy = 0.;
  149. eOp = DX2DXO_IDENTITY;
  150. }
  151. BOOL IsIdentity() const { return eOp == DX2DXO_IDENTITY; }
  152. void Scale( float sx, float sy );
  153. void Rotate( float Rotation );
  154. void Translate( float dx, float dy );
  155. BOOL Invert();
  156. void TransformBounds( const DXBNDS& Bnds, DXBNDS& ResultBnds ) const;
  157. void TransformPoints( const DXFPOINT InPnts[], DXFPOINT OutPnts[], ULONG ulCount ) const;
  158. void GetMinMaxScales( float& MinScale, float& MaxScale );
  159. /*--- operators ---*/
  160. DXFPOINT operator*( const DXFPOINT& v ) const;
  161. CDX2DXForm operator*( const CDX2DXForm& Other ) const;
  162. };
  163. //=== CDX2DXForm methods ==============================================================
  164. inline void CDX2DXForm::DetermineOp( void )
  165. {
  166. if( ( eM12 == 0. ) && ( eM21 == 0. ) )
  167. {
  168. if( ( eM11 == 1. ) && ( eM22 == 1. ) )
  169. {
  170. eOp = ( ( eDx == 0 ) && ( eDy == 0 ) )?(DX2DXO_IDENTITY):(DX2DXO_TRANSLATE);
  171. }
  172. else
  173. {
  174. eOp = ( ( eDx == 0 ) && ( eDy == 0 ) )?(DX2DXO_SCALE):(DX2DXO_SCALE_AND_TRANS);
  175. }
  176. }
  177. else
  178. {
  179. eOp = ( ( eDx == 0 ) && ( eDy == 0 ) )?(DX2DXO_GENERAL):(DX2DXO_GENERAL_AND_TRANS);
  180. }
  181. } /* CDX2DXForm::DetermineOp */
  182. inline float DXSq( float f ) { return f * f; }
  183. // This function computes the Min and Max scale that a matrix represents.
  184. // In other words, what is the maximum/minimum length that a line of length 1
  185. // could get stretched/shrunk to if the line was transformed by this matrix.
  186. //
  187. // The function uses eigenvalues; and returns two float numbers. Both are
  188. // non-negative; and MaxScale >= MinScale.
  189. //
  190. inline void CDX2DXForm::GetMinMaxScales( float& MinScale, float& MaxScale )
  191. {
  192. if( ( eM12 == 0. ) && ( eM21 == 0. ) )
  193. {
  194. // Let MinScale = abs(eM11)
  195. if (eM11 < 0)
  196. MinScale = -eM11;
  197. else
  198. MinScale = eM11;
  199. // Let MaxScale = abs(eM22)
  200. if (eM22 < 0)
  201. MaxScale = -eM22;
  202. else
  203. MaxScale = eM22;
  204. // Swap Min/Max if necessary
  205. if (MinScale > MaxScale)
  206. {
  207. float flTemp = MinScale;
  208. MinScale = MaxScale;
  209. MaxScale = flTemp;
  210. }
  211. }
  212. else
  213. {
  214. float t1 = DXSq(eM11) + DXSq(eM12) + DXSq(eM21) + DXSq(eM22);
  215. if( t1 == 0. )
  216. {
  217. MinScale = MaxScale = 0;
  218. }
  219. else
  220. {
  221. float t2 = (float)sqrt( (DXSq(eM12 + eM21) + DXSq(eM11 - eM22)) *
  222. (DXSq(eM12 - eM21) + DXSq(eM11 + eM22)) );
  223. // Due to floating point error; t1 may end up less than t2;
  224. // but that would mean that the min scale was small (relative
  225. // to max scale)
  226. if (t1 <= t2)
  227. MinScale = 0;
  228. else
  229. MinScale = (float)sqrt( (t1 - t2) * .5f );
  230. MaxScale = (float)sqrt( (t1 + t2) * .5f );
  231. }
  232. }
  233. } /* CDX2DXForm::GetMinMaxScales */
  234. inline void CDX2DXForm::Rotate( float Rotation )
  235. {
  236. double Angle = Rotation * (3.1415926535/180.0);
  237. float CosZ = (float)cos( Angle );
  238. float SinZ = (float)sin( Angle );
  239. if (CosZ > 0.0F && CosZ < 0.0000005F)
  240. {
  241. CosZ = .0F;
  242. }
  243. if (SinZ > -0.0000005F && SinZ < .0F)
  244. {
  245. SinZ = .0F;
  246. }
  247. float M11 = ( CosZ * eM11 ) + ( SinZ * eM21 );
  248. float M21 = (-SinZ * eM11 ) + ( CosZ * eM21 );
  249. float M12 = ( CosZ * eM12 ) + ( SinZ * eM22 );
  250. float M22 = (-SinZ * eM12 ) + ( CosZ * eM22 );
  251. eM11 = M11; eM21 = M21; eM12 = M12; eM22 = M22;
  252. DetermineOp();
  253. } /* CDX2DXForm::Rotate */
  254. inline void CDX2DXForm::Scale( float sx, float sy )
  255. {
  256. eM11 *= sx;
  257. eM12 *= sx;
  258. eDx *= sx;
  259. eM21 *= sy;
  260. eM22 *= sy;
  261. eDy *= sy;
  262. DetermineOp();
  263. } /* CDX2DXForm::Scale */
  264. inline void CDX2DXForm::Translate( float dx, float dy )
  265. {
  266. eDx += dx;
  267. eDy += dy;
  268. DetermineOp();
  269. } /* CDX2DXForm::Translate */
  270. inline void CDX2DXForm::TransformBounds( const DXBNDS& Bnds, DXBNDS& ResultBnds ) const
  271. {
  272. ResultBnds = Bnds;
  273. if( eOp != DX2DXO_IDENTITY )
  274. {
  275. ResultBnds.u.D[DXB_X].Min = (long)(( eM11 * Bnds.u.D[DXB_X].Min ) + ( eM12 * Bnds.u.D[DXB_Y].Min ) + eDx);
  276. ResultBnds.u.D[DXB_X].Max = (long)(( eM11 * Bnds.u.D[DXB_X].Max ) + ( eM12 * Bnds.u.D[DXB_Y].Max ) + eDx);
  277. ResultBnds.u.D[DXB_Y].Min = (long)(( eM21 * Bnds.u.D[DXB_X].Min ) + ( eM22 * Bnds.u.D[DXB_Y].Min ) + eDy);
  278. ResultBnds.u.D[DXB_Y].Max = (long)(( eM21 * Bnds.u.D[DXB_X].Max ) + ( eM22 * Bnds.u.D[DXB_Y].Max ) + eDy);
  279. }
  280. } /* CDX2DXForm::TransformBounds */
  281. inline void CDX2DXForm::TransformPoints( const DXFPOINT InPnts[], DXFPOINT OutPnts[], ULONG ulCount ) const
  282. {
  283. ULONG i;
  284. switch( eOp )
  285. {
  286. case DX2DXO_IDENTITY:
  287. memcpy( OutPnts, InPnts, ulCount * sizeof( DXFPOINT ) );
  288. break;
  289. case DX2DXO_TRANSLATE:
  290. for( i = 0; i < ulCount; ++i )
  291. {
  292. OutPnts[i].x = InPnts[i].x + eDx;
  293. OutPnts[i].y = InPnts[i].y + eDy;
  294. }
  295. break;
  296. case DX2DXO_SCALE:
  297. for( i = 0; i < ulCount; ++i )
  298. {
  299. OutPnts[i].x = InPnts[i].x * eM11;
  300. OutPnts[i].y = InPnts[i].y * eM22;
  301. }
  302. break;
  303. case DX2DXO_SCALE_AND_TRANS:
  304. for( i = 0; i < ulCount; ++i )
  305. {
  306. OutPnts[i].x = (InPnts[i].x * eM11) + eDx;
  307. OutPnts[i].y = (InPnts[i].y * eM22) + eDy;
  308. }
  309. break;
  310. case DX2DXO_GENERAL:
  311. for( i = 0; i < ulCount; ++i )
  312. {
  313. OutPnts[i].x = ( InPnts[i].x * eM11 ) + ( InPnts[i].y * eM12 );
  314. OutPnts[i].y = ( InPnts[i].x * eM21 ) + ( InPnts[i].y * eM22 );
  315. }
  316. break;
  317. case DX2DXO_GENERAL_AND_TRANS:
  318. for( i = 0; i < ulCount; ++i )
  319. {
  320. OutPnts[i].x = ( InPnts[i].x * eM11 ) + ( InPnts[i].y * eM12 ) + eDx;
  321. OutPnts[i].y = ( InPnts[i].x * eM21 ) + ( InPnts[i].y * eM22 ) + eDy;
  322. }
  323. break;
  324. default:
  325. _ASSERT( 0 ); // invalid operation id
  326. }
  327. } /* CDX2DXForm::TransformPoints */
  328. inline DXFPOINT CDX2DXForm::operator*( const DXFPOINT& v ) const
  329. {
  330. DXFPOINT NewPnt;
  331. NewPnt.x = ( v.x * eM11 ) + ( v.y * eM12 ) + eDx;
  332. NewPnt.y = ( v.x * eM21 ) + ( v.y * eM22 ) + eDy;
  333. return NewPnt;
  334. } /* CDX2DXForm::operator* */
  335. inline CDX2DXForm CDX2DXForm::operator*( const CDX2DXForm& Other ) const
  336. {
  337. DX2DXFORM x;
  338. x.eM11 = ( eM11 * Other.eM11 ) + ( eM12 * Other.eM21 );
  339. x.eM12 = ( eM11 * Other.eM12 ) + ( eM12 * Other.eM22 );
  340. x.eDx = ( eM11 * Other.eDx ) + ( eM12 * Other.eDy ) + eDx;
  341. x.eM21 = ( eM21 * Other.eM11 ) + ( eM22 * Other.eM21 );
  342. x.eM22 = ( eM21 * Other.eM12 ) + ( eM22 * Other.eM22 );
  343. x.eDy = ( eM21 * Other.eDx ) + ( eM22 * Other.eDy ) + eDy;
  344. return x;
  345. } /* CDX2DXForm::operator*= */
  346. inline BOOL CDX2DXForm::Invert()
  347. {
  348. switch( eOp )
  349. {
  350. case DX2DXO_IDENTITY:
  351. break;
  352. case DX2DXO_TRANSLATE:
  353. eDx = -eDx;
  354. eDy = -eDy;
  355. break;
  356. case DX2DXO_SCALE:
  357. if (eM11 == 0.0 || eM22 == 0.0)
  358. return false;
  359. eM11 = 1.0f / eM11;
  360. eM22 = 1.0f / eM22;
  361. break;
  362. case DX2DXO_SCALE_AND_TRANS:
  363. {
  364. if (eM11 == 0.0f || eM22 == 0.0f)
  365. return false;
  366. // Our old equation was F = aG + b
  367. // The inverse is G = F/a - b/a where a is eM11 and b is eDx
  368. float flOneOverA = 1.0f / eM11;
  369. eDx = -eDx * flOneOverA;
  370. eM11 = flOneOverA;
  371. // Our old equation was F = aG + b
  372. // The inverse is G = F/a - b/a where a is eM22 and b is eDy
  373. flOneOverA = 1.0f / eM22;
  374. eDy = -eDy * flOneOverA;
  375. eM22 = flOneOverA;
  376. break;
  377. }
  378. case DX2DXO_GENERAL:
  379. case DX2DXO_GENERAL_AND_TRANS:
  380. {
  381. // The inverse of A= |a b| is | d -c|*(1/Det) where Det is the determinant of A
  382. // |c d| |-b a|
  383. // Det(A) = ad - bc
  384. // Compute determininant
  385. float flDet = (eM11 * eM22 - eM12 * eM21);
  386. if (flDet == 0.0f)
  387. return FALSE;
  388. float flCoef = 1.0f / flDet;
  389. // Remember old value of eM11
  390. float flM11Original = eM11;
  391. eM11 = flCoef * eM22;
  392. eM12 = -flCoef * eM12;
  393. eM21 = -flCoef * eM21;
  394. eM22 = flCoef * flM11Original;
  395. // If we have a translation; then we need to
  396. // compute new values for that translation
  397. if (eOp == DX2DXO_GENERAL_AND_TRANS)
  398. {
  399. // Remember original value of eDx
  400. float eDxOriginal = eDx;
  401. eDx = -eM11 * eDx - eM12 * eDy;
  402. eDy = -eM21 * eDxOriginal - eM22 * eDy;
  403. }
  404. }
  405. break;
  406. default:
  407. _ASSERT( 0 ); // invalid operation id
  408. }
  409. // We don't need to call DetermineOp here
  410. // because the op doesn't change when inverted
  411. // i.e. a scale remains a scale, etc.
  412. return true;
  413. } /* CDX2DXForm::Invert */
  414. /*** CDXMatrix4x4F ************
  415. * This class implements basic matrix operation based on a 4x4 array.
  416. */
  417. //const float g_DXMat4X4Identity[4][4] =
  418. //{
  419. // { 1.0, 0. , 0. , 0. },
  420. // { 0. , 1.0, 0. , 0. },
  421. // { 0. , 0. , 1.0, 0. },
  422. // { 0. , 0. , 0. , 1.0 }
  423. //};
  424. class CDXMatrix4x4F
  425. {
  426. public:
  427. /*=== Member Data ===*/
  428. float m_Coeff[4][4];
  429. /*=== Methods =======*/
  430. public:
  431. /*--- Constructors ---*/
  432. CDXMatrix4x4F() { SetIdentity(); }
  433. CDXMatrix4x4F( const CDXMatrix4x4F& Other )
  434. { CopyMemory( (void *)&m_Coeff, (void *)&Other.m_Coeff, sizeof(m_Coeff) ); }
  435. CDXMatrix4x4F( DX2DXFORM& XForm );
  436. /*--- operations ---*/
  437. void ZeroMatrix( void ) { memset( m_Coeff, 0, sizeof( m_Coeff ) ); }
  438. void SetIdentity( void ) {
  439. memset( m_Coeff, 0, sizeof( m_Coeff ) );
  440. m_Coeff[0][0] = m_Coeff[1][1] = m_Coeff[2][2] = m_Coeff[3][3] = 1.0;
  441. }
  442. void SetCoefficients( float Coeff[4][4] ) { memcpy( m_Coeff, Coeff, sizeof( m_Coeff )); }
  443. void GetCoefficients( float Coeff[4][4] ) { memcpy( Coeff, m_Coeff, sizeof( m_Coeff )); }
  444. //BOOL IsIdentity();
  445. void Scale( float sx, float sy, float sz );
  446. void Rotate( float rx, float ry, float rz );
  447. void Translate( float dx, float dy, float dz );
  448. BOOL Invert();
  449. BOOL GetInverse( CDXMatrix4x4F *pIn );
  450. void Transpose();
  451. void GetTranspose( CDXMatrix4x4F *pIn );
  452. void GetAdjoint( CDXMatrix4x4F *pIn );
  453. HRESULT InitFromSafeArray( SAFEARRAY *psa );
  454. HRESULT GetSafeArray( SAFEARRAY **ppsa ) const;
  455. void TransformBounds( DXBNDS& Bnds, DXBNDS& ResultBnds );
  456. /*--- operators ---*/
  457. CDXDVec operator*( CDXDVec& v) const;
  458. CDXCVec operator*( CDXCVec& v) const;
  459. CDXMatrix4x4F operator*(CDXMatrix4x4F Matrix) const;
  460. void operator*=(CDXMatrix4x4F Matrix) const;
  461. void CDXMatrix4x4F::operator=(const CDXMatrix4x4F srcMatrix);
  462. void CDXMatrix4x4F::operator+=(const CDXMatrix4x4F otherMatrix);
  463. void CDXMatrix4x4F::operator-=(const CDXMatrix4x4F otherMatrix);
  464. BOOL CDXMatrix4x4F::operator==(const CDXMatrix4x4F otherMatrix) const;
  465. BOOL CDXMatrix4x4F::operator!=(const CDXMatrix4x4F otherMatrix) const;
  466. };
  467. inline CDXMatrix4x4F::CDXMatrix4x4F( DX2DXFORM& XForm )
  468. {
  469. SetIdentity();
  470. m_Coeff[0][0] = XForm.eM11;
  471. m_Coeff[0][1] = XForm.eM12;
  472. m_Coeff[1][0] = XForm.eM21;
  473. m_Coeff[1][1] = XForm.eM22;
  474. m_Coeff[0][3] = XForm.eDx;
  475. m_Coeff[1][3] = XForm.eDy;
  476. }
  477. // Additional Operations
  478. inline void CDXMatrix4x4F::operator=(const CDXMatrix4x4F srcMatrix)
  479. {
  480. CopyMemory( (void *)m_Coeff, (const void *)srcMatrix.m_Coeff, sizeof(srcMatrix.m_Coeff) );
  481. } /* CDXMatrix4x4F::operator= */
  482. inline BOOL CDXMatrix4x4F::operator==(const CDXMatrix4x4F otherMatrix) const
  483. {
  484. return !memcmp( (void *)m_Coeff, (const void *)otherMatrix.m_Coeff, sizeof(otherMatrix.m_Coeff) );
  485. } /* CDXMatrix4x4F::operator== */
  486. inline BOOL CDXMatrix4x4F::operator!=(const CDXMatrix4x4F otherMatrix) const
  487. {
  488. return memcmp( (void *)m_Coeff, (const void *)otherMatrix.m_Coeff, sizeof(otherMatrix.m_Coeff) );
  489. } /* CDXMatrix4x4F::operator!= */
  490. inline void CDXMatrix4x4F::operator+=(const CDXMatrix4x4F otherMatrix)
  491. {
  492. for( int i = 0; i < 4; i++ )
  493. for( int j = 0; j < 4; j++ )
  494. m_Coeff[i][j] += otherMatrix.m_Coeff[i][j];
  495. } /* CDXMatrix4x4F::operator+= */
  496. inline void CDXMatrix4x4F::operator-=(const CDXMatrix4x4F otherMatrix)
  497. {
  498. for( int i = 0; i < 4; i++ )
  499. for( int j = 0; j < 4; j++ )
  500. m_Coeff[i][j] -= otherMatrix.m_Coeff[i][j];
  501. } /* CDXMatrix4x4F::operator-= */
  502. inline CDXDVec CDXMatrix4x4F::operator*(CDXDVec& v) const
  503. {
  504. CDXDVec t;
  505. float temp;
  506. 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];
  507. t[0] = (long)((temp < 0) ? temp -= .5 : temp += .5);
  508. 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];
  509. t[1] = (long)((temp < 0) ? temp -= .5 : temp += .5);
  510. 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];
  511. t[2] = (long)((temp < 0) ? temp -= .5 : temp += .5);
  512. 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];
  513. t[3] = (long)((temp < 0) ? temp -= .5 : temp += .5);
  514. return t;
  515. } /* CDXMatrix4x4F::operator*(DXDVEC) */
  516. inline CDXCVec CDXMatrix4x4F::operator*(CDXCVec& v) const
  517. {
  518. CDXCVec t;
  519. 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];
  520. 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];
  521. 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];
  522. 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];
  523. return t;
  524. } /* CDXMatrix4x4F::operator*(DXCVEC) */
  525. inline CDXMatrix4x4F CDXMatrix4x4F::operator*(CDXMatrix4x4F Mx) const
  526. {
  527. CDXMatrix4x4F t;
  528. int i, j;
  529. for( i = 0; i < 4; i++ )
  530. {
  531. for( j = 0; j < 4; j++ )
  532. {
  533. t.m_Coeff[i][j] = m_Coeff[i][0] * Mx.m_Coeff[0][j] +
  534. m_Coeff[i][1] * Mx.m_Coeff[1][j] +
  535. m_Coeff[i][2] * Mx.m_Coeff[2][j] +
  536. m_Coeff[i][3] * Mx.m_Coeff[3][j];
  537. }
  538. }
  539. return t;
  540. } /* CDXMatrix4x4F::operator*(CDXMatrix4x4F) */
  541. inline void CDXMatrix4x4F::operator*=(CDXMatrix4x4F Mx) const
  542. {
  543. CDXMatrix4x4F t;
  544. int i, j;
  545. for( i = 0; i < 4; i++ )
  546. {
  547. for( j = 0; j < 4; j++ )
  548. {
  549. t.m_Coeff[i][j] = m_Coeff[i][0] * Mx.m_Coeff[0][j] +
  550. m_Coeff[i][1] * Mx.m_Coeff[1][j] +
  551. m_Coeff[i][2] * Mx.m_Coeff[2][j] +
  552. m_Coeff[i][3] * Mx.m_Coeff[3][j];
  553. }
  554. }
  555. CopyMemory( (void *)m_Coeff, (void *)t.m_Coeff, sizeof(m_Coeff) );
  556. } /* CDXMatrix4x4F::operator*=(CDXMatrix4x4F) */
  557. inline void CDXMatrix4x4F::Scale( float sx, float sy, float sz )
  558. {
  559. if( sx != 1. )
  560. {
  561. m_Coeff[0][0] *= sx;
  562. m_Coeff[0][1] *= sx;
  563. m_Coeff[0][2] *= sx;
  564. m_Coeff[0][3] *= sx;
  565. }
  566. if( sy != 1. )
  567. {
  568. m_Coeff[1][0] *= sy;
  569. m_Coeff[1][1] *= sy;
  570. m_Coeff[1][2] *= sy;
  571. m_Coeff[1][3] *= sy;
  572. }
  573. if( sz != 1. )
  574. {
  575. m_Coeff[2][0] *= sz;
  576. m_Coeff[2][1] *= sz;
  577. m_Coeff[2][2] *= sz;
  578. m_Coeff[2][3] *= sz;
  579. }
  580. } /* CDXMatrix4x4F::Scale */
  581. inline void CDXMatrix4x4F::Translate( float dx, float dy, float dz )
  582. {
  583. float a, b, c, d;
  584. a = b = c = d = 0;
  585. if( dx != 0. )
  586. {
  587. a += m_Coeff[0][0]*dx;
  588. b += m_Coeff[0][1]*dx;
  589. c += m_Coeff[0][2]*dx;
  590. d += m_Coeff[0][3]*dx;
  591. }
  592. if( dy != 0. )
  593. {
  594. a += m_Coeff[1][0]*dy;
  595. b += m_Coeff[1][1]*dy;
  596. c += m_Coeff[1][2]*dy;
  597. d += m_Coeff[1][3]*dy;
  598. }
  599. if( dz != 0. )
  600. {
  601. a += m_Coeff[2][0]*dz;
  602. b += m_Coeff[2][1]*dz;
  603. c += m_Coeff[2][2]*dz;
  604. d += m_Coeff[2][3]*dz;
  605. }
  606. m_Coeff[3][0] += a;
  607. m_Coeff[3][1] += b;
  608. m_Coeff[3][2] += c;
  609. m_Coeff[3][3] += d;
  610. } /* CDXMatrix4x4F::Translate */
  611. inline void CDXMatrix4x4F::Rotate( float rx, float ry, float rz )
  612. {
  613. const float l_dfCte = (const float)(3.1415926535/180.0);
  614. float lAngleY = 0.0;
  615. float lAngleX = 0.0;
  616. float lAngleZ = 0.0;
  617. float lCosX = 1.0;
  618. float lSinX = 0.0;
  619. float lCosY = 1.0;
  620. float lSinY = 0.0;
  621. float lCosZ = 1.0;
  622. float lSinZ = 0.0;
  623. // calculate rotation angle sines and cosines
  624. if( rx != 0 )
  625. {
  626. lAngleX = rx * l_dfCte;
  627. lCosX = (float)cos(lAngleX);
  628. lSinX = (float)sin(lAngleX);
  629. if (lCosX > 0.0F && lCosX < 0.0000005F)
  630. {
  631. lCosX = .0F;
  632. }
  633. if (lSinX > -0.0000005F && lSinX < .0F)
  634. {
  635. lSinX = .0F;
  636. }
  637. }
  638. if( ry != 0 )
  639. {
  640. lAngleY = ry * l_dfCte;
  641. lCosY = (float)cos(lAngleY);
  642. lSinY = (float)sin(lAngleY);
  643. if (lCosY > 0.0F && lCosY < 0.0000005F)
  644. {
  645. lCosY = .0F;
  646. }
  647. if (lSinY > -0.0000005F && lSinY < .0F)
  648. {
  649. lSinY = .0F;
  650. }
  651. }
  652. if( rz != 0 )
  653. {
  654. lAngleZ = rz * l_dfCte;
  655. lCosZ = (float)cos(lAngleZ);
  656. lSinZ = (float)sin(lAngleZ);
  657. if (lCosZ > 0.0F && lCosZ < 0.0000005F)
  658. {
  659. lCosZ = .0F;
  660. }
  661. if (lSinZ > -0.0000005F && lSinZ < .0F)
  662. {
  663. lSinZ = .0F;
  664. }
  665. }
  666. float u, v;
  667. int i;
  668. //--- X Rotation
  669. for( i = 0; i < 4; i++ )
  670. {
  671. u = m_Coeff[1][i];
  672. v = m_Coeff[2][i];
  673. m_Coeff[1][i] = lCosX*u+lSinX*v;
  674. m_Coeff[2][i] = -lSinX*u+lCosX*v;
  675. }
  676. //--- Y Rotation
  677. for( i = 0; i < 4; i++ )
  678. {
  679. u = m_Coeff[0][i];
  680. v = m_Coeff[2][i];
  681. m_Coeff[0][i] = lCosY*u-lSinY*v;
  682. m_Coeff[2][i] = lSinY*u+lCosY*v;
  683. }
  684. //--- Z Rotation
  685. for( i = 0; i < 4; i++ )
  686. {
  687. u = m_Coeff[0][i];
  688. v = m_Coeff[1][i];
  689. m_Coeff[0][i] = lCosZ*u+lSinZ*v;
  690. m_Coeff[1][i] = -lSinZ*u+lCosZ*v;
  691. }
  692. }
  693. /*
  694. inline BOOL CDXMatrix4x4F::IsIdentity()
  695. {
  696. return !memcmp( m_Coeff, g_DXMat4X4Identity, sizeof(g_DXMat4X4Identity) );
  697. } /* CDXMatrix4x4F::IsIdentity */
  698. /*
  699. Uses Gaussian elimination to invert the 4 x 4 non-linear matrix in t and
  700. return the result in Mx. The matrix t is destroyed in the process.
  701. */
  702. inline BOOL CDXMatrix4x4F::Invert()
  703. {
  704. int i,j,k,Pivot;
  705. float PValue;
  706. CDXMatrix4x4F Mx;
  707. Mx.SetIdentity();
  708. /* Find pivot element. Use partial pivoting by row */
  709. for( i = 0;i < 4; i++ )
  710. {
  711. Pivot = 0;
  712. for( j = 0; j < 4; j++ )
  713. {
  714. if( fabs(m_Coeff[i][j]) > fabs(m_Coeff[i][Pivot]) ) Pivot = j;
  715. }
  716. if( m_Coeff[i][Pivot] == 0.0 )
  717. {
  718. ZeroMatrix(); /* Singular Matrix */
  719. return FALSE;
  720. }
  721. /* Normalize */
  722. PValue = m_Coeff[i][Pivot];
  723. for( j = 0; j < 4; j++ )
  724. {
  725. m_Coeff[i][j] /= PValue;
  726. Mx.m_Coeff[i][j] /= PValue;
  727. }
  728. /* Zeroing */
  729. for( j = 0; j < 4; j++ )
  730. {
  731. if( j != i )
  732. {
  733. PValue = m_Coeff[j][Pivot];
  734. for( k = 0; k < 4; k++ )
  735. {
  736. m_Coeff[j][k] -= PValue*m_Coeff[i][k];
  737. Mx.m_Coeff[j][k] -= PValue*Mx.m_Coeff[i][k];
  738. }
  739. }
  740. }
  741. }
  742. /* Reorder rows */
  743. for( i = 0; i < 4; i++ )
  744. {
  745. if( m_Coeff[i][i] != 1.0 )
  746. {
  747. for( j = i + 1; j < 4; j++ )
  748. if( m_Coeff[j][i] == 1.0 ) break;
  749. if( j >= 4 )
  750. {
  751. ZeroMatrix();
  752. return FALSE;
  753. }
  754. //--- swap rows i and j of original
  755. for( k = 0; k < 4; k++ )
  756. {
  757. m_Coeff[i][k] += m_Coeff[j][k];
  758. m_Coeff[j][k] = m_Coeff[i][k] - m_Coeff[j][k];
  759. m_Coeff[i][k] -= m_Coeff[j][k];
  760. }
  761. //--- swap rows i and j of result
  762. for( k = 0; k < 4; k++ )
  763. {
  764. Mx.m_Coeff[i][k] += Mx.m_Coeff[j][k];
  765. Mx.m_Coeff[j][k] = Mx.m_Coeff[i][k] - Mx.m_Coeff[j][k];
  766. Mx.m_Coeff[i][k] -= Mx.m_Coeff[j][k];
  767. }
  768. }
  769. }
  770. *this = Mx;
  771. return TRUE;
  772. } /* CDXMatrix4x4F::Invert */
  773. inline void CDXMatrix4x4F::Transpose()
  774. {
  775. float temp;
  776. temp = m_Coeff[0][1];
  777. m_Coeff[0][1] = m_Coeff[1][0];
  778. m_Coeff[1][0] = temp;
  779. temp = m_Coeff[0][2];
  780. m_Coeff[0][2] = m_Coeff[2][0];
  781. m_Coeff[2][0] = temp;
  782. temp = m_Coeff[0][3];
  783. m_Coeff[0][3] = m_Coeff[3][0];
  784. m_Coeff[3][0] = temp;
  785. temp = m_Coeff[1][2];
  786. m_Coeff[1][2] = m_Coeff[2][1];
  787. m_Coeff[2][1] = temp;
  788. temp = m_Coeff[1][3];
  789. m_Coeff[1][3] = m_Coeff[3][1];
  790. m_Coeff[3][1] = temp;
  791. temp = m_Coeff[2][3];
  792. m_Coeff[2][3] = m_Coeff[3][2];
  793. m_Coeff[3][2] = temp;
  794. } /* CDXMatrix4x4F::Transpose */
  795. inline void CDXMatrix4x4F::GetTranspose( CDXMatrix4x4F *m )
  796. {
  797. float temp;
  798. (*this) = *m;
  799. temp = m_Coeff[0][1];
  800. m_Coeff[0][1] = m_Coeff[1][0];
  801. m_Coeff[1][0] = temp;
  802. temp = m_Coeff[0][2];
  803. m_Coeff[0][2] = m_Coeff[2][0];
  804. m_Coeff[2][0] = temp;
  805. temp = m_Coeff[0][3];
  806. m_Coeff[0][3] = m_Coeff[3][0];
  807. m_Coeff[3][0] = temp;
  808. temp = m_Coeff[1][2];
  809. m_Coeff[1][2] = m_Coeff[2][1];
  810. m_Coeff[2][1] = temp;
  811. temp = m_Coeff[1][3];
  812. m_Coeff[1][3] = m_Coeff[3][1];
  813. m_Coeff[3][1] = temp;
  814. temp = m_Coeff[2][3];
  815. m_Coeff[2][3] = m_Coeff[3][2];
  816. m_Coeff[3][2] = temp;
  817. } /* CDXMatrix4x4F::Transpose */
  818. /*
  819. Matrix Inversion
  820. by Richard Carling
  821. from "Graphics Gems", Academic Press, 1990
  822. */
  823. #define SMALL_NUMBER 1.e-8
  824. /*
  825. * inverse( original_matrix, inverse_matrix )
  826. *
  827. * calculate the inverse of a 4x4 matrix
  828. *
  829. * -1
  830. * A = ___1__ adjoint A
  831. * det A
  832. */
  833. inline BOOL CDXMatrix4x4F::GetInverse( CDXMatrix4x4F *pIn )
  834. {
  835. int i, j;
  836. float det;
  837. /* calculate the adjoint matrix */
  838. GetAdjoint( pIn );
  839. /* calculate the 4x4 determinant
  840. * if the determinant is zero,
  841. * then the inverse matrix is not unique.
  842. */
  843. det = det4x4( pIn );
  844. if( fabs( det ) < SMALL_NUMBER )
  845. {
  846. // Non-singular matrix, no inverse!
  847. return FALSE;;
  848. }
  849. /* scale the adjoint matrix to get the inverse */
  850. for( i = 0; i < 4; i++ )
  851. for( j = 0; j < 4; j++ )
  852. m_Coeff[i][j] = m_Coeff[i][j] / det;
  853. return TRUE;
  854. }
  855. /*
  856. * adjoint( original_matrix, inverse_matrix )
  857. *
  858. * calculate the adjoint of a 4x4 matrix
  859. *
  860. * Let a denote the minor determinant of matrix A obtained by
  861. * ij
  862. *
  863. * deleting the ith row and jth column from A.
  864. *
  865. * i+j
  866. * Let b = (-1) a
  867. * ij ji
  868. *
  869. * The matrix B = (b ) is the adjoint of A
  870. * ij
  871. */
  872. inline void CDXMatrix4x4F::GetAdjoint( CDXMatrix4x4F *pIn )
  873. {
  874. float a1, a2, a3, a4, b1, b2, b3, b4;
  875. float c1, c2, c3, c4, d1, d2, d3, d4;
  876. /* assign to individual variable names to aid */
  877. /* selecting correct values */
  878. a1 = pIn->m_Coeff[0][0]; b1 = pIn->m_Coeff[0][1];
  879. c1 = pIn->m_Coeff[0][2]; d1 = pIn->m_Coeff[0][3];
  880. a2 = pIn->m_Coeff[1][0]; b2 = pIn->m_Coeff[1][1];
  881. c2 = pIn->m_Coeff[1][2]; d2 = pIn->m_Coeff[1][3];
  882. a3 = pIn->m_Coeff[2][0]; b3 = pIn->m_Coeff[2][1];
  883. c3 = pIn->m_Coeff[2][2]; d3 = pIn->m_Coeff[2][3];
  884. a4 = pIn->m_Coeff[3][0]; b4 = pIn->m_Coeff[3][1];
  885. c4 = pIn->m_Coeff[3][2]; d4 = pIn->m_Coeff[3][3];
  886. /* row column labeling reversed since we transpose rows & columns */
  887. m_Coeff[0][0] = det3x3( b2, b3, b4, c2, c3, c4, d2, d3, d4);
  888. m_Coeff[1][0] = - det3x3( a2, a3, a4, c2, c3, c4, d2, d3, d4);
  889. m_Coeff[2][0] = det3x3( a2, a3, a4, b2, b3, b4, d2, d3, d4);
  890. m_Coeff[3][0] = - det3x3( a2, a3, a4, b2, b3, b4, c2, c3, c4);
  891. m_Coeff[0][1] = - det3x3( b1, b3, b4, c1, c3, c4, d1, d3, d4);
  892. m_Coeff[1][1] = det3x3( a1, a3, a4, c1, c3, c4, d1, d3, d4);
  893. m_Coeff[2][1] = - det3x3( a1, a3, a4, b1, b3, b4, d1, d3, d4);
  894. m_Coeff[3][1] = det3x3( a1, a3, a4, b1, b3, b4, c1, c3, c4);
  895. m_Coeff[0][2] = det3x3( b1, b2, b4, c1, c2, c4, d1, d2, d4);
  896. m_Coeff[1][2] = - det3x3( a1, a2, a4, c1, c2, c4, d1, d2, d4);
  897. m_Coeff[2][2] = det3x3( a1, a2, a4, b1, b2, b4, d1, d2, d4);
  898. m_Coeff[3][2] = - det3x3( a1, a2, a4, b1, b2, b4, c1, c2, c4);
  899. m_Coeff[0][3] = - det3x3( b1, b2, b3, c1, c2, c3, d1, d2, d3);
  900. m_Coeff[1][3] = det3x3( a1, a2, a3, c1, c2, c3, d1, d2, d3);
  901. m_Coeff[2][3] = - det3x3( a1, a2, a3, b1, b2, b3, d1, d2, d3);
  902. m_Coeff[3][3] = det3x3( a1, a2, a3, b1, b2, b3, c1, c2, c3);
  903. }
  904. /*
  905. * float = det4x4( matrix )
  906. *
  907. * calculate the determinant of a 4x4 matrix.
  908. */
  909. inline float det4x4( CDXMatrix4x4F *pIn )
  910. {
  911. float ans;
  912. float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
  913. /* assign to individual variable names to aid selecting */
  914. /* correct elements */
  915. a1 = pIn->m_Coeff[0][0]; b1 = pIn->m_Coeff[0][1];
  916. c1 = pIn->m_Coeff[0][2]; d1 = pIn->m_Coeff[0][3];
  917. a2 = pIn->m_Coeff[1][0]; b2 = pIn->m_Coeff[1][1];
  918. c2 = pIn->m_Coeff[1][2]; d2 = pIn->m_Coeff[1][3];
  919. a3 = pIn->m_Coeff[2][0]; b3 = pIn->m_Coeff[2][1];
  920. c3 = pIn->m_Coeff[2][2]; d3 = pIn->m_Coeff[2][3];
  921. a4 = pIn->m_Coeff[3][0]; b4 = pIn->m_Coeff[3][1];
  922. c4 = pIn->m_Coeff[3][2]; d4 = pIn->m_Coeff[3][3];
  923. ans = a1 * det3x3( b2, b3, b4, c2, c3, c4, d2, d3, d4 )
  924. - b1 * det3x3( a2, a3, a4, c2, c3, c4, d2, d3, d4 )
  925. + c1 * det3x3( a2, a3, a4, b2, b3, b4, d2, d3, d4 )
  926. - d1 * det3x3( a2, a3, a4, b2, b3, b4, c2, c3, c4 );
  927. return ans;
  928. }
  929. /*
  930. * float = det3x3( a1, a2, a3, b1, b2, b3, c1, c2, c3 )
  931. *
  932. * calculate the determinant of a 3x3 matrix
  933. * in the form
  934. *
  935. * | a1, b1, c1 |
  936. * | a2, b2, c2 |
  937. * | a3, b3, c3 |
  938. */
  939. inline float det3x3( float a1, float a2, float a3,
  940. float b1, float b2, float b3,
  941. float c1, float c2, float c3 )
  942. {
  943. float ans;
  944. ans = a1 * det2x2( b2, b3, c2, c3 )
  945. - b1 * det2x2( a2, a3, c2, c3 )
  946. + c1 * det2x2( a2, a3, b2, b3 );
  947. return ans;
  948. }
  949. /*
  950. * float = det2x2( float a, float b, float c, float d )
  951. *
  952. * calculate the determinant of a 2x2 matrix.
  953. */
  954. inline float det2x2( float a, float b, float c, float d )
  955. {
  956. float ans = a * d - b * c;
  957. return ans;
  958. }
  959. inline HRESULT CDXMatrix4x4F::InitFromSafeArray( SAFEARRAY * /*pSA*/ )
  960. {
  961. HRESULT hr = S_OK;
  962. #if 0
  963. long *pData;
  964. if( !pSA || ( pSA->cDims != 1 ) ||
  965. ( pSA->cbElements != sizeof(float) ) ||
  966. ( pSA->rgsabound->lLbound != 1 ) ||
  967. ( pSA->rgsabound->cElements != 8 )
  968. )
  969. {
  970. hr = E_INVALIDARG;
  971. }
  972. else
  973. {
  974. hr = SafeArrayAccessData(pSA, (void **)&pData);
  975. if( SUCCEEDED( hr ) )
  976. {
  977. for( int i = 0; i < 4; ++i )
  978. {
  979. m_Bounds[i].Min = pData[i];
  980. m_Bounds[i].Max = pData[i+4];
  981. m_Bounds[i].SampleRate = SampleRate;
  982. }
  983. hr = SafeArrayUnaccessData( pSA );
  984. }
  985. }
  986. #endif
  987. return hr;
  988. } /* CDXMatrix4x4F::InitFromSafeArray */
  989. inline HRESULT CDXMatrix4x4F::GetSafeArray( SAFEARRAY ** /*ppSA*/ ) const
  990. {
  991. HRESULT hr = S_OK;
  992. #if 0
  993. SAFEARRAY *pSA;
  994. if( !ppSA )
  995. {
  996. hr = E_POINTER;
  997. }
  998. else
  999. {
  1000. SAFEARRAYBOUND rgsabound;
  1001. rgsabound.lLbound = 1;
  1002. rgsabound.cElements = 16;
  1003. if( !(pSA = SafeArrayCreate( VT_I4, 1, &rgsabound ) ) )
  1004. {
  1005. hr = E_OUTOFMEMORY;
  1006. }
  1007. else
  1008. {
  1009. long *pData;
  1010. hr = SafeArrayAccessData( pSA, (void **)&pData );
  1011. if( SUCCEEDED( hr ) )
  1012. {
  1013. for( int i = 0; i < 4; ++i )
  1014. {
  1015. pData[i] = m_Bounds[i].Min;
  1016. pData[i+4] = m_Bounds[i].Max;
  1017. }
  1018. hr = SafeArrayUnaccessData( pSA );
  1019. }
  1020. }
  1021. if( SUCCEEDED( hr ) )
  1022. {
  1023. *ppSA = pSA;
  1024. }
  1025. }
  1026. #endif
  1027. return hr;
  1028. } /* CDXMatrix4x4F::GetSafeArray */
  1029. inline void CDXMatrix4x4F::TransformBounds( DXBNDS& /*Bnds*/, DXBNDS& /*ResultBnds*/ )
  1030. {
  1031. } /* CDXMatrix4x4F::TransformBounds */
  1032. #endif // DXVector_h