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.

1094 lines
31 KiB

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