Skinning problem

Nov 13, 2013 at 7:42 AM
Edited Nov 13, 2013 at 7:42 AM
Welcome
I have a problem with skinning effect. In the file LoadModelCMO i changed ability to read volumes of information about the bones and animations. After checking the data read correctly the problem is that animates me only the first bone. Even when trying to scale the only other bones there are no results.

Structure of bones:

1 bone root ParentIndex = -1;
2 bone bone2 ParentIndex = 0;
3 bone bone3 ParentIndex = 1;
4 bone bone4 ParentIndex = 2;
5 bone bone5 ParentIndex = 3;

And i read animation like this
for (auto it = m_model->meshParts.cbegin(); it != m_model->meshParts.cend(); ++it)
    {
        auto part = it->get();
        assert(part != 0);
        auto iskin = dynamic_cast<IEffectSkinning*>(part->effect.get());
        if (iskin)
        {
            auto skinningInfo = m_model->BoneInfoCollection();
            for (UINT b = 0; b < skinningInfo.size(); b++)
            {
                m_bones.get()[b] = XMLoadFloat4x4(&skinningInfo[b].BoneLocalTransform);
            }
            
            // get keyframes
            auto animClips = m_model->AnimationClips();
            auto found = animClips.begin();
        
            if (found != animClips.end())
            {
                auto kf = found->second.Keyframes;
                for (auto frame : kf)
                {
                    if (frame.Time > m_animTime)
                    {
                        break;
                    }

                    m_bones.get()[frame.BoneIndex] = XMLoadFloat4x4(&frame.Transform);

                }
                
                for (UINT b = 1; b < skinningInfo.size(); ++b)
                {
                    ModelMesh::BoneInfo& skinning = skinningInfo[b];

                    if (skinning.ParentIndex < 0)
                    {
                    
                        continue;
                    }
                        
                    Matrix leftMat = m_bones.get()[b];
                    Matrix rightMat = m_bones.get()[skinning.ParentIndex];

                    Matrix ret = leftMat * rightMat;

                    m_bones.get()[b] = ret;
                }

                for (UINT b = 0; b < skinningInfo.size(); b++)
                {
                    Matrix leftMat = XMLoadFloat4x4(&skinningInfo[b].InvBindPos);
                    Matrix rightMat = m_bones.get()[b];

                    Matrix ret = leftMat * rightMat;
                    m_bones.get()[b] = ret;
                }

                if (m_animTime > found->second.EndTime)
                {
                    m_animTime = found->second.StartTime + (m_animTime - found->second.EndTime);
                }
                
            

                
            }
            iskin->SetBoneTransforms(m_bones.get(), skinningInfo.size());

            
        }
Coordinator
Nov 13, 2013 at 5:49 PM
I'm still in the process of parsing the animation data myself for work item 858--which is on hold while I attend to some other work at the moment, but I plan to return to it in the next month or so.

I know from my testing that SkinnedEffect and DGSLEffect will makes proper use of the SetBoneTransforms() data for rendering.

I assume you've already looked through the VS Starter Kit code to determine how they compute animation from the CMO data?
Nov 13, 2013 at 8:30 PM
Yes i used same techincs to import bones data and i use teapot model from VS Starter Kit code
Nov 14, 2013 at 1:20 PM
Propably its bug in code is
  skinv->SetBlendIndices( *reinterpret_cast<const XMUINT4*>( skinptr->boneIndex ) );
  skinv->SetBlendWeights( *reinterpret_cast<const XMFLOAT4*>( skinptr->boneWeight ) );
and i think should be
 skinv->SetBlendIndices(*reinterpret_cast<const XMUINT4*>(skinptr[v].boneIndex));
 skinv->SetBlendWeights(*reinterpret_cast<const XMFLOAT4*>(skinptr[v].boneWeight));
Marked as answer by walbourn on 1/23/2014 at 11:25 PM