Jump to content
View in the app

A better way to browse. Learn more.

主视角中国

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

3D游戏角色动画

1 介绍微软的X文件

制作3D游戏角色动画需要与之相关的“动画容器”。这个“容器”中储存着动画的数据。微软的X文件正是这样的一种容器。由于微软的影响力,它们公司设计的X文件也广为流传。X文件是一套基于模版定义的文件,理论上它能够容纳任何数据。也就意味着不仅仅是3D模型文件,任何用于游戏引擎加载的外部资源都可以被包含于X文件之中。下面我们详细的介绍下X文件。为了得到一个直观的印象,我们首先浏览下它的全貌。

xof 0302txt 0032

template Header {

<3D82AB43-62DA-11cf-AB39-0020AF71E433>

DWORD major;

DWORD minor;

DWORD flags;

}

template Frame {

<3D82AB46-62DA-11cf-AB39-0020AF71E433>

[FrameTransformMatrix]

[Mesh]

}

Header {

1;

0;

1;

}

Frame Scene_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;;

}

Frame Pyramid_Frame {

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;;

}

Mesh PyramidMesh {

5;

0.00000;10.00000;0.00000;,

-10.00000;0.00000;10.00000;,

10.00000;0.00000;10.00000;,

-10.00000;0.00000;-10.00000;,

10.00000;0.00000;-10.00000;;

6;

3;0,1,2;,

3;0,2,3;,

3;0,3,4;,

3;0,4,1;,

3;2,1,4;,

3;2,4,3;;

MeshMaterialList {

1;

6;

0,0,0,0,0,0;;

Material Material0 {

1.000000; 1.000000; 1.000000; 1.000000;;

0.000000;

0.050000; 0.050000; 0.050000;;

0.000000; 0.000000; 0.000000;;

}

}

}

}

}

首先看头文件xof 0302txt 0032。xof表示这是一个真正的X文件。0302txt表示通知程序使用Directx的X文件,版本为3.2的模版,其中txt表示此文件为文本文件,可读,并非是一个2进制文件。0032表示一个浮点数的位数为32,如果想要用64位的浮点数,可以写成0064。

下面我们将按照以下七个步骤进行介绍和说明。

第一,声明一个模版:

假设声明 template ContactEntry ,首先需要用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"

// At beginning of source code file - add DEFINE_GUIDs

DEFINE_GUID(ContactEntry, \

0x4c9d055b, 0xc64d, 0x4bfe, 0xa7, 0xd9, 0x98, \

0x1f, 0x50, 0x7e, 0x45, 0xff);

还要在X文件中加入:

template ContactEntry {

<4C9D055B-C64D-4bfe-A7D9-981F507E45FF>}

这里介绍下声明模版用到的数据类型:

关键字 描述

WORD 16-bit value (short)

DWORD 32-bit value (32-bit int or long)

FLOAT IEEE float value (float)

DOUBLE 64-bit floating-point value (double)

CHAR 8-bit signed value (signed char)

UCHAR 8-bit unsigned value (unsigned char)

BYTE 8-bit unsigned value (unsigned char)

STRING A NULL-terminated string (char[]))

array Signifies an array of following data type to follow ([])

使用数据类型的举例:

DWORD Value;

array STRING Text[20];//定义一个名为Text的数组,类型为STRING,大小为20。

DWORD ArraySize; array STRING Names[ArraySize]; //可以将大小设置为变量。

现在,我们声明一个ContactEntry模版:

template ContactEntry {

<4C9D055B-C64D-4bfe-A7D9-981F507E45FF>

STRING Name; // The contact's name

STRING PhoneNumber; // The contact's phone number

DWORD Age; // The contact's age

}

实例化一个模版对象:

ContactEntry JimsEntry {

"Jim Adams";

"(800) 555-1212";

30;

}

{JimsEntry} 可以用这样的形式引用一个数据对象。例如,在一个animation sequence template中引用一个Frame data object做为其内嵌数据对象。也可以利用引用表示一个数据对象的副本,没有必要重复书写这个数据对象。

第二,内嵌数据对象和模版约束:

首先,我们分别声明了三个不同的模版,请仔细看它们的区别。

template ClosedTemplate {

<4C9D055B-C64D-4bfe-A7D9-981F507E45FF>

DWORD ClosedData;

}

template OpenTemplate {

<4C9D055B-C64D-4bff-A7D9-981F507E45FF>

DWORD OpenData;

[...]

}

template RestrictedTemplate {

<4C9D055B-C64D-4c00-A7D9-981F507E45FF>

DWORD RestrictedData;

[ClosedTemplate]

[OpenTemplate]

}

ClosedTemplate看起来没有什么不同,因为它就是标准的模版声明。在OpenTemplate中包含一个[...],表示这是一个开放模版。开放模版允许在[]中内嵌任何数据对象。例如,你可以实例化OpenTemplate,在里面定义一个OpenData变量和内嵌一个ClosedTemplate的实例。最后的RestrictedTemplate为约束模版。约束模版实例化时只允许包含它列出的数据对象,如,不能在RestrictedTemplate包含[ClosedTemplate],[OpenTemplate]以外的数据对象。

第三,充分利用DirectX .X Standard Templates:

正如上面提到的,X文件广泛用于包含一个mesh信息。一个Standard Templates包含了各种信息。

Table 3: DirectX .X Standard Templates

Template Name Description

Animation: Defines animation data for a single frame.

AnimationKey: Defines a single key frame for the parent animation template.

AnimationOptions: Contains animation playback information.

AnimationSet: Contains a collection of animation templates.

Boolean: Holds a Boolean value.

Boolean2d: Holds two Boolean values.

ColorRGB: Contains red, green, and blue color values.

ColorRGBA: Contains red, green, blue, and alpha color values.

Coords2d: Defines two coordinate values.

FloatKeys: Contains an array of floating-point values.

FrameTransformMatrix: Holds the transformation matrix for a parent Frame template.

Frame: A frame-of-reference template that defines a hierarchy.

Header: The .X file header that contains version numbers.

IndexedColor: Contains an indexed color value.

Material: Contains material color values.

Matrix4x4: Holds a 4x4 homogenous matrix container.

Mesh: Contains a single mesh's data.

MeshFace: Holds a mesh's face data.

MeshFaceWraps: Contains the texture wrapping for mesh faces.

MeshMaterialList: Contains the material for face-mapping values.

MeshNormals: Holds normals used for mesh data.

MeshTextureCoords: Holds texture coordinates used for mesh data.

MeshVertexColors: Holds vertex color information used for mesh vertices.

Patch: Defines a control patch.

PatchMesh: Contains a patch mesh (much like the Mesh template).

Quaternion: Holds a quaternion value.

SkinWeights: Contains an array of weight values mapped to a mesh's vertices. Used in skinned meshes.

TextureFilename: Contains the texture file name to use for a material.

TimedFloatKeys: Contains an array of FloatKeys templates.

Vector: Holds a 3D coordinate value.

VertexDuplicationIndices: Informs you which vertices are duplicates of other vertices.

XSkinMeshHeader: Used by skinned meshes to define the number of bones contained in a mesh.

我们可以在DirectX9SDK的安装目录下搜索到“rmxfguid.h”字样的头文件。在rmxfguid.h中定义了各个模版的宏,例如:

/* {3D82AB44-62DA-11cf-AB39-0020AF71E433} */

DEFINE_GUID(TID_D3DRMMesh,

0x3d82ab44, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33);

每个模版名加上前缀TID_D3DRM就是宏定义名。既然微软已经帮助我们定义了那么多的模版,我们可以根据需求,充分的去利用这些模版。另外,这些模版往往会有相关的帮助函数,我们使用它们可以事半功倍。

第四,创建X文件接口:

我们已经对X文件的模版概念有所了解,现在将使用它们。当然,要想使用首先得访问X文件。访问任何X文件首先要调用DirectXFileCreate函数创建一个IDirectXFile接口,这个接口就代表了一个X文件。

IDirectXFile *pDXFile = NULL;

HRESULT Result = DirectXFileCreate(&pDXFile);//用&pDXFile返回指向接口的指针。用SUCCEEDED或者FAILED宏判断返回值是否有效。

创建完IDirectXFile接口,我们要注册一个定制模版或者标准模版。定制模版是自己定义的模版,标准模版是微软帮我们定义的模版,其实它们之间没有本质的区别,你现在要做的就是告诉IDirectXFile接口,使用二者之中的哪种。

如何注册定制模版呢?下面举个例子更容易理解。你可以把X文件中的模版移除,直接在代码里定义那些模版。IDirectXFile接口支持这样的特性。需要调用IDirectXFile::RegisterTemplates函数。

HRESULT IDirectXFile::RegisterTemplates(

LPVOID pvData, // 一个定义模版数据的缓存,应该精确无误。

DWORD cbSize); // pvData缓存的字节数。

可以如下定义一个模版数据:

char *Templates = "

"xof 0303txt 0032 \ //标准X文件头。

template CustomTemplate { \

<4c944580-9e9a-11cf-ab43-0120af71e433> \

DWORD Length; \

array DWORD Values[Length]; \

}";

之后在用RegisterTemplates将其注册:

pFile→RegisterTemplates(Templates, strlen(Templates));

如何注册标准模版呢?首先需要在代码中包含rmxfguid.h和rmxftmpl.h。rmxfguid.h定义了各个标准模版的GUDI,rmxftmpl.h以2进制数据形式定义了标准模版数据的缓存和其字节数。然后调用RegisterTemplates将其注册:

pFile→RegisterTemplates(D3DRM_XTEMPLATES, \

D3DRM_XTEMPLATE_BYTES);

0 评论

Recommended Comments

没有要显示的评论。

访客
Add a comment...

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.