利用者:Kazanbas/Collada Animation Import

提供: wiki
移動先: 案内検索

COLLADA Animation Import: How It Works

Abbreviations used

tm = transformation (rotation, scale, translation, etc.), tms = transformations

The Problem

DAE has a very specific way of describing object tm. For example (excerpt from [1]):

<node id="l_hip" name="l_hip" sid="l_hip" type="JOINT">
  <translate sid="translate">0.450181 0.049889 0.340342</translate>
  <rotate sid="jointOrientZ">0 0 1.000000 -81.926788</rotate>
  <rotate sid="jointOrientY">0 1.000000 0 -3.109476</rotate>
  <rotate sid="jointOrientX">1.000000 0 0 0</rotate>
  <rotate sid="rotateY">0 1.000000 0 0</rotate>
  <rotate sid="rotateAxisX">1.000000 0 0 -150.000000</rotate>
  <node id="l_knee" name="l_knee" sid="l_knee" type="JOINT">
    <translate sid="translate">1.833014 -0.024761 -0.002519</translate>
    <rotate sid="jointOrientZ">0 0 1.000000 2.742172</rotate>
    <rotate sid="jointOrientY">0 1.000000 0 -8.695618</rotate>
    <rotate sid="jointOrientX">1.000000 0 0 -120.102058</rotate>
    <rotate sid="rotateZ">0 0 1.000000 0</rotate>
    <rotate sid="rotateAxisX">1.000000 0 0 -167.476486</rotate>
...

This shows 2 nodes, "l_knee" is a child node of "l_hip" (it's tms are in parent space). Both have a series of tms (there can be any number them) that have to be applied sequentially to produce the final tm.

Each tm can be driven by anim curve.

How This Fits Into Blender

To correctly translate DAE tms to a Blender object's rotation, scale, location, the following is done:

Separately for rotation, scale and location:

  • find all keys at which to sample
  • at each key: evalute the whole transform, write it

This is simple. Now the difficult part.

How Bone Animation Is Translated

For bone animation, DAE joint tm cannot be used "as is" for a Blender bone. Because:

  • in Blender, Y axis is the bone length direction. In DAE, there's no such convention (there're no bones actually, only arbitrarily-oriented nodes)
  • in Blender, bone animation is stored as relative to bone rest pose, in DAE it's plain object-space

So bone animation has to be converted somehow.

The following formula is used to translate a bone animation key:

K = iR * M * iR_dae * R

Where R and iR are Blender bone rest matrix and it's inverse, iR_dae is an inverse of DAE joint rest matrix, M is an evaluated joint matrix. All matrices are world-space.

(M * iR_dae) gives a world-space change of a joint from it's rest pose. Post-multiplying this change by R gives a world-space Blender bone matrix. Pre-multiplying the result by iR gives a matrix that changes a Blender bone rest pose the same way it changed a DAE joint.

It took me 2 weeks to determine this formula. Yes, I should read more maths books :)

References

[1] Seymour_anim2.dae from http://collada.org/owl