Direct9.0c SDK中提供了一个叫DXviewer的*.x格式文件查看器的源码,代码给出了基于DXUT框架的模型显示接口使用方法,

对于我想编写一个动作捕捉的上位程序是大有助益的。

我的想法是基于这个显示框架,实现实时导入经过四元数运算修改骨骼动画之后的*.x文件。而这就需要研究*.x模型文件的骨骼

动画部分的数据格式,经过查找资料,详细解释如下:

骨骼在.X文件里面用模板Frame来定义。

看看带骨骼的.X文件,一般的结构是:

Frame Frame1

{

FrameTransformMatrix

{

}

Mesh Mesh1

{

}

}

FrameTransformMatrix 表示了骨骼相对模型中心的变化矩阵,假如我们人的中心位置是在躯体的中心(大概是胃的位置),手臂的骨骼离那个位置是有一些偏移的,这个矩阵就是用来计算这个偏移信息的。

Mesh1是表示附属在Frame1上的模型顶点信息。比如我们手臂的骨头动了,附在上面的皮肤和肉都要动,在3D里面这些是用三角形来表示的。因此Mesh1表示Frame1影响到得顶点的信息。

要想产生动画, 光有骨骼还不行,必须得有描述这些骨骼在某一时候如何运动的信息。在.X文件里面,这些运动信息用模板AnimationSet来描述。

AnimationSet walk

{

Animation Animation1

{

{Frame1}

AnimationKey

{

}

}

Animation Animation2

{

{Frame2}

AnimationKey

{

}

}

}

以上是AnimationSet一般结构。要想产生walk(走路)的动作,要让脚动,有时候手也要动。Animation就记录了运动的骨骼的信息。在这个动作里面,走路要动的骨骼是Frame1,和Frame2。

那么怎么知道Animation里面骨骼在某个时候怎么运动呢?这些信息就放在AnimationKey里面。下面是AnimationKey的一个实例

AnimationKey AnimationKey1

{

4;

6;

0;16;0.881635,-0.111735,0.458514,0.000000,0.114895,0.993153,0.021101,0.000000,-0.457732,0.034078,0.888437,0.000000,-0.303751,9.349454,-0.603032,1.000000;;,

160;16;0.881635,-0.112752,0.458265,0.000000,0.114895,0.993104,0.023303,0.000000,-0.457733,0.032108,0.888510,0.000000,-0.304559,9.352407,-0.603871,1.000000;;,

320;16;0.881635,-0.113764,0.458015,0.000000,0.114896,0.993050,0.025496,0.000000,-0.457733,0.030146,0.888579,0.000000,-0.305481,9.355353,-0.604827,1.000000;;,

480;16;0.881635,-0.114774,0.457763,0.000000,0.114896,0.992992,0.027686,0.000000,-0.457733,0.028186,0.888643,0.000000,-0.306449,9.358295,-0.605831,1.000000;;,

640;16;0.881634,-0.115785,0.457509,0.000000,0.114896,0.992928,0.029878,0.000000,-0.457733,0.026225,0.888703,0.000000,-0.307393,9.361239,-0.606811,1.000000;;,

800;16;0.881634,-0.116798,0.457252,0.000000,0.114897,0.992859,0.032076,0.000000,-0.457733,0.024258,0.888759,0.000000,-0.308247,9.364190,-0.607697,1.000000;;,

}

4表示变化信息是矩阵(0:旋转,1:平移,2:缩放) 6表示下面有6个关键帧。第一个关键帧中的0:表示起始时间,16表示矩阵是4*4的,接下来就是变化矩阵的信息了。

这里就有问题了,我们只知道时间点0, 160, 320, 480, 640, 800处的变化信息,那么在100或是200的时间点上骨骼怎么运动呢?这就需要对关键帧进行线性插值。比如时间t1处变化矩阵是mat1, 时间t2处变化矩阵是mat2, 当t1<=t<t2时,mat = mat1+(mat2-mat1)*t/(t2-t1)。把100代入到上面的公式用AnimationKey1数据表示:mat=mat1+(mat2-mat1)*100/160, mat1,mat2是已知的,所以就可以得到mat。

就这样,walk这个动作的所有信息就可以表示了。

以上讲的骨骼(Frame)只包含了一个受影响的Mesh的顶点信息,这样的话,一个顶点只能受一块骨头影响,这样明显不符合实际情况(比如人的上臂和下臂过渡区得皮肤,明显要同时受到上臂骨骼和下臂骨骼的影响)。

如果一个顶点只受一个骨骼影响,比较明显的情况就是在两块骨头的过渡区间会产生撕裂现象。蒙皮动画就是为解决这个问题而产生的。下面是对蒙皮信息的定义:

SkinWeights

{

"Bip01_L_Clavicle";

2;

150,

3512;

0.303157,

0.601147;

1.253361,-0.000002,0.254069,0.000000,-0.218659,-0.223923,1.078679,0.000000,0.058231,-1.440720,-0.287275,0.000000,-8.131670,62.204407,-2.611076,1.000000;;

}

SkinWeights

{

"Bip01_Neck";

2;

150,

2100;

0.696843,

0.601147;

1.253361,-0.000002,0.254069,0.000000,-0.218659,-0.223923,1.078679,0.000000,0.058231,-1.440720,-0.287275,0.000000,-8.131670,62.204407,-2.611076,1.000000;;

}

