DWORD MeshParameterization::OnGenerateAtlas( DWORD size, void * params ) { VERIFY_MESSAGE_SIZE( size, sizeof( GENERATEATLASMESSAGE ) ); GENERATEATLASMESSAGE * msg = (GENERATEATLASMESSAGE*)params; if( !msg ) { return MSG_ERROR; } bool bUseIncomingTexCoords = msg->useIncomingTexCoords; GenerateBounds(); HRESULT hr; //This should be changed to use a new mesh parameterization technique DWORD numFaces = (DWORD)m_Faces->size(); DWORD numVertices = (DWORD)m_CollapsedMesh->size(); DWORD curError = 0; if( !bUseIncomingTexCoords && numFaces > 0 && numVertices > 0 ) { DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 ; DWORD flags = D3DXMESH_SYSTEMMEM ;// | D3DXMESH_MANAGED ;// | D3DXMESH_SOFTWAREPROCESSING | D3DXMESH_SYSTEMMEM |; LPD3DXMESH mesh = NULL; hr = D3DXCreateMeshFVF( numFaces, numVertices, flags, fvf, m_pDevice, &mesh ); if( FAILED( hr ) ) { curError = GetLastError(); EngineGetToolBox()->Log(LOGERROR, _T("MeshParameterization: Error in create mesh fvf\n")); return MSG_ERROR; } //now fill with data BYTE * vertexData; BYTE * indexData; hr = mesh->LockVertexBuffer( 0, (LPVOID*)&vertexData ); hr = mesh->LockIndexBuffer( 0, (LPVOID*)&indexData ); D3DVERTEXELEMENT9 Decl[ MAX_FVF_DECL_SIZE ]; mesh->GetDeclaration( Decl ); paramVertex * pVertOriginal = (paramVertex*)vertexData; for( int i = 0; i < (int)numVertices; i++ ) { paramVertex * pVert = (paramVertex*)vertexData; pVert->x = (*m_CollapsedMesh)[i].originalPosition.x; pVert->y = (*m_CollapsedMesh)[i].originalPosition.y; pVert->z = (*m_CollapsedMesh)[i].originalPosition.z; pVert->nx = -(*m_CollapsedMesh)[i].normal.x; pVert->ny = -(*m_CollapsedMesh)[i].normal.y; pVert->nz = -(*m_CollapsedMesh)[i].normal.z; pVert->u = (*m_CollapsedMesh)[i].generatedU; pVert->v = (*m_CollapsedMesh)[i].generatedV; NormalizeUV( pVert->u ); NormalizeUV( pVert->v ); vertexData += sizeof( paramVertex ); } for( int i = 0; i < (int)numFaces; i++ ) { unsigned short * index = (unsigned short*)indexData; index[0] = ( unsigned short )(*m_Faces)[ i ].index[ 0 ]; index[1] = ( unsigned short )(*m_Faces)[ i ].index[ 1 ]; index[2] = ( unsigned short )(*m_Faces)[ i ].index[ 2 ]; indexData += sizeof( unsigned short )*3;//32 bit indices triangles } LPD3DXBUFFER imt; hr = D3DXComputeIMTFromPerVertexSignal( mesh, (const float*)pVertOriginal + 3*sizeof(float), 3, sizeof(paramVertex), 0L, 0, 0, &imt ); mesh->UnlockIndexBuffer(); mesh->UnlockVertexBuffer(); //tensors float * tensors = new float[ 3*numFaces ]; for( int i = 0; i < 3*(int)numFaces; i += 3 ) { tensors[ i ] = 4.f; tensors[ i + 1 ] = 0.f; tensors[ i + 2 ] = 4.f; } //some checks numVertices = mesh->GetNumVertices(); numFaces = mesh->GetNumFaces(); //create adjacency DWORD * adjacency = new DWORD[ 3*numFaces ]; memset( adjacency, 0, sizeof(DWORD)*3*numFaces ); hr = mesh->GenerateAdjacency( 0.001f, adjacency ); //hr = mesh->ConvertPointRepsToAdjacency( NULL, adjacency ); if( FAILED( hr ) ) { curError = GetLastError(); EngineGetToolBox()->Log(LOGERROR, _T("MeshParameterization: Error in generate adjacency\n")); return MSG_ERROR; } /* save to mesh to check model uvs D3DXMATERIAL mat; mat.MatD3D.Ambient.r = mat.MatD3D.Ambient.a =mat.MatD3D.Ambient.b =mat.MatD3D.Ambient.g = 0; mat.MatD3D.Diffuse.r = mat.MatD3D.Diffuse.a =mat.MatD3D.Diffuse.b =mat.MatD3D.Diffuse.g = 1; mat.pTextureFilename = "tex.dds"; D3DXSaveMeshToX( "mesh.x", mesh, adjacency, &mat, NULL, 0, D3DXF_FILEFORMAT_TEXT ); */ float * imtTensor = tensors;//(float*)imt->GetBufferPointer(); float stretchout; unsigned int charts; LPD3DXMESH meshOut = NULL; LPD3DXBUFFER remappedData = NULL; LPD3DXBUFFER faceData = NULL; D3DXATTRIBUTERANGE Attrib; memset(&Attrib, 0, sizeof(D3DXATTRIBUTERANGE)); Attrib.FaceCount = numFaces; Attrib.VertexCount = numVertices; mesh->SetAttributeTable(&Attrib, 1); int gutter = m_TexSize / 32; gutter = min( gutter, 6 ); hr = D3DXUVAtlasCreate( mesh, 0, .5, m_TexSize, m_TexSize, 6, //gutter 0, adjacency, 0, imtTensor, (LPD3DXUVATLASCB)UVGenCallback, .0001f, 0, //D3DXUVATLAS_GEODESIC_QUALITY , D3DXUVATLAS_GEODESIC_FAST, &meshOut, &faceData, &remappedData, &stretchout, &charts ); if( FAILED( hr ) ) { curError = GetLastError(); EngineGetToolBox()->Log(LOGERROR, _T("MeshParameterization: Error in uv atlas create\n")); return MSG_ERROR; } /* save to mesh to check model uvs hr = meshOut->ConvertPointRepsToAdjacency( NULL, adjacency ); D3DXSaveMeshToX( "mesh2.x", meshOut, adjacency, &mat, NULL, 0, D3DXF_FILEFORMAT_TEXT ); */ delete [] adjacency; delete [] tensors; //Generate our lightmap cache data for passing on and saving GenerateCache( meshOut, remappedData ); GenerateTriangleTexelData(); meshOut->Release(); faceData->Release(); remappedData->Release(); mesh->Release(); } else if( bUseIncomingTexCoords ) { GenerateCache(); GenerateTriangleTexelData(); } return MSG_HANDLED_STOP; }