模拟实现ID3DXSkinInfo::UpdateSkinnedMesh
来源:互联网 发布:mac安装ug教程 编辑:程序博客网 时间:2024/04/30 03:59
模拟实现ID3DXSkinInfo::UpdateSkinnedMesh
作者:cywater2000
日期:
一.公式:
FinalPos = MeshPos + ∑( Difference_i * Weight_i)
= MeshPos + ∑( (NewMeshPos_i - MeshPos) * Weight_i )
= MeshPos + ∑( (MeshPos × OffsetMatix_i × CombinedMatrix_i - MeshPos) * Weight_i ) [1]
其中:
MeshPos: 某顶点在mesh中的原始位置
NewMeshPos_i: 此顶点受某骨骼i影响后变换到的新位置
Difference_i: 两者之间的位移差值
Weight_i:: 此顶点受某骨骼i的影响权重
OffsetMatix_i: 骨骼i的偏移矩阵
CombinedMatrix_i: 骨骼i经过层次更新后的混合矩阵
∑: 求和(对所有影响该顶点的骨骼)
FinalPos: 此顶点的最终位置
法线计算同理。
二.模拟代码(没有优化):
HRESULT UpdateSkinnedMesh(ID3DXSkinInfo *pSkinInfo,
const D3DXMATRIX *pBoneTransforms,
const D3DXMATRIX *pBoneInvTransposeTransforms, //not use(原函数也没用)
LPCVOID pVerticesSrc,
PVOID pVerticesDst,
//注意下面增加的两个变量是原函数在调用时没有的,因为ID3DXSkinInfo的内部机制可以获得
DWORD numTotalVerts, //add 1,指mesh的顶点个数
DWORD dwStride //add 2,指mesh每个顶点的间距,即每个顶点结构的大小
)
{
DWORD *pVertsIndic = NULL;
float *pVertsWeigh = NULL;
DWORD dwNumVerts;
DWORD offsetByte;
BYTE *pDest = (BYTE*)pVerticesDst; //目标顶点缓冲
const BYTE *pSrc = (BYTE*)pVerticesSrc; //源顶点缓冲
memcpy(pDest, pSrc, numTotalVerts * dwStride);
for(DWORD i = 0; i < pSkinInfo->GetNumBones(); i++)
{
dwNumVerts = pSkinInfo->GetNumBoneInfluences(i); //得到受影响的顶点个数
if(dwNumVerts <= 0)
continue;
pVertsIndic = new DWORD[dwNumVerts];
pVertsWeigh = new float[dwNumVerts];
pSkinInfo->GetBoneInfluence(i, pVertsIndic, pVertsWeigh);
while(dwNumVerts--)
{
DWORD index = pVertsIndic[dwNumVerts]; //当前受影响的顶点索引
float weight = pVertsWeigh[dwNumVerts]; //当前受影响顶点的权重
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;
}
注意在调用UpdateSkinnedMesh前,pBoneTransforms已经是OffsetMatix与CombinedMatrix的连接矩阵了(ID3DXSkinInfo::UpdateSkinnedMesh也是这么要求的)。
重要更新:
- 模拟实现ID3DXSkinInfo::UpdateSkinnedMesh
- 模拟实现ID3DXSkinInfo::UpdateSkinnedMesh
- 模拟实现ID3DXSkinInfo::UpdateSkinnedMesh
- 模拟实现strcpy、模拟实现strlen、模拟实现strstr函数
- 模拟实现strncpy ,模拟实现strncat ,模拟实现strncmp
- 模拟实现strcpy 模拟实现strncpy 模拟实现strcat 模拟实现strncat 模拟实现strcmp 模拟实现strncmp 模拟实现memcpy 模拟实现memmove
- C++模拟委托实现
- 模拟实现扫雷游戏
- 模拟window桌面实现
- 模拟window桌面实现
- 模拟接口实现
- SNOOPY 实现模拟登陆
- 实现模拟鼠标点击
- malloc的实现模拟
- C#模拟实现Union
- 模拟按键实现
- VC++ 实现星图模拟
- HibernateTemplate的模拟实现
- 2005 packetstorm exploit
- Microsoft Windows Shimgvw.dll WMF (Exploit)
- Vulnerability in Graphics Rendering Engine Allows Remote Code Execution
- WIN_SHELLCODE
- 窗口句柄的获得
- 模拟实现ID3DXSkinInfo::UpdateSkinnedMesh
- Sun JDK 不兼容 IBM JDK 备忘录
- (转载)P2P之UDP穿透NAT的原理与实现 - 增强篇(附修改过的源代码)
- 在 .NET Compact Framework 2.0 中使用 COM Interop
- 2006年的几个愿望
- JSP页面中的自定义标签
- javascript验证给定的日期的合法性——升级版
- 下面的源码需要解释
- 让手写输入在 Web 上持久留存