游戏开发论坛

 找回密码
 立即注册
搜索
楼主: zzzworm

关于骨骼动画及微软示例Skinned Mesh的解析

[复制链接]

8

主题

34

帖子

34

积分

注册会员

Rank: 2

积分
34
发表于 2007-7-28 17:04:00 | 显示全部楼层

Re:关于骨骼动画及微软示例Skinned Mesh的解析

哦,知道了,谢谢楼主

54

主题

116

帖子

122

积分

注册会员

Rank: 2

积分
122
发表于 2007-7-28 18:02:00 | 显示全部楼层

Re:关于骨骼动画及微软示例Skinned Mesh的解析

谢谢楼主的回答

8

主题

34

帖子

34

积分

注册会员

Rank: 2

积分
34
发表于 2007-7-31 15:07:00 | 显示全部楼层

Re:关于骨骼动画及微软示例Skinned Mesh的解析

楼主,我发现XFILE里面的时间点根实际的时间有差别
如TINY.X里animationSet里的最大周期是4960(是不是4.96秒)
但在实际的时候我用下面代码求出周期
LPD3DXANIMATIONSET m_set;
g_pAnimController->GetAnimationSet(0,&m_set);
int s=m_set->GetPeriod();
发现s(周期)为1.0333333,即TINY动作一个来回是S秒(我感觉这才是真正的周期)
请问这是怎么回事?

3

主题

18

帖子

23

积分

注册会员

Rank: 2

积分
23
 楼主| 发表于 2007-7-31 21:51:00 | 显示全部楼层

回楼上

你的说法是对的.animationkey中的时间戳数值,并不代表ms数.
这个时间与x文件的AnimTicksPerSecond有关系.AnimTicksPerSecond指出了实际每秒对应的动画的tick数,通过这个参数可以把.x动画文件中的时间数值转化为实际的秒数.
在tiny.x中,没有发现AnimTicksPerSecond项,就会取默认值.这个默认值,我认为就是AnimTicksPerSecond=4800
就是说,4960对应的实际时间是 4960/4800 =1.033333 秒.

当然,你也可以在.x中加上自定义的AnimTicksPerSecond如下
AnimTicksPerSecond
{
    9600;
}
这种情况下,人物的动作速度是原来的2倍

1

主题

17

帖子

28

积分

注册会员

Rank: 2

积分
28
发表于 2007-8-1 03:30:00 | 显示全部楼层

Re:关于骨骼动画及微软示例Skinned Mesh的解析

楼主,看了你这篇文章对我帮助很大,但是有点疑问,你说:
在动画文件中,框架通常用来描述骨骼。可以把Frame视做骨骼,所以不细加区分。
.在上面D3DXFRAME结构中,pFrameSibling, pFrameFirstChild两个指针,常用于递归函数中,遍历整个骨架。
.在D3DXFRAME结构中有一个pMeshContainer指针,难道框架与Mesh是一一对应的吗?
有一个框架(骨骼)就有一个Mesh吗?怎么.X文件中只有一个Mesh?难道加载时拆开存放?
答:从D3DXFrame结构上看,每个Frame都有一个pMeshContainer指针。这就有三种解释:
   第一种,加载到内存后所有的pMeshContainer都指向同一个全局Mesh
   第二种,加载到内存后,只有一个主框架的pMeshContainer不为空,其它Frame的pMeshContainer均为NULL,因为在.X中,它们没有定义自己的Mesh
   第三种,加载到内存后,D3D将Mesh拆分,分开到各骨骼所对应的Frame,每个Frame都有自己的Mesh。
你说是第二种情况.
那这样的话,在如下代码中
void DrawFrame( IDirect3DDevice9 *pd3dDevice, LPD3DXFRAME pFrame )
{
    LPD3DXMESHCONTAINER pMeshContainer;

    pMeshContainer = pFrame->pMeshContainer;
    while (pMeshContainer != NULL)
    {
        DrawMeshContainer( pd3dDevice, pMeshContainer, pFrame );

        pMeshContainer = pMeshContainer->pNextMeshContainer;
               
    }

    if (pFrame->pFrameSibling != NULL)
    {
        DrawFrame( pd3dDevice, pFrame->pFrameSibling);
    }

    if (pFrame->pFrameFirstChild != NULL)
    {
        DrawFrame( pd3dDevice, pFrame->pFrameFirstChild );
    }
}
其中的
    while (pMeshContainer != NULL)
    {
        DrawMeshContainer( pd3dDevice, pMeshContainer, pFrame );

        pMeshContainer = pMeshContainer->pNextMeshContainer;
               
    }就只在一层的递归调用的函数中执行了一次这样的循环?

3

主题

18

帖子

23

积分

注册会员

Rank: 2

积分
23
 楼主| 发表于 2007-8-1 15:56:00 | 显示全部楼层

回楼上

是的.你可以在此处下断点. 会发现,对于tiny.x,在每次Render()过程中,只调用一次DrawMeshContainer(),整个递归调用只进DrawMeshContainer一次.

8

主题

34

帖子

34

积分

注册会员

Rank: 2

积分
34
发表于 2007-8-2 21:19:00 | 显示全部楼层

Re:关于骨骼动画及微软示例Skinned Mesh的解析

是这样的,谢谢楼主

54

主题

116

帖子

122

积分

注册会员

Rank: 2

积分
122
发表于 2007-8-4 14:20:00 | 显示全部楼层

Re:关于骨骼动画及微软示例Skinned Mesh的解析

楼主,我想请教一下
1. 导入了一个带有动画信息的骨骼模型,我怎么知道它会什么动作呢?比如tiny.x就会跑步、走路,我看到其他有的模型就会踢腿,打拳什么的。虽然我能看懂.X文件的结构,但是那些关键帧都是些坐标,我怎么知道具体是什么动作呢?我觉得知道模型会什么动作可以帮助我们更好的利用模型吧。
2. 我看到有的游戏可以用键盘控制部分骨骼动作,而不像是关键帧里记录的。比如有个坦克的游戏就可以键盘控制炮桶左右转。这又是怎么实现的呢?

谢谢了

3

主题

18

帖子

23

积分

注册会员

Rank: 2

积分
23
 楼主| 发表于 2007-8-9 12:07:00 | 显示全部楼层

Re:关于骨骼动画及微软示例Skinned Mesh的解析

回楼上. 最近忙了起来,长时间不上线了.
你的问题似乎涉及多骨骼动画.可以参看微软的MultiAnimation示例,其中的GetAnimIndex()就是遍历各动画搜寻的例子.

30

主题

357

帖子

388

积分

中级会员

Rank: 3Rank: 3

积分
388
QQ
发表于 2007-8-9 22:56:00 | 显示全部楼层

Re:关于骨骼动画及微软示例Skinned Mesh的解析

支持楼主!当年为了搞明白骨骼动画,把XFile里的结构画了一张超大的图出来,贴在了地板上,每天回家都望着地板发呆,呵呵!
其实,X文件的结构是以灵活和扩展为设计目的,效率其实是非常底下的。是人都能在完全理解后想出比他更好的存储结构来。38楼所说的那种多动作融合,正是骨骼动画的优势所在。只要拿其他的骨骼动作替换掉相应的骨骼的动作就可以实现动作融合。比如:
有两个动作,分别是 射门 和 跑步。那么用“射门”的右大腿、右小腿的骨骼矩阵替换掉“跑步”的右大腿和右小腿的骨骼矩阵,就可以实现跑动中射门了。当然,不见得好看,呵呵。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-8-1 01:22

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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