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.

265 lines
8.8 KiB

  1. #include "pch.cpp"
  2. #pragma hdrstop
  3. //---------------------------------------------------------------------
  4. // This function uses Cramer's Rule to calculate the matrix inverse.
  5. // See nt\private\windows\opengl\serever\soft\so_math.c
  6. //
  7. // Returns:
  8. // 0 - if success
  9. // -1 - if input matrix is singular
  10. //
  11. int Inverse4x4(D3DMATRIX *src, D3DMATRIX *inverse)
  12. {
  13. double x00, x01, x02;
  14. double x10, x11, x12;
  15. double x20, x21, x22;
  16. double rcp;
  17. double x30, x31, x32;
  18. double y01, y02, y03, y12, y13, y23;
  19. double z02, z03, z12, z13, z22, z23, z32, z33;
  20. #define x03 x01
  21. #define x13 x11
  22. #define x23 x21
  23. #define x33 x31
  24. #define z00 x02
  25. #define z10 x12
  26. #define z20 x22
  27. #define z30 x32
  28. #define z01 x03
  29. #define z11 x13
  30. #define z21 x23
  31. #define z31 x33
  32. /* read 1st two columns of matrix into registers */
  33. x00 = src->_11;
  34. x01 = src->_12;
  35. x10 = src->_21;
  36. x11 = src->_22;
  37. x20 = src->_31;
  38. x21 = src->_32;
  39. x30 = src->_41;
  40. x31 = src->_42;
  41. /* compute all six 2x2 determinants of 1st two columns */
  42. y01 = x00*x11 - x10*x01;
  43. y02 = x00*x21 - x20*x01;
  44. y03 = x00*x31 - x30*x01;
  45. y12 = x10*x21 - x20*x11;
  46. y13 = x10*x31 - x30*x11;
  47. y23 = x20*x31 - x30*x21;
  48. /* read 2nd two columns of matrix into registers */
  49. x02 = src->_13;
  50. x03 = src->_14;
  51. x12 = src->_23;
  52. x13 = src->_24;
  53. x22 = src->_33;
  54. x23 = src->_34;
  55. x32 = src->_43;
  56. x33 = src->_44;
  57. /* compute all 3x3 cofactors for 2nd two columns */
  58. z33 = x02*y12 - x12*y02 + x22*y01;
  59. z23 = x12*y03 - x32*y01 - x02*y13;
  60. z13 = x02*y23 - x22*y03 + x32*y02;
  61. z03 = x22*y13 - x32*y12 - x12*y23;
  62. z32 = x13*y02 - x23*y01 - x03*y12;
  63. z22 = x03*y13 - x13*y03 + x33*y01;
  64. z12 = x23*y03 - x33*y02 - x03*y23;
  65. z02 = x13*y23 - x23*y13 + x33*y12;
  66. /* compute all six 2x2 determinants of 2nd two columns */
  67. y01 = x02*x13 - x12*x03;
  68. y02 = x02*x23 - x22*x03;
  69. y03 = x02*x33 - x32*x03;
  70. y12 = x12*x23 - x22*x13;
  71. y13 = x12*x33 - x32*x13;
  72. y23 = x22*x33 - x32*x23;
  73. /* read 1st two columns of matrix into registers */
  74. x00 = src->_11;
  75. x01 = src->_12;
  76. x10 = src->_21;
  77. x11 = src->_22;
  78. x20 = src->_31;
  79. x21 = src->_32;
  80. x30 = src->_41;
  81. x31 = src->_42;
  82. /* compute all 3x3 cofactors for 1st column */
  83. z30 = x11*y02 - x21*y01 - x01*y12;
  84. z20 = x01*y13 - x11*y03 + x31*y01;
  85. z10 = x21*y03 - x31*y02 - x01*y23;
  86. z00 = x11*y23 - x21*y13 + x31*y12;
  87. /* compute 4x4 determinant & its reciprocal */
  88. rcp = x30*z30 + x20*z20 + x10*z10 + x00*z00;
  89. if (rcp == (float)0)
  90. return -1;
  91. rcp = (float)1/rcp;
  92. /* compute all 3x3 cofactors for 2nd column */
  93. z31 = x00*y12 - x10*y02 + x20*y01;
  94. z21 = x10*y03 - x30*y01 - x00*y13;
  95. z11 = x00*y23 - x20*y03 + x30*y02;
  96. z01 = x20*y13 - x30*y12 - x10*y23;
  97. /* multiply all 3x3 cofactors by reciprocal */
  98. inverse->_11 = (float)(z00*rcp);
  99. inverse->_21 = (float)(z01*rcp);
  100. inverse->_12 = (float)(z10*rcp);
  101. inverse->_31 = (float)(z02*rcp);
  102. inverse->_13 = (float)(z20*rcp);
  103. inverse->_41 = (float)(z03*rcp);
  104. inverse->_14 = (float)(z30*rcp);
  105. inverse->_22 = (float)(z11*rcp);
  106. inverse->_32 = (float)(z12*rcp);
  107. inverse->_23 = (float)(z21*rcp);
  108. inverse->_42 = (float)(z13*rcp);
  109. inverse->_24 = (float)(z31*rcp);
  110. inverse->_33 = (float)(z22*rcp);
  111. inverse->_43 = (float)(z23*rcp);
  112. inverse->_34 = (float)(z32*rcp);
  113. inverse->_44 = (float)(z33*rcp);
  114. return 0;
  115. }
  116. //---------------------------------------------------------------------
  117. #define MATRIX_PRODUCT(res, a, b) \
  118. res->_11 = a->_11*b->_11 + a->_12*b->_21 + a->_13*b->_31 + a->_14*b->_41; \
  119. res->_12 = a->_11*b->_12 + a->_12*b->_22 + a->_13*b->_32 + a->_14*b->_42; \
  120. res->_13 = a->_11*b->_13 + a->_12*b->_23 + a->_13*b->_33 + a->_14*b->_43; \
  121. res->_14 = a->_11*b->_14 + a->_12*b->_24 + a->_13*b->_34 + a->_14*b->_44; \
  122. \
  123. res->_21 = a->_21*b->_11 + a->_22*b->_21 + a->_23*b->_31 + a->_24*b->_41; \
  124. res->_22 = a->_21*b->_12 + a->_22*b->_22 + a->_23*b->_32 + a->_24*b->_42; \
  125. res->_23 = a->_21*b->_13 + a->_22*b->_23 + a->_23*b->_33 + a->_24*b->_43; \
  126. res->_24 = a->_21*b->_14 + a->_22*b->_24 + a->_23*b->_34 + a->_24*b->_44; \
  127. \
  128. res->_31 = a->_31*b->_11 + a->_32*b->_21 + a->_33*b->_31 + a->_34*b->_41; \
  129. res->_32 = a->_31*b->_12 + a->_32*b->_22 + a->_33*b->_32 + a->_34*b->_42; \
  130. res->_33 = a->_31*b->_13 + a->_32*b->_23 + a->_33*b->_33 + a->_34*b->_43; \
  131. res->_34 = a->_31*b->_14 + a->_32*b->_24 + a->_33*b->_34 + a->_34*b->_44; \
  132. \
  133. res->_41 = a->_41*b->_11 + a->_42*b->_21 + a->_43*b->_31 + a->_44*b->_41; \
  134. res->_42 = a->_41*b->_12 + a->_42*b->_22 + a->_43*b->_32 + a->_44*b->_42; \
  135. res->_43 = a->_41*b->_13 + a->_42*b->_23 + a->_43*b->_33 + a->_44*b->_43; \
  136. res->_44 = a->_41*b->_14 + a->_42*b->_24 + a->_43*b->_34 + a->_44*b->_44;
  137. //---------------------------------------------------------------------
  138. // result = a*b
  139. // result is the same as a or b
  140. //
  141. void MatrixProduct2(D3DMATRIX *result, D3DMATRIX *a, D3DMATRIX *b)
  142. {
  143. D3DMATRIX res;
  144. MATRIX_PRODUCT((&res), a, b);
  145. *(D3DMATRIX*)result = res;
  146. }
  147. //---------------------------------------------------------------------
  148. // result = a*b.
  149. // "result" pointer could be equal to "a" or "b"
  150. //
  151. void MatrixProduct(D3DMATRIX *result, D3DMATRIX *a, D3DMATRIX *b)
  152. {
  153. if (result == a || result == b)
  154. {
  155. MatrixProduct2(result, a, b);
  156. return;
  157. }
  158. MATRIX_PRODUCT(result, a, b);
  159. }
  160. ///////////////////////////////////////////////////////////////////////////////
  161. //
  162. ///////////////////////////////////////////////////////////////////////////////
  163. //---------------------------------------------------------------------
  164. // RefVP::UpdateXformData
  165. // Updates transform data used by ProcessVertices
  166. //---------------------------------------------------------------------
  167. HRESULT
  168. RefVP::UpdateXformData()
  169. {
  170. HRESULT hr = D3D_OK;
  171. RDTRANSFORMDATA& TData = m_TransformData;
  172. // Update Mproj*Mclip
  173. if( m_dwDirtyFlags & RDPV_DIRTY_PROJXFM )
  174. {
  175. D3DMATRIX MShift;
  176. ZeroMemory (&MShift, sizeof(D3DMATRIX));
  177. MShift._11 = 0.5f;
  178. MShift._22 = 0.5f;
  179. MShift._41 = 0.5f;
  180. MShift._42 = 0.5f;
  181. MShift._44 = 1.0f;
  182. MShift._33 = 1.0f;
  183. MatrixProduct(&TData.m_PS, &m_xfmProj, &MShift);
  184. }
  185. // Update Mview*Mproj*Mclip
  186. if( m_dwDirtyFlags & (RDPV_DIRTY_VIEWXFM | RDPV_DIRTY_PROJXFM) )
  187. {
  188. MatrixProduct(&TData.m_VPS, &m_xfmView, &TData.m_PS);
  189. Inverse4x4( (D3DMATRIX *)&TData.m_VPS, (D3DMATRIX *)&TData.m_VPSInv );
  190. }
  191. for( DWORD i=0; i< RD_MAX_BLEND_WEIGHTS; i++)
  192. {
  193. MatrixProduct(&m_xfmCurrent[i], &m_xfmWorld[i], &TData.m_VPS);
  194. }
  195. // Compute xfmToEye (world*view) matrix (needed for lighting and fog)
  196. // if needed
  197. if (m_dwDirtyFlags & (RDPV_DIRTY_VIEWXFM |
  198. RDPV_DIRTY_WORLDXFM |
  199. RDPV_DIRTY_WORLD1XFM |
  200. RDPV_DIRTY_WORLD2XFM |
  201. RDPV_DIRTY_WORLD3XFM ))
  202. {
  203. m_dwDirtyFlags |= RDPV_DIRTY_INVERSEWORLDVIEW;
  204. }
  205. if (m_dwTLState & (RDPV_DOLIGHTING | RDPV_DOFOG | RDPV_DOCOMPUTEPOINTSIZE |
  206. RDPV_DOTEXGEN) &&
  207. (m_dwDirtyFlags & RDPV_DIRTY_INVERSEWORLDVIEW))
  208. {
  209. for( i=0; i< RD_MAX_BLEND_WEIGHTS; i++)
  210. {
  211. MatrixProduct(&m_xfmToEye[i], &m_xfmWorld[i], &m_xfmView);
  212. Inverse4x4((D3DMATRIX *)&m_xfmToEye[i],
  213. (D3DMATRIX *)&m_xfmToEyeInv[i]);
  214. m_dwDirtyFlags |= RDPV_DIRTY_NEEDXFMLIGHT;
  215. }
  216. m_dwDirtyFlags &= ~RDPV_DIRTY_INVERSEWORLDVIEW;
  217. }
  218. // Clear the world processed flags
  219. memset( m_WorldProcessed, 0, sizeof( m_WorldProcessed ) );
  220. // Clear the dirty transform flags
  221. m_dwDirtyFlags &= ~RDPV_DIRTY_XFORM;
  222. return hr;
  223. }
  224. void
  225. RefVP::UpdateWorld( DWORD i )
  226. {
  227. RDTRANSFORMDATA& TData = m_TransformData;
  228. if( m_WorldProcessed[i] == TRUE ) return;
  229. MatrixProduct(&m_xfmCurrent[i], &m_xfmWorld[i], &TData.m_VPS);
  230. if (m_dwTLState & (RDPV_DOLIGHTING | RDPV_DOFOG | RDPV_DOCOMPUTEPOINTSIZE |
  231. RDPV_DOTEXGEN))
  232. {
  233. MatrixProduct(&m_xfmToEye[i], &m_xfmWorld[i], &m_xfmView);
  234. Inverse4x4((D3DMATRIX *)&m_xfmToEye[i],
  235. (D3DMATRIX *)&m_xfmToEyeInv[i]);
  236. }
  237. m_WorldProcessed[i] = TRUE;
  238. }