How do I draw a scene with 2 nested frames
- by Guido Granobles
I have been trying for long time to figure out this:
I have loaded a model from a directx file (I am using opengl and Java) the model have a hierarchical system of nested reference frames (there are not bones). There are just 2 frames, one of them is called x3ds_Torso and it has a child frame called x3ds_Arm_01. Each one of them has a mesh. The thing is that I can't draw the arm connected to the body. Sometimes the body is in the center of the screen and the arm is at the top. Sometimes they are both in the center. I know that I have to multiply the matrix transformation of every frame by its parent frame starting from the top to the bottom and after that I have to multiply every vertex of every mesh by its final transformation matrix. So I have this:
public void calculeFinalMatrixPosition(Bone boneParent, Bone bone) {
System.out.println("-->" + bone.name);
if (boneParent != null) {
bone.matrixCombined = bone.matrixTransform.multiply(boneParent.matrixCombined);
} else {
bone.matrixCombined = bone.matrixTransform;
}
bone.matrixFinal = bone.matrixCombined;
for (Bone childBone : bone.boneChilds) {
calculeFinalMatrixPosition(bone, childBone);
}
}
Then I have to multiply every vertex of the mesh:
public void transformVertex(Bone bone) {
for (Iterator<Mesh> iterator = meshes.iterator(); iterator.hasNext();) {
Mesh mesh = iterator.next();
if (mesh.boneName.equals(bone.name)) {
float[] vertex = new float[4];
double[] newVertex = new double[3];
if (mesh.skinnedVertexBuffer == null) {
mesh.skinnedVertexBuffer = new FloatDataBuffer(
mesh.numVertices, 3);
}
mesh.vertexBuffer.buffer.rewind();
while (mesh.vertexBuffer.buffer.hasRemaining()) {
vertex[0] = mesh.vertexBuffer.buffer.get();
vertex[1] = mesh.vertexBuffer.buffer.get();
vertex[2] = mesh.vertexBuffer.buffer.get();
vertex[3] = 1;
newVertex = bone.matrixFinal.transpose().multiply(vertex);
mesh.skinnedVertexBuffer.buffer.put(((float) newVertex[0]));
mesh.skinnedVertexBuffer.buffer.put(((float) newVertex[1]));
mesh.skinnedVertexBuffer.buffer.put(((float) newVertex[2]));
}
mesh.vertexBuffer = new FloatDataBuffer(
mesh.numVertices, 3);
mesh.skinnedVertexBuffer.buffer.rewind();
mesh.vertexBuffer.buffer.put(mesh.skinnedVertexBuffer.buffer);
}
}
for (Bone childBone : bone.boneChilds) {
transformVertex(childBone);
}
}
I know this is not the more efficient code but by now I just want to understand exactly how a hierarchical model is organized and how I can draw it on the screen.
Thanks in advance for your help.