No Animation is happening with this code snippet.

Started by
6 comments, last by lucky6969b 10 years, 11 months ago

Hi Folks,

I don't get any animations out of this code, the model is confirmed to be animated in mesh viewer.

shader


////////////////////////////////////////////////////////////////////////////



extern float4x4 FinalTransforms[100];

extern int NumVertInfluences = 2; // <--- Normally set dynamically.



//Vertex Input

struct VS_INPUT_SKIN

{

     float4 position : POSITION0;

     float3 normal   : NORMAL;

     float2 tex0     : TEXCOORD0;

     float4 weights  : BLENDWEIGHT0;

     int4   boneIndices : BLENDINDICES0;

};



VS_OUTPUT vs_Skinning(VS_INPUT_SKIN IN)

{

    VS_OUTPUT OUT = (VS_OUTPUT)0;



    float4 p = float4(0.0f, 0.0f, 0.0f, 1.0f);

    float3 norm = float3(0.0f, 0.0f, 0.0f);

    float lastWeight = 0.0f;

    int n = NumVertInfluences-1;

    

    norm = normalize(IN.normal);

    

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

    {

        lastWeight += IN.weights;

        p += IN.weights * mul(IN.position, FinalTransforms[IN.boneIndices]);

        norm += IN.weights * mul(IN.normal, FinalTransforms[IN.boneIndices]);

    }

    lastWeight = 1.0f - lastWeight;

    

    p += lastWeight * mul(IN.position, FinalTransforms[IN.boneIndices[n]]);

    norm += lastWeight * mul(IN.normal, FinalTransforms[IN.boneIndices[n]]);

    

    p.w = 1.0f;        

    float4 posWorld = mul(p, matW);

    OUT.position = mul(posWorld, matVP);

    OUT.tex0 = IN.tex0;

    

    //Calculate Lighting

    norm = normalize(norm);

    norm = mul(norm, matW);

    OUT.shade = max(dot(norm, normalize(lightPos - posWorld)), 0.2f);

     

    return OUT;

}

main logics


if( SUCCEEDED(beginScene()) )

            {

                D3DXMATRIXA16 mViewProj = D3DXMATRIXA16((float*)&ViewMatrix()) * D3DXMATRIXA16((float*)&ProjMatrix());

                // DX10 spec only guarantees Sincos function from -100 * Pi to 100 * Pi

                float fBoundedTime = (float) m_fTime - (floor( (float) m_fTime / (2.0f * D3DX_PI)) * 2.0f * D3DX_PI);



                //m_pConstantTable->SetMatrix( g_pDevice, "mWorldViewProj", &mWorldViewProj );

                //m_pConstantTable->SetFloat( g_pDevice, "fTime", fBoundedTime );

                g_pEffect->SetMatrix("matVP", &mViewProj);



                g_pEffect->SetVector("lightPos", &D3DXVECTOR4(0.0f, -1.0f, 0.0f, 0.0f));

                //g_pEffect->SetFloat("fTime", fBoundedTime);

            

                

                for (int i = 0; i < m_vRenderObjects.size(); i++)

                {

                    D3DXMATRIX mat = m_vRenderObjects->GetWorldMatrix();

                    m_vRenderObjects->GetMesh()->Update(mat, fBoundedTime);

                    m_vRenderObjects->GetMesh()->Draw();

                }

                

                 

    



                endScene();

            }

SkinnedMesh.cpp


void SkinnedMesh::Update(const D3DXMATRIX& mat, float dt)

{

    D3DXMATRIX m(mat);



    if (m_pAnimCtrl)

    {

        m_pAnimCtrl->AdvanceTime(dt, NULL);

    }

        



    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 = &b->CombinedTransformationMatrix;

                else boneMesh->ppBoneMatrixPtrs = 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,

                    &boneMesh->pBoneOffsetMatrices,

                    boneMesh->ppBoneMatrixPtrs);

            }



            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.AttribId;

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

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

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

                g_pDevice->SetTexture(0, boneMesh->ppTextures);

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



                g_pEffect->SetVector( "materialColor",

                                         ( D3DXVECTOR4* )&(

                                         boneMesh->pMaterials.MatD3D.Diffuse ) );



                if (boneMesh->ppTextures != NULL)

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

                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

        {

        

                //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.MatD3D);

                    g_pEffect->SetVector( "materialColor",

                                             ( D3DXVECTOR4* )&(

                                             boneMesh->pMaterials.MatD3D.Diffuse ) );



                    if (boneMesh->ppTextures != NULL)

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



                    g_pEffect->Begin(NULL, NULL);

                    g_pEffect->BeginPass(0);



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



                    g_pEffect->EndPass();

                    g_pEffect->End();

                }

            }

        

        

    

    }

    if(f->pFrameSibling != NULL)

    {

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

    }

    if(f->pFrameFirstChild != NULL)

    {

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

    }

    

    

}



