feat(puppet): v0.3.0 — idle-return locomotion + version bump
- apply_locomotion idle-return: after (now - last_move_time) > idle_return_delay, the most-displaced planted leg steps back to its current hip position (over idle_step_duration). Group-stagger via bumping last_move_time forward by idle_return_stagger. - M.move_to tracks p.last_move_time when position actually changes. - README v0.3.0 changelog entry.
This commit is contained in:
17
README.md
17
README.md
@@ -5,7 +5,7 @@ tracks, rest pose, keyframe animations, procedural animations
|
|||||||
(Lua-side), and look-at constraint. No footplant IK in v0.1
|
(Lua-side), and look-at constraint. No footplant IK in v0.1
|
||||||
(deferred).
|
(deferred).
|
||||||
|
|
||||||
**Version:** 0.2.0
|
**Version:** 0.3.0
|
||||||
**Lib-ID:** lib-core.puppet
|
**Lib-ID:** lib-core.puppet
|
||||||
**Requires:** (none — pure Lua + engine.render.*)
|
**Requires:** (none — pure Lua + engine.render.*)
|
||||||
**Tags:** animation, skeleton, puppet, character
|
**Tags:** animation, skeleton, puppet, character
|
||||||
@@ -125,6 +125,21 @@ ownership at write time.
|
|||||||
|
|
||||||
## CHANGELOG
|
## CHANGELOG
|
||||||
|
|
||||||
|
### v0.3.0
|
||||||
|
- BoneState multi-channel (rot/pos/scl) with world.scl_x/y and world.rot
|
||||||
|
- Cascaded world-transform with scale propagation (compute_world)
|
||||||
|
- Procedural locomotion layer via rig.locomotion block (apply_locomotion):
|
||||||
|
step-trigger, step-placement, step-height, leg-aim + leg-stretch
|
||||||
|
- Idle-return logic in apply_locomotion: after (now - last_move_time) >
|
||||||
|
idle_return_delay, the most-displaced planted leg steps back to its hip
|
||||||
|
position over idle_step_duration; group-stagger via idle_return_stagger
|
||||||
|
- M.move_to tracks p.last_move_time when position actually changes
|
||||||
|
- Schema changes: rest.rot/scl required; legacy rest.angle rejected with
|
||||||
|
clear error message (Substrate-Parity v0.3.0 schema)
|
||||||
|
- Bone-rig top-level scale field removed; per-frame world state replaces it
|
||||||
|
- New APIs: bone_world_scale, set_foot_sprite_reach_test_only,
|
||||||
|
foot_state_test_only, bone_animated_test_only
|
||||||
|
|
||||||
### v0.2.0
|
### v0.2.0
|
||||||
- Rig-format extension (texture, z_order, scale, anchor, asset_pack
|
- Rig-format extension (texture, z_order, scale, anchor, asset_pack
|
||||||
fields on bones; rig.bones_z_sorted for render-order)
|
fields on bones; rig.bones_z_sorted for render-order)
|
||||||
|
|||||||
36
init.lua
36
init.lua
@@ -438,6 +438,7 @@ function M.move_to(handle, x, y)
|
|||||||
p.facing = math.atan(dy, dx)
|
p.facing = math.atan(dy, dx)
|
||||||
p.last_move_x = x
|
p.last_move_x = x
|
||||||
p.last_move_y = y
|
p.last_move_y = y
|
||||||
|
p.last_move_time = engine.time.now()
|
||||||
end
|
end
|
||||||
p.x = x
|
p.x = x
|
||||||
p.y = y
|
p.y = y
|
||||||
@@ -731,6 +732,41 @@ local function apply_locomotion(p, dt)
|
|||||||
|
|
||||||
::continue::
|
::continue::
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (now - p.last_move_time) > loco.idle_return_delay then
|
||||||
|
local any_stepping = false
|
||||||
|
for i, _ in ipairs(loco.legs) do
|
||||||
|
if p.foot_state[i].state ~= "planted" then any_stepping = true; break end
|
||||||
|
end
|
||||||
|
if not any_stepping then
|
||||||
|
local best_i, best_dist = nil, 0
|
||||||
|
for i, leg_def in ipairs(loco.legs) do
|
||||||
|
local fs = p.foot_state[i]
|
||||||
|
if fs.state == "planted" then
|
||||||
|
local hip_wx = p.bone_state[leg_def.leg].world.x
|
||||||
|
local hip_wy = p.bone_state[leg_def.leg].world.y
|
||||||
|
local d = math.sqrt((hip_wx - fs.anchor_x)^2 + (hip_wy - fs.anchor_y)^2)
|
||||||
|
if d > best_dist then
|
||||||
|
best_dist = d
|
||||||
|
best_i = i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if best_i and best_dist > 1 then
|
||||||
|
local fs = p.foot_state[best_i]
|
||||||
|
local hip_wx = p.bone_state[loco.legs[best_i].leg].world.x
|
||||||
|
local hip_wy = p.bone_state[loco.legs[best_i].leg].world.y
|
||||||
|
fs.state = "stepping"
|
||||||
|
fs.step_from_x = fs.cur_x
|
||||||
|
fs.step_from_y = fs.cur_y
|
||||||
|
fs.step_to_x = hip_wx
|
||||||
|
fs.step_to_y = hip_wy
|
||||||
|
fs.step_timer = 0
|
||||||
|
fs.step_total = loco.idle_step_duration
|
||||||
|
p.last_move_time = now - loco.idle_return_delay + loco.idle_return_stagger
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ====================================================================
|
-- ====================================================================
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "lib-core.puppet",
|
"id": "lib-core.puppet",
|
||||||
"version": "0.2.0",
|
"version": "0.3.0",
|
||||||
"api_min": "0.1",
|
"api_min": "0.1",
|
||||||
"deps": []
|
"deps": []
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user