c – COLLADA:错误的空间中反绑定姿势?

前端之家收集整理的这篇文章主要介绍了c – COLLADA:错误的空间中反绑定姿势?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在编写我自己的COLLADA进口商.我已经很远了,装载网格和材料等.但是我已经打动动画了,特别是联合旋转.

我用来剥皮我的网格的公式是直接的:

weighted;
for (i = 0; i < joint_influences; i++)
{
    weighted += 
        joint[joint_index[i]]->parent->local_matrix * 
        joint[joint_index[i]]->local_matrix * 
        skin->inverse_bind_pose[joint_index[i]] * 
        position * 
        skin->weight[j];
}
position = weighted;

就文献而言,这是正确的公式.现在,COLLADA指定了关节的两种旋转方式:局部和全局.您必须将旋转连接在一起以获得关节的局部变换.

COLLADA文档没有区别的是联合的本地轮换和联合的全局旋转.但是在我看到的大多数模型中,旋转可以具有rotate(全局)或jointOrient(local)的id.

当我忽略全局旋转,只使用本地旋转时,我得到模型的绑定姿势.但是,当我将全球轮转加入联合地方转型时,奇怪的事情开始发生.

这是没有使用全球轮换:

这是全球轮转:

在两个屏幕截图中,我使用线绘制骨架,但是在第一个视图中,它是不可见的,因为关节在网格内.在第二个屏幕截图中,顶点遍布当地!

为了比较,这是第二个截图应该是这样的:

很难看到,但是您可以看到关节在第二个截图中位于正确的位置.

但现在奇怪的是.如果我忽略由COLLADA指定的反向绑定姿势,而是采用联合的父局部变换的倒数乘以联合局部变换,我得到以下内容

在这个截图中,我从每个顶点绘制一条线到有影响的关节.我得到绑定姿势的事实不是很奇怪,因为公式现在变成:

world_matrix * inverse_world_matrix * position * weight

但是它导致我怀疑COLLADA的反绑定姿势是错误的空间.

所以我的问题是:COLLADA在什么空间中指定了其反绑定姿势?而且如何将逆绑定姿势转换到我需要的空间?

解决方法

我开始比较我的值与我从Assimp(一个开源模型加载器)读取的值.在编写代码之后,我查看了它们构建绑定矩阵及其反向绑定矩阵的位置.

最终我最终在SceneAnimator :: GetBoneMatrices中包含以下内容

// Bone matrices transform from mesh coordinates in bind pose to mesh coordinates in skinned pose
// Therefore the formula is offsetMatrix * currentGlobalTransform * inverseCurrentMeshTransform
for( size_t a = 0; a < mesh->mNumBones; ++a)
{
    const aiBone* bone = mesh->mBones[a];
    const aiMatrix4x4& currentGlobalTransform
        = GetGlobalTransform( mBoneNodesByName[ bone->mName.data ]);
    mTransforms[a] = globalInverseMeshTransform * currentGlobalTransform * bone->mOffsetMatrix;
}

globalInverseMeshTransform始终是身份,因为网格不会转换任何东西. currentGlobalTransform是绑定矩阵,联合的父本的本地矩阵与联合的局部矩阵相连.而mOffsetMatrix是直接来自皮肤的反向绑定矩阵.

我检查了这些矩阵的值到我自己的(哦,是的,我在一个手表窗口比较它们),它们是完全一样的,可能是0.0001%,但这是微不足道的.那么为什么Assimp的版本工作和我的,即使公式是一样的?

这是我得到的:

当Assimp终于将矩阵上传到皮肤着色器时,它们执行以下操作:

helper->piEffect->SetMatrixTransposeArray( "gBoneMatrix",(D3DXMATRIX*)matrices,60);

Waaaaait一秒.他们上传他们转置?这不是那么容易.没门.

对.

还有一件事我做错了:在应用皮肤矩阵之前,我将坐标转换成正确的系统(厘米到米).这导致完全失真的模型,因为矩阵是为原始坐标系设计的.

未来GOOGLERS

>按您收到的顺序读取所有节点变换(旋转,转换,缩放等).
将它们连接到一个关节的局部矩阵.
采取联合的父母,并将其与本地矩阵相乘.
>将其存储为绑定矩阵.
>阅读皮肤信息.
>存储关节的逆绑定姿势矩阵.
>存储每个顶点的关节权重.
将具有反向绑定姿势矩阵的绑定矩阵相乘并将其转置,称之为剥皮矩阵.
>将占位矩阵乘以关节重量,并将其添加到加权位置.
>使用加权位置进行渲染.

完成!

原文链接:https://www.f2er.com/c/113709.html

猜你在找的C&C++相关文章