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.
Files changed (47) hide show
  1. package/dist/TalkingHead.web.js +7 -17
  2. package/dist/api/studioApi.js +26 -25
  3. package/dist/appearance/apply.d.ts +6 -0
  4. package/dist/appearance/apply.js +72 -7
  5. package/dist/appearance/index.d.ts +1 -1
  6. package/dist/appearance/index.js +2 -1
  7. package/dist/appearance/matchers.js +2 -1
  8. package/dist/appearance/schema.d.ts +1 -0
  9. package/dist/appearance/schema.js +3 -1
  10. package/dist/appearance/sharedState.d.ts +11 -0
  11. package/dist/appearance/sharedState.js +13 -0
  12. package/dist/editor/AvatarCanvas.d.ts +1 -0
  13. package/dist/editor/AvatarCanvas.js +3 -2
  14. package/dist/editor/AvatarModel.d.ts +1 -3
  15. package/dist/editor/AvatarModel.js +13 -5
  16. package/dist/editor/RigidAccessory.js +2 -1
  17. package/dist/editor/SkinnedClothing.js +9 -18
  18. package/dist/filament/FilamentAvatar.js +20 -42
  19. package/dist/filament/editor/FilamentEditor.d.ts +16 -0
  20. package/dist/filament/editor/FilamentEditor.js +880 -0
  21. package/dist/filament/editor/FilamentEditor.web.d.ts +19 -0
  22. package/dist/filament/editor/FilamentEditor.web.js +58 -0
  23. package/dist/filament/editor/PrecisionPanel.d.ts +1 -0
  24. package/dist/filament/editor/PrecisionPanel.js +252 -0
  25. package/dist/filament/editor/boneSnap.d.ts +10 -0
  26. package/dist/filament/editor/boneSnap.js +97 -0
  27. package/dist/filament/editor/index.d.ts +5 -0
  28. package/dist/filament/editor/index.js +19 -0
  29. package/dist/filament/editor/studioTheme.d.ts +86 -0
  30. package/dist/filament/editor/studioTheme.js +89 -0
  31. package/dist/filament/useAuthedFilamentUri.js +9 -18
  32. package/dist/html.js +2 -1
  33. package/dist/index.d.ts +0 -2
  34. package/dist/index.js +1 -3
  35. package/dist/sketchfab/api.js +5 -4
  36. package/dist/sketchfab/useSketchfabSearch.js +2 -1
  37. package/dist/tts/useDirectVisemeStream.js +2 -1
  38. package/dist/tts/useMotionMarkers.d.ts +1 -0
  39. package/dist/tts/useMotionMarkers.js +2 -1
  40. package/dist/utils/avatarUtils.js +3 -2
  41. package/dist/utils/faceLandmarkerToShapeWeights.d.ts +44 -0
  42. package/dist/utils/faceLandmarkerToShapeWeights.js +112 -0
  43. package/dist/voice/convertToWav.js +2 -1
  44. package/dist/voice/useAudioPlayer.js +2 -1
  45. package/dist/voice/useAudioRecording.js +2 -1
  46. package/dist/wardrobe/useAvatarWardrobeHydration.js +2 -1
  47. 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) || (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
- })();
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
- // When localUri is empty (model not yet downloaded), pass a stable placeholder
152
- // so useModel doesn't error. ModelRenderer is gated on model.state === 'loaded'
153
- // so nothing will render until the real URI arrives.
154
- const model = (0, react_native_filament_1.useModel)({ uri: localUri || '' });
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
- let _fallbackGlbUri = null;
701
- async function getFallbackGlbUri() {
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
- const [fallbackUri, setFallbackUri] = react_1.default.useState(_fallbackGlbUri);
713
- react_1.default.useEffect(() => {
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 ?? fallbackUri;
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
- // We always render FilamentScene and conditionally render FilamentAvatarInner
728
- // inside it once the local file URI is ready.
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 ?? '', avatarUrl: avatarUrl, aspect: aspect, focalLength: focalLength, mood: mood, hairColor: hairColor, skinColor: skinColor, eyeColor: eyeColor, accessories: accessories, innerRef: ref, onReady: onReady, onError: onError }) }) }));
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;