• <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)而不息

            Working with skeletal animation(5)

            Loading Skinned Meshes from .X

            Loading a skinned mesh from an .X file is much like loading a standard mesh. Using a custom .X parser, you must enumerate your .X file objects using ParseObject. When it comes to processing a Mesh object, instead of calling the D3DXLoadMeshFromXof function to load the mesh data, you call the D3DXLoadSkinMeshFromXof function, which takes one additional parameter−a pointer to an ID3DXSkinInfo object. Check out the D3DXLoadSkinMeshFromXof prototype to see what I mean.

            Loads a skin mesh from a DirectX .x file data object.

            HRESULT D3DXLoadSkinMeshFromXof(
            LPD3DXFILEDATA pxofMesh,
            DWORD Options,
            LPDIRECT3DDEVICE9 pD3DDevice,
            LPD3DXBUFFER * ppAdjacency,
            LPD3DXBUFFER * ppMaterials,
            LPD3DXBUFFER * ppEffectInstances,
            DWORD * pMatOut,
            LPD3DXSKININFO * ppSkinInfo,
            LPD3DXMESH * ppMesh
            );

            Parameters

            pxofMesh
            [in] Pointer to an ID3DXFileData interface, representing the file data object to load.
            Options
            [in] Combination of one or more flags, from the D3DXMESH enumeration, specifying creation options for the mesh.
            pD3DDevice
            [in] Pointer to an IDirect3DDevice9 interface, the device object associated with the mesh.
            ppAdjacency
            [out] Address of a pointer to an ID3DXBuffer interface. When this method returns, this parameter is filled with an array of three DWORDs per face that specify the three neighbors for each face in the mesh.
            ppMaterials
            [out] Address of a pointer to an ID3DXBuffer interface. When the method returns, this parameter is filled with an array of D3DXMATERIAL structures.
            ppEffectInstances
            [out] Pointer to a buffer containing an array of effect instances, one per attribute group in the returned mesh. An effect instance is a particular instance of state information used to initialize an effect. See D3DXEFFECTINSTANCE. For more information about accessing the buffer, see ID3DXBuffer.
            pMatOut
            [out] Pointer to the number of D3DXMATERIAL structures in the ppMaterials array, when the method returns.
            ppSkinInfo
            [out] Address of a pointer to an ID3DXSkinInfo interface, which represents the skinning information.
            ppMesh
            [out] Address of a pointer to an ID3DXMesh interface, which represents the loaded mesh.

            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: D3DERR_INVALIDCALL.

            D3DXERR_INVALIDDATA E_OUTOFMEMORY

            Remarks

            This method takes a pointer to an internal object in the .x file, enabling you to load the frame hierarchy.

            For mesh files that do not contain effect instance information, default effect instances will be generated from the material information in the .x file. A default effect instance will have default values that correspond to the members of the D3DMATERIAL9 structure.

            The default texture name is also filled in, but is handled differently. The name will be Texture0@Name, which corresponds to an effect variable by the name of "Texture0" with an annotation called "Name." This will contain the string file name for the texture.

            When you are ready to load a mesh from an enumerated Mesh template, call the D3DXLoadSkinMeshFromXof function instead of calling D3DXLoadMeshFromXof. Make sure to supply an ID3DXSkinInfo object where it is shown in the prototype. Whether or not the Mesh template contains a skinned mesh doesn't matter−the D3DXLoadSkinMeshFromXof function will load regular and skinned meshes without a hitch. Here's an example:

            // Define the mesh and skinned mesh info objects
            ID3DXMesh *pMesh;
            ID3DXSkinInfo *pSkinInfo;

            // Define buffers to hold the material data and adjacency data
            ID3DXBuffer *pMaterialBuffer = NULL, *pAdjacencyBuffer = NULL;

            // DWORD to hold the number of materials being loaded
            DWORD NumMaterials;

            // Load the skinned mesh from IDirectXFileDataObject pDataObj
            D3DXLoadSkinMeshFromXof(pDataObj, D3DXMESH_SYSTEMMEM, pDevice, &pAdjacencyBuffer,
            &pMaterialBuffer, NULL, &NumMaterials, &pSkinInfo, &pMesh);

            Just because you used the D3DXLoadSkinnedMeshFromXof function, that doesn't mean a skinned mesh was loaded. First you need to check the pSkinInfo object. If it's set to NULL, then a skinned mesh wasn't loaded. If it's a valid object (non−NULL), then you need to check whether any bones exist.

            The easiest way to see whether bones exist is to call ID3DXSkinInfo::GetNumBones. The GetNumBones function will return the number of bones loaded from the Mesh template. If the number is 0, then there are no bones, and you can free the ID3DXSkinInfo object (using Release). If bones do exist, then you can continue using the skinned mesh.

            Check out this example, which tests whether a skinned mesh was loaded. If so, the example checks to see whether the mesh contains any bones.

            // Set a flag is there's a skinned mesh and bones to use
            BOOL SkinnedMesh = FALSE;
            if(pSkinInfo && pSkinInfo−>GetNumBones())
            SkinnedMesh = TRUE;
            else
            {
            // Free the skinned mesh info data object
            if(pSkinInfo)
            {
            pSkinInfo−>Release();
            pSkinInfo = NULL;
            }
            }

            If the SkinnedMesh flag is set to TRUE, then the pSkinInfo object is valid and you're ready to work with the skinned mesh. The next step is to create another mesh object that will contain the actual deforming mesh as you change the bones' orientations.

             

            Creating a Secondary Mesh Container

            After you create the skinned mesh, you need to create a second mesh container. Why, you ask? Well, the skinned mesh object you loaded from the D3DXLoadSkinMeshFromXof function is sort of the base of reference for your mesh's vertex data. Since these vertices are in the right positions to match the orientations of the bones, it would mess up things quite a bit if you started altering those positions.

            Let's leave things well enough alone and instead create a second mesh object (an ID3DXMesh object) that contains an exact duplicate of the skinned mesh. You need to read the vertex data from the skinned mesh data, apply the various bone transformations, and write the resulting vertex data to this duplicate mesh container (which I call the secondary mesh or secondary mesh container) that you use to render. Makes sense, doesn't it?

            As I mentioned, the secondary mesh is an identical match to the skinned mesh; everything from the number of vertices to the indices needed is the same. The easiest way to duplicate the skinned mesh object is to use the ID3DXMesh::CloseMeshFVF function.

            Clones a mesh using a flexible vertex format (FVF) code.

            HRESULT CloneMeshFVF(
            DWORD Options,
            DWORD FVF,
            LPDIRECT3DDEVICE9 pDevice,
            LPD3DXMESH * ppCloneMesh
            );

            Parameters

            Options
            [in] A combination of one or more D3DXMESH flags specifying creation options for the mesh.
            FVF
            [in] Combination of FVF codes, which specifies the vertex format for the vertices in the output mesh. For the values of the codes, see D3DFVF.
            pDevice
            [in] Pointer to an IDirect3DDevice9 interface representing the device object associated with the mesh.
            ppCloneMesh
            [out, retval] Address of a pointer to an ID3DXMesh interface, representing the cloned mesh.

            Return Values

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

            Remarks

            ID3DXBaseMesh::CloneMeshFVF is used to reformat and change the vertex data layout. This is done by creating a new mesh object. For example, use it to to add space for normals, texture coordinates, colors, weights, etc. that were not present before.

            ID3DXBaseMesh::UpdateSemantics updates the vertex declaration with different semantic information without changing the layout of the vertex buffer. This method does not modify the contents of the vertex buffer. For example, use it to relabel a 3D texture coordinate as a binormal or tangent or vice versa.

            The Options parameter of CloneMeshFVF is just like the one from the calls to D3DXLoadMeshFromX, D3DXLoadMeshFromXof, and D3DXLoadSkinMeshFromXof, so take your pick. I tend to set Options flags to 0, but feel free to change it.

            As for the FVF parameter, you only need to supply the FVF from the skinned mesh object using the skinned mesh's GetFVF function. Also, don't forget to supply the valid IDirect3DDevice9 object you are using, as well as a pointer to an ID3DXMesh object that will be your secondary mesh container.

            Here's a bit of code that demonstrates cloning a skinned mesh to create your secondary mesh:

            // pSkinMesh = ID3DXMesh object
            ID3DXMesh *pMesh; // Secondary mesh container
            pSkinMesh−>CloneMeshFVF(0, pMesh−>GetFVF(), pDevice, &pMesh);

            All this talk of cloning reminds me of Star Wars Episode II: Attack of the Clones. Good thing your cloned secondary meshes aren't going to try to take over the universeor are they? Well heck, those clones aren't going anywhere without a little effort, so let's get back to work and see what's next in line.

            After you've created the secondary mesh container, it's time to map your bones to the frame hierarchy. Why didn't we do this previously, when I was discussing bones and frames? Easy−the bone data was loaded until you called D3DXLoadSkinMeshFromXof!


            posted on 2008-04-23 19:17 lovedday 閱讀(636) 評(píng)論(0)  編輯 收藏 引用


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


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

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

            搜索

            最新評(píng)論

            久久亚洲AV无码西西人体| 久久精品一区二区三区AV| 精品久久久久久久久中文字幕| 国产精品久久久久AV福利动漫 | 女人香蕉久久**毛片精品| 久久久久99精品成人片三人毛片| 久久婷婷色香五月综合激情| 亚洲∧v久久久无码精品| 99久久婷婷国产综合亚洲| 欧美精品丝袜久久久中文字幕 | 精品无码久久久久久久动漫| 日本WV一本一道久久香蕉| 久久久久中文字幕| 一个色综合久久| 久久国产精品成人影院| 亚洲另类欧美综合久久图片区| 色综合久久最新中文字幕| 久久久久波多野结衣高潮| 国产精品日韩深夜福利久久| 久久久精品国产sm调教网站 | 久久99热狠狠色精品一区| 国产成人无码精品久久久性色| 91亚洲国产成人久久精品| 国内精品久久久久影院优| 亚洲第一极品精品无码久久| 久久夜色精品国产噜噜亚洲a| 久久se精品一区二区影院| 人人狠狠综合久久亚洲婷婷| 久久久国产乱子伦精品作者| 日本WV一本一道久久香蕉| 亚洲精品WWW久久久久久| 日日狠狠久久偷偷色综合0| A级毛片无码久久精品免费| 青青草原综合久久| 一本大道加勒比久久综合| 久久线看观看精品香蕉国产| 久久综合狠狠色综合伊人| 亚洲国产精品久久久久| 久久精品国产福利国产琪琪| 久久99精品九九九久久婷婷| 久久亚洲AV永久无码精品|