游戏开发论坛

 找回密码
 立即注册
搜索
查看: 5332|回复: 12

为什么我渲染的一个骨骼动画角色会是乱的,头脚不分. ?

[复制链接]

20

主题

33

帖子

33

积分

注册会员

Rank: 2

积分
33
发表于 2007-4-3 16:25:00 | 显示全部楼层 |阅读模式
为什么我渲染的一个骨骼动画角色会是乱的,头脚不分.   ?

这是我渲染出来的
sf_200743162437.jpg

20

主题

33

帖子

33

积分

注册会员

Rank: 2

积分
33
 楼主| 发表于 2007-4-3 16:27:00 | 显示全部楼层

Re:为什么我渲染的一个骨骼动画角色会是乱的,头脚不分. ?

绿的是脚,红黄的是头,脚会动,但我渲染竟然只有半条.

15

主题

363

帖子

390

积分

中级会员

Rank: 3Rank: 3

积分
390
发表于 2007-4-3 16:32:00 | 显示全部楼层

Re:为什么我渲染的一个骨骼动画角色会是乱的,头脚不分. ?

……我没做过,不知道……

不过你不把关键代码贴出来……
大家怎么帮你看啊……?

20

主题

33

帖子

33

积分

注册会员

Rank: 2

积分
33
 楼主| 发表于 2007-4-3 16:38:00 | 显示全部楼层

Re:为什么我渲染的一个骨骼动画角色会是乱的,头脚不分. ?

CSkinMesh::CSkinMesh(LPDIRECT3DDEVICE9 pD3DDevice)
{
m_pAnimController=NULL;
m_pd3dDevice=pD3DDevice;
m_pFrameRoot=NULL;

D3DXMatrixIdentity(&m_matMoveMatrices);

m_fStartTime=0.0f;
}

