@lovelace_lol/embody 0.0.8 → 0.0.9
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.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2049 -1466
- package/dist/index.js.map +1 -1
- package/dist/three/annotations/DPthreeCameraController.d.ts +1 -0
- package/dist/three/authoring.d.ts +95 -0
- package/dist/three/authoringTypes.d.ts +576 -0
- package/dist/three/character.d.ts +243 -0
- package/dist/three/characterHost.d.ts +48 -0
- package/dist/three/clipBindings.d.ts +6 -0
- package/dist/three/index.d.ts +28 -4
- package/dist/three/nativePlayback.d.ts +121 -0
- package/dist/three/playbackRendering.d.ts +14 -0
- package/dist/three.js +1982 -334
- package/dist/three.js.map +1 -1
- package/dist/wasm/compatibility.d.ts +14 -0
- package/dist/wasm/embody_wasm.d.ts +144 -199
- package/dist/wasm/embody_wasm.js +410 -576
- package/dist/wasm/embody_wasm_bg.wasm +0 -0
- package/dist/wasm/embody_wasm_bg.wasm.d.ts +71 -87
- package/dist/wasm/index.d.ts +7 -2
- package/dist/wasm.js +59 -2
- package/dist/wasm.js.map +1 -1
- package/package.json +5 -4
- package/dist/three/gaze.d.ts +0 -122
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { AnimationClip } from 'three';
|
|
2
|
+
import type { Mesh, Object3D } from 'three';
|
|
3
|
+
import { ThreeFrameApplier } from './index';
|
|
4
|
+
import type { ThreeModelInspection } from './index';
|
|
5
|
+
import type { ThreeModelReferencePose } from './reference-pose';
|
|
6
|
+
import type { ThreeNativePlaybackEvent } from './nativePlayback';
|
|
7
|
+
type JsonObject = Record<string, any>;
|
|
8
|
+
export type RustEmbodyHostConfig = {
|
|
9
|
+
profileMode?: 'preset' | 'profile';
|
|
10
|
+
presetId?: string;
|
|
11
|
+
presetType?: string;
|
|
12
|
+
profile?: JsonObject;
|
|
13
|
+
meshes?: Mesh[];
|
|
14
|
+
referencePose?: ThreeModelReferencePose;
|
|
15
|
+
};
|
|
16
|
+
export type CharacterPlaybackOptions = JsonObject;
|
|
17
|
+
export type CharacterPlaybackEvent = ThreeNativePlaybackEvent & {
|
|
18
|
+
actionId: string;
|
|
19
|
+
clipName: string;
|
|
20
|
+
};
|
|
21
|
+
export interface CharacterPlaybackHandle {
|
|
22
|
+
readonly name: string;
|
|
23
|
+
actionId?: string;
|
|
24
|
+
promise: Promise<CharacterPlaybackEvent>;
|
|
25
|
+
readonly finished: Promise<CharacterPlaybackEvent>;
|
|
26
|
+
play(): CharacterPlaybackHandle;
|
|
27
|
+
stop(): CharacterPlaybackHandle;
|
|
28
|
+
cancel(): CharacterPlaybackHandle;
|
|
29
|
+
pause(): CharacterPlaybackHandle;
|
|
30
|
+
resume(): CharacterPlaybackHandle;
|
|
31
|
+
setWeight(value: number): CharacterPlaybackHandle;
|
|
32
|
+
setIntensity(value: number): CharacterPlaybackHandle;
|
|
33
|
+
setSpeed(value: number): CharacterPlaybackHandle;
|
|
34
|
+
setPlaybackRate(value: number): CharacterPlaybackHandle;
|
|
35
|
+
setTime(value: number): CharacterPlaybackHandle;
|
|
36
|
+
seek(value: number): CharacterPlaybackHandle;
|
|
37
|
+
updateParams(value: CharacterPlaybackOptions): CharacterPlaybackHandle;
|
|
38
|
+
setParams(value: CharacterPlaybackOptions): CharacterPlaybackHandle;
|
|
39
|
+
subscribe(listener: ((event: CharacterPlaybackEvent) => void) | {
|
|
40
|
+
next(event: CharacterPlaybackEvent): void;
|
|
41
|
+
}): () => void;
|
|
42
|
+
}
|
|
43
|
+
export interface CharacterTransitionHandle {
|
|
44
|
+
promise: Promise<void>;
|
|
45
|
+
pause(): void;
|
|
46
|
+
resume(): void;
|
|
47
|
+
cancel(): void;
|
|
48
|
+
}
|
|
49
|
+
export declare function supportsRustEmbodyPreset(value?: string): boolean;
|
|
50
|
+
/** Character commands compile in Rust and play exclusively on the native connector. */
|
|
51
|
+
export declare class Embody {
|
|
52
|
+
private readonly config;
|
|
53
|
+
readonly meshes: Mesh[];
|
|
54
|
+
meshByName: Map<string, Mesh<import("three").BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>, import("three").Material<import("three").MaterialEventMap> | import("three").Material<import("three").MaterialEventMap>[], import("three").Object3DEventMap>>;
|
|
55
|
+
bones: ThreeModelInspection['bones'];
|
|
56
|
+
private readonly wasm;
|
|
57
|
+
private core;
|
|
58
|
+
private readonly inspector;
|
|
59
|
+
private readonly applier;
|
|
60
|
+
private readonly references;
|
|
61
|
+
private referenceBindings;
|
|
62
|
+
private boundModel?;
|
|
63
|
+
get model(): Object3D | undefined;
|
|
64
|
+
private inspection?;
|
|
65
|
+
private connector?;
|
|
66
|
+
private profile;
|
|
67
|
+
private profileSource;
|
|
68
|
+
private readonly profileMode;
|
|
69
|
+
private readonly preset;
|
|
70
|
+
private readonly sources;
|
|
71
|
+
private readonly playbacks;
|
|
72
|
+
private readonly current;
|
|
73
|
+
private playDepth;
|
|
74
|
+
private readonly pendingEvents;
|
|
75
|
+
private bindingGeneration;
|
|
76
|
+
private disposed;
|
|
77
|
+
private rendering;
|
|
78
|
+
private timeScale;
|
|
79
|
+
private nextLiveTarget;
|
|
80
|
+
private readonly liveTargets;
|
|
81
|
+
private readonly hairObjects;
|
|
82
|
+
private hairConfig;
|
|
83
|
+
private hairAppearance;
|
|
84
|
+
constructor(config?: RustEmbodyHostConfig);
|
|
85
|
+
static create(config?: RustEmbodyHostConfig): Promise<Embody>;
|
|
86
|
+
private assertAlive;
|
|
87
|
+
private requireModel;
|
|
88
|
+
private requireConnector;
|
|
89
|
+
private validateProfile;
|
|
90
|
+
private resolveProfile;
|
|
91
|
+
onReady(options: {
|
|
92
|
+
model: Object3D;
|
|
93
|
+
meshes?: Mesh[];
|
|
94
|
+
animations?: AnimationClip[];
|
|
95
|
+
referencePose?: ThreeModelReferencePose;
|
|
96
|
+
}): void;
|
|
97
|
+
private bind;
|
|
98
|
+
bindModel(meshes?: Mesh[]): void;
|
|
99
|
+
extendReferencePose(): ThreeModelReferencePose;
|
|
100
|
+
setProfile(value: JsonObject): void;
|
|
101
|
+
getProfile(): JsonObject;
|
|
102
|
+
getProfileMode(): 'preset' | 'profile';
|
|
103
|
+
getPresetId(): string | null;
|
|
104
|
+
supportsPreset(value?: string): boolean;
|
|
105
|
+
private onPlaybackEvent;
|
|
106
|
+
private compile;
|
|
107
|
+
private restValues;
|
|
108
|
+
private materialize;
|
|
109
|
+
private applyEasing;
|
|
110
|
+
private nativeOptions;
|
|
111
|
+
private validateEasing;
|
|
112
|
+
private handle;
|
|
113
|
+
private forget;
|
|
114
|
+
private updatePlayback;
|
|
115
|
+
registerAnimationClips(clips: AnimationClip[]): void;
|
|
116
|
+
loadAnimationClips(clips: AnimationClip[]): void;
|
|
117
|
+
removeAnimationClip(name: string): boolean;
|
|
118
|
+
getAnimationClips(): any[];
|
|
119
|
+
playAnimation(name: string, options?: CharacterPlaybackOptions): CharacterPlaybackHandle;
|
|
120
|
+
private build;
|
|
121
|
+
buildClip(name: string, curves: JsonObject, options?: CharacterPlaybackOptions): CharacterPlaybackHandle;
|
|
122
|
+
snippetToClip(name: string, curves: JsonObject, options?: CharacterPlaybackOptions): CharacterPlaybackHandle;
|
|
123
|
+
buildTypedClip(name: string, channels: any[], options?: CharacterPlaybackOptions): CharacterPlaybackHandle;
|
|
124
|
+
typedSnippetToClip(name: string, channels: any[], options?: CharacterPlaybackOptions): CharacterPlaybackHandle;
|
|
125
|
+
semanticAnimationToClip(name: string, animation: JsonObject, options?: CharacterPlaybackOptions): CharacterPlaybackHandle;
|
|
126
|
+
playSnippet(snippet: string | {
|
|
127
|
+
name: string;
|
|
128
|
+
curves: JsonObject;
|
|
129
|
+
}, curvesOrOptions?: JsonObject, options?: CharacterPlaybackOptions): CharacterPlaybackHandle;
|
|
130
|
+
playTypedSnippet(snippet: {
|
|
131
|
+
name: string;
|
|
132
|
+
channels: any[];
|
|
133
|
+
}, options?: CharacterPlaybackOptions): CharacterPlaybackHandle;
|
|
134
|
+
playClip(value: string | CharacterPlaybackHandle): CharacterPlaybackHandle;
|
|
135
|
+
supportsClipCurves(): boolean;
|
|
136
|
+
cleanupSnippet(name: string): void;
|
|
137
|
+
crossfadeTo(name: string, seconds: number, options?: CharacterPlaybackOptions): CharacterPlaybackHandle;
|
|
138
|
+
stopAnimation(name: string): void;
|
|
139
|
+
stopAllAnimations(): void;
|
|
140
|
+
pauseAnimation(name: string): void;
|
|
141
|
+
resumeAnimation(name: string): void;
|
|
142
|
+
pauseAllAnimations(): void;
|
|
143
|
+
resumeAllAnimations(): void;
|
|
144
|
+
updateClipParams(name: string, options: CharacterPlaybackOptions): void;
|
|
145
|
+
setAnimationSpeed(name: string, value: number): void;
|
|
146
|
+
setAnimationIntensity(name: string, value: number): void;
|
|
147
|
+
setAnimationLoop(name: string, value: boolean): void;
|
|
148
|
+
setAnimationLoopMode(name: string, value: string): void;
|
|
149
|
+
setAnimationRepeatCount(name: string, value: number | null): void;
|
|
150
|
+
setAnimationReverse(name: string, value: boolean): void;
|
|
151
|
+
setAnimationBlendMode(name: string, value: string): void;
|
|
152
|
+
setAnimationEasing(name: string, value: string): void;
|
|
153
|
+
seekAnimation(name: string, value: number): void;
|
|
154
|
+
setAnimationTime(name: string, value: number): void;
|
|
155
|
+
setSnippetTime(name: string, value: number): void;
|
|
156
|
+
seekSnippet(name: string, value: number): void;
|
|
157
|
+
seek(name: string, value: number): void;
|
|
158
|
+
setAnimationTimeScale(value: number): void;
|
|
159
|
+
getAnimationState(name: string): JsonObject;
|
|
160
|
+
getPlayingAnimations(): string[];
|
|
161
|
+
private commitLive;
|
|
162
|
+
private mutateLive;
|
|
163
|
+
private transition;
|
|
164
|
+
setAU(id: number, value: number, balance?: number): void;
|
|
165
|
+
getAU(id: number): number;
|
|
166
|
+
getAUBalance(id: number): number;
|
|
167
|
+
getBodyControls(): any[];
|
|
168
|
+
getSemanticPoseCatalog(): any[];
|
|
169
|
+
captureSemanticPose(): JsonObject;
|
|
170
|
+
validateSemanticPose(pose: JsonObject): JsonObject;
|
|
171
|
+
applySemanticPose(pose: JsonObject): void;
|
|
172
|
+
validateSemanticAnimation(animation: JsonObject, options?: JsonObject): void;
|
|
173
|
+
resetBodyControls(): void;
|
|
174
|
+
setContinuum(negative: number, positive: number, value: number, balance?: number): void;
|
|
175
|
+
getContinuum(negative: number, positive: number): number;
|
|
176
|
+
transitionAU(id: number, value: number, durationMs?: number, balance?: number): CharacterTransitionHandle;
|
|
177
|
+
setViseme(index: number, value: number, jawScale?: number): void;
|
|
178
|
+
getViseme(index: number): number;
|
|
179
|
+
getVisemeJawScale(index: number): number;
|
|
180
|
+
setVisemeById(id: string, value: number, jawScale?: number): void;
|
|
181
|
+
transitionViseme(index: number, value: number, durationMs?: number, jawScale?: number): CharacterTransitionHandle;
|
|
182
|
+
transitionVisemeById(id: string, value: number, durationMs?: number, jawScale?: number): CharacterTransitionHandle;
|
|
183
|
+
setAUMixWeight(id: number, value: number): void;
|
|
184
|
+
getAUMixWeight(id: number): number;
|
|
185
|
+
hasLeftRightBones(id: number): boolean;
|
|
186
|
+
setMorph(key: string | number, value: number, meshNames?: string[]): void;
|
|
187
|
+
setMorphOnMeshes(meshNames: string[], key: string | number, value: number): void;
|
|
188
|
+
releaseMorph(key: string | number, meshNames?: string[]): void;
|
|
189
|
+
transitionMorph(key: string | number, value: number, durationMs?: number, meshNames?: string[]): CharacterTransitionHandle;
|
|
190
|
+
getMorphTargets(): Record<string, string[]>;
|
|
191
|
+
getMorphTargetIndices(): Record<string, {
|
|
192
|
+
name: string;
|
|
193
|
+
index: number;
|
|
194
|
+
}[]>;
|
|
195
|
+
addMorphTarget(target: Parameters<ThreeFrameApplier['addMorphTarget']>[1], options?: Parameters<ThreeFrameApplier['addMorphTarget']>[2]): number;
|
|
196
|
+
addMorphTargets(targets: Parameters<ThreeFrameApplier['addMorphTargets']>[1], options?: Parameters<ThreeFrameApplier['addMorphTargets']>[2]): Record<string, number>;
|
|
197
|
+
private meshCategory;
|
|
198
|
+
getMeshList(): JsonObject[];
|
|
199
|
+
getBones(): ThreeModelInspection['bones'];
|
|
200
|
+
private meshProfile;
|
|
201
|
+
setMeshVisible(name: string, visible: boolean): void;
|
|
202
|
+
highlightMesh(name: string | null, color?: number, value?: number): void;
|
|
203
|
+
getMeshMaterialConfig(name: string): Record<string, unknown> | null;
|
|
204
|
+
setMeshMaterialConfig(name: string, value: Parameters<ThreeFrameApplier['setMeshMaterialConfig']>[2]): void;
|
|
205
|
+
registerHairObjects(objects: Object3D[]): {
|
|
206
|
+
name: string;
|
|
207
|
+
isMesh: boolean;
|
|
208
|
+
isEyebrow: boolean;
|
|
209
|
+
}[];
|
|
210
|
+
getRegisteredHairObjects(): Object3D[];
|
|
211
|
+
getHairMorphTargets(name?: string): string[];
|
|
212
|
+
getHairAppearance(): JsonObject;
|
|
213
|
+
private setHairAppearance;
|
|
214
|
+
setHairColor(value: string | JsonObject): void;
|
|
215
|
+
setEyebrowColor(value: string | JsonObject): void;
|
|
216
|
+
setHairBaseColor(value: string): void;
|
|
217
|
+
setEyebrowBaseColor(value: string): void;
|
|
218
|
+
setHairGlow(color: string, value: number): void;
|
|
219
|
+
setEyebrowGlow(color: string, value: number): void;
|
|
220
|
+
setHairOutline(value: {
|
|
221
|
+
show: boolean;
|
|
222
|
+
color?: string;
|
|
223
|
+
opacity?: number;
|
|
224
|
+
}): void;
|
|
225
|
+
private restartHair;
|
|
226
|
+
setHairPhysicsEnabled(value: boolean): void;
|
|
227
|
+
isHairPhysicsEnabled(): boolean;
|
|
228
|
+
setHairPhysicsConfig(value: JsonObject): void;
|
|
229
|
+
getHairPhysicsConfig(): JsonObject;
|
|
230
|
+
validateHairMorphTargets(): string[];
|
|
231
|
+
applyHairStateToObject(name: string, state: JsonObject): void;
|
|
232
|
+
private authoredHeadMotion;
|
|
233
|
+
private setHairGravity;
|
|
234
|
+
playHairImpulse(horizontal: number, vertical: number): CharacterPlaybackHandle | undefined;
|
|
235
|
+
start(): void;
|
|
236
|
+
stop(): void;
|
|
237
|
+
clear(): void;
|
|
238
|
+
resetToNeutral(): void;
|
|
239
|
+
dispose(): void;
|
|
240
|
+
}
|
|
241
|
+
export declare function createRustEmbodyHostUnbound(config?: RustEmbodyHostConfig): Embody;
|
|
242
|
+
export declare function createRustEmbodyHost(model: Object3D, config?: RustEmbodyHostConfig): Promise<Embody>;
|
|
243
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Camera, Scene } from 'three';
|
|
2
|
+
import { Embody } from './character';
|
|
3
|
+
import type { RustEmbodyHostConfig } from './character';
|
|
4
|
+
import type { CharacterModelLoadOptions, CharacterModelLoadResult, CharacterModelTransform } from './model';
|
|
5
|
+
import type { CharacterSceneBackend, CharacterSceneRenderer, CharacterSceneRenderingController, DefaultCharacterSceneAsyncOptions, ReadyDefaultCharacterScene } from './scene';
|
|
6
|
+
import type { Profile } from './authoringTypes';
|
|
7
|
+
export interface CharacterHostCharacterOptions extends CharacterModelTransform {
|
|
8
|
+
modelUrl: string;
|
|
9
|
+
presetType?: string;
|
|
10
|
+
profile?: Profile;
|
|
11
|
+
}
|
|
12
|
+
export interface CharacterHostExternalScene {
|
|
13
|
+
scene: Scene;
|
|
14
|
+
renderer: CharacterSceneRenderer;
|
|
15
|
+
backend?: CharacterSceneBackend;
|
|
16
|
+
rendering?: CharacterSceneRenderingController;
|
|
17
|
+
camera: Camera;
|
|
18
|
+
mountCanvas?: boolean;
|
|
19
|
+
manageResize?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface CharacterHostOptions {
|
|
22
|
+
signal?: AbortSignal;
|
|
23
|
+
container: HTMLElement;
|
|
24
|
+
character: CharacterHostCharacterOptions;
|
|
25
|
+
embody?: RustEmbodyHostConfig;
|
|
26
|
+
scene?: Omit<DefaultCharacterSceneAsyncOptions, 'signal'>;
|
|
27
|
+
external?: CharacterHostExternalScene;
|
|
28
|
+
loader?: CharacterModelLoadOptions;
|
|
29
|
+
autoStart?: boolean;
|
|
30
|
+
renderLoop?: boolean;
|
|
31
|
+
autoFrame?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface CharacterHost extends Omit<CharacterModelLoadResult, 'gltf'> {
|
|
34
|
+
engine: Embody;
|
|
35
|
+
scene: Scene;
|
|
36
|
+
readonly renderer: CharacterSceneRenderer | null;
|
|
37
|
+
readonly backend: CharacterSceneBackend | null;
|
|
38
|
+
readonly rendering: CharacterSceneRenderingController | null;
|
|
39
|
+
camera: Camera;
|
|
40
|
+
lighting: ReadyDefaultCharacterScene['lighting'] | null;
|
|
41
|
+
ownsScene: boolean;
|
|
42
|
+
container: HTMLElement;
|
|
43
|
+
setCharacter(character: CharacterHostCharacterOptions, loader?: CharacterModelLoadOptions): Promise<void>;
|
|
44
|
+
resize(): void;
|
|
45
|
+
dispose(): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
/** Acquire a character and bind it to the existing Three rendering integration. */
|
|
48
|
+
export declare function createCharacterHost(options: CharacterHostOptions): Promise<CharacterHost>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AnimationClip } from 'three';
|
|
2
|
+
import type { ClipIRTrack, ThreeModelInspection } from './index';
|
|
3
|
+
/** One PropertyMixer cache key for every concrete renderer destination. */
|
|
4
|
+
export declare function concreteTrackName(target: ClipIRTrack['target'] | undefined, inspection: ThreeModelInspection): string | undefined;
|
|
5
|
+
/** Retain authored samples and interpolants; normalize only cloned binding names. */
|
|
6
|
+
export declare function cloneWithConcreteTrackNames(clip: AnimationClip, tracks: readonly ClipIRTrack[], inspection: ThreeModelInspection): AnimationClip;
|
package/dist/three/index.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { AnimationClip } from 'three';
|
|
2
2
|
export * from './annotations/index';
|
|
3
|
+
export * from './authoring';
|
|
4
|
+
export * from './character';
|
|
5
|
+
export * from './characterHost';
|
|
6
|
+
export { renderScenePlayback, createScenePlaybackFrame } from './playbackRendering';
|
|
3
7
|
import type { ThreeModelReferencePose } from './reference-pose';
|
|
4
8
|
export { captureModelReferencePose, bindModelReferencePose, extendModelReferencePose } from './reference-pose';
|
|
5
9
|
export type { ThreeModelReferencePose, ThreeReferencePoseNode } from './reference-pose';
|
|
10
|
+
export { ThreeNativePlaybackConnector } from './nativePlayback';
|
|
11
|
+
export type { ThreeNativeLoop, ThreeNativePlaybackOptions, ThreeNativePlaybackControl, ThreeNativePlaybackEvent, ThreeNativePlaybackBinding, } from './nativePlayback';
|
|
6
12
|
import type { Material, Mesh, Object3D } from 'three';
|
|
7
|
-
export { ThreeGazeFocus } from './gaze';
|
|
8
|
-
export type { ThreeGazeFocusOptions, ThreeGazeFocusRequest, ThreeGazeFocusControls, ThreeGazeFocusDiagnostic } from './gaze';
|
|
9
13
|
export declare const THREE_BLENDING_MODES: {
|
|
10
14
|
readonly Normal: 1;
|
|
11
15
|
readonly Additive: 2;
|
|
@@ -13,6 +17,13 @@ export declare const THREE_BLENDING_MODES: {
|
|
|
13
17
|
readonly Multiply: 4;
|
|
14
18
|
readonly None: 0;
|
|
15
19
|
};
|
|
20
|
+
export declare const BLENDING_MODES: {
|
|
21
|
+
readonly Normal: 1;
|
|
22
|
+
readonly Additive: 2;
|
|
23
|
+
readonly Subtractive: 3;
|
|
24
|
+
readonly Multiply: 4;
|
|
25
|
+
readonly None: 0;
|
|
26
|
+
};
|
|
16
27
|
type BoneEntry = {
|
|
17
28
|
obj: Object3D;
|
|
18
29
|
basePos: {
|
|
@@ -43,7 +54,15 @@ type AddMorphTargetOptions = {
|
|
|
43
54
|
resetInfluence?: boolean;
|
|
44
55
|
};
|
|
45
56
|
export type ThreeModelInspection = {
|
|
46
|
-
descriptor: Record<string, unknown
|
|
57
|
+
descriptor: Record<string, unknown> & {
|
|
58
|
+
morphTargets: Array<{
|
|
59
|
+
id: number;
|
|
60
|
+
meshId: number | undefined;
|
|
61
|
+
name: string;
|
|
62
|
+
hostIndex: number;
|
|
63
|
+
initialValue: number;
|
|
64
|
+
}>;
|
|
65
|
+
};
|
|
47
66
|
meshByName: Map<string, Mesh>;
|
|
48
67
|
allMeshes: Mesh[];
|
|
49
68
|
morphMeshes: Mesh[];
|
|
@@ -86,6 +105,11 @@ export type ClipIRTrack = {
|
|
|
86
105
|
export type ClipIR = {
|
|
87
106
|
name: string;
|
|
88
107
|
durationSeconds?: number;
|
|
108
|
+
channels?: Array<{
|
|
109
|
+
id: number;
|
|
110
|
+
kind: string;
|
|
111
|
+
name?: string;
|
|
112
|
+
}>;
|
|
89
113
|
tracks: ClipIRTrack[];
|
|
90
114
|
};
|
|
91
115
|
/**
|
|
@@ -107,7 +131,7 @@ export declare function serializeAnimationClips(model: Object3D, clips: readonly
|
|
|
107
131
|
kind: string;
|
|
108
132
|
name: string;
|
|
109
133
|
}[];
|
|
110
|
-
tracks:
|
|
134
|
+
tracks: ClipIRTrack[];
|
|
111
135
|
}[];
|
|
112
136
|
type MaterialConfig = {
|
|
113
137
|
renderOrder?: number;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { AnimationMixer } from 'three';
|
|
2
|
+
import type { AnimationAction, AnimationClip, Object3D } from 'three';
|
|
3
|
+
import type { NativePlaybackSession } from '../wasm/index';
|
|
4
|
+
import type { ClipIR, ThreeModelInspection } from './index';
|
|
5
|
+
export type ThreeNativeLoop = {
|
|
6
|
+
mode: 'once' | 'repeat' | 'pingPong';
|
|
7
|
+
count?: number | null;
|
|
8
|
+
};
|
|
9
|
+
export type ThreeNativePlaybackOptions = {
|
|
10
|
+
replace?: string;
|
|
11
|
+
startSeconds?: number;
|
|
12
|
+
speed?: number;
|
|
13
|
+
/** Native contribution only; semantic intensity belongs in the compiled clip. */
|
|
14
|
+
weight?: number;
|
|
15
|
+
blendMode?: 'normal' | 'additive';
|
|
16
|
+
loop?: ThreeNativeLoop;
|
|
17
|
+
finalPose?: 'release' | 'hold';
|
|
18
|
+
};
|
|
19
|
+
export type ThreeNativePlaybackControl = {
|
|
20
|
+
type: 'pause' | 'resume' | 'stop';
|
|
21
|
+
} | {
|
|
22
|
+
type: 'seek';
|
|
23
|
+
seconds: number;
|
|
24
|
+
} | {
|
|
25
|
+
type: 'setSpeed';
|
|
26
|
+
speed: number;
|
|
27
|
+
} | {
|
|
28
|
+
type: 'setWeight';
|
|
29
|
+
weight: number;
|
|
30
|
+
} | {
|
|
31
|
+
type: 'setBlendMode';
|
|
32
|
+
blendMode: 'normal' | 'additive';
|
|
33
|
+
} | {
|
|
34
|
+
type: 'setLoop';
|
|
35
|
+
loop: ThreeNativeLoop;
|
|
36
|
+
} | {
|
|
37
|
+
type: 'setFinalPose';
|
|
38
|
+
finalPose: 'release' | 'hold';
|
|
39
|
+
} | {
|
|
40
|
+
type: 'fadeIn' | 'fadeOut';
|
|
41
|
+
seconds: number;
|
|
42
|
+
};
|
|
43
|
+
export type ThreeNativePlaybackEvent = {
|
|
44
|
+
type: 'completed';
|
|
45
|
+
handle: string;
|
|
46
|
+
} | {
|
|
47
|
+
type: 'cancelled';
|
|
48
|
+
handle: string;
|
|
49
|
+
reason: string;
|
|
50
|
+
} | {
|
|
51
|
+
type: 'error';
|
|
52
|
+
handle: string;
|
|
53
|
+
message: string;
|
|
54
|
+
};
|
|
55
|
+
export type ThreeNativePlaybackBinding = {
|
|
56
|
+
model: Object3D;
|
|
57
|
+
inspection: ThreeModelInspection;
|
|
58
|
+
/** Optional existing native mixer. Otherwise the connector owns one. */
|
|
59
|
+
mixer?: AnimationMixer;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Execute validated Rust commands on the native mixer. There is no
|
|
63
|
+
* clock or update API. Each play owns a unique clip/action; other mixer users
|
|
64
|
+
* remain untouched by stop, replacement, rebind and disposal.
|
|
65
|
+
*
|
|
66
|
+
* The connector owns the supplied Wasm session and frees it after successful
|
|
67
|
+
* disposal. A failed release retains ownership and can be retried by dispose.
|
|
68
|
+
*/
|
|
69
|
+
export declare class ThreeNativePlaybackConnector {
|
|
70
|
+
private readonly session;
|
|
71
|
+
private binding;
|
|
72
|
+
private rendering;
|
|
73
|
+
private renderingEnabled;
|
|
74
|
+
private readonly resources;
|
|
75
|
+
private readonly actionHandles;
|
|
76
|
+
private readonly listeners;
|
|
77
|
+
private readonly pending;
|
|
78
|
+
private readonly notifications;
|
|
79
|
+
private depth;
|
|
80
|
+
private flushingNotifications;
|
|
81
|
+
private notificationScheduled;
|
|
82
|
+
private sessionDisposed;
|
|
83
|
+
private disposed;
|
|
84
|
+
private readonly onError?;
|
|
85
|
+
private readonly onRelease?;
|
|
86
|
+
constructor(session: NativePlaybackSession, binding: ThreeNativePlaybackBinding & {
|
|
87
|
+
onError?: (error: Error) => void;
|
|
88
|
+
onRelease?: (handle: string) => void;
|
|
89
|
+
});
|
|
90
|
+
/** Prepare bindings first; old actions are released before the new binding is exposed. */
|
|
91
|
+
rebind(modelKey: string, profileKey: string, binding?: ThreeNativePlaybackBinding): void;
|
|
92
|
+
play(clip: ClipIR, options?: ThreeNativePlaybackOptions): string;
|
|
93
|
+
/**
|
|
94
|
+
* Validate native track bindings through the existing serializer, then retain
|
|
95
|
+
* the native clone's interpolants and authored/additive sample values. Concrete
|
|
96
|
+
* binding names match compiled tracks so Three shares their PropertyMixer.
|
|
97
|
+
*/
|
|
98
|
+
playNativeClip(clip: AnimationClip, options?: ThreeNativePlaybackOptions): string;
|
|
99
|
+
control(handle: string, control: ThreeNativePlaybackControl): void;
|
|
100
|
+
setRendering(enabled: boolean): void;
|
|
101
|
+
setTimeScale(value: number): void;
|
|
102
|
+
fadeIn(handle: string, seconds: number): void;
|
|
103
|
+
fadeOut(handle: string, seconds: number): void;
|
|
104
|
+
/** Edit authored samples, retaining the native action and its loop/fade progress. */
|
|
105
|
+
replaceClip(handle: string, clip: AnimationClip): void;
|
|
106
|
+
/** Native state for the owning adapter; never exposed through Polymer. */
|
|
107
|
+
getAction(handle: string): AnimationAction | undefined;
|
|
108
|
+
/** Deliver native completion after the borrowed mixer has finished sampling. */
|
|
109
|
+
flushEvents(): void;
|
|
110
|
+
subscribe(listener: (event: ThreeNativePlaybackEvent) => void): () => void;
|
|
111
|
+
dispose(): void;
|
|
112
|
+
private pauseFade;
|
|
113
|
+
private resumeFade;
|
|
114
|
+
private beforeOperation;
|
|
115
|
+
private retryPending;
|
|
116
|
+
private dispatch;
|
|
117
|
+
private drain;
|
|
118
|
+
private execute;
|
|
119
|
+
private readonly finished;
|
|
120
|
+
private flushNotifications;
|
|
121
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Timer } from 'three';
|
|
2
|
+
import type { AnimationMixer, Object3D } from 'three';
|
|
3
|
+
/** Register native playback with the existing scene renderer; never starts a loop. */
|
|
4
|
+
export declare function bindPlaybackRendering(model: Object3D, mixer: AnimationMixer, afterFrame: () => void): {
|
|
5
|
+
setEnabled(enabled: boolean): void;
|
|
6
|
+
dispose(): void;
|
|
7
|
+
};
|
|
8
|
+
/** Called once by the Three render integration, using its native Timer. */
|
|
9
|
+
export declare function renderScenePlayback(scene: Object3D, timer: Timer): void;
|
|
10
|
+
/** Frame hook for an existing Three/R3F renderer. Does not create a render loop. */
|
|
11
|
+
export declare function createScenePlaybackFrame(scene: Object3D, document?: Document): {
|
|
12
|
+
onFrame(timestamp?: number): void;
|
|
13
|
+
dispose(): void;
|
|
14
|
+
};
|