Sign in to follow this  

After exporting a character mesh, the head is gone.

This topic is 1711 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

xof 0303txt 0032

template KeyValuePair {

 <26e6b1c3-3d4d-4a1d-a437-b33668ffa1c2>

 STRING key;

 STRING value;

}



template Frame {

 <3d82ab46-62da-11cf-ab39-0020af71e433>

 [...]

}



template Matrix4x4 {

 <f6f23f45-7686-11cf-8f52-0040333594a3>

 array FLOAT matrix[16];

}



template FrameTransformMatrix {

 <f6f23f41-7686-11cf-8f52-0040333594a3>

 Matrix4x4 frameMatrix;

}



template ObjectMatrixComment {

 <95a48e28-7ef4-4419-a16a-ba9dbdf0d2bc>

 Matrix4x4 objectMatrix;

}



template Vector {

 <3d82ab5e-62da-11cf-ab39-0020af71e433>

 FLOAT x;

 FLOAT y;

 FLOAT z;

}



template MeshFace {

 <3d82ab5f-62da-11cf-ab39-0020af71e433>

 DWORD nFaceVertexIndices;

 array DWORD faceVertexIndices[nFaceVertexIndices];

}



template Mesh {

 <3d82ab44-62da-11cf-ab39-0020af71e433>

 DWORD nVertices;

 array Vector vertices[nVertices];

 DWORD nFaces;

 array MeshFace faces[nFaces];

 [...]

}



template MeshNormals {

 <f6f23f43-7686-11cf-8f52-0040333594a3>

 DWORD nNormals;

 array Vector normals[nNormals];

 DWORD nFaceNormals;

 array MeshFace faceNormals[nFaceNormals];

}



template Coords2d {

 <f6f23f44-7686-11cf-8f52-0040333594a3>

 FLOAT u;

 FLOAT v;

}



template MeshTextureCoords {

 <f6f23f40-7686-11cf-8f52-0040333594a3>

 DWORD nTextureCoords;

 array Coords2d textureCoords[nTextureCoords];

}



template ColorRGBA {

 <35ff44e0-6c7c-11cf-8f52-0040333594a3>

 FLOAT red;

 FLOAT green;

 FLOAT blue;

 FLOAT alpha;

}



template IndexedColor {

 <1630b820-7842-11cf-8f52-0040333594a3>

 DWORD index;

 ColorRGBA indexColor;

}



template MeshVertexColors {

 <1630b821-7842-11cf-8f52-0040333594a3>

 DWORD nVertexColors;

 array IndexedColor vertexColors[nVertexColors];

}



template VertexElement {

 <f752461c-1e23-48f6-b9f8-8350850f336f>

 DWORD Type;

 DWORD Method;

 DWORD Usage;

 DWORD UsageIndex;

}



template DeclData {

 <bf22e553-292c-4781-9fea-62bd554bdd93>

 DWORD nElements;

 array VertexElement Elements[nElements];

 DWORD nDWords;

 array DWORD data[nDWords];

}



template ColorRGB {

 <d3e16e81-7835-11cf-8f52-0040333594a3>

 FLOAT red;

 FLOAT green;

 FLOAT blue;

}



template Material {

 <3d82ab4d-62da-11cf-ab39-0020af71e433>

 ColorRGBA faceColor;

 FLOAT power;

 ColorRGB specularColor;

 ColorRGB emissiveColor;

 [...]

}



template MeshMaterialList {

 <f6f23f42-7686-11cf-8f52-0040333594a3>

 DWORD nMaterials;

 DWORD nFaceIndexes;

 array DWORD faceIndexes[nFaceIndexes];

 [Material <3d82ab4d-62da-11cf-ab39-0020af71e433>]

}





KeyValuePair {

 "Date";

 "2013-04-08 19:12:32";

}



KeyValuePair {

 "File";

 "D:\\Jacky\\Desktop\\operator 7.max";

}



KeyValuePair {

 "User";

 "Jacky";

}



KeyValuePair {

 "CoreTime";

 "0";

}



Frame Camera01 {

 



 FrameTransformMatrix relative {

  0.954699,-0.048181,-0.293648,0.000000,-0.262458,0.328708,-0.907230,0.000000,0.140236,0.943202,0.301171,0.000000,-132.849613,176.480128,-402.618522,1.000000;;

 }



 ObjectMatrixComment object {

  1.000000,-0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,-0.000015,-0.000031,-0.000015,1.000000;;

 }

}



Frame CameraFront {

 



 FrameTransformMatrix relative {

  0.999048,0.005303,-0.043296,0.000000,-0.043619,0.121754,-0.991601,0.000000,0.000013,0.992546,0.121869,0.000000,-135.957888,524.95680,-4940.4292,1.000000;;

 }



 ObjectMatrixComment object {

  1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000046,0.000488,0.000000,1.000000;;

 }

}



Frame CameraSide {

 



 FrameTransformMatrix relative {

  0.003753,0.008559,-0.999956,0.000000,-0.999795,0.019928,-0.003582,0.000000,0.019897,0.999765,0.008632,0.000000,-6249.5436,34.218938,290.278528,1.000000;;

 }



 ObjectMatrixComment object {

  1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,-0.000000,1.000000,0.000000,-0.000031,0.000350,-0.000015,1.000000;;

 }

}



