@liveroom-tech/react-immersive 6.2.0 → 6.2.1

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 (61) hide show
  1. package/dist/DownloadedEnvironment-NHM4U2LJ.mjs +1 -0
  2. package/dist/{SequencesTab-ODR5IGDX.mjs → SequencesTab-VZKEKAUG.mjs} +1 -1
  3. package/dist/StreamingTilesModel-6Z7SIC2J.mjs +16 -0
  4. package/dist/binding-builder.css +1 -1
  5. package/dist/binding-builder.d.mts +3 -3
  6. package/dist/binding-builder.d.ts +3 -3
  7. package/dist/binding-builder.js +59 -58
  8. package/dist/binding-builder.mjs +1 -1
  9. package/dist/chunk-25WC5KDO.mjs +50 -0
  10. package/dist/chunk-2AJK643D.mjs +1 -0
  11. package/dist/chunk-3OCHN3CA.mjs +1 -0
  12. package/dist/{chunk-3XZKDTB2.mjs → chunk-7OVEHDDE.mjs} +1 -1
  13. package/dist/chunk-KFLS7GI6.mjs +1 -0
  14. package/dist/{chunk-EWNN4BBR.mjs → chunk-KYXJG3TX.mjs} +1 -1
  15. package/dist/{chunk-2CUPPOBW.mjs → chunk-LD7QWHB4.mjs} +2 -2
  16. package/dist/{chunk-GXY3VML4.mjs → chunk-NMRTI3NQ.mjs} +1 -1
  17. package/dist/chunk-RKDATTUM.mjs +1 -0
  18. package/dist/chunk-RXZ4Q7CY.mjs +1 -0
  19. package/dist/chunk-TUYVYSN5.mjs +1 -0
  20. package/dist/{chunk-IOLT2VXU.mjs → chunk-UAZ6I25Y.mjs} +1 -1
  21. package/dist/chunk-UCD76KQ6.mjs +1 -0
  22. package/dist/chunk-UHRJ2RBF.mjs +1 -0
  23. package/dist/chunk-UTVFRMYW.mjs +47 -0
  24. package/dist/chunk-YKDDNX2D.mjs +69 -0
  25. package/dist/exportSceneMesh-YJFOLFHS.mjs +1 -0
  26. package/dist/hosted.css +1 -1
  27. package/dist/hosted.d.mts +3 -3
  28. package/dist/hosted.d.ts +3 -3
  29. package/dist/hosted.js +58 -57
  30. package/dist/hosted.mjs +1 -1
  31. package/dist/index.css +1 -1
  32. package/dist/index.d.mts +4 -4
  33. package/dist/index.d.ts +4 -4
  34. package/dist/index.js +52 -51
  35. package/dist/index.mjs +1 -1
  36. package/dist/meshFormats-4C6NHYOA.mjs +1 -0
  37. package/dist/modelFileResolver-CVmON8hg.d.mts +1724 -0
  38. package/dist/modelFileResolver-CVmON8hg.d.ts +1724 -0
  39. package/dist/modelViewerProps-BBnZTFO-.d.ts +949 -0
  40. package/dist/modelViewerProps-CIY4nsNY.d.mts +949 -0
  41. package/dist/{publicProps-Cmh9JtzJ.d.ts → publicProps-BARVwXu7.d.ts} +1 -1
  42. package/dist/{publicProps-TMARX628.d.mts → publicProps-n0Yvr_Km.d.mts} +1 -1
  43. package/dist/simple-model-viewer.css +1 -1
  44. package/dist/simple-model-viewer.d.mts +22 -4
  45. package/dist/simple-model-viewer.d.ts +22 -4
  46. package/dist/simple-model-viewer.js +5 -5
  47. package/dist/simple-model-viewer.mjs +1 -1
  48. package/dist/utils.d.mts +4 -4
  49. package/dist/utils.d.ts +4 -4
  50. package/dist/utils.js +2 -2
  51. package/dist/utils.mjs +1 -1
  52. package/dist/xrRuntime-5S7KYUVB.mjs +1 -0
  53. package/package.json +1 -1
  54. package/dist/chunk-3MIILDHB.mjs +0 -83
  55. package/dist/chunk-6Q6YZ7O5.mjs +0 -1
  56. package/dist/chunk-7MN2TMY6.mjs +0 -47
  57. package/dist/chunk-X4WRTDO6.mjs +0 -50
  58. package/dist/modelFileResolver-ChKYsF21.d.mts +0 -495
  59. package/dist/modelFileResolver-ChKYsF21.d.ts +0 -495
  60. package/dist/modelViewerProps-Ch6pIZIE.d.ts +0 -2159
  61. package/dist/modelViewerProps-HazR2IE_.d.mts +0 -2159
