diff options
-rwxr-xr-x | io_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py | 22 |
1 files changed, 7 insertions, 15 deletions
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py b/io_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py index 5bf14826..65f68c4f 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py @@ -84,13 +84,6 @@ class BlenderBoneAnim(): @staticmethod def parse_rotation_channel(gltf, node, obj, bone, channel, animation): """Manage rotation animation.""" - # Note: some operations lead to issue with quaternions. Converting to matrix and then back to quaternions breaks - # quaternion continuity - # (see antipodal quaternions). Blender interpolates between two antipodal quaternions, which causes glitches in - # animation. - # Converting to euler and then back to quaternion is a dirty fix preventing this issue in animation, until a - # better solution is found - # This fix is skipped when parent matrix is identity blender_path = "pose.bones[" + json.dumps(bone.name) + "].rotation_quaternion" group_name = bone.name @@ -107,12 +100,6 @@ class BlenderBoneAnim(): else: quat_keyframes = [quaternion_gltf_to_blender(vals) for vals in values] - # Manage antipodal quaternions - # (but is not suffisant, we also convert quaternion --> euler --> quaternion) - for i in range(1, len(quat_keyframes)): - if quat_keyframes[i].dot(quat_keyframes[i-1]) < 0: - quat_keyframes[i] = -quat_keyframes[i] - if not node.parent: final_rots = [ @@ -129,15 +116,20 @@ class BlenderBoneAnim(): final_rots = [ bind_rotation.rotation_difference( (parent_mat @ quat_keyframe.to_matrix().to_4x4()).to_quaternion() - ).to_euler().to_quaternion() + ) for quat_keyframe in quat_keyframes ] else: final_rots = [ - bind_rotation.rotation_difference(quat_keyframe).to_euler().to_quaternion() + bind_rotation.rotation_difference(quat_keyframe) for quat_keyframe in quat_keyframes ] + # Manage antipodal quaternions + for i in range(1, len(final_rots)): + if final_rots[i].dot(final_rots[i-1]) < 0: + final_rots[i] = -final_rots[i] + BlenderBoneAnim.fill_fcurves( obj.animation_data.action, keys, |