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

麒麟子

~~

導航

<2009年3月>
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

統計

常用鏈接

留言簿(12)

隨筆分類

隨筆檔案

Friends

WebSites

積分與排名

最新隨筆

最新評論

閱讀排行榜

評論排行榜

[導入]DX 骨骼動畫

第一,了解骨骼結構(Skeletal Structures)和骨層級(Bone Hierarchies):

骨骼結構就是連續很多的骨頭(Bone)相結合,形成的骨層級。第一個骨頭叫做根骨(root bone),是形成骨骼結構的關鍵點。其它所有的骨骼作為孩子骨(child bone)或者兄弟骨(sibling bone)附加在根骨之上。所謂的“骨”用一個幀(frame)對象表示。在Directx中,用一個D3DXFRAME結構或者X文件中的Frame template來表示幀對象。下面看一下Frame template和D3DXFRAME結構的定義:

template Frame
{
        < 3D82AB46-62DA-11cf-AB39-0020AF71E433 >
        FrameTransformMatrix frameTransformMatrix;      // 骨骼相對于父節點的坐標變換矩陣,就是一個matrix
        Mesh mesh;                                      // 骨骼的Mesh
}

typedef struct _D3DXFRAME
{
LPSTR                   Name;                   // 骨骼名稱
D3DXMATRIX         TransformationMatrix;        // 相對與父節點的坐標變換矩陣
LPD3DXMESHCONTAINER     pMeshContainer; // LPD3DXMESHCONTAINER對象,
//用來加載MESH,還有一些附加屬性,見SDK
struct _D3DXFRAME       *pFrameSibling;         // 兄弟節點指針,和下面的子節點指針
// 一塊作用構成骨骼的層次結構。   
    struct _D3DXFRAME       *pFrameFirstChild;   // 子節點指針
} D3DXFRAME, *LPD3DXFRAME;


注意D3DXFRAME * pFrameSibling和D3DXFRAME * pFrameFirstChild,主要是利用這兩個指針形成骨層級。pFrameSibling把一個骨頭連接到兄弟層級,相對的,pFrameFirstChild把一個骨頭連接到子層級。通常,你需要用建模軟件為你的程序創建那些骨骼結構,輸出骨層級到X文件以便使用。Microsoft有3D Studio Max和Maya的輸出插件(exporter),可以輸出骨骼和動畫數據到X文件。很多建模程序也都有這樣的功能。


利用D3DXFRAME pointers指針形成了一個兄弟幀和孩子幀的鏈表。

在前面template Frame中已經提及過每個Frame數據對象中存放著一個變換矩陣,這個矩陣描述了該骨骼相對于父骨骼的位置。另外在根Frame數據對象中內嵌了一個標準的Mesh數據對象。Frame定義了骨骼的層級,而Mesh中的SkinWeights數據對象定義了Frame代表的骨頭。我們用D3DXFRAME結構容納從X文件加載進來的Frame數據對象。為了更好的容納Frame數據對象,我們需要擴展下D3DXFRAME結構:

struct D3DXFRAME_EX : D3DXFRAME
{
D3DXMATRIX matCombined;   // 組合變換矩陣,用于儲存變換的骨骼矩陣
D3DXMATRIX matOriginal;   // 從X文件加載的原始變換矩陣
D3DXFRAME_EX()
{
    Name = NULL;
    pMeshContainer = NULL;
    pFrameSibling = pFrameFirstChild = NULL;
    D3DXMatrixIdentity(&matCombined);
    D3DXMatrixIdentity(&matOriginal);
    D3DXMatrixIdentity(&TransformationMatrix);
}

~D3DXFRAME_EX()
{
    delete [] Name;          Name = NULL;
    delete pFrameSibling;    pFrameSibling = NULL;
    delete pFrameFirstChild; pFrameFirstChild = NULL;
}
}

利用我們以前介紹的cXParse類可以遍歷X文件的數據對象,從而加載出Frame數據對象。下面的代碼都是寫在方法ParseObject中,如下:

// 判斷當前分析的是不是Frame節點
if( objGUID == TID_D3DRMFrame )
{
// 引用對象直接返回,不需要做分析。一個數據段實際定義一次后可以被其他模板引用,例
//如后面的Animation動畫模板就會引用這里的Frame
// 節點,標識動畫關聯的骨骼。
if( pDataObj->IsReference() )
return true;
        // D3DXFRAME_EX為D3DXFRAME的擴展結構,增加些數據成員
        D3DXFRAME_EX *pFrame = new D3DXFRAME_EX();

// 得到名稱
        pFrame->Name = GetObjectName( pDataObj );

// 注意觀察文件就可以發現一個Frame要么是根Frame,父節點不存在, 要么作為某

//個Frame的孩子Frame而存在。
        if( NULL == pData )
        {
                // 作為根節點的兄弟節點加入鏈表。
                pFrame->pFrameSibling = m_pRootFrame;
                m_pRootFrame = pFrame;
                pFrame = NULL;
            // 將自定義數據指針指向自己,供子節點引用。
                pData = ( void** )&m_pRootFrame;
         }
         else
         {
                // 作為傳入節點的子節點
                D3DXFRAME_EX *pDataFrame = ( D3DXFRAME_EX* )( *pData );
                pFrame->pFrameSibling = pDataFrame->pFrameFirstChild;
                pDataFrame->pFrameFirstChild = pFrame;
                pFrame = NULL;
                pData = ( void** )&pDataFrame->pFrameFirstChild;
          }
}

記住我們只需要做一件事情,判斷類型,分配匹配的對象然后拷貝數據,下面來分析Frame中的matrix,

// frame的坐標變換矩陣, 因為matrix必然屬于某個Frame所以pData必須有效
else if( objGUID == TID_D3DRMFrameTransformMatrix && pData )
{
          // 我們可以肯定pData指向某個Frame
          D3DXFRAME_EX *pDataFrame = ( D3DXFRAME_EX* )( *pData );
          // 先取得緩沖區大小,應該是個標準的4x4矩陣
          DWORD size = 0;
          LPCVOID buffer = NULL;

          hr = pDataObj->Lock( &size, &buffer );
          if( FAILED( hr ) )
return false;

          // 拷貝數據
          if( size == sizeof( D3DXMATRIX ) )
          {
               memcpy( &pDataFrame->TransformationMatrix, buffer, size );
               pDataObj->Unlock();
               pDataFrame->matOriginal = pDataFrame->TransformationMatrix;
          }
}

第二,修改和更新骨骼層級:

加載完骨骼層級之后,你可以操作它,更改骨骼的方位。你需要創建一個遞歸函數,按照名字找到相應的Frame數據對象。這個函數如下:

D3DXFRAME_EX *FindFrame(D3DXFRAME_EX *Frame, char *Name)
{
if(Frame && Frame->Name && Name) {
// 如果名字找到,返回一個Frame指針
if(!strcmp(Frame->Name, Name)) // strcmp函數比較兩個字符串,如果兩個字符串相等,返回0
return Frame;
}
// 在sibling frames找匹配的名字
if(Frame && Frame->pFrameSibling) {
D3DXFRAME_EX *FramePtr = FindFrame((D3DXFRAME_EX*)Frame->pFrameSibling, Name);
if(FramePtr)
return FramePtr;

}
// 在child frames找匹配的名字
if(Frame && Frame->pFrameFirstChild) {
D3DXFRAME_EX *FramePtr = FindFrame((D3DXFRAME_EX*)Frame->pFrameFirstChild,Name);
if(FramePtr)
return FramePtr;
}
// 如果沒有找到,返回 NULL
return NULL;
}

如果你想找到一個叫“Leg”的Frame,可以把“Leg”傳入FindFrame函數,并且提供指向RootFrame的指針:
// pRootframe 為D3DXFRAME_EX root frame 指針
D3DXFRAME_EX *Frame = FindFrame(pRootFrame, "Leg");
if(Frame) {
// 可以在這里做一些處理,比如旋轉操作
// 你在這里可以稍微的旋轉這個骨頭
D3DXMatrixRotationY(&Frame->TransformationMatrix, 1.57f);
}

一旦你修改變換骨頭,你需要更新整個骨骼層級,也就是把變換的組合矩陣存入D3DXFRAME_EX結構的matCombined成員中,用于后面的渲染。下面的函數應該增加到D3DXFRAME_EX結構中,如下:

void UpdateHierarchy(D3DXMATRIX *matTransformation = NULL)
{
    D3DXFRAME_EX *pFramePtr;
    D3DXMATRIX matIdentity;
    // 如果為空,用一個全同矩陣
    if(!matTransformation) {
      D3DXMatrixIdentity(&matIdentity);
      matTransformation = &matIdentity;
    }
    // 把變換矩陣組合到matCombined中
    matCombined = TransformationMatrix * (*matTransformation);
    // 更新兄弟層級
    if((pFramePtr = (D3DXFRAME_EX*)pFrameSibling))
      pFramePtr->UpdateHierarchy(matTransformation);
    // 更新孩子層級
    if((pFramePtr = (D3DXFRAME_EX*)pFrameFirstChild))
      pFramePtr->UpdateHierarchy(&matCombined);
}
現在matCombined儲存著每個骨骼相對于原點的變換矩陣,然后只要把各個頂點附在相應的骨骼上,就能渲染了。

第三,使用蒙皮網格:

蒙皮網格和普通網格的唯一不同點就是看XskinMeshHeader和SkinWeights模版是否存在。如果把這兩個模版從任何一個蒙皮網格里面移走的話,就可以得到一個普通網格。在X文件中,我們將會發現一個GUID為TID_D3DRMMesh的模版,這表示模版里面存有一個網格。利用D3D的幫助函數D3DXLoadSkinMeshFromXof將會加載蒙皮網格和其它補充性數據。只需要向它傳遞一個IDirectXFileData指針,然后它將為你做剩下的事情。現在介紹下D3DXLoadSkinMeshFromXof函數:

HRESULT D3DXLoadSkinMeshFromXof(
LPD3DXFILEDATA pxofMesh,        //X文件數據接口
DWORD Options,                   //加載參數
LPDIRECT3DDEVICE9 pD3DDevice, //使用的三維設備
LPD3DXBUFFER * ppAdjacency,      //鄰接信息緩沖接口
LPD3DXBUFFER * ppMaterials,       //材質緩沖接口
LPD3DXBUFFER * ppEffectInstances, //效果實例接口
DWORD * pMatOut,                 //材質數
LPD3DXSKININFO * ppSkinInfo,      //蒙皮信息接口
LPD3DXMESH * ppMesh             //加載的網格模型接口
);


文章來源:http://ly-weiwei.blog.163.com/blog/static/72975283200922394958876

