@preference-sl/pref-viewer 2.18.0 → 3.0.0-beta.0
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 +267 -31
- package/index.d.ts +75 -6
- package/package.json +8 -2
- package/src/babylonjs-animation-controller.js +18 -10
- package/src/babylonjs-animation-opening-menu.js +80 -14
- package/src/babylonjs-animation-opening.js +3 -3
- package/src/babylonjs-ar-floor-bounds.js +169 -0
- package/src/babylonjs-ar-glass.js +128 -0
- package/src/babylonjs-ar-placement-feedback.js +449 -0
- package/src/babylonjs-ar-placement.js +1038 -0
- package/src/babylonjs-camera-wheel-motion.js +35 -2
- package/src/babylonjs-controller.js +507 -125
- package/src/babylonjs-orbital-pointers-input.js +186 -0
- package/src/{render-math.js → babylonjs-render-math.js} +11 -11
- package/src/babylonjs-selection-controller.js +4 -4
- package/src/babylonjs-view-cube-canvas-controller.js +1287 -0
- package/src/babylonjs-view-cube-canvas-orbit-math.js +220 -0
- package/src/babylonjs-view-cube-canvas-renderer.js +775 -0
- package/src/babylonjs-view-cube-controller.js +74 -1103
- package/src/babylonjs-view-cube-svg-controller.js +1012 -0
- package/src/file-storage.js +7 -4
- package/src/gltf-resolver.js +13 -8
- package/src/localization/translations.js +12 -0
- package/src/panzoom-controller.js +4 -4
- package/src/pref-viewer-2d.js +2 -2
- package/src/pref-viewer-3d.js +55 -9
- package/src/pref-viewer-controls-presentation.js +292 -0
- package/src/pref-viewer-dialog.js +86 -7
- package/src/pref-viewer-menu-3d.js +134 -17
- package/src/pref-viewer-style-controller.js +320 -0
- package/src/pref-viewer.js +133 -109
- package/src/quick-look-action.js +280 -0
- package/src/styles.js +702 -98
- package/src/babylonjs-view-cube-renderer.js +0 -548
- package/src/view-cube-orbit-math.js +0 -199
package/src/file-storage.js
CHANGED
|
@@ -9,6 +9,7 @@ import { openDB } from "idb";
|
|
|
9
9
|
* - Falls back to direct server access when IndexedDB is unavailable.
|
|
10
10
|
* - Supports file blob retrieval, timestamp checking, and size queries.
|
|
11
11
|
* - Uses the idb library for simplified IndexedDB operations.
|
|
12
|
+
* - Observes cache-write request and transaction completion together so simultaneous failures are handled.
|
|
12
13
|
*
|
|
13
14
|
* Dependencies:
|
|
14
15
|
* - idb (IndexedDB wrapper library)
|
|
@@ -423,6 +424,7 @@ export default class FileStorage {
|
|
|
423
424
|
|
|
424
425
|
/**
|
|
425
426
|
* Updates `lastAccess` for a record to keep LRU ordering current.
|
|
427
|
+
* Observes the write and transaction together; failed touches are caught without leaking an abort rejection.
|
|
426
428
|
* @private
|
|
427
429
|
* @param {String} uri Record key.
|
|
428
430
|
* @param {Object} record Existing normalized record.
|
|
@@ -443,8 +445,7 @@ export default class FileStorage {
|
|
|
443
445
|
try {
|
|
444
446
|
const transaction = this.#db.transaction(this.osName, "readwrite");
|
|
445
447
|
const store = transaction.objectStore(this.osName);
|
|
446
|
-
store.put(normalized, uri);
|
|
447
|
-
await transaction.done;
|
|
448
|
+
await Promise.all([store.put(normalized, uri), transaction.done]);
|
|
448
449
|
} catch (error) {}
|
|
449
450
|
}
|
|
450
451
|
|
|
@@ -596,6 +597,7 @@ export default class FileStorage {
|
|
|
596
597
|
* @description
|
|
597
598
|
* Runs maintenance before write (TTL, max entries, and quota-aware cleanup), then retries quota errors
|
|
598
599
|
* by evicting least-recently-used entries.
|
|
600
|
+
* Observes each write request and transaction completion together so simultaneous WebKit failures are handled.
|
|
599
601
|
*/
|
|
600
602
|
async #putFile(file, uri) {
|
|
601
603
|
if (this.#db === undefined) {
|
|
@@ -619,8 +621,9 @@ export default class FileStorage {
|
|
|
619
621
|
try {
|
|
620
622
|
const transaction = this.#db.transaction(this.osName, "readwrite");
|
|
621
623
|
const store = transaction.objectStore(this.osName);
|
|
622
|
-
|
|
623
|
-
|
|
624
|
+
// Observe both promises immediately: WebKit can reject the write and abort
|
|
625
|
+
// its transaction together. Awaiting them sequentially leaks a rejection.
|
|
626
|
+
const [result] = await Promise.all([store.put(record, uri), transaction.done]);
|
|
624
627
|
return result;
|
|
625
628
|
} catch (error) {
|
|
626
629
|
if (!this.#isQuotaExceededError(error) || attempt === this.#maxQuotaEvictionRetries) {
|
package/src/gltf-resolver.js
CHANGED
|
@@ -9,6 +9,7 @@ import { closeDb, initDb, loadModel } from "./gltf-storage.js";
|
|
|
9
9
|
* - Decodes base64 data and determines file type (.gltf or .glb).
|
|
10
10
|
* - Normalizes and replaces asset URIs with resolved URLs from FileStorage.
|
|
11
11
|
* - Handles cache validation using asset size and timestamp to avoid unnecessary reloads.
|
|
12
|
+
* Callers may opt into an explicit unchanged marker to distinguish cache hits from unavailable content.
|
|
12
13
|
* - Tracks generated object URLs so callers can revoke them after Babylon finishes loading.
|
|
13
14
|
* - Provides methods for initializing storage, decoding assets, and preparing sources for viewer components.
|
|
14
15
|
*
|
|
@@ -17,7 +18,7 @@ import { closeDb, initDb, loadModel } from "./gltf-storage.js";
|
|
|
17
18
|
* - Prepare asset: await resolver.getSource(storage, currentSize, currentTimeStamp);
|
|
18
19
|
*
|
|
19
20
|
* Public Methods:
|
|
20
|
-
* - getSource(storage, currentSize, currentTimeStamp):
|
|
21
|
+
* - getSource(storage, currentSize, currentTimeStamp, reportUnchanged?): Prepares a source or reports a cache hit.
|
|
21
22
|
* - revokeObjectURLs(objectURLs): Releases temporary blob URLs generated during source resolution.
|
|
22
23
|
* - dispose(): Releases resolver resources and closes the internal FileStorage DB handle.
|
|
23
24
|
*
|
|
@@ -220,7 +221,7 @@ export default class GLTFResolver {
|
|
|
220
221
|
/**
|
|
221
222
|
* Revoke browser object URLs and clear the provided list.
|
|
222
223
|
* @public
|
|
223
|
-
* @param {string[]} objectURLs - URLs previously created via URL.createObjectURL.
|
|
224
|
+
* @param {string[]} [objectURLs=[]] - URLs previously created via URL.createObjectURL.
|
|
224
225
|
* @returns {void}
|
|
225
226
|
*/
|
|
226
227
|
revokeObjectURLs(objectURLs = []) {
|
|
@@ -251,17 +252,21 @@ export default class GLTFResolver {
|
|
|
251
252
|
* @param {object} storage - Storage descriptor containing url, db, table, and id properties.
|
|
252
253
|
* @param {number|null} currentSize - The current cached size of the asset, or null if not cached.
|
|
253
254
|
* @param {string|null} currentTimeStamp - The current cached timestamp of the asset, or null if not cached.
|
|
254
|
-
* @
|
|
255
|
-
*
|
|
255
|
+
* @param {boolean} [reportUnchanged=false] - Return an explicit unchanged marker for cache hits.
|
|
256
|
+
* @returns {Promise<false|{unchanged:true}|{source: File|string, size: number, timeStamp: string|null, extension: string, metadata: object, objectURLs: string[]}>}
|
|
257
|
+
* - Resolves to false for missing data or an unchanged asset when reportUnchanged is false.
|
|
258
|
+
* - Resolves to {unchanged: true} for a cache hit when reportUnchanged is true.
|
|
256
259
|
* - Resolves to an object containing source, cache metadata, and tracked object URLs if an update is required.
|
|
260
|
+
* @throws {Error} Rejects when storage access, source retrieval or glTF JSON decoding fails.
|
|
257
261
|
* @description
|
|
258
262
|
* - If storage specifies IndexedDB (db, table, id), loads the asset from IndexedDB and checks for updates.
|
|
259
263
|
* - If storage specifies a direct URL or base64 data, decodes and validates the asset.
|
|
260
264
|
* - For .gltf files, replaces internal URIs with resolved URLs from FileStorage.
|
|
261
265
|
* - Performs cache validation using size and timestamp to avoid unnecessary reloads.
|
|
262
266
|
* - Returns the prepared source, size, timestamp, extension, metadata, and objectURLs for further processing.
|
|
267
|
+
* - The caller owns revoking returned objectURLs after the loader finishes consuming them.
|
|
263
268
|
*/
|
|
264
|
-
async getSource(storage, currentSize, currentTimeStamp) {
|
|
269
|
+
async getSource(storage, currentSize, currentTimeStamp, reportUnchanged = false) {
|
|
265
270
|
let source = storage.url || null;
|
|
266
271
|
let newSize, newTimeStamp;
|
|
267
272
|
let pending = false;
|
|
@@ -277,7 +282,7 @@ export default class GLTFResolver {
|
|
|
277
282
|
source = object.data;
|
|
278
283
|
metadata = { ...(object.metadata ?? {}) };
|
|
279
284
|
if (object.timeStamp === currentTimeStamp) {
|
|
280
|
-
return false;
|
|
285
|
+
return reportUnchanged ? { unchanged: true } : false;
|
|
281
286
|
} else {
|
|
282
287
|
pending = true;
|
|
283
288
|
newSize = object.size;
|
|
@@ -304,7 +309,7 @@ export default class GLTFResolver {
|
|
|
304
309
|
}
|
|
305
310
|
if (!pending) {
|
|
306
311
|
if (currentTimeStamp === null && currentSize === size) {
|
|
307
|
-
return false;
|
|
312
|
+
return reportUnchanged ? { unchanged: true } : false;
|
|
308
313
|
} else {
|
|
309
314
|
pending = true;
|
|
310
315
|
newSize = size;
|
|
@@ -316,7 +321,7 @@ export default class GLTFResolver {
|
|
|
316
321
|
extension = extMatch ? `.${extMatch[1].toLowerCase()}` : ".gltf";
|
|
317
322
|
let [fileSize, fileTimeStamp] = [await this.#fileStorage.getSize(source), await this.#fileStorage.getTimeStamp(source)];
|
|
318
323
|
if (currentSize === fileSize && currentTimeStamp === fileTimeStamp) {
|
|
319
|
-
return false;
|
|
324
|
+
return reportUnchanged ? { unchanged: true } : false;
|
|
320
325
|
} else {
|
|
321
326
|
pending = true;
|
|
322
327
|
newSize = fileSize;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
export const translations = {
|
|
2
2
|
"en-EN": {
|
|
3
3
|
prefViewer: {
|
|
4
|
+
ar: {
|
|
5
|
+
open: "View in AR",
|
|
6
|
+
preparing: "Preparing AR…",
|
|
7
|
+
retry: "Retry preparing AR",
|
|
8
|
+
},
|
|
4
9
|
viewCube: {
|
|
5
10
|
title: "View orientation",
|
|
6
11
|
front: "Inner",
|
|
@@ -14,6 +19,7 @@ export const translations = {
|
|
|
14
19
|
title: "3D render settings",
|
|
15
20
|
subtitle: "Modify the visual effects.",
|
|
16
21
|
actions: {
|
|
22
|
+
close: "Close",
|
|
17
23
|
play: "Play",
|
|
18
24
|
pause: "Pause",
|
|
19
25
|
},
|
|
@@ -71,6 +77,11 @@ export const translations = {
|
|
|
71
77
|
},
|
|
72
78
|
"es-ES": {
|
|
73
79
|
prefViewer: {
|
|
80
|
+
ar: {
|
|
81
|
+
open: "Ver en RA",
|
|
82
|
+
preparing: "Preparando RA…",
|
|
83
|
+
retry: "Reintentar preparar RA",
|
|
84
|
+
},
|
|
74
85
|
viewCube: {
|
|
75
86
|
title: "Orientación de vista",
|
|
76
87
|
front: "Interior",
|
|
@@ -84,6 +95,7 @@ export const translations = {
|
|
|
84
95
|
title: "Ajustes de render 3D",
|
|
85
96
|
subtitle: "Modifica los efectos visuales.",
|
|
86
97
|
actions: {
|
|
98
|
+
close: "Cerrar",
|
|
87
99
|
play: "Reproducir",
|
|
88
100
|
pause: "Pausar",
|
|
89
101
|
},
|
|
@@ -108,10 +108,10 @@ export default class PanzoomController {
|
|
|
108
108
|
/**
|
|
109
109
|
* Stores the SVG wrapper, Panzoom options and callbacks, and binds reusable input handlers.
|
|
110
110
|
* @public
|
|
111
|
-
* @param {HTMLElement|SVGElement} wrapper - Element transformed by Panzoom.
|
|
112
|
-
* @param {object} [options] - Panzoom configuration.
|
|
113
|
-
* @param {function(object): void} [changedCallback] - Receives the current viewport state.
|
|
114
|
-
* @param {function(Event): void} [clickCallback] - Receives the original event for a recognized click.
|
|
111
|
+
* @param {HTMLElement|SVGElement|null} [wrapper=null] - Element transformed by Panzoom.
|
|
112
|
+
* @param {object} [options={}] - Panzoom configuration.
|
|
113
|
+
* @param {?(function(object): void)} [changedCallback=null] - Receives the current viewport state.
|
|
114
|
+
* @param {?(function(Event): void)} [clickCallback=null] - Receives the original event for a recognized click.
|
|
115
115
|
*/
|
|
116
116
|
constructor(wrapper = null, options = {}, changedCallback = null, clickCallback = null) {
|
|
117
117
|
this.#wrapper = wrapper;
|
package/src/pref-viewer-2d.js
CHANGED
|
@@ -492,7 +492,7 @@ export default class PrefViewer2D extends HTMLElement {
|
|
|
492
492
|
* @param {Element} node - Clone to append.
|
|
493
493
|
* @param {string} semanticId - Business id represented by the clone.
|
|
494
494
|
* @param {"selectable"|"selected"|"definition"} layer - Layer type.
|
|
495
|
-
* @param {Element|null} parent - Optional parent; defaults to drawing root.
|
|
495
|
+
* @param {Element|null} [parent=null] - Optional parent; defaults to drawing root.
|
|
496
496
|
* @returns {Element|null}
|
|
497
497
|
*/
|
|
498
498
|
#appendSelectionNode(node, semanticId, layer, parent = null) {
|
|
@@ -697,7 +697,7 @@ export default class PrefViewer2D extends HTMLElement {
|
|
|
697
697
|
/**
|
|
698
698
|
* Apply a complete semantic selection snapshot to the current drawing.
|
|
699
699
|
* @public
|
|
700
|
-
* @param {{selectableIds?: string[], selectedItems?: Array<{id: string, highlights?: string[]}>}} state - Selection snapshot.
|
|
700
|
+
* @param {{selectableIds?: string[], selectedItems?: Array<{id: string, highlights?: string[]}>}} [state={}] - Selection snapshot.
|
|
701
701
|
* @returns {void}
|
|
702
702
|
*/
|
|
703
703
|
applySelectionState(state = {}) {
|
package/src/pref-viewer-3d.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CameraData, ContainerData, MaterialData, IBLData } from "./pref-viewer-3d-data.js";
|
|
2
2
|
import BabylonJSController from "./babylonjs-controller.js";
|
|
3
3
|
import { PrefViewer3DStyles } from "./styles.js";
|
|
4
|
+
import PrefViewerControlsPresentation from "./pref-viewer-controls-presentation.js";
|
|
4
5
|
import FileStorage from "./file-storage.js";
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -25,6 +26,7 @@ import FileStorage from "./file-storage.js";
|
|
|
25
26
|
* - show-model: Show or hide the 3D model ("true"/"false").
|
|
26
27
|
* - show-scene: Show or hide the 3D environment ("true"/"false").
|
|
27
28
|
* - visible: Show or hide the entire viewer ("true"/"false").
|
|
29
|
+
* - view-cube-renderer: Selects independent Babylon Canvas (default) or SVG via reflected viewCubeRenderer.
|
|
28
30
|
* - show-view-cube: Enable the orientation overlay while visible; only "false" disables it (default: enabled).
|
|
29
31
|
*
|
|
30
32
|
* Public Methods:
|
|
@@ -80,11 +82,14 @@ import FileStorage from "./file-storage.js";
|
|
|
80
82
|
* - "pref-viewer-3d-element-click": Internal event carrying distance-ordered semantic model mesh ids.
|
|
81
83
|
*
|
|
82
84
|
* Notes:
|
|
85
|
+
* - Owns responsive controls only when standalone; nested 3D inherits its root viewer presentation.
|
|
83
86
|
* - Internal state and heavy initialization are handled in connectedCallback.
|
|
84
87
|
* - Designed for extensibility and integration in product configurators, PrefViewer host elements, and visualization tools.
|
|
85
88
|
* - All resource management and rendering operations are performed asynchronously for performance.
|
|
86
89
|
*/
|
|
87
90
|
export default class PrefViewer3D extends HTMLElement {
|
|
91
|
+
#controlsPresentation = null;
|
|
92
|
+
#componentStyle = null;
|
|
88
93
|
// State flags
|
|
89
94
|
#isInitialized = false;
|
|
90
95
|
#isLoaded = false;
|
|
@@ -98,6 +103,20 @@ export default class PrefViewer3D extends HTMLElement {
|
|
|
98
103
|
|
|
99
104
|
#babylonJSController = null; // BabylonJSController instance
|
|
100
105
|
|
|
106
|
+
/** @returns {"svg"|"canvas"} Per-instance normalized renderer; missing/invalid attributes use Canvas. */
|
|
107
|
+
get viewCubeRenderer() {
|
|
108
|
+
return this.getAttribute("view-cube-renderer") === "svg" ? "svg" : "canvas";
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Reflects the renderer preference immediately without reloading assets or changing visibility.
|
|
113
|
+
* @param {"svg"|"canvas"} value - SVG selects the vector widget; all other values select the dedicated Canvas 3D scene.
|
|
114
|
+
* @returns {void}
|
|
115
|
+
*/
|
|
116
|
+
set viewCubeRenderer(value) {
|
|
117
|
+
this.setAttribute("view-cube-renderer", value === "svg" ? "svg" : "canvas");
|
|
118
|
+
}
|
|
119
|
+
|
|
101
120
|
/**
|
|
102
121
|
* Create a new instance of the 3D viewer component.
|
|
103
122
|
* The constructor only calls super(); heavy initialization happens in connectedCallback.
|
|
@@ -107,11 +126,11 @@ export default class PrefViewer3D extends HTMLElement {
|
|
|
107
126
|
}
|
|
108
127
|
|
|
109
128
|
/**
|
|
110
|
-
* Attributes observed by the custom element.
|
|
129
|
+
* Attributes observed by the custom element, including renderer selection and standalone controls-density.
|
|
111
130
|
* @returns {string[]} Array of attribute names that trigger attributeChangedCallback.
|
|
112
131
|
*/
|
|
113
132
|
static get observedAttributes() {
|
|
114
|
-
return ["show-model", "show-scene", "visible", "show-view-cube"];
|
|
133
|
+
return ["show-model", "show-scene", "visible", "show-view-cube", "view-cube-renderer", "controls-density"];
|
|
115
134
|
}
|
|
116
135
|
|
|
117
136
|
/**
|
|
@@ -124,10 +143,18 @@ export default class PrefViewer3D extends HTMLElement {
|
|
|
124
143
|
* - "show-model": shows or hides the model according to the attribute value ("true"/"false").
|
|
125
144
|
* - "show-scene": shows or hides the scene according to the attribute value ("true"/"false").
|
|
126
145
|
* - "visible": shows or hides the component according to the attribute value ("true"/"false").
|
|
146
|
+
* - "view-cube-renderer": replaces only the cube overlay, preserving camera and assets.
|
|
147
|
+
* - "controls-density": refreshes standalone presentation without reloading the scene.
|
|
127
148
|
* - "show-view-cube": activates the cube only while visible and the attribute is not "false".
|
|
128
149
|
*/
|
|
129
150
|
attributeChangedCallback(name, _old, value) {
|
|
130
151
|
switch (name) {
|
|
152
|
+
case "view-cube-renderer":
|
|
153
|
+
this.#babylonJSController?.setViewCubeRenderer(this.viewCubeRenderer);
|
|
154
|
+
break;
|
|
155
|
+
case "controls-density":
|
|
156
|
+
this.#controlsPresentation?.refresh();
|
|
157
|
+
break;
|
|
131
158
|
case "show-view-cube":
|
|
132
159
|
this.#babylonJSController?.setViewCubeEnabled(this.#isVisible && value !== "false");
|
|
133
160
|
break;
|
|
@@ -161,12 +188,16 @@ export default class PrefViewer3D extends HTMLElement {
|
|
|
161
188
|
/**
|
|
162
189
|
* Called when the element is added to the DOM.
|
|
163
190
|
* Creates the DOM structure, sets initial visibility, initializes component data, and sets up the BabylonJSController.
|
|
164
|
-
*
|
|
191
|
+
* Creates a presentation owner only when standalone, then performs heavy 3D initialization.
|
|
165
192
|
* @public
|
|
166
193
|
* @returns {void}
|
|
167
194
|
*/
|
|
168
195
|
connectedCallback() {
|
|
169
196
|
this.#createDOMElements();
|
|
197
|
+
if (!this.getRootNode().host?.matches?.("pref-viewer")) {
|
|
198
|
+
this.#controlsPresentation = new PrefViewerControlsPresentation(this,
|
|
199
|
+
() => this.getAttribute("controls-density"), () => this.refreshViewCube());
|
|
200
|
+
}
|
|
170
201
|
this.#setInitialVisibility();
|
|
171
202
|
this.#initializeData();
|
|
172
203
|
this.#initializeBabylonJS();
|
|
@@ -175,29 +206,33 @@ export default class PrefViewer3D extends HTMLElement {
|
|
|
175
206
|
|
|
176
207
|
/**
|
|
177
208
|
* Called when the element is removed from the DOM.
|
|
178
|
-
*
|
|
209
|
+
* Releases standalone presentation observers and disables Babylon resources/listeners.
|
|
179
210
|
* @public
|
|
180
211
|
* @returns {void}
|
|
181
212
|
*/
|
|
182
213
|
disconnectedCallback() {
|
|
214
|
+
this.#controlsPresentation?.dispose();
|
|
215
|
+
this.#controlsPresentation = null;
|
|
183
216
|
if (this.#babylonJSController) {
|
|
184
217
|
void this.#babylonJSController.disable();
|
|
185
218
|
}
|
|
186
219
|
}
|
|
187
220
|
|
|
188
221
|
/**
|
|
189
|
-
*
|
|
222
|
+
* Replaces the owned canvas wrapper/styles on reconnect, retaining any consumer-added child content.
|
|
190
223
|
* @private
|
|
191
224
|
* @returns {void}
|
|
192
225
|
*/
|
|
193
226
|
#createDOMElements() {
|
|
227
|
+
this.#wrapper?.remove();
|
|
228
|
+
this.#componentStyle?.remove();
|
|
194
229
|
this.#wrapper = document.createElement("div");
|
|
195
230
|
this.append(this.#wrapper);
|
|
196
231
|
|
|
197
232
|
this.#canvas = document.createElement("canvas");
|
|
198
233
|
this.#wrapper.appendChild(this.#canvas);
|
|
199
234
|
|
|
200
|
-
const style = document.createElement("style");
|
|
235
|
+
const style = this.#componentStyle = document.createElement("style");
|
|
201
236
|
style.textContent = PrefViewer3DStyles;
|
|
202
237
|
this.append(style);
|
|
203
238
|
}
|
|
@@ -245,7 +280,7 @@ export default class PrefViewer3D extends HTMLElement {
|
|
|
245
280
|
}
|
|
246
281
|
|
|
247
282
|
/**
|
|
248
|
-
* Initializes the Babylon controller with asset/option state and the visibility-aware cube contract.
|
|
283
|
+
* Initializes the Babylon controller with asset/option state and the selected visibility-aware cube contract.
|
|
249
284
|
* Supplies current host culture and dispatches measured view-cube-layout events for render-menu positioning.
|
|
250
285
|
* Starts asynchronous engine initialization without waiting for asset loading.
|
|
251
286
|
* @private
|
|
@@ -253,8 +288,19 @@ export default class PrefViewer3D extends HTMLElement {
|
|
|
253
288
|
*/
|
|
254
289
|
#initializeBabylonJS() {
|
|
255
290
|
this.#babylonJSController = new BabylonJSController(this.#canvas, this.#data.containers, this.#data.options, {
|
|
291
|
+
renderer: this.viewCubeRenderer,
|
|
256
292
|
enabled: this.#isVisible && this.getAttribute("show-view-cube") !== "false",
|
|
293
|
+
/**
|
|
294
|
+
* Resolves the containing viewer culture for localized ViewCube labels.
|
|
295
|
+
* @returns {string|undefined} Host culture, or undefined for standalone default handling.
|
|
296
|
+
*/
|
|
257
297
|
getCulture: () => this.getRootNode().host?.culture,
|
|
298
|
+
/**
|
|
299
|
+
* Publishes current ViewCube layout measurements for the containing viewer controls.
|
|
300
|
+
* @param {number} offset - Active cube height in CSS pixels; zero clears the offset.
|
|
301
|
+
* @param {number} height - Scene viewport height in CSS pixels.
|
|
302
|
+
* @returns {void}
|
|
303
|
+
*/
|
|
258
304
|
onLayout: (offset, height) => this.dispatchEvent(new CustomEvent("view-cube-layout", { detail: { offset, height } })),
|
|
259
305
|
});
|
|
260
306
|
this.#babylonJSController.enable();
|
|
@@ -798,7 +844,7 @@ export default class PrefViewer3D extends HTMLElement {
|
|
|
798
844
|
/**
|
|
799
845
|
* Applies the host-owned semantic selection snapshot to the 3D model.
|
|
800
846
|
* @public
|
|
801
|
-
* @param {object} state - Canonical PrefViewer selection state.
|
|
847
|
+
* @param {object} [state={}] - Canonical PrefViewer selection state.
|
|
802
848
|
* @returns {void}
|
|
803
849
|
*/
|
|
804
850
|
applySelectionState(state = {}) {
|
|
@@ -927,7 +973,7 @@ export default class PrefViewer3D extends HTMLElement {
|
|
|
927
973
|
}
|
|
928
974
|
|
|
929
975
|
/**
|
|
930
|
-
* Forwards an internal culture/camera refresh to the existing overlay without activating a disabled cube.
|
|
976
|
+
* Forwards an internal culture/camera/presentation resize refresh to the existing overlay without activating a disabled cube.
|
|
931
977
|
* @public
|
|
932
978
|
* @returns {void}
|
|
933
979
|
*/
|