@lovelace_lol/embody 0.0.15 → 0.0.16
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/README.md +407 -149
- package/dist/index.js +1320 -381
- package/dist/index.js.map +1 -1
- package/dist/three/annotations/modelObservation.d.ts +9 -7
- package/dist/three/annotations/morphGeometry.d.ts +19 -0
- package/dist/three/authoring.d.ts +18 -18
- package/dist/three/authoringTypes.d.ts +38 -4
- package/dist/three/character.d.ts +58 -14
- package/dist/three/index.d.ts +12 -11
- package/dist/three/model.d.ts +2 -0
- package/dist/three/nativePlayback.d.ts +6 -0
- package/dist/three/playbackRendering.d.ts +1 -1
- package/dist/three/scene.d.ts +2 -0
- package/dist/three/sceneBackground.d.ts +11 -0
- package/dist/three/scenery.d.ts +46 -0
- package/dist/three/vrm-animation.d.ts +70 -0
- package/dist/three.js +1320 -381
- package/dist/three.js.map +1 -1
- package/dist/wasm/README.md +407 -149
- package/dist/wasm/embody_wasm.d.ts +241 -95
- package/dist/wasm/embody_wasm.js +541 -31
- package/dist/wasm/embody_wasm_bg.wasm +0 -0
- package/dist/wasm/embody_wasm_bg.wasm.d.ts +113 -88
- package/dist/wasm/highlighting.d.ts +16 -0
- package/dist/wasm/index.d.ts +10 -0
- package/dist/wasm/savedAnimation.d.ts +4 -0
- package/dist/wasm.js +1123 -2
- package/dist/wasm.js.map +1 -1
- package/model-tools/index.d.ts +57 -0
- package/model-tools/index.mjs +354 -0
- package/model-tools/prepare-actor.mjs +79 -0
- package/package.json +19 -5
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
2
|
import type { NativeAnnotationRuntime } from './runtime';
|
|
3
|
+
export { readAttribute } from './morphGeometry';
|
|
3
4
|
type Bounds = {
|
|
4
5
|
min: number[];
|
|
5
6
|
max: number[];
|
|
@@ -20,25 +21,26 @@ export interface AnnotationModelObservation {
|
|
|
20
21
|
morphNames: string[];
|
|
21
22
|
}[];
|
|
22
23
|
}
|
|
23
|
-
export declare function readAttribute(attribute: THREE.BufferAttribute | THREE.InterleavedBufferAttribute): Float32Array;
|
|
24
24
|
/** Stable native handle table. No region matching or anchor policy lives here. */
|
|
25
25
|
export declare class AnnotationModelObserver {
|
|
26
26
|
readonly model: THREE.Object3D;
|
|
27
27
|
readonly objects: Map<number, THREE.Object3D<THREE.Object3DEventMap>>;
|
|
28
28
|
readonly meshes: THREE.Mesh[];
|
|
29
29
|
private readonly ids;
|
|
30
|
+
private morphGeneration;
|
|
31
|
+
private morphObservations;
|
|
32
|
+
private readonly morphGeometry;
|
|
33
|
+
private readonly vertex;
|
|
30
34
|
constructor(model: THREE.Object3D);
|
|
31
35
|
id(object: THREE.Object3D): number | undefined;
|
|
36
|
+
private updateWorldMatrices;
|
|
32
37
|
capture(): AnnotationModelObservation;
|
|
33
38
|
observe(runtime: NativeAnnotationRuntime): void;
|
|
34
39
|
transforms(runtime: NativeAnnotationRuntime): Float32Array;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
z: number;
|
|
39
|
-
}>;
|
|
40
|
+
private prepareMorphAnchors;
|
|
41
|
+
/** Transport only: Rust owns the vertex selection, weights and live anchor. */
|
|
42
|
+
observeMorphAnchors(runtime: NativeAnnotationRuntime): void;
|
|
40
43
|
/** Rust selects influenced vertices; Three evaluates the current native pose. */
|
|
41
44
|
observeFocus(runtime: NativeAnnotationRuntime, request: unknown): void;
|
|
42
45
|
}
|
|
43
46
|
export declare function observeAnnotationModel(model: THREE.Object3D): AnnotationModelObservation;
|
|
44
|
-
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
type Attribute = THREE.BufferAttribute | THREE.InterleavedBufferAttribute;
|
|
3
|
+
export declare function readAttribute(attribute: Attribute): Float32Array;
|
|
4
|
+
export declare function readMorphGeometry(mesh: THREE.Mesh, names: string[]): {
|
|
5
|
+
base: Float32Array;
|
|
6
|
+
morphs: Float32Array;
|
|
7
|
+
relative: boolean;
|
|
8
|
+
} | null;
|
|
9
|
+
export declare function updateAnnotationWorldMatrices(model: THREE.Object3D): void;
|
|
10
|
+
export declare function sampleMorphVertices(mesh: THREE.Mesh, indices: ArrayLike<number>, samples: Float32Array, vertex?: THREE.Vector3): void;
|
|
11
|
+
/** Native identities/versions only. Rust decides whether this observation
|
|
12
|
+
* invalidates an attachment and which geometry/vertices are needed next. */
|
|
13
|
+
export declare class MorphGeometryObservation {
|
|
14
|
+
revision: number;
|
|
15
|
+
namesJson: string;
|
|
16
|
+
private signature;
|
|
17
|
+
observe(mesh: THREE.Mesh): void;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -9,52 +9,52 @@ export declare const getPreset: (id: Types.PresetType) => Types.Profile;
|
|
|
9
9
|
export declare const extendCharacterConfigWithPreset: <T extends Types.ProfileRuntimeConfig>(config: T) => T;
|
|
10
10
|
export declare const extractProfileOverrides: (config: Types.ProfileRuntimeConfig) => Partial<Types.Profile>;
|
|
11
11
|
export declare const mergeCharacterRegionsByName: (base?: Region[], override?: Region[]) => Region[];
|
|
12
|
-
export declare const getMeshNamesForAUProfile: (profile: Types.Profile
|
|
12
|
+
export declare const getMeshNamesForAUProfile: (profile: Partial<Types.Profile>, auId: number) => string[];
|
|
13
13
|
/** Resolve routing and legacy mesh aliases once for an editor inventory. */
|
|
14
14
|
export declare const resolveMorphMeshSelections: (profile: Partial<Pick<Types.Profile, "morphToMesh" | "visemeMeshCategory">>, categories: string[], availableNames: string[]) => Record<string, Types.MorphMeshSelection>;
|
|
15
15
|
export declare const getHumanoidSpecification: () => Types.HumanoidSpecification;
|
|
16
|
-
export declare const setAUMorphTargets: (profile: Types.
|
|
17
|
-
export declare const setHumanoidRoleBinding: (profile: Types.
|
|
18
|
-
export declare const resolveHumanoidCharacterization: (profile: Types.Profile) => Types.HumanoidCharacterizationResolution;
|
|
19
|
-
export declare const hasLeftRightMorphs: (profile: Types.Profile
|
|
20
|
-
export declare const isMixedAU: (profile: Types.Profile
|
|
16
|
+
export declare const setAUMorphTargets: (profile: Types.ProfileInput, auId: number, side: "left" | "right" | "center", targets: Types.MorphTargetRef[]) => Partial<Types.Profile> & Pick<Types.Profile, "auToMorphs">;
|
|
17
|
+
export declare const setHumanoidRoleBinding: (profile: Types.ProfileInput, role: Types.VRMHumanoidRole, boneName: string | null) => Partial<Types.Profile>;
|
|
18
|
+
export declare const resolveHumanoidCharacterization: (profile: Partial<Types.Profile>) => Types.HumanoidCharacterizationResolution;
|
|
19
|
+
export declare const hasLeftRightMorphs: (profile: Partial<Types.Profile>, auId: number) => boolean;
|
|
20
|
+
export declare const isMixedAU: (profile: Partial<Types.Profile>, auId: number) => boolean;
|
|
21
21
|
export declare const resolveVisemeProfile: (profile: Partial<Types.Profile>) => Types.ResolvedVisemeProfile;
|
|
22
22
|
export declare const isMaxDegreesOnlyAxisBindingUpdate: (update: Types.BoneAxisBindingUpdate) => boolean;
|
|
23
|
-
export declare const findNodeKeyForBone: (boneName: string, profile: Types.Profile | null) => string | null;
|
|
23
|
+
export declare const findNodeKeyForBone: (boneName: string, profile: Partial<Types.Profile> | null) => string | null;
|
|
24
24
|
export declare const ensureBoneNodeKey: (profile: Types.Profile, boneName: string) => {
|
|
25
25
|
nodeKey: string;
|
|
26
26
|
boneNodes: Record<string, string>;
|
|
27
27
|
};
|
|
28
|
-
export declare const ensureBilateralBoneNodeKeys: (profile: Types.
|
|
28
|
+
export declare const ensureBilateralBoneNodeKeys: (profile: Types.ProfileInput, leftBoneName: string, rightBoneName: string) => Partial<Types.Profile>;
|
|
29
29
|
export declare const resolveBoneNameForNodeKey: (profile: Types.Profile, nodeKey: string) => string | null;
|
|
30
30
|
export declare const stripConfiguredBoneAffixes: (profile: Pick<Types.Profile, "bonePrefix" | "boneSuffix"> | null | undefined, boneName: string) => string;
|
|
31
31
|
export declare const inferChiralBoneNamePair: (boneNames: string[], selectedBoneName: string) => Types.ChiralBoneNamePair | null;
|
|
32
32
|
export declare const formatAxisLabel: (axis: Types.BoneAxisKey) => string;
|
|
33
33
|
export declare const formatAxisDirectionLabel: (axis: Types.BoneAxisKey, direction: Types.BoneAxisDirection) => string;
|
|
34
34
|
export declare const getAxisFromChannel: (channel?: string) => Types.BoneAxisKey | null;
|
|
35
|
-
export declare const getBoneAxisBindingState: (profile: Types.Profile
|
|
35
|
+
export declare const getBoneAxisBindingState: (profile: Partial<Types.Profile>, boneName: string, axis: Types.BoneAxisKey) => Types.BoneAxisBindingState | null;
|
|
36
36
|
export declare const resolveBoneAxisChannel: (profile: Types.Profile, boneName: string, axis: Types.BoneAxisKey) => Types.RotationChannel;
|
|
37
|
-
export declare const getBilateralAxisBindingState: (profile: Types.Profile
|
|
38
|
-
export declare const getAUBoneBindingState: (profile: Types.Profile
|
|
37
|
+
export declare const getBilateralAxisBindingState: (profile: Partial<Types.Profile>, boneName: string, axis: Types.BoneAxisKey) => Types.BilateralAxisBindingState | null;
|
|
38
|
+
export declare const getAUBoneBindingState: (profile: Partial<Types.Profile>, auId: number) => Types.AUBoneBindingState;
|
|
39
39
|
/** Resolve a panel's bone links without repeatedly serializing its full character. */
|
|
40
40
|
export declare const getAUBoneBindingStates: (profile: Partial<Pick<Types.Profile, "auToBones" | "boneNodes" | "bonePrefix" | "boneSuffix" | "suffixPattern" | "compositeRotations" | "continuumPairs" | "humanoidCharacterization">>, auIds: readonly number[]) => Record<number, Types.AUBoneBindingState>;
|
|
41
41
|
export declare const inferEyeControlScope: (profile: Pick<Types.Profile, "auToBones">, binding: Pick<Types.BoneAxisBindingState, "nodeKey" | "negativeAuId" | "positiveAuId">) => Types.BoneControlScope | null;
|
|
42
42
|
export declare const inferEyeControlFamily: (binding: Pick<Types.BoneAxisBindingState, "nodeKey" | "axis">) => Types.BoneControlFamily | null;
|
|
43
|
-
export declare const applyBoneAxisBindingUpdate: (profile: Types.
|
|
44
|
-
export declare const applyBilateralAxisBindingUpdate: (profile: Types.
|
|
43
|
+
export declare const applyBoneAxisBindingUpdate: (profile: Types.ProfileInput, boneName: string, axis: Types.BoneAxisKey, update: Types.BoneAxisBindingUpdate) => Partial<Types.Profile>;
|
|
44
|
+
export declare const applyBilateralAxisBindingUpdate: (profile: Types.ProfileInput, boneName: string, axis: Types.BoneAxisKey, scope: Types.BilateralBoneAxisScope, update: Types.BoneAxisBindingUpdate) => Partial<Types.Profile>;
|
|
45
45
|
export declare const applyAUBoneBindingUpdate: (profile: Types.Profile, auId: number, update: {
|
|
46
46
|
boneName: string | null;
|
|
47
47
|
axis: Types.BoneAxisKey;
|
|
48
48
|
direction: Types.BoneAxisDirection;
|
|
49
49
|
maxDegrees: number | null;
|
|
50
50
|
}) => Types.Profile;
|
|
51
|
-
export declare const createBoneAxisAu: (profile: Types.
|
|
51
|
+
export declare const createBoneAxisAu: (profile: Types.ProfileInput, boneName: string, axis: Types.BoneAxisKey, direction: Types.BoneAxisDirection, options?: {
|
|
52
52
|
name?: string;
|
|
53
53
|
}) => Types.CreatedBoneAxisAu;
|
|
54
|
-
export declare const createBilateralBoneAxisAu: (profile: Types.
|
|
54
|
+
export declare const createBilateralBoneAxisAu: (profile: Types.ProfileInput, boneName: string, axis: Types.BoneAxisKey, scope: Types.BilateralBoneAxisScope, direction: Types.BoneAxisDirection, options?: {
|
|
55
55
|
name?: string;
|
|
56
56
|
}) => Types.CreatedBoneAxisAu;
|
|
57
|
-
export declare const buildBoneAuOptions: (profile: Types.Profile) => Array<{
|
|
57
|
+
export declare const buildBoneAuOptions: (profile: Partial<Types.Profile>) => Array<{
|
|
58
58
|
value: string;
|
|
59
59
|
label: string;
|
|
60
60
|
detail?: string;
|
|
@@ -64,7 +64,7 @@ export declare const classifyAuAsJointControl: (profile: Types.Profile, auId: nu
|
|
|
64
64
|
boneName?: string | null;
|
|
65
65
|
nodeKey?: string | null;
|
|
66
66
|
}) => Types.Profile;
|
|
67
|
-
export declare const resolveContinuumDisplayLabel: (profile: Pick<Types.Profile, "continuumPairs" | "continuumLabels" | "auInfo" | "boneNodes" | "bonePrefix" | "boneSuffix"
|
|
67
|
+
export declare const resolveContinuumDisplayLabel: (profile: Partial<Pick<Types.Profile, "continuumPairs" | "continuumLabels" | "auInfo" | "boneNodes" | "bonePrefix" | "boneSuffix">>, negativeAuId: number, positiveAuId: number) => string;
|
|
68
68
|
export declare function extractModelData(model: Object3D, meshes?: Mesh[], animations?: AnimationClip[]): Types.ModelData;
|
|
69
69
|
export declare function analyzeModel(options: {
|
|
70
70
|
source: {
|
|
@@ -80,7 +80,7 @@ export declare function analyzeModel(options: {
|
|
|
80
80
|
suggestCorrections?: boolean;
|
|
81
81
|
}): Promise<Types.ModelAnalysisReport>;
|
|
82
82
|
export declare function validateMappings(meshes: unknown[], skeleton: unknown, profile: Partial<Types.Profile>, options?: Record<string, unknown>): Types.ValidationResult;
|
|
83
|
-
export declare function validateHumanoidCharacterization(model: Object3D, profile: Types.Profile): Types.HumanoidCharacterizationResolution;
|
|
83
|
+
export declare function validateHumanoidCharacterization(model: Object3D, profile: Partial<Types.Profile>): Types.HumanoidCharacterizationResolution;
|
|
84
84
|
export declare function normalizeHairColorAppearance(value: Types.HairColorAppearance | string, fallback?: Types.HairColorAppearance): Types.HairColorAppearance;
|
|
85
85
|
export declare const getHumanoidSkeletonTemplate: (id: string) => Types.HumanoidSkeletonTemplate | null;
|
|
86
86
|
export declare function getHumanoidSkeletonTemplateBoneNames(template?: Types.HumanoidSkeletonTemplate): string[];
|
|
@@ -25,7 +25,7 @@ export interface MorphMeshSelection {
|
|
|
25
25
|
resolvedNames: string[];
|
|
26
26
|
unresolvedNames: string[];
|
|
27
27
|
}
|
|
28
|
-
export type MeshCategory = 'body' | 'eye' | 'eyeOcclusion' | 'tearLine' | 'teeth' | 'tongue' | 'hair' | 'eyebrow' | 'cornea' | 'eyelash';
|
|
28
|
+
export type MeshCategory = 'body' | 'eye' | 'eyeOcclusion' | 'tearLine' | 'teeth' | 'tongue' | 'hair' | 'eyebrow' | 'cornea' | 'eyelash' | 'other';
|
|
29
29
|
export type BlendingMode = 'Normal' | 'Additive' | 'Subtractive' | 'Multiply' | 'None';
|
|
30
30
|
export interface MorphTargetsBySide {
|
|
31
31
|
left: MorphTargetRef[];
|
|
@@ -123,6 +123,8 @@ export interface MeshMaterialSettings {
|
|
|
123
123
|
depthTest?: boolean;
|
|
124
124
|
blending?: BlendingMode;
|
|
125
125
|
}
|
|
126
|
+
/** Current values read from a native mesh and its first material. */
|
|
127
|
+
export type ThreeResolvedMaterialConfig = Required<MeshMaterialSettings>;
|
|
126
128
|
export interface MeshInfo {
|
|
127
129
|
name?: string;
|
|
128
130
|
visible?: boolean;
|
|
@@ -259,6 +261,8 @@ export interface Profile {
|
|
|
259
261
|
hairPhysics?: HairPhysicsProfileConfig;
|
|
260
262
|
humanoidCharacterization?: HumanoidCharacterization;
|
|
261
263
|
}
|
|
264
|
+
/** Intake accepts app metadata while keeping the profile's known keys explicit. */
|
|
265
|
+
export type ProfileInput = Partial<Profile> | (Partial<Profile> & Record<string, unknown>);
|
|
262
266
|
export interface ProfileRuntimeConfig extends Partial<Profile> {
|
|
263
267
|
profilePresetId?: PresetType;
|
|
264
268
|
presetId?: PresetType;
|
|
@@ -297,6 +301,22 @@ export type CharacterConfig = CharacterProfile & {
|
|
|
297
301
|
modelPath: string;
|
|
298
302
|
regions: Region[];
|
|
299
303
|
};
|
|
304
|
+
export type AnimationSource = string;
|
|
305
|
+
export type BakedClipChannel = 'face' | 'body' | 'scene' | 'custom';
|
|
306
|
+
/** Rust's clip catalog describes which native channels can be played. */
|
|
307
|
+
export interface BakedClipChannelInfo {
|
|
308
|
+
channel: BakedClipChannel;
|
|
309
|
+
trackCount: number;
|
|
310
|
+
playable: boolean;
|
|
311
|
+
blendMode?: 'replace' | 'additive';
|
|
312
|
+
}
|
|
313
|
+
export interface AnimationClipInfo {
|
|
314
|
+
name: string;
|
|
315
|
+
duration: number;
|
|
316
|
+
trackCount: number;
|
|
317
|
+
source: AnimationSource;
|
|
318
|
+
channels: BakedClipChannelInfo[];
|
|
319
|
+
}
|
|
300
320
|
export interface HairColorAppearance {
|
|
301
321
|
name: string;
|
|
302
322
|
baseColor: string;
|
|
@@ -310,9 +330,23 @@ export interface HairAppearanceState {
|
|
|
310
330
|
outlineColor: string;
|
|
311
331
|
outlineOpacity: number;
|
|
312
332
|
}
|
|
313
|
-
export interface HairPhysicsRuntimeConfig {
|
|
333
|
+
export interface HairPhysicsRuntimeConfig extends Omit<HairPhysicsProfileConfig, 'direction' | 'morphTargets'> {
|
|
314
334
|
enabled: boolean;
|
|
315
|
-
|
|
335
|
+
direction?: {
|
|
336
|
+
yawSign?: number;
|
|
337
|
+
pitchSign?: number;
|
|
338
|
+
} | null;
|
|
339
|
+
/** Runtime normalization accepts authored records and returns names/weights. */
|
|
340
|
+
morphTargets?: {
|
|
341
|
+
swayLeft?: string | HairMorphTargetMapping | null;
|
|
342
|
+
swayRight?: string | HairMorphTargetMapping | null;
|
|
343
|
+
swayFront?: string | HairMorphTargetMapping | null;
|
|
344
|
+
fluffRight?: string | HairMorphTargetMapping | null;
|
|
345
|
+
fluffBottom?: string | HairMorphTargetMapping | null;
|
|
346
|
+
headUp?: Record<string, number | HairMorphTargetValueMapping | null> | null;
|
|
347
|
+
headDown?: Record<string, number | HairMorphTargetValueMapping | null> | null;
|
|
348
|
+
} | null;
|
|
349
|
+
[extension: string]: unknown;
|
|
316
350
|
}
|
|
317
351
|
export type HairPhysicsRuntimeConfigUpdate = Partial<HairPhysicsRuntimeConfig>;
|
|
318
352
|
export interface TransitionHandle {
|
|
@@ -392,7 +426,7 @@ export interface ChiralBoneNamePair {
|
|
|
392
426
|
}
|
|
393
427
|
export interface CreatedBoneAxisAu {
|
|
394
428
|
auId: number;
|
|
395
|
-
profile: Profile
|
|
429
|
+
profile: Partial<Profile>;
|
|
396
430
|
}
|
|
397
431
|
export interface BoneInfo {
|
|
398
432
|
name: string;
|
|
@@ -4,17 +4,31 @@ import type { AUDescriptor } from '@lovelace_lol/embody/wasm';
|
|
|
4
4
|
import { ThreeFrameApplier } from './index';
|
|
5
5
|
import type { ThreeModelInspection } from './index';
|
|
6
6
|
import type { ThreeModelReferencePose } from './reference-pose';
|
|
7
|
+
import type { VrmAnimationFile, VrmAnimationInfo, VrmAnimationUnits } from './vrm-animation';
|
|
7
8
|
import type { ThreeNativePlaybackEvent } from './nativePlayback';
|
|
9
|
+
import type { AnimationClipInfo, HairAppearanceState, HairColorAppearance, HairPhysicsRuntimeConfig, HairPhysicsRuntimeConfigUpdate, MeshInfo, Profile, ProfileInput, ThreeResolvedMaterialConfig } from './authoringTypes';
|
|
8
10
|
type JsonObject = Record<string, any>;
|
|
9
11
|
export type RustEmbodyHostConfig = {
|
|
10
12
|
profileMode?: 'preset' | 'profile';
|
|
11
13
|
presetId?: string;
|
|
12
14
|
presetType?: string;
|
|
13
|
-
profile?:
|
|
15
|
+
profile?: ProfileInput;
|
|
14
16
|
meshes?: Mesh[];
|
|
15
17
|
referencePose?: ThreeModelReferencePose;
|
|
16
18
|
};
|
|
17
19
|
export type CharacterPlaybackOptions = JsonObject;
|
|
20
|
+
/** Semantic AU values keyed by numeric AU id. */
|
|
21
|
+
export type CharacterAUState = {
|
|
22
|
+
live: Record<string, number>;
|
|
23
|
+
animated: Record<string, number>;
|
|
24
|
+
total: Record<string, number>;
|
|
25
|
+
unreadable: string[];
|
|
26
|
+
};
|
|
27
|
+
export type CharacterAUGoalMeasurement = {
|
|
28
|
+
distance: number;
|
|
29
|
+
reversal: boolean;
|
|
30
|
+
current: Record<string, number>;
|
|
31
|
+
};
|
|
18
32
|
export type CharacterPlaybackEvent = ThreeNativePlaybackEvent & {
|
|
19
33
|
actionId: string;
|
|
20
34
|
clipName: string;
|
|
@@ -69,10 +83,12 @@ export declare class Embody {
|
|
|
69
83
|
private readonly profileMode;
|
|
70
84
|
private readonly preset;
|
|
71
85
|
private readonly sources;
|
|
86
|
+
private readonly vrmAnimations;
|
|
72
87
|
private readonly playbacks;
|
|
73
88
|
private readonly current;
|
|
74
89
|
private playDepth;
|
|
75
90
|
private readonly pendingEvents;
|
|
91
|
+
private readonly pendingReleases;
|
|
76
92
|
private bindingGeneration;
|
|
77
93
|
private disposed;
|
|
78
94
|
private rendering;
|
|
@@ -80,6 +96,7 @@ export declare class Embody {
|
|
|
80
96
|
private nextLiveTarget;
|
|
81
97
|
private readonly liveTargets;
|
|
82
98
|
private readonly hairObjects;
|
|
99
|
+
private hairHeadObservation?;
|
|
83
100
|
private hairConfig;
|
|
84
101
|
private hairAppearance;
|
|
85
102
|
constructor(config?: RustEmbodyHostConfig);
|
|
@@ -98,12 +115,13 @@ export declare class Embody {
|
|
|
98
115
|
private bind;
|
|
99
116
|
bindModel(meshes?: Mesh[]): void;
|
|
100
117
|
extendReferencePose(): ThreeModelReferencePose;
|
|
101
|
-
setProfile(value:
|
|
102
|
-
getProfile():
|
|
118
|
+
setProfile(value: ProfileInput): void;
|
|
119
|
+
getProfile(): Partial<Profile>;
|
|
103
120
|
getProfileMode(): 'preset' | 'profile';
|
|
104
121
|
getPresetId(): string | null;
|
|
105
122
|
supportsPreset(value?: string): boolean;
|
|
106
123
|
private onPlaybackEvent;
|
|
124
|
+
private flushPendingPlaybackEvents;
|
|
107
125
|
private compile;
|
|
108
126
|
private restValues;
|
|
109
127
|
private materialize;
|
|
@@ -113,10 +131,17 @@ export declare class Embody {
|
|
|
113
131
|
private handle;
|
|
114
132
|
private forget;
|
|
115
133
|
private updatePlayback;
|
|
134
|
+
supportsVrmAnimation(): boolean;
|
|
135
|
+
convertMixamoFbxToVrmAnimations(bytes: ArrayBuffer, options: VrmAnimationUnits): VrmAnimationFile[];
|
|
136
|
+
getVrmAnimationInfo(bytes: Uint8Array): VrmAnimationInfo;
|
|
137
|
+
/** Registers a source; Animation owns the later playback request. */
|
|
138
|
+
registerVrmAnimation(name: string, bytes: Uint8Array, options: VrmAnimationUnits): void;
|
|
139
|
+
/** Stale editor cleanup must not remove a later same-name native source. */
|
|
140
|
+
releaseVrmAnimation(name: string): void;
|
|
116
141
|
registerAnimationClips(clips: AnimationClip[]): void;
|
|
117
142
|
loadAnimationClips(clips: AnimationClip[]): void;
|
|
118
143
|
removeAnimationClip(name: string): boolean;
|
|
119
|
-
getAnimationClips():
|
|
144
|
+
getAnimationClips(): AnimationClipInfo[];
|
|
120
145
|
playAnimation(name: string, options?: CharacterPlaybackOptions): CharacterPlaybackHandle;
|
|
121
146
|
private build;
|
|
122
147
|
buildClip(name: string, curves: JsonObject, options?: CharacterPlaybackOptions): CharacterPlaybackHandle;
|
|
@@ -136,6 +161,7 @@ export declare class Embody {
|
|
|
136
161
|
cleanupSnippet(name: string): void;
|
|
137
162
|
crossfadeTo(name: string, seconds: number, options?: CharacterPlaybackOptions): CharacterPlaybackHandle;
|
|
138
163
|
stopAnimation(name: string): void;
|
|
164
|
+
/** Stop every caller playback. Live setter targets and hair actions keep running. */
|
|
139
165
|
stopAllAnimations(): void;
|
|
140
166
|
pauseAnimation(name: string): void;
|
|
141
167
|
resumeAnimation(name: string): void;
|
|
@@ -167,6 +193,24 @@ export declare class Embody {
|
|
|
167
193
|
getAUDescriptors(): AUDescriptor[];
|
|
168
194
|
setContinuum(negative: number, positive: number, value: number, balance?: number): void;
|
|
169
195
|
getContinuum(negative: number, positive: number): number;
|
|
196
|
+
/**
|
|
197
|
+
* One clip slot's own semantic AU contribution right now (`{auId: value}`),
|
|
198
|
+
* evaluated in Rust at the native action's time and effective weight.
|
|
199
|
+
* Null when the slot is not playing or was not an AU-curve clip.
|
|
200
|
+
*/
|
|
201
|
+
readAUContribution(name: string): Record<string, number> | null;
|
|
202
|
+
/**
|
|
203
|
+
* On-demand AU state: live control values, active AU-curve clip
|
|
204
|
+
* contributions and their sum. Baked/native and typed clips cannot be
|
|
205
|
+
* inverted to AU values and are listed as `unreadable`, never estimated.
|
|
206
|
+
*/
|
|
207
|
+
readAUState(): CharacterAUState;
|
|
208
|
+
/**
|
|
209
|
+
* Distance from a slot's current contribution to AU destinations, measured
|
|
210
|
+
* along profile continuum pairs, and whether it reverses unfinished travel.
|
|
211
|
+
* A slot that is not playing is at zero. Callers choose any timing policy.
|
|
212
|
+
*/
|
|
213
|
+
measureAUGoal(name: string, destinations: Record<string, number>): CharacterAUGoalMeasurement;
|
|
170
214
|
transitionAU(id: number, value: number, durationMs?: number, balance?: number): CharacterTransitionHandle;
|
|
171
215
|
setViseme(index: number, value: number, jawScale?: number): void;
|
|
172
216
|
getViseme(index: number): number;
|
|
@@ -189,12 +233,12 @@ export declare class Embody {
|
|
|
189
233
|
addMorphTarget(target: Parameters<ThreeFrameApplier['addMorphTarget']>[1], options?: Parameters<ThreeFrameApplier['addMorphTarget']>[2]): number;
|
|
190
234
|
addMorphTargets(targets: Parameters<ThreeFrameApplier['addMorphTargets']>[1], options?: Parameters<ThreeFrameApplier['addMorphTargets']>[2]): Record<string, number>;
|
|
191
235
|
private meshCategory;
|
|
192
|
-
getMeshList():
|
|
236
|
+
getMeshList(): MeshInfo[];
|
|
193
237
|
getBones(): ThreeModelInspection['bones'];
|
|
194
238
|
private meshProfile;
|
|
195
239
|
setMeshVisible(name: string, visible: boolean): void;
|
|
196
240
|
highlightMesh(name: string | null, color?: number, value?: number): void;
|
|
197
|
-
getMeshMaterialConfig(name: string):
|
|
241
|
+
getMeshMaterialConfig(name: string): ThreeResolvedMaterialConfig | null;
|
|
198
242
|
setMeshMaterialConfig(name: string, value: Parameters<ThreeFrameApplier['setMeshMaterialConfig']>[2]): void;
|
|
199
243
|
registerHairObjects(objects: Object3D[]): {
|
|
200
244
|
name: string;
|
|
@@ -203,10 +247,10 @@ export declare class Embody {
|
|
|
203
247
|
}[];
|
|
204
248
|
getRegisteredHairObjects(): Object3D[];
|
|
205
249
|
getHairMorphTargets(name?: string): string[];
|
|
206
|
-
getHairAppearance():
|
|
250
|
+
getHairAppearance(): HairAppearanceState;
|
|
207
251
|
private setHairAppearance;
|
|
208
|
-
setHairColor(value: string |
|
|
209
|
-
setEyebrowColor(value: string |
|
|
252
|
+
setHairColor(value: string | Partial<HairColorAppearance>): void;
|
|
253
|
+
setEyebrowColor(value: string | Partial<HairColorAppearance>): void;
|
|
210
254
|
setHairBaseColor(value: string): void;
|
|
211
255
|
setEyebrowBaseColor(value: string): void;
|
|
212
256
|
setHairGlow(color: string, value: number): void;
|
|
@@ -216,15 +260,15 @@ export declare class Embody {
|
|
|
216
260
|
color?: string;
|
|
217
261
|
opacity?: number;
|
|
218
262
|
}): void;
|
|
219
|
-
private
|
|
263
|
+
private hairClipOptions;
|
|
264
|
+
private bindHairHead;
|
|
265
|
+
private sampleHairResponse;
|
|
220
266
|
setHairPhysicsEnabled(value: boolean): void;
|
|
221
267
|
isHairPhysicsEnabled(): boolean;
|
|
222
|
-
setHairPhysicsConfig(value:
|
|
223
|
-
getHairPhysicsConfig():
|
|
268
|
+
setHairPhysicsConfig(value: HairPhysicsRuntimeConfigUpdate): void;
|
|
269
|
+
getHairPhysicsConfig(): Partial<HairPhysicsRuntimeConfig>;
|
|
224
270
|
validateHairMorphTargets(): string[];
|
|
225
271
|
applyHairStateToObject(name: string, state: JsonObject): void;
|
|
226
|
-
private authoredHeadMotion;
|
|
227
|
-
private setHairGravity;
|
|
228
272
|
playHairImpulse(horizontal: number, vertical: number): CharacterPlaybackHandle | undefined;
|
|
229
273
|
start(): void;
|
|
230
274
|
stop(): void;
|
package/dist/three/index.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import type { MeshHighlightFrame } from '../wasm/highlighting';
|
|
1
2
|
import { AnimationClip } from 'three';
|
|
2
3
|
export * from './annotations/index';
|
|
4
|
+
export * from './vrm-animation';
|
|
3
5
|
export * from './authoring';
|
|
4
6
|
export * from './character';
|
|
5
7
|
export * from './characterHost';
|
|
6
8
|
export { renderScenePlayback, createScenePlaybackFrame } from './playbackRendering';
|
|
7
9
|
import type { ThreeModelReferencePose } from './reference-pose';
|
|
10
|
+
import type { MeshMaterialSettings, ThreeResolvedMaterialConfig } from './authoringTypes';
|
|
8
11
|
export { captureModelReferencePose, bindModelReferencePose, extendModelReferencePose } from './reference-pose';
|
|
9
12
|
export type { ThreeModelReferencePose, ThreeReferencePoseNode } from './reference-pose';
|
|
10
13
|
export { ThreeNativePlaybackConnector } from './nativePlayback';
|
|
@@ -133,20 +136,13 @@ export declare function serializeAnimationClips(model: Object3D, clips: readonly
|
|
|
133
136
|
}[];
|
|
134
137
|
tracks: ClipIRTrack[];
|
|
135
138
|
}[];
|
|
136
|
-
type MaterialConfig =
|
|
137
|
-
renderOrder?: number;
|
|
138
|
-
transparent?: boolean;
|
|
139
|
-
opacity?: number;
|
|
140
|
-
depthWrite?: boolean;
|
|
141
|
-
depthTest?: boolean;
|
|
142
|
-
blending?: keyof typeof THREE_BLENDING_MODES;
|
|
143
|
-
};
|
|
139
|
+
type MaterialConfig = MeshMaterialSettings;
|
|
144
140
|
export declare class ThreeFrameApplier {
|
|
145
141
|
private meshes;
|
|
146
142
|
private morphs;
|
|
147
143
|
private bones;
|
|
148
144
|
private objects;
|
|
149
|
-
private
|
|
145
|
+
private highlighted;
|
|
150
146
|
setBindings(inspection: ThreeModelInspection): void;
|
|
151
147
|
applyPackedMorphFrameDelta(values: ArrayLike<number>, stride?: number): void;
|
|
152
148
|
applyPackedBoneFrameDelta(values: ArrayLike<number>, stride?: number): void;
|
|
@@ -155,10 +151,14 @@ export declare class ThreeFrameApplier {
|
|
|
155
151
|
visible?: boolean;
|
|
156
152
|
material?: MaterialConfig;
|
|
157
153
|
}>): void;
|
|
158
|
-
getMeshMaterialConfig(root: Object3D, name: string): null;
|
|
154
|
+
getMeshMaterialConfig(root: Object3D, name: string): ThreeResolvedMaterialConfig | null;
|
|
159
155
|
setMeshMaterialConfig(root: Object3D, name: string, config: MaterialConfig): void;
|
|
156
|
+
private applyHighlightedMeshMaterial;
|
|
160
157
|
setMeshVisible(root: Object3D, name: string, visible: boolean): void;
|
|
161
|
-
|
|
158
|
+
/** Apply a complete Rust snapshot. Only native resources and ID bindings live here. */
|
|
159
|
+
applyMeshHighlightFrame(frame: MeshHighlightFrame): void;
|
|
160
|
+
clearMeshHighlights(): void;
|
|
161
|
+
private clearMeshHighlight;
|
|
162
162
|
applyHairAppearance(meshes: readonly Mesh[], appearance: any): void;
|
|
163
163
|
addMorphTarget(root: Object3D, target: MorphTargetInput, options?: AddMorphTargetOptions): number;
|
|
164
164
|
addMorphTargets(root: Object3D, targets: readonly MorphTargetInput[], options?: AddMorphTargetOptions): Record<string, number>;
|
|
@@ -169,5 +169,6 @@ export declare class ThreeFrameApplier {
|
|
|
169
169
|
export declare const collectMorphMeshes: (root: Object3D) => Mesh<import("three").BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>, Material<import("three").MaterialEventMap> | Material<import("three").MaterialEventMap>[], import("three").Object3DEventMap>[];
|
|
170
170
|
export * from './model';
|
|
171
171
|
export * from './scene';
|
|
172
|
+
export * from './scenery';
|
|
172
173
|
export * from './editor/SkeletonOverlay';
|
|
173
174
|
export * from './editor/morphVertexPreview';
|
package/dist/three/model.d.ts
CHANGED
|
@@ -6,7 +6,9 @@ export type CharacterModelLoadResult = {
|
|
|
6
6
|
animations: AnimationClip[];
|
|
7
7
|
gltf: GLTF | null;
|
|
8
8
|
};
|
|
9
|
+
export type CharacterModelFormat = 'gltf' | 'fbx';
|
|
9
10
|
export type CharacterModelLoadOptions = {
|
|
11
|
+
format?: CharacterModelFormat;
|
|
10
12
|
onProgress?: (progress: number) => void;
|
|
11
13
|
castShadows?: boolean;
|
|
12
14
|
dracoDecoderPath?: string;
|
|
@@ -57,6 +57,8 @@ export type ThreeNativePlaybackBinding = {
|
|
|
57
57
|
inspection: ThreeModelInspection;
|
|
58
58
|
/** Optional existing native mixer. Otherwise the connector owns one. */
|
|
59
59
|
mixer?: AnimationMixer;
|
|
60
|
+
/** Apply renderer effects using the existing scene clock; never starts a loop. */
|
|
61
|
+
onFrame?: (deltaSeconds: number) => void;
|
|
60
62
|
};
|
|
61
63
|
/**
|
|
62
64
|
* Execute validated Rust commands on the native mixer. There is no
|
|
@@ -83,10 +85,13 @@ export declare class ThreeNativePlaybackConnector {
|
|
|
83
85
|
private disposed;
|
|
84
86
|
private readonly onError?;
|
|
85
87
|
private readonly onRelease?;
|
|
88
|
+
private readonly afterSample?;
|
|
86
89
|
constructor(session: NativePlaybackSession, binding: ThreeNativePlaybackBinding & {
|
|
87
90
|
onError?: (error: Error) => void;
|
|
88
91
|
onRelease?: (handle: string) => void;
|
|
92
|
+
afterSample?: (deltaSeconds: number) => void;
|
|
89
93
|
});
|
|
94
|
+
private readonly afterFrame;
|
|
90
95
|
/** Prepare bindings first; old actions are released before the new binding is exposed. */
|
|
91
96
|
rebind(modelKey: string, profileKey: string, binding?: ThreeNativePlaybackBinding): void;
|
|
92
97
|
play(clip: ClipIR, options?: ThreeNativePlaybackOptions): string;
|
|
@@ -105,6 +110,7 @@ export declare class ThreeNativePlaybackConnector {
|
|
|
105
110
|
replaceClip(handle: string, clip: AnimationClip): void;
|
|
106
111
|
/** Native state for the owning adapter; never exposed through Polymer. */
|
|
107
112
|
getAction(handle: string): AnimationAction | undefined;
|
|
113
|
+
private readonly sampleResponse;
|
|
108
114
|
/** Deliver native completion after the borrowed mixer has finished sampling. */
|
|
109
115
|
flushEvents(): void;
|
|
110
116
|
subscribe(listener: (event: ThreeNativePlaybackEvent) => void): () => void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Timer } from 'three';
|
|
2
2
|
import type { AnimationMixer, Object3D } from 'three';
|
|
3
3
|
/** Register native playback with the existing scene renderer; never starts a loop. */
|
|
4
|
-
export declare function bindPlaybackRendering(model: Object3D, mixer: AnimationMixer, afterFrame: () => void): {
|
|
4
|
+
export declare function bindPlaybackRendering(model: Object3D, mixer: AnimationMixer, afterFrame: (deltaSeconds: number) => void, afterSample?: (deltaSeconds: number) => void): {
|
|
5
5
|
setEnabled(enabled: boolean): void;
|
|
6
6
|
dispose(): void;
|
|
7
7
|
};
|
package/dist/three/scene.d.ts
CHANGED
|
@@ -186,6 +186,8 @@ export interface CharacterSceneRenderingController {
|
|
|
186
186
|
subscribe(listener: (snapshot: CharacterSceneRenderingSnapshot) => void): () => void;
|
|
187
187
|
/** Borrow for capture/readback; release in finally. Unavailable during switching/loss. */
|
|
188
188
|
acquireRenderer(): CharacterSceneRendererLease;
|
|
189
|
+
/** Wait for queued scene work, then atomically borrow the active renderer. Release in finally. */
|
|
190
|
+
acquireRendererAsync(): Promise<CharacterSceneRendererLease>;
|
|
189
191
|
/** Drain borrowed work, then synchronously detach/free caller-owned resources, even after loss/disposal. */
|
|
190
192
|
releaseSceneResources(release: () => void): Promise<void>;
|
|
191
193
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Scene } from 'three';
|
|
2
|
+
/** Character settings update the inherited background even while scenery covers it. */
|
|
3
|
+
export declare function setSceneBaseBackground(scene: Scene, value: Scene['background']): void;
|
|
4
|
+
/** One scenery owner per scene prevents competing capture-and-restore cleanups. */
|
|
5
|
+
export declare function acquireSceneBackground(scene: Scene, onSceneDispose: () => void): {
|
|
6
|
+
set(value: Scene["background"], intensity: number, rotationDegrees: number): void;
|
|
7
|
+
clear(): void;
|
|
8
|
+
dispose(): void;
|
|
9
|
+
};
|
|
10
|
+
/** Called by the scene's existing lifetime; the renderer owns its async drain. */
|
|
11
|
+
export declare function disposeSceneBackground(scene: Scene): void;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Scene } from 'three';
|
|
2
|
+
import type { CharacterSceneRenderingController } from './scene';
|
|
3
|
+
/** World coordinates in the scene's native units (Y up for default character scenes). */
|
|
4
|
+
export type SceneSceneryPosition = {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
z: number;
|
|
8
|
+
};
|
|
9
|
+
export type SceneSceneryInstance = {
|
|
10
|
+
instanceId: string;
|
|
11
|
+
assetId: string;
|
|
12
|
+
position: SceneSceneryPosition;
|
|
13
|
+
};
|
|
14
|
+
export type SceneScenerySkybox = {
|
|
15
|
+
kind: 'skybox' | 'backdrop' | 'color';
|
|
16
|
+
assetId: string | null;
|
|
17
|
+
/** Six-digit #rrggbb, also used by the generated sky when assetId is null. */
|
|
18
|
+
color: string;
|
|
19
|
+
intensity: number;
|
|
20
|
+
/** Y-axis degrees. Applies to equirectangular skyboxes. */
|
|
21
|
+
rotation: number;
|
|
22
|
+
};
|
|
23
|
+
export type SceneSceneryLayout = {
|
|
24
|
+
skybox: SceneScenerySkybox | null;
|
|
25
|
+
instances: readonly SceneSceneryInstance[];
|
|
26
|
+
};
|
|
27
|
+
export type SceneSceneryAsset = {
|
|
28
|
+
bytes: ArrayBuffer;
|
|
29
|
+
contentType: string;
|
|
30
|
+
};
|
|
31
|
+
export type SceneSceneryRendererOptions = {
|
|
32
|
+
scene: Scene;
|
|
33
|
+
/** The scene's existing controller. Omit only for an externally managed scene. */
|
|
34
|
+
rendering?: CharacterSceneRenderingController | null;
|
|
35
|
+
/** Storage authorization, caching and asset identities remain with the caller. */
|
|
36
|
+
loadAsset(assetId: string, signal: AbortSignal): Promise<SceneSceneryAsset>;
|
|
37
|
+
onError?: (message: string) => void;
|
|
38
|
+
};
|
|
39
|
+
export type SceneSceneryRenderer = {
|
|
40
|
+
/** Validates and copies the entire layout before changing the current selection. */
|
|
41
|
+
update(layout: SceneSceneryLayout | null): void;
|
|
42
|
+
/** Cancels loads, drains borrowed rendering work, and releases only scenery. */
|
|
43
|
+
dispose(): Promise<void>;
|
|
44
|
+
};
|
|
45
|
+
/** Native scene resources only: no storage, character selection, mixer or render loop. */
|
|
46
|
+
export declare function createSceneSceneryRenderer(options: SceneSceneryRendererOptions): SceneSceneryRenderer;
|