From 475f60da21a46498636767c936b24d2544450f09 Mon Sep 17 00:00:00 2001 From: Axel Meyer Date: Sun, 17 May 2026 20:17:06 +0200 Subject: [PATCH] fix(puppet): store all bone angles in radians for render consistency The pipeline now stores radians uniformly in bone_state, matching the look-at branch's math.atan output and the render path's draw_rect_rotated expectations. JSON degrees are converted at the boundary (build_animation, write_bone). sample_animation returns radians. --- init.lua | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/init.lua b/init.lua index 6369a0e..676186a 100644 --- a/init.lua +++ b/init.lua @@ -162,7 +162,7 @@ function M.build_animation(anim_table, rig) .. "' which is not in animation's track '" .. anim_table.track .. "'") end cooked.bones[k] = { - angle = v.angle or 0, -- keep in degrees; interpolation stays in degrees + angle = math.rad(v.angle or 0), -- JSON degrees → radians for internal storage } end end @@ -220,7 +220,6 @@ function M.sample_animation(anim, t) local next_v = next_kf.bones[bid] if prev_v and next_v then frame[bid] = { - -- keyframe angles are stored in degrees; interpolate in degrees. angle = prev_v.angle * (1 - alpha) + next_v.angle * alpha, } elseif prev_v then @@ -334,8 +333,7 @@ function M.clear_look_target(handle) end function M.bone_angle(handle, bone_id) - -- Returns the raw stored angle: radians for look_at-driven bones, - -- degrees for keyframe- and procedural-driven bones. + -- Returns the stored angle in radians (uniform across all channels). return all_puppets[handle].bone_state[bone_id].angle end @@ -370,9 +368,7 @@ function M.write_bone(handle, bone_id, values) end end if values.angle ~= nil then - -- Store the caller-supplied value directly; write_bone accepts degrees - -- (same units as rest-pose angles and keyframe angles). - p.bone_state[bone_id].angle = values.angle + p.bone_state[bone_id].angle = math.rad(values.angle) -- caller passes degrees end end @@ -411,9 +407,6 @@ function M.update(dt) end local frame = M.sample_animation(anim, play_state.t) for bid, bone_kf in pairs(frame) do - -- sample_animation returns degrees; store directly (bone_state - -- uses degrees for keyframe/procedural channels, radians for - -- look_at which writes via math.atan). p.bone_state[bid].angle = bone_kf.angle end end