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
Opengl 动画蒙皮转换顺序问题_Opengl_Graphics_Skeletal Animation - Fatal编程技术网

Opengl 动画蒙皮转换顺序问题

Opengl 动画蒙皮转换顺序问题,opengl,graphics,skeletal-animation,Opengl,Graphics,Skeletal Animation,我在做骨骼动画渲染器时遇到了一些问题。 我编写了自己的Collada加载程序,加载的一切都很好(我已经检查了多次),我已经为绘图准备好了蒙皮和骨架数据 按照我的理解,您必须首先通过反向绑定变换将关节相乘,以使它们位于世界坐标系的中心,然后根据动画将关节相乘到动画矩阵(关节层次的浓缩局部关节变换)将关节转换为正确的世界位置 我将粘贴下面的代码,为了不处理帧的插值,我尝试渲染每个关节动画的第一帧,以便只关注蒙皮 static void update_animator(Animator* animat

我在做骨骼动画渲染器时遇到了一些问题。 我编写了自己的Collada加载程序,加载的一切都很好(我已经检查了多次),我已经为绘图准备好了蒙皮和骨架数据

按照我的理解,您必须首先通过反向绑定变换将关节相乘,以使它们位于世界坐标系的中心,然后根据动画将关节相乘到动画矩阵(关节层次的浓缩局部关节变换)将关节转换为正确的世界位置

我将粘贴下面的代码,为了不处理帧的插值,我尝试渲染每个关节动画的第一帧,以便只关注蒙皮

static void
update_animator(Animator* animator)
{
    if (animator->anim == NULL)return;
    increase_animation_time(animator);
    //this is the array holding the animated local bind transforms for each joint,
    //if there is no animation in a certain joint its simply m4d(1.f)
    mat4 *local_animated_transforms= (mat4*)malloc(sizeof(mat4) *joints_count);
    for (i32 i = 0; i < 44; ++i)
    {
        local_animated_transforms[i] = m4d(1.f);
    }

    for (u32 i = 0; i < animator->anim->joint_anims_count; ++i)
    {
        JointKeyFrame current_pose = animator->anim->joint_animations[i].keyframes[0];
        u32 animation_index = current_pose.joint_index;
        mat4 local_animated_transform = translate_mat4(current_pose.transform.position) * quat_to_mat4(current_pose.transform.rotation);
        local_animated_transforms[animation_index] = local_animated_transform;
    }
    for (u32 i = 0; i < joints_count;++i)
        calc_animated_transform(animator, animator->model.joints, local_animated_transforms, i);
}

static void
calc_animated_transform(Animator *animator, Joint *joints, mat4 *local_transforms, u32 index)
{
    //here we get the animated joint transform meaning the world pos of the joint in the animation
    mat4 animated_joint_transform = concat_local_transforms(joints, local_transforms, index); 
    //here we multiply by inv bind transform to get the world pos relative to the original bone transforms
    joints[index].animated_transform =animated_joint_transform * joints[index].inv_bind_transform;
}
静态无效
更新_animator(animator*animator)
{
如果(animator->anim==NULL)返回;
增加动画时间(动画师);
//这是为每个关节保存动画局部绑定变换的阵列,
//如果某个关节中没有动画,则其仅为m4d(1.f)
mat4*局部动画变换=(mat4*)malloc(sizeof(mat4)*关节计数);
对于(i32 i=0;i<44;++i)
{
局部_变换[i]=m4d(1.f);
}
对于(u32 i=0;ianim->joint\u anims\u count;++i)
{
JointKeyFrame当前_姿势=动画师->动画->关节_动画[i]。关键帧[0];
u32 animation_UIndex=当前的U pose.joint_UIndex;
mat4局部\ U动画\ U变换=平移\ mat4(当前\姿势.变换.位置)*四次到\ mat4(当前\姿势.变换.旋转);
局部动画变换[动画索引]=局部动画变换;
}
对于(u32 i=0;imodel.joints,局部动画变换,i);
}
静态空隙
计算动画变换(动画家*动画家,关节*关节,mat4*局部变换,u32索引)
{
//这里我们得到动画关节变换,即关节在动画中的世界位置
mat4动画_关节_变换=concat_局部_变换(关节、局部_变换、索引);
//在这里,我们乘以inv bind transform得到相对于原始骨骼变换的世界位置
关节[索引]。已设置动画的关节变换=已设置动画的关节变换*关节[索引]。inv\u bind\u变换;
}
这就是模型的外观:


感谢您的帮助

我在发动机tbh中使用这两种方法。。但是在这个动画系统中,因为我的矩阵是列主矩阵,所以我仅将其保留为opengl。最终关节变换=parentJointTransform[在世界空间中(将此关节的父局部变换与此关节局部变换相乘,然后再次成为其所有子关节的parentJointTransform)]*关节变换[来自局部关节空间中的动画]*inverseJointTransform[世界空间中此关节的]如果从colladae文件加载,您可能还需要加载矩阵的转置