Blender version: 2.73a

(FBX binary exporter)

When exporting a binary FBX, the coordinate system properties [*UpAxis*, *UpAxisSign*, *FrontAxis*, *FrontAxisSign*, *CoordAxis* and *CoordAxisSign*] are chosen incorrectly.

This error arises when mapping via the look-up table *RIGHT_HAND_AXES*. This table is correct as documented in the comments, in that it correctly maps tuples of (*Up*, *Front*) to the corresponding FBX properties. The error arises because everywhere in the FBX exporter/importer code, the value used to index into the table is actually (*Up*, * Forward*), not (

*Up*,

*Front*). Note that FBX considers the "front" vector as being the vector describing the normal direction of the visible faces of the model, i.e. a vector pointing toward the camera, not away from it. Basically, the

*front*vector is the negation of the

*forward*vector, so the result is a coordinate system that is rotated 180 degrees to what we actually wanted.

Because of this, while the actual mesh data is correctly exported, any importer that makes use of the coordinate system properties will, on converting the mesh data, rotate it 180 degrees. (This does not affect the Blender FBX importer because it uses the same look-up table on import, so the error is reversed.)

This bug is easily illustrated by exporting any mesh and then loading it into an external viewer such as the Visual Studio 2013 built-in viewer. You will see that the mesh is rotated 180 degrees.

The fix for this is trivial: simply convert *RIGHT_HAND_AXES* to be indexed by (*Up*, *Forward*) instead of (*Up*, *Front*) by negating the *front* vectors in the table indices. I have attached before and after versions of the relevant file*. This simple change fixes the problem 100%.

Bonus info: I haven't looked too far into it but it sounds like bug T42110 may be caused by this, since it is using an external importer.

^* Hmm. My browser is giving me no indication that these files have actually been uploaded. In case they haven't, here is the before and after version of the table as text.

BEFORE:

RIGHT_HAND_AXES = { # Up, Front -> FBX values (tuples of (axis, sign), Up, Front, Coord). ('X', 'Y'): ((0, 1), (1, 1), (2, 1)), ('X', '-Y'): ((0, 1), (1, -1), (2, -1)), ('X', 'Z'): ((0, 1), (2, 1), (1, -1)), ('X', '-Z'): ((0, 1), (2, -1), (1, 1)), ('-X', 'Y'): ((0, -1), (1, 1), (2, -1)), ('-X', '-Y'): ((0, -1), (1, -1), (2, 1)), ('-X', 'Z'): ((0, -1), (2, 1), (1, 1)), ('-X', '-Z'): ((0, -1), (2, -1), (1, -1)), ('Y', 'X'): ((1, 1), (0, 1), (2, -1)), ('Y', '-X'): ((1, 1), (0, -1), (2, 1)), ('Y', 'Z'): ((1, 1), (2, 1), (0, 1)), ('Y', '-Z'): ((1, 1), (2, -1), (0, -1)), ('-Y', 'X'): ((1, -1), (0, 1), (2, 1)), ('-Y', '-X'): ((1, -1), (0, -1), (2, -1)), ('-Y', 'Z'): ((1, -1), (2, 1), (0, -1)), ('-Y', '-Z'): ((1, -1), (2, -1), (0, 1)), ('Z', 'X'): ((2, 1), (0, 1), (1, 1)), ('Z', '-X'): ((2, 1), (0, -1), (1, -1)), ('Z', 'Y'): ((2, 1), (1, 1), (0, -1)), ('Z', '-Y'): ((2, 1), (1, -1), (0, 1)), # Blender system! ('-Z', 'X'): ((2, -1), (0, 1), (1, -1)), ('-Z', '-X'): ((2, -1), (0, -1), (1, 1)), ('-Z', 'Y'): ((2, -1), (1, 1), (0, 1)), ('-Z', '-Y'): ((2, -1), (1, -1), (0, -1)), }

And AFTER:

RIGHT_HAND_AXES = { # Up, Forward -> FBX values (tuples of (axis, sign), Up, Front, Coord). ('X', '-Y'): ((0, 1), (1, 1), (2, 1)), ('X', 'Y'): ((0, 1), (1, -1), (2, -1)), ('X', '-Z'): ((0, 1), (2, 1), (1, -1)), ('X', 'Z'): ((0, 1), (2, -1), (1, 1)), ('-X', '-Y'): ((0, -1), (1, 1), (2, -1)), ('-X', 'Y'): ((0, -1), (1, -1), (2, 1)), ('-X', '-Z'): ((0, -1), (2, 1), (1, 1)), ('-X', 'Z'): ((0, -1), (2, -1), (1, -1)), ('Y', '-X'): ((1, 1), (0, 1), (2, -1)), ('Y', 'X'): ((1, 1), (0, -1), (2, 1)), ('Y', '-Z'): ((1, 1), (2, 1), (0, 1)), ('Y', 'Z'): ((1, 1), (2, -1), (0, -1)), ('-Y', '-X'): ((1, -1), (0, 1), (2, 1)), ('-Y', 'X'): ((1, -1), (0, -1), (2, -1)), ('-Y', '-Z'): ((1, -1), (2, 1), (0, -1)), ('-Y', 'Z'): ((1, -1), (2, -1), (0, 1)), ('Z', '-X'): ((2, 1), (0, 1), (1, 1)), ('Z', 'X'): ((2, 1), (0, -1), (1, -1)), ('Z', '-Y'): ((2, 1), (1, 1), (0, -1)), ('Z', 'Y'): ((2, 1), (1, -1), (0, 1)), # Blender system! ('-Z', '-X'): ((2, -1), (0, 1), (1, -1)), ('-Z', 'X'): ((2, -1), (0, -1), (1, 1)), ('-Z', '-Y'): ((2, -1), (1, 1), (0, 1)), ('-Z', 'Y'): ((2, -1), (1, -1), (0, -1)), }