Repository: khronosgroup/gltf-blender-io
Issue: Exporting rotation doesn't work when at least one scale dimension ist 0

This is related to #302 but the core issue hasn't been fixed so I'm opening a new issue.

I need to export an empty object that has scale 0 along the z-axis. This certainly isn't a common use case but I still think it will come up from time to time.

After a little investigation I found that currently translation, rotation, scale is extracted by decomposing the object's matrix:
https://github.com/KhronosGroup/glTF-Blender-IO/blob/d8aa684b87779d43ead627a6463ce2b6d7763f0b/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py#L106

This of course doesn't work when some axis is scaled to 0. Blender provides access to it's objects' properties `position`, `rotation_quaternion` and `scale` directly. Is there a specific reason why these aren't used?

The above mentioned function is used in only two places.

The first one is where I suggest we use the object's properties directly (modified by export settings of course):
https://github.com/KhronosGroup/glTF-Blender-IO/blob/b44e4794490f7d526727cf40f2fe20097f961385/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py#L278

and the second one should be left unchanged:
https://github.com/KhronosGroup/glTF-Blender-IO/blob/90b0c1f640c6d1105f9f520d0bf230b3cf8fe87c/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py#L50

I'm happy to do a pull request. Please let met know.

Thanks.

Changed files:
addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py, addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py, addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py

diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
index 1fa58622..634f1c18 100644
--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
@@ -102,13 +102,8 @@ def convert_swizzle_scale(scale, export_settings):
         return Vector((scale[0], scale[1], scale[2]))
 
 
-def decompose_transition(matrix, context, export_settings):
+def decompose_transition(matrix, export_settings):
     translation, rotation, scale = matrix.decompose()
-    """Decompose a matrix depending if it is associated to a joint or node."""
-    if context == 'NODE':
-        translation = convert_swizzle_location(translation, export_settings)
-        rotation = convert_swizzle_rotation(rotation, export_settings)
-        scale = convert_swizzle_scale(scale, export_settings)
 
     # Put w at the end.
     rotation = Quaternion((rotation[1], rotation[2], rotation[3], rotation[0]))
diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py
index 8c505717..f1c0dbe5 100644
--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py
@@ -48,7 +48,7 @@ def gather_joint(blender_bone, export_settings):
         # matrix_basis = blender_object.convert_space(blender_bone, blender_bone.matrix, from_space='POSE',
         #                                             to_space='LOCAL')
     trans, rot, sca = gltf2_blender_extract.decompose_transition(
-        gltf2_blender_math.multiply(correction_matrix_local, matrix_basis), 'JOINT', export_settings)
+        gltf2_blender_math.multiply(correction_matrix_local, matrix_basis), export_settings)
     translation, rotation, scale = (None, None, None)
     if trans[0] != 0.0 or trans[1] != 0.0 or trans[2] != 0.0:
         translation = [trans[0], trans[1], trans[2]]
diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
index c539dbf2..8f9a8d0f 100644
--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
@@ -275,7 +275,20 @@ def __gather_name(blender_object, export_settings):
 
 
 def __gather_trans_rot_scale(blender_object, export_settings):
-    trans, rot, sca = gltf2_blender_extract.decompose_transition(blender_object.matrix_local, 'NODE', export_settings)
+    trans = gltf2_blender_extract.convert_swizzle_location(blender_object.location, export_settings)
+
+    if blender_object.rotation_mode in ['QUATERNION', 'AXIS_ANGLE']:
+        rotation = blender_object.rotation_quaternion
+    else:
+        rotation = blender_object.rotation_euler.to_quaternion()
+
+    rotation = gltf2_blender_extract.convert_swizzle_rotation(rotation, export_settings)
+
+    # Put w at the end.
+    rot = Quaternion((rotation[1], rotation[2], rotation[3], rotation[0]))
+
+    sca = gltf2_blender_extract.convert_swizzle_scale(blender_object.scale, export_settings)
+
     if bpy.app.version < (2, 80, 0):
         if blender_object.dupli_type == 'GROUP' and blender_object.dupli_group:
             trans = -gltf2_blender_extract.convert_swizzle_location(