posted on 2009-03-23 21:50 麒麟子 閱讀(247) 評論(0)  編輯 收藏 引用

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            一本色道久久综合亚洲精品按摩 | 99av国产精品欲麻豆| 亚洲日本中文字幕免费在线不卡| 欧美成人蜜桃| 亚洲午夜av电影| 亚洲美女av黄| 欧美日韩www| 久久久不卡网国产精品一区| 免费黄网站欧美| 亚洲图中文字幕| 亚洲婷婷综合色高清在线| 久久国产福利| 亚洲一区三区电影在线观看| 欧美精品亚洲| 欧美一级淫片播放口| 一本大道久久精品懂色aⅴ| 欧美a级片网站| 久久久久久久综合日本| 久久久免费观看视频| 免费观看一区| 国产区在线观看成人精品| 91久久亚洲| 国内精品久久久久伊人av| 91久久在线观看| 国产精品欧美一区喷水| 亚洲性夜色噜噜噜7777| 国产精品乱码久久久久久| 一区二区三区日韩欧美| 看片网站欧美日韩| 欧美一级黄色网| 欧美久久成人| 蘑菇福利视频一区播放| 亚洲精品资源美女情侣酒店| 一区二区电影免费在线观看| 亚洲精品综合久久中文字幕| 欧美成人午夜激情在线| 裸体丰满少妇做受久久99精品| 亚洲日本在线视频观看| 久久精品视频在线看| 一区二区精品在线| 国产精品婷婷| 欧美日韩免费一区二区三区| 亚洲精品视频在线播放| 午夜精品剧场| 亚洲激情第一页| 美女亚洲精品| 欧美不卡视频一区发布| 亚洲高清视频的网址| 亚洲一区二区三区成人在线视频精品| 亚洲精品国产品国语在线app| 国产精品色在线| 国内精品久久久久久久97牛牛| 欧美一区二区三区精品电影| 久久久噜噜噜久久中文字幕色伊伊 | 亚洲第一页中文字幕| 欧美顶级少妇做爰| 免费观看在线综合色| 国产精品区一区| 在线免费观看日本一区| 欧美视频一区| 欧美三级电影精品| 国产精品久久久久久久午夜片| 美女精品国产| 欧美成人在线免费观看| 亚洲网站视频福利| 午夜精品免费在线| 亚洲欧美日韩精品久久| 亚洲香蕉成视频在线观看| 亚洲国产精品嫩草影院| 老司机午夜免费精品视频| 久热精品视频在线| 午夜天堂精品久久久久| 久久精品综合| 翔田千里一区二区| 日韩午夜黄色| 亚洲精品美女久久7777777| 亚洲日韩欧美视频| 西西裸体人体做爰大胆久久久| 久久久噜噜噜久久久| 国产精品日韩欧美一区| 欧美日本高清| 狠狠色狠色综合曰曰| 亚洲电影免费观看高清完整版在线| 国产欧美精品| 在线欧美日韩| 久久成人免费网| 亚洲一区影音先锋| 亚洲国产精品999| 亚洲一区二区三区视频| 久久久精品2019中文字幕神马| 欧美中文在线免费| 日韩亚洲欧美成人| 国产主播一区二区| 麻豆久久婷婷| 亚洲永久免费av| 国产视频一区免费看| 欧美一区高清| 午夜精品影院在线观看| 久久综合色88| 亚洲一区网站| 午夜精品福利电影| 免费在线成人| 国产亚洲精品一区二区| 午夜精品婷婷| 亚洲欧美日韩国产综合精品二区| 美女国内精品自产拍在线播放| 欧美日韩国产综合一区二区| 亚洲娇小video精品| 蜜桃av久久久亚洲精品| 亚洲精品国产精品国自产观看| 免费在线看成人av| 亚洲欧美日韩区| 精品动漫3d一区二区三区| 一本大道久久a久久综合婷婷| 亚洲综合精品一区二区| 国产一区二区三区观看| 欧美一站二站| 浪潮色综合久久天堂| 亚洲午夜精品视频| 亚洲一区国产精品| 亚洲一区二区少妇| 久久免费精品日本久久中文字幕| 在线成人www免费观看视频| 亚洲精品日产精品乱码不卡| 好看的日韩视频| 久久免费偷拍视频| 亚洲一区二区三区在线看| 91久久夜色精品国产九色| 亚洲小说欧美另类婷婷| 久久精品国产2020观看福利| 欧美在线播放一区| 亚洲第一色在线| 欧美日韩视频在线第一区| 欧美一区二区三区四区夜夜大片| 国产精品播放| 欧美一区二区免费视频| 亚洲综合电影| 亚洲综合首页| 一区二区三区在线免费播放| 国产精品久久久久三级| 欧美日本一区| 久久久九九九九| 亚洲少妇在线| 国产精品专区一| 久久久久久电影| 亚洲一区免费在线观看| 欧美精品亚洲精品| 久久人人看视频| 夜夜嗨av一区二区三区| 欧美淫片网站| 国产精品一区在线观看你懂的| 亚洲婷婷综合久久一本伊一区| 久久久久久久久久久久久9999| 亚洲精品影视| 欧美日本一区二区三区| 91久久国产自产拍夜夜嗨| 久久丁香综合五月国产三级网站| 精品av久久久久电影| 欧美日韩免费观看中文| 欧美一区二区视频在线观看| 牛牛影视久久网| 欧美一区二区国产| 国产乱码精品一区二区三区忘忧草| 亚洲国产裸拍裸体视频在线观看乱了中文 | 亚洲欧美日韩国产| 亚洲精华国产欧美| 国产专区欧美专区| 国产婷婷色一区二区三区在线| 欧美国产日韩视频| 欧美韩日亚洲| 亚洲欧美一区二区精品久久久| 日韩视频一区二区在线观看 | 国产精品视频观看| 欧美成人精品1314www| 欧美日韩亚洲高清| 在线免费一区三区| 免费不卡亚洲欧美| 亚洲国产精品第一区二区| 老司机免费视频一区二区| 欧美国产日本韩| 亚洲区第一页| 亚洲精品国产欧美| 久久狠狠婷婷| 久久天天躁狠狠躁夜夜爽蜜月| 欧美怡红院视频| 亚洲欧美综合一区| 久久蜜桃精品| 欧美国产激情| 91久久精品久久国产性色也91 | 伊人久久大香线蕉综合热线| 男男成人高潮片免费网站| 欧美一激情一区二区三区| 久久夜色撩人精品| 国产精品国产三级国产普通话三级| 国产精品日韩一区二区三区| 国产一区深夜福利| 亚洲日产国产精品| 久久精品在线免费观看| 一区二区不卡在线视频 午夜欧美不卡在 | 欧美韩国日本综合|