mxAPPLICATION_ENTRY_POINT int mxAppMain() { SetupBaseUtil setupBase; //FileLogUtil fileLog; SetupCoreUtil setupCore; const String srcFileName( "D:/dev/_assets/_diplomarbeit/iryoku-head/Head.sdkmesh" //"D:/research/_current/iryoku-separable-sss-f61b44c/Demo/Media/Head.sdkmesh" //"D:/dev/_assets/Head.sdkmesh" ); FileReader srcFile( srcFileName ); CHK_VRET_X_IF_NOT( srcFile.IsOpen(), -1 ); StaticTriangleMeshData staticMeshData; { SDKMesh sdkMesh; if( FAILED(sdkMesh.Create(mxTO_UNICODE( srcFileName ))) ) { return -1; } const SDKMESH_HEADER& header = *sdkMesh.GetHeader(); (void)header; const UINT numMeshes = sdkMesh.GetNumMeshes(); Assert(numMeshes == 1); const UINT iFirstMesh = 0; const UINT numSubsets = sdkMesh.GetNumSubsets( iFirstMesh ); Assert( numSubsets == 1 ); const UINT iFirstSubset = 0; const SDKMESH_SUBSET* pSubset = sdkMesh.GetSubset( iFirstMesh, iFirstSubset ); const UINT numVertices = pSubset->VertexCount; const UINT numIndices = pSubset->IndexCount; const UINT numVBs = sdkMesh.GetNumVBs(); Assert( numVBs == 1 ); const UINT numIBs = sdkMesh.GetNumIBs(); Assert( numIBs == 1 ); const SDKMeshVertex* srcVertices = (const SDKMeshVertex*) sdkMesh.GetRawVerticesAt(0); const SDKMESH_INDEX_TYPE indexType = sdkMesh.GetIndexType( iFirstMesh ); Assert( indexType == SDKMESH_INDEX_TYPE::IT_16BIT ); const UINT16* srcIndices = (const UINT16*) sdkMesh.GetRawIndicesAt(0); { TList< Vec3D > & positions = staticMeshData.positions; TList< Vec2D > & texCoords = staticMeshData.texCoords; TList< Vec3D > & normals = staticMeshData.normals; //TList< Vec3D > & binormals = staticMeshData.binormals; TList< Vec3D > & tangents = staticMeshData.tangents; positions.SetNum( numVertices ); texCoords.SetNum( numVertices ); normals.SetNum( numVertices ); tangents.SetNum( numVertices ); staticMeshData.localBounds.Clear(); for( UINT iVertex = 0; iVertex < numVertices; iVertex++ ) { const SDKMeshVertex & srcVertex = srcVertices[ iVertex ]; Assert( srcVertex.normal.IsNormalized() ); Assert( srcVertex.tangent.IsNormalized() ); positions[ iVertex ] = srcVertex.position; texCoords[ iVertex ] = srcVertex.texCoord; normals[ iVertex ] = srcVertex.normal; tangents[ iVertex ] = srcVertex.tangent; staticMeshData.localBounds.AddPoint( srcVertex.position ); } staticMeshData.indices.AddBytes( srcIndices, numIndices * sizeof srcIndices[0] ); staticMeshData.indexStride = sizeof srcIndices[0]; MeshPart & firstBatch = staticMeshData.batches.Add(); { firstBatch.baseVertex = pSubset->VertexStart; firstBatch.startIndex = pSubset->IndexStart; firstBatch.indexCount = pSubset->IndexCount; firstBatch.vertexCount = pSubset->VertexCount; } } } const String dstPathName( //"D:/dev/_assets" "R:/" ); String dstFileName( "iryoku-Head" ); //srcFileName.ExtractFileBase( dstFileName ); dstFileName += ".static_mesh"; FileWriter dstFile( dstPathName + dstFileName ); CHK_VRET_X_IF_NOT( dstFile.IsOpen(), -1 ); ArchivePODWriter archive( dstFile ); staticMeshData.Serialize( archive ); return 0; }
void Model::CreateFromSDKMeshFile(ID3D11Device* device, LPCWSTR fileName) { _ASSERT(FileExists(fileName)); // Use the SDKMesh class to load in the data SDKMesh sdkMesh; sdkMesh.Create(fileName); wstring directory = GetDirectoryFromFileName(fileName); // Make materials UINT numMaterials = sdkMesh.GetNumMaterials(); for (UINT i = 0; i < numMaterials; ++i) { MeshMaterial material; SDKMESH_MATERIAL* mat = sdkMesh.GetMaterial(i); memcpy(&material.AmbientAlbedo, &mat->Ambient, sizeof(D3DXVECTOR4)); memcpy(&material.DiffuseAlbedo, &mat->Diffuse, sizeof(D3DXVECTOR4)); memcpy(&material.SpecularAlbedo, &mat->Specular, sizeof(D3DXVECTOR4)); memcpy(&material.Emissive, &mat->Emissive, sizeof(D3DXVECTOR4)); material.Alpha = mat->Diffuse.w; material.SpecularPower = mat->Power; material.DiffuseMapName = AnsiToWString(mat->DiffuseTexture); material.NormalMapName = AnsiToWString(mat->NormalTexture); LoadMaterialResources(material, directory, device); meshMaterials.push_back(material); } // Make a D3D9 device IDirect3DDevice9Ptr d3d9Device = CreateD3D9Device(); UINT numMeshes = sdkMesh.GetNumMeshes(); for (UINT meshIdx = 0; meshIdx < numMeshes; ++meshIdx) { // Figure out the index type UINT ops = D3DXMESH_MANAGED; UINT indexSize = 2; Mesh::IndexType indexType = Mesh::Index16Bit; if (sdkMesh.GetIndexType(meshIdx) == IT_32BIT) { ops |= D3DXMESH_32BIT; indexSize = 4; indexType = Mesh::Index32Bit; } // Make a D3DX mesh ID3DXMesh* d3dxMesh = NULL; UINT numPrims = static_cast<UINT>(sdkMesh.GetNumIndices(meshIdx) / 3); UINT numVerts = static_cast<UINT>(sdkMesh.GetNumVertices(meshIdx, 0)); UINT vbIndex = sdkMesh.GetMesh(meshIdx)->VertexBuffers[0]; UINT ibIndex = sdkMesh.GetMesh(meshIdx)->IndexBuffer; const D3DVERTEXELEMENT9* vbElements = sdkMesh.VBElements(vbIndex); DXCall(D3DXCreateMesh(numPrims, numVerts, ops, vbElements, d3d9Device, &d3dxMesh)); IUnknownReleaser<ID3DXMesh> meshReleaser(d3dxMesh); // Copy in vertex data BYTE* verts = NULL; BYTE* srcVerts = reinterpret_cast<BYTE*>(sdkMesh.GetRawVerticesAt(vbIndex)); UINT vbStride = sdkMesh.GetVertexStride(meshIdx, 0); UINT declStride = D3DXGetDeclVertexSize(vbElements, 0); DXCall(d3dxMesh->LockVertexBuffer(0, reinterpret_cast<void**>(&verts))); for (UINT vertIdx = 0; vertIdx < numVerts; ++vertIdx) { memcpy(verts, srcVerts, declStride); verts += declStride; srcVerts += vbStride; } DXCall(d3dxMesh->UnlockVertexBuffer()); // Copy in index data void* indices = NULL; void* srcIndices = sdkMesh.GetRawIndicesAt(ibIndex); DXCall(d3dxMesh->LockIndexBuffer(0, &indices)); memcpy(indices, srcIndices, numPrims * 3 * indexSize); DXCall(d3dxMesh->UnlockIndexBuffer()); // Set up the attribute table DWORD* attributeBuffer = NULL; DXCall(d3dxMesh->LockAttributeBuffer(0, &attributeBuffer)); UINT numSubsets = sdkMesh.GetNumSubsets(meshIdx); D3DXATTRIBUTERANGE* attributes = new D3DXATTRIBUTERANGE[numSubsets]; ArrayDeleter<D3DXATTRIBUTERANGE> attributeDeleter(attributes); for (UINT i = 0; i < numSubsets; ++i) { SDKMESH_SUBSET* subset = sdkMesh.GetSubset(meshIdx, i); attributes[i].AttribId = subset->MaterialID; attributes[i].FaceStart = static_cast<DWORD>(subset->IndexStart / 3); attributes[i].FaceCount = static_cast<DWORD>(subset->IndexCount / 3); attributes[i].VertexStart = static_cast<DWORD>(subset->VertexStart); // attributes[i].VertexCount = static_cast<DWORD>(subset->VertexCount); attributes[i].VertexCount = numVerts; for (UINT faceIdx = attributes[i].FaceStart; faceIdx < attributes[i].FaceStart + attributes[i].FaceCount; ++faceIdx) attributeBuffer[faceIdx] = subset->MaterialID; } DXCall(d3dxMesh->UnlockAttributeBuffer()); d3dxMesh->SetAttributeTable(attributes, numSubsets); // Generate initial adjacency vector<DWORD> initialAdjacency; initialAdjacency.resize(d3dxMesh->GetNumFaces() * 3); DXCall(d3dxMesh->GenerateAdjacency(0.0001f, &initialAdjacency[0])); // Make the mesh Mesh mesh; mesh.CreateFromD3DXMesh(directory, device, d3d9Device, d3dxMesh, false, false, &initialAdjacency[0], indexType); meshes.push_back(mesh); } }