i-animated-display-object-3d.component overview
Table of contents
- utils
- IAnimatedDisplayObject3dComponent (interface)
- PlayAnimationOptions (interface)
- isAnimatedDisplayObject3d
utils
IAnimatedDisplayObject3dComponent (interface)
A 3D display object that also carries a skeletal/keyframe animation rig - e.g. a glTF/GLB model
loaded with bones and AnimationClips (see IDisplayObject3dComponentLoader.loadFromGlb), as
opposed to an auto-generated primitive mesh (box, capsule, ...) which never implements this.
Optional/adapter-specific on purpose: most display objects (primitives, static props) have
nothing to animate, so this isn't part of the base IDisplayObject3dComponent contract at all -
check with {@link isAnimatedDisplayObject3d} before calling into it, the same way an app checks
for any other optional capability on a value it only knows generically.
A driver (e.g. CharacterAnimationController) is expected to call {@link updateAnimations}
once per tick with the frame's own delta time, and {@link playAnimation}/{@link stopAnimation}
only when the desired clip actually changes - see CharacterAnimationController's own doc for
the established TickOrder.ANIMATION_MIXERS timing this assumes (after a mesh's position/
rotation has already been synced from its driving body/controller this frame, before rendering).
Signature
export interface IAnimatedDisplayObject3dComponent<VTypeDoc extends VisualTypeDocRepo3D = VisualTypeDocRepo3D>
extends IDisplayObject3dComponent<VTypeDoc> {
/** Names of every animation clip available on this model, as authored in the source asset. */
readonly animationNames: string[]
/** The clip name last passed to {@link playAnimation}, or `null` if none has played yet (or
* {@link stopAnimation} was called since). */
readonly currentAnimationName: string | null
/**
* Plays the named clip, crossfading from whatever was playing before (if anything). A no-op
* (with a `warnOnce` warning) if `name` isn't one of {@link animationNames}. Calling this again
* with the same `name` already playing is a no-op - it does not restart/pop the clip.
*/
playAnimation(name: string, options?: PlayAnimationOptions): void
/** Fades out and stops whatever clip is currently playing, leaving the model in its last posed
* frame. A no-op if nothing is currently playing. */
stopAnimation(fadeDuration?: number): void
/** Advances every active/fading animation action by `deltaSeconds` - must be called once per
* tick for animation to progress at all (nothing here ticks itself). */
updateAnimations(deltaSeconds: number): void
}
PlayAnimationOptions (interface)
Options for {@link IAnimatedDisplayObject3dComponent.playAnimation}.
Signature
export interface PlayAnimationOptions {
/** Whether the clip repeats indefinitely once it reaches its end, vs. playing once and holding
* its last frame. Default `true`. */
loop?: boolean
/** Crossfade duration (seconds) blending out whichever clip was previously playing into this
* one, so a state switch (e.g. walk -> run) doesn't visibly pop. `0` swaps instantly. Default
* `0.2`. */
fadeDuration?: number
/** Playback speed multiplier applied to the clip's own authored timing. Default `1`. */
timeScale?: number
}
isAnimatedDisplayObject3d
Type guard for {@link IAnimatedDisplayObject3dComponent} - checks for the two methods that
distinguish an animated display object from an ordinary one, since the capability is optional
and adapter-specific (see that interface's own doc). Prefer this over an instanceof check
against any concrete adapter class, which would defeat the point of the TypeDoc-generic,
library-agnostic interfaces the rest of packages/core is built around.
Signature
export declare function isAnimatedDisplayObject3d<VTypeDoc extends VisualTypeDocRepo3D = VisualTypeDocRepo3D>(
displayObject: VTypeDoc['displayObject'] | null | undefined
): displayObject is IAnimatedDisplayObject3dComponent<VTypeDoc>