PDA

View Full Version : 3D animation with Collada

shacharco
10-20-2016, 07:47 AM
Hello everyone,

I am trying to make my java program display a 3D animation it reads from a Collada file.
I have read many tutorials, but yet something isn't working right,

the way i do it is:
1. I parse the collada file
2. each frame i calculate the keyframe transform for each joint by multiplying the joint's transform by it's parent tranform
3. I save as a SkinningMatrix the joint's keyframe transform matrix multiplyed by the joint's inverse bind matrix
4. I load to the vertex shader the skinningMatrices for all joints and for each vertex it's weights and joint's indecies
5. in the vertex shader i calculate the position by adding position * bindShapeMatrix * skinningMatrix[i] * weights[i] for all i that has weight > 0

but yet my animation looks really bad and wrong.
I'm adding my relevant source code and would thank you alot for any help.

vec4 initPos = vec4(0, 0, 0, 0);
vec4 initNormal = vec4(0, 0, 0, 0);
int count = 0;
for(int i = 0; i < MAX_WEIGHTS; i++)
{
float weight = weights[i];
if(weight > 0) {
count++;
int jointIndex = joints[i];
vec4 tmpPos = vec4(position, 1.0) * bindShapeMatrix * jointsMatrix[jointIndex];
initPos += weight * tmpPos;

vec4 tmpNormal = vec4(normal, 0.0) * bindShapeMatrix * jointsMatrix[jointIndex];
initNormal += weight * tmpNormal;
}
}
if (count == 0)
{
initPos = bindShapeMatrix * vec4(position, 1.0);
initNormal = bindShapeMatrix * vec4(normal, 0.0);
}

vec4 worldPosition = transformationMatrix * initPos ;

vec4 positionRelativeToCam = viewMatrix * worldPosition;

gl_Position = projectionMatrix * positionRelativeToCam ;

in the render method:

private void setupSkeleton(AnimationData anim) {
Stack<Bone> boneStack = new Stack<Bone>();
boneStack.push(anim.getRootBone());
while(!boneStack.isEmpty()){
Bone bone = boneStack.pop();

Matrix4f worldMatrix = interpolate(bone, DisplayManager.getCurrentTime());

if(bone.getParent() != null){
worldMatrix = Matrix4f.mul(worldMatrix, bone.getParent().getWorldMatrix(), null);
}
bone.setWorldMatrix(worldMatrix);
Matrix4f invBindMatrix = bone.getInvBindMatrix();

//if the isnt an inv bind matrix
if(invBindMatrix == null){
invBindMatrix = new Matrix4f();
invBindMatrix.setIdentity();
}
bone.setSkinningMatrix(Matrix4f.mul(invBindMatrix, worldMatrix, null));

for(Bone child : bone.getChilds()){
boneStack.push(child);
}

}