Correct the pose composition for a non-180° rest (rest-relative swing axis), backward-compatible with the 13-core fallback
Full build / Import + headless tests (push) Successful in 42s
Full build / Full desktop build + optional release (push) Skipped

This commit is contained in:
zwitschi committed 2026-11-06 09:57:27 +01:00
1 parent f121167e52
commit 8b1bf736af
1 file changed
+7 -3
+7 -3
View File
@@ -535,10 +535,14 @@ func _pose_bone(bone_name: String, angle: float, axis: Vector3) -> void:
if not _bone_indices.has(bone_name): if not _bone_indices.has(bone_name):
return return
var index: int = _bone_indices[bone_name] var index: int = _bone_indices[bone_name]
# Bone pose rotation is the absolute local orientation, not an offset from # The pose is rest-relative (global = parent * rest * pose), so the proxy's
# rest; compose with the rest rotation so identity preserves the bind pose. # world-space swing axis must be expressed in the bone's rest-local frame.
# `rest * Quaternion(rest.inverse() * axis, angle)` swings around the world
# `axis`; for the old rig (rest = 180 deg) this reduces to the legacy
# `rest * Quaternion(axis, angle)`, so the 13-core fallback is unchanged.
var rest := _skeleton.get_bone_rest(index).basis.get_rotation_quaternion() var rest := _skeleton.get_bone_rest(index).basis.get_rotation_quaternion()
_skeleton.set_bone_pose_rotation(index, rest * Quaternion(axis, angle)) var local_axis := rest.inverse() * axis
_skeleton.set_bone_pose_rotation(index, rest * Quaternion(local_axis, angle))
func _build_body(npc_type: int) -> void: func _build_body(npc_type: int) -> void:
_rig = Node3D.new() _rig = Node3D.new()