cutan.characters.registration¶
The character side of the cut-out genre, as declarations: play and character.
What the cut-out genre (cutan.genre) registers from here (ADR 0001
§First slice):
the ``play`` action kind —
PlayAction, how long a duration-less play occupies asequence(its natural length, through the caller’s extent resolver), and itsscene.mdspelling;the ``character`` entity kind — a rigged character, whose nodes are nodes of the 2D stage engine (the
stage.nodeproperty space).
Plain declarations: importing this module registers nothing.
>>> PLAY.name, CHARACTER.space
('play', 'stage.node')
Functions
|
The shot that shows one character on its own (an#347's |
|
A duration-less play's extent when no descriptor is known: a motion preset's natural length over |
|
Play a named animation of the target entity's descriptor (an#7). |
|
The span a |
|
|
|
The |
Classes
|
Play a named animation of the target entity's descriptor (an#7). |
- class cutan.characters.registration.PlayAction(*, name=None, kind='play', target, animation, duration=None, speed=1.0, loop=None, args=None, **extra_data)[source]¶
Bases:
ExtensionActionPlay a named animation of the target entity’s descriptor (an#7).
animationnames an entry ofCharacterDescriptor.animations(the seededidle_breathandblink, or anything an author adds); the compiler resolves its tracks into channels on the entity’s nodes. A name the descriptor does NOT declare — or any name on an entity with no descriptor (a procedural rig, a prop) — falls back to the motion presets ofcutan.motion.PRESETS(hop,nod, …), which expand to ordinary tweens at the target’s built rest pose; a descriptor animation of the same name wins (an#166). Both halves are decided bycutan.characters.play.play_problems(), the one resolveran validateand the compiler share. For a preset,argsare its parameters,durationstretches the whole move to that length,speeddivides it, andloop: trueis refused (a preset is a one-shot).durationwidens/narrows the placement window;Nonemeans the animation’s own duration — or, when the resolvedloopis true, the rest of the shot, because a loop bounded by its own natural duration never loops.loopoverrides the animation’s declaredloop(None= use the descriptor’s). Inside asequencea play withduration=Noneoccupies its NATURAL length — a motion preset’s own length, a non-looping descriptor animation’sduration, both overspeed— so the next sibling starts when it ends; a looping one runs to the shot end and occupies ZERO (an.characters.play.play_extent()).- args: dict[str, Any] | None¶
Parameters of a MOTION PRESET (an#166) —
{"height": 30}for ahop— passed to itscutan.motion.PRESETSfunction as keyword arguments.None(the default, omitted from JSON) means the preset’s own defaults. A descriptor animation takes none, and one given to it is refused;restis never one — it is read off the built scene.
- cutan.characters.registration.character_specimen(ref)[source]¶
The shot that shows one character on its own (an#347’s
EntityKind.specimen, cutan#40): the character at rest, facing the camera (its rest view, untouched), alone, so the rig builder places its root at the stage centre.an library sheetdraws its first frame on a canvas sized from the descriptor’sview_boxand trims it to what it shows.>>> from an.ir.schema import AssetRef >>> shot = character_specimen(AssetRef(kind="character", id="ned", store="characters", ref="ned")) >>> shot.renderer, [e.id for e in shot.entities], shot.actions ('cutout', ['ned'], [])- Return type:
- cutan.characters.registration.default_play_extent(action)[source]¶
A duration-less play’s extent when no descriptor is known: a motion preset’s natural length over
speed, else0.0.The one resolver is
cutan.characters.play.play_extent(); this is it withdesc=None.>>> default_play_extent(PlayAction(target="a", animation="hop")) 0.5 >>> default_play_extent(PlayAction(target="a", animation="not_a_preset")) 0.0- Return type:
- cutan.characters.registration.play(target, animation, *, duration=None, speed=1.0, loop=None, args=None)[source]¶
Play a named animation of the target entity’s descriptor (an#7).
duration=Nonefills the animation’s natural length — or the shot’s remainder for a looping one. In asequencea play with nodurationoccupies its natural length (a motion preset’s own length divided byspeed; a non-looping descriptor animation’s likewise), so the sibling after it starts when it ends; a looping one runs to the shot end and occupies zero:>>> [f.start for f in flatten(sequence(play("a", "idle_breath"), delay(1.0), play("a", "blink")))] [0.0, 1.0] >>> [f.start for f in flatten(sequence(play("a", "idle_breath", duration=2.0), play("a", "blink")))] [0.0, 2.0] >>> [f.start for f in flatten(sequence(play("a", "hop"), play("a", "nod")))] [0.0, 0.5] >>> [f.start for f in flatten(sequence(play("a", "hop", speed=2.0), play("a", "nod")))] [0.0, 0.25](Bare
flattenknows only the presets, by name;an validateand the compiler pass the entity’s descriptor too —cutan.characters.play.play_extent()— so a descriptor animation that shares a preset’s name is measured as the descriptor’s.)A name the descriptor does not declare falls back to a motion preset of
cutan.motion.PRESETS, withargsas its parameters (an#166):>>> play("charlie", "hop", args={"height": 30}).args {'height': 30}- Return type:
- cutan.characters.registration.play_duration(action, extent)[source]¶
The span a
playoccupies: itsduration, else its natural extent.extentis the caller’s resolver (the compiler andan validatepass one bound to the entity’s descriptor); without one, a motion preset’s own length (default_play_extent()).>>> play_duration(PlayAction(target="a", animation="hop", duration=2.0), None) 2.0 >>> play_duration(PlayAction(target="a", animation="hop"), None) 0.5- Return type:
- cutan.characters.registration.read_play_md(item, *, index)[source]¶
{kind: play, target, animation, [duration], [speed], [loop], [args]}.Resolved at compile against the target entity’s descriptor
animations(an#7), falling back to the motion presets ofcutan.motion.PRESETSfor a name the descriptor does not declare, withargsas the preset’s parameters (an#166).loopomitted means the animation’s own. This reader accepted the shape from the start, then #24 made it refuse (nothing resolved a play) while the writer kept emitting it — three days of a project’s own scene.md failing to parse.- Return type: