Esempio n. 1
0
void CreateGeometry(const char* sourceFile)
{
    cout << endl << "Reading " << sourceFile << endl;
    wstring wideSourceFile(sourceFile, sourceFile + strlen(sourceFile));

    // Load the mesh from the specified file
    LPD3DXBUFFER pD3DXMtrlBuffer;
    LPD3DXBUFFER pD3DXEffectInstances;
    HRESULT hr = D3DXLoadMeshFromX(
        wideSourceFile.c_str(),
        D3DXMESH_SYSTEMMEM,
        g_pd3dDevice, 0,
        &pD3DXMtrlBuffer, &pD3DXEffectInstances, &g_dwNumMaterials,
        &g_pMesh);

    if (FAILED(hr))
    {
        MessageBox(0, (L"Could not find " + wideSourceFile).c_str(), L"X2CTM", MB_OK);
        exit(1);
    }

    DWORD* adjacencyIn = new DWORD[3 * g_pMesh->GetNumFaces()];
    g_pMesh->GenerateAdjacency(0.0001f, adjacencyIn);

    DWORD* adjacencyOut = new DWORD[3 * g_pMesh->GetNumFaces()];

    LPD3DXMESH newMesh = 0;
    //hr = g_pMesh->Optimize(D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT, adjacencyIn, adjacencyOut, 0, 0, &newMesh);
    //hr = g_pMesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT, adjacencyIn, adjacencyOut, 0, 0);
    if (FAILED(hr))
    {
        MessageBox(0, L"Unable to build attribute table", L"Whatever", MB_OK);
        exit(1);
    }
    //g_pMesh = newMesh;

    if (WeldVertices)
    {
        DWORD beforeVertCount = g_pMesh->GetNumVertices();
        DWORD beforeFaceCount = g_pMesh->GetNumFaces();
        hr = D3DXWeldVertices(g_pMesh, D3DXWELDEPSILONS_WELDALL, 0, 0, 0, 0, 0);
        DWORD afterVertCount = g_pMesh->GetNumVertices();
        DWORD afterFaceCount = g_pMesh->GetNumFaces();
    }

    D3DXATTRIBUTERANGE table[256];
    DWORD tableSize = sizeof(table) / sizeof(table[0]);
    g_pMesh->GetAttributeTable(&table[0], &tableSize);

    D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*) pD3DXMtrlBuffer->GetBufferPointer();
    D3DXEFFECTINSTANCE* d3dxEffects = (D3DXEFFECTINSTANCE*) pD3DXEffectInstances->GetBufferPointer();

    g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials];
    g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials];

    for (DWORD i = 0; i < g_dwNumMaterials; i++)
    {
        g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
        g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;
        g_pMeshTextures[i] = 0;
        if (d3dxMaterials[i].pTextureFilename && lstrlenA(d3dxMaterials[i].pTextureFilename) > 0)
        {
            D3DXCreateTextureFromFileA(g_pd3dDevice, d3dxMaterials[i].pTextureFilename, &g_pMeshTextures[i]);
        }
    }
/*
    for (DWORD attrib = 0;  attrib < tableSize; ++attrib)
    {

        // I'm not so sure about material-to-attribute correlation
//        if (attrib < g_dwNumMaterials)
//        {
            LPSTR pTexture = d3dxMaterials[attrib].pTextureFilename;
            LPSTR pSlash = strchr(pTexture, '\\');
            if (pSlash)
            {
                pTexture = ++pSlash;
            }
            cout << "{Texture='" << pTexture << "',";
//        }

        string subMeshFilename = string("X_") + string("Armature.ctm"); // string(pTexture).substr(0, strlen(pTexture) - 4) + ".ctm";
        subMeshFilename[0] = attrib + 'A';

        ExportRangeCTM(table[attrib], g_pMesh, subMeshFilename.c_str());

        cout
            //<< table[attrib].AttribId << ' '
            << "FaceStart=" << table[attrib].FaceStart << ','
            << "FaceCount=" << table[attrib].FaceCount << ','
            << "VertexStart=" << table[attrib].VertexStart << ','
            << "VertexCount=" << table[attrib].VertexCount << '}' << endl;
    }
*/
    pD3DXMtrlBuffer->Release();


    // Convert the filename from .X to .CTM while preserving the full path.

   char destFile[_MAX_PATH];
   char drive[_MAX_DRIVE];
   char dir[_MAX_DIR];
   char fname[_MAX_FNAME];
   char ext[_MAX_EXT];
    
   _splitpath_s(sourceFile, drive, _MAX_DRIVE, dir, _MAX_DIR, fname, _MAX_FNAME, ext, _MAX_EXT);
   _makepath_s(destFile, _MAX_PATH, drive, dir, fname, "ctm");

    ExportCTM(g_pMesh, destFile);
    cout << "Exported " << destFile << endl;
