微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

骨骼动画的结果是错误的

如何解决骨骼动画的结果是错误的


顾名思义,我对骨骼动画有疑问。我已经调试了几个星期,但仍然找不到任何可以帮助我的东西。

所以,我的问题是,当没有对其应用动画时,网格看起来很正常(绑定姿势):
[绑定姿势] [1]

但是,一旦我介绍了加载的动画,一切似乎都错了:
[Animated Mesh] [2]
最近,我发现问题不是我的关节(骨骼)或背后的数学问题,而是从collada文件加载动画的过程。因为Blender(我用来制作模型的3D软件)将动画变换存储在一个矩阵中,所以我首先必须分解该矩阵才能对值进行插值。为此,我使用以下代码

    public static Transform decomposeMatrix(Matrix4f input)
    {
        // For translations and scale,this method was used: https://gamedev.stackexchange.com/questions/117528/calculate-matrix-transformation-components-separately
        
        System.out.println("Input: " + input);
        
        Vector3f translation = new Vector3f(input.m30(),input.m31(),input.m32());
        Vector3f scale = new Vector3f();
        scale.x = new Vector3f(input.get(0,0),input.get(0,1),2)).length();
        scale.y = new Vector3f(input.get(1,input.get(1,2)).length();
        scale.z = new Vector3f(input.get(2,input.get(2,2)).length();
                
        Quaternionf rotation = getQuaternionFromMatrix(input);
        
        Transform transform =  new Transform(translation,rotation,scale);
        
        System.out.println("output: " + transform.getLocalTransformationMatrix());
        
        System.out.println("Input transformed: " + new Vector4f(7,1,9,1).mul(input) + " where as output transformed: " + new Vector4f(7,1).mul(transform.getLocalTransformationMatrix()));
        
        return transform;
    }

    public static Quaternionf getQuaternionFromMatrix(Matrix4f matrix)
    {
        float w,x,y,z;
        float diagonal = matrix.m00() + matrix.m11() + matrix.m22();
        if (diagonal > 0) {
            float w4 = (float) (Math.sqrt(diagonal + 1f) * 2f);
            w = w4 / 4f;
            x = (matrix.m21() - matrix.m12()) / w4;
            y = (matrix.m02() - matrix.m20()) / w4;
            z = (matrix.m10() - matrix.m01()) / w4;
        } else if ((matrix.m00() > matrix.m11()) && (matrix.m00() > matrix.m22())) {
            float x4 = (float) (Math.sqrt(1f + matrix.m00() - matrix.m11() - matrix.m22()) * 2f);
            w = (matrix.m21() - matrix.m12()) / x4;
            x = x4 / 4f;
            y = (matrix.m01() + matrix.m10()) / x4;
            z = (matrix.m02() + matrix.m20()) / x4;
        } else if (matrix.m11() > matrix.m22()) {
            float y4 = (float) (Math.sqrt(1f + matrix.m11() - matrix.m00() - matrix.m22()) * 2f);
            w = (matrix.m02() - matrix.m20()) / y4;
            x = (matrix.m01() + matrix.m10()) / y4;
            y = y4 / 4f;
            z = (matrix.m12() + matrix.m21()) / y4;
        } else {
            float z4 = (float) (Math.sqrt(1f + matrix.m22() - matrix.m00() - matrix.m11()) * 2f);
            w = (matrix.m10() - matrix.m01()) / z4;
            x = (matrix.m02() + matrix.m20()) / z4;
            y = (matrix.m12() + matrix.m21()) / z4;
            z = z4 / 4f;
        }
        
        return new Quaternionf(x,z,w);
    }


以下是这些方法的结果:
输入矩阵:
-2.151E-1 -2.553E-1 -9.426E-1 -1.490E-8
-9.500E-1 -1.692E-1 2.626E-1 1.481E + 0
-2.265E-1 9.520E-1 -2.061E-1 0.000E + 0
0.000E + 0 0.000E + 0 0.000E + 0 1.000E + 0

输入矩阵转换为转换矩阵
-2.151E-1 -9.500E-1 -2.265E-1 -1.490E-8
-2.553E-1 -1.692E-1 9.520E-1 1.481E + 0
-9.426E-1 2.626E-1 -2.061E-1 0.000E + 0
0.000E + 0 0.000E + 0 0.000E + 0 1.000E + 0

因此,这些转换完全不相同:
如果我们将两个转换都应用于矢量,例如Vector4( 7,1,9 ,1 ),我们得到以下结果:

所需的转换:
Vector4( -1.024E + 1,-2.975E + 0,-2.489E + 0,1.000E + 0

“已转换”转换:
Vector4( -4.494E +0,8.092E + 0,-8.191E + 0,1.000E + 0

所以,希望您能帮助我解决这个问题。
[1]:https://i.stack.imgur.com/MC1JV.png [2]:https://i.stack.imgur.com/wxxoS.png

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。