Results 1 to 7 of 7

Thread: skinning implement problem

  1. #1
    Junior Member
    Join Date
    Jun 2010
    Posts
    1

    skinning implement problem

    Hi guys

    I am trying to implement skinning,

    here is the source code

    http://18ejdq.blu.livefilestore.com/y1p ... oad&psid=1
    or
    http://cid-2f2a55eaad2be759.office.live ... ollada.rar

    the key file is AnimationMesh.cpp

    below I will paste the code how I implement Skinning,the problem is I can't get right result as I expected.

    the skinning method I was refer to Nvidia DirectX SDK 10.5- Smoke.

    the problem is skinning result is wrong.....

    I am sure I get right skinning weights and influnce joints for each vertex.
    the key file is

    ColladaControllers.cpp
    void sController::sSkin::GenerateWeightsAndBonesData()

    if someone teach how I make it right,and it works I would like to share full source code for everyone

    ================================================== ============
    below is how I implement skinning

    Code :
    Vector3	cAnimationMesh::GetSkinWorldPosBySkinningData(Vector3 e_vPos,float*e_pfWeihts,char*e_pcInflunceBoneIndex,cMatrix44*e_pBoneMatrices)
    {
    	Vector3	l_vFinalPos = Vector3::Zero;
    #ifdef _DEBUG
    	float	l_f[4] = {e_pfWeihts[0],e_pfWeihts[1],e_pfWeihts[2],e_pfWeihts[3]};
    	if( l_f[0]+l_f[1]+l_f[2]+l_f[3]<=0.9f )
    	{
    		assert(0);
    	}
    	char	l_InflunceJointIndex[4] = {e_pcInflunceBoneIndex[0],e_pcInflunceBoneIndex[1],e_pcInflunceBoneIndex[2],e_pcInflunceBoneIndex[3]};
    #endif
    	//if( e_pcInflunceBoneIndex[0] >1 )
    	//	return Vector3(-10,10,10);
    	cMatrix44	l_mat = cMatrix44::Identity;
    	//if(e_pfWeihts[0]>MIN_VALID_WEIGHT)
    	if( e_pcInflunceBoneIndex[0] != -1 )
    	{
    		l_vFinalPos += e_pBoneMatrices[e_pcInflunceBoneIndex[0]].TransformVector(e_vPos)*e_pfWeihts[0];
    	}
    	//if(e_pfWeihts[1]>MIN_VALID_WEIGHT)
    	if( e_pcInflunceBoneIndex[1] != -1 )
    	{
    		l_vFinalPos += e_pBoneMatrices[e_pcInflunceBoneIndex[1]].TransformVector(e_vPos)*e_pfWeihts[1];
    	}
    	//if(e_pfWeihts[2]>MIN_VALID_WEIGHT)
    	if( e_pcInflunceBoneIndex[2] != -1 )
    	{
    		l_vFinalPos += e_pBoneMatrices[e_pcInflunceBoneIndex[2]].TransformVector(e_vPos)*e_pfWeihts[2];
    	}
    	//if(e_pfWeihts[3]>MIN_VALID_WEIGHT)
    	if( e_pcInflunceBoneIndex[3] != -1 )
    	{
    		l_vFinalPos += e_pBoneMatrices[e_pcInflunceBoneIndex[3]].TransformVector(e_vPos)*e_pfWeihts[3];
    	}
    	return l_vFinalPos;
    }
     
     
    	int	l_iBoneSize = this->m_AllBoneVector.GetNum();
    	cBone**l_ppBone = &(*m_AllBoneVector.GetList())[0];
    	for(int i=0;i<l_iBoneSize;++i)
    	{
    		//boneMatrix = boneIt->node->worldXForm * boneIt->invBindPose * instIt->meshBindPose;
    		//invert multiply
    		cMatrix44  l_WorldTransform =  l_ppBone[i]->GetWorldTransform();
    		//cMatrix44  l_WorldTransform;// =  this->m_matBindPose * l_ppBone[i]->GetInvBindPose() * l_ppBone[i]->GetWorldTransform();
    		cMatrix44 aaa = l_ppBone[i]->GetInvBindPose();
    		//l_WorldTransform = l_ppBone[i]->GetWorldTransform() * l_ppBone[i]->GetInvBindPose().Inverted() * this->m_matBindPose;
    		//m_pAllBonesMatrixForSkinned[i] = l_WorldTransform;
    		m_pAllBonesMatrixForSkinned[i] = aaa*l_WorldTransform;
    		//m_pShaderParameter->GetBonesMatrixVariable()->SetMatrixArray((float*)&l_WorldTransform2,i,1);
    	}
    	//OutputDebugString(L"FUCK!!!\n");
    	//OutputDebugString(L"glGet GL_ARRAY_BUFFER_BINDING,GL_ELEMENT_ARRAY_BUFFER_BINDING,before get buffer data u have to glBindBuffer(GL_ARRAY_BUFFER, l_uiBufferID);");
    	//here should get position data by glBindBuffer(GL_ARRAY_BUFFER, l_uiBufferID);.
    	Vector3	*l_pvPos = 0;
    	if( !m_pVBOBuffer )
    		l_pvPos = (Vector3*)this->m_ppfVerticesBuffer[FVF_POS];
    	else
    		l_pvPos = (Vector3*)this->m_pVBOBuffer->GetData(POSITION_LOCATION);
    	float*	l_fWeight = this->m_ppfVerticesBuffer[FVF_SKINNING_WEIGHT];
    	char*	l_pcInflunceJoints = (char*)m_ppfVerticesBuffer[FVF_SKINNING_BONE_INDEX];//endusr the size as expected
    	cMatrix44	l_mat;
    	for( UINT i=0;i<m_uiVertexBufferCount;++i )
    	{
    		Vector3	l_vPos = GetSkinWorldPosBySkinningData(l_pvPos[i],&l_fWeight[i*4],&l_pcInflunceJoints[i*4],m_pAllBonesMatrixForSkinned);
    		int	l_iTest = l_pcInflunceJoints[i*4];
    		if( l_iTest != 4 )
    		{
    			int a=0;
    		}
    		m_pvVertexBuferForSkinned[i*3] = l_vPos.x;
    		m_pvVertexBuferForSkinned[i*3+1] = l_vPos.y;
    		m_pvVertexBuferForSkinned[i*3+2] = l_vPos.z;
    		//m_pvVertexBuferForSkinned[i*3] = l_pvPos[i].x;
    		//m_pvVertexBuferForSkinned[i*3+1] = l_pvPos[i].y;
    		//m_pvVertexBuferForSkinned[i*3+2] = l_pvPos[i].z;
    	}

    and how I update animation

    Code :
    void cAnimationMesh::UpdateNodes(float e_fTimeValue)
    {
        assert((e_fTimeValue>=m_fMinKeyTime) && (e_fTimeValue <=m_fMaxKeyTime));
     
        if(m_fLastNodesUpdateTime == e_fTimeValue)
            return;
     
    	int	l_iNum = this->m_AllBoneVector.GetNum();
        for(int i=0;i<l_iNum;++i)
        {
    		if(!m_AllBoneVector[i]->GetParent())
                UpdateNode(m_AllBoneVector[i],e_fTimeValue);
        }
     
        m_fLastNodesUpdateTime = e_fTimeValue;
    }
    //========================================================
    //
    //========================================================
    void	cAnimationMesh::UpdateNode(cBone*e_pBone,float e_fTime)
    {
    	//assert(0&&"only need to update children");
    	e_pBone->EvaluateLocalXForm(e_fTime);
    	if (e_pBone->GetFirstChild() != NULL)
    	{
    		UpdateNode( (cBone*)e_pBone->GetFirstChild(),e_fTime);
    	}
     
    	if( e_pBone->GetNextSibling() != NULL)
    	{
    		UpdateNode( (cBone*)e_pBone->GetNextSibling(),e_fTime);
    	}	
    	//if( e_pBone->GetParent() )
    	//	e_pBone->SetWorldTransform(e_pBone->GetParent()->GetWorldTransform()*e_pBone->GetLocalTransform());
    	//else
    	//	e_pBone->SetWorldTransform(e_pBone->GetLocalTransform());
    }
    //========================================================
    //
    //========================================================
    void	cAnimationMesh::Update(float elapsedTime)
    {
        float newTime(m_fCurrentTime);
        // Handle time advance based on animation playback options
        if((m_fCurrentTime+elapsedTime) > m_fEndTime)
        {
            float endMinusStart = m_fEndTime-m_fStartTime;
            if( endMinusStart > 0.001)
            {
                //switch(m_animEndHandling)
                //{
                //case LOOP:
                //    {
                    float overTime = (m_fCurrentTime + elapsedTime - m_fEndTime);
                    newTime = m_fStartTime + fmod(overTime, endMinusStart);
                //    }
                //    break;
                //case BLOCK:
                //default:
                //    newTime = m_endTime;
                //    break;
                //}
            }
            else
            {
                newTime = m_fCurrentTime;
            }
        }
        else
        {
            newTime = m_fCurrentTime + elapsedTime;
        };    
        m_fCurrentTime = newTime;
    	//if(m_fCurrentTime>m_fEndTime)
    	//	m_fCurrentTime -= m_fEndTime;
    	SetCurrentAnimationTime(m_fCurrentTime);
    }
    //========================================================
    //
    //========================================================
    void	cAnimationMesh::SetCurrentAnimationTime(float e_fCurrentTime)
    {
    	this->m_fCurrentTime = e_fCurrentTime;
    	assert(this->m_fMinKeyTime <= this->m_fMaxKeyTime);
    	float	l_fUpdateTime = 0;
        if(m_fCurrentTime > m_fMaxKeyTime)
    		UpdateNode(m_pMainRootBone,m_fMaxKeyTime);
    		//l_fUpdateTime = m_fMaxKeyTime;
        else if(m_fCurrentTime< m_fMinKeyTime)
    		UpdateNode(m_pMainRootBone,m_fMinKeyTime);
    		//l_fUpdateTime = m_fMinKeyTime;
        else
    		UpdateNode(m_pMainRootBone,m_fCurrentTime);
    		l_fUpdateTime = m_fCurrentTime;
    	//for(int i=0;i<this->m_AllBoneVector.GetNum();++i)
    	//{
    	//	if(m_AllBoneVector[i]->GetParent() == NULL)
    	//		m_AllBoneVector[i]->EvaluateLocalXForm(l_fUpdateTime);
    	//}
    }

  2. #2
    Junior Member
    Join Date
    Jun 2010
    Posts
    1

    Re: skinning implement problem

    sorry...after I clicked submit.....I saw a choose file button.....
    so I upload the file

  3. #3
    Junior Member
    Join Date
    Jun 2010
    Posts
    1

    Re: skinning implement problem

    it seems no anybody here ,but I still keep doing my project,now I got a new problem...
    I have render skeleton correctly,but the mesh is wrong,the attach images show the result, it looks like setup wrong influence joints or somethings...Could anybody just take a glance and tell me what possible wrong it is.


    thanks for all

  4. #4
    Senior Member
    Join Date
    Aug 2004
    Location
    California
    Posts
    771

    Re: skinning implement problem

    Sorry that no one can take the time to debug your code for you. There is plenty of existing COLLADA skinning and animation code in the open source community that you can examine to learn where your code is going wrong.

  5. #5
    Junior Member
    Join Date
    Jun 2010
    Posts
    1

    Re: skinning implement problem

    Quote Originally Posted by marcus
    Sorry that no one can take the time to debug your code for you. There is plenty of existing COLLADA skinning and animation code in the open source community that you can examine to learn where your code is going wrong.
    Hi marcus
    thanks for replay,I know it's hard to ask someone who would like to spend lots time to debug for me,I will finish it one day,and write a tutorial for all guys who need use it.

    All the open source tutorial are using different way to implement Collada,some of them choice third party library to get all Collada data(FCollada),or Skinning demo in XNA or ColladaDOM,the XNA demo seems simple enough to me, but it still is not simple enough to the people who first time to learn Collada,if you got time please go check my data structure,it is quite stupid but easy,I hope one day I could share a tutorial which use such stupid way to implement Collada

  6. #6
    Senior Member
    Join Date
    Aug 2004
    Location
    California
    Posts
    771

    Re: skinning implement problem

    Have you read all the forum threads on skinning?

    Like this one? viewtopic.php?f=12&t=1485

  7. #7
    Junior Member
    Join Date
    Jun 2010
    Posts
    1

    Re: skinning implement problem

    Thanks Marcus!!

    I have read all thread about skinning,and finally it seems work for some model...

    I will post it and share the code and my XML tool,but it does't parse well for all Collada files,I will keep maintain it and post in my blog

    here is the link

    http://fatmingwang.spaces.live.com/default.aspx

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •