talking-head-studio 0.3.5 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/TalkingHead.web.js +7 -17
- package/dist/api/studioApi.js +26 -25
- package/dist/appearance/apply.d.ts +6 -0
- package/dist/appearance/apply.js +72 -7
- package/dist/appearance/index.d.ts +1 -1
- package/dist/appearance/index.js +2 -1
- package/dist/appearance/matchers.js +2 -1
- package/dist/appearance/schema.d.ts +1 -0
- package/dist/appearance/schema.js +3 -1
- package/dist/appearance/sharedState.d.ts +11 -0
- package/dist/appearance/sharedState.js +13 -0
- package/dist/editor/AvatarCanvas.d.ts +1 -0
- package/dist/editor/AvatarCanvas.js +3 -2
- package/dist/editor/AvatarModel.d.ts +1 -3
- package/dist/editor/AvatarModel.js +13 -5
- package/dist/editor/RigidAccessory.js +2 -1
- package/dist/editor/SkinnedClothing.js +9 -18
- package/dist/filament/FilamentAvatar.js +20 -42
- package/dist/filament/editor/FilamentEditor.d.ts +16 -0
- package/dist/filament/editor/FilamentEditor.js +880 -0
- package/dist/filament/editor/FilamentEditor.web.d.ts +19 -0
- package/dist/filament/editor/FilamentEditor.web.js +58 -0
- package/dist/filament/editor/PrecisionPanel.d.ts +1 -0
- package/dist/filament/editor/PrecisionPanel.js +252 -0
- package/dist/filament/editor/boneSnap.d.ts +10 -0
- package/dist/filament/editor/boneSnap.js +97 -0
- package/dist/filament/editor/index.d.ts +5 -0
- package/dist/filament/editor/index.js +19 -0
- package/dist/filament/editor/studioTheme.d.ts +86 -0
- package/dist/filament/editor/studioTheme.js +89 -0
- package/dist/filament/useAuthedFilamentUri.js +9 -18
- package/dist/html.js +2 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js +1 -3
- package/dist/sketchfab/api.js +5 -4
- package/dist/sketchfab/useSketchfabSearch.js +2 -1
- package/dist/tts/useDirectVisemeStream.js +2 -1
- package/dist/tts/useMotionMarkers.d.ts +1 -0
- package/dist/tts/useMotionMarkers.js +2 -1
- package/dist/utils/avatarUtils.js +3 -2
- package/dist/utils/faceLandmarkerToShapeWeights.d.ts +44 -0
- package/dist/utils/faceLandmarkerToShapeWeights.js +112 -0
- package/dist/voice/convertToWav.js +2 -1
- package/dist/voice/useAudioPlayer.js +2 -1
- package/dist/voice/useAudioRecording.js +2 -1
- package/dist/wardrobe/useAvatarWardrobeHydration.js +2 -1
- package/package.json +25 -3
|
@@ -15,23 +15,13 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) ||
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
})();
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
35
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
26
|
exports.FilamentAvatar = exports.CAMERA_FOCAL_PIP = exports.CAMERA_FOCAL_FULL = void 0;
|
|
37
27
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
@@ -51,7 +41,6 @@ const react_1 = __importStar(require("react"));
|
|
|
51
41
|
const react_native_1 = require("react-native");
|
|
52
42
|
const react_native_filament_1 = require("react-native-filament");
|
|
53
43
|
const useAuthedFilamentUri_1 = require("./useAuthedFilamentUri");
|
|
54
|
-
const expo_asset_1 = require("expo-asset");
|
|
55
44
|
const faceSqueezeAssets_1 = require("./faceSqueezeAssets");
|
|
56
45
|
const morphTables_1 = require("./morphTables");
|
|
57
46
|
// ---------------------------------------------------------------------------
|
|
@@ -148,10 +137,11 @@ function buildVisemeMorphCache(dispatchMap) {
|
|
|
148
137
|
}
|
|
149
138
|
function FilamentAvatarInner({ localUri, mood: initialMood = 'neutral', hairColor: initialHairColor, skinColor: initialSkinColor, eyeColor: initialEyeColor, onReady, onError: _onError, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
150
139
|
innerRef, aspect, focalLength = exports.CAMERA_FOCAL_FULL, }) {
|
|
151
|
-
//
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
|
|
140
|
+
// localUri is either a file:// string (remote download) or a require() number (bundled fallback).
|
|
141
|
+
// useModel accepts both as BufferSource (number | { uri: string }) — cast to any since
|
|
142
|
+
// tsconfig resolves to an older type declaration that only shows { uri: string }.
|
|
143
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
144
|
+
const model = (0, react_native_filament_1.useModel)(typeof localUri === 'number' ? localUri : { uri: localUri });
|
|
155
145
|
const modelRef = (0, react_1.useRef)(model);
|
|
156
146
|
modelRef.current = model;
|
|
157
147
|
const { renderableManager } = (0, react_native_filament_1.useFilamentContext)();
|
|
@@ -697,36 +687,24 @@ innerRef, aspect, focalLength = exports.CAMERA_FOCAL_FULL, }) {
|
|
|
697
687
|
// ---------------------------------------------------------------------------
|
|
698
688
|
// Outer component — handles URL resolution + FilamentScene wrapper
|
|
699
689
|
// ---------------------------------------------------------------------------
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
if (_fallbackGlbUri)
|
|
703
|
-
return _fallbackGlbUri;
|
|
704
|
-
const asset = expo_asset_1.Asset.fromModule(faceSqueezeAssets_1.FACE_SQUEEZE_LOCAL_MODULE);
|
|
705
|
-
await asset.downloadAsync();
|
|
706
|
-
_fallbackGlbUri = asset.localUri ?? asset.uri ?? '';
|
|
707
|
-
return _fallbackGlbUri;
|
|
708
|
-
}
|
|
690
|
+
// The fallback is the bundled require() number — useModel accepts this directly
|
|
691
|
+
// (BufferSource = number | { uri: string }), so no async asset resolution needed.
|
|
709
692
|
exports.FilamentAvatar = (0, react_1.forwardRef)(({ style, avatarUrl, aspect, focalLength, mood, hairColor, skinColor, eyeColor, accessories, onReady, onError }, ref) => {
|
|
710
693
|
const fileResult = (0, useAuthedFilamentUri_1.useAuthedFilamentUri)(avatarUrl ?? null);
|
|
711
694
|
const currentUri = fileResult?.uri ?? null;
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
getFallbackGlbUri().then(setFallbackUri).catch((e) => console.error('[FilamentAvatar] fallback uri failed:', e));
|
|
715
|
-
}, []);
|
|
716
|
-
// Stabilize localUri: once a valid file URI resolves, keep it until a new one
|
|
717
|
-
// arrives. Never let it drop to null between URL transitions — that would cause
|
|
718
|
-
// the conditional below to unmount FilamentScene mid-render.
|
|
695
|
+
// Stabilize localUri: once a valid remote file URI resolves, keep it until a new
|
|
696
|
+
// one arrives. Falls back to the bundled require() number — always available sync.
|
|
719
697
|
const stableUriRef = react_1.default.useRef(null);
|
|
720
698
|
if (currentUri)
|
|
721
699
|
stableUriRef.current = currentUri;
|
|
722
|
-
const localUri = stableUriRef.current ??
|
|
700
|
+
const localUri = stableUriRef.current ?? faceSqueezeAssets_1.FACE_SQUEEZE_LOCAL_MODULE;
|
|
723
701
|
// FilamentScene MUST stay mounted for the lifetime of this component.
|
|
724
702
|
// Unmounting it disposes GPU assets on the JS thread while Filament's native
|
|
725
703
|
// render thread (FEngine::loop) and surface thread (JNISurfaceTextu) still hold
|
|
726
704
|
// references to those objects → SIGSEGV / corrupted-PC use-after-free crashes.
|
|
727
|
-
//
|
|
728
|
-
//
|
|
729
|
-
return ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: [style, styles.fill], children: (0, jsx_runtime_1.jsx)(react_native_filament_1.FilamentScene, { children: (0, jsx_runtime_1.jsx)(FilamentAvatarInner, { localUri: localUri
|
|
705
|
+
// FilamentAvatarInner keeps FilamentView permanently mounted; only ModelRenderer
|
|
706
|
+
// is conditional on the model being ready.
|
|
707
|
+
return ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: [style, styles.fill], children: (0, jsx_runtime_1.jsx)(react_native_filament_1.FilamentScene, { children: (0, jsx_runtime_1.jsx)(FilamentAvatarInner, { localUri: localUri, avatarUrl: avatarUrl, aspect: aspect, focalLength: focalLength, mood: mood, hairColor: hairColor, skinColor: skinColor, eyeColor: eyeColor, accessories: accessories, innerRef: ref, onReady: onReady, onError: onError }) }) }));
|
|
730
708
|
});
|
|
731
709
|
exports.FilamentAvatar.displayName = 'FilamentAvatar';
|
|
732
710
|
const styles = react_native_1.StyleSheet.create({
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ViewStyle } from 'react-native';
|
|
2
|
+
import type { WearableAsset } from '../../api/types';
|
|
3
|
+
import type { AssetPlacement } from '../../wardrobe/wardrobeStore';
|
|
4
|
+
export interface FilamentEditorProps {
|
|
5
|
+
avatarUrl: string;
|
|
6
|
+
style?: ViewStyle;
|
|
7
|
+
onDone: () => void;
|
|
8
|
+
skinColor?: string;
|
|
9
|
+
equipped: Record<string, WearableAsset>;
|
|
10
|
+
placements: Record<string, AssetPlacement>;
|
|
11
|
+
activeAssetId: string | null;
|
|
12
|
+
onActiveAssetChange: (assetId: string | null) => void;
|
|
13
|
+
onPlacementChange: (assetId: string, placement: AssetPlacement) => void;
|
|
14
|
+
}
|
|
15
|
+
export declare function FilamentEditor(props: FilamentEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export default FilamentEditor;
|