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

            【ZT】模擬實(shí)現(xiàn)ID3DXSkinInfo::UpdateSkinnedMesh

            原文出處:http://blog.csdn.net/cywater2000/archive/2006/01/05/571299.aspx

            一.公式:

            FinalPos = MeshPos + ∑( Difference_i * Weight_i)

            = MeshPos + ∑( (NewMeshPos_i - MeshPos) * Weight_i )

            = MeshPos + ∑( (MeshPos × OffsetMatix_i × CombinedMatrix_i - MeshPos) * Weight_i ) [1]


            其中:

            MeshPos:                  某頂點(diǎn)在mesh中的原始位置

            NewMeshPos_i:         此頂點(diǎn)受某骨骼i影響后變換到的新位置

            Difference_i:              兩者之間的位移差值

            Weight_i::                  此頂點(diǎn)受某骨骼i的影響權(quán)重

            OffsetMatix_i:            骨骼i的偏移矩陣

            CombinedMatrix_i:       骨骼i經(jīng)過層次更新后的混合矩陣

            ∑:                              求和(對所有影響該頂點(diǎn)的骨骼)

            FinalPos:                    此頂點(diǎn)的最終位置

             

            法線計(jì)算同理。

             

            二.模擬代碼(沒有優(yōu)化):


            HRESULT UpdateSkinnedMesh(ID3DXSkinInfo *pSkinInfo,
                              
            const D3DXMATRIX *pBoneTransforms,
                              
            const D3DXMATRIX *pBoneInvTransposeTransforms, //not use(原函數(shù)也沒用)
                              LPCVOID pVerticesSrc,
                              PVOID pVerticesDst,
            //注意下面增加的兩個變量是原函數(shù)在調(diào)用時沒有的,因?yàn)镮D3DXSkinInfo的內(nèi)部機(jī)制可以獲得
                              DWORD numTotalVerts, 
            // 指mesh的頂點(diǎn)個數(shù)
                              DWORD dwStride 
            // 指mesh每個頂點(diǎn)的間距,即每個頂點(diǎn)結(jié)構(gòu)的大小
                              )
            {
                DWORD 
            *pVertsIndic = NULL;
                
            float *pVertsWeigh = NULL;
                DWORD dwNumVerts;
                DWORD offsetByte;

                BYTE 
            *pDest = (BYTE*)pVerticesDst; //目標(biāo)頂點(diǎn)緩沖
                
            const BYTE *pSrc = (BYTE*)pVerticesSrc; //源頂點(diǎn)緩沖

                memcpy(pDest, pSrc, numTotalVerts 
            * dwStride);

                
            for(DWORD i = 0; i < pSkinInfo->GetNumBones(); i++)
                {
                   dwNumVerts 
            = pSkinInfo->GetNumBoneInfluences(i); //得到受影響的頂點(diǎn)個數(shù)

                   
            if(dwNumVerts <= 0)
                       
            continue;

                   pVertsIndic 
            = new DWORD[dwNumVerts];
                   pVertsWeigh 
            = new float[dwNumVerts];

                   pSkinInfo
            ->GetBoneInfluence(i, pVertsIndic, pVertsWeigh);

                   
            while(dwNumVerts--)
                   {
                       DWORD index 
            = pVertsIndic[dwNumVerts]; //當(dāng)前受影響的頂點(diǎn)索引
                       
            float weight = pVertsWeigh[dwNumVerts]; //當(dāng)前受影響頂點(diǎn)的權(quán)重

                       offsetByte 
            = index * dwStride;

                       D3DXVECTOR3 vecPos 
            = *(D3DXVECTOR3 *)(pSrc + offsetByte); //位置
                       D3DXVECTOR3 vecNor 
            = *(D3DXVECTOR3 *)(pSrc + offsetByte + sizeof(D3DXVECTOR3)); //法線

                       D3DXVECTOR3 vecPos2, vecNor2;
                       D3DXVec3TransformCoord(
            &vecPos2, &vecPos, &pBoneTransforms[i]);
                       D3DXVec3TransformNormal(
            &vecNor2, &vecNor, &pBoneTransforms[i]);

                       D3DXVECTOR3 
            *pV = (D3DXVECTOR3 *)(pDest + offsetByte);
                       D3DXVECTOR3 
            *pN = (D3DXVECTOR3 *)(pDest + offsetByte + sizeof(D3DXVECTOR3));

                       D3DXVECTOR3 diff 
            = (vecPos2 - vecPos) * weight;
                       
            *pV += diff;

                       diff 
            = (vecNor2 - vecNor) * weight;
                       
            *pN += diff;
                   }

                   delete[] pVertsIndic;
                   delete[] pVertsWeigh;
                }
             
                
            return S_OK;

            }

                注意在調(diào)用UpdateSkinnedMesh前,pBoneTransforms已經(jīng)是OffsetMatix與CombinedMatrix的連接矩陣了(ID3DXSkinInfo::UpdateSkinnedMesh也是這么要求的)。

             

            重要更新:

            骨骼動畫屬于Geometry Blending,因此標(biāo)準(zhǔn)做法應(yīng)該是:
             [2]
            即FinalPos =∑(NewMeshPos_i  * Weight_i) + NewMeshPos_n * (1 - ∑Weight_i ) , i=0,1..n-1
            =∑(MeshPos × OffsetMatix_i × CombinedMatrix_i * Weight_i) + (MeshPos × OffsetMatix_n × CombinedMatrix_n) * (1 - ∑Weight_i ) , i=0,1..n-1 [3]
            (顯然只有當(dāng)影響頂點(diǎn)的所有權(quán)重之和等于1時,公式[1]與[3]才等價(jià))


            posted on 2008-04-22 15:22 lovedday 閱讀(1082) 評論(0)  編輯 收藏 引用 所屬分類: ■ DirectX 9 Program

            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

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

            搜索

            最新評論

            精产国品久久一二三产区区别 | 人妻精品久久久久中文字幕一冢本| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区| 久久这里只有精品久久| 久久久久亚洲AV成人网人人软件| 久久久久久久久久免免费精品 | yellow中文字幕久久网| 亚洲国产成人久久一区久久| 国内精品久久久久影院日本| 一本一道久久精品综合| 2019久久久高清456| 精品久久人人妻人人做精品| 中文字幕热久久久久久久| 久久精品国产一区| 亚洲精品午夜国产VA久久成人| 久久精品国产一区二区三区不卡| 国产精品乱码久久久久久软件| 精品久久久久久亚洲| 亚洲国产日韩综合久久精品| 国产精品久久久天天影视香蕉| 国产成人精品三上悠亚久久 | 99久久精品国产一区二区| 欧美精品九九99久久在观看| 久久久久国产精品熟女影院| 久久99精品国产麻豆宅宅| 久久se精品一区二区影院| 国内精品九九久久久精品| 国产成人无码精品久久久久免费| 无码精品久久久久久人妻中字| 99久久精品毛片免费播放| 91久久精品国产成人久久| 久久综合亚洲欧美成人| 一本色道久久HEZYO无码| 99蜜桃臀久久久欧美精品网站| 久久久久亚洲?V成人无码| 97久久久久人妻精品专区| 久久国产精品波多野结衣AV| 综合久久国产九一剧情麻豆| 人妻无码精品久久亚瑟影视| 亚洲欧美另类日本久久国产真实乱对白| 久久99国产精品一区二区|