Clip length in seconds (§17, §7a). Metadata, not a limit: tracks clamp to their own key range and a player decides what happens past the end.
ReadonlyeventsThe clip's events (§17), sorted by time.
The constructor sorts a copy when the input is out of order and leaves an already-sorted input in its given order. The sort is stable, so events sharing a time keep their construction order and fire in it — a deterministic tie-break (§33) rather than whatever the engine's sort happened to do.
Clip name (§17).
ReadonlytracksThe clip's tracks, in evaluation order (§17).
Order is the array's order, forever — insertion order, never sorted or de-duplicated (§33: iterate collections in insertion order only). Two tracks on the same path are allowed and the later one wins, because that is what applying them in order does; the mixer, which owns conflict policy (§16), is where a warning belongs.
Visits every event in the half-open interval (fromExclusive, toInclusive] — event.time > fromExclusive && event.time <= toInclusive
— in time order, and returns how many were visited.
Forward playback advances clip time in steps: (t₀ → t₁], (t₁ → t₂], …
Because each step excludes its start and includes its end, consecutive
steps partition the timeline: every event fires exactly once, and an
event landing exactly on a step boundary fires with the step that reaches
it, never with the one that leaves it. That is §16's "exactly once per
forward crossing" reduced to arithmetic.
Consequences worth stating outright:
toInclusive is visited; one at exactly
fromExclusive is not;fromExclusive === toInclusive) visits nothing, so a
paused player crossing no time fires nothing;toInclusive < fromExclusive) visits nothing and
returns 0. Reverse playback is not "the same thing backwards": §16
defines marker crossing as a forward notion, so a player running in
reverse decides its own policy rather than getting a silent guess here;0 needs fromExclusive < 0 to fire. A player starting
at 0 therefore begins its first step from a value below zero (or fires
the zero-time events explicitly on start) — a deliberate consequence of
the rule that no event fires twice.The visitor receives the event and its index into
AnimationClip.events. Allocation-free with a hoisted visitor: the
scan is a binary search for the first event past fromExclusive followed by
a walk.
Index of the first event with time > timeExclusive, or
events.length when there is none.
The positioning primitive behind AnimationClip.eventsInRange, and
the one a seek uses on its own: jumping to time t sets the cursor here so
that already-crossed markers are skipped rather than re-fired (§16).
Binary search; allocation-free.
Samples every track at timeSeconds (clip-local) and hands each result to
sink, in AnimationClip.tracks order (§33: insertion order only).
Allocates nothing, provided the sink's outFor returns pre-allocated
storage. This is the whole of the clip's contribution to the mixer's inner
loop: ordered iteration, with the guarantee that a track's index here is the
same index it had when the mixer resolved its binding.
§17's animation clip: named, timed, tracks plus events.