ludic.anim: animset_choice names the playing choice's clip as the set does, animset_can says whether the rig carries any of a state's clips (a one-shot with none is not asked for)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
a22b8a572b
commit
a87f20c66e
6 changed files with 35 additions and 3 deletions
|
|
@ -68,7 +68,9 @@ and transitions (from a state or `"*"`, with a fade; with `@frame when: fn() ->
|
|||
own the frame it answers true). The code binds an `AnimPlayer` to a set and a rig
|
||||
(`animset_bind`), sets parameters (`animset_param`), asks for a state (`animset_request`, taken once
|
||||
however often it is asked) and ticks it into a skin (`animset_tick`). A one-shot (`loop: false`)
|
||||
holds its last pose and hands on to `next`. Clip names are made once per rig; a tick makes nothing.
|
||||
holds its last pose and hands on to `next`. `animset_choice` names the playing choice's clip as the set
|
||||
does ("sit_seat", no rig), and `animset_can(key)` says whether the rig carries any of a state's clips, so a
|
||||
one-shot with none yet is not asked for. Clip names are made once per rig; a tick makes nothing.
|
||||
|
||||
## Tests
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,17 @@ export function animset_request(pl: AnimPlayer, key: string) -> void {
|
|||
pl.want = i
|
||||
}
|
||||
|
||||
# the state is in the set and the rig carries one of its clips: a one-shot with none is not asked for
|
||||
export function animset_can(pl: AnimPlayer, key: string) -> bool {
|
||||
if pl.set < 0 or pl.clips == null { return false }
|
||||
let i = as_state(AnimSets[pl.set], key)
|
||||
if i < 0 { return false }
|
||||
let d = AnimSets[pl.set].states[i]
|
||||
if d.choices == null { return false }
|
||||
for c in 0 .. len(d.choices) { if pl.clips[pl.base[i] + c] != null { return true } }
|
||||
return false
|
||||
}
|
||||
|
||||
function as_param_at(pl: AnimPlayer, name: string) -> int {
|
||||
if pl.set < 0 { return -1 }
|
||||
let s = AnimSets[pl.set]
|
||||
|
|
|
|||
|
|
@ -20,10 +20,16 @@ export property AnimPlayer {
|
|||
mix: float = 1.0
|
||||
fade: float = 0.2
|
||||
rate: float = 1.0
|
||||
pick: int = -1 # which of the state's choices plays
|
||||
}
|
||||
|
||||
export function animset_clip(pl: AnimPlayer) -> Clip { return pl.clip }
|
||||
export function animset_time(pl: AnimPlayer) -> float { return pl.t }
|
||||
export function animset_rate(pl: AnimPlayer) -> float { return pl.rate }
|
||||
# the playing choice's clip as the set names it, without the rig ("sit_seat"); "" before a tick
|
||||
export function animset_choice(pl: AnimPlayer) -> string {
|
||||
if pl.set < 0 or pl.pick < 0 { return "" }
|
||||
return AnimSets[pl.set].states[pl.state].choices[pl.pick].clip
|
||||
}
|
||||
export function animset_ready(pl: AnimPlayer) -> bool { return pl.ready }
|
||||
export function animset_bound(pl: AnimPlayer, set: int, rig: string) -> bool { return pl.set == set and pl.rig == rig and pl.names != null }
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ export function animset_tick(anim_st: mut AnimState, pl: AnimPlayer, sk: Skin, d
|
|||
let d = AnimSets[pl.set].states[pl.state]
|
||||
let k = as_pick(pl, d)
|
||||
if k < 0 { return false }
|
||||
pl.pick = k
|
||||
pl.rate = as_rate(pl, d, d.choices[k])
|
||||
as_switch(pl, d, pl.clips[pl.base[pl.state] + k])
|
||||
let adv = dt * pl.rate
|
||||
|
|
|
|||
|
|
@ -113,4 +113,15 @@ program AnimSetTest {
|
|||
}
|
||||
expect(playing(pl) == "rig_idle")
|
||||
}
|
||||
test "the playing choice is named as the set names it; a state the rig has no clip for cannot be asked" (anim_st: mut AnimState, render3d_st: mut Render3dState) {
|
||||
let sk = skin(render3d_st)
|
||||
let pl = rig(anim_st)
|
||||
expect(animset_choice(pl) == "")
|
||||
animset_param(pl, "speed", 1.0)
|
||||
animset_tick(anim_st, pl, sk, 0.016)
|
||||
expect(animset_choice(pl) == "walk")
|
||||
expect(animset_can(pl, "wave"))
|
||||
expect(not animset_can(pl, "bow"))
|
||||
expect(not animset_can(pl, "nope"))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# sets.lres - the test's one set: a ground state picking by speed bands, a one-shot that hands back,
|
||||
# and a hop the code never asks for, taken when toy_hops says so
|
||||
# a hop the code never asks for, taken when toy_hops says so, and a bow no rig carries
|
||||
toy {
|
||||
entry: "ground"
|
||||
params: ["speed"]
|
||||
|
|
@ -14,7 +14,8 @@ toy {
|
|||
]
|
||||
},
|
||||
{ key: "wave", loop: false, next: "ground", choices: [{ clip: "wave" }] },
|
||||
{ key: "hop", choices: [{ clip: "hop" }] }
|
||||
{ key: "hop", choices: [{ clip: "hop" }] },
|
||||
{ key: "bow", loop: false, next: "ground", choices: [{ clip: "bow" }] }
|
||||
]
|
||||
transitions: [{ from: "ground", to: "hop", blend: 0.1, when: fn toy_hops }]
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue