Game Development Reference
In-Depth Information
// flatten bone matrices to array
for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
// compute the offset between the current and the original
transform
// was already representing the offset; however, this
requires some
// major changes to the animation system
mat4.mul(offsetMatrix, this.bones[ b ].skinMatrix,
this.boneInverses[ b ] );
this.flattenToArrayOffset(offsetMatrix, this.boneMatrices,
b * 16 );
}
};
}();
In the preceding code,
UpdateWorldMatrix
is the key function where all the
computations happen. It performs the following steps:
1. It first computes its own
modelMatrix
and then updates its
matrixWorld
matrix (concatenates
parentMatrix
).
2.
It iterates over the children array. If the child object is an instance of
bone
,
then it invokes the
update
function to compute its
skinMatrix
. If the child
object is an instance of
StageObject
, it invokes
updateWorldMatrix
of the
child object to compute its
matrixWorld
matrix.
It then computes the offset matrix for each bone in the array. When the object of
RiggedMesh
is first initialized and
updateWorldMatrix
is invoked, it checks whether
the
boneInverses
array is created. If they don't exist, it computes the inverse of
each bone's
skinMatrix
and stores it in the
boneInverses
array. The bone's initial
matrix is the binding matrix. This initial call stores the inverse binding matrix. Then in
subsequent calls of
updateWorldMatrix
, it does not calculate the
boneInverses
array
(discussed in the
The binding matrix
section of this chapter). The inverse binding matrix
is only calculated once. It then computes
offsetMatrix
i
=B
-1
i
*skinMatrix
. While
animating bones,
skinMatrix
will change each time, but the initial inverse binding
matrix is calculated only once and stored in the
boneInverse
variable. When we
load the
08-Loading-Skinned-Models.html
page in a browser, the character model
maintains its starting pose. This happens because the initial skin matrix is multiplied
by its own inverse. Hence the offset matrix for each bone becomes an identity matrix,
so no vertex is transformed. During animation, a vertex is transformed from the skin
local space to joint local space, and then we transform it using the
joint's
skinMatrix
.