Frame Camera02 {

 



 FrameTransformMatrix relative {

  0.995041,0.031253,-0.094431,0.000000,-0.091776,-0.077591,-0.992752,0.000000,-0.038354,0.996495,-0.074338,0.000000,-56.457754,218.555597,-206.817331,1.000000;;

 }



 ObjectMatrixComment object {

  1.000000,0.000000,-0.000000,0.000000,-0.000000,1.000000,-0.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000008,1.000000;;

 }

}



Frame Head {

 



 FrameTransformMatrix relative {

  -0.185920,0.000000,0.000000,0.000000,0.000000,0.000000,-0.189494,0.000000,0.000000,0.193587,0.000000,0.000000,0.001830,25.805435,0.158419,1.000000;;

 }



 ObjectMatrixComment object {

  1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,8.784056,-0.000011,-53.488144,1.000000;;

 }



 Mesh mesh_Head {

  12576;

  -6.663792;-4.453252;4.463104;,

  -8.113831;-4.302740;3.912979;,

  -7.098774;-5.174445;4.092575;,

  -8.611297;-5.001015;3.608841;,

  -7.539185;-5.876936;3.701386;,

  -9.609235;-4.119639;3.480789;,

  -5.160847;-3.779241;5.591461;,

  -6.229849;-3.660912;4.894409;,

  -5.423100;-4.540097;5.194412;,

  -7.127871;-7.326566;3.197830;,

  -6.635538;-6.691591;3.722351;,

  -7.989399;-6.613170;3.208191;,

 

http://youtu.be/gvcN6pLcDwQ

 

The physique modifier has been deleted. Left alone was the mesh.

However, let's see the coding

 

 

#include "skinnedMesh.h"

#include <tchar.h>



#pragma warning(disable:4996)



extern IDirect3DDevice9 *g_pDevice;

extern ID3DXEffect *g_pEffect;

 

extern std::ofstream g_debug;



//-----------------------------------------------------------------------------

// Miscellaneous helper functions

//-----------------------------------------------------------------------------

#define SAFE_DELETE(p)       { if(p) { delete (p);     (p)=NULL; } }

#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p);   (p)=NULL; } }

#define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=NULL; } }









//-----------------------------------------------------------------------------

// Name: AllocateName()

// Desc: Allocates memory for a string to hold the name of a frame or mesh

//-----------------------------------------------------------------------------

HRESULT AllocateName( LPCSTR Name, LPSTR *pNewName )

{

    UINT cbLength;



    if (Name != NULL)

    {

        cbLength = (UINT)strlen(Name) + 1;

        *pNewName = new CHAR[cbLength];

        if (*pNewName == NULL)

            return E_OUTOFMEMORY;

        memcpy(*pNewName, Name, cbLength*sizeof(CHAR));

    }

    else

    {

        *pNewName = NULL;

    }



    return S_OK;

}





HRESULT CAllocateHierarchy::CreateFrame(LPCSTR Name, LPD3DXFRAME* ppNewFrame)

{

    D3DXFRAME_DERIVED* newFrame = new D3DXFRAME_DERIVED();

    //memset (newFrame, 0, sizeof(D3DXFRAME_DERIVED));

    

    

    if (Name != NULL)

    {

        newFrame->Name = new char[strlen(Name)+1];

        strcpy (newFrame->Name, Name);

    }

    else

    {

        newFrame->Name = NULL;

    }

    

    D3DXMatrixIdentity(&newFrame->TransformationMatrix);

    D3DXMatrixIdentity(&newFrame->CombinedTransformationMatrix);



    newFrame->pFrameFirstChild = NULL;

    newFrame->pFrameSibling = NULL;

    

    *ppNewFrame = newFrame;



      

    

    return S_OK;

}



HRESULT CAllocateHierarchy::CreateMeshContainer(LPCSTR Name,

                                            CONST D3DXMESHDATA *pMeshData,

                                            CONST D3DXMATERIAL *pMaterials,

                                            CONST D3DXEFFECTINSTANCE *pEffectInstances,

                                            DWORD NumMaterials,

                                            CONST DWORD *pAdjacency,

                                            LPD3DXSKININFO pSkinInfo,

                                            LPD3DXMESHCONTAINER *ppNewMeshContainer)

{



#if 0

    

    D3DXMESHCONTAINER_DERIVED *pMeshContainer = new D3DXMESHCONTAINER_DERIVED;  

    

    //ZeroMemory(&pMeshContainer, sizeof(D3DXMESHCONTAINER_DERIVED)); // don't do this

    

    if (Name != NULL)

    {

        pMeshContainer->Name = new char[strlen(Name)+1];

        strcpy (pMeshContainer->Name, Name);

    }

    else

    {

        Name = NULL;

    }

    



    

    pMeshContainer->MeshData.pMesh = pMeshData->pMesh;

    pMeshContainer->MeshData.Type = pMeshData->Type;

    pMeshContainer->MeshData.pMesh->AddRef();



    pMeshContainer->OriginalMesh = pMeshData->pMesh;

    pMeshContainer->OriginalMesh->AddRef();

    



 

    IDirect3DDevice9 *pDevice = NULL;    

    pMeshData->pMesh->GetDevice(&pDevice);



    for(int i=0;i<(int)NumMaterials;i++)

    {

        D3DXMATERIAL mtrl;

        memcpy(&mtrl, &pMaterials[i], sizeof(D3DXMATERIAL));

        pMeshContainer->materials.push_back(mtrl.MatD3D);

        IDirect3DTexture9* newTexture = NULL;



        if(mtrl.pTextureFilename != NULL)

        {

            char textureFname[200];

            strcpy(textureFname, "Data/");

            strcat(textureFname, mtrl.pTextureFilename);



            //Load texture

            D3DXCreateTextureFromFileA(g_pDevice, textureFname, &newTexture);

            pMeshContainer->textures.push_back(newTexture);

        }

        else

        {



            pMeshContainer->textures.push_back(newTexture);

        }



        

    

    }



    if(pSkinInfo != NULL)

    {

        //Get Skin Info

        pMeshContainer->pSkinInfo = pSkinInfo;

        pSkinInfo->AddRef();    //Add reference so that the SkinInfo isnt deallocated



        DWORD maxVertInfluences = 0;

        DWORD numBoneComboEntries = 0;

        ID3DXBuffer* boneComboTable = 0;



        pSkinInfo->ConvertToIndexedBlendedMesh(pMeshData->pMesh,

                                                D3DXMESH_MANAGED | D3DXMESH_WRITEONLY,  

                                                30,

                                                0, // ignore adjacency in

                                                0, // ignore adjacency out

                                                0, // ignore face remap

                                                0, // ignore vertex remap

                                                &maxVertInfluences,

                                                &numBoneComboEntries,

                                                &boneComboTable,

                                                &pMeshContainer->MeshData.pMesh);



        if(boneComboTable != NULL)

            boneComboTable->Release();



        //Get Attribute Table

        pMeshContainer->MeshData.pMesh->GetAttributeTable(NULL, &pMeshContainer->NumAttributeGroups);

        pMeshContainer->attributeTable = new D3DXATTRIBUTERANGE[pMeshContainer->NumAttributeGroups];

        pMeshContainer->MeshData.pMesh->GetAttributeTable(pMeshContainer->attributeTable, NULL);



        //Create bone offset and current matrices

        int NumBones = pSkinInfo->GetNumBones();

        pMeshContainer->boneOffsetMatrices = new D3DXMATRIX[NumBones];        

        pMeshContainer->currentBoneMatrices = new D3DXMATRIX[NumBones];



        //Get bone offset matrices

        for(int i=0;i < NumBones;i++)

            pMeshContainer->boneOffsetMatrices[i] = *(pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(i));

    }

    

    pMeshContainer->pNextMeshContainer = NULL;



    



    *ppNewMeshContainer = pMeshContainer;



    //delete pMeshContainer;

    pDevice->Release();



    return S_OK;

#endif

    HRESULT hr;

    D3DXMESHCONTAINER_DERIVED *pMeshContainer = NULL;

    UINT NumFaces;

    UINT iMaterial;

    UINT iBone, cBones;

    LPDIRECT3DDEVICE9 pd3dDevice = NULL;



    LPD3DXMESH pMesh = NULL;



    *ppNewMeshContainer = NULL;



    // this sample does not handle patch meshes, so fail when one is found

    if (pMeshData->Type != D3DXMESHTYPE_MESH)

    {

        hr = E_FAIL;

        goto e_Exit;

    }



    // get the pMesh interface pointer out of the mesh data structure

    pMesh = pMeshData->pMesh;



    // this sample does not FVF compatible meshes, so fail when one is found

    /*if (pMesh->GetFVF() == 0)

    {

        hr = E_FAIL;

        goto e_Exit;

    }*/



    // allocate the overloaded structure to return as a D3DXMESHCONTAINER

    pMeshContainer = new D3DXMESHCONTAINER_DERIVED;

    if (pMeshContainer == NULL)

    {

        hr = E_OUTOFMEMORY;

        goto e_Exit;

    }

    memset(pMeshContainer, 0, sizeof(D3DXMESHCONTAINER_DERIVED));



    // make sure and copy the name.  All memory as input belongs to caller, interfaces can be addref'd though

    hr = AllocateName(Name, &pMeshContainer->Name);

    if (FAILED(hr))

        goto e_Exit;        



    pMesh->GetDevice(&pd3dDevice);

    NumFaces = pMesh->GetNumFaces();



    // if no normals are in the mesh, add them

    if (!(pMesh->GetFVF() & D3DFVF_NORMAL))

    {

        pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;



        // clone the mesh to make room for the normals

        hr = pMesh->CloneMeshFVF( pMesh->GetOptions(),

                                    pMesh->GetFVF() | D3DFVF_NORMAL,

                                    pd3dDevice, &pMeshContainer->MeshData.pMesh );

        if (FAILED(hr))

            goto e_Exit;



        // get the new pMesh pointer back out of the mesh container to use

        // NOTE: we do not release pMesh because we do not have a reference to it yet

        pMesh = pMeshContainer->MeshData.pMesh;



        // now generate the normals for the pmesh

        D3DXComputeNormals( pMesh, NULL );

    }

    else  // if no normals, just add a reference to the mesh for the mesh container

    {

        pMeshContainer->MeshData.pMesh = pMesh;

        pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;



        pMesh->AddRef();

    }

        

    // allocate memory to contain the material information.  This sample uses

    //   the D3D9 materials and texture names instead of the EffectInstance style materials

    pMeshContainer->NumMaterials = max(1, NumMaterials);

    pMeshContainer->pMaterials = new D3DXMATERIAL[pMeshContainer->NumMaterials];

    pMeshContainer->ppTextures = new LPDIRECT3DTEXTURE9[pMeshContainer->NumMaterials];

    pMeshContainer->pAdjacency = new DWORD[NumFaces*3];

    if ((pMeshContainer->pAdjacency == NULL) || (pMeshContainer->pMaterials == NULL))

    {

        hr = E_OUTOFMEMORY;

        goto e_Exit;

    }



    memcpy(pMeshContainer->pAdjacency, pAdjacency, sizeof(DWORD) * NumFaces*3);

    memset(pMeshContainer->ppTextures, 0, sizeof(LPDIRECT3DTEXTURE9) * pMeshContainer->NumMaterials);



    // if materials provided, copy them

 

    if (NumMaterials > 0)            

    {

        memcpy(pMeshContainer->pMaterials, pMaterials, sizeof(D3DXMATERIAL) * NumMaterials);



        for (iMaterial = 0; iMaterial < NumMaterials; iMaterial++)

        {

            if (pMeshContainer->pMaterials[iMaterial].pTextureFilename != NULL)

            {

                TCHAR strTexturePath[MAX_PATH] = _T("");

                TCHAR *tszFilename;

#ifdef UNICODE

                TCHAR tszBuf[MAX_PATH];

                tszFilename = tszBuf;

                MultiByteToWideChar( CP_ACP, 0, pMeshContainer->pMaterials[iMaterial].pTextureFilename, -1, tszBuf, MAX_PATH );

                tszBuf[MAX_PATH - 1] = _T('\0');

#else

                tszFilename = pMeshContainer->pMaterials[iMaterial].pTextureFilename;

#endif

                _tcscpy( strTexturePath, _T("Data\\"));

                _tcscat( strTexturePath, tszBuf );



                if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexturePath,

                                                        &pMeshContainer->ppTextures[iMaterial] ) ) )

                    pMeshContainer->ppTextures[iMaterial] = NULL;





                // don't remember a pointer into the dynamic memory, just forget the name after loading

                pMeshContainer->pMaterials[iMaterial].pTextureFilename = NULL;

            }

        }

    }

    else // if no materials provided, use a default one

    {

        pMeshContainer->pMaterials[0].pTextureFilename = NULL;

        memset(&pMeshContainer->pMaterials[0].MatD3D, 0, sizeof(D3DMATERIAL9));

        pMeshContainer->pMaterials[0].MatD3D.Diffuse.r = 0.5f;

        pMeshContainer->pMaterials[0].MatD3D.Diffuse.g = 0.5f;

        pMeshContainer->pMaterials[0].MatD3D.Diffuse.b = 0.5f;

        pMeshContainer->pMaterials[0].MatD3D.Specular = pMeshContainer->pMaterials[0].MatD3D.Diffuse;

    }

 