/*
    const WORD MISSING_ATTRIBUTE = 0xffff;
    WORD positionsOffset = MISSING_ATTRIBUTE;
    WORD normalsOffset = MISSING_ATTRIBUTE;
    WORD texCoordsOffset = MISSING_ATTRIBUTE;

    D3DVERTEXELEMENT9 vertexLayout[MAX_FVF_DECL_SIZE];
    D3DVERTEXELEMENT9 endMarker = D3DDECL_END();
    g_pMesh->GetDeclaration(vertexLayout);
    D3DVERTEXELEMENT9* pVertexLayout = &vertexLayout[0];
    for (int attrib = 0;  attrib < MAX_FVF_DECL_SIZE; ++attrib, pVertexLayout++)
    {
        if (0 == memcmp(&vertexLayout[attrib], &endMarker, sizeof(endMarker)))
        {
            break;
        }
        if (pVertexLayout->Stream != 0)
        {
            cout << "Nonzero stream: " << pVertexLayout->Stream << endl;
            continue;
        }
        if (pVertexLayout->Usage == D3DDECLUSAGE_POSITION && pVertexLayout->Type == D3DDECLTYPE_FLOAT3)
        {
            cout << "Contains positions " << (int) pVertexLayout->UsageIndex << endl;
            positionsOffset = pVertexLayout->Offset;
        }
        else if (pVertexLayout->Usage == D3DDECLUSAGE_NORMAL && pVertexLayout->Type == D3DDECLTYPE_FLOAT3)
        {
            cout << "Contains normals " << (int) pVertexLayout->UsageIndex << endl;
            normalsOffset = pVertexLayout->Offset;
        }
        else if (pVertexLayout->Usage == D3DDECLUSAGE_TEXCOORD && pVertexLayout->Type == D3DDECLTYPE_FLOAT2)
        {
            cout << "Contains texture coordinates " << (int) pVertexLayout->UsageIndex << endl;
            texCoordsOffset = pVertexLayout->Offset;
        }
        else
        {
            cout << "Mysterious attribute" << endl;
        }
    }

    // Check that we support the format of the data.

    if (positionsOffset == MISSING_ATTRIBUTE)
    {
        exit(1);
    }

    // Obtain vertex & index counts from the D3D mesh; allocate memory for the CTM mesh.
    DWORD dwVertexCount = g_pMesh->GetNumVertices();
    DWORD dwTriangleCount = g_pMesh->GetNumFaces();
    DWORD dwIndexCount = dwTriangleCount * 3;

    // Lock down the verts and pluck out the positions and normals.
    {
        void* pData = 0;
        if (S_OK != g_pMesh->LockVertexBuffer(0, &pData))
        {
            exit(1);
        }

        if (positionsOffset != MISSING_ATTRIBUTE)
        {
            unsigned char* pSource = ((unsigned char*) pData) + positionsOffset;
            DWORD dwSourceStride = g_pMesh->GetNumBytesPerVertex();
            DWORD dwDestStride = sizeof(CTMfloat) * 3;

            for (DWORD dwVertex = 0; dwVertex < dwVertexCount; ++dwVertex)
            {
                float* pFloat = (float*) pSource;
                *pFloat = -*pFloat;
                //*pFloat = -*pFloat;
                pSource += dwSourceStride;
            }
        }

        g_pMesh->UnlockVertexBuffer();
    }

    // Lock down the indices and convert them to unsigned 32-bit integers.
    {
        void* pData = 0;
        g_pMesh->LockIndexBuffer(0, &pData);

        DWORD dwOptions = g_pMesh->GetOptions();
        DWORD dwSourceStride = (dwOptions & D3DXMESH_32BIT) ? 4 : 2;

        unsigned char* pSource = (unsigned char*) pData;

        for (DWORD dwIndex = 0; dwIndex < dwIndexCount / 3; ++dwIndex)
        {
            unsigned short* inds = (unsigned short*) pSource;
            
            std::swap(inds[0], inds[1]);

            pSource += dwSourceStride * 3;
        }

        g_pMesh->UnlockIndexBuffer();
    }


    D3DXSaveMeshToX(L"new.x", g_pMesh, 0, d3dxMaterials, d3dxEffects, g_dwNumMaterials, D3DXF_FILEFORMAT_BINARY | D3DXF_FILEFORMAT_COMPRESSED);
    cout << "Saved." << endl;
*/   
}