青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當自強而不息

Using Key?Framed Skeletal Animation(3)

Assuming you want more than one animation set loaded at once, you can even create a class that contains an array (or rather, a linked list) of cAnimationSet classes, which means that you can access a whole slew of animations with one interface! This class, called cAnimationCollection, is also derived from the cXParser class, so you can parse .X files directly from the class in which you'll be storing the animations.

Here's the class declaration for cAnimationCollection:

class cAnimationCollection : public cXParser
{
public:
DWORD m_NumAnimationSets;
cAnimationSet *m_AnimationSets;
protected:
// Parse an .X file object
BOOL ParseObject(IDirectXFileData *pDataObj,
IDirectXFileData *pParentDataObj,
DWORD Depth,
void **Data, BOOL Reference);
public:
cAnimationCollection();
~cAnimationCollection();
	BOOL Load(char *Filename);
void Free();
void Map(D3DXFRAME *RootFrame);
void Update(char *AnimationSetName, DWORD Time);
};

The details of each function in the cAnimationCollection class are not very important at this point so I'll get back to them in a bit. At this point, all you're interested in is reading in that animation data from an .X file. The custom .X parser contained in the cAnimationCollection class does just that, it loads the data from the Animation objects' data into the dizzying array of objects you've just seen.

For every AnimationSet object you encounter in the .X file being parsed, you need to allocate a cAnimationSet class and add it to the linked list of animation sets already loaded. The most current cAnimationSet object is stored at the start of the linked list, which makes it easy to determine which animation−set data you are currently using.

From here, you can appropriately parse the Animation objects. If you were to keep the most current cAnimationSet object at the start of your linked list, every following Animation object that you parse would belong to that animation−set object. The same goes for the AnimationKey objects, their data would belong to the first cAnimation object in the linked list.

I will skip the constructors and destructors for all the different classes because you only need them to clear and release each class's data. You're only interested in a couple functions, the first being cAnimationCollection::ParseObject, which deals with each animation object being parsed from an .X file.

The ParseObject function starts by checking whether the currently enumerated object is an AnimationSet. If it is, a new cAnimationSet object is allocated and linked to the list of objects, while the animation−set object is simultaneously named for further reference.

