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

            天行健 君子當(dāng)自強(qiáng)而不息

            Using Key?Framed Skeletal Animation(4)

            Matching Animations to Bones

            After you've loaded the animation data, you need to map the animation classes to their respective bones in the bone hierarchy. Mapping the hierarchies is important because whenever an animation is updated, you need a quick way to access the bone's transformations. By mapping, you create an easier method of accessing the bones.

            In this instance, the bone hierarchy will be represented in a D3DXFRAME hierarchy. Inside the D3DXFRAME structure, there are two linked list pointers that you'll use to help construct the hierarchy. From the root D3DXFRAME structure you are using, you can access child objects through the D3DXFRAME::pFrameFirstChild pointer and sibling objects through the D3DXFRAME::pFrameSibling pointer.

            The next function in cAnimationCollection to which you want to pay attention is Map. You use the Map function to map the animation structure's m_Bone pointer to a frame in the frame hierarchy that shares the same name.

            The Map function scans through every cAnimationSet object and iterates every cAnimation object contained in each of the animation set objects. The name of each cAnimation object is compared to each of the frame's names; if a match is found, the cAnimation::m_Bone pointer is set to the frame's address.

            The Map function takes the hierarchy's root frame parameter.

            void cAnimationCollection::Map(D3DXFRAME *RootFrame)
            {
            // Go through each animation set
            cAnimationSet *AnimSet = m_AnimationSets;
            	while(AnimSet != NULL) 
            {
            // Go through each animation object
            cAnimation *Anim = AnimSet−>m_Animations;
            		while(Anim != NULL) 
            {
            // Go through all frames and look for match
            Anim−>m_Bone = FindFrame(RootFrame, Anim−>m_Name);
            			// Go to next animation object
            Anim = Anim−>m_Next;
            }
            		// Go to next animation set object
            AnimSet = AnimSet−>m_Next;
            }
            }

            Whereas the Map function only scans through each of the cAnimationSet and cAnimation objects, the FindFrame function recursively works through the frame hierarchy to look for a match to the name you provide. When it finds a matching name, the FindFrame function returns the pointer to the specific frame. Take a look at the FindFrame code on which the Map function depends.

            D3DXFRAME *cAnimationCollection::FindFrame(D3DXFRAME *Frame, char *Name)
            {
            D3DXFRAME *FramePtr;
            	// Return NULL if no frame
            if(!Frame)
            return NULL;
            	// Return current frame if no name used
            if(!Name)
            return Frame;
            	// Process child frames
            if((FramePtr = FindFrame(Frame−>pFrameFirstChild, Name)))
            return FramePtr;
            	// Process sibling frames
            if((FramePtr = FindFrame(Frame−>pFrameSibling, Name)))
            return FramePtr;
            	// Nothing found
            return NULL;
            }

            Again, take a deep breath. The animation data has been loaded, and you've mapped the animation objects to the bone hierarchy. All that's left to do is update the animation and set the transformation matrices for the bones.

             

            Updating Animations

            After you've matched the animation classes to the bone hierarchy, you can begin animating your meshes! All you have to do is scan the animation keys for each bone, applying the interpolated transformations to each bone's transformation before rendering. This is merely a matter of iterating through each animation class and its keys to find the proper key values to use.

            Going back to the cAnimationCollection class, you can see that one function will do all that for you. By supplying the cAnimationCollection::Update function with the name of the animation set you want to use, as well as the time in the animation, all of the transformation matrices in your entire mapped bone hierarchy will be set and ready for rendering.

            Take a closer look at the Update function to see how you can update your animation data.

            void cAnimationCollection::Update(char *AnimationSetName, DWORD Time)
            {
            cAnimationSet *AnimSet = m_AnimationSets;
            DWORD i, Key, Key2;
            	// Look for matching animation set name if used
            if(AnimationSetName)
            {
            // Find matching animation set name
            while(AnimSet != NULL)
            {
            // Break when match found
            if(!stricmp(AnimSet−>m_Name, AnimationSetName))
            break;
            			// Go to next animation set object
            AnimSet = AnimSet−>m_Next;
            }
            }
            	// Return no set found
            if(AnimSet == NULL)
            return;

            The Update function starts by scanning the list of animation sets loaded into the linked list. If you instead supply a NULL value for AnimationSetName, Update will merely use the first animation set in the list (which happens to be the last set loaded). If no matching sets are found using the name you specified, the function returns without further delay.

            Once a matching animation set is found, however, the code continues by scanning each cAnimation object in it. For each animation object, the entire list of keys (translation, scaling, rotation, and transformation) is searched, and the time you specify is checked to see which key to use.

            After you've found the proper key to use, the values (rotation, scaling, translation, or transformation) are interpolated, and a final transformation matrix is computed. This final transformation matrix is then stored in the mapped bone (as pointed to by the m_Bone pointer).

            You've already seen how to scan a list of keys to look for the ones between which a specific time falls, so I'll skip the code here.

            Once you've calculated the transformations to apply to each bone from the animation data, you can jump right back into the game and render the mesh. Remember, you must apply the transformation matrices for each bone to the appropriate vertices in the mesh, and the best way to do so is to use a vertex shader.


            posted on 2008-04-25 13:13 lovedday 閱讀(283) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            超级碰久久免费公开视频| 色青青草原桃花久久综合| 久久精品无码专区免费东京热| 国内精品久久久久久久久电影网| 亚洲乱码中文字幕久久孕妇黑人| 99久久精品午夜一区二区 | 日产精品99久久久久久| 久久久久久a亚洲欧洲aⅴ| 午夜不卡久久精品无码免费 | 久久精品国产亚洲av麻豆小说| 91精品国产综合久久久久久| 久久人搡人人玩人妻精品首页| 久久99精品久久久久久动态图| 久久精品国产亚洲av瑜伽| 久久亚洲中文字幕精品一区| 一级做a爰片久久毛片人呢| 伊人色综合久久天天人手人婷| 国产成人无码精品久久久久免费| 国产色综合久久无码有码| 国产精品欧美亚洲韩国日本久久| 久久婷婷五月综合成人D啪| 99久久精品免费看国产| 丁香狠狠色婷婷久久综合| 国产精品99久久久精品无码| 久久亚洲国产成人精品无码区| a级成人毛片久久| 久久精品国产亚洲AV无码偷窥 | 久久婷婷五月综合国产尤物app| 99久久亚洲综合精品成人| 日本久久久久亚洲中字幕| 亚洲国产另类久久久精品小说 | 久久久久久国产精品美女| 久久久精品久久久久特色影视| 91视频国产91久久久| 69国产成人综合久久精品| 99精品国产在热久久无毒不卡| 77777亚洲午夜久久多人| 久久无码高潮喷水| 久久久久久久精品成人热色戒| 亚洲国产成人精品无码久久久久久综合 | 亚洲国产天堂久久久久久|