CSkinMesh::~CSkinMesh()
{

}
HRESULT CSkinMesh:oadFromXFile(TCHAR* strFileName)
{
        CAllocateHierarchy Alloc(this);
          
    if(D3DXLoadMeshHierarchyFromX(strFileName, D3DXMESH_MANAGED, m_pd3dDevice, &Alloc, NULL, &m_pFrameRoot, &m_pAnimController)!=D3D_OK)
        {
      return D3DERR_INVALIDCALL;
        }

        if(m_pFrameRoot==NULL)
        {
                return D3DERR_INVALIDCALL;
        }
        if(SetupBoneMatrixPointers(m_pFrameRoot)!=D3D_OK)
                return D3DERR_INVALIDCALL;
        if(D3DXFrameCalculateBoundingSphere(m_pFrameRoot, &m_vObjectCenter, &m_fObjectRadius)!=D3D_OK)
        {
                return D3DERR_INVALIDCALL;
        }

        return D3D_OK;
}
HRESULT CSkinMesh::SetupBoneMatrixPointers( LPD3DXFRAME pFrame )
{
  if(pFrame->pMeshContainer!=NULL)
  {
    if(SetupBoneMatrixPointersOnMesh(pFrame->pMeshContainer)!=D3D_OK)
        {
                return D3DERR_INVALIDCALL;
        }
  }
  if(pFrame->pFrameSibling!=NULL)
  {
         if( SetupBoneMatrixPointers(pFrame->pFrameSibling)!=D3D_OK)
         {
                 return D3DERR_INVALIDCALL;
         }
  }
  if(pFrame->pFrameFirstChild!=NULL)
  {
     if(SetupBoneMatrixPointers(pFrame->pFrameFirstChild)!=D3D_OK)
         {
                 return D3DERR_INVALIDCALL;
         }
  }
  return D3D_OK;
}
HRESULT CSkinMesh::SetupBoneMatrixPointersOnMesh( LPD3DXMESHCONTAINER pMeshContainerBase )
{
  D3DXFRAME_DERIVED* pFrame=NULL;
  D3DXMESHCONTAINER_DERIVED* pMeshContainer=(D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;
  if(pMeshContainer->pSkinInfo!=NULL)
  {
          UINT Bones=pMeshContainer->pSkinInfo->GetNumBones();
      pMeshContainer->ppBoneMatrixPtrs =new D3DXMATRIX*[Bones];
          if(pMeshContainer==NULL)
          {
                  return E_OUTOFMEMORY;
          }
          for(UINT I=0;I<Bones;I++)
          {
        pFrame=(D3DXFRAME_DERIVED*)D3DXFrameFind(m_pFrameRoot,pMeshContainer->pSkinInfo->GetBoneName(I));
        pMeshContainer->ppBoneMatrixPtrs[I]=&pFrame->matCombined;
          }
  }
  return D3D_OK;
}
HRESULT CSkinMesh::GenerateSkinnedMesh(D3DXMESHCONTAINER_DERIVED* pMeshContainer)
{
LPDIRECT3DINDEXBUFFER9 pIB;
if(pMeshContainer->pOrigMesh->GetIndexBuffer(&pIB)!=D3D_OK)
{
        return D3DERR_INVALIDCALL;
}
DWORD maxFaceInfluences;
if(pMeshContainer->pSkinInfo->GetMaxFaceInfluences(pIB,pMeshContainer->pOrigMesh->GetNumFaces(),&maxFaceInfluences)!=D3D_OK){
return  D3DERR_INVALIDCALL;
}
//sSAFE_RELEASE(pIB);
pMeshContainer->NumPaletteEntries=min(128,pMeshContainer->pSkinInfo->GetNumBones());
pMeshContainer->MeshData.pMesh=NULL;
pMeshContainer->pBoneCombinationBuf=NULL;
if(pMeshContainer->pSkinInfo->ConvertToIndexedBlendedMesh(pMeshContainer->pOrigMesh,NULL,
   pMeshContainer->NumPaletteEntries,
   pMeshContainer->pAdjacency,
   NULL, NULL, NULL,
   &pMeshContainer->NumInfl,
   &pMeshContainer->NumAttributeGroups,
   &pMeshContainer->pBoneCombinationBuf,
   &pMeshContainer->MeshData.pMesh)!=D3D_OK)
{
return  D3DERR_INVALIDCALL;
}
  return D3D_OK;
}
VOID CSkinMesh::UpdateFrameMatrices( LPD3DXFRAME pFrameBase, LPD3DXMATRIX pParentMatrix )
{
  D3DXFRAME_DERIVED* pFrame=(D3DXFRAME_DERIVED*)pFrameBase;
  if(pParentMatrix!=NULL)
  {
   D3DXMatrixMultiply(&pFrame->matCombined,&pFrame->TransformationMatrix,pParentMatrix);
  }else{
    pFrame->matCombined=pFrame->TransformationMatrix;
  }
  if(pFrame->pFrameSibling!=NULL)
  {
      UpdateFrameMatrices(pFrame->pFrameSibling,pParentMatrix);
  }
    if(pFrame->pFrameFirstChild!=NULL)
  {
      UpdateFrameMatrices(pFrame->pFrameFirstChild,pParentMatrix);
  }
}
VOID CSkinMesh::Render()
{
double fElapsedTime=0.0;
fElapsedTime=fElapsedTime+30.0 ;);//先做测试型简单的变化
    D3DXMATRIXA16 matWorld,matWorld2;
        //先将角色的中心点平移到世界坐标系的原点
    D3DXMatrixTranslation(&matWorld, -m_vObjectCenter.x,
                                  -m_vObjectCenter.y,
                                  -m_vObjectCenter.z );
        //将角色的中心点向上提高,保证角色的脚站在地面上
    D3DXMatrixTranslation( &matWorld2, 0,m_fObjectRadius,0);
        //以上两个变换的合成矩阵
        D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2);
        //角色绕Y轴旋转m_fRotateAngle角
        D3DXMatrixRotationY(&matWorld2,m_fRotateAngle);  //旋转矩阵
        D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2);  //旋转变换
        //与移步矩阵相乘得到最终的合成矩阵
        D3DXMatrixMultiply(&matWorld,&matWorld,&m_matMoveMatrices);
        //设置渲染管道流水线的世界坐标变换矩阵
    m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
        m_pAnimController->AdvanceTime(fElapsedTime,NULL);//先做测试型简单的变化


        UpdateFrameMatrices(m_pFrameRoot, &matWorld);
        //渲染一帧
        DrawFrame(m_pFrameRoot);
}
VOID CSkinMesh:rawMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase)
{
      D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;
    D3DXFRAME_DERIVED *pFrame = (D3DXFRAME_DERIVED*)pFrameBase;
    UINT iMaterial;
    UINT iAttrib;
    LPD3DXBONECOMBINATION pBoneComb;
    UINT iMatrixIndex;
    UINT iPaletteEntry;
    D3DXMATRIXA16 matTemp;
       
    if (pMeshContainer->pSkinInfo != NULL)
    {
                        if (pMeshContainer->NumInfl)
                m_pd3dDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE);
            if (pMeshContainer->NumInfl == 1)
                m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_0WEIGHTS);
            else
                m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, pMeshContainer->NumInfl - 1);
            //取得网格子集的组合属性表(包括子集内的各个骨骼id)
                        pBoneComb =(LPD3DXBONECOMBINATION)pMeshContainer->pBoneCombinationBuf->GetBufferPointer();
            //每子集
                        for (iAttrib = 0; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++)
            {
                //每个子集内的每个骨骼,逐个计算世界坐标变换矩阵
                for (iPaletteEntry = 0; iPaletteEntry < pMeshContainer->NumPaletteEntries; ++iPaletteEntry)
                {
                    iMatrixIndex = pBoneComb[iAttrib].BoneId[iPaletteEntry]; //取出骨骼id
                    if (iMatrixIndex != UINT_MAX)
                    {
                        D3DXMatrixMultiply( &matTemp, &pMeshContainer->pBoneOffsetMatrices[iMatrixIndex], pMeshContainer->ppBoneMatrixPtrs[iMatrixIndex] );
                        m_pd3dDevice->SetTransform( D3DTS_WORLDMATRIX( iPaletteEntry ), &matTemp );
                    }
                }
                //设置材质
                m_pd3dDevice->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D );
                m_pd3dDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] );
                //用当前的矩阵调板渲染网格子集
                pMeshContainer->MeshData.pMesh->DrawSubset( iAttrib );
            }
            //恢复渲染状态标志
            m_pd3dDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
            m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);
    }   
    else  //网格没有骨骼动画数据
    {
        m_pd3dDevice->SetTransform(D3DTS_WORLD, &pFrame->matCombined);
        for (iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++)
        {
            m_pd3dDevice->SetMaterial( &pMeshContainer->pMaterials[iMaterial].MatD3D );
            m_pd3dDevice->SetTexture( 0, pMeshContainer->ppTextures[iMaterial] );
            pMeshContainer->MeshData.pMesh->DrawSubset(iMaterial);
        }
    }

}
VOID CSkinMesh::DrawFrame(LPD3DXFRAME pFrame)
{
    LPD3DXMESHCONTAINER pMeshContainer;
       
    pMeshContainer = pFrame->pMeshContainer;
    while (pMeshContainer != NULL)
    {
        DrawMeshContainer(pMeshContainer, pFrame); //渲染网格
        pMeshContainer = pMeshContainer->pNextMeshContainer;
    }
       
    if (pFrame->pFrameSibling != NULL)
    {
        DrawFrame(pFrame->pFrameSibling);  //递归调用
    }
       
    if (pFrame->pFrameFirstChild != NULL)
    {
        DrawFrame(pFrame->pFrameFirstChild);
    }
}