BOOL cAnimationCollection::ParseObject( 
IDirectXFileData *pDataObj,
IDirectXFileData *pParentDataObj,
DWORD Depth,
void **Data, BOOL Reference)
{
const GUID *Type = GetObjectGUID(pDataObj);
DWORD i;
	// Check if object is AnimationSet type
if(*Type == TID_D3DRMAnimationSet) {
// Create and link in a cAnimationSet object
cAnimationSet *AnimSet = new cAnimationSet();
AnimSet−>m_Next = m_AnimationSets;
m_AnimationSets = AnimSet;
		// Increase # of animation sets
m_NumAnimationSets++;
		// Set animation set name (set a default one if none)
if(!(AnimSet−>m_Name = GetObjectName(pDataObj)))
AnimSet−>m_Name = strdup("NoName");
}

As you can see, nothing special goes on with the animation set objects, you're merely allocating an object that will eventually hold the upcoming Animation data objects. Speaking of which, you want to parse the Animation objects next.

// Check if object is Animation type
if(*Type == TID_D3DRMAnimation && m_AnimationSets) {
// Add a cAnimation class to top−level cAnimationSet
cAnimation *Anim = new cAnimation();
Anim−>m_Next = m_AnimationSets−>m_Animations;
m_AnimationSets−>m_Animations = Anim;
	// Increase # of animations
m_AnimationSets−>m_NumAnimations++;
}

Again, nothing special going on there. In the preceding code, you're simply ensuring that there's a cAnimationSet object allocated at the start of the linked list. If there is, you can allocate and link a cAnimation object to the list in the cAnimationSet object.

While we're on the topic of the cAnimation object, the next bit of code retrieves the name of the frame instance located within the Animation object.

// Check if a frame reference inside animation object
if(*Type == TID_D3DRMFrame && Reference == TRUE && m_AnimationSets && m_AnimationSets−>m_Animations) {
// Make sure parent object is an Animation object
if(pParentDataObj && *GetObjectGUID(pParentDataObj) == TID_D3DRMAnimation) {
// Get name of frame and store it as animation
if(!(m_AnimationSets−>m_Animations−>m_Name = GetObjectName(pDataObj)))
m_AnimationSets−>m_Animations−>m_Name=strdup("NoName");
}
}

You can see in this code that only referenced frame objects are allowed in the Animation object, a fact that you can verify by checking the parent object's template GUID. Whew! So far this code is pretty easy, isn't it? Well, I don't want to burst your bubble, but the hardest is yet to come! In fact, the most difficult part of loading animation data from an .X file is loading the key data. Don't let me scare you away, though; the key data is nothing more than a time value and an array of values that represent the key data.

The remaining code in the ParseObject function checks to see which type of key data an AnimationKey object holds. Depending on the type of data, the code branches off and reads the data into the specific key objects (m_RotationKeys, m_TranslationKeys, m_ScaleKeys, and m_MatrixKeys) inside the current cAnimation object. Take a closer look to see how simple this code really is.

// Check if object is AnimationKey type
if(*Type == TID_D3DRMAnimationKey && m_AnimationSets && m_AnimationSets−>m_Animations) {
// Get a pointer to top−level animation object
cAnimation *Anim = m_AnimationSets−>m_Animations;
	// Get a data pointer
DWORD *DataPtr = (DWORD*)GetObjectData(pDataObj, NULL);
	// Get key type
DWORD Type = *DataPtr++;
	// Get # of keys to follow
DWORD NumKeys = *DataPtr++;

In addition to checking to see whether there are valid cAnimationSet and cAnimation objects at the start of the linked list of objects, the preceding code gets a pointer to the key data and pulls out the key type value and the number of keys to follow. Using the key type, the code then branches off to allocate the key−frame objects and load in the key data.

// Branch based on key type
switch(Type) {
case 0: // Rotation
delete [] Anim−>m_RotationKeys;
Anim−>m_NumRotationKeys = NumKeys;
Anim−>m_RotationKeys = new cAnimationQuaternionKey[NumKeys];
	for(i=0;i<NumKeys;i++) {
// Get time
Anim−>m_RotationKeys[i].m_Time = *DataPtr++;
		if(Anim−>m_RotationKeys[i].m_Time > m_AnimationSets−>m_Length)
m_AnimationSets−>m_Length = Anim−>m_RotationKeys[i].m_Time;
		// Skip # keys to follow (should be 4)
DataPtr++;
		// Get rotational values
		float *fPtr = (float*)DataPtr;
		Anim−>m_RotationKeys[i].m_quatKey.w = *fPtr++;
Anim−>m_RotationKeys[i].m_quatKey.x = *fPtr++;
Anim−>m_RotationKeys[i].m_quatKey.y = *fPtr++;
Anim−>m_RotationKeys[i].m_quatKey.z = *fPtr++;
		DataPtr+=4;
}
	break;

You'll recall from earlier in this chapter that rotation keys use quaternion values. These values are stored in w, x, y, z order; to make sure you use the proper values, you must read them into the key's quaternion object appropriately.

Next comes the code to load in the scaling and translation keys, which both use vectors to store the x−, y−, and z−axis information.

case 1: // Scaling
delete [] Anim−>m_ScaleKeys;
Anim−>m_NumScaleKeys = NumKeys;
Anim−>m_ScaleKeys = new cAnimationVectorKey[NumKeys];
	for(i=0;i<NumKeys;i++) {
// Get time
Anim−>m_ScaleKeys[i].m_Time = *DataPtr++;
		if(Anim−>m_ScaleKeys[i].m_Time > m_AnimationSets−>m_Length)
m_AnimationSets−>m_Length = Anim−>m_ScaleKeys[i].m_Time;
		// Skip # keys to follow (should be 3)
DataPtr++;
		// Get scale values
D3DXVECTOR3 *vecPtr = (D3DXVECTOR3*)DataPtr;
Anim−>m_ScaleKeys[i].m_vecKey = *vecPtr;
DataPtr+=3;
}
	break;
case 2: // Translation
delete [] Anim−>m_TranslationKeys;
Anim−>m_NumTranslationKeys = NumKeys;
Anim−>m_TranslationKeys = new cAnimationVectorKey[NumKeys];
	for(i=0;i<NumKeys;i++) {
// Get time
Anim−>m_TranslationKeys[i].m_Time = *DataPtr++;
		if(Anim−>m_TranslationKeys[i].m_Time > m_AnimationSets−>m_Length)
m_AnimationSets−>m_Length = Anim−>m_TranslationKeys[i].m_Time;
		// Skip # keys to follow (should be 3)
DataPtr++;
		// Get translation values
D3DXVECTOR3 *vecPtr = (D3DXVECTOR3*)DataPtr;
Anim−>m_TranslationKeys[i].m_vecKey = *vecPtr;
DataPtr+=3;
}
	break;

Last is the code to read an array of transformation matrix keys.

	case 4: // Transformation matrix
delete [] Anim−>m_MatrixKeys;
Anim−>m_NumMatrixKeys = NumKeys;
Anim−>m_MatrixKeys = new cAnimationMatrixKey[NumKeys];
		for(i=0;i<NumKeys;i++) {
// Get time
Anim−>m_MatrixKeys[i].m_Time = *DataPtr++;
			if(Anim−>m_MatrixKeys[i].m_Time > m_AnimationSets−>m_Length)
m_AnimationSets−>m_Length = Anim−>m_MatrixKeys[i].m_Time;
			// Skip # keys to follow (should be 16)
DataPtr++;
			// Get matrix values
D3DXMATRIX *mPtr = (D3DXMATRIX *)DataPtr;
Anim−>m_MatrixKeys[i].m_matKey = *mPtr;
DataPtr += 16;
}
		break;
}
}

Okay now, take a quick breather and look back at what you've just accomplished. So far, you've processed every AnimationSet, Animation, and AnimationKey object (not to mention referenced Frame objects that contain the bones' names), plus you've loaded the key objects full of the animation data. You're almost ready to start animating!

Almost is right; there is one small step left: matching the animation objects to their respective bone objects.


posted on 2008-04-24 19:27 lovedday 閱讀(288) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


公告

導航

統計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美xxx成人| 99在线热播精品免费| 国产在线精品二区| 亚洲精品综合精品自拍| 欧美在线观看网址综合| 最新高清无码专区| 亚洲免费在线观看| 裸体歌舞表演一区二区| 一区二区日韩精品| 久久男女视频| 国产午夜精品久久久久久免费视 | 亚洲欧洲一区二区三区| 欧美日韩第一区| 亚洲国产精品久久精品怡红院| 亚洲在线观看视频网站| 亚洲成色999久久网站| 欧美一区二区精品| 国产精品影视天天线| 亚洲性夜色噜噜噜7777| 亚洲激情网站| 国产精品免费观看在线| 亚洲午夜小视频| 欧美一区三区三区高中清蜜桃 | 免费欧美日韩| 在线观看的日韩av| 老色鬼久久亚洲一区二区| 欧美aⅴ99久久黑人专区| 亚洲亚洲精品三区日韩精品在线视频| 中国成人黄色视屏| 欧美日韩免费观看一区=区三区| 亚洲国产一区在线观看| 免费久久精品视频| 久久久久久久久综合| 一区国产精品| 欧美电影免费观看高清| 美女网站久久| 亚洲欧洲精品一区| 亚洲激情图片小说视频| 国产伦精品一区二区三区视频黑人 | 欧美成人高清视频| 亚洲国产欧美另类丝袜| 亚洲一级网站| 国产一区二区黄| 老司机精品视频一区二区三区| 欧美日本一道本| 亚洲与欧洲av电影| 欧美国产日本高清在线| 日韩天堂在线观看| 一区二区三区四区蜜桃| 91久久久久| 久久久xxx| 在线亚洲成人| 欧美一区二区高清| 午夜精品久久久久影视| 久久国产综合精品| 日韩视频在线一区| 蜜桃av一区二区在线观看| 久久精彩免费视频| 欧美大片免费观看| 欧美成人一区二区三区片免费| 国产欧美日韩一区| 亚洲国产天堂久久综合| 国产精品黄视频| 另类天堂av| 黑丝一区二区三区| 亚洲精品永久免费| 国产综合av| 久久精品首页| 久久免费视频这里只有精品| 欧美极品在线观看| 久久婷婷人人澡人人喊人人爽| 欧美国产日韩精品| 亚洲激情二区| 在线一区二区日韩| 欧美视频日韩视频| 亚洲国产va精品久久久不卡综合| 国产精品久久7| 亚洲自拍电影| 99在线精品免费视频九九视| 欧美另类高清视频在线| av成人天堂| 亚洲大胆女人| 香蕉乱码成人久久天堂爱免费| 亚洲毛片av在线| 欧美日韩在线精品| 亚洲视频福利| 久久青草欧美一区二区三区| 1024成人网色www| 欧美国产精品久久| 一区二区三区高清| 久久久精品一区| 国产精品日韩久久久| 亚洲精品国产精品国自产观看| 韩国一区二区三区在线观看| 开元免费观看欧美电视剧网站| 欧美在线日韩| 国产精品日韩欧美综合| 久久成人一区二区| 亚洲人成免费| 久久精品官网| 亚洲美女色禁图| 国产午夜精品一区二区三区欧美| 久久久久久网址| 在线亚洲观看| 欧美成人四级电影| 欧美一区二区免费| 亚洲人成绝费网站色www| 国产精品亚发布| 欧美激情第4页| 欧美在线网站| 乱中年女人伦av一区二区| 一本色道久久综合一区| 国产视频在线观看一区二区三区 | av成人毛片| 老司机精品导航| 午夜亚洲福利在线老司机| 最近中文字幕mv在线一区二区三区四区| 欧美日韩精品系列| 麻豆精品视频在线观看| 亚洲欧美日韩区| 久久网站热最新地址| 这里只有精品视频| 亚洲激情一区二区| 国内一区二区在线视频观看| 欧美日韩视频不卡| 欧美激情亚洲激情| 久久午夜av| 欧美在线你懂的| 亚洲欧美日韩视频一区| 一区二区三区免费在线观看| 亚洲国产高清自拍| 欧美成年人视频网站欧美| 久久狠狠婷婷| 欧美在线一二三四区| 亚洲一区二区三区四区中文| 99国内精品久久| av72成人在线| 夜久久久久久| 99在线精品观看| 中文一区二区| 在线播放豆国产99亚洲| 国产亚洲精品v| 国产亚洲精品aa| 国产日韩欧美制服另类| 国产欧美日韩不卡免费| 国产精品社区| 国产美女精品视频免费观看| 国产精品免费在线| 国产女主播在线一区二区| 国产精品免费一区二区三区在线观看| 国产精品va在线播放| 久久久久亚洲综合| 久久久久久久综合狠狠综合| 久久九九热免费视频| 久久影视精品| 欧美精品18+| 欧美色欧美亚洲另类二区| 欧美日韩网站| 国产精品一区久久| 国产一区二区三区自拍| 伊人成年综合电影网| 最近中文字幕mv在线一区二区三区四区| 伊人激情综合| 日韩亚洲欧美精品| 小辣椒精品导航| 亚洲一级二级| 久久gogo国模啪啪人体图| 久久久亚洲一区| 91久久嫩草影院一区二区| 99热这里只有成人精品国产| 亚洲女人天堂av| 久久这里只精品最新地址| 欧美精品色综合| 国产麻豆日韩| 亚洲激情二区| 亚洲一区尤物| 蜜臀av性久久久久蜜臀aⅴ| 亚洲国产精品精华液2区45| 一本一本大道香蕉久在线精品| 欧美在线观看网址综合| 欧美激情精品久久久六区热门| 欧美视频免费在线观看| 狠狠爱成人网| 一本一本久久a久久精品综合妖精| 欧美一区二区观看视频| 欧美高清日韩| 午夜精品一区二区三区电影天堂| 快射av在线播放一区| 国产精品美女午夜av| 亚洲国产一区二区a毛片| 欧美一级夜夜爽| 91久久久久久国产精品| 欧美在线地址| 国产精品久久97| 99精品99久久久久久宅男| 久久青草福利网站| 洋洋av久久久久久久一区| 美女网站久久| 激情懂色av一区av二区av| 亚洲欧美精品在线观看|