#if 0

    for(int i=0;i<(int)NumMaterials;i++)

    {

        D3DXMATERIAL mtrl;

        memcpy(&mtrl, &pMaterials[i], sizeof(D3DXMATERIAL));

        pMeshContainer->materials.push_back(mtrl.MatD3D);

        IDirect3DTexture9* newTexture = NULL;



        if(mtrl.pTextureFilename != NULL)

        {

            char textureFname[200];

            strcpy(textureFname, "Data/");

            strcat(textureFname, mtrl.pTextureFilename);



            //Load texture

            D3DXCreateTextureFromFileA(g_pDevice, textureFname, &newTexture);

            pMeshContainer->textures.push_back(newTexture);

        }

        else

        {



            pMeshContainer->textures.push_back(newTexture);

        }



        

    

    }

#endif



    // if there is skinning information, save off the required data and then setup for HW skinning

    if (pSkinInfo != NULL)

    {

        // first save off the SkinInfo and original mesh data

        pMeshContainer->pSkinInfo = pSkinInfo;

        pSkinInfo->AddRef();



        pMeshContainer->pOrigMesh = pMesh;

        pMesh->AddRef();



        // Will need an array of offset matrices to move the vertices from the figure space to the bone's space

        cBones = pSkinInfo->GetNumBones();

        pMeshContainer->pBoneOffsetMatrices = new D3DXMATRIX[cBones];

        if (pMeshContainer->pBoneOffsetMatrices == NULL)

        {

            hr = E_OUTOFMEMORY;

            goto e_Exit;

        }



        // get each of the bone offset matrices so that we don't need to get them later

        for (iBone = 0; iBone < cBones; iBone++)

        {

            pMeshContainer->pBoneOffsetMatrices[iBone] = *(pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(iBone));

        }



        // GenerateSkinnedMesh will take the general skinning information and transform it to a HW friendly version

        hr = m_SkinnedMesh->GenerateSkinnedMesh(pMeshContainer);

        if (FAILED(hr))

            goto e_Exit;

    }



    *ppNewMeshContainer = pMeshContainer;

    pMeshContainer = NULL;

