fix: use world-space rotation via global pose override

The bone rest poses have complex non-identity rotations (e.g. LeftUpperArm
euler=(-0.161,-2.760,-2.760)). Applying local rotations on top of these
produces incorrect results. Fix by using set_bone_global_pose_override()
with world-space rotation pre-multiplied on the rest pose basis.
This commit is contained in:
2026-06-25 11:24:54 -04:00
parent 35cb2ef10c
commit 35decd65b3
+8 -4
View File
@@ -545,7 +545,7 @@ func _process(delta: float) -> void:
func _apply_procedural_animation(data: Dictionary, time: float) -> void: func _apply_procedural_animation(data: Dictionary, time: float) -> void:
## Applies procedural animation data to the skeleton at the given time. ## Applies procedural animation data to the skeleton at the given time.
## Uses linear interpolation between keyframe values. ## Uses global pose override to set bone transforms relative to their rest pose.
if not skeleton: if not skeleton:
return return
var tracks = data["tracks"] var tracks = data["tracks"]
@@ -577,9 +577,13 @@ func _apply_procedural_animation(data: Dictionary, time: float) -> void:
if prev_kf.has("rot") and next_kf.has("rot"): if prev_kf.has("rot") and next_kf.has("rot"):
var rot: Vector3 = lerp(prev_kf["rot"], next_kf["rot"], t) var rot: Vector3 = lerp(prev_kf["rot"], next_kf["rot"], t)
# Convert euler angles to Quaternion for set_bone_pose_rotation # Get the bone's rest global pose
var quat = Quaternion.from_euler(rot) var rest_global = skeleton.get_bone_global_pose(bone_idx)
skeleton.set_bone_pose_rotation(bone_idx, quat) # Apply rotation offset around world axes (pre-multiply)
# For locomotion: X = forward/back swing, Y = twist, Z = lateral
var world_basis = Basis(Quaternion.from_euler(rot))
var new_global = Transform3D(world_basis * rest_global.basis, rest_global.origin)
skeleton.set_bone_global_pose_override(bone_idx, new_global, 1.0, true)
elif prev_kf.has("pos") and next_kf.has("pos"): elif prev_kf.has("pos") and next_kf.has("pos"):
var pos: Vector3 = lerp(prev_kf["pos"], next_kf["pos"], t) var pos: Vector3 = lerp(prev_kf["pos"], next_kf["pos"], t)
skeleton.set_bone_pose_position(bone_idx, pos) skeleton.set_bone_pose_position(bone_idx, pos)