void SkinnedMesh::SetAnimation(std::string name)

{

    ID3DXAnimationSet *anim = NULL;



    int numAnims = (int)m_pAnimCtrl->GetMaxNumAnimationSets();



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

    {

        anim = NULL;

        m_pAnimCtrl->GetAnimationSet(i, &anim);



        if(anim != NULL)

        {

            if(strcmp(name.c_str(), anim->GetName()) == 0)

                m_pAnimCtrl->SetTrackAnimationSet(0, anim);

            anim->Release();

        }

    }

}





void SkinnedMesh::GetAnimations(std::vector<std::string> &animations)

{

    ID3DXAnimationSet *anim = NULL;



    if (m_pAnimCtrl)

    {



        for(int i=0;i<(int)m_pAnimCtrl->GetMaxNumAnimationSets();i++)

        {

            anim = NULL;

            m_pAnimCtrl->GetAnimationSet(i, &anim);



            if(anim != NULL)

            {

                animations.push_back(anim->GetName());

                anim->Release();

            }

        }



    }

    else

    {

        animations.clear();

    }

}

Please help

Thanks

Jack

Advertisement

You cannot have 100 x float4x4, maximum is 64

float4x4 FinalTransforms[100];

Hi Belfegor,

I have brought it down to 60 to no avail.

It is still not animating.

Any further suggestions?

Thanks

Jack

the time value is to small

+1 what ankhd said, also enable d3d debug runtime to see debug messages and check all functions that return HRESULT for error.

It looks like you are just copy-pasting the code from somewhere without understanding what it does, what it needs and how is the whole pipeline set up.

Break it down into smaller steps and fix those first:

1. Confirm that the rendering code is OK - Can you render the mesh without any animation - e.g. just a single static frame ? This will make sure that the vertex stream matches the data that shader receives and confirms that your render pipeline is set up correctly.

2. Start by slowly adding feature by feature, into the shader, and note which one breaks it.

VladR My 3rd person action RPG on GreenLight: http://steamcommunity.com/sharedfiles/filedetails/?id=92951596

The PIX program suddenly stops working. I run the experiment, see the output and no debug pane comes out.

So I need to debug it by hand. I can see the m_pBoneMatrices change every time, so it must be in the shader

Any suggestions that why the shader fails?

Thanks

Jack

After changing the code beneath, the first keyframe is shown, but it is still not moving

{
        // 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 = 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
                                                (
                                                pMesh,
                                                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;
            }
        }

    }

DWORD t = GetTickCount();
    
            
            if( SUCCEEDED(beginScene()) )
            {
                D3DXMATRIXA16 mViewProj = D3DXMATRIXA16((float*)&ViewMatrix()) * D3DXMATRIXA16((float*)&ProjMatrix());
                // DX10 spec only guarantees Sincos function from -100 * Pi to 100 * Pi
                //float fBoundedTime = (float) m_fTime - (floor( (float) m_fTime / (2.0f * D3DX_PI)) * 2.0f * D3DX_PI);
                
                float deltaTime = (t - m_fTime) * 0.001f;

                //m_pConstantTable->SetMatrix( g_pDevice, "mWorldViewProj", &mWorldViewProj );
                //m_pConstantTable->SetFloat( g_pDevice, "fTime", fBoundedTime );
                g_pEffect->SetMatrix("matVP", &mViewProj);

                g_pEffect->SetVector("lightPos", &D3DXVECTOR4(0.0f, -1.0f, 0.0f, 0.0f));
                //g_pEffect->SetFloat("fTime", fBoundedTime);
            
                
                for (int i = 0; i < m_vRenderObjects.size(); i++)
                {
                    D3DXMATRIX mat = m_vRenderObjects->GetWorldMatrix();
                    m_vRenderObjects->GetMesh()->Update(mat, deltaTime);
                    m_vRenderObjects->GetMesh()->Draw();
                }
                
                 
    

                endScene();
            }

This topic is closed to new replies.

Advertisement