//----------------------------------------------------------------------------- // Name: // Desc: //----------------------------------------------------------------------------- VOID CMyD3DApplication::ComputeTangentsAndBinormals() { EMBOSSVERTEX* pVertices; WORD* pIndices; DWORD dwNumVertices; DWORD dwNumIndices; // Gain access to the object's vertex and index buffers LPDIRECT3DVERTEXBUFFER8 pVB; m_pObject->GetSysMemMesh()->GetVertexBuffer( &pVB ); pVB->Lock( 0, 0, (BYTE**)&pVertices, 0 ); dwNumVertices = m_pObject->GetSysMemMesh()->GetNumVertices(); LPDIRECT3DINDEXBUFFER8 pIB; m_pObject->GetSysMemMesh()->GetIndexBuffer( &pIB ); pIB->Lock( 0, 0, (BYTE**)&pIndices, 0 ); dwNumIndices = m_pObject->GetSysMemMesh()->GetNumFaces() * 3; // Allocate space for the vertices' tangents and binormals m_pTangents = new D3DXVECTOR3[dwNumVertices]; m_pBinormals = new D3DXVECTOR3[dwNumVertices]; ZeroMemory( m_pTangents, sizeof(D3DXVECTOR3)*dwNumVertices ); ZeroMemory( m_pBinormals, sizeof(D3DXVECTOR3)*dwNumVertices ); // Generate the vertices' tangents and binormals for( DWORD i=0; i<dwNumIndices; i+=3 ) { WORD a = pIndices[i+0]; WORD b = pIndices[i+1]; WORD c = pIndices[i+2]; // To find a tangent that heads in the direction of +tv(texcoords), // find the components of both vectors on the tangent surface , // and add a linear combination of the two projections that head in the +tv direction m_pTangents[a] += ComputeTangentVector( pVertices[a], pVertices[b], pVertices[c] ); m_pTangents[b] += ComputeTangentVector( pVertices[b], pVertices[a], pVertices[c] ); m_pTangents[c] += ComputeTangentVector( pVertices[c], pVertices[a], pVertices[b] ); } for( i=0; i<dwNumVertices; i++ ) { // Normalize the tangents D3DXVec3Normalize( &m_pTangents[i], &m_pTangents[i] ); // Compute the binormals D3DXVec3Cross( &m_pBinormals[i], &pVertices[i].n, &m_pTangents[i] ); } // Unlock and release the vertex and index buffers pIB->Unlock(); pVB->Unlock(); pIB->Release(); pVB->Release(); }
BRUSH* ConvertXModelToBrushFormat ( char* szFilename, BRUSH* pBrush, int* piCount, LPDIRECT3DDEVICE8 lpDevice ) { // takes an x model and converts it into brushes // check the pointers are valid if ( !szFilename || !piCount ) return NULL; // used to access vertex data struct sMeshData { float x, y, z; float nx, ny, nz; float tu, tv; }; // variable declarations tagModelData* ptr; // model data LPDIRECT3DVERTEXBUFFER8 pMeshVertexBuffer; // vertex buffer LPDIRECT3DINDEXBUFFER8 pMeshIndexBuffer; // index buffer sMeshData* pMeshVertices; // mesh vertices WORD* pMeshIndices; // mesh indices sMesh* pMesh; // mesh data int iCount; // load the model Constructor ( lpDevice ); ptr = Load ( 1, szFilename ); pMesh = ptr->m_Object.m_Meshes; // count the number of brushes so we can allocate enough memory for them iCount = 0; while ( pMesh ) { pMesh = pMesh->m_Next; iCount++; } // store the number of models in the brush count pointer *piCount = iCount; // now setup the brushes pBrush = new BRUSH [ iCount ]; // allocate memory // set the mesh pointer back to the original mesh pMesh = ptr->m_Object.m_Meshes; // run through all meshes and store the brush data // first off set iCount to 0 so we know which brush // we are dealing with iCount = 0; while ( pMesh ) { int iInd = 0; DWORD dwNumVertices = pMesh->m_Mesh->GetNumVertices ( ); DWORD dwNumFaces = pMesh->m_Mesh->GetNumFaces ( ); pBrush [ iCount ].Faces = new POLYGON [ dwNumFaces ]; pBrush [ iCount ].FaceCount = dwNumFaces; pBrush [ iCount ].Bounds.Max = D3DXVECTOR3 ( 150.0f, 150.0f, 150.0f ); pBrush [ iCount ].Bounds.Min = D3DXVECTOR3 ( -150.0f, -150.0f, -150.0f ); pBrush [ iCount ].BSPTree = NULL; pMesh->m_Mesh->GetVertexBuffer ( &pMeshVertexBuffer ); pMesh->m_Mesh->GetIndexBuffer ( &pMeshIndexBuffer ); DWORD dwFVF = pMesh->m_Mesh->GetFVF ( ); pMeshVertexBuffer->Lock ( 0, pMesh->m_Mesh->GetNumVertices ( ) * sizeof ( sMeshData ), ( BYTE** ) &pMeshVertices, 0 ); pMeshIndexBuffer->Lock ( 0, 3 * pMesh->m_Mesh->GetNumFaces ( ) * sizeof ( WORD ), ( BYTE** ) &pMeshIndices, 0 ); for ( int iTemp = 0; iTemp < dwNumFaces; iTemp++ ) { char szX [ 256 ]; char szY [ 256 ]; char szZ [ 256 ]; int iA = pMeshIndices [ iInd + 0 ]; int iB = pMeshIndices [ iInd + 1 ]; int iC = pMeshIndices [ iInd + 2 ]; WORD wIndices [ ] = { 0, 1, 2 }; pBrush [ iCount ].Faces [ iTemp ].IndexCount = 3; pBrush [ iCount ].Faces [ iTemp ].TextureIndex = 0; pBrush [ iCount ].Faces [ iTemp ].VertexCount = 3; pBrush [ iCount ].Faces [ iTemp ].Indices = new WORD [ 3 ]; pBrush [ iCount ].Faces [ iTemp ].Vertices = new D3DVERTEX [ 3 ]; pBrush [ iCount ].Faces [ iTemp ].Vertices [ 0 ] = SetupVertex ( pMeshVertices [ iA ].x, pMeshVertices [ iA ].y, pMeshVertices [ iA ].z, pMeshVertices [ iA ].tu, pMeshVertices [ iA ].tv ); pBrush [ iCount ].Faces [ iTemp ].Vertices [ 1 ] = SetupVertex ( pMeshVertices [ iB ].x, pMeshVertices [ iB ].y, pMeshVertices [ iB ].z, pMeshVertices [ iB ].tu, pMeshVertices [ iB ].tv ); pBrush [ iCount ].Faces [ iTemp ].Vertices [ 2 ] = SetupVertex ( pMeshVertices [ iC ].x, pMeshVertices [ iC ].y, pMeshVertices [ iC ].z, pMeshVertices [ iC ].tu, pMeshVertices [ iC ].tv ); for ( int iChar = 0; iChar < 3; iChar++ ) { sprintf ( szX, "%.1f", pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].x ); sprintf ( szY, "%.1f", pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].y ); sprintf ( szZ, "%.1f", pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].z ); pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].x = atof ( szX ); pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].y = atof ( szY ); pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].z = atof ( szZ ); } memcpy ( pBrush [ iCount ].Faces [ iTemp ].Indices, wIndices, sizeof ( wIndices ) ); CalculateNormal ( &pBrush [ iCount ].Faces [ iTemp ] ); iInd += 3; } SetBlockPosition ( &pBrush [ iCount ], 0.0f, 0.0f, 0.0f, 1.0f ); pMeshVertexBuffer->Unlock ( ); pMeshIndexBuffer->Unlock ( ); iCount++; pMesh = pMesh->m_Next; } iCount = 0; pMesh = ptr->m_Object.m_Meshes; for ( int iTemp = ptr->m_Object.m_NumFrames; iTemp > 0; iTemp-- ) { sFrame* pFrame = ptr->m_Object.m_Frames->FindFrame ( iTemp ); if ( pFrame ) { pBrush [ iCount ].Matrix._41 = pFrame->m_matOriginal._41; pBrush [ iCount ].Matrix._42 = pFrame->m_matOriginal._42; pBrush [ iCount ].Matrix._43 = pFrame->m_matOriginal._43; iCount++; } } return pBrush; }