骨骼动画3

类别:编程语言 点击:0 评论:0 推荐:

骨骼动画3

 

第三界简单的骨骼动画、骨骼动画理论

Keep in touch :[email protected]

 

 

目的:指导别人使用矩阵

任务:编写教程,编写代码

阅读对象:d3d入门者,c/c++熟练,windows编程熟练,VC IDE熟练

描述:

       这一届我们来做一个简单的骨骼动画(非常简单啊!只有两个线段啊!)并且介绍一下实现思想是什么

 

在3d世界中,人物的动画过程主要有两种实现方式:

1.       key frame animation(关键帧动画)

a)       是将要播放的关键帧都做好放到存储介质中(文件,内存),播放时一帧帧的调出来

2.       (骨骼动画)

a)       是将动作对象分解成一个个的键(joint),和骨(bone)要使对象动作只要将joint和bone进行矩阵坐标转换就可以了

第一种方式我们暂时不研究(等我写完骨骼动画后我会再介绍的),我们只关心第二种实现方式。

      下图就是一个最最基本的骨骼构成模式

      图1

      其中键有:A,B,C,D;骨有a,b,c;我们现在假设ABCD的坐标是A(1,0,Z),B(0,0,Z)C(0,1,Z)D(1,1,Z),我们想让a,c骨骼动起来,而b不动

     

                            图2

      经过变换之后我们的图1就变成图2了。现在我们来看看用数学表达是怎样表示上面的转换我们设C>C’转了r度,D>D’在C不变的情况下(什么?为什么C不变?这个……你自己考虑吧)转了t度,则C’的坐标是(x’,y’,Z),D’的坐标是(x’’,y’’,Z)。什么坐标是怎么计算出来的?你可真着急啊当然是通过矩阵变换的啊

      计算步骤:  

第一步:我们首先认为C和D点是一起的也就是说当C移动时D也随之移动,这样我们可以计算出C’和D’’的坐标都是绕A点以垂直于AC和CD的平面的向量旋转的,通过转换矩阵我们可以得到C’D’’的向量坐标,

第二步: 再处理D’’向D’转动,这是可以将C”点看成是转点,计算得出D’的向量坐标

 

好了,我们来看一下代码吧

为了方便操作,我将原本在setup函数中的vertices变量放到了外边,成了全局变量(这样不是一个好的方法,但这只是一时之举,少后我将会改正)

Vertex* vertices;

在程序中我们将键(joint)设成一个点,骨(bone)则是一个线段

 

其中要注意的代码只有一段,那就是在display()函数中的下列语句

 

    //申明了四个点,其中tempA,tempB,tempC各代表ACD三个点tempD代表了一个临时的数据存放空间,主要是用来放转换之后的C’C’’D’的位置数据

D3DXVECTOR3* tempA = new D3DXVECTOR3(vertices[0]._x,vertices[0]._y,vertices[0]._z); //将ABC复制到temp里面

D3DXVECTOR3* tempB = new D3DXVECTOR3(vertices[1]._x,vertices[1]._y,vertices[1]._z);

D3DXVECTOR3* tempC = new D3DXVECTOR3(vertices[2]._x,vertices[2]._y,vertices[2]._z);

        D3DXVECTOR3* tempD =new D3DXVECTOR3() ;

       

        //计算BA

        D3DXVECTOR3* BA = &(*tempB-*tempA);//计算出向量BA

        //计算CA

        D3DXVECTOR3* CA = &(*tempC-*tempA); //计算出向量CA

       

        //将BA在垂直BA方向上旋转ax

   

        D3DXMatrixRotationAxis(&RAba,(D3DXVec3Cross(tempD,BA,CA)),ax);//前面介绍过这个函数

// D3DXVec3Cross函数的功能是将BA向量和CA向量进行X(不能读成”埃克司”啊,应该是“叉乘”)乘,(得到的是一个垂直于BA和CA的向量)

        D3DXMatrixRotationAxis(&RAcb,(D3DXVec3Cross(tempD,BA,CA)),ax);

        D3DXVec3TransformNormal(BA,BA,&RAba);//该函数的功能是将BA向量通过转换矩阵RAba变成BA’

        D3DXVec3TransformNormal(CA,CA,&RAcb);

 

        *tempB = (*BA+*tempA);

        //重新对内存中的数据进行复制

        vertices[1]._x=tempB->x;

        vertices[1]._y=tempB->y;

        vertices[1]._z=tempB->z;

        *tempC = (*CA+*tempA);

       

       

        //计算C'B'

        D3DXVECTOR3* CB = &(*tempC-*tempB);

        //将C'B'在垂直C'B'方向上旋转ax

        D3DXMatrixRotationAxis(&RAba,(D3DXVec3Cross(tempD,BA,CA)),-ax);

        D3DXVec3TransformNormal(CB,CB,&RAba);

        *tempC = (*CB+*tempB);

        vertices[2]._x=tempC->x;

        vertices[2]._y=tempC->y;

    vertices[2]._z=tempC->z;

 

 

好了运行一下吧,看看有什么效果!

   

 

    怎么样是不是很“裸”(这是我上大学时,我们班人常说的一个字,意思说:很差劲,很白痴,无能,发泄的意思,反正不是个好东西了,是我们班人发明的哦,没有授权你不能使用的啊“^_^”)

    的确这段代码对付这两个线段是可以了,可是要有上百个上千个怎么办啊?没关系了,我们可以将代码重构一下。写的更加复杂一些,并且使用一些OO(面向对象)方法,和design pattern(设计模式),这些将会在下一界中介绍。

 

 

 

备:写这些东西好累啊,白天上班晚上还要回来写东西真的很累啊,所以这个周休息一下下周再写。
附件下载地址http://blog.blogchina.com/upload/2004-12-02/20041202090040332679.rar

本文地址:http://com.8s8s.com/it/it24791.htm