@zephyr3d/editor 0.3.5 → 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/assets/{index-DlnbO59X.js → index-ySiLtSxz.js} +2 -2
  2. package/dist/assistant/zephyr-types-index.json +14215 -7892
  3. package/dist/index.html +1 -1
  4. package/dist/modules/zephyr3d_backend-webgl.js.map +1 -1
  5. package/dist/modules/zephyr3d_backend-webgpu.js.map +1 -1
  6. package/dist/modules/zephyr3d_base.js +152 -152
  7. package/dist/modules/zephyr3d_base.js.map +1 -1
  8. package/dist/modules/zephyr3d_imgui.js.map +1 -1
  9. package/dist/modules/zephyr3d_loaders.js +6 -6
  10. package/dist/modules/zephyr3d_loaders.js.map +1 -1
  11. package/dist/modules/zephyr3d_scene.js +2538 -348
  12. package/dist/modules/zephyr3d_scene.js.map +1 -1
  13. package/dist/vendor/zephyr3d/backend-webgl/dist/index.js.map +1 -1
  14. package/dist/vendor/zephyr3d/backend-webgpu/dist/index.js.map +1 -1
  15. package/dist/vendor/zephyr3d/base/dist/vfs/common.js +152 -152
  16. package/dist/vendor/zephyr3d/base/dist/vfs/common.js.map +1 -1
  17. package/dist/vendor/zephyr3d/imgui/dist/index.d.ts +7 -0
  18. package/dist/vendor/zephyr3d/imgui/dist/index.js.map +1 -1
  19. package/dist/vendor/zephyr3d/loaders/dist/gltf/gltf_importer.js +6 -6
  20. package/dist/vendor/zephyr3d/loaders/dist/gltf/gltf_importer.js.map +1 -1
  21. package/dist/vendor/zephyr3d/scene/dist/animation/animation.js +87 -0
  22. package/dist/vendor/zephyr3d/scene/dist/animation/animation.js.map +1 -1
  23. package/dist/vendor/zephyr3d/scene/dist/animation/animationcontroller.js +503 -0
  24. package/dist/vendor/zephyr3d/scene/dist/animation/animationcontroller.js.map +1 -0
  25. package/dist/vendor/zephyr3d/scene/dist/animation/animationset.js +782 -156
  26. package/dist/vendor/zephyr3d/scene/dist/animation/animationset.js.map +1 -1
  27. package/dist/vendor/zephyr3d/scene/dist/animation/animationtimeline.js +974 -0
  28. package/dist/vendor/zephyr3d/scene/dist/animation/animationtimeline.js.map +1 -0
  29. package/dist/vendor/zephyr3d/scene/dist/animation/joint_dynamics/convex_collider.js +320 -0
  30. package/dist/vendor/zephyr3d/scene/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
  31. package/dist/vendor/zephyr3d/scene/dist/app/scriptregistry.js +130 -125
  32. package/dist/vendor/zephyr3d/scene/dist/app/scriptregistry.js.map +1 -1
  33. package/dist/vendor/zephyr3d/scene/dist/asset/model.js +64 -63
  34. package/dist/vendor/zephyr3d/scene/dist/asset/model.js.map +1 -1
  35. package/dist/vendor/zephyr3d/scene/dist/index.d.ts +1270 -9
  36. package/dist/vendor/zephyr3d/scene/dist/index.js +3 -1
  37. package/dist/vendor/zephyr3d/scene/dist/index.js.map +1 -1
  38. package/dist/vendor/zephyr3d/scene/dist/material/mixins/lit.js +7 -3
  39. package/dist/vendor/zephyr3d/scene/dist/material/mixins/lit.js.map +1 -1
  40. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/manager.js +1 -0
  41. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/manager.js.map +1 -1
  42. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/animation.js +4 -3
  43. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/animation.js.map +1 -1
  44. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/camera.js +1 -1
  45. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/camera.js.map +1 -1
  46. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/node.js +3 -2
  47. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/node.js.map +1 -1
  48. package/package.json +8 -8
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animationtimeline.js","sources":["../../src/animation/animationtimeline.ts"],"sourcesContent":["import { Observable } from '@zephyr3d/base';\r\nimport type {\r\n AnimationFrameEvent,\r\n AnimationMarkerEvent,\r\n AnimationPlayback,\r\n AnimationSet,\r\n PlayAnimationOptions,\r\n StopAnimationOptions\r\n} from './animationset';\r\n\r\n/**\r\n * How a response disposes of the timeline's currently active playbacks/steps.\r\n * - `'stop'` (default): stop the active steps before running the response.\r\n * - `'keep'`: leave the active steps running; the response runs concurrently.\r\n * - `{ fadeOut }`: stop the active steps with a fade-out.\r\n * @public\r\n */\r\nexport type AnimationTimelineActiveDisposition = 'stop' | 'keep' | { fadeOut: number };\r\n\r\n/**\r\n * Return target for controller state-transition responses.\r\n *\r\n * - `true`: return to the state that was active before the transition.\r\n * - `string`: return to the named state.\r\n *\r\n * Only {@link AnimationController} state responses can perform the return; bare timeline runners\r\n * report state-transition targets as unhandled so the controller can act on them.\r\n * @public\r\n */\r\nexport type AnimationTimelineStateReturnTarget = true | string;\r\n\r\n/**\r\n * What a response does when its event fires. Exactly one variant applies.\r\n * @public\r\n */\r\nexport type AnimationTimelineEventTarget =\r\n | {\r\n /** Steps to run when the event is handled. */\r\n steps: AnimationTimelineStep[];\r\n /** Not used for step targets; keeps this union variant mutually exclusive. */\r\n targetState?: undefined;\r\n /** Not used for step targets; keeps this union variant mutually exclusive. */\r\n returnTo?: undefined;\r\n /** Not used for step targets; keeps this union variant mutually exclusive. */\r\n returnTransition?: undefined;\r\n /** Not used for step targets; keeps this union variant mutually exclusive. */\r\n consume?: undefined;\r\n /** Not used for step targets; keeps this union variant mutually exclusive. */\r\n ignore?: undefined;\r\n }\r\n | {\r\n /** Controller state name to transition to. */\r\n targetState: string;\r\n /**\r\n * Optional state to enter when `targetState` completes.\r\n *\r\n * Use `true` to return to the state active before the transition, or a string to return to\r\n * a specific named state. This is only applied by {@link AnimationController}.\r\n */\r\n returnTo?: AnimationTimelineStateReturnTarget;\r\n /**\r\n * Optional transition duration used when returning from `targetState`.\r\n *\r\n * If omitted, the return state's own transition setting is used.\r\n */\r\n returnTransition?: number;\r\n /** Not used for state-transition targets; keeps this union variant mutually exclusive. */\r\n steps?: undefined;\r\n /** Not used for state-transition targets; keeps this union variant mutually exclusive. */\r\n consume?: undefined;\r\n /** Not used for state-transition targets; keeps this union variant mutually exclusive. */\r\n ignore?: undefined;\r\n }\r\n | {\r\n /** Consume the event without starting steps or changing state. */\r\n consume: true;\r\n /** Not used for consume targets; keeps this union variant mutually exclusive. */\r\n steps?: undefined;\r\n /** Not used for consume targets; keeps this union variant mutually exclusive. */\r\n targetState?: undefined;\r\n /** Not used for consume targets; keeps this union variant mutually exclusive. */\r\n returnTo?: undefined;\r\n /** Not used for consume targets; keeps this union variant mutually exclusive. */\r\n returnTransition?: undefined;\r\n /** Not used for consume targets; keeps this union variant mutually exclusive. */\r\n ignore?: undefined;\r\n }\r\n | {\r\n /** Explicitly ignore the event. */\r\n ignore: true;\r\n /** Not used for ignore targets; keeps this union variant mutually exclusive. */\r\n steps?: undefined;\r\n /** Not used for ignore targets; keeps this union variant mutually exclusive. */\r\n targetState?: undefined;\r\n /** Not used for ignore targets; keeps this union variant mutually exclusive. */\r\n returnTo?: undefined;\r\n /** Not used for ignore targets; keeps this union variant mutually exclusive. */\r\n returnTransition?: undefined;\r\n /** Not used for ignore targets; keeps this union variant mutually exclusive. */\r\n consume?: undefined;\r\n };\r\n\r\n/**\r\n * Resolved kind of action a dispatched event produced.\r\n * @public\r\n */\r\nexport type AnimationTimelineEventPolicy = 'none' | 'ignore' | 'consume' | 'steps' | 'enqueue' | 'transition';\r\n\r\n/**\r\n * Result returned when a timeline or controller dispatches an event.\r\n * @public\r\n */\r\nexport type AnimationTimelineEventResult = {\r\n /**\r\n * Whether the event was consumed, converted into steps, enqueued, or accepted as a transition.\r\n */\r\n handled: boolean;\r\n /**\r\n * The action selected for the event.\r\n */\r\n policy: AnimationTimelineEventPolicy;\r\n /**\r\n * Dispatched event name.\r\n */\r\n event: string;\r\n /**\r\n * Optional payload supplied by the caller.\r\n */\r\n payload?: unknown;\r\n};\r\n\r\n/**\r\n * A reaction to a gameplay event, declared on a timeline or a controller state.\r\n *\r\n * The model is orthogonal: `target` says *what* to do, `onActive` says what happens to the\r\n * currently running steps, and `enqueue` defers `steps` instead of running them immediately.\r\n * @public\r\n */\r\nexport type AnimationTimelineEventResponse = {\r\n /**\r\n * Event name this response handles.\r\n */\r\n event: string;\r\n /** What the event does. */\r\n target: AnimationTimelineEventTarget;\r\n /**\r\n * Disposition of the currently active steps. Defaults to `'stop'`.\r\n * Use `'keep'` with `target.steps` to run the new steps concurrently (true parallel branch).\r\n * Ignored for `consume`/`ignore` targets.\r\n */\r\n onActive?: AnimationTimelineActiveDisposition;\r\n /**\r\n * When `true` and `target.steps` is set, the steps are appended to the queue and run after the\r\n * current steps drain, instead of replacing/joining them. `onActive` is ignored.\r\n */\r\n enqueue?: boolean;\r\n};\r\n\r\n/**\r\n * One executable instruction in an animation timeline.\r\n * @public\r\n */\r\nexport type AnimationTimelineStep =\r\n | {\r\n /** Start an animation clip playback. */\r\n type: 'play';\r\n /** Name of the animation clip to play from the owning AnimationSet. */\r\n clip: string;\r\n /**\r\n * Optional local reference id used by later `target` fields in this runner.\r\n *\r\n * If a later step replaces the same logical playback and future responses should keep using\r\n * this name, assign the same id again on the replacement `play` step.\r\n */\r\n id?: string;\r\n /** Playback options passed to `AnimationSet.play`. */\r\n options?: PlayAnimationOptions;\r\n /**\r\n * Whether to block the timeline on this playback before advancing to the next step.\r\n * - `'complete'`: wait until the playback completes or is stopped.\r\n * - `false` or omitted (default): start the playback and immediately continue.\r\n *\r\n * A clip that loops forever (`repeat: 0`) only completes when stopped, so combine\r\n * `wait: 'complete'` with a finite `repeat`/`range` or an external stop.\r\n */\r\n wait?: 'complete' | false;\r\n }\r\n | {\r\n /** Stop a playback owned by this runner. */\r\n type: 'stop';\r\n /**\r\n * Optional playback target id.\r\n *\r\n * When omitted, all playbacks owned by the current runner are stopped.\r\n */\r\n target?: string;\r\n /** Stop behavior passed to the matching playback or playbacks. */\r\n options?: StopAnimationOptions;\r\n }\r\n | {\r\n /** Wait for a fixed duration. */\r\n type: 'wait';\r\n /** Number of seconds to wait before continuing. */\r\n seconds: number;\r\n }\r\n | {\r\n /** Wait until a matching event is dispatched to the runner. */\r\n type: 'waitEvent';\r\n /** Event name that releases the wait. */\r\n event: string;\r\n }\r\n | {\r\n /** Wait until a playback crosses a marker. */\r\n type: 'waitMarker';\r\n /** Marker id or name to wait for. */\r\n marker: string;\r\n /** Optional playback target id; defaults to the current playback in scope. */\r\n target?: string;\r\n }\r\n | {\r\n /** Wait until a playback crosses a frame number. */\r\n type: 'waitFrame';\r\n /** Frame number to wait for. */\r\n frame: number;\r\n /** Optional playback target id; defaults to the current playback in scope. */\r\n target?: string;\r\n }\r\n | {\r\n /** Emit a timeline event through the runner. */\r\n type: 'emit';\r\n /** Event name emitted to runner listeners. */\r\n event: string;\r\n /** Optional payload emitted with the event. */\r\n payload?: unknown;\r\n }\r\n | {\r\n /** Execute child steps sequentially. */\r\n type: 'sequence';\r\n /** Child steps run in order. */\r\n steps: AnimationTimelineStep[];\r\n }\r\n | {\r\n /** Execute child steps as parallel branches. */\r\n type: 'parallel';\r\n /** Child steps that become isolated parallel branches. */\r\n steps: AnimationTimelineStep[];\r\n };\r\n\r\n/**\r\n * Serializable timeline definition.\r\n * @public\r\n */\r\nexport type AnimationTimelineDefinition = {\r\n /**\r\n * Root sequence of timeline steps.\r\n */\r\n steps: AnimationTimelineStep[];\r\n /**\r\n * Optional responses evaluated when dispatched events are not consumed by waiters.\r\n */\r\n responses?: AnimationTimelineEventResponse[];\r\n};\r\n\r\n/**\r\n * Event map emitted by {@link AnimationTimelineRunner}.\r\n * @public\r\n */\r\nexport type AnimationTimelineRunnerEventMap = {\r\n /**\r\n * Emitted when the runner drains all main, concurrent, and queued work.\r\n */\r\n complete: [runner: AnimationTimelineRunner];\r\n /**\r\n * Emitted when an active runner is explicitly stopped.\r\n */\r\n stop: [runner: AnimationTimelineRunner];\r\n /**\r\n * Emitted by an `emit` timeline step.\r\n */\r\n emit: [event: string, payload: unknown];\r\n};\r\n\r\n/**\r\n * Serializable snapshot of a runner's runtime state.\r\n *\r\n * References to playbacks are by id; restoring playbacks themselves is the caller's\r\n * responsibility (replay should re-create the active playbacks before deserializing).\r\n * @public\r\n */\r\nexport type AnimationTimelineRunnerState = {\r\n /**\r\n * Serialized main control-flow stack.\r\n */\r\n stack: SerializedFrame[];\r\n /**\r\n * Serialized concurrent branches started with `keep` responses.\r\n */\r\n concurrent: SerializedFrame[];\r\n /**\r\n * Queued step batches waiting for the main stack to drain.\r\n */\r\n queued: AnimationTimelineStep[][];\r\n /** Ids of playbacks owned by concurrent (keep-active) branches that have already drained. */\r\n concurrentPlaybackIds: string[];\r\n /**\r\n * Runner-level playback references preserved after the frame that created them has drained.\r\n */\r\n playbackRefs?: Record<string, string>;\r\n /**\r\n * Whether the runner was stopped when the state was captured.\r\n */\r\n stopped: boolean;\r\n};\r\n\r\n/**\r\n * A scope tracks the \"current playback\" and named refs for a sequence of steps. Parallel branches\r\n * each own an isolated scope so their `waitMarker`/`waitFrame` resolve deterministically.\r\n *\r\n * `owner` records whether the scope belongs to the main control flow or a concurrent (keep-active)\r\n * branch, so a main-flow replacement does not stop the independent concurrent tracks.\r\n */\r\ntype FrameScope = {\r\n currentPlaybackId: string | null;\r\n refs: Record<string, string>;\r\n owner: 'main' | 'concurrent';\r\n};\r\n\r\ntype SeqFrame = {\r\n kind: 'seq';\r\n steps: AnimationTimelineStep[];\r\n index: number;\r\n scope: FrameScope;\r\n child: TimelineFrame | null;\r\n};\r\n\r\ntype ParallelFrame = {\r\n kind: 'parallel';\r\n branches: TimelineFrame[];\r\n};\r\n\r\ntype WaitFrame = { kind: 'wait'; remaining: number };\r\ntype WaitEventFrame = { kind: 'waitEvent'; event: string };\r\ntype WaitMarkerFrame = { kind: 'waitMarker'; marker: string; playbackId: string | null; satisfied: boolean };\r\ntype WaitFrameFrame = { kind: 'waitFrame'; frame: number; playbackId: string | null; satisfied: boolean };\r\ntype PlayWaitFrame = { kind: 'playWait'; playbackId: string };\r\n\r\ntype TimelineFrame =\r\n | SeqFrame\r\n | ParallelFrame\r\n | WaitFrame\r\n | WaitEventFrame\r\n | WaitMarkerFrame\r\n | WaitFrameFrame\r\n | PlayWaitFrame;\r\n\r\n/** Plain-data form of a frame (no live playback references), used by serialize/deserialize. */\r\ntype SerializedFrame = TimelineFrame;\r\n\r\n/**\r\n * Outcome of ticking a single frame.\r\n * - `block`: the frame is still waiting; stop advancing this stack.\r\n * - `pop`: the frame finished; `leftover` (if any) is unconsumed time to carry to the next step.\r\n * - `advanced`: the frame moved its cursor or pushed a child; re-tick with zero delta.\r\n */\r\ntype TickResult = { status: 'block' | 'advanced'; leftover?: number } | { status: 'pop'; leftover?: number };\r\n\r\n/**\r\n * Serializable animation timeline definition.\r\n * @public\r\n */\r\nexport class AnimationTimeline {\r\n /**\r\n * Root step sequence executed by runners created from this timeline.\r\n */\r\n readonly steps: AnimationTimelineStep[];\r\n /**\r\n * Event responses declared on this timeline.\r\n */\r\n readonly responses: AnimationTimelineEventResponse[];\r\n\r\n /**\r\n * Create a timeline from a definition object or a root step array.\r\n *\r\n * @param definition - Timeline definition, or a shorthand array used as the root steps.\r\n */\r\n constructor(definition: AnimationTimelineDefinition | AnimationTimelineStep[]) {\r\n if (Array.isArray(definition)) {\r\n this.steps = definition;\r\n this.responses = [];\r\n } else {\r\n this.steps = definition.steps;\r\n this.responses = definition.responses ?? [];\r\n }\r\n }\r\n\r\n /**\r\n * Create a runtime runner for this timeline.\r\n *\r\n * @param animationSet - Animation set used to create and update playbacks.\r\n * @returns A new stopped runner bound to this timeline and animation set.\r\n */\r\n createRunner(animationSet: AnimationSet) {\r\n return new AnimationTimelineRunner(animationSet, this);\r\n }\r\n}\r\n\r\n/**\r\n * Runtime interpreter for an AnimationTimeline.\r\n *\r\n * The interpreter is a synchronous frame-stack state machine advanced by {@link AnimationTimelineRunner.tick}, which is\r\n * driven by `AnimationSet.update(dt)` on the same logical clock as the animations. There is no\r\n * `async`/`await` in the control flow, so the runtime state can be serialized and replayed.\r\n * @public\r\n */\r\nexport class AnimationTimelineRunner extends Observable<AnimationTimelineRunnerEventMap> {\r\n /**\r\n * Animation set used to start, stop, and query animation playbacks.\r\n */\r\n readonly animationSet: AnimationSet;\r\n /**\r\n * Timeline definition interpreted by this runner.\r\n */\r\n readonly timeline: AnimationTimeline;\r\n private _stack: TimelineFrame[];\r\n private _concurrent: TimelineFrame[];\r\n private readonly _queued: AnimationTimelineStep[][];\r\n private _pendingEvents: string[];\r\n private _stopped: boolean;\r\n private _ticking: boolean;\r\n private _lastCompletedPlaybackId: string | null;\r\n private readonly _onTick: (deltaInSeconds: number) => void;\r\n /** Tracks playbacks created by this runner so `stop()` can tear them down. */\r\n private readonly _ownedPlaybacks: Map<string, AnimationPlayback>;\r\n /** Local playback refs that survive after the sequence frame that declared them drains. */\r\n private readonly _playbackRefs: Map<string, string>;\r\n /** Ids of playbacks owned by concurrent (keep-active) branches; preserved across main-flow stops. */\r\n private readonly _concurrentPlaybackIds: Set<string>;\r\n /** Marker/frame crossings observed since the last tick, keyed by playback id. */\r\n private readonly _crossedMarkers: Map<string, Set<string>>;\r\n private readonly _crossedFrames: Map<string, Set<number>>;\r\n\r\n /**\r\n * Create a stopped runner for a timeline.\r\n *\r\n * @param animationSet - Animation set that owns clips and playbacks referenced by the timeline.\r\n * @param timeline - Timeline definition to interpret.\r\n */\r\n constructor(animationSet: AnimationSet, timeline: AnimationTimeline) {\r\n super();\r\n this.animationSet = animationSet;\r\n this.timeline = timeline;\r\n this._stack = [];\r\n this._concurrent = [];\r\n this._queued = [];\r\n this._pendingEvents = [];\r\n this._stopped = true;\r\n this._ticking = false;\r\n this._lastCompletedPlaybackId = null;\r\n this._onTick = (deltaInSeconds) => this.tick(deltaInSeconds);\r\n this._ownedPlaybacks = new Map();\r\n this._playbackRefs = new Map();\r\n this._concurrentPlaybackIds = new Set();\r\n this._crossedMarkers = new Map();\r\n this._crossedFrames = new Map();\r\n }\r\n\r\n /**\r\n * Playback currently referenced by the active main-flow scope.\r\n *\r\n * @returns The current playback, or null when the main flow has no active playback reference.\r\n */\r\n get currentPlayback() {\r\n const scope = this.activeScope();\r\n if (!scope?.currentPlaybackId) {\r\n return null;\r\n }\r\n return this._ownedPlaybacks.get(scope.currentPlaybackId) ?? null;\r\n }\r\n\r\n /**\r\n * Whether this runner is stopped.\r\n *\r\n * @returns True when the runner is stopped; otherwise false.\r\n */\r\n get stopped() {\r\n return this._stopped;\r\n }\r\n\r\n /**\r\n * Playback id for the most recent playback that completed naturally.\r\n *\r\n * @returns The playback id, or null when no owned playback has completed.\r\n */\r\n get lastCompletedPlaybackId() {\r\n return this._lastCompletedPlaybackId;\r\n }\r\n\r\n /**\r\n * Start or restart the runner from the beginning of the timeline.\r\n *\r\n * @returns This runner for chaining.\r\n */\r\n start() {\r\n this._stopped = false;\r\n this._stack = [this.makeSeqFrame(this.timeline.steps)];\r\n this._concurrent = [];\r\n this._queued.length = 0;\r\n this._pendingEvents = [];\r\n this._lastCompletedPlaybackId = null;\r\n this._playbackRefs.clear();\r\n this.animationSet._registerTimelineTicker(this._onTick);\r\n // Drain any leading non-blocking steps immediately so e.g. an initial `play` starts now.\r\n this.flush();\r\n return this;\r\n }\r\n\r\n /**\r\n * Stop the runner and all playbacks it owns.\r\n *\r\n * @param options - Optional stop behavior applied to owned playbacks.\r\n * @returns This runner for chaining.\r\n */\r\n stop(options?: StopAnimationOptions) {\r\n const wasStopped = this._stopped;\r\n this._stopped = true;\r\n this._stack = [];\r\n this._concurrent = [];\r\n this._queued.length = 0;\r\n this._pendingEvents = [];\r\n this._crossedMarkers.clear();\r\n this._crossedFrames.clear();\r\n this._lastCompletedPlaybackId = null;\r\n const stopOptions = options ?? { reason: 'interrupted' };\r\n // Always tear down owned playbacks, even if the control flow already drained: a state whose\r\n // script finished may still have a looping clip playing that a transition must stop.\r\n this._ownedPlaybacks.forEach((playback) => {\r\n this.detachPlayback(playback);\r\n playback.stop(stopOptions);\r\n });\r\n this._ownedPlaybacks.clear();\r\n this._playbackRefs.clear();\r\n this._concurrentPlaybackIds.clear();\r\n this.animationSet._unregisterTimelineTicker(this._onTick);\r\n if (!wasStopped) {\r\n this.dispatchEvent('stop', this);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Append a batch of steps to run after the main stack drains.\r\n *\r\n * If the runner has already completed, enqueueing steps revives it and registers it for ticking.\r\n *\r\n * @param steps - Steps to run as the next queued batch.\r\n * @returns void\r\n */\r\n enqueue(steps: AnimationTimelineStep[]) {\r\n if (steps.length === 0) {\r\n return;\r\n }\r\n this._queued.push(steps);\r\n // Revive a runner that already drained so queued steps are not silently dropped.\r\n if (this._stopped) {\r\n this._stopped = false;\r\n this._stack = [];\r\n this.animationSet._registerTimelineTicker(this._onTick);\r\n }\r\n this.flush();\r\n }\r\n\r\n /**\r\n * Run `steps` concurrently with the current control flow (a true parallel branch). Unlike\r\n * {@link AnimationTimelineRunner.enqueue}, these do not wait for the main stack to drain.\r\n *\r\n * @param steps - Steps to run immediately in an independent concurrent branch.\r\n * @returns void\r\n * @public\r\n */\r\n runConcurrent(steps: AnimationTimelineStep[]) {\r\n if (steps.length === 0) {\r\n return;\r\n }\r\n this._concurrent.push(this.makeSeqFrame(steps, 'concurrent'));\r\n if (this._stopped) {\r\n this._stopped = false;\r\n this.animationSet._registerTimelineTicker(this._onTick);\r\n } else {\r\n this.ensureTicking();\r\n }\r\n this.flush();\r\n }\r\n\r\n /**\r\n * Dispatch an event to this runner.\r\n *\r\n * Waiting `waitEvent` frames consume matching events first. If no waiter consumes the event,\r\n * the timeline response table is evaluated.\r\n *\r\n * @param event - Event name to dispatch.\r\n * @param payload - Optional payload returned in the result.\r\n * @returns The resolved handling result for the event.\r\n */\r\n dispatch(event: string, payload?: unknown): AnimationTimelineEventResult {\r\n // A waiting `waitEvent` frame consumes the event; flush advances past it synchronously.\r\n if (this.hasWaiterFor(event)) {\r\n this._pendingEvents.push(event);\r\n this.flush();\r\n return { handled: true, policy: 'consume', event, payload };\r\n }\r\n const response = this.timeline.responses.find((item) => item.event === event);\r\n if (!response || response.target.ignore) {\r\n return { handled: false, policy: response ? 'ignore' : 'none', event, payload };\r\n }\r\n if (response.target.consume) {\r\n return { handled: true, policy: 'consume', event, payload };\r\n }\r\n if (response.target.targetState !== undefined) {\r\n // Only the controller can switch states; bubble up so it can act on its own table.\r\n return { handled: false, policy: 'transition', event, payload };\r\n }\r\n const steps = response.target.steps;\r\n if (!steps?.length) {\r\n return { handled: false, policy: 'none', event, payload };\r\n }\r\n if (response.enqueue) {\r\n this.enqueue(steps);\r\n return { handled: true, policy: 'enqueue', event, payload };\r\n }\r\n const disposition = response.onActive ?? 'stop';\r\n if (disposition === 'keep') {\r\n // Run the new steps concurrently with the existing control flow (true parallel branch).\r\n this.runConcurrent(steps);\r\n } else {\r\n const stopOptions =\r\n typeof disposition === 'object' ? { ...disposition, reason: 'interrupted' as const } : undefined;\r\n this.stopMainFlow(stopOptions);\r\n this._stopped = false;\r\n this._stack = [this.makeSeqFrame(steps)];\r\n this.ensureTicking();\r\n this.flush();\r\n }\r\n return { handled: true, policy: 'steps', event, payload };\r\n }\r\n\r\n /**\r\n * Run pending non-blocking work synchronously (a zero-delta tick), without advancing any\r\n * time-based waits. Lets `start()`/`dispatch()` take effect immediately while keeping all\r\n * runtime state in the serializable frame stack.\r\n *\r\n * @returns This runner for chaining.\r\n * @public\r\n */\r\n flush() {\r\n // Guard against re-entrancy: an `emit` listener firing during a tick may dispatch again.\r\n if (!this._ticking) {\r\n this.tick(0);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Advance the timeline by `deltaInSeconds`. Called by `AnimationSet.update`.\r\n *\r\n * @param deltaInSeconds - Elapsed time in seconds for this tick.\r\n * @returns void\r\n * @public\r\n */\r\n tick(deltaInSeconds: number) {\r\n if (this._stopped && this._queued.length === 0) {\r\n return;\r\n }\r\n this._ticking = true;\r\n // Advance the main control-flow stack.\r\n if (this._stack.length === 0 && this._queued.length > 0) {\r\n const next = this._queued.shift()!;\r\n this._stack = [this.makeSeqFrame(next)];\r\n }\r\n if (this._stack.length > 0) {\r\n this.tickFrames(this._stack, deltaInSeconds);\r\n }\r\n // Advance any concurrent (keep-active) branches; drop the ones that finished.\r\n if (this._concurrent.length > 0) {\r\n this._concurrent = this._concurrent.filter((frame) => {\r\n const stack = [frame];\r\n this.tickFrames(stack, deltaInSeconds);\r\n return stack.length > 0;\r\n });\r\n }\r\n // Consumed this tick.\r\n this._pendingEvents = [];\r\n this._crossedMarkers.clear();\r\n this._crossedFrames.clear();\r\n this._ticking = false;\r\n // Pull queued batches once the stack drains.\r\n while (this._stack.length === 0 && this._queued.length > 0) {\r\n const next = this._queued.shift()!;\r\n this._stack = [this.makeSeqFrame(next)];\r\n this.tickFrames(this._stack, 0);\r\n }\r\n if (\r\n !this._stopped &&\r\n this._stack.length === 0 &&\r\n this._concurrent.length === 0 &&\r\n this._queued.length === 0\r\n ) {\r\n this._stopped = true;\r\n this.animationSet._unregisterTimelineTicker(this._onTick);\r\n this.dispatchEvent('complete', this);\r\n }\r\n }\r\n\r\n /**\r\n * Export the runtime state as plain data.\r\n *\r\n * @returns A serializable snapshot of the runner state.\r\n * @public\r\n */\r\n serialize(): AnimationTimelineRunnerState {\r\n return {\r\n stack: this._stack.map((frame) => this.cloneFrame(frame)),\r\n concurrent: this._concurrent.map((frame) => this.cloneFrame(frame)),\r\n queued: this._queued.map((steps) => steps.slice()),\r\n concurrentPlaybackIds: [...this._concurrentPlaybackIds],\r\n playbackRefs: Object.fromEntries(this._playbackRefs),\r\n stopped: this._stopped\r\n };\r\n }\r\n\r\n /**\r\n * Restore runtime state previously produced by {@link AnimationTimelineRunner.serialize}.\r\n *\r\n * Re-create the relevant active playbacks on the AnimationSet before calling this so that\r\n * playback-bound frames (play-wait, waitMarker, waitFrame) can re-attach by id.\r\n *\r\n * @param animationSet - Animation set containing any live playbacks referenced by the state.\r\n * @param timeline - Timeline definition to bind to the restored runner.\r\n * @param state - Serialized state previously returned by {@link AnimationTimelineRunner.serialize}.\r\n * @returns A runner restored to the supplied runtime state.\r\n * @public\r\n */\r\n static deserialize(\r\n animationSet: AnimationSet,\r\n timeline: AnimationTimeline,\r\n state: AnimationTimelineRunnerState\r\n ): AnimationTimelineRunner {\r\n const runner = new AnimationTimelineRunner(animationSet, timeline);\r\n runner._stack = state.stack.map((frame) => runner.cloneFrame(frame));\r\n runner._concurrent = state.concurrent.map((frame) => runner.cloneFrame(frame));\r\n state.queued.forEach((steps) => runner._queued.push(steps.slice()));\r\n state.concurrentPlaybackIds?.forEach((id) => runner._concurrentPlaybackIds.add(id));\r\n Object.entries(state.playbackRefs ?? {}).forEach(([ref, id]) => runner._playbackRefs.set(ref, id));\r\n runner._stopped = state.stopped;\r\n // Re-attach to any live playbacks referenced by the restored frames.\r\n runner.reattachPlaybacks(runner._stack);\r\n runner._concurrent.forEach((frame) => runner.reattachPlaybacks([frame]));\r\n // Re-attach drained concurrent playbacks tracked only by id, so they survive future stops.\r\n runner._concurrentPlaybackIds.forEach((id) => {\r\n if (!runner._ownedPlaybacks.has(id)) {\r\n const playback = runner.findLivePlayback(id);\r\n if (playback) {\r\n runner.attachPlayback(playback);\r\n }\r\n }\r\n });\r\n runner._playbackRefs.forEach((id) => {\r\n if (!runner._ownedPlaybacks.has(id)) {\r\n const playback = runner.findLivePlayback(id);\r\n if (playback) {\r\n runner.attachPlayback(playback);\r\n }\r\n }\r\n });\r\n if (!runner._stopped) {\r\n animationSet._registerTimelineTicker(runner._onTick);\r\n }\r\n return runner;\r\n }\r\n\r\n // --- internals -------------------------------------------------------------\r\n\r\n private ensureTicking() {\r\n if (!this._ticking) {\r\n this.animationSet._registerTimelineTicker(this._onTick);\r\n }\r\n }\r\n\r\n private makeSeqFrame(steps: AnimationTimelineStep[], owner: 'main' | 'concurrent' = 'main'): SeqFrame {\r\n return {\r\n kind: 'seq',\r\n steps,\r\n index: 0,\r\n scope: { currentPlaybackId: null, refs: {}, owner },\r\n child: null\r\n };\r\n }\r\n\r\n /** The scope of the innermost active sequence on the main stack (for currentPlayback). */\r\n private activeScope(): FrameScope | null {\r\n for (let i = this._stack.length - 1; i >= 0; i--) {\r\n const scope = this.deepestScope(this._stack[i]);\r\n if (scope) {\r\n return scope;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n private deepestScope(frame: TimelineFrame): FrameScope | null {\r\n if (frame.kind === 'seq') {\r\n return frame.child ? (this.deepestScope(frame.child) ?? frame.scope) : frame.scope;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Advance a frame stack in place. The top frame runs until it blocks or completes; completed\r\n * frames pop and the parent sequence advances. Returns when the stack blocks or empties.\r\n */\r\n private tickFrames(stack: TimelineFrame[], deltaInSeconds: number) {\r\n this.tickFramesWithLeftover(stack, deltaInSeconds);\r\n }\r\n\r\n /**\r\n * Same as {@link AnimationTimelineRunner.tickFrames} but returns the time left unconsumed when the stack drains\r\n * completely (so a parent sequence can hand it to its next step).\r\n */\r\n private tickFramesWithLeftover(stack: TimelineFrame[], deltaInSeconds: number): number {\r\n let guard = 0;\r\n while (stack.length > 0) {\r\n if (++guard > 10000) {\r\n // Defensive: a malformed timeline should not spin forever.\r\n break;\r\n }\r\n const frame = stack[stack.length - 1];\r\n const result = this.tickFrame(frame, stack, deltaInSeconds);\r\n if (result.status === 'block') {\r\n return 0;\r\n }\r\n if (result.status === 'pop') {\r\n stack.pop();\r\n // Carry any unused time (e.g. a `wait` that overshot its duration this tick) to the next\r\n // step so a sequence of waits/actions tracks logical time regardless of frame rate.\r\n deltaInSeconds = result.leftover ?? 0;\r\n continue;\r\n }\r\n // 'advanced': the frame pushed a child or moved its cursor; loop again with delta 0 so a\r\n // single tick can drain consecutive non-blocking steps.\r\n deltaInSeconds = 0;\r\n }\r\n return deltaInSeconds;\r\n }\r\n\r\n private tickFrame(frame: TimelineFrame, stack: TimelineFrame[], deltaInSeconds: number): TickResult {\r\n switch (frame.kind) {\r\n case 'seq':\r\n return this.tickSeq(frame, stack, deltaInSeconds);\r\n case 'parallel':\r\n return this.tickParallel(frame, deltaInSeconds);\r\n case 'wait':\r\n frame.remaining -= deltaInSeconds;\r\n // On completion, hand back the overshoot (negative remaining) as leftover time.\r\n return frame.remaining <= 0 ? { status: 'pop', leftover: -frame.remaining } : { status: 'block' };\r\n case 'waitEvent':\r\n return this._pendingEvents.includes(frame.event) ? { status: 'pop' } : { status: 'block' };\r\n case 'waitMarker':\r\n return this.tickWaitMarker(frame);\r\n case 'waitFrame':\r\n return this.tickWaitFrame(frame);\r\n case 'playWait':\r\n return this.tickPlayWait(frame);\r\n }\r\n }\r\n\r\n private tickSeq(frame: SeqFrame, _stack: TimelineFrame[], deltaInSeconds: number): TickResult {\r\n // Drain steps in a loop so unconsumed time (e.g. a `wait` that overshot) flows into the next\r\n // step within the same tick instead of being dropped.\r\n let guard = 0;\r\n for (;;) {\r\n if (++guard > 10000) {\r\n return { status: 'block' };\r\n }\r\n if (frame.child) {\r\n const childStack = [frame.child];\r\n const leftover = this.tickFramesWithLeftover(childStack, deltaInSeconds);\r\n if (childStack.length > 0) {\r\n return { status: 'block' };\r\n }\r\n frame.child = null;\r\n frame.index++;\r\n deltaInSeconds = leftover;\r\n }\r\n if (frame.index >= frame.steps.length) {\r\n return { status: 'pop', leftover: deltaInSeconds };\r\n }\r\n const step = frame.steps[frame.index];\r\n const blocking = this.beginStep(step, frame);\r\n if (blocking) {\r\n // Tick the freshly-pushed child immediately with the carried time on the next loop turn.\r\n frame.child = blocking;\r\n continue;\r\n }\r\n frame.index++;\r\n // A non-blocking step consumes no time; keep the remaining delta for the following step.\r\n }\r\n }\r\n\r\n private tickParallel(frame: ParallelFrame, deltaInSeconds: number): TickResult {\r\n frame.branches = frame.branches.filter((branch) => {\r\n const branchStack = [branch];\r\n this.tickFrames(branchStack, deltaInSeconds);\r\n return branchStack.length > 0;\r\n });\r\n // Parallel branches may finish at different times; we do not attempt to reconcile a single\r\n // leftover across them, so the join simply consumes the whole tick.\r\n return frame.branches.length > 0 ? { status: 'block' } : { status: 'pop' };\r\n }\r\n\r\n /**\r\n * Execute a non-blocking step immediately and return null, or return a frame to block on.\r\n */\r\n private beginStep(step: AnimationTimelineStep, scopeFrame: SeqFrame): TimelineFrame | null {\r\n const scope = scopeFrame.scope;\r\n switch (step.type) {\r\n case 'sequence': {\r\n const child = this.makeSeqFrame(step.steps);\r\n // Inherit the parent scope so refs/currentPlayback carry into the nested sequence.\r\n child.scope = scope;\r\n return child;\r\n }\r\n case 'parallel': {\r\n // Each branch gets an isolated scope so currentPlayback/refs don't race (#7), but inherits\r\n // the parent's owner so concurrent branches stay concurrent through nested parallels.\r\n const branches = step.steps.map((child) => {\r\n const branchScope: FrameScope = {\r\n currentPlaybackId: scope.currentPlaybackId,\r\n refs: { ...scope.refs },\r\n owner: scope.owner\r\n };\r\n const seq = this.makeSeqFrame([child]);\r\n seq.scope = branchScope;\r\n return seq as TimelineFrame;\r\n });\r\n return { kind: 'parallel', branches };\r\n }\r\n case 'play': {\r\n const playback = this.animationSet.play(step.clip, this.resolvePlayOptions(step.options, scope));\r\n if (!playback) {\r\n return null;\r\n }\r\n this.attachPlayback(playback);\r\n if (scope.owner === 'concurrent') {\r\n // Remember concurrent ownership independently of the frames: a non-blocking keep-active\r\n // play drains out of `_concurrent` immediately, but its playback must still survive a\r\n // later main-flow replacement (#2).\r\n this._concurrentPlaybackIds.add(playback.id);\r\n }\r\n scope.currentPlaybackId = playback.id;\r\n if (step.id) {\r\n scope.refs[step.id] = playback.id;\r\n this._playbackRefs.set(step.id, playback.id);\r\n }\r\n scope.refs[playback.id] = playback.id;\r\n this._playbackRefs.set(playback.id, playback.id);\r\n if (step.wait === 'complete') {\r\n return { kind: 'playWait', playbackId: playback.id };\r\n }\r\n return null;\r\n }\r\n case 'stop': {\r\n const playback = this.resolvePlayback(step.target, scope);\r\n if (playback) {\r\n playback.stop(step.options);\r\n } else if (!step.target) {\r\n this._ownedPlaybacks.forEach((item) => item.stop(step.options));\r\n }\r\n return null;\r\n }\r\n case 'wait':\r\n return step.seconds > 0 ? { kind: 'wait', remaining: step.seconds } : null;\r\n case 'waitEvent':\r\n return { kind: 'waitEvent', event: step.event };\r\n case 'waitMarker': {\r\n const playback = this.resolvePlayback(step.target, scope) ?? this.scopeCurrentPlayback(scope);\r\n if (!playback) {\r\n return null;\r\n }\r\n return { kind: 'waitMarker', marker: step.marker, playbackId: playback.id, satisfied: false };\r\n }\r\n case 'waitFrame': {\r\n const playback = this.resolvePlayback(step.target, scope) ?? this.scopeCurrentPlayback(scope);\r\n if (!playback) {\r\n return null;\r\n }\r\n return { kind: 'waitFrame', frame: step.frame, playbackId: playback.id, satisfied: false };\r\n }\r\n case 'emit':\r\n this.dispatchEvent('emit', step.event, step.payload);\r\n return null;\r\n }\r\n }\r\n\r\n private resolvePlayOptions(options: PlayAnimationOptions | undefined, scope: FrameScope) {\r\n const target = options?.sync?.target;\r\n if (!target) {\r\n return options;\r\n }\r\n const mapped = this.resolvePlaybackRef(target, scope);\r\n if (!mapped) {\r\n return options;\r\n }\r\n return {\r\n ...options,\r\n sync: {\r\n ...options.sync,\r\n target: mapped\r\n }\r\n };\r\n }\r\n\r\n private resolvePlaybackRef(target: string, scope: FrameScope): string | null {\r\n return scope.refs[target] ?? this._playbackRefs.get(target) ?? null;\r\n }\r\n\r\n private tickWaitMarker(frame: WaitMarkerFrame): TickResult {\r\n if (frame.satisfied || !frame.playbackId) {\r\n return { status: 'pop' };\r\n }\r\n const playback = this._ownedPlaybacks.get(frame.playbackId);\r\n if (!playback || playback.state === 'stopped' || playback.state === 'completed') {\r\n return { status: 'pop' };\r\n }\r\n const crossed = this._crossedMarkers.get(frame.playbackId);\r\n if (crossed && crossed.has(frame.marker)) {\r\n return { status: 'pop' };\r\n }\r\n return { status: 'block' };\r\n }\r\n\r\n private tickWaitFrame(frame: WaitFrameFrame): TickResult {\r\n if (frame.satisfied || frame.playbackId === null) {\r\n return { status: 'pop' };\r\n }\r\n const playback = this._ownedPlaybacks.get(frame.playbackId);\r\n if (!playback || playback.state === 'stopped' || playback.state === 'completed') {\r\n return { status: 'pop' };\r\n }\r\n const crossed = this._crossedFrames.get(frame.playbackId);\r\n if (crossed && crossed.has(frame.frame)) {\r\n return { status: 'pop' };\r\n }\r\n return { status: 'block' };\r\n }\r\n\r\n private tickPlayWait(frame: PlayWaitFrame): TickResult {\r\n const playback = this._ownedPlaybacks.get(frame.playbackId);\r\n if (!playback || playback.state === 'stopped' || playback.state === 'completed') {\r\n return { status: 'pop' };\r\n }\r\n return { status: 'block' };\r\n }\r\n\r\n private attachPlayback(playback: AnimationPlayback) {\r\n this._ownedPlaybacks.set(playback.id, playback);\r\n playback.on('marker', this.onPlaybackMarker);\r\n playback.on('frame', this.onPlaybackFrame);\r\n playback.on('stop', this.onPlaybackEnd);\r\n playback.on('complete', this.onPlaybackComplete);\r\n }\r\n\r\n private detachPlayback(playback: AnimationPlayback) {\r\n playback.off('marker', this.onPlaybackMarker);\r\n playback.off('frame', this.onPlaybackFrame);\r\n playback.off('stop', this.onPlaybackEnd);\r\n playback.off('complete', this.onPlaybackComplete);\r\n }\r\n\r\n private forgetPlayback(playback: AnimationPlayback) {\r\n this.detachPlayback(playback);\r\n this._ownedPlaybacks.delete(playback.id);\r\n this._concurrentPlaybackIds.delete(playback.id);\r\n this.forgetPlaybackRefs(playback.id);\r\n }\r\n\r\n /**\r\n * Cleanup when an owned playback ends (externally or naturally). Only touches runner-local\r\n * bookkeeping, so it is safe to run inside `AnimationSet.update`'s playback loop. Frames blocked\r\n * on this playback observe its absence on the next tick and unblock.\r\n */\r\n private readonly onPlaybackEnd = (event: { playback: AnimationPlayback }) => {\r\n const playback = this._ownedPlaybacks.get(event.playback.id);\r\n if (playback) {\r\n this.forgetPlayback(playback);\r\n }\r\n };\r\n\r\n private readonly onPlaybackComplete = (event: { playback: AnimationPlayback }) => {\r\n this._lastCompletedPlaybackId = event.playback.id;\r\n const playback = this._ownedPlaybacks.get(event.playback.id);\r\n if (playback) {\r\n this.forgetPlayback(playback);\r\n }\r\n };\r\n\r\n private readonly onPlaybackMarker = (event: AnimationMarkerEvent) => {\r\n const id = event.playback.id;\r\n let set = this._crossedMarkers.get(id);\r\n if (!set) {\r\n set = new Set();\r\n this._crossedMarkers.set(id, set);\r\n }\r\n if (event.marker.id !== undefined) {\r\n set.add(event.marker.id);\r\n }\r\n set.add(event.marker.name);\r\n };\r\n\r\n private readonly onPlaybackFrame = (event: AnimationFrameEvent) => {\r\n const id = event.playback.id;\r\n let set = this._crossedFrames.get(id);\r\n if (!set) {\r\n set = new Set();\r\n this._crossedFrames.set(id, set);\r\n }\r\n set.add(event.frame);\r\n };\r\n\r\n private resolvePlayback(target: string | undefined, scope: FrameScope): AnimationPlayback | null {\r\n if (!target) {\r\n return null;\r\n }\r\n const mapped = this.resolvePlaybackRef(target, scope);\r\n if (mapped) {\r\n const owned = this._ownedPlaybacks.get(mapped);\r\n if (owned) {\r\n return owned;\r\n }\r\n }\r\n return this._ownedPlaybacks.get(target) ?? this.animationSet.getPlayback(target);\r\n }\r\n\r\n private forgetPlaybackRefs(playbackId: string) {\r\n [...this._playbackRefs.entries()].forEach(([ref, id]) => {\r\n if (id === playbackId) {\r\n this._playbackRefs.delete(ref);\r\n }\r\n });\r\n }\r\n\r\n private scopeCurrentPlayback(scope: FrameScope): AnimationPlayback | null {\r\n return scope.currentPlaybackId ? (this._ownedPlaybacks.get(scope.currentPlaybackId) ?? null) : null;\r\n }\r\n\r\n private hasWaiterFor(event: string): boolean {\r\n const inFrame = (frame: TimelineFrame): boolean => {\r\n switch (frame.kind) {\r\n case 'waitEvent':\r\n return frame.event === event;\r\n case 'seq':\r\n return frame.child ? inFrame(frame.child) : false;\r\n case 'parallel':\r\n return frame.branches.some(inFrame);\r\n default:\r\n return false;\r\n }\r\n };\r\n return this._stack.some(inFrame) || this._concurrent.some(inFrame);\r\n }\r\n\r\n /** Stop only the main control flow (used when a response replaces it). */\r\n private stopMainFlow(options?: StopAnimationOptions) {\r\n const stopOptions = options ?? { reason: 'interrupted' };\r\n // Stop every playback owned by the main flow, not just those still referenced by `_stack`:\r\n // a sequence that already drained may have left a looping clip playing (e.g. `play idle` with\r\n // `repeat: 0`), and replacing the main flow must stop it. Playbacks owned by concurrent\r\n // (keep-active) branches are independent parallel tracks and are preserved — tracked by id so\r\n // they survive even after their branch frames drained.\r\n this._ownedPlaybacks.forEach((playback, id) => {\r\n if (this._concurrentPlaybackIds.has(id)) {\r\n return;\r\n }\r\n this.detachPlayback(playback);\r\n playback.stop(stopOptions);\r\n this._ownedPlaybacks.delete(id);\r\n this.forgetPlaybackRefs(id);\r\n });\r\n this._stack = [];\r\n }\r\n\r\n private collectScopePlaybackIds(frames: TimelineFrame[]): Set<string> {\r\n const ids = new Set<string>();\r\n const visit = (frame: TimelineFrame) => {\r\n if (frame.kind === 'seq') {\r\n Object.values(frame.scope.refs).forEach((id) => ids.add(id));\r\n if (frame.scope.currentPlaybackId) {\r\n ids.add(frame.scope.currentPlaybackId);\r\n }\r\n if (frame.child) {\r\n visit(frame.child);\r\n }\r\n } else if (frame.kind === 'parallel') {\r\n frame.branches.forEach(visit);\r\n }\r\n };\r\n frames.forEach(visit);\r\n return ids;\r\n }\r\n\r\n private cloneFrame(frame: TimelineFrame): TimelineFrame {\r\n switch (frame.kind) {\r\n case 'seq':\r\n return {\r\n kind: 'seq',\r\n steps: frame.steps,\r\n index: frame.index,\r\n scope: {\r\n currentPlaybackId: frame.scope.currentPlaybackId,\r\n refs: { ...frame.scope.refs },\r\n owner: frame.scope.owner\r\n },\r\n child: frame.child ? this.cloneFrame(frame.child) : null\r\n };\r\n case 'parallel':\r\n return { kind: 'parallel', branches: frame.branches.map((b) => this.cloneFrame(b)) };\r\n case 'wait':\r\n return { kind: 'wait', remaining: frame.remaining };\r\n case 'waitEvent':\r\n return { kind: 'waitEvent', event: frame.event };\r\n case 'waitMarker':\r\n return { ...frame };\r\n case 'waitFrame':\r\n return { ...frame };\r\n case 'playWait':\r\n return { ...frame };\r\n }\r\n }\r\n\r\n private reattachPlaybacks(frames: TimelineFrame[]) {\r\n const ids = this.collectAllPlaybackIds(frames);\r\n ids.forEach((id) => {\r\n if (this._ownedPlaybacks.has(id)) {\r\n return;\r\n }\r\n const playback = this.findLivePlayback(id);\r\n if (playback) {\r\n this.attachPlayback(playback);\r\n }\r\n });\r\n }\r\n\r\n private collectAllPlaybackIds(frames: TimelineFrame[]): Set<string> {\r\n const ids = this.collectScopePlaybackIds(frames);\r\n const visit = (frame: TimelineFrame) => {\r\n if (frame.kind === 'playWait') {\r\n ids.add(frame.playbackId);\r\n } else if ((frame.kind === 'waitMarker' || frame.kind === 'waitFrame') && frame.playbackId) {\r\n ids.add(frame.playbackId);\r\n } else if (frame.kind === 'seq' && frame.child) {\r\n visit(frame.child);\r\n } else if (frame.kind === 'parallel') {\r\n frame.branches.forEach(visit);\r\n }\r\n };\r\n frames.forEach(visit);\r\n return ids;\r\n }\r\n\r\n private findLivePlayback(id: string): AnimationPlayback | null {\r\n return this.animationSet.getPlaybacks().find((playback) => playback.id === id) ?? null;\r\n }\r\n}\r\n"],"names":["AnimationTimeline","definition","Array","isArray","steps","responses","createRunner","animationSet","AnimationTimelineRunner","Observable","_stack","_concurrent","_queued","_pendingEvents","_stopped","_ticking","_lastCompletedPlaybackId","_onTick","_crossedFrames","timeline","deltaInSeconds","tick","_ownedPlaybacks","Map","_playbackRefs","_concurrentPlaybackIds","Set","_crossedMarkers","currentPlayback","scope","activeScope","currentPlaybackId","get","stopped","lastCompletedPlaybackId","start","makeSeqFrame","length","clear","_registerTimelineTicker","flush","stop","options","wasStopped","stopOptions","reason","forEach","playback","detachPlayback","_unregisterTimelineTicker","dispatchEvent","enqueue","push","runConcurrent","ensureTicking","dispatch","event","payload","hasWaiterFor","handled","policy","response","find","item","target","ignore","consume","targetState","undefined","disposition","onActive","stopMainFlow","next","shift","tickFrames","filter","frame","stack","serialize","map","cloneFrame","concurrent","queued","slice","concurrentPlaybackIds","playbackRefs","Object","fromEntries","deserialize","state","runner","id","add","entries","ref","set","reattachPlaybacks","has","findLivePlayback","attachPlayback","owner","kind","index","refs","child","i","deepestScope","tickFramesWithLeftover","guard","result","tickFrame","status","pop","leftover","tickSeq","tickParallel","remaining","includes","tickWaitMarker","tickWaitFrame","tickPlayWait","childStack","step","blocking","beginStep","branches","branch","branchStack","scopeFrame","type","branchScope","seq","play","clip","resolvePlayOptions","wait","playbackId","resolvePlayback","seconds","scopeCurrentPlayback","marker","satisfied","sync","mapped","resolvePlaybackRef","crossed","on","onPlaybackMarker","onPlaybackFrame","onPlaybackEnd","onPlaybackComplete","off","forgetPlayback","delete","forgetPlaybackRefs","name","owned","getPlayback","inFrame","some","collectScopePlaybackIds","frames","ids","visit","values","b","collectAllPlaybackIds","getPlaybacks"],"mappings":"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"}
@@ -0,0 +1,320 @@
1
+ import { Matrix4x4, Vector3 } from '@zephyr3d/base';
2
+ import { getVertexFormatComponentCount } from '@zephyr3d/device';
3
+ import '../../scene/scene.js';
4
+ import '../../values.js';
5
+ import '../../render/render_queue.js';
6
+ import '../../render/primitive.js';
7
+ import '../../material/shader/helper.js';
8
+ import '../../material/lambert.js';
9
+ import '../../material/blinn.js';
10
+ import '../../material/unlit.js';
11
+ import '../../material/particle.js';
12
+ import '../../material/subsurfaceprofile.js';
13
+ import '../../material/meshmaterial.js';
14
+ import '../../material/grassmaterial.js';
15
+ import '../../material/terrain-cm.js';
16
+ import '../../material/pbrmr.js';
17
+ import '../../material/pbrsg.js';
18
+ import '../../material/mtoon.js';
19
+ import '../../material/pbrblueprint.js';
20
+ import '../../material/sprite.js';
21
+ import '../../material/sprite_std.js';
22
+ import '../../utility/blueprint/material/texture.js';
23
+ import '../../render/rendergraph/forward_plus_builder.js';
24
+ import '../../render/lightpass.js';
25
+ import '../../render/sky.js';
26
+ import '../../render/clipmap.js';
27
+ import '../../shaders/atmosphere.js';
28
+ import { getSceneMeshAssetBinding } from '../../scene/scene_node.js';
29
+ import '../../shadow/shadowmapper.js';
30
+ import '../../scene/mesh.js';
31
+ import '../../scene/basesprite.js';
32
+ import '../../scene/meshdrawable.js';
33
+ import '../../material/msdf_text.js';
34
+ import '../../scene/water.js';
35
+ import '../../scene/particlesys.js';
36
+ import '../../scene/batchgroup.js';
37
+ import '../../scene/terrain-cm/terrain-cm.js';
38
+ import '../../scene/terrain-cm/grass.js';
39
+ import '../../scene/raycast_visitor.js';
40
+ import { ColliderForce } from './types.js';
41
+
42
+ const EPS = 1e-6;
43
+ /**
44
+ * Generate convex JointDynamics colliders from skinned mesh bone weights.
45
+ *
46
+ * @public
47
+ */ function generateJointDynamicsConvexCollidersFromSkinWeights(meshes, skinBinding, bones, options = {}) {
48
+ const sources = collectSourcePrimitives(meshes);
49
+ const results = [];
50
+ for (const bone of bones){
51
+ const jointIndex = skinBinding.joints.indexOf(bone);
52
+ if (jointIndex < 0) {
53
+ continue;
54
+ }
55
+ const points = collectBonePoints(sources, skinBinding, jointIndex, options);
56
+ if (points.length < (options.minVertexCount ?? 8)) {
57
+ continue;
58
+ }
59
+ const hull = buildConvexHull(points, options.maxHullVertices ?? 48, options.margin ?? 0);
60
+ if (!hull || hull.vertices.length < 4 || hull.planes.length < 4) {
61
+ continue;
62
+ }
63
+ results.push({
64
+ bone,
65
+ vertexCount: points.length,
66
+ hullVertexCount: hull.vertices.length,
67
+ collider: {
68
+ radius: 0,
69
+ radiusTailScale: 1,
70
+ height: 0,
71
+ friction: options.friction ?? 0,
72
+ isInverseCollider: options.inversed ?? false,
73
+ forceType: ColliderForce.Off,
74
+ convex: hull
75
+ }
76
+ });
77
+ }
78
+ return results;
79
+ }
80
+ function collectSourcePrimitives(meshes) {
81
+ const result = [];
82
+ const seen = new Set();
83
+ for (const mesh of meshes){
84
+ const binding = getSceneMeshAssetBinding(mesh);
85
+ const subMesh = binding?.subMesh;
86
+ const primitive = subMesh?.primitive ?? null;
87
+ if (primitive && !seen.has(primitive)) {
88
+ seen.add(primitive);
89
+ result.push({
90
+ primitive,
91
+ subMesh
92
+ });
93
+ }
94
+ }
95
+ return result;
96
+ }
97
+ function collectBonePoints(sources, skinBinding, jointIndex, options) {
98
+ const points = [];
99
+ const weightThreshold = options.weightThreshold ?? 0.45;
100
+ const dominantBoneOnly = options.dominantBoneOnly ?? true;
101
+ const inverseBind = skinBinding.inverseBindMatrices[jointIndex] ?? Matrix4x4.identity();
102
+ for (const source of sources){
103
+ const primitive = source.primitive;
104
+ const positionInfo = primitive.vertices.position;
105
+ const blendIndexInfo = primitive.vertices.blendIndices;
106
+ const blendWeightInfo = primitive.vertices.blendWeights;
107
+ if (!positionInfo || !blendIndexInfo || !blendWeightInfo) {
108
+ continue;
109
+ }
110
+ const positions = positionInfo.data;
111
+ const blendIndices = blendIndexInfo.data;
112
+ const blendWeights = blendWeightInfo.data;
113
+ const posStride = getVertexFormatComponentCount(positionInfo.format);
114
+ const idxStride = getVertexFormatComponentCount(blendIndexInfo.format);
115
+ const weightStride = getVertexFormatComponentCount(blendWeightInfo.format);
116
+ const vertexCount = Math.floor(positions.length / posStride);
117
+ for(let i = 0; i < vertexCount; i++){
118
+ let weight = 0;
119
+ let maxWeight = -1;
120
+ let maxJoint = -1;
121
+ const influenceCount = Math.min(4, idxStride, weightStride);
122
+ for(let k = 0; k < influenceCount; k++){
123
+ const idx = Number(blendIndices[i * idxStride + k]) | 0;
124
+ const w = Number(blendWeights[i * weightStride + k]) || 0;
125
+ if (idx === jointIndex) {
126
+ weight = Math.max(weight, w);
127
+ }
128
+ if (w > maxWeight) {
129
+ maxWeight = w;
130
+ maxJoint = idx;
131
+ }
132
+ }
133
+ if (weight < weightThreshold || dominantBoneOnly && maxJoint !== jointIndex) {
134
+ continue;
135
+ }
136
+ const p = new Vector3(Number(positions[i * posStride]) || 0, Number(positions[i * posStride + 1]) || 0, Number(positions[i * posStride + 2]) || 0);
137
+ points.push(inverseBind.transformPointAffine(p, p));
138
+ }
139
+ }
140
+ return uniquePoints(points);
141
+ }
142
+ function uniquePoints(points) {
143
+ const result = [];
144
+ const keys = new Set();
145
+ for (const point of points){
146
+ const key = `${Math.round(point.x * 100000)}:${Math.round(point.y * 100000)}:${Math.round(point.z * 100000)}`;
147
+ if (!keys.has(key)) {
148
+ keys.add(key);
149
+ result.push(point);
150
+ }
151
+ }
152
+ return result;
153
+ }
154
+ function buildConvexHull(points, maxHullVertices, margin) {
155
+ const sampled = sampleSupportPoints(points, Math.max(8, maxHullVertices));
156
+ if (sampled.length < 4) {
157
+ return null;
158
+ }
159
+ const faces = bruteForceHullFaces(sampled);
160
+ if (faces.length < 4) {
161
+ return null;
162
+ }
163
+ const planes = mergePlanes(faces);
164
+ if (margin > 0) {
165
+ for (const plane of planes){
166
+ plane.distance -= margin;
167
+ }
168
+ }
169
+ return {
170
+ vertices: sampled.map((point)=>point.clone()),
171
+ planes,
172
+ edges: extractHullEdges(sampled, planes)
173
+ };
174
+ }
175
+ function sampleSupportPoints(points, maxCount) {
176
+ if (points.length <= maxCount) {
177
+ return [
178
+ ...points
179
+ ];
180
+ }
181
+ const dirs = buildSampleDirections(maxCount);
182
+ const selected = [];
183
+ const indices = new Set();
184
+ for (const dir of dirs){
185
+ let bestIndex = -1;
186
+ let bestDot = -Infinity;
187
+ for(let i = 0; i < points.length; i++){
188
+ const d = Vector3.dot(points[i], dir);
189
+ if (d > bestDot) {
190
+ bestDot = d;
191
+ bestIndex = i;
192
+ }
193
+ }
194
+ if (bestIndex >= 0 && !indices.has(bestIndex)) {
195
+ indices.add(bestIndex);
196
+ selected.push(points[bestIndex]);
197
+ if (selected.length >= maxCount) {
198
+ break;
199
+ }
200
+ }
201
+ }
202
+ return selected.length >= 4 ? selected : [
203
+ ...points.slice(0, maxCount)
204
+ ];
205
+ }
206
+ function buildSampleDirections(maxCount) {
207
+ const dirs = [
208
+ new Vector3(1, 0, 0),
209
+ new Vector3(-1, 0, 0),
210
+ new Vector3(0, 1, 0),
211
+ new Vector3(0, -1, 0),
212
+ new Vector3(0, 0, 1),
213
+ new Vector3(0, 0, -1)
214
+ ];
215
+ const rings = Math.max(4, Math.ceil(Math.sqrt(maxCount)));
216
+ for(let y = 0; y < rings && dirs.length < maxCount; y++){
217
+ const v = rings === 1 ? 0 : -1 + 2 * y / (rings - 1);
218
+ const r = Math.sqrt(Math.max(0, 1 - v * v));
219
+ for(let x = 0; x < rings * 2 && dirs.length < maxCount; x++){
220
+ const a = x / (rings * 2) * Math.PI * 2;
221
+ dirs.push(new Vector3(Math.cos(a) * r, v, Math.sin(a) * r));
222
+ }
223
+ }
224
+ return dirs;
225
+ }
226
+ function bruteForceHullFaces(points) {
227
+ const center = new Vector3();
228
+ for (const point of points){
229
+ Vector3.add(center, point, center);
230
+ }
231
+ Vector3.scale(center, 1 / points.length, center);
232
+ const faces = [];
233
+ const faceKeys = new Set();
234
+ for(let i = 0; i < points.length - 2; i++){
235
+ for(let j = i + 1; j < points.length - 1; j++){
236
+ for(let k = j + 1; k < points.length; k++){
237
+ const ab = Vector3.sub(points[j], points[i]);
238
+ const ac = Vector3.sub(points[k], points[i]);
239
+ const normal = Vector3.cross(ab, ac);
240
+ const len = normal.magnitude;
241
+ if (len <= EPS) {
242
+ continue;
243
+ }
244
+ Vector3.scale(normal, 1 / len, normal);
245
+ let distance = -Vector3.dot(normal, points[i]);
246
+ if (Vector3.dot(normal, center) + distance > 0) {
247
+ Vector3.scale(normal, -1, normal);
248
+ distance = -Vector3.dot(normal, points[i]);
249
+ }
250
+ let valid = true;
251
+ for(let p = 0; p < points.length; p++){
252
+ if (p === i || p === j || p === k) {
253
+ continue;
254
+ }
255
+ if (Vector3.dot(normal, points[p]) + distance > 1e-5) {
256
+ valid = false;
257
+ break;
258
+ }
259
+ }
260
+ if (!valid) {
261
+ continue;
262
+ }
263
+ const key = planeKey(normal, distance);
264
+ if (faceKeys.has(key)) {
265
+ continue;
266
+ }
267
+ faceKeys.add(key);
268
+ faces.push({
269
+ a: i,
270
+ b: j,
271
+ c: k,
272
+ normal: normal.clone(),
273
+ distance
274
+ });
275
+ }
276
+ }
277
+ }
278
+ return faces;
279
+ }
280
+ function mergePlanes(faces) {
281
+ const planes = [];
282
+ for (const face of faces){
283
+ if (planes.some((plane)=>Math.abs(Vector3.dot(plane.normal, face.normal) - 1) < 1e-4 && Math.abs(plane.distance - face.distance) < 1e-4)) {
284
+ continue;
285
+ }
286
+ planes.push({
287
+ normal: face.normal.clone(),
288
+ distance: face.distance
289
+ });
290
+ }
291
+ return planes;
292
+ }
293
+ function extractHullEdges(vertices, planes) {
294
+ const result = [];
295
+ const keys = new Set();
296
+ for(let i = 0; i < vertices.length - 1; i++){
297
+ for(let j = i + 1; j < vertices.length; j++){
298
+ const sharedPlaneCount = planes.reduce((count, plane)=>{
299
+ const di = Math.abs(Vector3.dot(plane.normal, vertices[i]) + plane.distance);
300
+ const dj = Math.abs(Vector3.dot(plane.normal, vertices[j]) + plane.distance);
301
+ return count + (di < 1e-4 && dj < 1e-4 ? 1 : 0);
302
+ }, 0);
303
+ if (sharedPlaneCount < 2) {
304
+ continue;
305
+ }
306
+ const key = `${i}:${j}`;
307
+ if (!keys.has(key)) {
308
+ keys.add(key);
309
+ result.push(i, j);
310
+ }
311
+ }
312
+ }
313
+ return result;
314
+ }
315
+ function planeKey(normal, distance) {
316
+ return `${Math.round(normal.x * 10000)}:${Math.round(normal.y * 10000)}:${Math.round(normal.z * 10000)}:${Math.round(distance * 10000)}`;
317
+ }
318
+
319
+ export { generateJointDynamicsConvexCollidersFromSkinWeights };
320
+ //# sourceMappingURL=convex_collider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convex_collider.js","sources":["../../../src/animation/joint_dynamics/convex_collider.ts"],"sourcesContent":["import { Matrix4x4, Vector3 } from '@zephyr3d/base';\nimport { getVertexFormatComponentCount } from '@zephyr3d/device';\nimport type { Mesh, SceneNode } from '../../scene';\nimport { getSceneMeshAssetBinding } from '../../scene';\nimport type { AssetPrimitiveInfo, AssetSubMeshData } from '../../asset';\nimport type { SkinBinding } from '../skeleton';\nimport { ColliderForce, type ColliderR, type ConvexColliderPlane } from './types';\n\n/** @public */\nexport type JointDynamicsConvexColliderGenerationOptions = {\n weightThreshold?: number;\n dominantBoneOnly?: boolean;\n maxHullVertices?: number;\n margin?: number;\n minVertexCount?: number;\n friction?: number;\n inversed?: boolean;\n};\n\n/** @public */\nexport type JointDynamicsConvexColliderGenerationResult = {\n bone: SceneNode;\n collider: ColliderR;\n vertexCount: number;\n hullVertexCount: number;\n};\n\ntype SourcePrimitive = {\n primitive: AssetPrimitiveInfo;\n subMesh?: AssetSubMeshData;\n};\n\ntype Face = {\n a: number;\n b: number;\n c: number;\n normal: Vector3;\n distance: number;\n};\n\nconst EPS = 1e-6;\n\n/**\n * Generate convex JointDynamics colliders from skinned mesh bone weights.\n *\n * @public\n */\nexport function generateJointDynamicsConvexCollidersFromSkinWeights(\n meshes: readonly Mesh[],\n skinBinding: SkinBinding,\n bones: readonly SceneNode[],\n options: JointDynamicsConvexColliderGenerationOptions = {}\n): JointDynamicsConvexColliderGenerationResult[] {\n const sources = collectSourcePrimitives(meshes);\n const results: JointDynamicsConvexColliderGenerationResult[] = [];\n for (const bone of bones) {\n const jointIndex = skinBinding.joints.indexOf(bone);\n if (jointIndex < 0) {\n continue;\n }\n const points = collectBonePoints(sources, skinBinding, jointIndex, options);\n if (points.length < (options.minVertexCount ?? 8)) {\n continue;\n }\n const hull = buildConvexHull(points, options.maxHullVertices ?? 48, options.margin ?? 0);\n if (!hull || hull.vertices.length < 4 || hull.planes.length < 4) {\n continue;\n }\n results.push({\n bone,\n vertexCount: points.length,\n hullVertexCount: hull.vertices.length,\n collider: {\n radius: 0,\n radiusTailScale: 1,\n height: 0,\n friction: options.friction ?? 0,\n isInverseCollider: options.inversed ?? false,\n forceType: ColliderForce.Off,\n convex: hull\n }\n });\n }\n return results;\n}\n\nfunction collectSourcePrimitives(meshes: readonly Mesh[]): SourcePrimitive[] {\n const result: SourcePrimitive[] = [];\n const seen = new Set<AssetPrimitiveInfo>();\n for (const mesh of meshes) {\n const binding = getSceneMeshAssetBinding(mesh);\n const subMesh = binding?.subMesh as AssetSubMeshData | undefined;\n const primitive = subMesh?.primitive ?? null;\n if (primitive && !seen.has(primitive)) {\n seen.add(primitive);\n result.push({ primitive, subMesh });\n }\n }\n return result;\n}\n\nfunction collectBonePoints(\n sources: readonly SourcePrimitive[],\n skinBinding: SkinBinding,\n jointIndex: number,\n options: JointDynamicsConvexColliderGenerationOptions\n): Vector3[] {\n const points: Vector3[] = [];\n const weightThreshold = options.weightThreshold ?? 0.45;\n const dominantBoneOnly = options.dominantBoneOnly ?? true;\n const inverseBind = skinBinding.inverseBindMatrices[jointIndex] ?? Matrix4x4.identity();\n for (const source of sources) {\n const primitive = source.primitive;\n const positionInfo = primitive.vertices.position;\n const blendIndexInfo = primitive.vertices.blendIndices;\n const blendWeightInfo = primitive.vertices.blendWeights;\n if (!positionInfo || !blendIndexInfo || !blendWeightInfo) {\n continue;\n }\n const positions = positionInfo.data;\n const blendIndices = blendIndexInfo.data;\n const blendWeights = blendWeightInfo.data;\n const posStride = getVertexFormatComponentCount(positionInfo.format);\n const idxStride = getVertexFormatComponentCount(blendIndexInfo.format);\n const weightStride = getVertexFormatComponentCount(blendWeightInfo.format);\n const vertexCount = Math.floor(positions.length / posStride);\n for (let i = 0; i < vertexCount; i++) {\n let weight = 0;\n let maxWeight = -1;\n let maxJoint = -1;\n const influenceCount = Math.min(4, idxStride, weightStride);\n for (let k = 0; k < influenceCount; k++) {\n const idx = Number(blendIndices[i * idxStride + k]) | 0;\n const w = Number(blendWeights[i * weightStride + k]) || 0;\n if (idx === jointIndex) {\n weight = Math.max(weight, w);\n }\n if (w > maxWeight) {\n maxWeight = w;\n maxJoint = idx;\n }\n }\n if (weight < weightThreshold || (dominantBoneOnly && maxJoint !== jointIndex)) {\n continue;\n }\n const p = new Vector3(\n Number(positions[i * posStride]) || 0,\n Number(positions[i * posStride + 1]) || 0,\n Number(positions[i * posStride + 2]) || 0\n );\n points.push(inverseBind.transformPointAffine(p, p));\n }\n }\n return uniquePoints(points);\n}\n\nfunction uniquePoints(points: readonly Vector3[]): Vector3[] {\n const result: Vector3[] = [];\n const keys = new Set<string>();\n for (const point of points) {\n const key = `${Math.round(point.x * 100000)}:${Math.round(point.y * 100000)}:${Math.round(point.z * 100000)}`;\n if (!keys.has(key)) {\n keys.add(key);\n result.push(point);\n }\n }\n return result;\n}\n\nfunction buildConvexHull(points: readonly Vector3[], maxHullVertices: number, margin: number) {\n const sampled = sampleSupportPoints(points, Math.max(8, maxHullVertices));\n if (sampled.length < 4) {\n return null;\n }\n const faces = bruteForceHullFaces(sampled);\n if (faces.length < 4) {\n return null;\n }\n const planes = mergePlanes(faces);\n if (margin > 0) {\n for (const plane of planes) {\n plane.distance -= margin;\n }\n }\n return {\n vertices: sampled.map((point) => point.clone()),\n planes,\n edges: extractHullEdges(sampled, planes)\n };\n}\n\nfunction sampleSupportPoints(points: readonly Vector3[], maxCount: number): Vector3[] {\n if (points.length <= maxCount) {\n return [...points];\n }\n const dirs = buildSampleDirections(maxCount);\n const selected: Vector3[] = [];\n const indices = new Set<number>();\n for (const dir of dirs) {\n let bestIndex = -1;\n let bestDot = -Infinity;\n for (let i = 0; i < points.length; i++) {\n const d = Vector3.dot(points[i], dir);\n if (d > bestDot) {\n bestDot = d;\n bestIndex = i;\n }\n }\n if (bestIndex >= 0 && !indices.has(bestIndex)) {\n indices.add(bestIndex);\n selected.push(points[bestIndex]);\n if (selected.length >= maxCount) {\n break;\n }\n }\n }\n return selected.length >= 4 ? selected : [...points.slice(0, maxCount)];\n}\n\nfunction buildSampleDirections(maxCount: number): Vector3[] {\n const dirs = [\n new Vector3(1, 0, 0),\n new Vector3(-1, 0, 0),\n new Vector3(0, 1, 0),\n new Vector3(0, -1, 0),\n new Vector3(0, 0, 1),\n new Vector3(0, 0, -1)\n ];\n const rings = Math.max(4, Math.ceil(Math.sqrt(maxCount)));\n for (let y = 0; y < rings && dirs.length < maxCount; y++) {\n const v = rings === 1 ? 0 : -1 + (2 * y) / (rings - 1);\n const r = Math.sqrt(Math.max(0, 1 - v * v));\n for (let x = 0; x < rings * 2 && dirs.length < maxCount; x++) {\n const a = (x / (rings * 2)) * Math.PI * 2;\n dirs.push(new Vector3(Math.cos(a) * r, v, Math.sin(a) * r));\n }\n }\n return dirs;\n}\n\nfunction bruteForceHullFaces(points: readonly Vector3[]): Face[] {\n const center = new Vector3();\n for (const point of points) {\n Vector3.add(center, point, center);\n }\n Vector3.scale(center, 1 / points.length, center);\n const faces: Face[] = [];\n const faceKeys = new Set<string>();\n for (let i = 0; i < points.length - 2; i++) {\n for (let j = i + 1; j < points.length - 1; j++) {\n for (let k = j + 1; k < points.length; k++) {\n const ab = Vector3.sub(points[j], points[i]);\n const ac = Vector3.sub(points[k], points[i]);\n const normal = Vector3.cross(ab, ac);\n const len = normal.magnitude;\n if (len <= EPS) {\n continue;\n }\n Vector3.scale(normal, 1 / len, normal);\n let distance = -Vector3.dot(normal, points[i]);\n if (Vector3.dot(normal, center) + distance > 0) {\n Vector3.scale(normal, -1, normal);\n distance = -Vector3.dot(normal, points[i]);\n }\n let valid = true;\n for (let p = 0; p < points.length; p++) {\n if (p === i || p === j || p === k) {\n continue;\n }\n if (Vector3.dot(normal, points[p]) + distance > 1e-5) {\n valid = false;\n break;\n }\n }\n if (!valid) {\n continue;\n }\n const key = planeKey(normal, distance);\n if (faceKeys.has(key)) {\n continue;\n }\n faceKeys.add(key);\n faces.push({ a: i, b: j, c: k, normal: normal.clone(), distance });\n }\n }\n }\n return faces;\n}\n\nfunction mergePlanes(faces: readonly Face[]): ConvexColliderPlane[] {\n const planes: ConvexColliderPlane[] = [];\n for (const face of faces) {\n if (\n planes.some(\n (plane) =>\n Math.abs(Vector3.dot(plane.normal, face.normal) - 1) < 1e-4 &&\n Math.abs(plane.distance - face.distance) < 1e-4\n )\n ) {\n continue;\n }\n planes.push({ normal: face.normal.clone(), distance: face.distance });\n }\n return planes;\n}\n\nfunction extractHullEdges(\n vertices: readonly Vector3[],\n planes: readonly ConvexColliderPlane[]\n): number[] {\n const result: number[] = [];\n const keys = new Set<string>();\n for (let i = 0; i < vertices.length - 1; i++) {\n for (let j = i + 1; j < vertices.length; j++) {\n const sharedPlaneCount = planes.reduce((count, plane) => {\n const di = Math.abs(Vector3.dot(plane.normal, vertices[i]) + plane.distance);\n const dj = Math.abs(Vector3.dot(plane.normal, vertices[j]) + plane.distance);\n return count + (di < 1e-4 && dj < 1e-4 ? 1 : 0);\n }, 0);\n if (sharedPlaneCount < 2) {\n continue;\n }\n const key = `${i}:${j}`;\n if (!keys.has(key)) {\n keys.add(key);\n result.push(i, j);\n }\n }\n }\n return result;\n}\n\nfunction planeKey(normal: Vector3, distance: number): string {\n return `${Math.round(normal.x * 10000)}:${Math.round(normal.y * 10000)}:${Math.round(normal.z * 10000)}:${Math.round(distance * 10000)}`;\n}\n"],"names":["EPS","generateJointDynamicsConvexCollidersFromSkinWeights","meshes","skinBinding","bones","options","sources","collectSourcePrimitives","results","bone","jointIndex","joints","indexOf","points","collectBonePoints","length","minVertexCount","hull","buildConvexHull","maxHullVertices","margin","vertices","planes","push","vertexCount","hullVertexCount","collider","radius","radiusTailScale","height","friction","isInverseCollider","inversed","forceType","ColliderForce","Off","convex","result","seen","Set","mesh","binding","getSceneMeshAssetBinding","subMesh","primitive","has","add","weightThreshold","dominantBoneOnly","inverseBind","inverseBindMatrices","Matrix4x4","identity","source","positionInfo","position","blendIndexInfo","blendIndices","blendWeightInfo","blendWeights","positions","data","posStride","getVertexFormatComponentCount","format","idxStride","weightStride","Math","floor","i","weight","maxWeight","maxJoint","influenceCount","min","k","idx","Number","w","max","p","Vector3","transformPointAffine","uniquePoints","keys","point","key","round","x","y","z","sampled","sampleSupportPoints","faces","bruteForceHullFaces","mergePlanes","plane","distance","map","clone","edges","extractHullEdges","maxCount","dirs","buildSampleDirections","selected","indices","dir","bestIndex","bestDot","Infinity","d","dot","slice","rings","ceil","sqrt","v","r","a","PI","cos","sin","center","scale","faceKeys","j","ab","sub","ac","normal","cross","len","magnitude","valid","planeKey","b","c","face","some","abs","sharedPlaneCount","reduce","count","di","dj"],"mappings":"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"}