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

天行健 君子當自強而不息

Blending Skeletal Animations(3)

Check Out the Demo

Although this chapter only has one demo to tout, it sure is a whopper! Demonstrating the technique of blended animation, the SkeletalAnimBlend demo program (see Figure 6.3) shows off Microsoft's Tiny character in all her blended glory!

Figure 6.3: Explore your new found blended skeletal animation techniques by choosing which animations to blend in real time.

I edited the Tiny.x file to split her animation up into multiple sets. There are animation sets for each of her arms and legs, as well as an animation set for her body. Pressing any of the keys displayed on the screen toggles the blending of the appropriate animation set. For instance, hitting 1 toggles the blending of her left arm animation sequence. When enabled, the left arm animation has Tiny swinging her arm in sequence with her step. When disabled, her left arm hangs limp.

To really illustrate the power of blending, suppose you add a new animation set to the Tiny.x file that has Tiny waving her arm as opposed to swinging it back and forth. You only need to turn off blending of the swinging animation and blend in the waving animation to create a new and totally unique animation!

 

SkeletalAnimBlend.h:

#ifndef SKELETAL_ANIM_BLEND_H
#define SKELETAL_ANIM_BLEND_H

#include 
"SkeletalAnim.h"

class cBlendAnimationCollection : public cAnimationCollection
{
public:
    
void blend(const char* anim_set_name, DWORD time, bool is_loop, float blend);
};

#endif

 

SkeletalAnimBlend.cpp:

#include "SkeletalAnimBlend.h"

#pragma warning(disable : 
4996)

