ludic.anim: animation sets - the game's src/animset moved in as it stood (records, AnimPlayer, animset_bind / request / param / tick and the accessors); AnimSets is an open @ByKey registry a game fills with def AnimSets from; a test on a rig of hand-made clips
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d9a73d63bd
commit
5517873275
10 changed files with 442 additions and 1 deletions
53
packages/ludic.anim/set_bind.ludic
Normal file
53
packages/ludic.anim/set_bind.ludic
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# set_bind.ludic - a player given a set and a rig: the clip names are made once per rig, and
|
||||
# looked up again (without making anything) until the model has loaded and read its clips
|
||||
@alloc_ok("a rig's clip names and tables, made once when the rig changes")
|
||||
function as_names(pl: AnimPlayer, set: int, rig: string) -> void {
|
||||
let s = AnimSets[set]
|
||||
pl.set = set
|
||||
pl.rig = intern(rig)
|
||||
pl.names = new []string
|
||||
pl.clips = new []Clip
|
||||
pl.base = new []int
|
||||
pl.vals = new []float
|
||||
for i in 0 .. len(s.states) {
|
||||
push(pl.base, len(pl.names))
|
||||
let d = s.states[i]
|
||||
for c in 0 .. len(d.choices) {
|
||||
push(pl.names, intern(rig + "_" + d.choices[c].clip))
|
||||
push(pl.clips, null)
|
||||
}
|
||||
}
|
||||
if s.params != null { for i in 0 .. len(s.params) { push(pl.vals, 0.0) } }
|
||||
}
|
||||
|
||||
# Bind (or look again). A new rig is a different skeleton: nothing of the last one's cross-fade
|
||||
# may carry over. Ready once the entry state's default - its last choice - is found.
|
||||
export function animset_bind(anim_st: AnimState, pl: AnimPlayer, set: int, rig: string) -> bool {
|
||||
if animset_bound(pl, set, rig) and pl.ready { return true }
|
||||
if not animset_bound(pl, set, rig) {
|
||||
as_names(pl, set, rig)
|
||||
pl.ready = false
|
||||
}
|
||||
for i in 0 .. len(pl.names) { pl.clips[i] = anim_find(anim_st, pl.names[i]) }
|
||||
let s = AnimSets[set]
|
||||
pl.state = as_entry(s)
|
||||
pl.want = pl.state
|
||||
pl.asked = ""
|
||||
pl.clip = null
|
||||
pl.prev = null
|
||||
let d = s.states[pl.state]
|
||||
let n = len(d.choices)
|
||||
pl.ready = n > 0 and pl.clips[pl.base[pl.state] + n - 1] != null
|
||||
return pl.ready
|
||||
}
|
||||
|
||||
function as_entry(s: AnimSet) -> int {
|
||||
let i = as_state(s, s.entry)
|
||||
if i < 0 { return 0 }
|
||||
return i
|
||||
}
|
||||
|
||||
export function as_state(s: AnimSet, key: string) -> int {
|
||||
for i in 0 .. len(s.states) { if s.states[i].key == key { return i } }
|
||||
return -1
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue