Tuesday, 8 July 2014

Keynote *.mqx file format

The Keynote plugin for Metasequoia stores its animation data in an XML text file with the file extension *.mqx.

I created the following simple animation using the Keynote plugin to study the keyframe data stored in the *.mqx file.

The animation starts and ends with both bones pointing in the +Y axis direction.

An animation created with the Keynote Metasequoia plugin



The *.mqx file listing is shown below where bone2 is the child of bone1.

<?xml version='1.0' encoding='UTF-8'?>
<MetasequoiaDocument>
    <IncludedBy>bonekeynote2.mqo</IncludedBy>
    <Plugin.BD1224DB.0000002C name="Motion">
        <XSFormat version="0.2" app="Metasequoia">
            <XSConfig>
                <XSFileConfig limitFPS="1" FPS="60.00" step="0" freeze="0" fastcalc="1" adjustwgt="0" debugdraw="1" mode="0" multitrack="0"/>
                <XSSceneConfig col_scn="8375551"/>
                <XSBoneConfig col_def="6737049" col_sel="16757299" col_hot="16776960" col_cst="15040434" col_phy="8362444"/>
            </XSConfig>
            <XSAnimationContainer>
                <XSAnimationSet name="motion_01" interpolate="21">
                    <XSAnimation frame="0">
                        <XSAnimationKey name="bone1"/>
                        <XSAnimationKey name="bone2"/>
                    </XSAnimation>
                    <XSAnimation frame="20">
                        <XSAnimationKey name="bone1">
                            <q>0.000000 0.000000 -0.707107 0.707107</q>
                        </XSAnimationKey>
                        <XSAnimationKey name="bone2"/>
                    </XSAnimation>
                    <XSAnimation frame="40">
                        <XSAnimationKey name="bone1">
                            <q>0.000000 0.000000 -0.707107 0.707107</q>
                        </XSAnimationKey>
                        <XSAnimationKey name="bone2">
                            <q>0.000000 0.000000 0.707107 0.707107</q>
                        </XSAnimationKey>
                    </XSAnimation>
                    <XSAnimation frame="70">
                        <XSAnimationKey name="bone1">
                            <q>0.000000 0.000000 -0.707107 0.707107</q>
                        </XSAnimationKey>
                        <XSAnimationKey name="bone2">
                            <q>-0.499858 -0.500000 0.500000 0.500143</q>
                        </XSAnimationKey>
                    </XSAnimation>
                    <XSAnimation frame="100">
                        <XSAnimationKey name="bone1"/>
                        <XSAnimationKey name="bone2">
                            <q>0.000000 0.000000 0.707107 0.707107</q>
                        </XSAnimationKey>
                    </XSAnimation>
                    <XSAnimation frame="120">
                        <XSAnimationKey name="bone1"/>
                        <XSAnimationKey name="bone2"/>
                    </XSAnimation>
                    <XSAnimation frame="140">
                        <XSAnimationKey name="bone1"/>
                        <XSAnimationKey name="bone2"/>
                    </XSAnimation>
                </XSAnimationSet>
            </XSAnimationContainer>
        </XSFormat>
    </Plugin.BD1224DB.0000002C>
</MetasequoiaDocument>

The keyframe rotation data is stored as quaternions in (i j k w) form which was confirmed by changing the quaternions to (0 0 0 1) in a text editor, viewing the animation and seeing no rotation.

Calculating the rotations by the methods in this post [link] we get the following.

Note that the –0.0000 values are a result of floating point operations in the program I am using to calculate the quaternions and occur because instead of returning zero a very tiny negative number is returned.


At frames 0, 120 and 140 the skeleton is in the bind pose.
  • bone1’s absolute rotation = (-0.5000 -0.5000 -0.5000 0.5000)
  • bone2’s absolute rotation = (-0.5000 -0.5000 -0.5000 0.5000)
  • bone1’s relative rotation = (-0.5000 -0.5000 -0.5000 0.5000)
  • bone2’s relative rotation = (0 0 0 1)


At frame 20:
  • bone1’s absolute rotation = (0.7071 -0.0000 0.7071 -0.0000)
  • bone2’s absolute rotation = (0.7071 -0.0000 0.7071 -0.0000)
  • bone1’s relative rotation = (0.7071 -0.0000 0.7071 -0.0000)
  • bone2’s relative rotation = (0 0 0 1)
absolute rotation from bind pose = absolute rotation x inv. of absolute rotation of bind pose
  • bone1’s absolute rotation from bind pose = (0.0000 0.0000 0.7071 -0.7071)
  • bone2’s absolute rotation from bind pose = (0.0000 0.0000 0.7071 -0.7071)

  • bone1’s relative rotation from bind pose = (0.0000 0.0000 0.7071 -0.7071)

absolute rotation = parent bone’s absolute rotation x relative rotation

relative rotation = inverse of parent bone’s absolute rotation x absolute rotation

  • bone2’s relative rotation from bind pose:

= (0.0000 0.0000 -0.7071 -0.7071) x (0.0000 0.0000 0.7071 -0.7071)

= (0.0000 0.0000 0.0000 1.0000)

These relative rotations from bind pose match the values stored in the *.mqx if we choose the quaternion with the positive real part to represent a rotation and store the identity quaternion as an empty XML tag for a bone, <XSAnimationKey name="bone"/>.

Lets check for frame 40.
  • bone1’s absolute rotation = (0.7071 -0.0000 0.7071 -0.0000)
  • bone2’s absolute rotation = (-0.5000 -0.5000 -0.5000 0.5000)
  • bone1’s relative rotation = (0.7071 -0.0000 0.7071 -0.0000)
  • bone2’s relative rotation = (0.7071 0.0000 0.0000 0.7071)

absolute rotation from bind pose = absolute rotation x inv. of absolute rotation of bind pose
  • bone1’s absolute rotation from bind pose = (0.0000 0.0000 0.7071 -0.7071)
  • bone2’s absolute rotation from bind pose = (0.0000 0.0000 0.0000 1.0000)

relative rotation = inverse of parent bone’s absolute rotation x absolute rotation
  • bone1’s relative rotation from bind pose = (0.0000 0.0000 0.7071 -0.7071)
  • bone2’s relative rotation from bind pose:

= (0.0000 0.0000 -0.7071 -0.7071) x (0.0000 0.0000 0.0000 1.0000)

= (0.0000 0.0000 -0.7071 -0.7071)

These values match the file values when multiplied by –1.

See also: http://sappersblog.blogspot.com/2014/07/mikoto-mkm-file-format.html


No comments:

Post a Comment