e_Exit:

    SAFE_RELEASE(pd3dDevice);



    // call Destroy function to properly clean up the memory allocated

    if (pMeshContainer != NULL)

    {

        DestroyMeshContainer(pMeshContainer);

    }



    return hr;

}



HRESULT CAllocateHierarchy::DestroyFrame(LPD3DXFRAME pFrameToFree)

{

    SAFE_DELETE_ARRAY( pFrameToFree->Name );

    SAFE_DELETE( pFrameToFree );

    return S_OK;



     

}



HRESULT CAllocateHierarchy::DestroyMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase)

{

    /*

    */

    //Release textures

    

    

    

UINT iMaterial;

    D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;



    SAFE_DELETE_ARRAY( pMeshContainer->Name );

    SAFE_DELETE_ARRAY( pMeshContainer->pAdjacency );

    SAFE_DELETE_ARRAY( pMeshContainer->pMaterials );

    SAFE_DELETE_ARRAY( pMeshContainer->pBoneOffsetMatrices );



    // release all the allocated textures

    if (pMeshContainer->ppTextures != 0)

    {

        for (iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++)

        {

            SAFE_RELEASE( pMeshContainer->ppTextures[iMaterial] );

        }

    }



    //SAFE_DELETE_ARRAY( pMeshContainer->ppTextures );

    SAFE_DELETE_ARRAY( pMeshContainer->ppBoneMatrixPtrs );

    SAFE_RELEASE( pMeshContainer->pBoneCombinationBuf );

    SAFE_RELEASE( pMeshContainer->MeshData.pMesh );

    SAFE_RELEASE( pMeshContainer->pSkinInfo );

    SAFE_RELEASE( pMeshContainer->pOrigMesh );

    SAFE_DELETE( pMeshContainer );

    return S_OK;

}



