Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何计算COLLADA文件';父对象和子对象的关节变换?_C++_Opengl_Matrix_Collada_Skeletal Animation - Fatal编程技术网

C++ 如何计算COLLADA文件';父对象和子对象的关节变换?

C++ 如何计算COLLADA文件';父对象和子对象的关节变换?,c++,opengl,matrix,collada,skeletal-animation,C++,Opengl,Matrix,Collada,Skeletal Animation,尝试实施索具: 使用Blender创建了一个简单的操纵蛇测试,并导出了COLLADA文件 我已正确加载顶点位置、权重和关节ID 我已经为每个骨骼加载了骨骼关节层次和这些变换(我加载了矩阵,将所有的浮点值放入一个浮点值[16],然后我使用glm::make_mat4(tmpFloatArray),然后我将其转置,不确定这是否是正确的方法): 1 0 0 0 0 0 1 0 0 -1 0 0 0 0 0 1 0.3299372 0.944003-1.78814e-70-4.76837e-70-

尝试实施索具:

  • 使用Blender创建了一个简单的操纵蛇测试,并导出了COLLADA文件
  • 我已正确加载顶点位置、权重和关节ID
  • 我已经为每个骨骼加载了骨骼关节层次和这些变换(我加载了矩阵,将所有的浮点值放入一个浮点值[16],然后我使用glm::make_mat4(tmpFloatArray),然后我将其转置,不确定这是否是正确的方法):

1 0 0 0 0 0 1 0 0 -1 0 0 0 0 0 1
0.3299372 0.944003-1.78814e-70-4.76837e-70-10-0.944003 0.3299374 3.8743e-7 0 0 1
0.886344-0.4630275 3.31894e-7 2.98023e-8 0.4630274 0.886344-1.86307e-7 1.239941-2.07907e-7 3.18808e-7 1-2.84217e-14 0 0 1
0.9669114 0.2551119-1.83038e-7-1.19209e-7-0.2551119 0.9669115 1.29195e-7 1.219687 2.09941e-7-7.82246e-8 1 0 0 0 1
0.8538353 0.5205433 1.0139e-7-1.19209e-7-0.5205433 0.8538353 2.4693e-7 1.815649 4.19671e-8-2.63615e-7 1 5.68434e-14 0 0 1
现在,如果我将每个骨骼的矩阵设置为glm::mat4(1),则得到以下结果:

但是,如果我尝试乘以关节父变换,就像在瘦矩阵装配教程中一样,我会得到非常奇怪的结果:

void SkelManager::setTposeTransforms(std::vector<Joint>& _reference)
{
    for (int child = 0; child < _reference.size(); child++)
    {
        if (_reference[child].parent == -1)
        {
            //_reference[child].tPose = glm::mat4(1);
            _reference[child].tPose = _reference[child].transform;
        }
        for (int parent = 0; parent < _reference.size(); parent++)
        if (_reference[child].parent == parent)
        {
            //_reference[child].tPose = glm::mat4(1);
            _reference[child].tPose = _reference[parent].tPose * _reference[child].transform;
        }
    }
}
void SkelManager::setTposeTransforms(std::vector&\u引用)
{
对于(int child=0;child<_reference.size();child++)
{
if(_引用[child].parent==-1)
{
//_引用[child].tPose=glm::mat4(1);
_引用[child].tPose=\u引用[child].transform;
}
对于(int parent=0;parent<_reference.size();parent++)
if(_引用[child].parent==parent)
{
//_引用[child].tPose=glm::mat4(1);
_引用[child]。tPose=_引用[parent]。tPose*_引用[child]。转换;
}
}
}

请帮帮我,我已经在这上面呆了几个星期了,但我没有成功,无论我多么努力地在网上搜索,我都找不到任何有用的东西,有没有关于我可能做错什么的想法

我使用glm::make_mat4(tmpFloatArray),然后转置它,不确定 如果这是正确的方法):

请参见COLLADA规范中关于矩阵的部分:

