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.

1084 lines
31 KiB

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