@lovelace_lol/embody 0.0.6 → 0.0.8

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 (127) hide show
  1. package/README.md +541 -2394
  2. package/dist/index.d.ts +2 -100
  3. package/dist/index.js +7714 -12951
  4. package/dist/index.js.map +1 -1
  5. package/dist/three/annotations/DOMControls.d.ts +73 -0
  6. package/dist/three/annotations/DPthree.d.ts +113 -0
  7. package/dist/three/annotations/DPthree3DMarkers.d.ts +319 -0
  8. package/dist/three/annotations/DPthreeCameraController.d.ts +414 -0
  9. package/dist/three/annotations/DPthreeHTMLMarkers.d.ts +131 -0
  10. package/dist/three/annotations/DPthreeMarkers.d.ts +52 -0
  11. package/dist/three/annotations/adapter.d.ts +157 -0
  12. package/dist/three/annotations/animationFrameTaskScheduler.d.ts +18 -0
  13. package/dist/three/annotations/annotationAnchorModel.d.ts +16 -0
  14. package/dist/three/annotations/annotationCameraCore.d.ts +5 -0
  15. package/dist/three/annotations/boneResolutionProfile.d.ts +7 -0
  16. package/dist/three/annotations/index.d.ts +20 -0
  17. package/dist/three/annotations/loadFrame.d.ts +2 -0
  18. package/dist/three/annotations/markerSurfaceRaycast.d.ts +11 -0
  19. package/dist/three/annotations/markerVisibilityLifecycle.d.ts +21 -0
  20. package/dist/three/annotations/modelRenderPreparation.d.ts +6 -0
  21. package/dist/three/annotations/runtimeAnnotationPreview.d.ts +15 -0
  22. package/dist/three/annotations/runtimeAnnotationPreviewSide.d.ts +10 -0
  23. package/dist/three/annotations/runtimeAnnotationSidePreview.d.ts +5 -0
  24. package/dist/three/annotations/types.d.ts +262 -0
  25. package/dist/three/gaze.d.ts +122 -0
  26. package/dist/three/index.d.ts +147 -0
  27. package/dist/three/model.d.ts +31 -0
  28. package/dist/three/modelSkinning.d.ts +3 -0
  29. package/dist/three/reference-pose.d.ts +73 -0
  30. package/dist/three/scene.d.ts +253 -0
  31. package/dist/three/sceneRenderingBinding.d.ts +22 -0
  32. package/dist/three.js +7696 -8936
  33. package/dist/three.js.map +1 -1
  34. package/dist/wasm/README.md +551 -62
  35. package/dist/wasm/auto.d.ts +1 -0
  36. package/dist/wasm/embody_wasm.d.ts +388 -52
  37. package/dist/wasm/embody_wasm.js +1514 -119
  38. package/dist/wasm/embody_wasm_bg.wasm +0 -0
  39. package/dist/wasm/embody_wasm_bg.wasm.d.ts +115 -40
  40. package/dist/wasm/index.d.ts +126 -0
  41. package/dist/wasm.d.ts +1 -43
  42. package/dist/wasm.js +1043 -239
  43. package/dist/wasm.js.map +1 -1
  44. package/package.json +34 -39
  45. package/service-worker/character-asset-service-worker.js +295 -0
  46. package/dist/authoring/boneAuthoring.d.ts +0 -132
  47. package/dist/camera/annotationCameraAngles.d.ts +0 -28
  48. package/dist/camera/cameraRelativeGaze.d.ts +0 -15
  49. package/dist/camera/rustAnnotationCameraCore.d.ts +0 -136
  50. package/dist/cljs.cjs +0 -362
  51. package/dist/cljs.cjs.map +0 -1
  52. package/dist/cljs.d.ts +0 -5
  53. package/dist/cljs.js +0 -359
  54. package/dist/cljs.js.map +0 -1
  55. package/dist/core/TsClipCompiler.d.ts +0 -51
  56. package/dist/core/WasmRuntimeCore.d.ts +0 -41
  57. package/dist/core/compositeAxis.d.ts +0 -4
  58. package/dist/core/contracts/abi.d.ts +0 -70
  59. package/dist/core/contracts/clip.d.ts +0 -44
  60. package/dist/core/contracts/frame.d.ts +0 -27
  61. package/dist/core/contracts/host.d.ts +0 -28
  62. package/dist/core/contracts/ids.d.ts +0 -15
  63. package/dist/core/contracts/index.d.ts +0 -10
  64. package/dist/core/contracts/model.d.ts +0 -31
  65. package/dist/core/contracts/primitives.d.ts +0 -17
  66. package/dist/core/contracts/skeletonFit.d.ts +0 -41
  67. package/dist/core/index.d.ts +0 -6
  68. package/dist/core/types.d.ts +0 -472
  69. package/dist/core.cjs +0 -343
  70. package/dist/core.cjs.map +0 -1
  71. package/dist/core.js +0 -323
  72. package/dist/core.js.map +0 -1
  73. package/dist/engines/three/Embody.d.ts +0 -372
  74. package/dist/engines/three/ThreeAnimationRuntime.d.ts +0 -203
  75. package/dist/engines/three/ThreeClipAdapter.d.ts +0 -24
  76. package/dist/engines/three/ThreeFrameApplier.d.ts +0 -68
  77. package/dist/engines/three/ThreeModelInspector.d.ts +0 -54
  78. package/dist/engines/three/bakedClipPartitioning.d.ts +0 -16
  79. package/dist/engines/three/balanceUtils.d.ts +0 -3
  80. package/dist/engines/three/characterHost.d.ts +0 -80
  81. package/dist/engines/three/characterScene.d.ts +0 -98
  82. package/dist/engines/three/hair/HairPhysicsController.d.ts +0 -124
  83. package/dist/engines/three/index.d.ts +0 -20
  84. package/dist/engines/three/modelLoader.d.ts +0 -61
  85. package/dist/engines/three/profileTestScene.d.ts +0 -52
  86. package/dist/engines/three/types.d.ts +0 -20
  87. package/dist/hair/appearance.d.ts +0 -29
  88. package/dist/index.cjs +0 -14871
  89. package/dist/index.cjs.map +0 -1
  90. package/dist/interfaces/Animation.d.ts +0 -315
  91. package/dist/interfaces/EmbodyRuntime.d.ts +0 -90
  92. package/dist/interfaces/Hair.d.ts +0 -181
  93. package/dist/interfaces/HairPhysics.d.ts +0 -90
  94. package/dist/interfaces/index.d.ts +0 -11
  95. package/dist/mappings/extendPresetWithProfile.d.ts +0 -17
  96. package/dist/mappings/types.d.ts +0 -309
  97. package/dist/mappings/visemeSystem.d.ts +0 -26
  98. package/dist/physics/HairPhysics.d.ts +0 -86
  99. package/dist/physics/RustHairPhysics.d.ts +0 -18
  100. package/dist/physics/index.d.ts +0 -6
  101. package/dist/preset.cjs +0 -2005
  102. package/dist/preset.cjs.map +0 -1
  103. package/dist/preset.js +0 -2003
  104. package/dist/preset.js.map +0 -1
  105. package/dist/presets/bettaFish.d.ts +0 -328
  106. package/dist/presets/cc4.d.ts +0 -145
  107. package/dist/presets/index.d.ts +0 -30
  108. package/dist/presets/registry.d.ts +0 -57
  109. package/dist/profiles/resolveProfileConfig.d.ts +0 -36
  110. package/dist/profiles/rustResolvedProfile.d.ts +0 -31
  111. package/dist/profiles/types.d.ts +0 -118
  112. package/dist/regions/normalizeRegionTree.d.ts +0 -6
  113. package/dist/regions/regionMapping.d.ts +0 -17
  114. package/dist/regions/types.d.ts +0 -122
  115. package/dist/skeletonTemplates/humanoidSkeletonTemplates.d.ts +0 -32
  116. package/dist/test/setupWasm.d.ts +0 -1
  117. package/dist/three.cjs +0 -9550
  118. package/dist/three.cjs.map +0 -1
  119. package/dist/validation/analyzeModel.d.ts +0 -68
  120. package/dist/validation/extractModelData.d.ts +0 -90
  121. package/dist/validation/generateMappingCorrections.d.ts +0 -32
  122. package/dist/validation/geometryHelpers.d.ts +0 -66
  123. package/dist/validation/types.d.ts +0 -10
  124. package/dist/validation/validateMappings.d.ts +0 -77
  125. package/dist/wasm.cjs +0 -302
  126. package/dist/wasm.cjs.map +0 -1
  127. package/dist/wasmTypes.d.ts +0 -123
