3D游戏角色动画Word文件下载.docx
《3D游戏角色动画Word文件下载.docx》由会员分享,可在线阅读,更多相关《3D游戏角色动画Word文件下载.docx(30页珍藏版)》请在冰豆网上搜索。
![3D游戏角色动画Word文件下载.docx](https://file1.bdocx.com/fileroot1/2023-1/28/ba5be197-4168-4907-bea7-45f740d45b41/ba5be197-4168-4907-bea7-45f740d45b411.gif)
而右上臂是上身的子节点,后者则是躯体的子节点。
通过改变不同部分之间的相对位置,比如夹角,位移等等,就可以实现所需要的各种动画效果。
这类动画的优点很多。
首先,在动画序列的关键帧中只需要存储节点间的相对变化,因此动画文件占用的空间很小。
其次,可以实现很多复杂的动画效果,如果应用程序支持反向动力学还可以动态实现预先存储的动画序列之外的新的动画效果。
当然这类动画也有不少缺点。
其中之一是由于角色模型是一个层次模型,要获得某一个部分相对于世界坐标的位置,必须从根结点开始遍历该节点所有的祖先节点累计计算模型的世界变换。
但最关键的问题是在不同部分的结合处往往会有很明显的接缝,这会严重的影响模型的真实感。
第二类是渐变动画(MorphingAnimation)。
这种动画中的角色由一系列的渐变网格模型构成。
在动画序列的关键帧中记录着组成网格的各个顶点的新位置或者是相对于原位置的改变量。
通过在相邻关键帧之间插值来直接改变该网格模型中各个顶点的位置就可以实现动画效果。
相对于关节动画,单一网格模型动画的角色看上去更真实,也不会有关节动画所面临的接缝问题。
由于没有使用层次模型,获得模型网格顶点在世界坐标中位置的计算量也很小。
但是,这类动画的适应性很弱,角色很难通过实时计算来与环境进行良好的互动,以获得预先存储的动画序列之外的动画效果。
另一方面,由于关键帧要存储网格模型所有的顶点信息,动画文件占用的空间比较大。
第三类是骨骼蒙皮动画(SkinnedMesh)。
骨骼蒙皮动画可以看作是关节动画和渐变动画的结合。
他同时兼有关节动画的灵活和渐变动画的逼真。
后面将详细介绍骨骼蒙皮动画的技术细节。
3D角色动画技术和其它动画技术相结合,就能创造出绚丽多彩的游戏世界。
在一个游戏项目中,计时扮演了一个重要的角色。
基于时间的运动,也就是创建计时器来控制运动。
它能够产生这样一种动画效果:
同样处理10000毫秒的动画,在性能好的计算机上得到平滑完整的动画效果,在性能不好的计算机上显得跳帧,但也能够在10000毫秒的时候完成任务,和性能好的计算机是同步的。
基本思路是事先设置好动画关键帧序列,在主循环中判断出第一个动画关键帧和下一个动画关键帧的编号,利用一个时间计数器去定位相对于第一动画关键帧的位置。
随着时间计数器的增长,不断从第一个动画关键帧的位置移动至下一个动画关键帧的位置。
主要分为以下几个步骤:
1设置动画关键帧序列。
2计算出每一帧的时间Time,Time是相对于程序开始运行的毫秒数。
3定位出第一个动画关键帧和下一个动画关键帧。
4利用Time计算出相对于第一个动画关键帧的毫秒数,再利用这个偏移毫秒数计算出相对于第一个动画帧的偏移位置。
5设置变换矩阵。
6回到第2步。
上图表示了4帧的关键帧动画,其中第0帧和第3帧变换矩阵相同。
下面直接看代码,我将结合代码详细叙述。
typedefstructsKeyframe
{
DWORDTime;
D3DMATRIXmatTransformation;
}sKeyframe;
//关键帧的结构,DWORDTime为执行该帧的时间,D3DMATRIX//matTransformation为在该帧时模型的变换矩阵。
sKeyframeg_Keyframes[4]=
//Keyframe0,0ms
{0,1.000000f,0.000000f,0.000000f,0.000000f,
0.000000f,1.000000f,0.000000f,0.000000f,
0.000000f,0.000000f,1.000000f,0.000000f,
0.000000f,0.000000f,0.000000f,1.000000f},
//Keyframe1,40ms
{400,0.000796f,1.000000f,0.000000f,0.000000f,
-1.000000f,0.000796f,0.000000f,0.000000f,
50.000000f,0.000000f,0.000000f,1.000000f},
//Keyframe2,80ms
{800,-0.999999f,0.001593f,0.000000f,0.000000f,
-0.001593f,-0.999999f,0.000000f,0.000000f,
25.000000f,25.000000f,0.000000f,1.000000f},
//Keyframe3,120ms
{1200,1.000000f,0.000000f,0.000000f,0.000000f,
0.000000f,0.000000f,0.000000f,1.000000f}
};
//定义了4帧的关键动画。
其中第3帧和第0帧的变换矩阵一样,为了使动画能进入循环状态。
voidDoFrame()//此函数在循环内
staticDWORDStartTime=timeGetTime();
DWORDTime=timeGetTime()-StartTime;
//用timeGetTime()得到一个操作系统运行的毫秒数,储存到static变量以后将不再改变,//DWORDTime变量不断改变,为本程序运行的毫秒数。
Time%=(g_Keyframes[3].Time+1);
//得到一个不断从0到1200变化的毫秒数。
DWORDKeyframe=0;
//从第0帧开始。
for(DWORDi=0;
i<
4;
i++){
//如果Time>
=某一关键帧的时间,将关键帧定位于此帧。
if(Time>
=g_Keyframes[i].Time)
Keyframe=i;
}
DWORDKeyframe2=(Keyframe==3)?
Keyframe:
Keyframe+1;
//得到接下来的关键帧,如//果Keyframe为第3关键动画帧,Keyframe2也为第3关键动画帧。
//当Keyframe=1200时这种情况才成立,几率很小。
一般情况下,Keyframe2=Keyframe+1。
DWORDTimeDiff=g_Keyframes[Keyframe2].Time-
g_Keyframes[Keyframe].Time;
if(!
TimeDiff)
TimeDiff=1;
//计算两个sKeyframe的时间差,当Keyframe=Keyframe2=3时,TimeDiff=0,//此时另TimeDiff=1。
floatScalar=(float)(Time-g_Keyframes[Keyframe].Time)/(float)TimeDiff;
//Scalar取//值为[0,1),利用Time计算出相对于Keyframe的偏移毫秒数,再除以两//帧的时间差。
D3DXMATRIXmatInt=D3DXMATRIX(g_Keyframes[Keyframe2].matTransformation)-
D3DXMATRIX(g_Keyframes[Keyframe].matTransformation);
matInt*=Scalar;
//用于计算相对于Keyfrme的偏移位置。
matInt+=D3DXMATRIX(g_Keyframes[Keyframe].matTransformation);
//计算出该帧处相//对于Keyfrme的偏移位置。
g_pD3DDevice->
SetTransform(D3DTS_WORLD,&
matInt);
//设置worldtransformationmatrix
设置完变换矩阵,剩下的事情就只是渲染了。
创建计时器控制动画的技术是非常简单有效的,这是现代计算机游戏动画的基础,因此,必须深刻理解它的内容。
1介绍微软的X文件
制作3D游戏角色动画需要与之相关的“动画容器”。
这个“容器”中储存着动画的数据。
微软的X文件正是这样的一种容器。
由于微软的影响力,它们公司设计的X文件也广为流传。
X文件是一套基于模版定义的文件,理论上它能够容纳任何数据。
也就意味着不仅仅是3D模型文件,任何用于游戏引擎加载的外部资源都可以被包含于X文件之中。
下面我们详细的介绍下X文件。
为了得到一个直观的印象,我们首先浏览下它的全貌。
xof0302txt0032
templateHeader{
<
3D82AB43-62DA-11cf-AB39-0020AF71E433>
DWORDmajor;
DWORDminor;
DWORDflags;
}
templateFrame{
3D82AB46-62DA-11cf-AB39-0020AF71E433>
[FrameTransformMatrix]
[Mesh]
Header{
1;
0;
FrameScene_Root{
FrameTransformMatrix{
1.000000,0.000000,0.000000,0.000000,
0.000000,1.000000,0.000000,0.000000,
0.000000,0.000000,1.000000,0.000000,
0.000000,0.000000,0.000000,1.000000;
;
FramePyramid_Frame{
MeshPyramidMesh{
5;
0.00000;
10.00000;
-10.00000;
6;
3;
0,1,2;
0,2,3;
0,3,4;
0,4,1;
2,1,4;
2,4,3;
MeshMaterialList{
0,0,0,0,0,0;
MaterialMaterial0{
1.000000;
1.000000;
0.000000;
0.050000;
0.050000;
0.000000;
首先看头文件xof0302txt0032。
xof表示这是一个真正的X文件。
0302txt表示通知程序使用Directx的X文件,版本为3.2的模版,其中txt表示此文件为文本文件,可读,并非是一个2进制文件。
0032表示一个浮点数的位数为32,如果想要用64位的浮点数,可以写成0064。
下面我们将按照以下七个步骤进行介绍和说明。
第一,声明一个模版:
假设声明templateContactEntry,首先需要用guidgen.exe产生一个GUID。
产生的GUID如下:
//{4C9D055B-C64D-4bfe-A7D9-981F507E45FF}
DEFINE_GUID(<
name>
>
0x4c9d055b,0xc64d,0x4bfe,0xa7,0xd9,0x98,\
0x1f,0x50,0x7e,0x45,0xff);
之后需要在程序代码中加入:
#include"
initguid.h"
//Atbeginningofsourcecodefile-addDEFINE_GUIDs
DEFINE_GUID(ContactEntry,\
还要在X文件中加入:
templateContactEntry{
4C9D055B-C64D-4bfe-A7D9-981F507E45FF>
这里介绍下声明模版用到的数据类型:
关键字描述
WORD16-bitvalue(short)
DWORD32-bitvalue(32-bitintorlong)
FLOATIEEEfloatvalue(float)
DOUBLE64-bitfloating-pointvalue(double)
CHAR8-bitsignedvalue(signedchar)
UCHAR8-bitunsignedvalue(unsignedchar)
BYTE8-bitunsignedvalue(unsignedchar)
STRINGANULL-terminatedstring(char[]))
arraySignifiesanarrayoffollowingdatatypetofollow([])
使用数据类型的举例:
DWORDValue;
arraySTRINGText[20];
//定义一个名为Text的数组,类型为STRING,大小为20。
DWORDArraySize;
arraySTRINGNames[ArraySize];
//可以将大小设置为变量。
现在,我们声明一个ContactEntry模版:
STRINGName;
//Thecontact'
sname
STRINGPhoneNumber;
sphonenumber
DWORDAge;
sage
实例化一个模版对象:
ContactEntryJimsEntry{
"
JimAdams"
(800)555-1212"
30;
{JimsEntry}可以用这样的形式引用一个数据对象。
例如,在一个animationsequencetemplate中引用一个Framedataobject做为其内嵌数据对象。
也可以利用引用表示一个数据对象的副本,没有必要重复书写这个数据对象。
第二,内嵌数据对象和模版约束:
首先,我们分别声明了三个不同的模版,请仔细看它们的区别。
templateClosedTemplate{
DWORDClosedData;
templateOpenTemplate{
4C9D055B-C64D-4bff-A7D9-981F507E45FF>
DWORDOpenData;
[...]
templateRestrictedTemplate{
4C9D055B-C64D-4c00-A7D9-981F507E45FF>
DWORDRestrictedData;
[ClosedTemplate]
[OpenTemplate]
ClosedTemplate看起来没有什么不同,因为它就是标准的模版声明。
在OpenTemplate中包含一个[...],表示这是一个开放模版。
开放模版允许在[]中内嵌任何数据对象。
例如,你可以实例化OpenTemplate,在里面定义一个OpenData变量和内嵌一个ClosedTemplate的实例。
最后的RestrictedTemplate为约束模版。
约束模版实例化时只允许包含它列出的数据对象,如,不能在RestrictedTemplate包含[ClosedTemplate],[OpenTemplate]以外的数据对象。
第三,充分利用DirectX.XStandardTemplates:
正如上面提到的,X文件广泛用于包含一个mesh信息。
一个StandardTemplates包含了各种信息。
Table3:
DirectX.XStandardTemplates
TemplateNameDescription
Animation:
Definesanimationdataforasingleframe.
AnimationKey:
Definesasinglekeyframefortheparentanimationtemplate.
AnimationOptions:
Containsanimationplaybackinformation.
AnimationSet:
Containsacollectionofanimationtemplates.
Boolean:
HoldsaBooleanvalue.
Boolean2d:
HoldstwoBooleanvalues.
ColorRGB:
Containsred,green,andbluecolorvalues.
ColorRGBA:
Containsred,green,blue,andalphacolorvalues.
Coords2d:
Definestwocoordinatevalues.
FloatKeys:
Containsanarrayoffloating-pointvalues.
FrameTransformMatrix:
HoldsthetransformationmatrixforaparentFrametemplate.
Frame:
Aframe-of-referencetemplatethatdefinesahierarchy.
Header:
The.Xfileheaderthatcontainsversionnumbers.
IndexedColor:
Containsanindexedcolorvalue.
Material:
Containsmaterialcolorvalues.
Matrix4x4:
Holdsa4x4homogenousmatrixcontainer.
Mesh:
Containsasinglemesh'
sdata.
MeshFace:
Holdsamesh'
sfacedata.
MeshFaceWraps:
Containsthetexturewrappingformeshfaces.
MeshMaterialList:
Containsthematerialforface-mappingvalues.
MeshNormals:
Holdsnormalsusedformeshdata.
MeshTextureCoords:
Holdstexturecoordinatesusedformeshdata.
MeshVertexColors:
Holdsvertexcolorinformationusedformeshvertices.
Patch:
Definesacontrolpatch.
PatchMesh:
Containsapatchmesh(muchliketheMeshtemplate).
Quaternion:
Holdsaquaternionvalue.
SkinWeights:
Containsanarrayofweightvaluesmappedtoamesh'
svertices.Usedinskinnedmeshes.
TextureFilename:
Containsthetexturefilenametouseforamaterial.
TimedFloatKeys