void cBlendAnimationCollection::blend(const char* anim_set_name, 
                                      DWORD time, 
bool is_loop, float blend)
{
    sAnimationSet
* anim_set = m_anim_sets;

    
// look for matching animation set if name used
    if(anim_set_name)
    {
        
// find matching animation set name
        while(anim_set != NULL)
        {
            
// break when match found
            if(! stricmp(anim_set->name, anim_set_name))
                
break;

            anim_set 
= anim_set->next;
        }
    }

    
if(anim_set == NULL)    // no animation set found
        return;

    
// bounds time to animation length
    if(time > anim_set->length)
        time 
= is_loop ? (time % (anim_set->length + 1)) : anim_set->length;

    
for(sAnimation* anim = anim_set->anims; anim != NULL; anim = anim->next)
    {
        
if(anim->bone == NULL)    // only process if it is attached to a bone
            continue;
    
        
// reset transformation
        D3DXMATRIX anim_matrix;
        D3DXMatrixIdentity(
&anim_matrix);

        
// apply various matrices to transformation

        
// scaling
        if(anim->num_scale_keys && anim->scale_keys)
        {
            DWORD key1 
= 0, key2 = 0;

            
// loop for matching scale key
            for(DWORD i = 0; i < anim->num_scale_keys; i++)
            {
                
if(time >= anim->scale_keys[i].time)
                    key1 
= i;
            }

            key2 
= (key1 >= (anim->num_scale_keys - 1)) ? key1 : key1+1;

            DWORD time_diff 
= anim->scale_keys[key2].time - anim->scale_keys[key1].time;

            
if(time_diff == 0)
                time_diff 
= 1;

            
float scalar = (float)(time - anim->scale_keys[key1].time) / time_diff;

            
// calculate interpolated scale values
            D3DXVECTOR3 scale_vec = anim->scale_keys[key2].vec - anim->scale_keys[key1].vec;
            scale_vec 
*= scalar;
            scale_vec 
+= anim->scale_keys[key1].vec;

            
// create scale matrix and combine with transformation
            D3DXMATRIX scale_matrix;
            D3DXMatrixScaling(
&scale_matrix, scale_vec.x, scale_vec.y, scale_vec.z);
            anim_matrix 
*= scale_matrix;
        }

        
// rotation
        if(anim->num_rotation_keys && anim->rotation_keys)
        {
            DWORD key1 
= 0, key2 = 0;

            
// loop for matching rotation key
            for(DWORD i = 0; i < anim->num_rotation_keys; i++)
            {
                
if(time >= anim->rotation_keys[i].time)
                    key1 
= i;
            }

            key2 
= (key1 >= (anim->num_rotation_keys - 1)) ? key1 : key1+1;

            DWORD time_diff 
= anim->rotation_keys[key2].time - anim->rotation_keys[key1].time;

            
if(time_diff == 0)
                time_diff 
= 1;

            
float scalar = (float)(time - anim->rotation_keys[key1].time) / time_diff;

            
// slerp rotation values
            D3DXQUATERNION rot_quat;
            D3DXQuaternionSlerp(
&rot_quat, &anim->rotation_keys[key1].quat, &anim->rotation_keys[key2].quat, scalar);

            
// create rotation matrix and combine with transformation
            D3DXMATRIX rot_matrix;
            D3DXMatrixRotationQuaternion(
&rot_matrix, &rot_quat);
            anim_matrix 
*= rot_matrix;
        }

        
// translation
        if(anim->num_translation_keys && anim->translation_keys)
        {
            DWORD key1 
= 0, key2 = 0;

            
// loop for matching translation key
            for(DWORD i = 0; i < anim->num_translation_keys; i++)
            {
                
if(time >= anim->translation_keys[i].time)
                    key1 
= i;
            }

            key2 
= (key1 >= (anim->num_matrix_keys - 1)) ? key1 : key1+1;

            DWORD time_diff 
= anim->translation_keys[key2].time - anim->translation_keys[key1].time;

            
if(time_diff == 0)
                time_diff 
= 1;

            
float scalar = (float)(time - anim->translation_keys[key1].time) / time_diff;

            
// calculate interpolated vector values
            D3DXVECTOR3 pos_vec = anim->translation_keys[key2].vec - anim->translation_keys[key1].vec;
            pos_vec 
*= scalar;
            pos_vec 
+= anim->translation_keys[key1].vec;

            
// create translation matrix and combine with transformation
            D3DXMATRIX translation_matrix;
            D3DXMatrixTranslation(
&translation_matrix, pos_vec.x, pos_vec.y, pos_vec.z);
            anim_matrix 
*= translation_matrix;
        }

        
// matrix
        if(anim->num_matrix_keys && anim->matrix_keys)
        {
            DWORD key1 
= 0, key2 = 0;

            
// loop for matching matrix key
            for(DWORD i = 0; i < anim->num_matrix_keys; i++)
            {
                
if(time >= anim->matrix_keys[i].time)
                    key1 
= i;
            }

            key2 
= (key1 >= (anim->num_matrix_keys - 1)) ? key1 : key1+1;

            DWORD time_diff 
= anim->matrix_keys[key2].time - anim->matrix_keys[key1].time;

            
if(time_diff == 0)
                time_diff 
= 1;

            
float scalar = (float)(time - anim->matrix_keys[key1].time) / time_diff;

            
// calculate interpolated matrix
            D3DXMATRIX diff_matrix = anim->matrix_keys[key2].matrix - anim->matrix_keys[key1].matrix;
            diff_matrix 
*= scalar;
            diff_matrix 
+= anim->matrix_keys[key1].matrix;

            
// combine with transformation
            anim_matrix *= diff_matrix;
        }

        D3DXMATRIX diff_matrix 
= anim_matrix - anim->bone->mat_original;
        diff_matrix 
*= blend;
        anim
->bone->TransformationMatrix += diff_matrix;
    }
}

 

WinMain.cpp:

/***********************************************************************************************
 Demonstrates how multiple skeletal-based animations can be blended together into one animation.
**********************************************************************************************
*/

#include 
<windows.h>
#include 
<d3d9.h>
#include 
<d3dx9.h>
#include 
"Direct3D.h"
#include 
"SkeletalAnimBlend.h"

IDirect3D9
*                g_d3d;
IDirect3DDevice9
*        g_device;
D3DXMESHCONTAINER_EX
*    g_mesh_container;
D3DXFRAME_EX
*            g_frame;
IDirect3DTexture9
*        g_guide_texture;
ID3DXSprite
*            g_guide_sprite;

cBlendAnimationCollection    g_blend_anim_collection;

char g_blend_flags[5];        // blending toggles (arms, legs, )

const char CLASS_NAME[] = "BlendSkeletalAnimClass";
const char CAPTION[]    = "Blended Skeletal Animation Demo";

////////////////////////////////////////////////////////////////////////////////////////////////

LRESULT FAR PASCAL window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

bool do_init(HWND hwnd);
void do_shutdown();
void do_frame();


//////////////////////////////////////////////////////////////////////////////////////////////

