home *** CD-ROM | disk | FTP | other *** search
- // DXHELP3.cpp : Contains routines shared by multiple 3D effects
- #include "stdafx.h"
- #include "dxhelp3.h"
- #include <malloc.h>
- #include <math.h>
- #include <stdio.h>
-
- void Rotate::Set(D3DVECTOR d3dvctrNormal, double dAngle)
- {
- #ifdef _DEBUG
- float NormalSum = d3dvctrNormal.x * d3dvctrNormal.x +
- d3dvctrNormal.y * d3dvctrNormal.y +
- d3dvctrNormal.z * d3dvctrNormal.z;
- _ASSERT(NormalSum == 0.0f || (0.99f < NormalSum && NormalSum < 1.01f));
- #endif
-
- // The following transformation matrix routines are from
- // Graphics Gems (the first one) page 466 (Converting
- // between Matrix and Axis-Amount Representations)
- float s = (float)sin(dAngle), c = (float)cos(dAngle);
- float t = 1.0f - c;
-
- m_d3dvctrXComponent.x = t * d3dvctrNormal.x * d3dvctrNormal.x + c;
- m_d3dvctrXComponent.y = t * d3dvctrNormal.x * d3dvctrNormal.y - s * d3dvctrNormal.z;
- m_d3dvctrXComponent.z = t * d3dvctrNormal.x * d3dvctrNormal.z + s * d3dvctrNormal.y;
-
- m_d3dvctrYComponent.x = t * d3dvctrNormal.x * d3dvctrNormal.y + s * d3dvctrNormal.z;
- m_d3dvctrYComponent.y = t * d3dvctrNormal.y * d3dvctrNormal.y + c;
- m_d3dvctrYComponent.z = t * d3dvctrNormal.y * d3dvctrNormal.z - s * d3dvctrNormal.x;
-
- m_d3dvctrZComponent.x = t * d3dvctrNormal.x * d3dvctrNormal.z - s * d3dvctrNormal.y;
- m_d3dvctrZComponent.y = t * d3dvctrNormal.y * d3dvctrNormal.z + s * d3dvctrNormal.x;
- m_d3dvctrZComponent.z = t * d3dvctrNormal.z * d3dvctrNormal.z + c;
- }
-
- static HRESULT DecoupleOneMeshBuilder(void *lpThis /* Ignored */,
- IDirect3DRMMeshBuilder3 *lpMeshBuilderOut,
- IDirect3DRMMeshBuilder3 *lpMeshBuilderIn)
- {
- HRESULT hr = lpMeshBuilderOut->SetAppData(lpMeshBuilderIn->GetAppData());
-
- if(FAILED(hr))
- {
- return hr;
- }
-
- const int ciOutputFaceCount = lpMeshBuilderOut->GetFaceCount();
- const int ciMaxFaceCount = lpMeshBuilderIn->GetFaceCount();
- if(!ciMaxFaceCount)
- {
- return hr;
- }
- CComPtr<IDirect3DRMFaceArray> cpD3DRMFaceArray;
-
- hr = lpMeshBuilderIn->GetFaces(&cpD3DRMFaceArray);
- if(hr != D3DRM_OK)
- {
- return hr;
- }
-
- D3DVECTOR *lpvctrPosition = NULL;
- D3DVECTOR *lpvctrFaceNormals = NULL;
- DWORD dwMaxVertexCount = 0;
-
- // By reserving space we speed things up by a factor of 20 or 30 X!
-
- DWORD dwTotalVertexCount = lpMeshBuilderIn->GetVertexCount();
- _ASSERT(dwTotalVertexCount >= 3);
- if (dwTotalVertexCount/ciMaxFaceCount < 3)
- {
- dwTotalVertexCount = ciMaxFaceCount * 3; // There will be at least 3 vertices per face.
- }
- hr = lpMeshBuilderOut->ReserveSpace(dwTotalVertexCount, dwTotalVertexCount, ciMaxFaceCount);
-
- if(hr != D3DRM_OK)
- {
- return hr;
- }
-
- // Need to have seperate vertices for each face in the output mesh.
- int iFaceIndex = 0;
- do
- {
- CComPtr<IDirect3DRMFace> cpd3dInFaceTemp;
- CComPtr<IDirect3DRMFace2> cpd3dOutFace;
-
- if(FAILED(hr = cpD3DRMFaceArray->GetElement((DWORD)iFaceIndex, &cpd3dInFaceTemp)))
- {
- break;
- }
- _ASSERT(cpd3dInFaceTemp);
-
- CComPtr<IDirect3DRMFace2> cpd3dInFace;
- if(FAILED(hr = cpd3dInFaceTemp->QueryInterface(
- IID_IDirect3DRMFace2, (void **)&cpd3dInFace)))
- {
- break;
- }
-
- DWORD dwVertexCount;
-
- cpd3dInFace->GetVertices(&dwVertexCount, NULL, NULL);
- _ASSERT(dwVertexCount >= 3);
-
- if(dwVertexCount > dwMaxVertexCount)
- {
- dwMaxVertexCount = dwVertexCount;
-
- D3DVECTOR *lpTemp = lpvctrPosition;
- D3DVECTOR *lpNormalTemp = lpvctrFaceNormals;
-
- lpvctrPosition = (D3DVECTOR *)realloc(lpvctrPosition, dwMaxVertexCount * sizeof (*lpvctrPosition));
- lpvctrFaceNormals = (D3DVECTOR *)realloc(lpvctrFaceNormals, dwMaxVertexCount * sizeof (*lpvctrFaceNormals));
-
- if(!lpvctrPosition || !lpvctrFaceNormals)
- {
- free(lpTemp);
- free(lpNormalTemp);
- hr = E_OUTOFMEMORY;
- break;
- }
-
- // We may have a problem in the amount of space reserved in the output meshbuilder.
- if((ciMaxFaceCount - iFaceIndex) * dwMaxVertexCount > dwTotalVertexCount)
- {
- dwTotalVertexCount = (ciMaxFaceCount - iFaceIndex) * dwMaxVertexCount;
- hr = lpMeshBuilderOut->ReserveSpace(dwTotalVertexCount, dwTotalVertexCount, ciMaxFaceCount - iFaceIndex);
-
- if(hr != D3DRM_OK)
- {
- break;
- }
- }
- }
-
- if(FAILED(hr = cpd3dInFace->GetVertices(&dwVertexCount, lpvctrPosition, lpvctrFaceNormals)) ||
- FAILED(hr = lpMeshBuilderOut->CreateFace(&cpd3dOutFace)) ||
- FAILED(hr = cpd3dOutFace->SetAppData(cpd3dInFace->GetAppData())))
- {
- break;
- }
-
-
- CComPtr<IDirect3DRMMaterial2> cpMaterial;
- CComPtr<IDirect3DRMTexture3> cpTexture;
- BOOL bU, bV;
-
- if(hr != D3DRM_OK ||
- (hr = cpd3dInFace->GetMaterial(&cpMaterial)) != D3DRM_OK ||
- (hr = cpd3dOutFace->SetMaterial(cpMaterial)) != D3DRM_OK ||
- (hr = cpd3dOutFace->SetColor(cpd3dInFace->GetColor())) != D3DRM_OK ||
- (hr = cpd3dInFace->GetTexture(&cpTexture)) != D3DRM_OK ||
- (hr = cpd3dOutFace->SetTexture(cpTexture)) != D3DRM_OK ||
- (hr = cpd3dInFace->GetTextureTopology(&bU, &bV)) != D3DRM_OK ||
- (hr = cpd3dOutFace->SetTextureTopology(bU, bV)) != D3DRM_OK)
- {
- break;
- }
-
- DWORD dwInFaceVertex = 0;
- do
- {
- int iVIndex = lpMeshBuilderOut->AddVertex(lpvctrPosition[dwInFaceVertex].x,
- lpvctrPosition[dwInFaceVertex].y,
- lpvctrPosition[dwInFaceVertex].z);
- int iNIndex = lpMeshBuilderOut->AddNormal(lpvctrFaceNormals[dwInFaceVertex].x,
- lpvctrFaceNormals[dwInFaceVertex].y,
- lpvctrFaceNormals[dwInFaceVertex].z);
-
- D3DVALUE U, V;
-
- if(FAILED(hr = cpd3dOutFace->AddVertexAndNormalIndexed(iVIndex, iNIndex)) ||
- FAILED(hr = cpd3dInFace->GetTextureCoordinates(dwInFaceVertex, &U, &V)) ||
- FAILED(hr = cpd3dOutFace->SetTextureCoordinates(dwInFaceVertex, U, V)))
- {
- break;
- }
- } while (++dwInFaceVertex < dwVertexCount);
- dwTotalVertexCount -= dwVertexCount;
- } while (hr == D3DRM_OK && ++iFaceIndex < ciMaxFaceCount);
-
- free(lpvctrPosition);
- free(lpvctrFaceNormals);
-
- return hr;
- }
-
- HRESULT TraverseSubMeshes( HRESULT (*lpCallBack)(void *lpThis,
- IDirect3DRMMeshBuilder3* lpOut,
- IDirect3DRMMeshBuilder3* lpIn),
- void *lpThis,
- IDirect3DRMMeshBuilder3* lpMeshBuilderOut,
- IDirect3DRMMeshBuilder3* lpMeshBuilderIn)
- {
- HRESULT hr;
-
- _ASSERT(lpCallBack);
- if(FAILED(hr = (*lpCallBack)(lpThis, lpMeshBuilderOut, lpMeshBuilderIn)))
- return hr;
-
- DWORD dwInSubMeshCount;
- hr = lpMeshBuilderIn->GetSubMeshes(&dwInSubMeshCount, NULL);
-
- if(FAILED(hr) || dwInSubMeshCount == 0)
- return hr;
-
- DWORD dwOutSubMeshCount;
- if(FAILED(hr = lpMeshBuilderOut->GetSubMeshes(&dwOutSubMeshCount, NULL)))
- {
- return hr;
- }
-
- const BOOL bCreateOutMeshes = (dwOutSubMeshCount == 0);
- _ASSERT(bCreateOutMeshes || dwInSubMeshCount == dwOutSubMeshCount);
-
- LPUNKNOWN *lplpunkInSubMeshes =
- (LPUNKNOWN *)malloc(dwInSubMeshCount * sizeof(*lplpunkInSubMeshes));
-
- LPUNKNOWN *lplpunkOutSubMeshes = (bCreateOutMeshes? NULL:
- (LPUNKNOWN *)malloc(dwOutSubMeshCount * sizeof(*lplpunkOutSubMeshes)));
-
- if(!lplpunkInSubMeshes || !bCreateOutMeshes && !lplpunkOutSubMeshes)
- {
- return E_OUTOFMEMORY;
- }
-
- if(FAILED(hr = lpMeshBuilderIn->GetSubMeshes(&dwInSubMeshCount, lplpunkInSubMeshes)) ||
- !bCreateOutMeshes &&
- FAILED(hr = lpMeshBuilderOut->GetSubMeshes(&dwOutSubMeshCount, lplpunkOutSubMeshes)))
- {
- return hr;
- }
-
- CComPtr<IDirect3DRMMeshBuilder3> cpInSubMesh, cpOutSubMesh;
-
- DWORD dwSubMesh;
- for(dwSubMesh = 0; SUCCEEDED(hr) && dwSubMesh < dwInSubMeshCount; dwSubMesh++)
- {
- cpInSubMesh = NULL;
- cpOutSubMesh = NULL;
-
- // Get the current input submesh.
- hr = lplpunkInSubMeshes[dwSubMesh]->QueryInterface(IID_IDirect3DRMMeshBuilder3,
- (void **)&cpInSubMesh);
-
- if(FAILED(hr))
- break;
-
- if(bCreateOutMeshes)
- {
- // Create a new submesh in the output mesh to match the input submesh.
- LPUNKNOWN lpunkSubmesh;
-
- if(FAILED(hr = lpMeshBuilderOut->CreateSubMesh(&lpunkSubmesh)))
- break;
-
- hr = lpunkSubmesh->QueryInterface(IID_IDirect3DRMMeshBuilder3,
- (void **)&cpOutSubMesh);
- lpunkSubmesh->Release();
- }
- else
- {
- // Get the current output submesh.
- hr = lplpunkOutSubMeshes[dwSubMesh]->QueryInterface(IID_IDirect3DRMMeshBuilder3,
- (void **)&cpOutSubMesh);
- }
- if(FAILED(hr))
- break;
-
- // Do all the children for these two MeshBuilders.
- hr = TraverseSubMeshes(lpCallBack, lpThis, cpOutSubMesh, cpInSubMesh);
- }
-
- for(dwSubMesh = 0; dwSubMesh < dwInSubMeshCount; dwSubMesh++)
- {
- lplpunkInSubMeshes[dwSubMesh]->Release();
-
- if(lplpunkOutSubMeshes)
- {
- lplpunkOutSubMeshes[dwSubMesh]->Release();
- }
- }
-
- free(lplpunkInSubMeshes);
- free(lplpunkOutSubMeshes);
-
- return hr;
- }
-
- HRESULT DecoupleVertices(IDirect3DRMMeshBuilder3* lpMeshBuilderOut,
- IDirect3DRMMeshBuilder3* lpMeshBuilderIn)
- {
- DWORD dwSubMeshCount;
-
- HRESULT hr = lpMeshBuilderOut->GetSubMeshes(&dwSubMeshCount, NULL);
-
- if(FAILED(hr))
- return hr;
-
- if(lpMeshBuilderOut->GetFaceCount() || dwSubMeshCount)
- {
- if(FAILED(hr = lpMeshBuilderOut->Empty(0)))
- return hr;
- }
- hr = TraverseSubMeshes(DecoupleOneMeshBuilder, NULL,
- lpMeshBuilderOut, lpMeshBuilderIn);
- return hr;
- }
-
- float GetDlgItemFloat(HWND hDlg, int id)
- {
- TCHAR *pEnd;
- TCHAR szItemText[20];
- GetDlgItemText(hDlg, id, szItemText, 20);
- return (float)strtod(szItemText, &pEnd);
- }
-
- BOOL SetDlgItemFloat( HWND hDlg, int id, float f )
- {
- TCHAR szItem[20];
- _stprintf( szItem, _T("%.2f"), f );
- return SetDlgItemText( hDlg, id, szItem );
- }
-
- double GetDlgItemDouble(HWND hDlg, int id)
- {
- TCHAR *pEnd;
- TCHAR szItemText[20];
- GetDlgItemText(hDlg, id, szItemText, 20);
- return strtod(szItemText, &pEnd);
- }
-
- BOOL SetDlgItemDouble( HWND hDlg, int id, double d )
- {
- TCHAR szItem[20];
- _stprintf( szItem, _T("%.2d"), d );
- return SetDlgItemText( hDlg, id, szItem );
- }
-
-