当我建该对象成功之后,随之调用Render() 就是那样罗

3

主题

24

帖子

24

积分

注册会员

Rank: 2

积分
24
发表于 2007-4-3 19:04:00 | 显示全部楼层

Re:为什么我渲染的一个骨骼动画角色会是乱的,头脚不分. ?

怎么没有递归的便历?

2

主题

41

帖子

47

积分

注册会员

Rank: 2

积分
47
发表于 2007-10-24 16:05:00 | 显示全部楼层

Re:为什么我渲染的一个骨骼动画角色会是乱的,头脚不分. ?

directx sdk里的tiny呀,我做的时候也和你一模一样过,你的代码还没有写全,多做看那个例子吧,

59

主题

984

帖子

1200

积分

金牌会员

Rank: 6Rank: 6

积分
1200
发表于 2007-10-24 17:05:00 | 显示全部楼层

Re:为什么我渲染的一个骨骼动画角色会是乱的,头脚不分. ?

没看你的代码
不过这种状况一般是没有逐个乘骨骼的matrix造成的

36

主题

1047

帖子

1147

积分

金牌会员

Rank: 6Rank: 6

积分
1147
发表于 2007-10-24 22:43:00 | 显示全部楼层

Re:为什么我渲染的一个骨骼动画角色会是乱的,头脚不分. ?

d3d sdk 的 skinned mesh 害死人啊~。

0

主题

228

帖子

285

积分

中级会员

Rank: 3Rank: 3

积分
285
发表于 2007-10-25 10:31:00 | 显示全部楼层

Re:为什么我渲染的一个骨骼动画角色会是乱的,头脚不分. ?

楼上说的对

54

主题

116

帖子

122

积分

注册会员

Rank: 2

积分
122
发表于 2007-10-26 17:18:00 | 显示全部楼层

Re:为什么我渲染的一个骨骼动画角色会是乱的,头脚不分. ?

请教,为什么说害死人呢?我正在看那个例子。那我应该看什么例子可以学会蒙皮动画
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-21 11:47

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表