From 4448fc7a2991b209648e32aaf18df8907df08cba Mon Sep 17 00:00:00 2001 From: Axel Meyer Date: Mon, 18 May 2026 22:31:39 +0200 Subject: [PATCH] =?UTF-8?q?feat(puppet):=20v0.4.3=20=E2=80=94=20inherit=5F?= =?UTF-8?q?scale=3Dfalse=20flag=20(decouple=20world.scl)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New optional bone field 'inherit_scale' (default true). When set false, world.scl = local.scl (no parent.scl multiplier). Position cascade still uses parent.scl (so child follows parent's stretch positionally). Use case: feet that move with leg-end as leg.scl_y cycles +1/0/-1, but foot sprite stays at constant scale (no Y-flip when leg flips, no collapse when leg collapses). --- init.lua | 20 ++++++++++++++++++-- manifest.lib | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/init.lua b/init.lua index a74af94..19c618b 100644 --- a/init.lua +++ b/init.lua @@ -112,6 +112,11 @@ function M.build_rig(rig_table) -- v0.4.0: Parse virtual flag (virtual=true skips render; bone still participates in compute_world) local virtual = (b.virtual == true) + -- v0.4.3: Parse inherit_scale flag (default true; false → world.scl = local.scl, + -- ignoring parent.world.scl. Position cascade still uses parent.scl). + local inherit_scale = true + if b.inherit_scale == false then inherit_scale = false end + bones_by_id[b.id] = { id = b.id, parent = nil, -- resolved below @@ -128,6 +133,7 @@ function M.build_rig(rig_table) look_at_slerp = look_at_slerp, -- v0.4.0: slerp-rate (unitless float) sprite_rot = sprite_rot, virtual = virtual, -- v0.4.0: skip render if true + inherit_scale = inherit_scale, -- v0.4.3: false → world.scl decoupled from parent.scl color = b.color or { 200, 200, 200 }, texture = b.texture, -- optional atlas-id (string) or nil z_order = b.z_order or 0, -- render-sort key; default 0 @@ -728,8 +734,18 @@ local function compute_world(p, b) bs.world.x = pw.x + (cos_r * bs.pos.x * sx - sin_r * bs.pos.y * sy) bs.world.y = pw.y + (sin_r * bs.pos.x * sx + cos_r * bs.pos.y * sy) bs.world.rot = pw.rot + bs.rot - bs.world.scl_x = pw.scl_x * bs.scl.x - bs.world.scl_y = pw.scl_y * bs.scl.y + if b.inherit_scale == false then + -- v0.4.3: inherit_scale=false → world.scl from local only, + -- ignoring parent.world.scl. POSITION cascade above still + -- uses parent.scl (so child follows parent's stretch + -- positionally without scaling its own sprite). Use case: + -- feet that track leg-end but don't Y-flip when leg flips. + bs.world.scl_x = bs.scl.x + bs.world.scl_y = bs.scl.y + else + bs.world.scl_x = pw.scl_x * bs.scl.x + bs.world.scl_y = pw.scl_y * bs.scl.y + end end end diff --git a/manifest.lib b/manifest.lib index 4c56d54..bc42043 100644 --- a/manifest.lib +++ b/manifest.lib @@ -1,6 +1,6 @@ { "id": "lib-core.puppet", - "version": "0.4.2", + "version": "0.4.3", "api_min": "0.1", "deps": [] }