第一个蒙皮该信息表示 索引值为2,150号的顶点受到骨骼Bip01_L_Clavicle的影响,影响的权重是0.303157,0.601147; 这里解释一下权重的概念。DX9最多支持一个顶点受到4个骨骼影响,

假设一个顶点受到4个骨骼影响,骨骼对应的矩阵分别是mat1,mat2,mat3,mat4. 权重是w1,w2,w3,w4。那个最终顶点变换矩阵就是mat1*w1+mat2*w2+mat3*w3+mat4*w4。必须满足w1+w2+w3+w4=1

由上面的信息看出 150号顶点只受到Bip01_L_Clavicle,Bip01_Neck两个骨骼的影响(应为0.303157+0.696843=1).至于最后一个变换矩阵,还需下一步具体研究。

DirectX9.0c SDK学习笔记(一)的更多相关文章

  1. OpenXml SDK学习笔记(1):Word的基本结构

    能写多少篇我就不确定了,可能就这一篇就太监了,也有可能会写不少. OpenXml SDK 相信很多人都不陌生,这个就是管Office一家的文档格式,Word, Excel, PowerPoint等都用 ...

  2. OpenXml SDK学习笔记(4):设置文件级别的样式

    观察上一段日记最后的代码: 这里的样式基本可以理解为行内CSS.那么既然有行内的样式,就肯定有外部的样式.那这部分就对应笔记1里说的style.xml文件.这个文件对应的是Document.MainD ...

  3. RealThinClient SDK 学习笔记(1)

    从客户端调用远程函数的两种方法 1: RtcClientModule1.Prepare('select'); // call the "select" function on th ...

  4. 一起学ASP.NET Core 2.0学习笔记(一): CentOS下 .net core2 sdk nginx、supervisor、mysql环境搭建

    作为.neter,看到.net core 2.0的正式发布,心里是有点小激动的,迫不及待的体验了一把,发现速度确实是快了很多,其中也遇到一些小问题,所以整理了一些学习笔记: 阅读目录 环境说明 安装C ...

  5. golang学习笔记18 用go语言编写移动端sdk和app开发gomobile

    golang学习笔记18 用go语言编写移动端sdk和app开发gomobile gomobile的使用-用go语言编写移动端sdk和app开发https://blog.csdn.net/u01249 ...

  6. Intel® Media SDK Media Samples Linux 学习笔记(转)

    最近折腾intel media sdk,主要硬件平台是在HD4600的核显上进行测试,intel media sdk是intel提供的一种基于核显的硬件编解码的解决方案,之前已经有使用ffmpeg进行 ...

  7. go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时])

    目录 go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时]) 静态配置 flag注入 在线热加载配置 远程配置中心 go微 ...

  8. DirectX 11游戏编程学习笔记之1: 开场白

    本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com           这是我之前的博客系列"DirectX9.0c游戏开发手记之'龙书'第二版学习笔记 ...

  9. react-native学习笔记--史上最详细Windows版本搭建安装React Native环境配置

    参考:http://www.lcode.org/react-native/ React native中文网:http://reactnative.cn/docs/0.23/android-setup. ...

随机推荐

  1. WPS之替换样式

    以前写文档需要颜色设置什么的时候,都是遇到的时候,就进行设置,挺烦的,要一直切换. 今天突然想到,既然有替换应该可能也有样式替换,就查了一下,试了试果然可以,以后就这么干了

  2. 在fedora 18中将普通用户设置为sudo权限

    将一般的用户加入sudo组is not in the sudoers file. This incident will be reported 解决方法 在一般用户下执行sudo命令提示xxx is ...

  3. pythonday

    python学习          http://www.cnblogs.com/fengyuhao/p/7168903.html pythonday    http://www.cnblogs.co ...

  4. WEB安全第一篇--对服务器的致命一击:代码与命令注入

    零.前言 最近做专心web安全有一段时间了,但是目测后面的活会有些复杂,涉及到更多的中间件.底层安全.漏洞研究与安全建设等越来越复杂的东东,所以在这里想写一个系列关于web安全基础以及一些讨巧的pay ...

  5. Mysql group_concat函数列转行,与行转列

    例一: SELECT num from user 1.使用group_concat函数得到列转行 select group_concat(num) from user 2.使用SUBSTRING_IN ...

  6. go练习5--生成md5

    import "crypto/md5" import "encoding/hex" //go 生成 md5 func T4_1() { m := md5.New ...

  7. springMVC各个包下的作用

    spring的jar各包作用spring.jar是包含有完整发布的单个jar包,spring.jar中包含除了spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下 ...

  8. Redis构建处理海量数据的大型购物网站

    本系列教程内容提要 Java工程师之Redis实战系列教程教程是一个学习教程,是关于Java工程师的Redis知识的实战系列教程,本系列教程均以解决特定问题为目标,使用Redis快速解决在实际生产中的 ...

  9. 关于cdn原理(就是内容分发网络)

    cdn,我理解其本质就是为了解决距离远产生的速度问题,使用就近的服务. 从中国请求美国一台服务器上的图片.一般比较慢,因为距离这么远,网络传输是存在损耗的,距离越远,传输的时间就越长.一般会看到浏览器 ...

  10. Spring Security使用心得

    某天,你的客户提出这样一个需求,在点击购买商品的时,如果用户没有注册,并且用户没有账号,这时用户去创建账户,然后要直接返回到想购买商品的付款页面.你会该如何基于Spring Security实现? S ...