Skip to content

DiceTransformations

Ben Heasly edited this page Aug 21, 2015 · 9 revisions

DiceTransformations is a variant of the Dice example scene. It applies spatial transformations to one of the dice objects in the scene to demonstrate how spatial transformations can interact. In particular, spatial transformations exported from the modeler can interact with spatial transformations applied in the RenderToolbox3 [mappings file](Mappings File Format), perhaps unexpectedly.

Separate Transformations vs Combined 4x4 Matrix

This example was motivated by a change in how Blender exports spatial transformations to Collada files. Blender's old default behavior was to export separate translation, rotation, and scale transformations. These were easy and intuitive to modify with the mappings file because values specified in the mappings file had the same effect as values typed into the Blender user interface.

Around Blender version 2.69, Blender's default behavior changed to export one combined 4x4 transformation matrix instead of separate translation, rotation and scale. The net effect is the same for separate transformations or 4x4 matrix, but the 4x4 matrix is harder to modify with the mappings file because the combined matrix obscures and confuses the individual transformations.

One way to get the old behavior is to choose the "TransRotLoc" Transformation Type in Blender's Export Collada Operator Presets. The Operator Presets are accessible from Blender's Export Collada dialog when choosing the output file name.

This option only works if you have Blender and you can re-export your own Blender project to Collada. If you have another Collada file that you can't re-export, you might need to deal with 4x4 transformation matrices in your mappings file. Read on!

Transforming Dice

The original Dice scene shows four 6-sided dice in mid-roll. The die closest to the camera is called Die2 and its visible faces show 6 pips and 4 pips.

Suppose we wanted to move Die2 closer to the camera, and rotate it so that the face with 1 pip was visible. One intuitive way to do this would be to apply transformations in the mappings file similar to transformations that we would have typed into Blender's user interface. For example:

Collada firstTry {
    % append custom translation and rotation
    Die2:translate|sid=location = 4 -5 0
    Die2:rotate|sid=rotationZ = 0 0 1 180
}

Translate Die2 closer to the camera by 4 x-units and -5 y-units. Rotate it around the vertical axis 180 degrees to make the opposite face visible.

This approach might work if the Collada file contained separate translation and rotation for Dice2. These transformations would simply be modified in place. But when the Collada file contains a 4x4 combined matrix, there is no explicit translation or rotation to modify.

Instead the translation and rotation are appended after the transformations in the 4x4 matrix. And since spatial transformations are not generally commutative, our translation and rotation are applied with respect to a transformed coordinate system, not the expected "to world" coordinate system for Dice2.

The results: the face with 1 pip is visible as we intended, but the translations went in the wrong direction causing Die2 to collide with another die.

To correct this, we would need to keep track of the transformed coordinate system that resulted from the exported 4x4 matrix, then think of different translations that we could apply in this coordinate system to have the intended effect. This is certainly possible. But it may be difficult to do on the fly and in your head.

An alternative is to forget about the exported 4x4 matrix by converting it to the identity matrix:

Collada identity {
    % forget any 4x4 camera transformation from Blender
    Die2:matrix|sid=transform = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1

This puts Die2 at the origin and undoes any rotation or scale.

Now we are free to apply intuitive transformations "from scratch", without any unexpected interactions. For example,

Collada fromScratch {
    % forget any 4x4 camera transformation from Blender
    Die2:matrix|sid=transform = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1

    % apply custom transformations
    Die2:translate|sid=location = 4 -5 2
    Die2:rotate|sid=rotationZ = 0 0 1 20
}

Translate Die2 towards the camera by 4 x-units and -5 y-units. Translate it up out of the floor by 2 z-units. Rotate 20 degrees about the vertical axis, just enough to bring the face with one pip from its original unrotated direction directly towards the camera.

One disadvantage of this approach is that it made us start over. We lost any clever or careful positioning for Die2 that was done in Blender. But it allowed us to take control of Die2 without having to wrestle with transformations applied in coordinate systems that are them selves transformed.

This approach should work no matter what Blender exports: if Blender exports separate translations and rotations, then our separate translations and rotations should just modify those. If Blender exports a 4x4 matrix, then our separate transformations should effectively replace it.

Full Example

The executive script MakeDiceTransformations.m produced the images above. It is located at here:

(path-to-RenderToolbox3)/ExampleScenes/Dice/MakeDiceTransformations.m
Clone this wiki locally