//-----------------------------------------------------------------------------

// Name: GenerateSkinnedMesh()

// Desc: Called either by CreateMeshContainer when loading a skin mesh, or when

//       changing methods.  This function uses the pSkinInfo of the mesh

//       container to generate the desired drawable mesh and bone combination

//       table.

//-----------------------------------------------------------------------------

HRESULT SkinnedMesh::GenerateSkinnedMesh(D3DXMESHCONTAINER_DERIVED *pMeshContainer)

{

    HRESULT hr = S_OK;



    if (pMeshContainer->pSkinInfo == NULL)

        return hr;



    SAFE_RELEASE( pMeshContainer->MeshData.pMesh );

    SAFE_RELEASE( pMeshContainer->pBoneCombinationBuf );



    // if non-indexed skinning mode selected, use ConvertToBlendedMesh to generate drawable mesh

    if (m_SkinningMethod == D3DNONINDEXED)

    {



        hr = pMeshContainer->pSkinInfo->ConvertToBlendedMesh

                                   (

                                       pMeshContainer->pOrigMesh,

                                       D3DXMESH_MANAGED|D3DXMESHOPT_VERTEXCACHE,

                                       pMeshContainer->pAdjacency,

                                       NULL, NULL, NULL,

                                       &pMeshContainer->NumInfl,

                                       &pMeshContainer->NumAttributeGroups,

                                       &pMeshContainer->pBoneCombinationBuf,

                                       &pMeshContainer->MeshData.pMesh

                                   );

        if (FAILED(hr))

            goto e_Exit;





        /* If the device can only do 2 matrix blends, ConvertToBlendedMesh cannot approximate all meshes to it

           Thus we split the mesh in two parts: The part that uses at most 2 matrices and the rest. The first is

           drawn using the device's HW vertex processing and the rest is drawn using SW vertex processing. */

        LPD3DXBONECOMBINATION rgBoneCombinations  = reinterpret_cast<LPD3DXBONECOMBINATION>(pMeshContainer->pBoneCombinationBuf->GetBufferPointer());



        // look for any set of bone combinations that do not fit the caps

        for (pMeshContainer->iAttributeSW = 0; pMeshContainer->iAttributeSW < pMeshContainer->NumAttributeGroups; pMeshContainer->iAttributeSW++)

        {

            DWORD cInfl   = 0;



            for (DWORD iInfl = 0; iInfl < pMeshContainer->NumInfl; iInfl++)

            {

                if (rgBoneCombinations[pMeshContainer->iAttributeSW].BoneId[iInfl] != UINT_MAX)

                {

                    ++cInfl;

                }

            }



            if (cInfl > m_d3dcaps.MaxVertexBlendMatrices)

            {

                break;

            }

        }



        // if there is both HW and SW, add the Software Processing flag

        if (pMeshContainer->iAttributeSW < pMeshContainer->NumAttributeGroups)

        {

            LPD3DXMESH pMeshTmp;



            hr = pMeshContainer->MeshData.pMesh->CloneMeshFVF(D3DXMESH_SOFTWAREPROCESSING|pMeshContainer->MeshData.pMesh->GetOptions(),

                                                pMeshContainer->MeshData.pMesh->GetFVF(),

                                                g_pDevice, &pMeshTmp);

            if (FAILED(hr))

            {

                goto e_Exit;

            }



            pMeshContainer->MeshData.pMesh->Release();

            pMeshContainer->MeshData.pMesh = pMeshTmp;

            pMeshTmp = NULL;

        }

    }

    // if indexed skinning mode selected, use ConvertToIndexedsBlendedMesh to generate drawable mesh

    else if (m_SkinningMethod == D3DINDEXED)

    {

        DWORD NumMaxFaceInfl;

        DWORD Flags = D3DXMESHOPT_VERTEXCACHE;



        LPDIRECT3DINDEXBUFFER9 pIB;

        hr = pMeshContainer->pOrigMesh->GetIndexBuffer(&pIB);

        if (FAILED(hr))

            goto e_Exit;



        hr = pMeshContainer->pSkinInfo->GetMaxFaceInfluences(pIB, pMeshContainer->pOrigMesh->GetNumFaces(), &NumMaxFaceInfl);

        pIB->Release();

        if (FAILED(hr))

            goto e_Exit;



        // 12 entry palette guarantees that any triangle (4 independent influences per vertex of a tri)

        // can be handled

        NumMaxFaceInfl = min(NumMaxFaceInfl, 12);



        if (m_d3dcaps.MaxVertexBlendMatrixIndex + 1 < NumMaxFaceInfl)

        {

            // HW does not support indexed vertex blending. Use SW instead

            pMeshContainer->NumPaletteEntries = min(256, pMeshContainer->pSkinInfo->GetNumBones());

            pMeshContainer->UseSoftwareVP = true;

            Flags |= D3DXMESH_SYSTEMMEM;

        }

        else

        {

            // using hardware - determine palette size from caps and number of bones

            // If normals are present in the vertex data that needs to be blended for lighting, then

            // the number of matrices is half the number specified by MaxVertexBlendMatrixIndex.

            pMeshContainer->NumPaletteEntries = min( ( m_d3dcaps.MaxVertexBlendMatrixIndex + 1 ) / 2,

                                                     pMeshContainer->pSkinInfo->GetNumBones() );

            pMeshContainer->UseSoftwareVP = false;

            Flags |= D3DXMESH_MANAGED;

        }



        hr = pMeshContainer->pSkinInfo->ConvertToIndexedBlendedMesh

                                                (

                                                pMeshContainer->pOrigMesh,

                                                Flags,

                                                pMeshContainer->NumPaletteEntries,

                                                pMeshContainer->pAdjacency,

                                                NULL, NULL, NULL,

                                                &pMeshContainer->NumInfl,

                                                &pMeshContainer->NumAttributeGroups,

                                                &pMeshContainer->pBoneCombinationBuf,

                                                &pMeshContainer->MeshData.pMesh);

        if (FAILED(hr))

            goto e_Exit;

    }

    // if vertex shader indexed skinning mode selected, use ConvertToIndexedsBlendedMesh to generate drawable mesh

    else if ((m_SkinningMethod == D3DINDEXEDVS) || (m_SkinningMethod == D3DINDEXEDHLSLVS))

    {

        // Get palette size

        // First 9 constants are used for other data.  Each 4x3 matrix takes up 3 constants.

        // (96 - 9) /3 i.e. Maximum constant count - used constants

        UINT MaxMatrices = 26;

        pMeshContainer->NumPaletteEntries = min(MaxMatrices, pMeshContainer->pSkinInfo->GetNumBones());



        DWORD Flags = D3DXMESHOPT_VERTEXCACHE;

        if (m_d3dcaps.VertexShaderVersion >= D3DVS_VERSION(1, 1))

        {

            pMeshContainer->UseSoftwareVP = false;

            Flags |= D3DXMESH_MANAGED;

        }

        else

        {

            pMeshContainer->UseSoftwareVP = true;

            Flags |= D3DXMESH_SYSTEMMEM;

        }



        SAFE_RELEASE(pMeshContainer->MeshData.pMesh);



        hr = pMeshContainer->pSkinInfo->ConvertToIndexedBlendedMesh

                                                (

                                                pMeshContainer->pOrigMesh,

                                                Flags,

                                                pMeshContainer->NumPaletteEntries,

                                                pMeshContainer->pAdjacency,

                                                NULL, NULL, NULL,             

                                                &pMeshContainer->NumInfl,

                                                &pMeshContainer->NumAttributeGroups,

                                                &pMeshContainer->pBoneCombinationBuf,

                                                &pMeshContainer->MeshData.pMesh);

        if (FAILED(hr))

            goto e_Exit;





        // FVF has to match our declarator. Vertex shaders are not as forgiving as FF pipeline

        DWORD NewFVF = (pMeshContainer->MeshData.pMesh->GetFVF() & D3DFVF_POSITION_MASK) | D3DFVF_NORMAL | D3DFVF_TEX1 | D3DFVF_LASTBETA_UBYTE4;

        if (NewFVF != pMeshContainer->MeshData.pMesh->GetFVF())

        {

            LPD3DXMESH pMesh;

            hr = pMeshContainer->MeshData.pMesh->CloneMeshFVF(pMeshContainer->MeshData.pMesh->GetOptions(), NewFVF, g_pDevice, &pMesh);

            if (!FAILED(hr))

            {

                pMeshContainer->MeshData.pMesh->Release();

                pMeshContainer->MeshData.pMesh = pMesh;

                pMesh = NULL;

            }

        }



        D3DVERTEXELEMENT9 pDecl[MAX_FVF_DECL_SIZE];

        LPD3DVERTEXELEMENT9 pDeclCur;

        hr = pMeshContainer->MeshData.pMesh->GetDeclaration(pDecl);

        if (FAILED(hr))

            goto e_Exit;



        // the vertex shader is expecting to interpret the UBYTE4 as a D3DCOLOR, so update the type

        //   NOTE: this cannot be done with CloneMesh, that would convert the UBYTE4 data to float and then to D3DCOLOR

        //          this is more of a "cast" operation

        pDeclCur = pDecl;

        while (pDeclCur->Stream != 0xff)

        {

            if ((pDeclCur->Usage == D3DDECLUSAGE_BLENDINDICES) && (pDeclCur->UsageIndex == 0))

                pDeclCur->Type = D3DDECLTYPE_D3DCOLOR;

            pDeclCur++;

        }



        hr = pMeshContainer->MeshData.pMesh->UpdateSemantics(pDecl);

        if (FAILED(hr))

            goto e_Exit;



        // allocate a buffer for bone matrices, but only if another mesh has not allocated one of the same size or larger

        if (m_NumBoneMatricesMax < pMeshContainer->pSkinInfo->GetNumBones())

        {

            m_NumBoneMatricesMax = pMeshContainer->pSkinInfo->GetNumBones();



            // Allocate space for blend matrices

            delete []m_pBoneMatrices;

            m_pBoneMatrices  = new D3DXMATRIXA16[m_NumBoneMatricesMax];

            if (m_pBoneMatrices == NULL)

            {

                hr = E_OUTOFMEMORY;

                goto e_Exit;

            }

        }



    }

    // if software skinning selected, use GenerateSkinnedMesh to create a mesh that can be used with UpdateSkinnedMesh

    else if (m_SkinningMethod == SOFTWARE)

    {

        hr = pMeshContainer->pOrigMesh->CloneMeshFVF(D3DXMESH_MANAGED, pMeshContainer->pOrigMesh->GetFVF(),

                                              g_pDevice, &pMeshContainer->MeshData.pMesh);

        if (FAILED(hr))

            goto e_Exit;



        hr = pMeshContainer->MeshData.pMesh->GetAttributeTable(NULL, &pMeshContainer->NumAttributeGroups);

        if (FAILED(hr))

            goto e_Exit;



        delete[] pMeshContainer->pAttributeTable;

        pMeshContainer->pAttributeTable  = new D3DXATTRIBUTERANGE[pMeshContainer->NumAttributeGroups];

        if (pMeshContainer->pAttributeTable == NULL)

        {

            hr = E_OUTOFMEMORY;

            goto e_Exit;

        }



        hr = pMeshContainer->MeshData.pMesh->GetAttributeTable(pMeshContainer->pAttributeTable, NULL);

        if (FAILED(hr))

            goto e_Exit;



        // allocate a buffer for bone matrices, but only if another mesh has not allocated one of the same size or larger

        if (m_NumBoneMatricesMax < pMeshContainer->pSkinInfo->GetNumBones())

        {

            m_NumBoneMatricesMax = pMeshContainer->pSkinInfo->GetNumBones();



            // Allocate space for blend matrices

            delete []m_pBoneMatrices;

            m_pBoneMatrices  = new D3DXMATRIXA16[m_NumBoneMatricesMax];

            if (m_pBoneMatrices == NULL)

            {

                hr = E_OUTOFMEMORY;

                goto e_Exit;

            }

        }

    }

    else  // invalid m_SkinningMethod value

    {        

        // return failure due to invalid skinning method value

        hr = E_INVALIDARG;

        goto e_Exit;

    }



e_Exit:

    return hr;

}









