FBX Exported Animation Has Unstable Rotation #105209

Closed
opened 2024-03-03 14:09:33 +01:00 by Ailuridae · 4 comments

System Information
Operating system: Linux-6.6.16-2-MANJARO-x86_64-with-glibc2.39 64 Bits, X11 UI
Graphics card: NVIDIA GeForce GTX 1660 Ti/PCIe/SSE2 NVIDIA Corporation 4.6.0 NVIDIA 545.29.06

Blender Version
Broken: version: 4.0.2, branch: blender-v4.0-release, commit date: 2023-12-05 07:41, hash: 9be62e85b727

Short description of error
When exporting to FBX, some animated bones will start to shake. I've attached a Blend file as an example.

ExampleBlend.gif

ExampleFBX.gif

Steps to Reproduce

  • Open the attached example Blend file
  • Export as FBX with options
    • Transform:Forward Y
    • Transform:Up Z
  • Import the generated FBX with default options

Debugging
It seems only Bone.001 is affected. The wrong rotation at certain frames is either caused by an incorrectly generated matrix during the baking step, or by incorrectly converting that matrix to Euler rotations. However, I doubt it is the latter. I've printed some values of Bone.001 in the fbx_object_tx function, while it was called by frame_values_gen.

# Frame: 4
matrix = Matrix((( 0.000001980912,  1.000000000000, -0.000000075535,  0.000000986483),
                 (-0.000002013889,  0.000000075554,  1.000000000000,  0.000000149974),
                 ( 1.000000000000, -0.000001921286,  0.000002038500,  0.000000041622),
                 ( 0.000000000000,  0.000000000000,  0.000000000000,  1.000000000000)))

rot = Euler((-43.26432041054461, -89.99983857993809, -46.73573332035233))

# Frame: 5
matrix = Matrix((( 0.000001980919,  1.000000000000, -0.000000075499, -0.000000197244),
                 (-0.000002053577,  0.000000075510,  0.999999940395,  0.000000219111),
                 ( 0.999999940395, -0.000001921337,  0.000002088037,  0.000000060298),
                 ( 0.000000000000,  0.000000000000,  0.000000000000,  1.000000000000)))

rot = Euler((-45.00002515790118, -89.99983857993809, -48.366488796017066))
# This rotation deviates from frame 4 and 6 and is what causes the shaking effect

# Frame: 6
matrix = Matrix((( 0.000001980945,  1.000000000000, -0.000000075506, -0.000001380893),
                 (-0.000002035912,  0.000000075463,  1.000000000000,  0.000000285914),
                 ( 1.000000119209, -0.000001921362,  0.000002016113,  0.000000079287),
                 ( 0.000000000000,  0.000000000000,  0.000000000000,  1.000000000000)))

rot = Euler((-43.26432041054461, -89.99983857993809, -46.73573332035233))
**System Information** Operating system: Linux-6.6.16-2-MANJARO-x86_64-with-glibc2.39 64 Bits, X11 UI Graphics card: NVIDIA GeForce GTX 1660 Ti/PCIe/SSE2 NVIDIA Corporation 4.6.0 NVIDIA 545.29.06 **Blender Version** Broken: version: 4.0.2, branch: blender-v4.0-release, commit date: 2023-12-05 07:41, hash: `9be62e85b727` **Short description of error** When exporting to FBX, some animated bones will start to shake. I've attached a Blend file as an example. ![ExampleBlend.gif](/attachments/256f2ff9-e45a-4d11-9944-95adace4376c) ![ExampleFBX.gif](/attachments/a7c3e4cf-0b8c-43f3-b83d-79ce60a79b50) **Steps to Reproduce** - Open the attached example Blend file - Export as FBX with options - Transform:Forward Y - Transform:Up Z - Import the generated FBX with default options **Debugging** It seems only `Bone.001` is affected. The wrong rotation at certain frames is either caused by an incorrectly generated matrix during the baking step, or by incorrectly converting that matrix to Euler rotations. However, I doubt it is the latter. I've printed some values of `Bone.001` in the `fbx_object_tx` function, while it was called by `frame_values_gen`. ```python # Frame: 4 matrix = Matrix((( 0.000001980912, 1.000000000000, -0.000000075535, 0.000000986483), (-0.000002013889, 0.000000075554, 1.000000000000, 0.000000149974), ( 1.000000000000, -0.000001921286, 0.000002038500, 0.000000041622), ( 0.000000000000, 0.000000000000, 0.000000000000, 1.000000000000))) rot = Euler((-43.26432041054461, -89.99983857993809, -46.73573332035233)) # Frame: 5 matrix = Matrix((( 0.000001980919, 1.000000000000, -0.000000075499, -0.000000197244), (-0.000002053577, 0.000000075510, 0.999999940395, 0.000000219111), ( 0.999999940395, -0.000001921337, 0.000002088037, 0.000000060298), ( 0.000000000000, 0.000000000000, 0.000000000000, 1.000000000000))) rot = Euler((-45.00002515790118, -89.99983857993809, -48.366488796017066)) # This rotation deviates from frame 4 and 6 and is what causes the shaking effect # Frame: 6 matrix = Matrix((( 0.000001980945, 1.000000000000, -0.000000075506, -0.000001380893), (-0.000002035912, 0.000000075463, 1.000000000000, 0.000000285914), ( 1.000000119209, -0.000001921362, 0.000002016113, 0.000000079287), ( 0.000000000000, 0.000000000000, 0.000000000000, 1.000000000000))) rot = Euler((-43.26432041054461, -89.99983857993809, -46.73573332035233)) ```
Ailuridae added the
Status
Needs Triage
Priority
Normal
Type
Report
labels 2024-03-03 14:09:33 +01:00
Author

