diff --git a/g3blend/operators/io_export_xmot.py b/g3blend/operators/io_export_xmot.py index 00fa137..113f4eb 100644 --- a/g3blend/operators/io_export_xmot.py +++ b/g3blend/operators/io_export_xmot.py @@ -113,6 +113,9 @@ def save_xmot(context: bpy.types.Context, filepath: str, global_scale: float, gl else: bone_matrix = bone_matrix + # Also consider the pose base matrix. + bone_matrix = bone_matrix @ pose_bone.matrix_basis + loc, rot, scale = bone_matrix.decompose() motion_part = _add_chunk(chunks, Xmot.LmaChunkId.motionpart, 3, Xmot.CnkMotionPart) diff --git a/g3blend/operators/io_import_xmot.py b/g3blend/operators/io_import_xmot.py index 6a93ac1..cca2e55 100644 --- a/g3blend/operators/io_import_xmot.py +++ b/g3blend/operators/io_import_xmot.py @@ -81,6 +81,17 @@ def load_xmot(context: bpy.types.Context, filepath: str, global_scale: float, gl _to_blend_quat(chunk.content.pose_rotation), _to_blend_vec(chunk.content.pose_scale)) last_motion_part_rest_matrix_inv = last_motion_part_rest_matrix.inverted_safe() + + if last_motion_part not in arm_obj.pose.bones: + continue + + pose_bone = arm_obj.pose.bones[last_motion_part] + # Set pose matrix used in xmot (relative to bone's rest matrix) + bone = pose_bone.bone + rest_matrix = bone.matrix_local + if bone.parent is not None: + rest_matrix = bone.parent.matrix_local.inverted_safe() @ rest_matrix + pose_bone.matrix_basis = rest_matrix.inverted_safe() @ last_motion_part_rest_matrix elif isinstance(chunk.content, Xmot.CnkKeyFrame): if last_motion_part is None: raise ValueError('KeyFrame chunk must be preceded by a MotionPart chunk.') @@ -94,10 +105,6 @@ def load_xmot(context: bpy.types.Context, filepath: str, global_scale: float, gl pre_matrix = last_motion_part_rest_matrix_inv post_matrix = Matrix() - # Apply matrix - # TODO: Necessary? - # pose_bone.matrix_basis = bone_matrix - keyframe_chunk = chunk.content match keyframe_chunk.animation_type: # Position