SkinnedMesh::SkinnedMesh(const D3DCAPS9& caps)

    : m_pRoot(0), m_pAnimCtrl(0), m_d3dcaps(caps)

{

    m_SkinningMethod = D3DINDEXEDHLSLVS;

    m_pBoneMatrices = NULL;

    m_NumBoneMatricesMax = 0;

}



SkinnedMesh::~SkinnedMesh()

{

    

    

    if (m_pRoot != NULL)

    {

        CAllocateHierarchy Alloc(this);    

        

        //Alloc.DestroyFrame(m_pRoot);

        D3DXFrameDestroy(m_pRoot, &Alloc);

        

        m_pRoot = NULL;

    }

    

    if (m_pAnimCtrl) { m_pAnimCtrl->Release(); m_pAnimCtrl = NULL; }

}







bool SkinnedMesh::Load(const std::wstring& filename)

{

    HRESULT hr = S_OK;

    

    CAllocateHierarchy Alloc(this);

    

    

    hr = D3DXLoadMeshHierarchyFromXW(filename.c_str(), D3DXMESH_MANAGED,

                               g_pDevice, &Alloc ,

                               NULL, &m_pRoot, &m_pAnimCtrl);

                               



    SetupBoneMatrixPointers((D3DXFRAME_DERIVED*)m_pRoot);

    //Update all the bones

    

    D3DXMATRIX i;

    

    D3DXMatrixIdentity(&i);

    UpdateMatrices((D3DXFRAME_DERIVED*)m_pRoot, &i);

    

    return true;

}