int PASCAL WinMain(HINSTANCE inst, HINSTANCE, LPSTR, int cmd_show)
{      
    CoInitialize(NULL);    
// Initialize the COM system

    
// Create the window class here and register it

    WNDCLASSEX win_class;  

    win_class.cbSize        
= sizeof(win_class);
    win_class.style         
= CS_CLASSDC;
    win_class.lpfnWndProc   
= window_proc;
    win_class.cbClsExtra    
= 0;
    win_class.cbWndExtra    
= 0;
    win_class.hInstance     
= inst;
    win_class.hIcon         
= LoadIcon(NULL, IDI_APPLICATION);
    win_class.hCursor       
= LoadCursor(NULL, IDC_ARROW);
    win_class.hbrBackground 
= NULL;
    win_class.lpszMenuName  
= NULL;
    win_class.lpszClassName 
= CLASS_NAME;
    win_class.hIconSm       
= LoadIcon(NULL, IDI_APPLICATION);

    
if(!RegisterClassEx(&win_class))
        
return -1;

    
// Create the main window
    HWND hwnd = CreateWindow(CLASS_NAME, CAPTION, WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
                             
00640480, NULL, NULL, inst, NULL);

    
if(hwnd == NULL)
        
return -1;

    ShowWindow(hwnd, cmd_show);
    UpdateWindow(hwnd);

    
// Call init function and enter message pump
    if(do_init(hwnd)) 
    {
        MSG msg;    
        ZeroMemory(
&msg, sizeof(MSG));

        
// Start message pump, waiting for user to exit
        while(msg.message != WM_QUIT) 
        {
            
if(PeekMessage(&msg, NULL, 00, PM_REMOVE)) 
            {
                TranslateMessage(
&msg);
                DispatchMessage(
&msg);
            }
            
            do_frame();    
// Render a single frame
        }
    }
  
    do_shutdown();
    UnregisterClass(CLASS_NAME, inst);
    CoUninitialize();

    
return 0;
}

LRESULT FAR PASCAL window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    
// Only handle window destruction messages
    switch(msg) 
    {
    
case WM_KEYUP:
        
// toggle a body part
        if(wParam >= '1' && wParam <= '5')
            g_blend_flags[wParam 
- '1'^= 1;

        
// clear toggles
        if(wParam == VK_SPACE)
            memset(g_blend_flags, 
1sizeof(g_blend_flags));

        
break;

    
case WM_KEYDOWN:
        
if(wParam == VK_ESCAPE)
            DestroyWindow(hwnd);
        
break;

    
case WM_DESTROY:
        PostQuitMessage(
0);
        
break;    
    }

    
return DefWindowProc(hwnd, msg, wParam, lParam);
}

bool do_init(HWND hwnd)
{
    init_d3d(
&g_d3d, &g_device, hwnd, falsefalse);

    
// load skeletal mesh
    if(FAILED(load_mesh(&g_mesh_container, &g_frame, g_device, "..\\Data\\tiny.x""..\\Data\\"
                        
0, D3DXMESH_SYSTEMMEM)))
    {
        
return false;
    }

    
// load animation data
    if(! g_blend_anim_collection.load("..\\Data\\tiny.x"))
        
return false;

    
// map the animation to the frame hierarchy
    g_blend_anim_collection.map_frames(g_frame);

    
// load the guide texture and create the sprite interface

    D3DXCreateTextureFromFileEx(g_device, 
"..\\Data\\Guide.bmp", D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 
                                
0, D3DFMT_A1R5G5B5, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
                                
0xFF000000, NULL, NULL, &g_guide_texture);

    D3DXCreateSprite(g_device, 
&g_guide_sprite);

    
// clear toggles
    memset(g_blend_flags, 1sizeof(g_blend_flags));

    
return true;
}

void do_shutdown()
{
    
// free mesh data
    delete g_mesh_container;    g_mesh_container = NULL;
    delete g_frame;                g_frame 
= NULL;

    
// free guide texture and sprite interface
    release_com(g_guide_texture);
    release_com(g_guide_sprite);
    
    
// release D3D objects
    release_com(g_device);
    release_com(g_d3d);
}

void do_frame()
{
    
static DWORD start_time = timeGetTime();
    DWORD curr_time 
= timeGetTime();

    g_frame
->reset();

    DWORD time 
= curr_time - start_time;

    
// blend the animations

    
if(g_blend_flags[0])
        g_blend_anim_collection.blend(
"left_arm",    time, true1.5f);
    
    
if(g_blend_flags[1])
        g_blend_anim_collection.blend(
"right_arm",    time, true1.5f);

    
if(g_blend_flags[2])
        g_blend_anim_collection.blend(
"left_leg",    time, true1.2f);

    
if(g_blend_flags[3])
        g_blend_anim_collection.blend(
"right_leg",    time, true1.2f);

    
if(g_blend_flags[4])
        g_blend_anim_collection.blend(
"body",        time, true1.0f);

    
// rebuild the frame hierarchy transformations
    if(g_frame)
        g_frame
->update_hierarchy(NULL);

    
// rebuild the mesh
    update_skin_mesh(g_mesh_container);

    
// calculate a view transformation matrix using the mesh's bounding radius to position the viewer
    
    D3DXMATRIX  mat_view;
    D3DXVECTOR3 eye(
600.0f200.0f-600.0f);
    D3DXVECTOR3 at(
0.0f0.0f0.0f);
    D3DXVECTOR3 up(
0.0f1.0f0.0f);

    D3DXMatrixLookAtLH(
&mat_view, &eye, &at, &up);
    g_device
->SetTransform(D3DTS_VIEW, &mat_view);    

    D3DXMATRIX mat_world;
    D3DXMatrixIdentity(
&mat_world);
    g_device
->SetTransform(D3DTS_WORLD, &mat_world);

    
// clear the device and start drawing the scene

    g_device
->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0064255), 1.0f0);

    g_device
->BeginScene();    

    draw_mesh(g_mesh_container);

    
// enable per pixel alpha testing
    g_device->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);

    
// specifies a reference alpha value against which pixels are tested
    g_device->SetRenderState(D3DRS_ALPHAREF, 0x01);

    
// accept the new pixel if its value is greater than the value of the current pixel
    g_device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);

    
// draw the guid teture
    g_guide_sprite->Begin(0);
    g_guide_sprite
->Draw(g_guide_texture, NULL, NULL, NULL, D3DCOLOR_RGBA(255 ,2550255));
    g_guide_sprite
->End();

    g_device
->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);

    g_device
->EndScene();

    g_device
->Present(NULL, NULL, NULL, NULL);
}

 

download source file


