talking-head-studio 0.4.10 → 0.4.12
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 +299 -337
- package/dist/TalkingHead.d.ts +44 -28
- package/dist/TalkingHead.js +21 -2
- package/dist/TalkingHead.web.d.ts +37 -4
- package/dist/TalkingHead.web.js +28 -8
- package/dist/TalkingHeadVisualization.d.ts +22 -0
- package/dist/TalkingHeadVisualization.js +30 -10
- package/dist/api/studioApi.d.ts +12 -1
- package/dist/api/studioApi.js +41 -28
- package/dist/appearance/apply.js +2 -3
- package/dist/appearance/matchers.js +1 -2
- package/dist/appearance/schema.js +1 -2
- package/dist/contract.d.ts +14 -0
- package/dist/contract.js +30 -0
- package/dist/core/avatar/avatarCapabilities.d.ts +60 -0
- package/dist/core/avatar/avatarCapabilities.js +100 -0
- package/dist/core/avatar/backend.d.ts +130 -0
- package/dist/core/avatar/backend.js +4 -0
- package/dist/core/avatar/backends/gaussian.d.ts +49 -0
- package/dist/core/avatar/backends/gaussian.js +293 -0
- package/dist/core/avatar/backends/index.d.ts +3 -0
- package/dist/core/avatar/backends/index.js +7 -0
- package/dist/core/avatar/backends/morphTarget.d.ts +39 -0
- package/dist/core/avatar/backends/morphTarget.js +179 -0
- package/dist/core/avatar/faceControls.d.ts +40 -0
- package/dist/core/avatar/faceControls.js +138 -0
- package/dist/core/avatar/motion.d.ts +1713 -0
- package/dist/core/avatar/motion.js +550 -0
- package/dist/core/avatar/motionRuntime.d.ts +46 -0
- package/dist/core/avatar/motionRuntime.js +84 -0
- package/dist/core/avatar/schema.d.ts +78 -0
- package/dist/core/avatar/schema.js +134 -0
- package/dist/core/avatar/visemes.d.ts +47 -1
- package/dist/core/avatar/visemes.js +114 -1
- package/dist/editor/AvatarCanvas.js +93 -3
- package/dist/editor/AvatarEditor.native.js +19 -9
- package/dist/editor/AvatarModel.js +2 -2
- package/dist/editor/FaceSqueezeEditor.d.ts +3 -1
- package/dist/editor/FaceSqueezeEditor.js +195 -121
- package/dist/editor/FaceSqueezeEditor.web.d.ts +3 -1
- package/dist/editor/FaceSqueezeEditor.web.js +32 -30
- package/dist/editor/RigidAccessory.js +18 -4
- package/dist/editor/SkinnedClothing.js +19 -9
- package/dist/editor/boneLockedDrag.d.ts +11 -0
- package/dist/editor/boneLockedDrag.js +68 -0
- package/dist/editor/boneSnap.js +22 -12
- package/dist/editor/boneSnap.web.d.ts +27 -0
- package/dist/editor/boneSnap.web.js +99 -0
- package/dist/editor/index.web.d.ts +10 -0
- package/dist/editor/index.web.js +26 -0
- package/dist/editor/sounds/haha.wav +0 -0
- package/dist/editor/sounds/owie.wav +0 -0
- package/dist/editor/sounds/stop.wav +0 -0
- package/dist/editor/studioTheme.d.ts +14 -14
- package/dist/editor/studioTheme.js +19 -16
- package/dist/editor/types.d.ts +1 -0
- package/dist/html/accessories.d.ts +7 -0
- package/dist/html/accessories.js +149 -0
- package/dist/html/motion.d.ts +1 -0
- package/dist/html/motion.js +189 -0
- package/dist/html/visemes.d.ts +7 -0
- package/dist/html/visemes.js +348 -0
- package/dist/html.d.ts +1 -1
- package/dist/html.js +56 -734
- package/dist/index.d.ts +19 -1
- package/dist/index.js +44 -5
- package/dist/index.web.d.ts +18 -1
- package/dist/index.web.js +36 -3
- package/dist/platform/api/types.d.ts +10 -0
- package/dist/platform/api/types.js +2 -0
- package/dist/platform/marketplace/types.d.ts +32 -0
- package/dist/platform/marketplace/types.js +2 -0
- package/dist/platform/sdk/unity.d.ts +27 -0
- package/dist/platform/sdk/unity.js +2 -0
- package/dist/platform/sdk/unreal.d.ts +23 -0
- package/dist/platform/sdk/unreal.js +2 -0
- package/dist/platform/sdk/web.d.ts +16 -0
- package/dist/platform/sdk/web.js +2 -0
- package/dist/sketchfab/api.js +5 -5
- package/dist/sketchfab/glbInspect.d.ts +22 -0
- package/dist/sketchfab/glbInspect.js +58 -0
- package/dist/sketchfab/index.d.ts +3 -0
- package/dist/sketchfab/index.js +8 -1
- package/dist/sketchfab/inspectRemote.d.ts +13 -0
- package/dist/sketchfab/inspectRemote.js +77 -0
- package/dist/sketchfab/types.d.ts +10 -0
- package/dist/sketchfab/useSketchfabSearch.js +1 -2
- package/dist/studio/AccessoryBrowserScreen.d.ts +6 -0
- package/dist/studio/AccessoryBrowserScreen.js +626 -0
- package/dist/studio/AccessoryPanel.d.ts +10 -0
- package/dist/studio/AccessoryPanel.js +396 -0
- package/dist/studio/AppearancePanel.d.ts +9 -0
- package/dist/studio/AppearancePanel.js +77 -0
- package/dist/studio/AvatarCreatorScreen.d.ts +5 -0
- package/dist/studio/AvatarCreatorScreen.js +806 -0
- package/dist/studio/AvatarEditorScreen.d.ts +14 -0
- package/dist/studio/AvatarEditorScreen.js +510 -0
- package/dist/studio/AvatarGrid.d.ts +23 -0
- package/dist/studio/AvatarGrid.js +257 -0
- package/dist/studio/ColorSwatch.d.ts +8 -0
- package/dist/studio/ColorSwatch.js +100 -0
- package/dist/studio/CreateVoiceProfileSheet.d.ts +8 -0
- package/dist/studio/CreateVoiceProfileSheet.js +242 -0
- package/dist/studio/DetailsPanel.d.ts +15 -0
- package/dist/studio/DetailsPanel.js +239 -0
- package/dist/studio/FilamentEditor.d.ts +2 -0
- package/dist/studio/FilamentEditor.js +6 -0
- package/dist/studio/PrecisionPanel.d.ts +2 -0
- package/dist/studio/PrecisionPanel.js +7 -0
- package/dist/studio/PublicGalleryScreen.d.ts +5 -0
- package/dist/studio/PublicGalleryScreen.js +358 -0
- package/dist/studio/SketchfabModelCard.d.ts +20 -0
- package/dist/studio/SketchfabModelCard.js +104 -0
- package/dist/studio/StudioBrowseHeader.d.ts +9 -0
- package/dist/studio/StudioBrowseHeader.js +28 -0
- package/dist/studio/StudioEmptyState.d.ts +8 -0
- package/dist/studio/StudioEmptyState.js +29 -0
- package/dist/studio/StudioFloatingAction.d.ts +13 -0
- package/dist/studio/StudioFloatingAction.js +42 -0
- package/dist/studio/StudioSectionHeader.d.ts +7 -0
- package/dist/studio/StudioSectionHeader.js +27 -0
- package/dist/studio/StudioSurfaceCard.d.ts +8 -0
- package/dist/studio/StudioSurfaceCard.js +20 -0
- package/dist/studio/VoicePanel.d.ts +15 -0
- package/dist/studio/VoicePanel.js +305 -0
- package/dist/studio/constants.d.ts +3 -0
- package/dist/studio/constants.js +6 -0
- package/dist/studio/index.d.ts +29 -0
- package/dist/studio/index.js +54 -0
- package/dist/studio/useSketchfabCapabilities.d.ts +31 -0
- package/dist/studio/useSketchfabCapabilities.js +82 -0
- package/dist/tts/useDirectVisemeStream.d.ts +2 -6
- package/dist/tts/useDirectVisemeStream.js +16 -12
- package/dist/tts/useMotionMarkers.d.ts +0 -1
- package/dist/tts/useMotionMarkers.js +1 -2
- package/dist/utils/avatarUtils.js +94 -8
- package/dist/utils/faceLandmarkerToShapeWeights.js +21 -14
- package/dist/voice/convertToWav.js +1 -2
- package/dist/voice/index.d.ts +3 -0
- package/dist/voice/index.js +6 -1
- package/dist/voice/useAudioPlayer.js +18 -6
- package/dist/voice/useAudioRecording.js +1 -2
- package/dist/voice/useFaceControls.d.ts +14 -0
- package/dist/voice/useFaceControls.js +81 -0
- package/dist/voice/useVoicePreview.d.ts +7 -0
- package/dist/voice/useVoicePreview.js +83 -0
- package/dist/wardrobe/index.d.ts +3 -0
- package/dist/wardrobe/index.js +8 -1
- package/dist/wardrobe/useAccessoryGestures.d.ts +20 -0
- package/dist/wardrobe/useAccessoryGestures.js +94 -0
- package/dist/wardrobe/useAvatarWardrobeHydration.js +9 -4
- package/dist/wardrobe/useStudioAvatar.d.ts +29 -0
- package/dist/wardrobe/useStudioAvatar.js +186 -0
- package/dist/wardrobe/wardrobeStore.d.ts +2 -0
- package/dist/wardrobe/wardrobeStore.js +12 -2
- package/dist/wgpu/R3FWebGpuCanvas.d.ts +15 -0
- package/dist/wgpu/R3FWebGpuCanvas.js +176 -0
- package/dist/wgpu/WgpuAvatar.d.ts +26 -2
- package/dist/wgpu/WgpuAvatar.js +313 -46
- package/dist/wgpu/accessoryDefaults.d.ts +12 -0
- package/dist/wgpu/accessoryDefaults.js +19 -0
- package/dist/wgpu/blobShim.d.ts +2 -0
- package/dist/wgpu/blobShim.js +191 -0
- package/dist/wgpu/index.d.ts +1 -0
- package/dist/wgpu/index.js +4 -1
- package/dist/wgpu/loadGLTFFromUri.d.ts +2 -0
- package/dist/wgpu/loadGLTFFromUri.js +75 -0
- package/dist/wgpu/morphTables.js +21 -10
- package/dist/wgpu/motionState.d.ts +20 -0
- package/dist/wgpu/motionState.js +31 -0
- package/dist/wgpu/patchThreeForRN.d.ts +28 -0
- package/dist/wgpu/patchThreeForRN.js +292 -0
- package/dist/wgpu/scenePlacement.d.ts +5 -0
- package/dist/wgpu/scenePlacement.js +50 -0
- package/dist/wgpu/useAuthedModelUri.js +22 -11
- package/dist/wgpu/useNativeGLTF.d.ts +7 -0
- package/dist/wgpu/useNativeGLTF.js +36 -0
- package/package.json +102 -32
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.R3FWebGpuCanvas = R3FWebGpuCanvas;
|
|
37
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
38
|
+
const react_1 = require("react");
|
|
39
|
+
const react_native_1 = require("react-native");
|
|
40
|
+
const THREE = __importStar(require("three"));
|
|
41
|
+
const fiber_1 = require("@react-three/fiber");
|
|
42
|
+
const react_native_wgpu_1 = require("react-native-wgpu");
|
|
43
|
+
function formatErrorMessage(error) {
|
|
44
|
+
if (error instanceof Error)
|
|
45
|
+
return error.message;
|
|
46
|
+
return String(error);
|
|
47
|
+
}
|
|
48
|
+
class ReactNativeCanvas {
|
|
49
|
+
constructor(canvas) {
|
|
50
|
+
this.canvas = canvas;
|
|
51
|
+
}
|
|
52
|
+
get width() { return this.canvas.width; }
|
|
53
|
+
set width(width) { this.canvas.width = width; }
|
|
54
|
+
get height() { return this.canvas.height; }
|
|
55
|
+
set height(height) { this.canvas.height = height; }
|
|
56
|
+
get clientWidth() { return this.canvas.width; }
|
|
57
|
+
set clientWidth(width) { this.canvas.width = width; }
|
|
58
|
+
get clientHeight() { return this.canvas.height; }
|
|
59
|
+
set clientHeight(height) { this.canvas.height = height; }
|
|
60
|
+
addEventListener() { }
|
|
61
|
+
removeEventListener() { }
|
|
62
|
+
dispatchEvent() { }
|
|
63
|
+
setPointerCapture() { }
|
|
64
|
+
releasePointerCapture() { }
|
|
65
|
+
}
|
|
66
|
+
const THREE_WITH_WEBGPU = THREE;
|
|
67
|
+
(0, fiber_1.extend)(THREE);
|
|
68
|
+
function R3FWebGpuCanvas({ children, style, camera, clearColor = '#000', onCreated, onError, }) {
|
|
69
|
+
const canvasRef = (0, react_1.useRef)(null);
|
|
70
|
+
const rootRef = (0, react_1.useRef)(null);
|
|
71
|
+
const contextRef = (0, react_1.useRef)(null);
|
|
72
|
+
const rendererRef = (0, react_1.useRef)(null);
|
|
73
|
+
const surfaceRef = (0, react_1.useRef)(null);
|
|
74
|
+
const rendererPatchedRef = (0, react_1.useRef)(false);
|
|
75
|
+
const rendererInitializedRef = (0, react_1.useRef)(false);
|
|
76
|
+
const [layoutSize, setLayoutSize] = (0, react_1.useState)({ width: 0, height: 0 });
|
|
77
|
+
const [configured, setConfigured] = (0, react_1.useState)(false);
|
|
78
|
+
const childrenRef = (0, react_1.useRef)(children);
|
|
79
|
+
(0, react_1.useEffect)(() => {
|
|
80
|
+
childrenRef.current = children;
|
|
81
|
+
}, [children]);
|
|
82
|
+
const handleLayout = (0, react_1.useCallback)((event) => {
|
|
83
|
+
const { width, height } = event.nativeEvent.layout;
|
|
84
|
+
setLayoutSize((prev) => (prev.width === width && prev.height === height ? prev : { width, height }));
|
|
85
|
+
}, []);
|
|
86
|
+
(0, react_1.useEffect)(() => {
|
|
87
|
+
if (!canvasRef.current || layoutSize.width <= 0 || layoutSize.height <= 0)
|
|
88
|
+
return;
|
|
89
|
+
let cancelled = false;
|
|
90
|
+
const configure = async () => {
|
|
91
|
+
try {
|
|
92
|
+
if (!contextRef.current) {
|
|
93
|
+
contextRef.current = canvasRef.current?.getContext('webgpu');
|
|
94
|
+
}
|
|
95
|
+
const context = contextRef.current;
|
|
96
|
+
if (!context)
|
|
97
|
+
throw new Error('Unable to acquire a WebGPU canvas context');
|
|
98
|
+
const surface = surfaceRef.current ?? new ReactNativeCanvas(context.canvas);
|
|
99
|
+
surfaceRef.current = surface;
|
|
100
|
+
const dpr = react_native_1.PixelRatio.get();
|
|
101
|
+
surface.width = Math.max(1, Math.round(layoutSize.width * dpr));
|
|
102
|
+
surface.height = Math.max(1, Math.round(layoutSize.height * dpr));
|
|
103
|
+
const root = rootRef.current ?? (0, fiber_1.createRoot)(surface);
|
|
104
|
+
rootRef.current = root;
|
|
105
|
+
const renderer = rendererRef.current ?? new THREE_WITH_WEBGPU.WebGPURenderer({
|
|
106
|
+
alpha: false,
|
|
107
|
+
antialias: true,
|
|
108
|
+
canvas: surface,
|
|
109
|
+
context,
|
|
110
|
+
});
|
|
111
|
+
rendererRef.current = renderer;
|
|
112
|
+
if (!rendererInitializedRef.current) {
|
|
113
|
+
await renderer.init();
|
|
114
|
+
rendererInitializedRef.current = true;
|
|
115
|
+
}
|
|
116
|
+
await root.configure({
|
|
117
|
+
dpr: 1,
|
|
118
|
+
frameloop: 'always',
|
|
119
|
+
size: {
|
|
120
|
+
width: surface.clientWidth,
|
|
121
|
+
height: surface.clientHeight,
|
|
122
|
+
top: 0,
|
|
123
|
+
left: 0,
|
|
124
|
+
},
|
|
125
|
+
camera: camera,
|
|
126
|
+
gl: renderer,
|
|
127
|
+
onCreated: (state) => {
|
|
128
|
+
if (!rendererPatchedRef.current) {
|
|
129
|
+
const originalRender = state.gl.render.bind(state.gl);
|
|
130
|
+
state.gl.render = (scene, camera) => {
|
|
131
|
+
const result = originalRender(scene, camera);
|
|
132
|
+
context.present();
|
|
133
|
+
return result;
|
|
134
|
+
};
|
|
135
|
+
rendererPatchedRef.current = true;
|
|
136
|
+
}
|
|
137
|
+
state.scene.background = new THREE.Color(clearColor);
|
|
138
|
+
onCreated?.(state);
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
if (!cancelled) {
|
|
142
|
+
root.render(childrenRef.current);
|
|
143
|
+
setConfigured(true);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
if (!cancelled) {
|
|
148
|
+
setConfigured(false);
|
|
149
|
+
onError?.(formatErrorMessage(error));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
void configure();
|
|
154
|
+
return () => {
|
|
155
|
+
cancelled = true;
|
|
156
|
+
};
|
|
157
|
+
}, [camera, clearColor, layoutSize.height, layoutSize.width, onCreated, onError]);
|
|
158
|
+
(0, react_1.useEffect)(() => {
|
|
159
|
+
if (!configured || !rootRef.current)
|
|
160
|
+
return;
|
|
161
|
+
rootRef.current.render(children);
|
|
162
|
+
}, [children, configured]);
|
|
163
|
+
(0, react_1.useEffect)(() => () => {
|
|
164
|
+
rootRef.current?.unmount();
|
|
165
|
+
rootRef.current = null;
|
|
166
|
+
contextRef.current = null;
|
|
167
|
+
rendererRef.current = null;
|
|
168
|
+
surfaceRef.current = null;
|
|
169
|
+
rendererPatchedRef.current = false;
|
|
170
|
+
rendererInitializedRef.current = false;
|
|
171
|
+
}, []);
|
|
172
|
+
return ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: [styles.container, style], onLayout: handleLayout, children: (0, jsx_runtime_1.jsx)(react_native_wgpu_1.Canvas, { ref: canvasRef, style: react_native_1.StyleSheet.absoluteFill, transparent: true }) }));
|
|
173
|
+
}
|
|
174
|
+
const styles = react_native_1.StyleSheet.create({
|
|
175
|
+
container: { overflow: 'hidden' },
|
|
176
|
+
});
|
|
@@ -1,26 +1,49 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WgpuAvatar — drop-in replacement for FilamentAvatar using react-three-fiber
|
|
3
|
-
* + react-native-wgpu
|
|
3
|
+
* + react-native-wgpu. Exposes the same ref interface as
|
|
4
4
|
* FilamentAvatarRef so siteclaw can swap renderers without changing call sites.
|
|
5
5
|
*
|
|
6
6
|
* No SurfaceTexture, no choreographer, no JNI surface lifecycle bugs.
|
|
7
7
|
*
|
|
8
8
|
* Peer deps required by the host app:
|
|
9
|
-
* react-native-wgpu
|
|
9
|
+
* react-native-wgpu
|
|
10
10
|
* @react-three/fiber >= 8
|
|
11
11
|
* @react-three/drei >= 9
|
|
12
12
|
* three >= 0.170
|
|
13
13
|
*/
|
|
14
|
+
import './blobShim';
|
|
14
15
|
import React from 'react';
|
|
15
16
|
import { type StyleProp, type ViewStyle } from 'react-native';
|
|
16
17
|
import * as THREE from 'three';
|
|
17
18
|
import type { TalkingHeadMood, TalkingHeadAccessory, TalkingHeadVisemeSchedule } from '../index';
|
|
19
|
+
import { type MotionKey, type TalkingHeadGesture, type TalkingHeadPose } from '../core/avatar/motion';
|
|
18
20
|
export interface WgpuAvatarRef {
|
|
19
21
|
setMood: (mood: TalkingHeadMood) => void;
|
|
20
22
|
sendAmplitude: (amplitude: number) => void;
|
|
21
23
|
sendViseme: (viseme: string, weight?: number) => void;
|
|
22
24
|
scheduleVisemes: (schedule: TalkingHeadVisemeSchedule) => void;
|
|
23
25
|
clearVisemes: () => void;
|
|
26
|
+
/** Play a procedural body motion (e.g. 'attack', 'defend', 'groove'). */
|
|
27
|
+
playMotion(name: MotionKey): void;
|
|
28
|
+
playMotion(name: string): void;
|
|
29
|
+
/** Stop the active procedural motion and restore the rest pose. */
|
|
30
|
+
stopMotion: () => void;
|
|
31
|
+
/** Procedural fallback for upstream TalkingHead gestures on native WGPU. */
|
|
32
|
+
playGesture: (name: TalkingHeadGesture | string, opts?: {
|
|
33
|
+
ms?: number;
|
|
34
|
+
}) => void;
|
|
35
|
+
stopGesture: () => void;
|
|
36
|
+
/** Procedural fallback for upstream TalkingHead pose templates on native WGPU. */
|
|
37
|
+
playPose: (name: TalkingHeadPose | string) => void;
|
|
38
|
+
stopPose: () => void;
|
|
39
|
+
/** Play an animation clip from a GLB loaded by the native WGPU path. */
|
|
40
|
+
playAnimation: (url: string, opts?: {
|
|
41
|
+
dur?: number;
|
|
42
|
+
index?: number;
|
|
43
|
+
}) => void;
|
|
44
|
+
stopAnimation: () => void;
|
|
45
|
+
/** Triggers a single natural blink — use as a reaction to accessory snap-on. */
|
|
46
|
+
triggerBlink: () => void;
|
|
24
47
|
}
|
|
25
48
|
interface WgpuAvatarProps {
|
|
26
49
|
style?: StyleProp<ViewStyle>;
|
|
@@ -32,6 +55,7 @@ interface WgpuAvatarProps {
|
|
|
32
55
|
accessories?: TalkingHeadAccessory[];
|
|
33
56
|
onReady?: () => void;
|
|
34
57
|
onError?: (message: string) => void;
|
|
58
|
+
onAvatarState?: (state: string) => void;
|
|
35
59
|
/** Called once the R3F scene and camera are available (for editor raycasting). */
|
|
36
60
|
onSceneReady?: (scene: THREE.Scene, camera: THREE.Camera) => void;
|
|
37
61
|
}
|