void SkinnedMesh::Update(const D3DXMATRIX& mat)

{

    D3DXMATRIX m(mat);

    this->UpdateMatrices((D3DXFRAME_DERIVED*)m_pRoot, &m);

}



void SkinnedMesh::Draw()

{

    Render(NULL);

}



void SkinnedMesh::UpdateMatrices(D3DXFRAME_DERIVED* f, D3DXMATRIX* parentMatrix)

{

    if(f == NULL)return;



    D3DXMatrixMultiply(&f->CombinedTransformationMatrix,

                       &f->TransformationMatrix,

                       parentMatrix);



    if(f->pFrameSibling != NULL)

    {

        UpdateMatrices((D3DXFRAME_DERIVED*)f->pFrameSibling, parentMatrix);

    }

    if(f->pFrameFirstChild != NULL)

    {

        UpdateMatrices((D3DXFRAME_DERIVED*)f->pFrameFirstChild, &f->CombinedTransformationMatrix);

    }

}



void SkinnedMesh::SetupBoneMatrixPointers(D3DXFRAME_DERIVED *bone)

{

    if(bone->pMeshContainer != NULL)

    {

        D3DXMESHCONTAINER_DERIVED *boneMesh = (D3DXMESHCONTAINER_DERIVED*)bone->pMeshContainer;



        if(boneMesh->pSkinInfo != NULL)

        {

            int NumBones = boneMesh->pSkinInfo->GetNumBones();

            boneMesh->ppBoneMatrixPtrs = new D3DXMATRIX*[NumBones];



            for(int i=0;i < NumBones;i++)

            {

                D3DXFRAME_DERIVED *b = (D3DXFRAME_DERIVED*)D3DXFrameFind(m_pRoot, boneMesh->pSkinInfo->GetBoneName(i));

                if(b != NULL)boneMesh->ppBoneMatrixPtrs[i] = &b->CombinedTransformationMatrix;

                else boneMesh->ppBoneMatrixPtrs[i] = NULL;

            }

        }

    }



    if(bone->pFrameSibling != NULL)SetupBoneMatrixPointers((D3DXFRAME_DERIVED*)bone->pFrameSibling);

    if(bone->pFrameFirstChild != NULL)SetupBoneMatrixPointers((D3DXFRAME_DERIVED*)bone->pFrameFirstChild);

}





void SkinnedMesh::Render(D3DXFRAME_DERIVED *f)

{

    if(f == NULL)f = (D3DXFRAME_DERIVED*)m_pRoot;



    //If there is a mesh to render...

    if(f->pMeshContainer != NULL)

    {

        D3DXMESHCONTAINER_DERIVED *boneMesh = (D3DXMESHCONTAINER_DERIVED*)f->pMeshContainer;



        if (boneMesh->pSkinInfo != NULL)

        {        

            

            // set up bone transforms

            int numBones = boneMesh->pSkinInfo->GetNumBones();

            for(int i=0;i < numBones;i++)

            {

                D3DXMatrixMultiply(&m_pBoneMatrices[i],

                    &boneMesh->pBoneOffsetMatrices[i],

                    boneMesh->ppBoneMatrixPtrs[i]);

            }



            D3DXMATRIX view, proj, identity;                

            g_pEffect->SetMatrixArray("FinalTransforms", m_pBoneMatrices, boneMesh->pSkinInfo->GetNumBones());

            



            //Render the mesh

            for(int i=0;i < (int)boneMesh->NumMaterials; i++)//>NumAttributeGroups;i++)

            {

                //int mtrlIndex = boneMesh->attributeTable[i].AttribId;

                //g_pDevice->SetMaterial(&(boneMesh->materials[mtrlIndex]));

                //g_pDevice->SetTexture(0, boneMesh->textures[mtrlIndex]);

                g_pDevice->SetMaterial(&(boneMesh->pMaterials[i]).MatD3D);

                g_pDevice->SetTexture(0, boneMesh->ppTextures[i]);

                g_pEffect->SetMatrix("matW", &f->CombinedTransformationMatrix);



                g_pEffect->SetVector( "materialColor",

                                         ( D3DXVECTOR4* )&(

                                         boneMesh->pMaterials[i].MatD3D.Diffuse ) );



                g_pEffect->SetTexture("texDiffuse", boneMesh->ppTextures[i]);

                D3DXHANDLE hTech = g_pEffect->GetTechniqueByName("Skinning");

                g_pEffect->SetTechnique(hTech);

                g_pEffect->Begin(NULL, NULL);

                g_pEffect->BeginPass(0);



                boneMesh->MeshData.pMesh->DrawSubset(i);



                g_pEffect->EndPass();

                g_pEffect->End();

            }

            

            

            

        }

        else

        {

            try

            {

                //Normal Static Mesh

                g_pEffect->SetMatrix("matW", &f->CombinedTransformationMatrix);



                D3DXHANDLE hTech = g_pEffect->GetTechniqueByName("Lighting");

                g_pEffect->SetTechnique(hTech);



                //Render the mesh

                



                for(int i=0;i < boneMesh->NumMaterials ;i++)

                {

                    g_pDevice->SetMaterial(&boneMesh->pMaterials[i].MatD3D);

                    g_pEffect->SetVector( "materialColor",

                                             ( D3DXVECTOR4* )&(

                                             boneMesh->pMaterials[i].MatD3D.Diffuse ) );

                    g_pEffect->SetTexture("texDiffuse", boneMesh->ppTextures[i]);



                    g_pEffect->Begin(NULL, NULL);

                    g_pEffect->BeginPass(0);



                    boneMesh->MeshData.pMesh->DrawSubset(i);



                    g_pEffect->EndPass();

                    g_pEffect->End();

                }

            }

            catch (std::bad_alloc e)

            {

                OutputDebugStringA(e.what());



            }

        }

    

    }

    if(f->pFrameSibling != NULL)

    {

        Render((D3DXFRAME_DERIVED*)f->pFrameSibling);

    }

    if(f->pFrameFirstChild != NULL)

    {

        Render((D3DXFRAME_DERIVED*)f->pFrameFirstChild);

    }

    

    

}

 

Thanks

Jack

 

 

Share this post


Link to post
Share on other sites

The first thing I'd look at before going into the code is to see weather the head was appearing somewhere else when rendering. Is the head a separate mesh from the body? and if so how does it's point of origin relate to the point of origin for the body.

 

Aimee

Share this post


Link to post
Share on other sites

I'm not going to debug your code - that is your job, but:

 

Every time the part of the mesh is missing start tracing backwards:

 

1. Check the export - amount of tris of the mesh in the 3D app that created it to make sure you aren't exporting the partial mesh.

2. Check the import - does your engine load correctly the full mesh  ? There might be numerous issues (e.g. UVs missing, normals missing, or something else)

3. Check the render - do you really render all tris that you think you do ?

 

 

I've had this issue countless times, and every single time the problem was one (or more) of the above.

Share this post


Link to post
Share on other sites

I recognize this code, it's the SDK skinned mesh sample. You mentioned you deleted the physique, unfortunately you need to add it back. That sample normally will not load your mesh if it's missing. Don't collapse the modifier into the mesh. Also when exporting to .x, have all of the BIP part in a separate layer and hide it before exporting. That way the tris won't get exported but the underlying skeleton will.

Share this post


Link to post
Share on other sites

This topic is 1711 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this