@@ -0,0 +1,949 @@
1
+ import { a9 as ProductCommerceAdapter, ac as ProductConfiguration, N as ObjectBinding, aD as SceneConfig, bf as ViewerCameraState, bi as ViewerModelBounds, ar as ReducedMotionSetting, j as CameraLimits, R as ObjectBindingDecal, a4 as ObjectSurfacePoint, J as ModelViewerLabels, bh as ViewerLoading, bk as ViewerReveal, F as ModelFormat, a3 as ObjectPointerEvent, bj as ViewerModelInfo, L as ObjectActionEvent, e as AnimationControls, ay as SceneAnnotationMarker, be as ViewerCameraConfig, bg as ViewerIsolation, as as SavedMeasurement, w as MeasurementSettings, b2 as SequenceControls } from './modelFileResolver-CVmON8hg.js';
2
+ import { Object3D, Material } from 'three';
3
+ import { ReactNode } from 'react';
4
+ import { CameraControls } from '@react-three/drei';
5
+
6
+ type LicenseStatus = "checking" | "valid" | "invalid";
7
+ interface LicenseResult {
8
+ status: LicenseStatus;
9
+ reason?: string;
10
+ environment?: "development" | "production";
11
+ tier?: string;
12
+ isLocalDomain: boolean;
13
+ }
14
+
15
+ type ViewerProductOptions = {
16
+ /** Connects your own pricing, stock, cart and quote services. */
17
+ adapter?: ProductCommerceAdapter;
18
+ /** Keep the choices in this URL parameter, so a link reopens the same configuration. */
19
+ urlParam?: string;
20
+ /** Start with the panel closed. On small screens it always starts closed. */
21
+ defaultClosed?: boolean;
22
+ onConfigurationChange?: (configuration: ProductConfiguration, checkoutUrl: string | null) => void;
23
+ };
24
+
25
+ type ComparisonCategory = "identity" | "appearance" | "transform" | "visibility" | "data" | "behavior" | "scene";
26
+ type ComparisonStatus = "added" | "removed" | "modified" | "unchanged" | "ambiguous";
27
+ type ConfigurationComparisonInput = {
28
+ objectBindings: Record<string, ObjectBinding>;
29
+ sceneConfig?: SceneConfig;
30
+ };
31
+ type SemanticComparisonOptions = {
32
+ /** Default: modelObjectId. Metadata matching is exact and never guesses duplicates. */
33
+ matchBy?: "modelObjectId" | "id" | {
34
+ metadataKey: string;
35
+ };
36
+ /** Explicit binding-key pairs, before key -> after key. Must be one-to-one. */
37
+ mapping?: Record<string, string>;
38
+ /** Absolute tolerance for numeric properties. Default: 0.000001. */
39
+ tolerance?: number;
40
+ ignoreMetadataKeys?: string[];
41
+ };
42
+ type ComparisonChange = {
43
+ path: string;
44
+ category: ComparisonCategory;
45
+ before?: unknown;
46
+ after?: unknown;
47
+ };
48
+ type ComparisonObject = {
49
+ id: string;
50
+ identity: string;
51
+ label: string;
52
+ status: ComparisonStatus;
53
+ beforeKey?: string;
54
+ afterKey?: string;
55
+ beforeObjectId?: string;
56
+ afterObjectId?: string;
57
+ changes: ComparisonChange[];
58
+ message?: string;
59
+ };
60
+ type ConfigurationComparisonReport = {
61
+ version: 1;
62
+ objects: ComparisonObject[];
63
+ counts: Record<ComparisonStatus, number>;
64
+ sceneChanges: ComparisonChange[];
65
+ };
66
+ type ComparisonHighlight = {
67
+ objectId: string;
68
+ color: string;
69
+ };
70
+ /** Compare authored configuration data. Does not infer geometry changes from meshes or URLs. */
71
+ declare function compareViewerConfigurations(before: ConfigurationComparisonInput, after: ConfigurationComparisonInput, options?: SemanticComparisonOptions): ConfigurationComparisonReport;
72
+
73
+ /** Serializable, controlled viewer props. Assets stay at their durable URLs. */
74
+ type ViewerConfiguration = Pick<ModelViewerProps, "activeModelId" | "modelUrl" | "modelFormat" | "tilesetUrl" | "models" | "mergeModels" | "sceneConfig" | "isolation" | "multiSelectedKeys" | "activeAnnotation" | "annotationCategories" | "backgroundColor" | "shadows" | "cinematic" | "cameraControllerType" | "objectTransformSpace" | "arScaleMode" | "usdzUrl" | "measurements" | "measurementSettings" | "measurementUnit" | "measurementModelId">;
75
+ /** Unversioned camera/visibility/selection links remain readable. */
76
+ type ShareableViewerState = {
77
+ version?: 1;
78
+ camera?: ViewerCameraState;
79
+ hidden?: string[];
80
+ selected?: string | null;
81
+ /** Full bindings, including materials, decals, transforms and metadata. */
82
+ objectBindings?: Record<string, ObjectBinding>;
83
+ configuration?: ViewerConfiguration;
84
+ };
85
+ /** Application-owned persistence. load may return parsed data or saved JSON. */
86
+ type ViewerStateStorage = {
87
+ save: (state: ShareableViewerState) => Promise<string>;
88
+ load: (id: string) => Promise<unknown>;
89
+ };
90
+ declare const MAX_VIEWER_STATE_BYTES: number;
91
+ /** JSON suitable for a file, database or application-owned storage adapter. */
92
+ declare function serializeViewerState(state: ShareableViewerState, baseUrl?: string): string;
93
+ /** Validate portable data. For live blob images use prepareViewerState first. */
94
+ declare function parseViewerState(input: unknown, baseUrl?: string): ShareableViewerState;
95
+ /**
96
+ * Capture live texture/decal/image blobs as data URLs. Models stay at their
97
+ * original durable URLs; no upload service or network asset scraping is used.
98
+ */
99
+ declare function prepareViewerState(input: unknown, baseUrl?: string): Promise<ShareableViewerState>;
100
+
101
+ type ARSnapshotSource = {
102
+ scene: Object3D;
103
+ instanceId?: string;
104
+ objectBindings?: NonNullable<ShareableViewerState["objectBindings"]>;
105
+ materialOverrides?: Record<string, Material | Material[]>;
106
+ /** Authored autoplay clips and sequences to include in Quick Look. */
107
+ sceneConfig?: Pick<SceneConfig, "animations" | "sequences">;
108
+ };
109
+ type ARExportOptions = {
110
+ scaleMode?: "normalized" | "real-world";
111
+ /** Longest texture dimension, default 2048; from 256 to 4096. */
112
+ maxTextureSize?: number;
113
+ signal?: AbortSignal;
114
+ };
115
+ type ARSnapshot = {
116
+ blob: Blob;
117
+ meshCount: number;
118
+ triangleCount: number;
119
+ /** Applied scale after centering horizontally and resting on Y=0. */
120
+ scale: number;
121
+ warnings: string[];
122
+ };
123
+ type ARHandoffRequest = {
124
+ /** Stable key for this configuration and application-supplied asset version. */
125
+ configurationKey: string;
126
+ /** Detached live data. Local model URLs may still be temporary. */
127
+ state: ShareableViewerState;
128
+ signal: AbortSignal;
129
+ /** Exports the current geometry and supported authored animation to USDZ. */
130
+ exportUSDZ: () => Promise<ARSnapshot>;
131
+ };
132
+ type ARHandoffStatus = "idle" | "preparing" | "ready" | "error" | "stale";
133
+ type ARHandoffOptions = {
134
+ /** Change this when replacing an asset at the same URL, or after direct scene mutations. */
135
+ assetVersion?: string;
136
+ maxTextureSize?: number;
137
+ /** Store large phone configurations using the same adapter in the receiving viewer. */
138
+ storage?: ViewerStateStorage;
139
+ /** Read this feature's configuration hash on arrival. Default true. */
140
+ autoRestore?: boolean;
141
+ /** Application-owned conversion/cache for assets unsupported by the local exporter. */
142
+ createUSDZ?: (request: ARHandoffRequest) => Promise<Blob | string>;
143
+ /** Application-owned upload/sharing path, including support for local model files. */
144
+ createMobileUrl?: (request: ARHandoffRequest) => Promise<string>;
145
+ onStatusChange?: (status: ARHandoffStatus) => void;
146
+ onError?: (error: Error) => void;
147
+ };
148
+
149
+ /** Whole-instance placement, outside the asset's authored transforms. Radians, source scene units. */
150
+ type AssetTransform = {
151
+ position?: [number, number, number];
152
+ rotation?: [number, number, number];
153
+ scale?: [number, number, number];
154
+ };
155
+ type AssetPlacement = AssetTransform & {
156
+ label?: string;
157
+ visible?: boolean;
158
+ deleted?: boolean;
159
+ };
160
+ /** Standalone editor placement state, keyed by persistent model identity. */
161
+ type SceneComposition = {
162
+ version: 1;
163
+ placements: Record<string, AssetPlacement>;
164
+ gridSize: number;
165
+ };
166
+ declare function parseAssetTransform(value: unknown): AssetTransform;
167
+ /** Snap the instance origin on the shared X/Z plane. */
168
+ declare function snapAssetToGrid(transform: AssetTransform, size: number): AssetTransform;
169
+ /** Place the transformed asset's lowest bound on the Y=0 ground plane. */
170
+ declare function groundAsset(transform: AssetTransform, bounds: {
171
+ min: [number, number, number];
172
+ max: [number, number, number];
173
+ }): AssetTransform;
174
+
175
+ type PerformanceProfile = "auto" | "high" | "low";
176
+
177
+ type AssetDiagnosticIssue = {
178
+ code: string;
179
+ severity: "info" | "warning" | "error";
180
+ title: string;
181
+ detail: string;
182
+ suggestion: string;
183
+ count?: number;
184
+ /** At most twenty names, even when a large asset has thousands of affected objects. */
185
+ objects?: string[];
186
+ };
187
+ type AssetDiagnosticsSource = {
188
+ format?: string;
189
+ name?: string;
190
+ sourceBytes?: number | null;
191
+ loadDurationMs?: number | null;
192
+ extensionsUsed?: string[];
193
+ extensionsRequired?: string[];
194
+ failedResources?: string[];
195
+ };
196
+ type AssetTextureDiagnostic = {
197
+ name: string;
198
+ width: number | null;
199
+ height: number | null;
200
+ compressed: boolean;
201
+ /** RGBA8 with mipmaps for ordinary textures; actual mip bytes for compressed textures. */
202
+ estimatedBytes: number | null;
203
+ };
204
+ type AssetDiagnosticsReport = {
205
+ version: 1;
206
+ status: "ready" | "failed";
207
+ scope: "asset" | "resident-tiles";
208
+ source: AssetDiagnosticsSource;
209
+ /** A format convention, not verification of the model author's physical scale. */
210
+ units: "meters (glTF convention)" | "unknown";
211
+ bounds: ViewerModelBounds | null;
212
+ statistics: {
213
+ meshes: number;
214
+ instances: number;
215
+ geometries: number;
216
+ materials: number;
217
+ textures: number;
218
+ /** Unique geometry data, not repeated instances or per-frame rendered triangles. */
219
+ vertices: number;
220
+ triangles: number;
221
+ geometryBytes: number;
222
+ estimatedTextureBytes: number;
223
+ unknownTextureSizes: number;
224
+ meshesWithoutUvs: number;
225
+ meshesWithoutNormals: number;
226
+ } | null;
227
+ textures: AssetTextureDiagnostic[];
228
+ extensions: {
229
+ name: string;
230
+ required: boolean;
231
+ recognized: boolean;
232
+ }[];
233
+ issues: AssetDiagnosticIssue[];
234
+ };
235
+ type InspectAssetOptions = {
236
+ source?: AssetDiagnosticsSource;
237
+ scope?: AssetDiagnosticsReport["scope"];
238
+ };
239
+ type StreamingDiagnostics = {
240
+ cachedBytes: number | null;
241
+ budgetBytes: number;
242
+ cachedTiles: number | null;
243
+ downloading: number;
244
+ parsing: number;
245
+ cacheFull: boolean;
246
+ /** Existing memory-pressure adaptation's multiplier; 1 is the requested detail. */
247
+ detailFactor: number;
248
+ errorTarget: number;
249
+ };
250
+ type ViewerRuntimeStats = {
251
+ sampledAt: string;
252
+ renderer: "webgl" | "webgpu";
253
+ /** Last completed renderer pass; may be a post-processing or shadow pass. */
254
+ drawCalls: number | null;
255
+ triangles: number | null;
256
+ geometries: number | null;
257
+ textures: number | null;
258
+ /** Spacing of consecutive active frame callbacks, not CPU/GPU execution time. */
259
+ frameIntervalMs: number | null;
260
+ fps: number | null;
261
+ frameSamples: number;
262
+ renderMode: "always" | "demand" | "never";
263
+ quality: {
264
+ profile: PerformanceProfile;
265
+ reducedGpuLoad: boolean;
266
+ dpr: number;
267
+ shadows: boolean;
268
+ /** Whether the quality profile/backend permits the post-processing stack. */
269
+ postProcessing: boolean;
270
+ };
271
+ streaming: StreamingDiagnostics | null;
272
+ };
273
+
274
+ /** Engagement from deliberate viewer interactions, with model/session context. */
275
+ type ViewerEngagementEvent = {
276
+ /** Ephemeral identifier for this viewer/model session; no persistent storage. */
277
+ sessionId: string;
278
+ /** ISO timestamp of the event. */
279
+ timestamp: string;
280
+ /** Milliseconds since tracking started for this model. */
281
+ elapsedMs: number;
282
+ modelUrl: string;
283
+ tilesetUrl: string | null;
284
+ } & ({
285
+ type: "part-viewed";
286
+ objectId: string;
287
+ objectKey: string;
288
+ label?: string;
289
+ source: "canvas" | "panel" | "keyboard";
290
+ } | {
291
+ type: "variant-chosen";
292
+ /** The variant chosen; null when a group's choice was cleared. */
293
+ variant: string | null;
294
+ /** The group's previous choice. */
295
+ previousVariant: string | null;
296
+ /** The option group's name; null for a group without one. */
297
+ group: string | null;
298
+ } | {
299
+ type: "ar-started";
300
+ } | {
301
+ type: "ar-ended";
302
+ durationMs: number;
303
+ reason: "session-ended" | "interrupted";
304
+ } | {
305
+ type: "ar-launch-requested";
306
+ channel: "quick-look" | "mobile-handoff";
307
+ } | {
308
+ type: "tour-started";
309
+ annotationCount: number;
310
+ } | {
311
+ type: "tour-completed";
312
+ annotationCount: number;
313
+ durationMs: number;
314
+ } | {
315
+ type: "tour-stopped";
316
+ annotationCount: number;
317
+ durationMs: number;
318
+ reason: "stopped" | "restarted" | "annotations-changed" | "interrupted";
319
+ });
320
+
321
+ type MouseControllerPosition = 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right' | 'center' | 'center-bottom' | 'center-top';
322
+
323
+ type XRScaleMode = "normalized" | "real-world";
324
+
325
+ /** A starting set of ModelViewer props for a common kind of page. */
326
+ type ModelViewerPreset = "minimal" | "showcase" | "configurator" | "inspector";
327
+ type ModelViewerUiOptions = {
328
+ /** The left panel for the selected object. Default `true`. */
329
+ objectPanel?: boolean;
330
+ /** The right panel listing the model's objects. Default `true`. */
331
+ sceneObjects?: boolean;
332
+ /** The download button; a string also sets the file name. Default `true`. */
333
+ download?: boolean | string;
334
+ /** The reset-view button. Default `true`. */
335
+ reset?: boolean;
336
+ /** The viewer fullscreen toggle in the action bar. Default `false`. */
337
+ fullscreen?: boolean;
338
+ /** The loading overlay and load-error message. Default `true`. */
339
+ loadingOverlay?: boolean;
340
+ /** The axis gizmo in the top-right corner. Default `false`. */
341
+ viewGizmo?: boolean;
342
+ /** The on-screen movement pad; an object also places it. Default `false`. */
343
+ mouseController?: boolean | {
344
+ position?: MouseControllerPosition;
345
+ opacity?: number;
346
+ };
347
+ /** Previous/Stop/Next controls for annotation tours. Default `true`. */
348
+ annotationNavigation?: boolean;
349
+ /** Show an annotation's details when its marker is hovered. Default `false`. */
350
+ annotationOnHover?: boolean;
351
+ /** Category filter chips. Default `true` when annotations have categories. */
352
+ annotationFilters?: boolean;
353
+ /** Highlight objects under the pointer. Default `true`. */
354
+ highlightOnHover?: boolean;
355
+ /** Swatch rows for the model's glTF material variants, one per option group. Default `true`. */
356
+ materialVariants?: boolean;
357
+ /**
358
+ * A tab stop for moving through and selecting objects with the keyboard,
359
+ * shown only while it has focus. Default `true`.
360
+ */
361
+ objectNavigator?: boolean;
362
+ };
363
+ /**
364
+ * Takes over parts of texture positioning (`texturePositioning`). Fields left
365
+ * out keep the viewer's own behavior, which reads and writes the binding.
366
+ */
367
+ type TexturePositioningControls = {
368
+ /** Shown in the Offset fields instead of the binding's offset. */
369
+ offset?: [number, number];
370
+ /** Shown in the Rotation field instead of the binding's, in degrees (0–360). */
371
+ rotationDegrees?: number;
372
+ /** Replaces the viewer's write when an Offset field changes. */
373
+ onOffsetChange?: (objectId: string, axisIndex: 0 | 1, value: number) => void;
374
+ /** Replaces the viewer's write when the Rotation field changes. */
375
+ onRotationChange?: (objectId: string, degrees: number) => void;
376
+ /** Whether to show "Done positioning" rather than the hint. */
377
+ isPositioning?: boolean;
378
+ /** Called after "Done positioning" ends Move/Zoom mode. */
379
+ onEndPositioning?: () => void;
380
+ };
381
+ type ModelViewerToolsOptions = {
382
+ /** Distance and dimension tools; an object also sets the unit. Default `false`. */
383
+ measure?: boolean | {
384
+ unit?: string;
385
+ };
386
+ /** The UV checker toggle. Default `false`. */
387
+ uvChecker?: boolean;
388
+ /** The exploded-view slider. Default `false`. */
389
+ explode?: boolean;
390
+ /** The section-cut tool, to cut the model open along an axis. Default `false`. */
391
+ section?: boolean;
392
+ /** A compact player for authored scene sequences. Default true. */
393
+ sequences?: boolean;
394
+ /** Isolate buttons in the scene objects panel, and a "Show all" pill. Default `false`. */
395
+ isolate?: boolean;
396
+ /** Texture offset, rotation and Move/Zoom for textured objects. Default `false`. */
397
+ texturePositioning?: boolean | TexturePositioningControls;
398
+ };
399
+ type ModelViewerControlsOptions = {
400
+ /** Orbit, pan and zoom with the pointer. Default `true`. */
401
+ enabled?: boolean;
402
+ /** Move the camera with the keyboard while the canvas has focus. Default `false`. */
403
+ keyboard?: boolean;
404
+ /**
405
+ * Cut motion the viewer starts on its own (auto-rotate, cinematic autoplay,
406
+ * camera glides). `"user"` follows the visitor's reduced-motion setting.
407
+ * Default `"user"`.
408
+ */
409
+ reducedMotion?: ReducedMotionSetting;
410
+ /** Wheel, pinch and middle-drag zoom, and zooming to a selected object. Default `true`. */
411
+ zoom?: boolean;
412
+ /**
413
+ * For a viewer inside a scrolling page: the mouse wheel scrolls the page
414
+ * (hold Ctrl or ⌘ to zoom; a trackpad pinch still zooms), and on touch
415
+ * screens a vertical swipe scrolls the page while a sideways drag rotates.
416
+ * Default `false`.
417
+ */
418
+ pageScroll?: boolean;
419
+ /** Zoom to an object when it's selected. Default `true`. */
420
+ zoomOnSelect?: boolean;
421
+ /** Turn the model slowly; a number sets the speed (1 is normal). Default `false`. */
422
+ autoRotate?: boolean | number;
423
+ /** Re-frame the model, or the selected object it zoomed to, when the viewer is resized. Default `true`. */
424
+ refitOnResize?: boolean;
425
+ /** Distance, angle and pan limits for the camera. */
426
+ limits?: CameraLimits;
427
+ /** Movement pad speed. Default `0.08`. */
428
+ moveSensitivity?: number;
429
+ /** Movement pad zoom speed. Default `1`. */
430
+ zoomSensitivity?: number;
431
+ };
432
+ type ModelViewerPerfOptions = {
433
+ /** `"demand"` draws only when something changes. Default `"demand"`. */
434
+ renderMode?: "always" | "demand";
435
+ /** Highest device pixel ratio to render at. Default `2`. */
436
+ maxDpr?: number;
437
+ /** `"low"` trades quality for speed on weak devices. Default `"auto"`. */
438
+ profile?: PerformanceProfile;
439
+ /** Needed for Download PNG and captureImage; costs GPU time. Default `false`. */
440
+ preserveDrawingBuffer?: boolean;
441
+ /**
442
+ * Draw with three's WebGPU renderer where the browser has WebGPU, WebGL
443
+ * elsewhere. Leaves out post-processing effects, contact shadows and WebXR.
444
+ * Default `false`.
445
+ */
446
+ webgpu?: boolean;
447
+ };
448
+ type ModelViewerTilesOptions = {
449
+ /** A 3D Tiles `tileset.json` to stream instead of loading `modelUrl` whole. */
450
+ url?: string | null;
451
+ /** Screen-space error target; lower is sharper. Default `8`. */
452
+ errorTarget?: number;
453
+ /** Most parsed tiles kept in memory. Default `800`. */
454
+ cacheSize?: number;
455
+ };
456
+ type ModelViewerXrOptions = {
457
+ /** "View in your space" (AR) and "Enter VR". Default `false`. */
458
+ enabled?: boolean;
459
+ /** A USDZ file for iOS AR Quick Look. */
460
+ usdzUrl?: string;
461
+ /** How the model is sized in AR. Default `"normalized"`. */
462
+ scaleMode?: XRScaleMode;
463
+ /** The page the desktop QR code opens on a phone. Default: the current page. */
464
+ mobileHandoffUrl?: string;
465
+ /** Prepare the edited configuration for USDZ and phone handoff. Opt-in. */
466
+ arHandoff?: boolean | ARHandoffOptions;
467
+ };
468
+ type ModelViewerDecoderOptions = {
469
+ /** Directory of the DRACO decoder files, or `false`. */
470
+ draco?: string | false;
471
+ /** Directory of the Basis/KTX2 transcoder files, or `false`. */
472
+ ktx2?: string | false;
473
+ /** Enable the bundled Meshopt decoder. Default `true`. */
474
+ meshopt?: boolean;
475
+ };
476
+ type GroupedModelViewerProps = {
477
+ /**
478
+ * A starting set of props for a common kind of page. Anything else you pass
479
+ * overrides it.
480
+ */
481
+ preset?: ModelViewerPreset;
482
+ ui?: ModelViewerUiOptions;
483
+ tools?: ModelViewerToolsOptions;
484
+ controls?: ModelViewerControlsOptions;
485
+ perf?: ModelViewerPerfOptions;
486
+ tiles?: ModelViewerTilesOptions;
487
+ xr?: ModelViewerXrOptions;
488
+ decoders?: ModelViewerDecoderOptions;
489
+ };
490
+ /** What each preset sets. Props that aren't listed keep their defaults. */
491
+ declare const MODEL_VIEWER_PRESETS: Readonly<Record<ModelViewerPreset, Readonly<Partial<ModelViewerProps>>>>;
492
+
493
+ type DecalMoveTarget = {
494
+ objectId: string;
495
+ decal: ObjectBindingDecal;
496
+ onCommit: (surface: ObjectSurfacePoint) => void;
497
+ onCancel: () => void;
498
+ };
499
+
500
+ type CameraControllerType = "orbit" | "pointerLock";
501
+
502
+ /** One bindable object in a model, as reported by `onObjectCatalog`. */
503
+ type ViewerObjectInfo = {
504
+ /** The node identifier bindings are keyed by. */
505
+ name: string;
506
+ triangles: number;
507
+ /**
508
+ * Axis-aligned bounds in the model's own units, in Z-up coordinates (the 3D
509
+ * Tiles convention): a glTF point (x, y, z) is (x, -z, y) here.
510
+ */
511
+ minimum: [number, number, number];
512
+ maximum: [number, number, number];
513
+ };
514
+
515
+ type CinematicWaypoint = {
516
+ position: [number, number, number];
517
+ target: [number, number, number];
518
+ /**
519
+ * Orbit angles in radians, as BindingBuilder captures them: position and
520
+ * target alone can't represent the rotation straight above or below the
521
+ * target. Leave them out when writing waypoints by hand.
522
+ */
523
+ azimuthAngle?: number;
524
+ polarAngle?: number;
525
+ segmentDuration?: number;
526
+ };
527
+ type CinematicConfig = {
528
+ waypoints?: CinematicWaypoint[];
529
+ duration?: number;
530
+ loop?: boolean;
531
+ autoPlay?: boolean;
532
+ };
533
+
534
+ /** Which three.js renderer draws a viewer. */
535
+ type RendererBackend = "webgl" | "webgpu";
536
+
537
+ type CaptureImageOptions = {
538
+ width?: number;
539
+ height?: number;
540
+ transparent?: boolean;
541
+ type?: "image/png" | "image/jpeg";
542
+ quality?: number;
543
+ };
544
+
545
+ type CaptureVideoOptions = {
546
+ /** Defaults to cinematic when a path is enabled, otherwise turntable. */
547
+ mode?: "cinematic" | "turntable";
548
+ /**
549
+ * Auto prefers WebM, then MP4. `"gif"` makes an animated GIF that loops
550
+ * forever. Explicit formats reject if unsupported.
551
+ */
552
+ format?: "auto" | "webm" | "mp4" | "gif";
553
+ /**
554
+ * Seconds per pass, in (0, 300]. Defaults to path timing, or an orbit of
555
+ * 24s (8s for a GIF).
556
+ */
557
+ duration?: number;
558
+ /** Capture frame rate, from 1 to 60. Default 30 (15 for a GIF). */
559
+ fps?: number;
560
+ /** Encoder target bitrate in bits per second. Default 8,000,000. Not used for GIFs. */
561
+ videoBitsPerSecond?: number;
562
+ /**
563
+ * GIF width in pixels, from 16 to 4096; the height follows the canvas. Never
564
+ * wider than the canvas. Default 480.
565
+ */
566
+ gifWidth?: number;
567
+ /** Aborting discards the recording and restores the viewer. */
568
+ signal?: AbortSignal;
569
+ };
570
+
571
+ type ViewerCameraPreset = {
572
+ position: [number, number, number];
573
+ target: [number, number, number];
574
+ fov?: number | null;
575
+ zoom?: number;
576
+ azimuthAngle?: number;
577
+ polarAngle?: number;
578
+ };
579
+ type UseViewerCameraOptions = {
580
+ /** Camera position applied once when each model becomes ready. */
581
+ initialPosition?: [number, number, number];
582
+ /** Orbit target applied once when each model becomes ready. */
583
+ initialTarget?: [number, number, number];
584
+ /** Whether the initial position/target should animate. Defaults to false. */
585
+ initialTransition?: boolean;
586
+ /** Initial named views, read once. Use setCameraPresets to load later edits. */
587
+ presets?: Record<string, ViewerCameraPreset>;
588
+ };
589
+ type HomeCameraState = {
590
+ position: [number, number, number];
591
+ target: [number, number, number];
592
+ };
593
+ type ViewerReadyState = {
594
+ objectBindings: Record<string, ObjectBinding>;
595
+ homeCameraState: HomeCameraState | null;
596
+ captureImage: (options?: CaptureImageOptions) => Promise<string>;
597
+ /** Whether a streamed model is still fetching tiles for the current view. */
598
+ isLoadingTiles: () => boolean;
599
+ /** Records one cinematic pass or turntable revolution as a video Blob. */
600
+ captureVideo: (options?: CaptureVideoOptions) => Promise<Blob>;
601
+ invalidate: () => void;
602
+ /**
603
+ * The renderer drawing the viewer: "webgpu" only when ModelViewer's
604
+ * `webgpu` asked for it and the browser has WebGPU.
605
+ */
606
+ rendererBackend: RendererBackend;
607
+ /**
608
+ * The live three.js scene, camera-controls instance, and model nodes, for
609
+ * integrations the rest of the API doesn't cover. Their shapes are those
610
+ * libraries' own and can change with them.
611
+ */
612
+ raw: {
613
+ controls: CameraControls;
614
+ scene: Object3D | null;
615
+ /** Model nodes by binding key and node name. */
616
+ nodes: Record<string, Object3D>;
617
+ };
618
+ };
619
+ type ViewerCameraProps = {
620
+ /**
621
+ * Rendering is suspended because the viewer is offscreen. Camera commands
622
+ * still complete: they jump straight to their end instead of animating.
623
+ */
624
+ isRenderPaused: boolean;
625
+ cameraState: ViewerCameraState | null;
626
+ cameraPresets: Record<string, ViewerCameraPreset>;
627
+ /** Replace named views after loading or editing them; does not move the camera. */
628
+ setCameraPresets: (presets: Record<string, ViewerCameraPreset>) => void;
629
+ resetView: () => Promise<boolean>;
630
+ /**
631
+ * Moves to the binding's `cameraState` when it has a position and target,
632
+ * as selecting the object in the viewer does; otherwise frames the object.
633
+ */
634
+ focusObject: (objectId: string) => Promise<boolean>;
635
+ fitScene: () => Promise<boolean>;
636
+ setCameraTarget: (target: [number, number, number], enableTransition?: boolean) => Promise<boolean>;
637
+ setCameraState: (state: ViewerCameraState, enableTransition?: boolean) => Promise<boolean>;
638
+ lookAt: (position: [number, number, number], target: [number, number, number], enableTransition?: boolean) => Promise<boolean>;
639
+ /**
640
+ * Orbits the camera around its target to the given angles, in degrees.
641
+ * Azimuth is the horizontal angle (0 is the front, +Z; 90 the right, +X);
642
+ * polar is the vertical angle (0 straight down, 90 level, 180 straight up).
643
+ */
644
+ orbitTo: (azimuthDegrees: number, polarDegrees: number, enableTransition?: boolean) => Promise<boolean>;
645
+ dollyTo: (distance: number, enableTransition?: boolean) => Promise<boolean>;
646
+ savePreset: (name: string) => ViewerCameraState | null;
647
+ goToPreset: (name: string, enableTransition?: boolean) => Promise<boolean>;
648
+ handleCameraChange: (state: ViewerCameraState) => void;
649
+ handleViewerReady: (viewer: ViewerReadyState) => void;
650
+ };
651
+ declare function useViewerCamera(options?: UseViewerCameraOptions): ViewerCameraProps;
652
+
653
+ type ObjectTransformSpace = "local" | "world";
654
+
655
+ type ModelMergeSource = {
656
+ url: string;
657
+ namePrefix: string;
658
+ };
659
+
660
+ type AnnotationMarker = SceneAnnotationMarker & {
661
+ markerId?: string;
662
+ };
663
+ type CustomObjectBindingDataPanelProps = {
664
+ isOpen: boolean;
665
+ selectedObject: ObjectBinding | null;
666
+ currentAction: ObjectActionEvent | null;
667
+ onClose: () => void;
668
+ onAction: (event: ObjectActionEvent) => void;
669
+ };
670
+ type CustomSceneObjectsPanelProps = {
671
+ objectBindings: Record<string, ObjectBinding>;
672
+ onAction?: (event: ObjectActionEvent) => void;
673
+ onFocus?: (binding: ObjectBinding) => void;
674
+ onHover?: (binding: ObjectBinding | null) => void;
675
+ };
676
+ type ModelViewerProps = GroupedModelViewerProps & {
677
+ /** Plain-text overrides for built-in UI labels. Missing keys use English. */
678
+ labels?: ModelViewerLabels;
679
+ modelUrl: string;
680
+ /**
681
+ * An image shown in the viewer's place until its 3D view is drawn: a render
682
+ * or photo of the model, best framed as the viewer frames it. Fitted inside
683
+ * the viewer; set the CSS variable `--ri-poster-fit: cover` to fill it.
684
+ */
685
+ poster?: string;
686
+ /**
687
+ * `"lazy"` (default) starts the 3D view when the viewer is on or near the
688
+ * screen. When the page needs room for viewers in view, one scrolled away
689
+ * from goes back to a picture of itself, and comes back as it was. `"eager"`
690
+ * starts at once and keeps its view.
691
+ */
692
+ loading?: ViewerLoading;
693
+ /**
694
+ * `"interaction"` keeps the poster, with a "View in 3D" button, until the
695
+ * visitor asks for the 3D view. Default `"auto"`.
696
+ */
697
+ reveal?: ViewerReveal;
698
+ /** Optional 3D Tiles manifest used instead of loading `modelUrl` monolithically. */
699
+ tilesetUrl?: string | null;
700
+ /** Screen-space error target for streamed 3D Tiles. Lower is sharper. */
701
+ tilesErrorTarget?: number;
702
+ /** Maximum number of parsed tiles retained by the client cache. */
703
+ tilesCacheSize?: number;
704
+ /**
705
+ * Every bindable object in the model: each named mesh, under the identifier
706
+ * bindings are keyed by. Reported each time a model loads; for a streamed
707
+ * model it comes from the catalog beside `tileset.json`, before the tiles
708
+ * that contain those objects have necessarily loaded.
709
+ */
710
+ onObjectCatalog?: (objects: ViewerObjectInfo[]) => void;
711
+ /** Explicit format for extensionless or signed model URLs. */
712
+ modelFormat?: ModelFormat;
713
+ licenseKey: string;
714
+ /** License state for application-owned loading and error interfaces. */
715
+ onLicenseStatusChange?: (result: LicenseResult) => void;
716
+ hideLicenseCheckingOverlay?: boolean;
717
+ /**
718
+ * The model's interactive objects, keyed by node name. Defaults to `"auto"`:
719
+ * a default binding for every mesh, generated when the model loads and
720
+ * reported through `onObjectBindingsChange`.
721
+ */
722
+ objectBindings?: Record<string, ObjectBinding> | "auto";
723
+ /**
724
+ * The selected object's binding (an `ObjectBinding`, not a three.js
725
+ * `Object3D`). Pass `null` to control selection with nothing selected.
726
+ */
727
+ selectedObject?: ObjectBinding | null;
728
+ /** Transient bounds outlines for semantic comparison; never modify authored materials. */
729
+ comparisonHighlights?: readonly ComparisonHighlight[];
730
+ /**
731
+ * Binding keys of several selected objects. Each is outlined in green.
732
+ * While set, the single-selection (blue) outline is hidden.
733
+ */
734
+ multiSelectedKeys?: readonly string[];
735
+ /** Explicit nodes to outline together, overriding multiSelectedKeys. */
736
+ selectedObjectRefs?: Object3D[] | null;
737
+ /** Color of the multi-selection outlines. Defaults to green. */
738
+ selectedObjectOutlineColor?: string;
739
+ panelHoveredObject?: ObjectBinding | null;
740
+ onObjectBindingsChange?: (next: Record<string, ObjectBinding>) => void;
741
+ onObjectSelect?: (binding: ObjectBinding | null) => void;
742
+ onObjectHover?: (binding: ObjectBinding | null) => void;
743
+ /**
744
+ * An object was double-clicked. Return `true` to skip the viewer's own
745
+ * double-click behavior: moving the orbit point to that spot, or starting
746
+ * texture positioning when that's enabled.
747
+ */
748
+ onObjectDoubleClick?: (event: ObjectPointerEvent) => boolean | void;
749
+ /** A decal on the model was double-clicked (the editor uses this to enable Move). */
750
+ onDecalDoubleClick?: (binding: ObjectBinding, decalId: string) => void;
751
+ /**
752
+ * An object was right-clicked or, on touch screens, long-pressed. Use it to
753
+ * open your own menu at `clientX`/`clientY`. A right-drag still pans.
754
+ */
755
+ onObjectContextMenu?: (event: ObjectPointerEvent) => void;
756
+ /** Editor preview: grab this decal and drag it over its object's surface. */
757
+ decalMove?: DecalMoveTarget | null;
758
+ /** The model finished loading: its bounds and mesh count. */
759
+ onModelLoaded?: (model: ViewerModelInfo) => void;
760
+ /** Opt-in inspection of the active loaded asset, including its merged nodes. */
761
+ onAssetDiagnostics?: (report: AssetDiagnosticsReport) => void;
762
+ /** Opt-in sampled statistics for this viewer's entire canvas. Does not force frames. */
763
+ onRuntimeStats?: (stats: ViewerRuntimeStats) => void;
764
+ /** Runtime sampling interval, clamped to 250–10000 ms; default 1000 ms. */
765
+ runtimeStatsIntervalMs?: number;
766
+ onLoadError?: (error: unknown) => void;
767
+ onProgress?: (event: ProgressEvent) => void;
768
+ onCameraControllerChange?: (controller: CameraControllerType) => void;
769
+ cameraControllerType?: CameraControllerType;
770
+ onAction?: (event: ObjectActionEvent) => void;
771
+ onHiddenObjectsChange?: (next: Record<string, boolean>) => void;
772
+ /** Opt-in interaction analytics; no telemetry is sent by the viewer. */
773
+ onEngagement?: (event: ViewerEngagementEvent) => void | Promise<void>;
774
+ /** Log engagement events in the developer console. Default `false`. */
775
+ debugEngagement?: boolean;
776
+ /** The camera moved. Fires often while the user orbits, pans or zooms. */
777
+ onCameraChange?: (state: ViewerCameraState) => void;
778
+ onViewerReady?: (viewer: ViewerReadyState) => void;
779
+ onTextureUpload?: (file: File, objectId: string) => Promise<string>;
780
+ onAnimationsReady?: (controls: AnimationControls) => void;
781
+ onModelAnimationsReady?: (url: string, controls: AnimationControls) => void;
782
+ onAnnotationsChange?: (annotations: AnnotationMarker[]) => void;
783
+ activeAnnotation?: AnnotationMarker | null;
784
+ onActiveAnnotationChange?: (annotation: AnnotationMarker | null) => void;
785
+ camera?: ViewerCameraConfig;
786
+ cameraLimits?: CameraLimits;
787
+ backgroundColor?: string;
788
+ shadows?: boolean;
789
+ showObjectBindingDataPanel?: boolean;
790
+ customObjectBindingDataPanel?: (props: CustomObjectBindingDataPanelProps) => ReactNode;
791
+ customSceneObjectsPanel?: (props: CustomSceneObjectsPanelProps) => ReactNode;
792
+ showSceneObjectsPanel?: boolean;
793
+ showDownloadButton?: boolean;
794
+ downloadFilename?: string;
795
+ showResetButton?: boolean;
796
+ /** Fullscreen action button; grouped form: `ui.fullscreen`. Default `false`. */
797
+ showFullscreenButton?: boolean;
798
+ showLoadingOverlay?: boolean;
799
+ showMouseController?: boolean;
800
+ mouseControllerPosition?: MouseControllerPosition;
801
+ mouseControllerOpacity?: number;
802
+ moveSensitivity?: number;
803
+ zoomSensitivity?: number;
804
+ sceneConfig?: SceneConfig;
805
+ /** Turns off wheel, pinch and middle-drag zoom, and zooming to a selected object. */
806
+ disableZoom?: boolean;
807
+ /**
808
+ * For a viewer inside a scrolling page: the mouse wheel scrolls the page
809
+ * (hold Ctrl or ⌘ to zoom; a trackpad pinch still zooms), and on touch
810
+ * screens a vertical swipe scrolls the page while a sideways drag rotates.
811
+ */
812
+ pageScroll?: boolean;
813
+ zoomOnSelected?: boolean;
814
+ highlightOnHover?: boolean;
815
+ onAutoFit?: () => Promise<boolean>;
816
+ enableCameraControls?: boolean;
817
+ moveModeEnabled?: boolean;
818
+ /** Shows a draggable corner handle to resize the selected object, independently of moveModeEnabled. */
819
+ scaleModeEnabled?: boolean;
820
+ /** Aligns PivotControls to the scene or to the selected object. */
821
+ objectTransformSpace?: ObjectTransformSpace;
822
+ /** Enables canvas-focused camera shortcuts. Disabled by default. */
823
+ enableKeyboardNavigation?: boolean;
824
+ /**
825
+ * Cuts motion the viewer starts on its own: auto-rotate and cinematic
826
+ * autoplay don't start, and camera moves jump instead of gliding. `"user"`
827
+ * (default) follows the visitor's `prefers-reduced-motion` setting;
828
+ * `"always"` and `"never"` override it.
829
+ */
830
+ reducedMotion?: ReducedMotionSetting;
831
+ refitOnResize?: boolean;
832
+ renderMode?: "always" | "demand";
833
+ maxDpr?: number;
834
+ preserveDrawingBuffer?: boolean;
835
+ webgpu?: boolean;
836
+ performanceProfile?: PerformanceProfile;
837
+ dracoDecoderPath?: string | false;
838
+ ktx2TranscoderPath?: string | false;
839
+ meshopt?: boolean;
840
+ showMeasureTools?: boolean;
841
+ showUvCheckerButton?: boolean;
842
+ showExplodeControls?: boolean;
843
+ isolation?: ViewerIsolation | null;
844
+ onIsolationChange?: (isolation: ViewerIsolation | null) => void;
845
+ showIsolateControls?: boolean;
846
+ showSectionTools?: boolean;
847
+ /**
848
+ * Lets visitors choose from `sceneConfig.product`, in a panel over the model.
849
+ * `true` uses the defaults; an object connects services, links and callbacks.
850
+ */
851
+ productOptions?: boolean | ViewerProductOptions;
852
+ showMaterialVariants?: boolean;
853
+ showObjectNavigator?: boolean;
854
+ cinematic?: boolean | CinematicConfig;
855
+ measurementUnit?: string;
856
+ /** Controlled named measurements; otherwise sceneConfig.measurements or local state. */
857
+ measurements?: SavedMeasurement[];
858
+ onMeasurementsChange?: (measurements: SavedMeasurement[]) => void;
859
+ /** Authored/display units and optional metres-per-unit calibration. */
860
+ measurementSettings?: MeasurementSettings;
861
+ /** Stable asset id for measurements when uploaded files receive new blob URLs. */
862
+ measurementModelId?: string;
863
+ onMeasurementSettingsChange?: (settings: MeasurementSettings) => void;
864
+ enableXR?: boolean;
865
+ usdzUrl?: string;
866
+ arScaleMode?: XRScaleMode;
867
+ mobileHandoffUrl?: string;
868
+ /** Prepare the edited configuration for USDZ and phone handoff. Opt-in. */
869
+ arHandoff?: boolean | ARHandoffOptions;
870
+ /** Receive sequence controls on load, or null when disconnected. */
871
+ onSequencesReady?: (controls: SequenceControls | null) => void;
872
+ /** Show a compact player when sceneConfig contains sequences. Default true. */
873
+ showSequenceControls?: boolean;
874
+ /** Honor sequence autoPlay flags. Default true; reduced motion disables autoplay. */
875
+ sequenceAutoPlay?: boolean;
876
+ showAnnotationNavigation?: boolean;
877
+ showAnnotationOnHover?: boolean;
878
+ showAnnotationFilters?: boolean;
879
+ annotationCategories?: string[] | null;
880
+ onAnnotationCategoriesChange?: (categories: string[] | null) => void;
881
+ onSceneConfigChange?: (config: SceneConfig) => void;
882
+ showViewGizmo?: boolean;
883
+ /**
884
+ * Your own UI over the 3D view: badges, HUDs, custom panels. It sits above
885
+ * the model and below the viewer's toolbars. The layer lets pointer events
886
+ * through to the model; its direct children receive them, so position them
887
+ * yourself (for example `position: "absolute"`).
888
+ */
889
+ overlay?: ReactNode;
890
+ /**
891
+ * react-three-fiber elements rendered inside the scene, for anything the
892
+ * viewer can't do itself. They work with three.js directly, so they're
893
+ * outside the viewer's own API and can break when three.js or
894
+ * react-three-fiber change.
895
+ */
896
+ unsafe_sceneChildren?: ReactNode;
897
+ autoRotate?: boolean;
898
+ autoRotateSpeed?: number;
899
+ /**
900
+ * Texture positioning for objects with an uploaded texture: Offset and
901
+ * Rotation fields in the Change Material panel, and Move/Zoom mode on
902
+ * double-click (drag to move, scroll to scale). Off by default. Pass `true`,
903
+ * or an object to take over parts of it; changes are written to the
904
+ * binding's `style.material.texture`.
905
+ */
906
+ texturePositioning?: boolean | TexturePositioningControls;
907
+ extraModelUrls?: string[];
908
+ onExtraModelError?: (url: string, error: unknown) => void;
909
+ onExtraModelLoaded?: (url: string, scene: Object3D) => void;
910
+ originalNodePoses?: Record<string, {
911
+ position: [number, number, number];
912
+ rotation?: [number, number, number];
913
+ scale?: [number, number, number];
914
+ }>;
915
+ /** Each entry supplies its own bindings. Uncontrolled edits are kept per instance (id ?? url). */
916
+ models?: ModelViewerModelEntry[];
917
+ /** Select an explicit instance ID, allowing several entries to reuse one URL. */
918
+ activeModelId?: string;
919
+ /** Instance switcher callback; preferred over onModelChange in ID mode. */
920
+ onActiveModelChange?: (id: string) => void;
921
+ mergeModels?: ModelMergeSource[];
922
+ onMergeModelLoaded?: (url: string, mergedRoot: Object3D) => void;
923
+ onMergeModelError?: (url: string, error: unknown) => void;
924
+ /** Selects a model from the switcher. The switcher is hidden when omitted. */
925
+ onModelChange?: (url: string) => void;
926
+ };
927
+ type ModelViewerModelEntry = {
928
+ url: string;
929
+ /** Stable unique instance identity. Required when URLs repeat. Object IDs stay local to each instance. */
930
+ id?: string;
931
+ /** Whole-asset placement; independent of node transforms and scene model rotation. */
932
+ transform?: AssetTransform;
933
+ /** Hide this whole instance without changing its object bindings. */
934
+ visible?: boolean;
935
+ /** Display name for the model switcher; falls back to the URL's filename. */
936
+ label?: string;
937
+ /** Bindings for this model; used in preference to top-level objectBindings. */
938
+ objectBindings: Record<string, ObjectBinding>;
939
+ originalNodePoses?: Record<string, {
940
+ position: [number, number, number];
941
+ rotation?: [number, number, number];
942
+ scale?: [number, number, number];
943
+ }>;
944
+ mergeModels?: ModelMergeSource[];
945
+ /** Scene settings for this slot while parked; the active slot uses the viewer's sceneConfig. */
946
+ sceneConfig?: SceneConfig;
947
+ };
948
+
949
+ export { type TexturePositioningControls as $, type ARExportOptions as A, type ModelMergeSource as B, type CameraControllerType as C, type DecalMoveTarget as D, type ModelViewerControlsOptions as E, type ModelViewerDecoderOptions as F, type GroupedModelViewerProps as G, type HomeCameraState as H, type InspectAssetOptions as I, type ModelViewerModelEntry as J, type ModelViewerPerfOptions as K, type LicenseResult as L, MAX_VIEWER_STATE_BYTES as M, type ModelViewerPreset as N, type ModelViewerProps as O, type ModelViewerTilesOptions as P, type ModelViewerToolsOptions as Q, type ModelViewerUiOptions as R, type ModelViewerXrOptions as S, type MouseControllerPosition as T, type ObjectTransformSpace as U, type PerformanceProfile as V, type RendererBackend as W, type SceneComposition as X, type SemanticComparisonOptions as Y, type ShareableViewerState as Z, type StreamingDiagnostics as _, type ARHandoffOptions as a, type UseViewerCameraOptions as a0, type ViewerCameraPreset as a1, type ViewerCameraProps as a2, type ViewerConfiguration as a3, type ViewerEngagementEvent as a4, type ViewerObjectInfo as a5, type ViewerProductOptions as a6, type ViewerReadyState as a7, type ViewerRuntimeStats as a8, type ViewerStateStorage as a9, type XRScaleMode as aa, compareViewerConfigurations as ab, groundAsset as ac, parseAssetTransform as ad, parseViewerState as ae, prepareViewerState as af, serializeViewerState as ag, snapAssetToGrid as ah, useViewerCamera as ai, type ARHandoffRequest as b, type ARHandoffStatus as c, type ARSnapshot as d, type ARSnapshotSource as e, type AnnotationMarker as f, type AssetDiagnosticIssue as g, type AssetDiagnosticsReport as h, type AssetDiagnosticsSource as i, type AssetTextureDiagnostic as j, type AssetTransform as k, type CaptureImageOptions as l, type CaptureVideoOptions as m, type CinematicConfig as n, type CinematicWaypoint as o, type ComparisonCategory as p, type ComparisonChange as q, type ComparisonHighlight as r, type ComparisonObject as s, type ComparisonStatus as t, type ConfigurationComparisonInput as u, type ConfigurationComparisonReport as v, type CustomObjectBindingDataPanelProps as w, type CustomSceneObjectsPanelProps as x, type LicenseStatus as y, MODEL_VIEWER_PRESETS as z };