posted on 2008-04-25 21:11 lovedday 閱讀(583) 評論(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>
            欧美日本免费| 久久精品国产成人| 先锋影音久久| 日韩视频免费观看高清完整版| 亚洲高清激情| 欧美成人一区二区三区片免费| 欧美成人一区二免费视频软件| 欧美韩国日本一区| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲欧洲精品成人久久奇米网| 日韩午夜在线观看视频| 午夜精品亚洲| 免费久久精品视频| 欧美日韩国产专区| 国产精品自拍在线| 好吊色欧美一区二区三区四区 | 欧美人与性禽动交情品 | 影院欧美亚洲| 亚洲精品中文字幕在线观看| 中文网丁香综合网| 久久久久久9| 亚洲日本va在线观看| 亚洲欧美国产视频| 欧美国产一区二区在线观看 | 亚洲精品国产精品国自产在线| 一本色道久久88综合亚洲精品ⅰ | 亚洲久色影视| 欧美一区二区三区四区夜夜大片 | 亚洲国产精品美女| 99视频精品全部免费在线| 欧美亚洲在线视频| 欧美日本在线| 亚洲国产精品尤物yw在线观看| 亚洲欧美激情视频在线观看一区二区三区| 久久精品欧美日韩| 在线视频精品一区| 欧美成人在线免费视频| 国产欧美在线观看一区| 亚洲免费电影在线| 久久久另类综合| 亚洲一区二区三区涩| 欧美黄网免费在线观看| 伊人色综合久久天天| 欧美亚洲一区二区在线| 亚洲日本一区二区| 美女精品在线| 狠狠色综合色区| 欧美国产视频日韩| 久久久精品动漫| 国产一二三精品| 性欧美18~19sex高清播放| 亚洲精品日产精品乱码不卡| 久久视频国产精品免费视频在线 | 欧美一区综合| 国产午夜精品一区理论片飘花| 亚洲少妇中出一区| 欧美激情1区2区3区| 亚洲欧洲三级| 欧美www视频| 亚洲激情午夜| 欧美激情第9页| 麻豆91精品91久久久的内涵| 国内精品写真在线观看| 久久这里有精品视频| 午夜在线观看免费一区| 国产日韩欧美不卡| 久久精品国产77777蜜臀| 亚洲摸下面视频| 国产欧美日韩另类一区| 午夜视频精品| 欧美亚洲三级| 在线视频成人| 欧美激情亚洲自拍| 欧美极品一区二区三区| 9国产精品视频| 在线一区亚洲| 国产欧美日韩亚洲一区二区三区| 久久er99精品| 久久久xxx| 一本久久综合亚洲鲁鲁| 亚洲综合色婷婷| 激情国产一区| 免费观看亚洲视频大全| 欧美韩日一区二区| 亚洲手机视频| 亚洲欧美中文另类| 在线成人免费视频| 亚洲欧洲日本在线| 国产精品爽爽爽| 麻豆精品在线播放| 欧美日韩精品免费观看视频| 欧美一区二区三区精品电影| 久久精品一区二区三区不卡| 99re亚洲国产精品| 亚洲成人在线视频网站| 欧美精品一区二区三区四区| 欧美一区二区免费视频| 欧美国产1区2区| 久久精品国产视频| 欧美国产一区在线| 欧美怡红院视频| 欧美激情乱人伦| 欧美在线观看天堂一区二区三区| 免费视频最近日韩| 欧美一区二区三区久久精品| 久久综合狠狠综合久久综合88| 国产精品一区二区女厕厕| 国产一区视频在线观看免费| 91久久久久久久久| 国产欧美一区二区三区另类精品 | 国产精品久久久久久久久免费樱桃| 久久国产一区二区三区| 欧美人妖另类| 免费成人高清视频| 国产精品一区二区欧美| 亚洲欧洲日产国产综合网| 国产综合色产| 亚洲免费影视第一页| 一本色道久久88亚洲综合88| 久久男女视频| 久久久久久国产精品一区| 国产精品地址| 亚洲欧洲午夜| 亚洲人体一区| 美女久久一区| 免费日韩av片| 老司机精品久久| 亚洲国产经典视频| 在线不卡免费欧美| 欧美一区二区三区久久精品 | 国产综合久久久久久鬼色| 亚洲午夜高清视频| 亚洲影视在线播放| 欧美性事在线| 亚洲一区在线播放| 性亚洲最疯狂xxxx高清| 国产精品久久久久久久电影| 亚洲最新在线视频| 亚洲一区一卡| 国产精品腿扒开做爽爽爽挤奶网站| 99re成人精品视频| 亚洲尤物在线| 国产精品视频yy9299一区| 99精品99| 欧美一级大片在线观看| 国产日韩欧美不卡| 欧美怡红院视频| 你懂的亚洲视频| 亚洲美女啪啪| 欧美日韩中文| 亚洲一区二区在线播放| 亚洲欧美日韩精品久久久| 欧美日韩一区在线播放| 国产精品99久久久久久有的能看| 亚洲四色影视在线观看| 国产精品男女猛烈高潮激情| 亚洲欧美在线磁力| 久久伊人免费视频| 亚洲国产欧美一区二区三区久久| 美日韩精品视频免费看| 欧美xx视频| 国产亚洲精品aa午夜观看| 欧美在线免费播放| 亚洲国产精品嫩草影院| 日韩亚洲视频在线| 国产综合网站| 亚洲特黄一级片| 国产精品xnxxcom| 欧美激情网站在线观看| 亚洲免费不卡| 国产女人aaa级久久久级| 久久精品视频免费播放| 最新国产成人av网站网址麻豆| 亚洲视频网站在线观看| 国产精一区二区三区| 久久综合伊人77777蜜臀| 亚洲精品久久久久中文字幕欢迎你| 正在播放欧美视频| 国产精品乱码一区二三区小蝌蚪 | 亚洲午夜羞羞片| 亚洲欧美成人精品| 亚洲电影激情视频网站| 欧美日韩在线亚洲一区蜜芽| 一区二区三区欧美亚洲| 久久人人九九| 一区二区三区高清| 一区精品在线| 国产精品亚发布| 免费在线欧美黄色| 欧美一区二区三区免费在线看| 亚洲精品国久久99热| 久久国内精品视频| 亚洲字幕一区二区| 日韩亚洲不卡在线| 亚洲高清视频一区二区| 国模精品一区二区三区| 国产精品v亚洲精品v日韩精品| 美女脱光内衣内裤视频久久网站| 午夜在线不卡| 午夜亚洲性色视频|