Android OpenGL ES2骨骼动画

Android OpenGL ES2骨骼动画,android,opengl-es,keyframe,skeletal-animation,Android,Opengl Es,Keyframe,Skeletal Animation,“我试图学习骨骼动画,因此我有很多误解” 我从Blender导出了一个非常简单的JSON格式文件,其中一个立方体和一块骨骼仅旋转了4帧,因此我加载了VBO,它有4个属性:位置vec4、法线vec4、权重vec2和骨骼索引vec2,正确渲染后,骨骼有位置,rotq和scale,因此我使用以下函数创建骨骼的变换矩阵 public static float[] createMat4(float[] t, float[] r, float[] s) { float[] mat4 = new fl

“我试图学习骨骼动画,因此我有很多误解” 我从Blender导出了一个非常简单的JSON格式文件,其中一个立方体和一块骨骼仅旋转了4帧,因此我加载了VBO,它有4个属性:位置vec4、法线vec4、权重vec2和骨骼索引vec2,正确渲染后,骨骼有位置,rotq和scale,因此我使用以下函数创建骨骼的变换矩阵

public static float[] createMat4(float[] t, float[] r, float[] s) {
    float[] mat4 = new float[16];
    float[] T = new float[16];
    float[] R = new float[16];
    float[] S = new float[16];
    setIdentityM(T, 0);
    setIdentityM(R, 0);
    setIdentityM(S, 0);
    translateM(T, 0, t[0], t[1], t[2]);
    rotateM(R, 0, r[3], r[0], r[1], r[2]);
    scaleM(S, 0, s[0], s[1], s[2]);
    float[] temp = new float[16];
    multiplyMM(temp, 0, T, 0, R, 0);
    multiplyMM(mat4, 0, temp, 0, S, 0);
    return mat4;
}
因此,我通过将绑定乘以其逆“据我所知”来计算骨骼最终矩阵,对于每一帧,我将该矩阵乘以关键帧矩阵,该关键帧矩阵也是通过前面的方法从pos、rotq和scl生成的,最后我通过mat4[]uniform将这些矩阵上传到GPU,这是顶点着色器

uniform mat4 modelview;
uniform mat4 projection;
uniform mat4 bones[BONES];  
uniform int animated;

attribute vec4 vertexPosition;
attribute vec4 vertexNormal;
attribute vec2 textureCoords;
attribute vec2 skinweight;
attribute vec2 skinindex;

varying vec2 vTextureCoords;
varying vec4 viewDir;
varying vec4 modelviewNormal;
varying mat4 mv;

void main() {
    mv=modelview;
    vec4 newVertex;
    vec4 newNormal;
    if(animated==1){
       int index;
       index=int(skinindex.x);
       newVertex += (bones[index] * vertexPosition  * skinweight.x) ;
       newNormal += (bones[index] * vertexPosition * skinweight.x) ;

       index=int(skinindex.y);
       newVertex += (bones[index] * vertexPosition * skinweight.y);
       newNormal += (bones[index]  * vertexNormal* skinweight.y);
   }
   else{
       newVertex=vertexPosition;
       newNormal=vertexNormal;
   }
   vec4 modelviewVertex=(modelview * newNormal);
   modelviewNormal = normalize(modelviewVertex);
   viewDir = normalize(-modelview*newVertex);  
   vTextureCoords = textureCoords;
   gl_Position = (projection * modelview )* vec4(newVertex.xyz, 1.0);
}
渲染结果意外时,某些面会消失并随机移动顶点。

问题在于四元数旋转,我使用此函数将四元数转换为旋转矩阵

private static float[] quaternionToMatrix(float[] q) {
    float[] m = new float[16];
    final float xx = q[0] * q[0];
    final float xy = q[0] * q[1];
    final float xz = q[0] * q[2];
    final float xw = q[0] * q[3];
    final float yy = q[1] * q[1];
    final float yz = q[1] * q[2];
    final float yw = q[1] * q[3];
    final float zz = q[2] * q[2];
    final float zw = q[2] * q[3];
    m[0] = 1 - 2 * (yy + zz);
    m[1] = 2 * (xy - zw);
    m[2] = 2 * (xz + yw);
    m[3] = 0;
    m[4] = 2 * (xy + zw);
    m[5] = 1 - 2 * (xx + zz);
    m[6] = 2 * (yz - xw);
    m[7] = 0;
    m[8] = 2 * (xz - yw);
    m[9] = 2 * (yz + xw);
    m[10] = 1 - 2 * (xx + yy);
    m[11] = 0;
    m[12] = 0;
    m[13] = 0;
    m[14] = 0;
    m[15] = 1;
    return m;
}

最后我得到了骨骼动画工作。

问题在于四元数旋转,我使用此函数将四元数转换为旋转矩阵

private static float[] quaternionToMatrix(float[] q) {
    float[] m = new float[16];
    final float xx = q[0] * q[0];
    final float xy = q[0] * q[1];
    final float xz = q[0] * q[2];
    final float xw = q[0] * q[3];
    final float yy = q[1] * q[1];
    final float yz = q[1] * q[2];
    final float yw = q[1] * q[3];
    final float zz = q[2] * q[2];
    final float zw = q[2] * q[3];
    m[0] = 1 - 2 * (yy + zz);
    m[1] = 2 * (xy - zw);
    m[2] = 2 * (xz + yw);
    m[3] = 0;
    m[4] = 2 * (xy + zw);
    m[5] = 1 - 2 * (xx + zz);
    m[6] = 2 * (yz - xw);
    m[7] = 0;
    m[8] = 2 * (xz - yw);
    m[9] = 2 * (yz + xw);
    m[10] = 1 - 2 * (xx + yy);
    m[11] = 0;
    m[12] = 0;
    m[13] = 0;
    m[14] = 0;
    m[15] = 1;
    return m;
}
newVertex += (bones[index] * vertexPosition  * skinweight.x) ;
newNormal += (bones[index] * vertexPosition * skinweight.x) ;
最后我得到了骨骼动画的工作

newVertex += (bones[index] * vertexPosition  * skinweight.x) ;
newNormal += (bones[index] * vertexPosition * skinweight.x) ;
我在两个未初始化的值上看到一个+=assgnment运算符

我在两个未初始化的值上看到一个+=assgnment运算符