@@ -1,136 +0,0 @@
1
- import type { WasmCameraFlightHandle, WasmCameraOrbitHandle } from '../wasmTypes';
2
- export interface Vec3Like {
3
- x: number;
4
- y: number;
5
- z: number;
6
- }
7
- export interface QuatLike {
8
- x: number;
9
- y: number;
10
- z: number;
11
- w: number;
12
- }
13
- export interface BoundsLike {
14
- center: Vec3Like;
15
- size: Vec3Like;
16
- }
17
- export interface CameraFramingResult {
18
- position: Vec3Like;
19
- target: Vec3Like;
20
- distance: number;
21
- }
22
- export interface CameraPoseSample extends Omit<CameraFramingResult, 'distance'> {
23
- done: boolean;
24
- }
25
- export interface FocusFramingOptions {
26
- focusBounds: BoundsLike;
27
- modelBounds?: BoundsLike | null;
28
- modelQuaternion?: QuatLike | null;
29
- fovDegrees: number;
30
- aspect: number;
31
- minDistance: number;
32
- closeUpPaddingFactor: number;
33
- zoomPaddingFactor: number;
34
- fullBodyPaddingFactor: number;
35
- overridePadding?: number;
36
- cameraAngle?: number;
37
- angleSpace?: 'model' | 'world';
38
- }
39
- export interface FullBodyFramingOptions {
40
- boxMin: Vec3Like;
41
- boxMax: Vec3Like;
42
- modelQuaternion?: QuatLike | null;
43
- fovDegrees: number;
44
- aspect: number;
45
- minDistance: number;
46
- fullBodyPaddingFactor: number;
47
- overridePadding?: number;
48
- cameraAngle?: number;
49
- angleSpace?: 'model' | 'world';
50
- }
51
- export type MarkerSoloState = 'none' | 'soloed' | 'other-soloed';
52
- export interface MarkerVisibilityAnimationFactors {
53
- itemOpacityFactor: number;
54
- labelScaleFactor: number;
55
- lineOpacityFactor: number;
56
- }
57
- export interface MarkerEndpointSeparationOptions {
58
- /** Packed marker surface anchors as `[x, y, z, ...]`. */
59
- starts: ArrayLike<number>;
60
- /** Packed marker leader-line ends as `[x, y, z, ...]`. */
61
- ends: ArrayLike<number>;
62
- modelCenter: Vec3Like;
63
- modelHeight: number;
64
- }
65
- export declare class RustCameraFlight {
66
- private handle;
67
- constructor(handle: WasmCameraFlightHandle);
68
- sample(elapsedMs: number): CameraPoseSample;
69
- get durationMs(): number;
70
- dispose(): void;
71
- }
72
- export declare class RustCameraOrbit {
73
- private handle;
74
- constructor(handle: WasmCameraOrbitHandle);
75
- sample(elapsedMs: number): CameraPoseSample;
76
- get durationMs(): number;
77
- dispose(): void;
78
- }
79
- export declare class RustAnnotationCameraCore {
80
- private core;
81
- private constructor();
82
- static create(): Promise<RustAnnotationCameraCore>;
83
- normalizeCameraAngle(angle: number): number;
84
- worldDirectionForCameraAngle(modelQuaternion: QuatLike | null, cameraAngle: number): Vec3Like;
85
- resolveFocusCameraDirection(modelQuaternion: QuatLike | null, effectiveAngle: number, cameraAngle: number | undefined, angleSpace?: 'model' | 'world'): Vec3Like;
86
- resolveAutoCloseupAngle(horizontalOffset: number, focusSize: Vec3Like, modelSize: Vec3Like): number | undefined;
87
- focusPaddingFactor(size: number, closeUpPaddingFactor: number, zoomPaddingFactor: number, fullBodyPaddingFactor: number): number;
88
- solveFocusFraming(options: FocusFramingOptions): CameraFramingResult;
89
- solveFullBodyFraming(options: FullBodyFramingOptions): CameraFramingResult;
90
- createCameraFlight(startPosition: Vec3Like, startTarget: Vec3Like, endPosition: Vec3Like, endTarget: Vec3Like, durationMs: number): RustCameraFlight;
91
- createCameraOrbit(center: Vec3Like, radius: number, height: number, durationMs: number): RustCameraOrbit;
92
- passesMarkerCameraAngleGate(params: {
93
- markerAngle?: number;
94
- currentCameraAngle?: number;
95
- rangeDegrees?: number;
96
- }): boolean;
97
- shouldShowMarker(params: {
98
- hiddenChild: boolean;
99
- solo: MarkerSoloState;
100
- markerAngle?: number;
101
- currentCameraAngle?: number;
102
- }): boolean;
103
- resolveViewportConstrainedLineScale(params: {
104
- startClip: readonly number[];
105
- endClip: readonly number[];
106
- safeX: number;
107
- safeY: number;
108
- minLengthRatio?: number;
109
- }): {
110
- visible: boolean;
111
- lineScale: number;
112
- };
113
- resolveViewportSafeBounds(params: {
114
- labelScaleX: number;
115
- labelScaleY: number;
116
- projectionXScale: number;
117
- projectionYScale: number;
118
- viewportWidth: number;
119
- viewportHeight: number;
120
- edgePaddingPx?: number;
121
- }): {
122
- safeX: number;
123
- safeY: number;
124
- };
125
- /** Returns `(segments + 1)` points as a flat `[x, y, z, ...]` array. */
126
- sampleMarkerBezierCurve(start: Vec3Like, end: Vec3Like, segments?: number): Float32Array;
127
- /** Returns `(segments + 1)` points as a flat `[x, y, z, ...]` array. */
128
- sampleMarkerArcCurve(start: Vec3Like, end: Vec3Like, segments?: number): Float32Array;
129
- markerVisibilityAnimationFactors(visible: boolean, t: number): MarkerVisibilityAnimationFactors;
130
- /**
131
- * Separates overlapping leader-line endpoints while retaining marker anchors
132
- * and leader-line lengths. Returns packed `[x, y, z, ...]` endpoints.
133
- */
134
- separateOverlappingMarkerEndpoints(options: MarkerEndpointSeparationOptions): Float32Array;
135
- }
136
- export declare function createRustAnnotationCameraCore(): Promise<RustAnnotationCameraCore>;
package/dist/cljs.cjs DELETED
@@ -1,362 +0,0 @@
1
- 'use strict';
2
-
3
- // src/cljs.ts
4
- var LOOP_MODES = /* @__PURE__ */ new Set(["once", "repeat", "pingpong"]);
5
- function nowMs() {
6
- return Date.now();
7
- }
8
- function isRecord(value) {
9
- return typeof value === "object" && value !== null && !Array.isArray(value);
10
- }
11
- function finiteNumber(value) {
12
- return typeof value === "number" && Number.isFinite(value);
13
- }
14
- function numberOr(value, fallback) {
15
- return finiteNumber(value) ? value : fallback;
16
- }
17
- function clamp(low, high, value) {
18
- const next = numberOr(value, low);
19
- return Math.min(high, Math.max(low, next));
20
- }
21
- function keyToString(value) {
22
- if (typeof value === "string") return value;
23
- if (typeof value === "number") return String(value);
24
- if (typeof value === "symbol") return value.description ?? "";
25
- return "";
26
- }
27
- function getConnectorFunction(connector, name) {
28
- const candidate = connector[name];
29
- return typeof candidate === "function" ? candidate : null;
30
- }
31
- function callFirst(connector, names, ...args) {
32
- for (const name of names) {
33
- const callback = getConnectorFunction(connector, name);
34
- if (callback) {
35
- return callback(...args);
36
- }
37
- }
38
- return void 0;
39
- }
40
- function normalizePoint(point) {
41
- const source = isRecord(point) ? point : {};
42
- return {
43
- time: numberOr(source.time ?? source.t, 0),
44
- intensity: numberOr(source.intensity ?? source.v, 0),
45
- inherit: Boolean(source.inherit)
46
- };
47
- }
48
- function normalizeCurves(curves) {
49
- if (!isRecord(curves)) {
50
- return {};
51
- }
52
- return Object.fromEntries(
53
- Object.entries(curves).map(([curveId, points]) => [
54
- keyToString(curveId),
55
- (Array.isArray(points) ? points : []).map(normalizePoint).sort((a, b) => a.time - b.time)
56
- ])
57
- );
58
- }
59
- function calculateDuration(curves, fallback) {
60
- return Object.values(curves).reduce((duration, points) => {
61
- const last = points[points.length - 1];
62
- return Math.max(duration, numberOr(last?.time, duration));
63
- }, numberOr(fallback, 0));
64
- }
65
- function normalizeLoopMode(options) {
66
- const mode = options.loopMode ?? options.mixerLoopMode;
67
- if (typeof mode === "string" && LOOP_MODES.has(mode)) {
68
- return mode;
69
- }
70
- return options.loop === false ? "once" : "repeat";
71
- }
72
- function normalizeOptions(options) {
73
- const source = isRecord(options) ? options : {};
74
- const loopMode = normalizeLoopMode(source);
75
- const rate = source.playbackRate ?? source.rate ?? source.speed;
76
- const weight = source.weight ?? source.intensity ?? source.mixerWeight;
77
- return {
78
- ...source,
79
- weight: Math.max(0, numberOr(weight, 1)),
80
- rate: Math.max(0, numberOr(rate, 1)),
81
- loopMode,
82
- loop: loopMode !== "once",
83
- repeatCount: finiteNumber(source.repeatCount) ? source.repeatCount : void 0,
84
- reverse: Boolean(source.reverse),
85
- source: keyToString(source.source) || "clip",
86
- startTime: Math.max(0, numberOr(source.startTime, 0)),
87
- balance: clamp(-1, 1, source.balance),
88
- jawScale: Math.max(0, numberOr(source.jawScale, 1)),
89
- intensityScale: Math.max(0, numberOr(source.intensityScale, 1))
90
- };
91
- }
92
- function makeActionId(clipName) {
93
- return `${clipName}#${nowMs()}-${Math.floor(Math.random() * 1e6)}`;
94
- }
95
- function emitCommand(connector, op, clipName, payload = {}) {
96
- const command = {
97
- type: "clipCommand",
98
- op,
99
- clipName,
100
- timestamp: nowMs(),
101
- ...payload
102
- };
103
- connector.onCommand?.(command);
104
- return command;
105
- }
106
- function emitState(connector, state) {
107
- connector.onState?.(snapshotState(state));
108
- }
109
- function snapshotState(state) {
110
- return {
111
- handles: Object.fromEntries(
112
- Object.entries(state.handles).map(([clipName, handle]) => [clipName, { ...handle }])
113
- ),
114
- order: [...state.order],
115
- eventCount: state.eventCount,
116
- lastEvent: state.lastEvent ? { ...state.lastEvent } : null,
117
- lastUpdatedTime: state.lastUpdatedTime,
118
- config: { ...state.config }
119
- };
120
- }
121
- function createAnimationRuntime(config = null, connector = null) {
122
- const renderer = connector ?? {};
123
- const state = {
124
- handles: {},
125
- order: [],
126
- eventCount: 0,
127
- lastEvent: null,
128
- lastUpdatedTime: null,
129
- config: isRecord(config) ? { ...config } : {}
130
- };
131
- const listeners = /* @__PURE__ */ new Map();
132
- const finishers = /* @__PURE__ */ new Map();
133
- const upsertHandle = (handle) => {
134
- state.handles[handle.clipName] = handle;
135
- if (!state.order.includes(handle.clipName)) {
136
- state.order.push(handle.clipName);
137
- }
138
- state.lastUpdatedTime = nowMs();
139
- };
140
- const updateHandle = (clipName, apply) => {
141
- const current = state.handles[clipName];
142
- if (!current) return;
143
- state.handles[clipName] = apply({ ...current, updatedAt: nowMs() });
144
- state.lastUpdatedTime = nowMs();
145
- };
146
- const removeHandle = (clipName) => {
147
- delete state.handles[clipName];
148
- state.order = state.order.filter((name) => name !== clipName);
149
- state.lastUpdatedTime = nowMs();
150
- };
151
- const notifyListeners = (clipName, event) => {
152
- for (const listener of Array.from(listeners.get(clipName) ?? [])) {
153
- try {
154
- listener(event);
155
- } catch (error) {
156
- console.error("[Embody runtime] clip listener failed", error);
157
- }
158
- }
159
- };
160
- const resolveFinished = (clipName) => {
161
- const resolve = finishers.get(clipName);
162
- if (resolve) {
163
- resolve();
164
- finishers.delete(clipName);
165
- }
166
- };
167
- const makeHandle = (clipName) => {
168
- const finished = new Promise((resolve) => {
169
- finishers.set(clipName, resolve);
170
- });
171
- return {
172
- clipName,
173
- actionId: state.handles[clipName]?.actionId,
174
- play: () => {
175
- updateHandle(clipName, (handle) => ({ ...handle, status: "playing" }));
176
- emitCommand(renderer, "play", clipName);
177
- callFirst(renderer, ["playClip", "play"], clipName);
178
- emitState(renderer, state);
179
- },
180
- stop: () => {
181
- updateHandle(clipName, (handle) => ({ ...handle, status: "stopped" }));
182
- emitCommand(renderer, "stop", clipName);
183
- callFirst(renderer, ["stopClip", "stop"], clipName);
184
- resolveFinished(clipName);
185
- emitState(renderer, state);
186
- },
187
- pause: () => {
188
- updateHandle(clipName, (handle) => ({ ...handle, status: "paused" }));
189
- emitCommand(renderer, "pause", clipName);
190
- callFirst(renderer, ["pauseClip", "pause"], clipName);
191
- emitState(renderer, state);
192
- },
193
- resume: () => {
194
- updateHandle(clipName, (handle) => ({ ...handle, status: "playing" }));
195
- emitCommand(renderer, "resume", clipName);
196
- callFirst(renderer, ["resumeClip", "resume"], clipName);
197
- emitState(renderer, state);
198
- },
199
- setWeight: (weight) => {
200
- const nextWeight = Math.max(0, numberOr(weight, 1));
201
- updateHandle(clipName, (handle) => ({ ...handle, weight: nextWeight }));
202
- emitCommand(renderer, "setWeight", clipName, { weight: nextWeight });
203
- callFirst(renderer, ["setClipWeight", "setWeight"], clipName, nextWeight);
204
- emitState(renderer, state);
205
- },
206
- setPlaybackRate: (rate) => {
207
- const nextRate = Math.max(0, numberOr(rate, 1));
208
- updateHandle(clipName, (handle) => ({ ...handle, rate: nextRate }));
209
- emitCommand(renderer, "setPlaybackRate", clipName, { rate: nextRate });
210
- callFirst(renderer, ["setClipPlaybackRate", "setPlaybackRate"], clipName, nextRate);
211
- emitState(renderer, state);
212
- },
213
- setLoop: (mode, repeatCount) => {
214
- const nextMode = LOOP_MODES.has(mode) ? mode : "repeat";
215
- updateHandle(clipName, (handle) => ({
216
- ...handle,
217
- loopMode: nextMode,
218
- loop: nextMode !== "once",
219
- repeatCount
220
- }));
221
- emitCommand(renderer, "setLoop", clipName, { loopMode: nextMode, repeatCount });
222
- callFirst(renderer, ["setClipLoop", "setLoop"], clipName, nextMode, repeatCount);
223
- emitState(renderer, state);
224
- },
225
- setTime: (time) => {
226
- const duration = state.handles[clipName]?.duration ?? 0;
227
- const nextTime = clamp(0, duration, time);
228
- updateHandle(clipName, (handle) => ({ ...handle, time: nextTime }));
229
- emitCommand(renderer, "setTime", clipName, { time: nextTime });
230
- callFirst(renderer, ["setClipTime", "setTime"], clipName, nextTime);
231
- emitState(renderer, state);
232
- },
233
- getTime: () => {
234
- const rendererTime = callFirst(renderer, ["getClipTime", "getTime"], clipName);
235
- return numberOr(rendererTime, state.handles[clipName]?.time ?? 0);
236
- },
237
- getDuration: () => {
238
- const rendererDuration = callFirst(renderer, ["getClipDuration", "getDuration"], clipName);
239
- return numberOr(rendererDuration, state.handles[clipName]?.duration ?? 0);
240
- },
241
- subscribe: (listener) => {
242
- const clipListeners = listeners.get(clipName) ?? /* @__PURE__ */ new Set();
243
- clipListeners.add(listener);
244
- listeners.set(clipName, clipListeners);
245
- return () => {
246
- clipListeners.delete(listener);
247
- };
248
- },
249
- finished
250
- };
251
- };
252
- const acceptClipEvent = (event) => {
253
- const eventRecord = isRecord(event) ? event : {};
254
- const clipName = keyToString(eventRecord.clipName ?? eventRecord.name);
255
- if (!clipName) return true;
256
- const eventType = keyToString(eventRecord.type ?? eventRecord.event);
257
- const currentTime = numberOr(
258
- eventRecord.currentTime,
259
- numberOr(eventRecord.time, state.handles[clipName]?.time ?? 0)
260
- );
261
- if (["time", "progress", "frame", "keyframe", "seek", "loop"].includes(eventType)) {
262
- updateHandle(clipName, (handle) => ({ ...handle, time: currentTime }));
263
- } else if (eventType === "paused") {
264
- updateHandle(clipName, (handle) => ({ ...handle, status: "paused" }));
265
- } else if (["resumed", "started", "played"].includes(eventType)) {
266
- updateHandle(clipName, (handle) => ({ ...handle, status: "playing" }));
267
- } else if (["completed", "finished"].includes(eventType)) {
268
- updateHandle(clipName, (handle) => ({
269
- ...handle,
270
- status: "completed",
271
- time: handle.duration
272
- }));
273
- resolveFinished(clipName);
274
- } else if (["stopped", "removed"].includes(eventType)) {
275
- updateHandle(clipName, (handle) => ({ ...handle, status: "stopped" }));
276
- resolveFinished(clipName);
277
- }
278
- state.eventCount += 1;
279
- state.lastEvent = { ...eventRecord, timestamp: nowMs() };
280
- notifyListeners(clipName, event);
281
- emitState(renderer, state);
282
- return true;
283
- };
284
- const buildClip = (clipNameInput, curvesInput, optionsInput) => {
285
- const clipName = keyToString(clipNameInput);
286
- if (!clipName) return null;
287
- const curves = normalizeCurves(curvesInput);
288
- const options = normalizeOptions(optionsInput);
289
- const connectorResult = callFirst(renderer, ["buildClip", "playClip"], clipName, curves, options);
290
- if (connectorResult == null || connectorResult === false) {
291
- return null;
292
- }
293
- const result = isRecord(connectorResult) ? connectorResult : {};
294
- const duration = calculateDuration(curves, result.duration);
295
- const handleState = {
296
- clipName,
297
- actionId: keyToString(result.actionId ?? result.id) || makeActionId(clipName),
298
- duration,
299
- time: numberOr(result.time, options.startTime),
300
- weight: options.weight,
301
- rate: options.rate,
302
- loopMode: options.loopMode,
303
- loop: options.loop,
304
- repeatCount: options.repeatCount,
305
- reverse: options.reverse,
306
- source: options.source,
307
- status: "playing",
308
- createdAt: nowMs(),
309
- updatedAt: nowMs()
310
- };
311
- upsertHandle(handleState);
312
- emitCommand(renderer, "buildClip", clipName, {
313
- actionId: handleState.actionId,
314
- duration: handleState.duration,
315
- options
316
- });
317
- emitState(renderer, state);
318
- return makeHandle(clipName);
319
- };
320
- return {
321
- snapshot: () => snapshotState(state),
322
- buildClip,
323
- playSnippet: (clipName, curves, options) => buildClip(clipName, curves, { ...options, source: options?.source ?? "snippet" }),
324
- acceptClipEvent,
325
- cleanupSnippet: (clipNameInput) => {
326
- const clipName = keyToString(clipNameInput);
327
- if (!clipName) return false;
328
- removeHandle(clipName);
329
- emitCommand(renderer, "cleanupSnippet", clipName);
330
- callFirst(renderer, ["cleanupSnippet", "removeClip"], clipName);
331
- emitState(renderer, state);
332
- return true;
333
- },
334
- updateClipParams: (clipNameInput, params) => {
335
- const clipName = keyToString(clipNameInput);
336
- if (!clipName) return false;
337
- const source = isRecord(params) ? params : {};
338
- updateHandle(clipName, (handle) => ({
339
- ...handle,
340
- weight: finiteNumber(source.weight) ? Math.max(0, source.weight) : handle.weight,
341
- rate: finiteNumber(source.rate) ? Math.max(0, source.rate) : handle.rate,
342
- loopMode: typeof source.loopMode === "string" && LOOP_MODES.has(source.loopMode) ? source.loopMode : handle.loopMode,
343
- loop: typeof source.loop === "boolean" ? source.loop : handle.loop,
344
- repeatCount: finiteNumber(source.repeatCount) ? source.repeatCount : handle.repeatCount,
345
- reverse: typeof source.reverse === "boolean" ? source.reverse : handle.reverse
346
- }));
347
- emitCommand(renderer, "updateClipParams", clipName, { params: source });
348
- const result = callFirst(renderer, ["updateClipParams"], clipName, source);
349
- emitState(renderer, state);
350
- return result === false ? false : true;
351
- }
352
- };
353
- }
354
- function installEmbody(target = globalThis) {
355
- target.createAnimationRuntime = createAnimationRuntime;
356
- return { createAnimationRuntime };
357
- }
358
-
359
- exports.createAnimationRuntime = createAnimationRuntime;
360
- exports.installEmbody = installEmbody;
361
- //# sourceMappingURL=cljs.cjs.map
362
- //# sourceMappingURL=cljs.cjs.map
package/dist/cljs.cjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cljs.ts"],"names":[],"mappings":"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","file":"cljs.cjs","sourcesContent":["import type {\n ClipEvent,\n ClipEventListener,\n ClipHandle,\n ClipOptions,\n CurvePoint,\n CurvesMap,\n EmbodyAnimationRuntime,\n EmbodyAnimationRuntimeConnector,\n} from './core/types';\n\ntype LoopMode = 'once' | 'repeat' | 'pingpong';\ntype RuntimeStatus = 'playing' | 'paused' | 'completed' | 'stopped';\n\ntype RuntimeOptions = {\n weight: number;\n rate: number;\n loopMode: LoopMode;\n loop: boolean;\n repeatCount?: number;\n reverse: boolean;\n source: string;\n startTime: number;\n [key: string]: unknown;\n};\n\ntype RuntimeHandleState = {\n clipName: string;\n actionId?: string;\n duration: number;\n time: number;\n weight: number;\n rate: number;\n loopMode: LoopMode;\n loop: boolean;\n repeatCount?: number;\n reverse: boolean;\n source: string;\n status: RuntimeStatus;\n createdAt: number;\n updatedAt: number;\n};\n\ntype RuntimeState = {\n handles: Record<string, RuntimeHandleState>;\n order: string[];\n eventCount: number;\n lastEvent: Record<string, unknown> | null;\n lastUpdatedTime: number | null;\n config: Record<string, unknown>;\n};\n\ntype ConnectorFunction = (...args: unknown[]) => unknown;\n\nconst LOOP_MODES = new Set<LoopMode>(['once', 'repeat', 'pingpong']);\n\nfunction nowMs(): number {\n return Date.now();\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction finiteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value);\n}\n\nfunction numberOr(value: unknown, fallback: number): number {\n return finiteNumber(value) ? value : fallback;\n}\n\nfunction clamp(low: number, high: number, value: unknown): number {\n const next = numberOr(value, low);\n return Math.min(high, Math.max(low, next));\n}\n\nfunction keyToString(value: unknown): string {\n if (typeof value === 'string') return value;\n if (typeof value === 'number') return String(value);\n if (typeof value === 'symbol') return value.description ?? '';\n return '';\n}\n\nfunction getConnectorFunction(\n connector: EmbodyAnimationRuntimeConnector,\n name: string\n): ConnectorFunction | null {\n const candidate = (connector as Record<string, unknown>)[name];\n return typeof candidate === 'function' ? candidate as ConnectorFunction : null;\n}\n\nfunction callFirst(\n connector: EmbodyAnimationRuntimeConnector,\n names: string[],\n ...args: unknown[]\n): unknown {\n for (const name of names) {\n const callback = getConnectorFunction(connector, name);\n if (callback) {\n return callback(...args);\n }\n }\n return undefined;\n}\n\nfunction normalizePoint(point: unknown): CurvePoint {\n const source = isRecord(point) ? point : {};\n return {\n time: numberOr(source.time ?? source.t, 0),\n intensity: numberOr(source.intensity ?? source.v, 0),\n inherit: Boolean(source.inherit),\n };\n}\n\nfunction normalizeCurves(curves: CurvesMap): CurvesMap {\n if (!isRecord(curves)) {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(curves).map(([curveId, points]) => [\n keyToString(curveId),\n (Array.isArray(points) ? points : [])\n .map(normalizePoint)\n .sort((a, b) => a.time - b.time),\n ])\n );\n}\n\nfunction calculateDuration(curves: CurvesMap, fallback: unknown): number {\n return Object.values(curves).reduce((duration, points) => {\n const last = points[points.length - 1];\n return Math.max(duration, numberOr(last?.time, duration));\n }, numberOr(fallback, 0));\n}\n\nfunction normalizeLoopMode(options: Record<string, unknown>): LoopMode {\n const mode = options.loopMode ?? options.mixerLoopMode;\n if (typeof mode === 'string' && LOOP_MODES.has(mode as LoopMode)) {\n return mode as LoopMode;\n }\n return options.loop === false ? 'once' : 'repeat';\n}\n\nfunction normalizeOptions(options?: ClipOptions): RuntimeOptions {\n const source = isRecord(options) ? options : {};\n const loopMode = normalizeLoopMode(source);\n const rate = source.playbackRate ?? source.rate ?? source.speed;\n const weight = source.weight ?? source.intensity ?? source.mixerWeight;\n\n return {\n ...source,\n weight: Math.max(0, numberOr(weight, 1)),\n rate: Math.max(0, numberOr(rate, 1)),\n loopMode,\n loop: loopMode !== 'once',\n repeatCount: finiteNumber(source.repeatCount) ? source.repeatCount : undefined,\n reverse: Boolean(source.reverse),\n source: keyToString(source.source) || 'clip',\n startTime: Math.max(0, numberOr(source.startTime, 0)),\n balance: clamp(-1, 1, source.balance),\n jawScale: Math.max(0, numberOr(source.jawScale, 1)),\n intensityScale: Math.max(0, numberOr(source.intensityScale, 1)),\n };\n}\n\nfunction makeActionId(clipName: string): string {\n return `${clipName}#${nowMs()}-${Math.floor(Math.random() * 1_000_000)}`;\n}\n\nfunction emitCommand(\n connector: EmbodyAnimationRuntimeConnector,\n op: string,\n clipName: string,\n payload: Record<string, unknown> = {}\n): Record<string, unknown> {\n const command = {\n type: 'clipCommand',\n op,\n clipName,\n timestamp: nowMs(),\n ...payload,\n };\n connector.onCommand?.(command);\n return command;\n}\n\nfunction emitState(connector: EmbodyAnimationRuntimeConnector, state: RuntimeState): void {\n connector.onState?.(snapshotState(state));\n}\n\nfunction snapshotState(state: RuntimeState): Record<string, unknown> {\n return {\n handles: Object.fromEntries(\n Object.entries(state.handles).map(([clipName, handle]) => [clipName, { ...handle }])\n ),\n order: [...state.order],\n eventCount: state.eventCount,\n lastEvent: state.lastEvent ? { ...state.lastEvent } : null,\n lastUpdatedTime: state.lastUpdatedTime,\n config: { ...state.config },\n };\n}\n\nexport function createAnimationRuntime(\n config: Record<string, unknown> | null = null,\n connector: EmbodyAnimationRuntimeConnector | null = null\n): EmbodyAnimationRuntime {\n const renderer = connector ?? {};\n const state: RuntimeState = {\n handles: {},\n order: [],\n eventCount: 0,\n lastEvent: null,\n lastUpdatedTime: null,\n config: isRecord(config) ? { ...config } : {},\n };\n const listeners = new Map<string, Set<ClipEventListener>>();\n const finishers = new Map<string, () => void>();\n\n const upsertHandle = (handle: RuntimeHandleState) => {\n state.handles[handle.clipName] = handle;\n if (!state.order.includes(handle.clipName)) {\n state.order.push(handle.clipName);\n }\n state.lastUpdatedTime = nowMs();\n };\n\n const updateHandle = (\n clipName: string,\n apply: (handle: RuntimeHandleState) => RuntimeHandleState\n ) => {\n const current = state.handles[clipName];\n if (!current) return;\n state.handles[clipName] = apply({ ...current, updatedAt: nowMs() });\n state.lastUpdatedTime = nowMs();\n };\n\n const removeHandle = (clipName: string) => {\n delete state.handles[clipName];\n state.order = state.order.filter((name) => name !== clipName);\n state.lastUpdatedTime = nowMs();\n };\n\n const notifyListeners = (clipName: string, event: ClipEvent) => {\n for (const listener of Array.from(listeners.get(clipName) ?? [])) {\n try {\n listener(event);\n } catch (error) {\n console.error('[Embody runtime] clip listener failed', error);\n }\n }\n };\n\n const resolveFinished = (clipName: string) => {\n const resolve = finishers.get(clipName);\n if (resolve) {\n resolve();\n finishers.delete(clipName);\n }\n };\n\n const makeHandle = (clipName: string): ClipHandle => {\n const finished = new Promise<void>((resolve) => {\n finishers.set(clipName, resolve);\n });\n\n return {\n clipName,\n actionId: state.handles[clipName]?.actionId,\n play: () => {\n updateHandle(clipName, (handle) => ({ ...handle, status: 'playing' }));\n emitCommand(renderer, 'play', clipName);\n callFirst(renderer, ['playClip', 'play'], clipName);\n emitState(renderer, state);\n },\n stop: () => {\n updateHandle(clipName, (handle) => ({ ...handle, status: 'stopped' }));\n emitCommand(renderer, 'stop', clipName);\n callFirst(renderer, ['stopClip', 'stop'], clipName);\n resolveFinished(clipName);\n emitState(renderer, state);\n },\n pause: () => {\n updateHandle(clipName, (handle) => ({ ...handle, status: 'paused' }));\n emitCommand(renderer, 'pause', clipName);\n callFirst(renderer, ['pauseClip', 'pause'], clipName);\n emitState(renderer, state);\n },\n resume: () => {\n updateHandle(clipName, (handle) => ({ ...handle, status: 'playing' }));\n emitCommand(renderer, 'resume', clipName);\n callFirst(renderer, ['resumeClip', 'resume'], clipName);\n emitState(renderer, state);\n },\n setWeight: (weight: number) => {\n const nextWeight = Math.max(0, numberOr(weight, 1));\n updateHandle(clipName, (handle) => ({ ...handle, weight: nextWeight }));\n emitCommand(renderer, 'setWeight', clipName, { weight: nextWeight });\n callFirst(renderer, ['setClipWeight', 'setWeight'], clipName, nextWeight);\n emitState(renderer, state);\n },\n setPlaybackRate: (rate: number) => {\n const nextRate = Math.max(0, numberOr(rate, 1));\n updateHandle(clipName, (handle) => ({ ...handle, rate: nextRate }));\n emitCommand(renderer, 'setPlaybackRate', clipName, { rate: nextRate });\n callFirst(renderer, ['setClipPlaybackRate', 'setPlaybackRate'], clipName, nextRate);\n emitState(renderer, state);\n },\n setLoop: (mode: LoopMode, repeatCount?: number) => {\n const nextMode = LOOP_MODES.has(mode) ? mode : 'repeat';\n updateHandle(clipName, (handle) => ({\n ...handle,\n loopMode: nextMode,\n loop: nextMode !== 'once',\n repeatCount,\n }));\n emitCommand(renderer, 'setLoop', clipName, { loopMode: nextMode, repeatCount });\n callFirst(renderer, ['setClipLoop', 'setLoop'], clipName, nextMode, repeatCount);\n emitState(renderer, state);\n },\n setTime: (time: number) => {\n const duration = state.handles[clipName]?.duration ?? 0;\n const nextTime = clamp(0, duration, time);\n updateHandle(clipName, (handle) => ({ ...handle, time: nextTime }));\n emitCommand(renderer, 'setTime', clipName, { time: nextTime });\n callFirst(renderer, ['setClipTime', 'setTime'], clipName, nextTime);\n emitState(renderer, state);\n },\n getTime: () => {\n const rendererTime = callFirst(renderer, ['getClipTime', 'getTime'], clipName);\n return numberOr(rendererTime, state.handles[clipName]?.time ?? 0);\n },\n getDuration: () => {\n const rendererDuration = callFirst(renderer, ['getClipDuration', 'getDuration'], clipName);\n return numberOr(rendererDuration, state.handles[clipName]?.duration ?? 0);\n },\n subscribe: (listener: ClipEventListener) => {\n const clipListeners = listeners.get(clipName) ?? new Set<ClipEventListener>();\n clipListeners.add(listener);\n listeners.set(clipName, clipListeners);\n return () => {\n clipListeners.delete(listener);\n };\n },\n finished,\n };\n };\n\n const acceptClipEvent = (event: ClipEvent | Record<string, unknown>): boolean => {\n const eventRecord: Record<string, unknown> = isRecord(event)\n ? event as Record<string, unknown>\n : {};\n const clipName = keyToString(eventRecord.clipName ?? eventRecord.name);\n if (!clipName) return true;\n\n const eventType = keyToString(eventRecord.type ?? eventRecord.event);\n const currentTime = numberOr(\n eventRecord.currentTime,\n numberOr(eventRecord.time, state.handles[clipName]?.time ?? 0)\n );\n\n if (['time', 'progress', 'frame', 'keyframe', 'seek', 'loop'].includes(eventType)) {\n updateHandle(clipName, (handle) => ({ ...handle, time: currentTime }));\n } else if (eventType === 'paused') {\n updateHandle(clipName, (handle) => ({ ...handle, status: 'paused' }));\n } else if (['resumed', 'started', 'played'].includes(eventType)) {\n updateHandle(clipName, (handle) => ({ ...handle, status: 'playing' }));\n } else if (['completed', 'finished'].includes(eventType)) {\n updateHandle(clipName, (handle) => ({\n ...handle,\n status: 'completed',\n time: handle.duration,\n }));\n resolveFinished(clipName);\n } else if (['stopped', 'removed'].includes(eventType)) {\n updateHandle(clipName, (handle) => ({ ...handle, status: 'stopped' }));\n resolveFinished(clipName);\n }\n\n state.eventCount += 1;\n state.lastEvent = { ...eventRecord, timestamp: nowMs() };\n notifyListeners(clipName, event as ClipEvent);\n emitState(renderer, state);\n return true;\n };\n\n const buildClip = (\n clipNameInput: string,\n curvesInput: CurvesMap,\n optionsInput?: ClipOptions\n ): ClipHandle | null => {\n const clipName = keyToString(clipNameInput);\n if (!clipName) return null;\n\n const curves = normalizeCurves(curvesInput);\n const options = normalizeOptions(optionsInput);\n const connectorResult = callFirst(renderer, ['buildClip', 'playClip'], clipName, curves, options);\n if (connectorResult == null || connectorResult === false) {\n return null;\n }\n\n const result = isRecord(connectorResult) ? connectorResult : {};\n const duration = calculateDuration(curves, result.duration);\n const handleState: RuntimeHandleState = {\n clipName,\n actionId: keyToString(result.actionId ?? result.id) || makeActionId(clipName),\n duration,\n time: numberOr(result.time, options.startTime),\n weight: options.weight,\n rate: options.rate,\n loopMode: options.loopMode,\n loop: options.loop,\n repeatCount: options.repeatCount,\n reverse: options.reverse,\n source: options.source,\n status: 'playing',\n createdAt: nowMs(),\n updatedAt: nowMs(),\n };\n\n upsertHandle(handleState);\n emitCommand(renderer, 'buildClip', clipName, {\n actionId: handleState.actionId,\n duration: handleState.duration,\n options,\n });\n emitState(renderer, state);\n return makeHandle(clipName);\n };\n\n return {\n snapshot: () => snapshotState(state),\n buildClip,\n playSnippet: (clipName, curves, options) => (\n buildClip(clipName, curves, { ...options, source: options?.source ?? 'snippet' })\n ),\n acceptClipEvent,\n cleanupSnippet: (clipNameInput) => {\n const clipName = keyToString(clipNameInput);\n if (!clipName) return false;\n removeHandle(clipName);\n emitCommand(renderer, 'cleanupSnippet', clipName);\n callFirst(renderer, ['cleanupSnippet', 'removeClip'], clipName);\n emitState(renderer, state);\n return true;\n },\n updateClipParams: (clipNameInput, params) => {\n const clipName = keyToString(clipNameInput);\n if (!clipName) return false;\n const source = isRecord(params) ? params : {};\n\n updateHandle(clipName, (handle) => ({\n ...handle,\n weight: finiteNumber(source.weight) ? Math.max(0, source.weight) : handle.weight,\n rate: finiteNumber(source.rate) ? Math.max(0, source.rate) : handle.rate,\n loopMode: typeof source.loopMode === 'string' && LOOP_MODES.has(source.loopMode as LoopMode)\n ? source.loopMode as LoopMode\n : handle.loopMode,\n loop: typeof source.loop === 'boolean' ? source.loop : handle.loop,\n repeatCount: finiteNumber(source.repeatCount) ? source.repeatCount : handle.repeatCount,\n reverse: typeof source.reverse === 'boolean' ? source.reverse : handle.reverse,\n }));\n emitCommand(renderer, 'updateClipParams', clipName, { params: source });\n const result = callFirst(renderer, ['updateClipParams'], clipName, source);\n emitState(renderer, state);\n return result === false ? false : true;\n },\n };\n}\n\nexport function installEmbody(\n target: Record<string, unknown> = globalThis as unknown as Record<string, unknown>\n): { createAnimationRuntime: typeof createAnimationRuntime } {\n target.createAnimationRuntime = createAnimationRuntime;\n return { createAnimationRuntime };\n}\n"]}
package/dist/cljs.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import type { EmbodyAnimationRuntime, EmbodyAnimationRuntimeConnector } from './core/types';
2
- export declare function createAnimationRuntime(config?: Record<string, unknown> | null, connector?: EmbodyAnimationRuntimeConnector | null): EmbodyAnimationRuntime;
3
- export declare function installEmbody(target?: Record<string, unknown>): {
4
- createAnimationRuntime: typeof createAnimationRuntime;
5
- };