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.

338 lines
10 KiB

  1. // DXHELP3.cpp : Contains routines shared by multiple 3D effects
  2. #include "dxhelp3.h"
  3. #include <malloc.h>
  4. #include <math.h>
  5. #include <stdio.h>
  6. void Rotate::Set(D3DVECTOR d3dvctrNormal, double dAngle)
  7. {
  8. #ifdef _DEBUG
  9. float NormalSum = d3dvctrNormal.x * d3dvctrNormal.x +
  10. d3dvctrNormal.y * d3dvctrNormal.y +
  11. d3dvctrNormal.z * d3dvctrNormal.z;
  12. _ASSERT(NormalSum == 0.0f || (0.99f < NormalSum && NormalSum < 1.01f));
  13. #endif
  14. // The following transformation matrix routines are from
  15. // Graphics Gems (the first one) page 466 (Converting
  16. // between Matrix and Axis-Amount Representations)
  17. float s = (float)sin(dAngle), c = (float)cos(dAngle);
  18. float t = 1.0f - c;
  19. m_d3dvctrXComponent.x = t * d3dvctrNormal.x * d3dvctrNormal.x + c;
  20. m_d3dvctrXComponent.y = t * d3dvctrNormal.x * d3dvctrNormal.y - s * d3dvctrNormal.z;
  21. m_d3dvctrXComponent.z = t * d3dvctrNormal.x * d3dvctrNormal.z + s * d3dvctrNormal.y;
  22. m_d3dvctrYComponent.x = t * d3dvctrNormal.x * d3dvctrNormal.y + s * d3dvctrNormal.z;
  23. m_d3dvctrYComponent.y = t * d3dvctrNormal.y * d3dvctrNormal.y + c;
  24. m_d3dvctrYComponent.z = t * d3dvctrNormal.y * d3dvctrNormal.z - s * d3dvctrNormal.x;
  25. m_d3dvctrZComponent.x = t * d3dvctrNormal.x * d3dvctrNormal.z - s * d3dvctrNormal.y;
  26. m_d3dvctrZComponent.y = t * d3dvctrNormal.y * d3dvctrNormal.z + s * d3dvctrNormal.x;
  27. m_d3dvctrZComponent.z = t * d3dvctrNormal.z * d3dvctrNormal.z + c;
  28. }
  29. static HRESULT DecoupleOneMeshBuilder(void *lpThis /* Ignored */,
  30. IDirect3DRMMeshBuilder3 *lpMeshBuilderOut,
  31. IDirect3DRMMeshBuilder3 *lpMeshBuilderIn)
  32. {
  33. HRESULT hr = lpMeshBuilderOut->SetAppData(lpMeshBuilderIn->GetAppData());
  34. if(FAILED(hr))
  35. {
  36. return hr;
  37. }
  38. const int ciOutputFaceCount = lpMeshBuilderOut->GetFaceCount();
  39. const int ciMaxFaceCount = lpMeshBuilderIn->GetFaceCount();
  40. if(!ciMaxFaceCount)
  41. {
  42. return hr;
  43. }
  44. CComPtr<IDirect3DRMFaceArray> cpD3DRMFaceArray;
  45. hr = lpMeshBuilderIn->GetFaces(&cpD3DRMFaceArray);
  46. if(hr != D3DRM_OK)
  47. {
  48. return hr;
  49. }
  50. D3DVECTOR *lpvctrPosition = NULL;
  51. D3DVECTOR *lpvctrFaceNormals = NULL;
  52. DWORD dwMaxVertexCount = 0;
  53. // By reserving space we speed things up by a factor of 20 or 30 X!
  54. DWORD dwTotalVertexCount = lpMeshBuilderIn->GetVertexCount();
  55. _ASSERT(dwTotalVertexCount >= 3);
  56. if (dwTotalVertexCount/ciMaxFaceCount < 3)
  57. {
  58. dwTotalVertexCount = ciMaxFaceCount * 3; // There will be at least 3 vertices per face.
  59. }
  60. hr = lpMeshBuilderOut->ReserveSpace(dwTotalVertexCount, dwTotalVertexCount, ciMaxFaceCount);
  61. if(hr != D3DRM_OK)
  62. {
  63. return hr;
  64. }
  65. // Need to have seperate vertices for each face in the output mesh.
  66. int iFaceIndex = 0;
  67. do
  68. {
  69. CComPtr<IDirect3DRMFace> cpd3dInFaceTemp;
  70. CComPtr<IDirect3DRMFace2> cpd3dOutFace;
  71. if(FAILED(hr = cpD3DRMFaceArray->GetElement((DWORD)iFaceIndex, &cpd3dInFaceTemp)))
  72. {
  73. break;
  74. }
  75. _ASSERT(cpd3dInFaceTemp);
  76. CComPtr<IDirect3DRMFace2> cpd3dInFace;
  77. if(FAILED(hr = cpd3dInFaceTemp->QueryInterface(
  78. IID_IDirect3DRMFace2, (void **)&cpd3dInFace)))
  79. {
  80. break;
  81. }
  82. DWORD dwVertexCount;
  83. cpd3dInFace->GetVertices(&dwVertexCount, NULL, NULL);
  84. _ASSERT(dwVertexCount >= 3);
  85. if(dwVertexCount > dwMaxVertexCount)
  86. {
  87. dwMaxVertexCount = dwVertexCount;
  88. D3DVECTOR *lpTemp = lpvctrPosition;
  89. D3DVECTOR *lpNormalTemp = lpvctrFaceNormals;
  90. lpvctrPosition = (D3DVECTOR *)realloc(lpvctrPosition, dwMaxVertexCount * sizeof (*lpvctrPosition));
  91. lpvctrFaceNormals = (D3DVECTOR *)realloc(lpvctrFaceNormals, dwMaxVertexCount * sizeof (*lpvctrFaceNormals));
  92. if(!lpvctrPosition || !lpvctrFaceNormals)
  93. {
  94. free(lpTemp);
  95. free(lpNormalTemp);
  96. hr = E_OUTOFMEMORY;
  97. break;
  98. }
  99. // We may have a problem in the amount of space reserved in the output meshbuilder.
  100. if((ciMaxFaceCount - iFaceIndex) * dwMaxVertexCount > dwTotalVertexCount)
  101. {
  102. dwTotalVertexCount = (ciMaxFaceCount - iFaceIndex) * dwMaxVertexCount;
  103. hr = lpMeshBuilderOut->ReserveSpace(dwTotalVertexCount, dwTotalVertexCount, ciMaxFaceCount - iFaceIndex);
  104. if(hr != D3DRM_OK)
  105. {
  106. break;
  107. }
  108. }
  109. }
  110. if(FAILED(hr = cpd3dInFace->GetVertices(&dwVertexCount, lpvctrPosition, lpvctrFaceNormals)) ||
  111. FAILED(hr = lpMeshBuilderOut->CreateFace(&cpd3dOutFace)) ||
  112. FAILED(hr = cpd3dOutFace->SetAppData(cpd3dInFace->GetAppData())))
  113. {
  114. break;
  115. }
  116. CComPtr<IDirect3DRMMaterial2> cpMaterial;
  117. CComPtr<IDirect3DRMTexture3> cpTexture;
  118. BOOL bU, bV;
  119. if(hr != D3DRM_OK ||
  120. (hr = cpd3dInFace->GetMaterial(&cpMaterial)) != D3DRM_OK ||
  121. (hr = cpd3dOutFace->SetMaterial(cpMaterial)) != D3DRM_OK ||
  122. (hr = cpd3dOutFace->SetColor(cpd3dInFace->GetColor())) != D3DRM_OK ||
  123. (hr = cpd3dInFace->GetTexture(&cpTexture)) != D3DRM_OK ||
  124. (hr = cpd3dOutFace->SetTexture(cpTexture)) != D3DRM_OK ||
  125. (hr = cpd3dInFace->GetTextureTopology(&bU, &bV)) != D3DRM_OK ||
  126. (hr = cpd3dOutFace->SetTextureTopology(bU, bV)) != D3DRM_OK)
  127. {
  128. break;
  129. }
  130. DWORD dwInFaceVertex = 0;
  131. do
  132. {
  133. int iVIndex = lpMeshBuilderOut->AddVertex(lpvctrPosition[dwInFaceVertex].x,
  134. lpvctrPosition[dwInFaceVertex].y,
  135. lpvctrPosition[dwInFaceVertex].z);
  136. int iNIndex = lpMeshBuilderOut->AddNormal(lpvctrFaceNormals[dwInFaceVertex].x,
  137. lpvctrFaceNormals[dwInFaceVertex].y,
  138. lpvctrFaceNormals[dwInFaceVertex].z);
  139. D3DVALUE U, V;
  140. if(FAILED(hr = cpd3dOutFace->AddVertexAndNormalIndexed(iVIndex, iNIndex)) ||
  141. FAILED(hr = cpd3dInFace->GetTextureCoordinates(dwInFaceVertex, &U, &V)) ||
  142. FAILED(hr = cpd3dOutFace->SetTextureCoordinates(dwInFaceVertex, U, V)))
  143. {
  144. break;
  145. }
  146. } while (++dwInFaceVertex < dwVertexCount);
  147. dwTotalVertexCount -= dwVertexCount;
  148. } while (hr == D3DRM_OK && ++iFaceIndex < ciMaxFaceCount);
  149. free(lpvctrPosition);
  150. free(lpvctrFaceNormals);
  151. return hr;
  152. }
  153. HRESULT TraverseSubMeshes( HRESULT (*lpCallBack)(void *lpThis,
  154. IDirect3DRMMeshBuilder3* lpOut,
  155. IDirect3DRMMeshBuilder3* lpIn),
  156. void *lpThis,
  157. IDirect3DRMMeshBuilder3* lpMeshBuilderOut,
  158. IDirect3DRMMeshBuilder3* lpMeshBuilderIn)
  159. {
  160. HRESULT hr;
  161. _ASSERT(lpCallBack);
  162. if(FAILED(hr = (*lpCallBack)(lpThis, lpMeshBuilderOut, lpMeshBuilderIn)))
  163. return hr;
  164. DWORD dwInSubMeshCount;
  165. hr = lpMeshBuilderIn->GetSubMeshes(&dwInSubMeshCount, NULL);
  166. if(FAILED(hr) || dwInSubMeshCount == 0)
  167. return hr;
  168. DWORD dwOutSubMeshCount;
  169. if(FAILED(hr = lpMeshBuilderOut->GetSubMeshes(&dwOutSubMeshCount, NULL)))
  170. {
  171. return hr;
  172. }
  173. const BOOL bCreateOutMeshes = (dwOutSubMeshCount == 0);
  174. _ASSERT(bCreateOutMeshes || dwInSubMeshCount == dwOutSubMeshCount);
  175. LPUNKNOWN *lplpunkInSubMeshes =
  176. (LPUNKNOWN *)malloc(dwInSubMeshCount * sizeof(*lplpunkInSubMeshes));
  177. LPUNKNOWN *lplpunkOutSubMeshes = (bCreateOutMeshes? NULL:
  178. (LPUNKNOWN *)malloc(dwOutSubMeshCount * sizeof(*lplpunkOutSubMeshes)));
  179. if(!lplpunkInSubMeshes || !bCreateOutMeshes && !lplpunkOutSubMeshes)
  180. {
  181. return E_OUTOFMEMORY;
  182. }
  183. if(FAILED(hr = lpMeshBuilderIn->GetSubMeshes(&dwInSubMeshCount, lplpunkInSubMeshes)) ||
  184. !bCreateOutMeshes &&
  185. FAILED(hr = lpMeshBuilderOut->GetSubMeshes(&dwOutSubMeshCount, lplpunkOutSubMeshes)))
  186. {
  187. return hr;
  188. }
  189. CComPtr<IDirect3DRMMeshBuilder3> cpInSubMesh, cpOutSubMesh;
  190. DWORD dwSubMesh;
  191. for(dwSubMesh = 0; SUCCEEDED(hr) && dwSubMesh < dwInSubMeshCount; dwSubMesh++)
  192. {
  193. cpInSubMesh = NULL;
  194. cpOutSubMesh = NULL;
  195. // Get the current input submesh.
  196. hr = lplpunkInSubMeshes[dwSubMesh]->QueryInterface(IID_IDirect3DRMMeshBuilder3,
  197. (void **)&cpInSubMesh);
  198. if(FAILED(hr))
  199. break;
  200. if(bCreateOutMeshes)
  201. {
  202. // Create a new submesh in the output mesh to match the input submesh.
  203. LPUNKNOWN lpunkSubmesh;
  204. if(FAILED(hr = lpMeshBuilderOut->CreateSubMesh(&lpunkSubmesh)))
  205. break;
  206. hr = lpunkSubmesh->QueryInterface(IID_IDirect3DRMMeshBuilder3,
  207. (void **)&cpOutSubMesh);
  208. lpunkSubmesh->Release();
  209. }
  210. else
  211. {
  212. // Get the current output submesh.
  213. hr = lplpunkOutSubMeshes[dwSubMesh]->QueryInterface(IID_IDirect3DRMMeshBuilder3,
  214. (void **)&cpOutSubMesh);
  215. }
  216. if(FAILED(hr))
  217. break;
  218. // Do all the children for these two MeshBuilders.
  219. hr = TraverseSubMeshes(lpCallBack, lpThis, cpOutSubMesh, cpInSubMesh);
  220. }
  221. for(dwSubMesh = 0; dwSubMesh < dwInSubMeshCount; dwSubMesh++)
  222. {
  223. lplpunkInSubMeshes[dwSubMesh]->Release();
  224. if(lplpunkOutSubMeshes)
  225. {
  226. lplpunkOutSubMeshes[dwSubMesh]->Release();
  227. }
  228. }
  229. free(lplpunkInSubMeshes);
  230. free(lplpunkOutSubMeshes);
  231. return hr;
  232. }
  233. HRESULT DecoupleVertices(IDirect3DRMMeshBuilder3* lpMeshBuilderOut,
  234. IDirect3DRMMeshBuilder3* lpMeshBuilderIn)
  235. {
  236. DWORD dwSubMeshCount;
  237. HRESULT hr = lpMeshBuilderOut->GetSubMeshes(&dwSubMeshCount, NULL);
  238. if(FAILED(hr))
  239. return hr;
  240. if(lpMeshBuilderOut->GetFaceCount() || dwSubMeshCount)
  241. {
  242. if(FAILED(hr = lpMeshBuilderOut->Empty(0)))
  243. return hr;
  244. }
  245. hr = TraverseSubMeshes(DecoupleOneMeshBuilder, NULL,
  246. lpMeshBuilderOut, lpMeshBuilderIn);
  247. return hr;
  248. }
  249. float GetDlgItemFloat(HWND hDlg, int id)
  250. {
  251. TCHAR *pEnd;
  252. TCHAR szItemText[20];
  253. GetDlgItemText(hDlg, id, szItemText, 20);
  254. return (float)strtod(szItemText, &pEnd);
  255. }
  256. BOOL SetDlgItemFloat( HWND hDlg, int id, float f )
  257. {
  258. TCHAR szItem[20];
  259. _stprintf( szItem, _T("%.2f"), f );
  260. return SetDlgItemText( hDlg, id, szItem );
  261. }
  262. double GetDlgItemDouble(HWND hDlg, int id)
  263. {
  264. TCHAR *pEnd;
  265. TCHAR szItemText[20];
  266. GetDlgItemText(hDlg, id, szItemText, 20);
  267. return strtod(szItemText, &pEnd);
  268. }
  269. BOOL SetDlgItemDouble( HWND hDlg, int id, double d )
  270. {
  271. TCHAR szItem[20];
  272. _stprintf( szItem, _T("%.2d"), d );
  273. return SetDlgItemText( hDlg, id, szItem );
  274. }