COLLADA中的矩阵是数学意义上的列矩阵。 这些矩阵是按行顺序写的,以帮助人类 读者。参见示例

所以,是的,你需要转换它

加载COLLADA的骨骼动画并不难。遵循以下步骤:

进口商方面:

  • 加载所有关节节点层次,将关节变换与父节点相乘直到根节点,就像对法线/其他节点(场景图)所做的那样。最好在每帧的变换发生变化时进行乘法
  • 使用关节IDs、权重加载控制器->蒙皮元素。。。同样绑定形状矩阵INV\u绑定矩阵
  • 加载动画对象以设置关节动画
  • 加载实例\u控制器,它存储材质和元素,该元素指示关节层次的根节点的位置。这很重要,因为您需要从该元素而不是整个文档或场景中的顶部节点开始解析SID
  • 渲染面:

  • 如果需要,为每个帧准备所有关节变换。将关节变换与其父对象相乘

  • 为每个关节创建此矩阵:

    FinalJointTrans4x4=JointTransform*InvBindPose*BindShapeMatrix

    JointTransform是与父项相乘的变换

    InvBindPose(或InvBindMatrix)是从蒙皮->关节->INV_BIND_矩阵中为每个关节读取的变换

    BindShapeMatrix是从skin->bind\u shape\u矩阵读取的变换

  • 将这些FinalJointTrans4x4矩阵和权重发送到着色器(统一的缓冲区有利于存储矩阵)

  • 在着色器中使用这些信息,然后对其进行渲染

  • 可能(来自):

    可能还有其他细节我可能忘记提及(我可能会在以后编辑答案),但这肯定会有很大帮助


    PS:有一个名为AssetKit()的库,如果您愿意,可以使用它加载COLLADA文件。

    非常感谢您的回答!我试着慢慢来,现在,我想得到默认姿势,我猜我需要为每个关节得到一个矩阵,没有旋转或平移,但有偏移,对吗?当我变换其中一个关节矩阵时,子节点会正确地移动,但它会在错误的点上旋转。也找不到INV_BIND_矩阵,不管我读了多少遍,我都不明白,因为这些新术语。但是非常感谢你的回答!如果您可以指定如何计算偏移量,我想我可以管理其余的。Thx!。您必须能够以
    的形式找到
    INV\u BIND\u矩阵。之所以需要,是因为需要将网格从对象空间变换到骨骼空间。然后,如果变换骨骼/关节,则网格将随之变换。按照上面的步骤创建
    FinalJointTrans4x4
    matrix,就像我提到的那样。教程你可以按照recp,我100%详细地阅读了你说的教程,现在它工作得更好了,但仍然不是100%好,如果你有一分钟的时间,你能像猴子一样解释一下吗,把这个从collada文件中取出来,乘以collada文件中的其他东西,然后在更新中做这个和这个,请,这会有很大帮助,我在这里呆了很长时间
    void SkelManager::setTposeTransforms(std::vector<Joint>& _reference)
    {
        for (int child = 0; child < _reference.size(); child++)
        {
            if (_reference[child].parent == -1)
            {
                //_reference[child].tPose = glm::mat4(1);
                _reference[child].tPose = _reference[child].transform;
            }
            for (int parent = 0; parent < _reference.size(); parent++)
            if (_reference[child].parent == parent)
            {
                //_reference[child].tPose = glm::mat4(1);
                _reference[child].tPose = _reference[parent].tPose * _reference[child].transform;
            }
        }
    }
    
    ...
    mat4 skinMat;
        
    skinMat = uJoints[JOINTS.x] * WEIGHTS.x
            + uJoints[JOINTS.y] * WEIGHTS.y
            + uJoints[JOINTS.z] * WEIGHTS.z
            + uJoints[JOINTS.w] * WEIGHTS.w;
        
    pos4  = skinMat * pos4;
    norm4 = skinMat * norm4;
    
    ...
    
    #ifdef JOINT_COUNT
      gl_Position = VP * pos4;
    #else
      gl_Position = MVP * pos4;
    #endif
    ...