Replacing the conversion of quaternion to Euler rotations in fbx_object_tx with the scipy implementation seems to solve the issue for this specific example. This neglects the compatibility check for the Euler rotations. I've not yet checked the underlying implementations of both methods.

    def fbx_object_tx(self, scene_data, rest=False, rot_euler_compat=None):
        """
        Generate object transform data (always in local space when possible).
        """
        matrix = self.fbx_object_matrix(scene_data, rest=rest)
        loc, rot, scale = matrix.decompose()
        matrix_rot = rot.to_matrix()

        # Original
        # quat -> euler, we always use 'XYZ' order, use ref rotation if given.
        # if rot_euler_compat is not None:
        #     rot = rot.to_euler('XYZ', rot_euler_compat)
        # else:
        #     rot = rot.to_euler('XYZ')

        # Workaround
        from scipy.spatial.transform import Rotation as R

        from mathutils import Euler

        rot = R.from_quat((rot.x, rot.y, rot.z, rot.w)).as_euler('xyz')

        rot = Euler((rot[0], rot[1], rot[2]), 'XYZ')

        return loc, rot, scale, matrix, matrix_rot
Replacing the conversion of quaternion to Euler rotations in `fbx_object_tx` with the scipy implementation seems to solve the issue for this specific example. This neglects the compatibility check for the Euler rotations. I've not yet checked the underlying implementations of both methods. ```python def fbx_object_tx(self, scene_data, rest=False, rot_euler_compat=None): """ Generate object transform data (always in local space when possible). """ matrix = self.fbx_object_matrix(scene_data, rest=rest) loc, rot, scale = matrix.decompose() matrix_rot = rot.to_matrix() # Original # quat -> euler, we always use 'XYZ' order, use ref rotation if given. # if rot_euler_compat is not None: # rot = rot.to_euler('XYZ', rot_euler_compat) # else: # rot = rot.to_euler('XYZ') # Workaround from scipy.spatial.transform import Rotation as R from mathutils import Euler rot = R.from_quat((rot.x, rot.y, rot.z, rot.w)).as_euler('xyz') rot = Euler((rot[0], rot[1], rot[2]), 'XYZ') return loc, rot, scale, matrix, matrix_rot ```
Member

Thanks for the report. I can reproduce the issue in 3.6 and 4.0, but not in 4.1. It looks like 5b00141144 fixed the underlying issue.

Thanks for the report. I can reproduce the issue in 3.6 and 4.0, but not in 4.1. It looks like https://projects.blender.org/blender/blender/commit/5b00141144d41ae7d3fcf709f4a97e7eb02a9b99 fixed the underlying issue.
Author

Thanks a lot! I'll check out 4.1 next week and close the issue accordingly.

Thanks a lot! I'll check out 4.1 next week and close the issue accordingly.
Author

I also cannot reproduce the issue in Blender 4.1.0 Release Candidate (hash 64bfe491645f built 2024-03-23 00:54:33).

I also cannot reproduce the issue in Blender 4.1.0 Release Candidate (hash 64bfe491645f built 2024-03-23 00:54:33).
Blender Bot added
Status
Archived
and removed
Status
Needs Triage
labels 2024-03-24 14:28:35 +01:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender-addons#105209
No description provided.