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

            天行健 君子當自強而不息

            網(wǎng)格模型高級技術(13)

            類cAnimMesh是最關鍵的一個類,所有與骨骼動畫相關的具體實現(xiàn)細節(jié)都封裝在該類中,該類還定義了類cAllocateHierarchy的一個對象m_alloc_hierarchy,該對象完成從文件中加載動畫網(wǎng)格模型的骨骼層次結構、動畫數(shù)據(jù)以及其他用于繪制模型的幾何數(shù)據(jù)。


            類cAnimMesh的定義如下所示:

            class cAnimMesh
            {
            private:
            cAllocateHierarchy* m_alloc_hierarchy;
            IDirect3DDevice9* m_device;
            D3DXFRAME* m_root_frame;
            public:
            D3DXVECTOR3 m_object_center;
            float m_object_radius;
            bool m_is_play_anim;
            ID3DXAnimationController* m_anim_controller;
            private:
            HRESULT load_from_xfile(CONST WCHAR* wfilename);
            void update_frame_matrices(D3DXFRAME* base_frame, CONST D3DXMATRIX* parent_matrix);
            void draw_frame(CONST D3DXFRAME* frame);
            void draw_mesh_container(CONST D3DXMESHCONTAINER* base_mesh_container, CONST D3DXFRAME* base_frame);
            public:
            HRESULT create(IDirect3DDevice9* device, CONST WCHAR* wfilename);
            void render(CONST D3DXMATRIX* mat_world, double app_elapsed_time);
            void destroy();
            public:
            cAnimMesh();
            virtual ~cAnimMesh();
            };

             

            構造函數(shù)負責分配資源和初始化成員變量,析構函數(shù)負責釋放資源:

            cAnimMesh::cAnimMesh()
            {
            m_is_play_anim = true;
            m_device = NULL;
            m_anim_controller = NULL;
            m_root_frame = NULL;
            	m_alloc_hierarchy = new cAllocateHierarchy();
            }
            cAnimMesh::~cAnimMesh()
            {
            D3DXFrameDestroy(m_root_frame, m_alloc_hierarchy);
            release_com(m_anim_controller);
            	delete m_alloc_hierarchy;
            }

             

            函數(shù)load_from_xfile()的主要任務是調(diào)用函數(shù)D3DXLoadMeshHierarchyFromX()從.x文件中加載動畫模型,其實現(xiàn)如下:

            HRESULT cAnimMesh::load_from_xfile(CONST WCHAR* wfilename)
            {
            HRESULT hr;
            	WCHAR wpath[MAX_PATH];
            DXUTFindDXSDKMediaFileCch(wpath, sizeof(wpath) / sizeof(WCHAR), wfilename);
            	V_RETURN(D3DXLoadMeshHierarchyFromXW(wpath, D3DXMESH_MANAGED, m_device, m_alloc_hierarchy, NULL, 
            &m_root_frame, &m_anim_controller));
            	V_RETURN(D3DXFrameCalculateBoundingSphere(m_root_frame, &m_object_center, &m_object_radius));
            	return S_OK;
            }

            雖然該函數(shù)的實現(xiàn)代碼非常簡單,但其內(nèi)部過程卻是很復雜的,關鍵是要弄清除D3DXLoadMeshHierarchyFromX()函數(shù)中m_alloc_hierarchy參數(shù)的作用。D3DXLoadMeshHierarchyFromX()函數(shù)在內(nèi)部隱式地通過m_alloc_hierarchy調(diào)用加載網(wǎng)格模型具體數(shù)據(jù)的函數(shù)(即上面提到的cAllocateHeirarchy中的CreateFrame()和CreateMeshContainer()函數(shù)),這些函數(shù)是由用戶編寫的,但卻是由Direct3D在內(nèi)部于適當機制調(diào)用。

            來看看D3DXLoadMeshHierarchyFromX()的具體使用說明:

            Loads the first frame hierarchy from a .x file.

            HRESULT D3DXLoadMeshHierarchyFromX(
            LPCSTR Filename,
            DWORD MeshOptions,
            LPDIRECT3DDEVICE9 pDevice,
            LPD3DXALLOCATEHIERARCHY pAlloc,
            LPD3DXLOADUSERDATA pUserDataLoader,
            LPD3DXFRAME* ppFrameHierarchy,
            LPD3DXANIMATIONCONTROLLER* ppAnimController
            );

            Parameters

            Filename
            [in] Pointer to a string that specifies the filename. If the compiler settings require Unicode, the data type LPCTSTR resolves to LPCWSTR. Otherwise, the string data type resolves to LPCSTR. See Remarks.
            MeshOptions
            [in] Combination of one or more flags from the D3DXMESH enumeration that specify creation options for the mesh.
            pDevice
            [in] Pointer to an IDirect3DDevice9 interface, the device object associated with the mesh.
            pAlloc
            [in] Pointer to an ID3DXAllocateHierarchy interface.
            pUserDataLoader
            [in] Application provided interface that allows loading of user data.
            ppFrameHierarchy
            [out, retval] Returns a pointer to the loaded frame hierarchy.
            ppAnimController
            [out, retval] Returns a pointer to the animation controller corresponding to animation in the .x file. This is created with default tracks and events.

            Return Values

            If the function succeeds, the return value is D3D_OK. If the function fails, the return value can be one of the following values: D3DERR_INVALIDCALL, E_OUTOFMEMORY.

            Remarks

            The compiler setting also determines the function version. If Unicode is defined, the function call resolves to D3DXLoadMeshHierarchyFromXW. Otherwise, the function call resolves to D3DXLoadMeshHierarchyFromXA.

            All the meshes in the file will be collapsed into one output mesh. If the file contains a frame hierarchy, all the transformations will be applied to the mesh.

            D3DXLoadMeshHierarchyFromX loads the animation data and frame hierarchy from a .x file. It scans the .x file and builds a frame hierarchy and animation controller according to the ID3DXAllocateHierarchy-derived object passed to it through pAlloc. Loading the data requires several steps as follows:

            1. Derive ID3DXAllocateHierarchy, implementing each method. This controls how frames and meshes are allocated and freed.
            2. Derive ID3DXLoadUserData, implementing each method. If your .x file has no embedded user-defined data, or if you do not need it, you can skip this part.
            3. Create an object of your ID3DXAllocateHierarchy class, and optionally of your LoadUserData class. You do not need to call any methods of these objects yourself.
            4. Call D3DXLoadMeshHierarchyFromX, passing in your ID3DXAllocateHierarchy object and your ID3DXLoadUserData object (or NULL) to create the frame hierarchy and animation controller. All the animation sets and frames are automatically registered to the animation controller.

            During the load, ID3DXAllocateHierarchy::CreateFrame and ID3DXLoadUserData::LoadFrameChildData are called back on each frame to control loading and allocation of the frame. The application defines these methods to control how frames are stored. ID3DXAllocateHierarchy::CreateMeshContainer and ID3DXLoadUserData::LoadMeshChildData are called back on each mesh object to control loading and allocation of mesh objects. ID3DXLoadUserData::LoadTopLevelData is called back for each top level object that doesn't get loaded by the other methods.

            To free this data, call ID3DXAnimationController::Release to free the animation sets, and D3DXFRAMEDestroy, passing in the root node of the frame hierarchy and an object of your derived ID3DXAllocateHierarchy class. ID3DXAllocateHierarchy::DestroyFrame and ID3DXAllocateHierarchy::DestroyMeshContainer will each be called for every frame and mesh object in the frame hierarchy. Your implementation of ID3DXAllocateHierarchy::DestroyFrame should release everything allocated by ID3DXAllocateHierarchy::CreateFrame, and likewise for the mesh container methods.

             

            因為在每次渲染網(wǎng)格模型前,只有知道每個框架的確切位置,才能在正確的位置上繪制出該框架包含的具體網(wǎng)格模型,所以需要計算得到各級框架的組合變換矩陣,函數(shù)update_frame_matrices()采用遞歸的方法計算各級框架的組合變換矩陣,具體實現(xiàn)代碼如下:

            void cAnimMesh::update_frame_matrices(D3DXFRAME* base_frame, CONST D3DXMATRIX* parent_matrix)
            {
            D3DXFRAME_DERIVED* frame = (D3DXFRAME_DERIVED*) base_frame;
            	if(parent_matrix != NULL)
            D3DXMatrixMultiply(&frame->CombinedTransformMatrix, &frame->TransformationMatrix, parent_matrix);
            else
            frame->CombinedTransformMatrix = frame->TransformationMatrix;
            	if(frame->pFrameSibling != NULL)
            update_frame_matrices(frame->pFrameSibling, parent_matrix);
            	if(frame->pFrameFirstChild != NULL)
            update_frame_matrices(frame->pFrameFirstChild, &frame->CombinedTransformMatrix);
            }

             

            因為骨骼動畫網(wǎng)格模型是通過框架按照樹狀結構組織起來的,而網(wǎng)格模型又包含在框架之中,所以在為了渲染網(wǎng)格模型的同時能將其中的動畫播放出來,就需要逐個框架逐個網(wǎng)格模型地進行渲染,其中draw_mesh_container()負責渲染框架中包含的具體網(wǎng)格模型:

            void cAnimMesh::draw_mesh_container(CONST D3DXMESHCONTAINER* base_mesh_container, CONST D3DXFRAME* base_frame)
            {
            D3DXMESHCONTAINER_DERIVED* mesh_container = (D3DXMESHCONTAINER_DERIVED*) base_mesh_container;
            D3DXFRAME_DERIVED* frame = (D3DXFRAME_DERIVED*) base_frame;
            	m_device->SetTransform(D3DTS_WORLD, &frame->CombinedTransformMatrix);
            	for(UINT i = 0; i < mesh_container->NumMaterials; i++)
            {
            m_device->SetMaterial(&mesh_container->pMaterials[i].MatD3D);
            m_device->SetTexture(0, mesh_container->ppTextures[i]);
            		mesh_container->MeshData.pMesh->DrawSubset(i);
            }
            }

            該函數(shù)的實現(xiàn)比較簡單,在渲染每個網(wǎng)格之前,首先調(diào)用函數(shù)SetTransform(),根據(jù)該網(wǎng)格在框架的組合變換矩陣,將網(wǎng)格中所包含的網(wǎng)格模型移動到正確的位置后,再設置材質(zhì)、紋理,最后進行繪制。

             

            函數(shù)draw_frame()以draw_mesh_container()為基礎,采用遞歸的方法,將整個網(wǎng)格模型繪制出來:

            void cAnimMesh::draw_frame(CONST D3DXFRAME* frame)
            {
            D3DXMESHCONTAINER* mesh_container = frame->pMeshContainer;
            	while(mesh_container != NULL)
            {
            draw_mesh_container(mesh_container, frame);
            mesh_container = mesh_container->pNextMeshContainer;
            }
            	if(frame->pFrameSibling != NULL)
            draw_frame(frame->pFrameSibling);
            	if(frame->pFrameFirstChild != NULL)
            draw_frame(frame->pFrameFirstChild);
            }

            在調(diào)用該函數(shù)時,只需將參數(shù)frame設置為網(wǎng)格模型的根節(jié)點就可以繪制出整個網(wǎng)格模型。

             

            函數(shù)render()通過draw_frame()完成整個網(wǎng)格模型的渲染,其實現(xiàn)如下:

            void cAnimMesh::render(CONST D3DXMATRIX* mat_world, double app_elapsed_time)
            {
            if(0.0f == app_elapsed_time)
            return;
            	if(m_is_play_anim && m_anim_controller != NULL)
            m_anim_controller->AdvanceTime(app_elapsed_time, NULL);
            	update_frame_matrices(m_root_frame, mat_world);
            draw_frame(m_root_frame);
            }

            在渲染網(wǎng)格模型之前,首先使用動畫控制器m_anim_controller調(diào)用函數(shù)AdvanceTime()將網(wǎng)格模型動畫向前推進,然后調(diào)用函數(shù)update_frame_matrices(),根據(jù)當前網(wǎng)格模型的世界矩陣mat_world更新整個網(wǎng)格模型的層次,即計算每個框架的組合變換矩陣,最后調(diào)用draw_frame()函數(shù)渲染出整個網(wǎng)格模型。

             

            create()函數(shù)用于根據(jù)參數(shù)指定的網(wǎng)格模型文件名創(chuàng)建骨骼動畫網(wǎng)格模型:

            HRESULT cAnimMesh::create(IDirect3DDevice9* device, CONST WCHAR* wfilename)
            {
            m_device = device;
            	HRESULT hr;
            V_RETURN(load_from_xfile(wfilename));
            	return S_OK;
            }

            函數(shù)destroy()只負責銷毀對象:

            void cAnimMesh::destroy()
            {
            delete this;
            }

            posted on 2008-06-11 15:46 lovedday 閱讀(3297) 評論(1)  編輯 收藏 引用

            評論

            # re: 網(wǎng)格模型高級技術(13) 2012-03-13 14:24 小班

            D3DXLoadMeshFromX()函數(shù)中返回一個LPD3DXMESM的網(wǎng)格對象,而你的個方法D3DXLoadMeshHierarchyFromX()是怎么返回的?急用  回復  更多評論   

            公告

            導航

            統(tǒng)計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            久久亚洲春色中文字幕久久久| 26uuu久久五月天| 综合久久给合久久狠狠狠97色 | 久久www免费人成精品香蕉| 久久国产一区二区| 无码任你躁久久久久久老妇| 色狠狠久久综合网| 久久精品国产亚洲欧美| 久久天天躁狠狠躁夜夜avapp| 99久久精品国产一区二区| 久久精品国产亚洲av影院| 精品久久久久久无码人妻蜜桃| 亚洲Av无码国产情品久久| avtt天堂网久久精品| 亚洲欧美一级久久精品| 精品久久久久久久久中文字幕| 色偷偷88欧美精品久久久| 久久久久久免费一区二区三区| 久久e热在这里只有国产中文精品99| 91麻豆国产精品91久久久| 青青青青久久精品国产h| 一本久道久久综合狠狠爱| 久久精品无码一区二区三区日韩| 亚洲中文字幕无码一久久区| 久久有码中文字幕| 久久成人18免费网站| 久久综合丝袜日本网| 久久久久人妻一区精品色| 欧美亚洲另类久久综合婷婷| 狠狠色丁香婷婷久久综合不卡| 久久精品国产久精国产一老狼| 狠狠色伊人久久精品综合网| 国产国产成人精品久久| 99久久777色| 精品久久久久久无码中文字幕一区 | 久久精品无码午夜福利理论片| 奇米影视7777久久精品人人爽| 午夜福利91久久福利| 亚洲国产成人精品女人久久久 | 亚洲精品无码久久毛片| 久久影视综合亚洲|