2016-12-17 4 views
0

«Я пытаюсь научиться скелетной анимации, поэтому у меня много недоразумений» У меня есть очень простой файл формата JSON, экспортированный из Blender, у которого есть один куб и одна кость повернута только на 4 кадра, поэтому я загружаю VBO который имеет 4 атрибуты позиции vec4, нормальный vec4, вес vec2 и индекс vec2 кости, который становитс правильно, кость имеет позы, rotq и масштаб, так что я использовал следующую функцию, чтобы создать матрицу преобразования костиOpenGL ES2 скелетная анимация

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; 
} 

, поэтому я вычисляю конечную матрицу кости с умножением связывания на ее обратное «как я понимаю» для каждого кадра. Я умножаю эту матрицу на матрицу ключевого кадра, которую я также генерирую предыдущим методом от пос, rotq и SCL, наконец, я загрузить эти матрицы на GPU с помощью mat4 [] однородным, это вершина шейдер

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); 
} 

при визуализации результат является неожиданным некоторые лица исчезает и случайная вершина движется. Rendering animation enter image description here

ответ

1

Проблема была в ротации кватернионов, я использовал эту функцию для преобразования кватернион в матрицу вращения

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; 
} 

наконец я скелетной анимации работы.

Смежные вопросы