0001:
0002: #include <assert.h>
0003: #include "D3DFile.h"
0004: #include "DXUtil.h"
0005: #include "CShadowVolume.h"
0006:
0007:
0008:
0009:
0010: const DWORD CShadowVolume::FVF = D3DFVF_XYZ | D3DFVF_NORMAL;
0011:
0012:
0013: CShadowVolume::CShadowVolume()
0014: {
0015: m_pVertices = NULL;
0016: m_dwNumFaces = 0;
0017: }
0018:
0019: CShadowVolume::~CShadowVolume()
0020: {
0021: }
0022:
0023:
0024:
0025: VOID CShadowVolume::Render( LPDIRECT3DDEVICE9 pd3dDevice )
0026: {
0027: pd3dDevice->SetFVF( CShadowVolume::FVF );
0028:
0029: pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, m_dwNumFaces,
0030: m_pVertices, sizeof(SHADOW_VOLUME_VERTEX) );
0031: }
0032:
0033:
0034:
0035: HRESULT CShadowVolume::Create( LPDIRECT3DDEVICE9 pd3dDevice, LPD3DXMESH pSrcMesh )
0036: {
0037: HRESULT ret = S_OK;
0038: struct MESHVERTEX { D3DXVECTOR3 p, n; };
0039: SHADOW_VOLUME_VERTEX* pVertices;
0040: WORD* pIndices;
0041: DWORD i,j,k,l, face;
0042: LPD3DXMESH pMesh;
0043:
0044: if( FAILED( pSrcMesh->CloneMeshFVF( D3DXMESH_SYSTEMMEM,
0045: D3DFVF_XYZ | D3DFVF_NORMAL,
0046: pd3dDevice, &pMesh ) ) )
0047: return E_FAIL;
0048: DWORD dwNumFaces = pMesh->GetNumFaces();
0049:
0050:
0051: m_dwNumFaces = 4*dwNumFaces;
0052: m_pVertices = new SHADOW_VOLUME_VERTEX[3*m_dwNumFaces];
0053:
0054:
0055: pMesh->LockVertexBuffer( 0L, (LPVOID*)&pVertices );
0056: pMesh->LockIndexBuffer ( 0L, (LPVOID*)&pIndices );
0057:
0058:
0059: D3DXVECTOR3 *vNormal = new D3DXVECTOR3[dwNumFaces];
0060: if(NULL==vNormal){
0061: m_dwNumFaces = 0;
0062: ret = E_OUTOFMEMORY;
0063: goto end;
0064: }
0065:
0066: for( i=0; i<dwNumFaces; i++ )
0067: {
0068: D3DXVECTOR3 v0 = pVertices[pIndices[3*i+0]].p;
0069: D3DXVECTOR3 v1 = pVertices[pIndices[3*i+1]].p;
0070: D3DXVECTOR3 v2 = pVertices[pIndices[3*i+2]].p;
0071:
0072: D3DXVECTOR3 vCross1(v1-v0);
0073: D3DXVECTOR3 vCross2(v2-v1);
0074: D3DXVec3Cross( &vNormal[i], &vCross1, &vCross2 );
0075:
0076: m_pVertices[3*i+0].p = v0;
0077: m_pVertices[3*i+1].p = v1;
0078: m_pVertices[3*i+2].p = v2;
0079: m_pVertices[3*i+0].n = vNormal[i];
0080: m_pVertices[3*i+1].n = vNormal[i];
0081: m_pVertices[3*i+2].n = vNormal[i];
0082: }
0083:
0084:
0085: face = dwNumFaces;
0086: for( i=0 ; i<dwNumFaces; i++ ){
0087: for( j=i+1; j<dwNumFaces; j++ ){
0088: DWORD id[2][2];
0089: DWORD cnt=0;
0090: for(k=0;k<3;k++){
0091: for(l=0;l<3;l++){
0092: D3DXVECTOR3 dv;
0093: D3DXVec3Subtract( &dv, &pVertices[pIndices[3*i+k]].p,
0094: &pVertices[pIndices[3*j+l]].p);
0095: if( D3DXVec3LengthSq( &dv ) < 0.001f ){
0096:
0097: id[cnt][0] = 3*i+k;
0098: id[cnt][1] = 3*j+l;
0099: cnt++;
0100: }
0101: }
0102: }
0103: if(2==cnt){
0104:
0105: if(id[1][0]-id[0][0]!=1){
0106:
0107: DWORD tmp = id[0][0];
0108: id[0][0] = id[1][0];
0109: id[1][0] = tmp;
0110: tmp = id[0][1];
0111: id[0][1] = id[1][1];
0112: id[1][1] = tmp;
0113: }
0114:
0115: m_pVertices[3*face+0].p = pVertices[pIndices[id[1][0]]].p;
0116: m_pVertices[3*face+2].p = pVertices[pIndices[id[0][1]]].p;
0117: m_pVertices[3*face+1].p = pVertices[pIndices[id[0][0]]].p;
0118: m_pVertices[3*face+0].n = vNormal[i];
0119: m_pVertices[3*face+2].n = vNormal[j];
0120: m_pVertices[3*face+1].n = vNormal[i];
0121: face++;
0122: m_pVertices[3*face+0].p = pVertices[pIndices[id[1][0]]].p;
0123: m_pVertices[3*face+2].p = pVertices[pIndices[id[1][1]]].p;
0124: m_pVertices[3*face+1].p = pVertices[pIndices[id[0][1]]].p;
0125: m_pVertices[3*face+0].n = vNormal[i];
0126: m_pVertices[3*face+2].n = vNormal[j];
0127: m_pVertices[3*face+1].n = vNormal[j];
0128: face++;
0129: }
0130: }
0131: }
0132: assert(face == m_dwNumFaces);
0133: m_dwNumFaces=face;
0134:
0135: delete[] vNormal;
0136: end:
0137:
0138: pMesh->UnlockVertexBuffer();
0139: pMesh->UnlockIndexBuffer();
0140:
0141: pMesh->Release();
0142:
0143: return ret;
0144: }
0145:
0146:
0147:
0148: VOID CShadowVolume::Destroy()
0149: {
0150: SAFE_DELETE_ARRAY( m_pVertices );
0151: m_dwNumFaces = 0;
0152: }
0153:
0154: