@preference-sl/pref-viewer 2.10.0-beta.12 → 2.10.0-beta.13
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/package.json +1 -1
- package/src/index.js +130 -197
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* =============================================================================
|
|
3
|
-
* PrefViewer Web Component (JavaScript)
|
|
3
|
+
* PrefViewer Web Component (JavaScript)
|
|
4
4
|
* =============================================================================
|
|
5
5
|
*
|
|
6
6
|
* Overview
|
|
@@ -49,76 +49,13 @@ import { initDb, loadModel } from "./gltf-storage.js";
|
|
|
49
49
|
class PrefViewer extends HTMLElement {
|
|
50
50
|
#initialized = false;
|
|
51
51
|
|
|
52
|
-
// ---
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
debug: () => {},
|
|
58
|
-
info: () => {},
|
|
59
|
-
warn: () => {},
|
|
60
|
-
error: () => {},
|
|
61
|
-
time: () => {},
|
|
62
|
-
timeEnd: () => {},
|
|
63
|
-
group: () => {},
|
|
64
|
-
groupEnd: () => {},
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
#enableDebug(enable) {
|
|
68
|
-
const on = !!enable;
|
|
69
|
-
this.#debugEnabled = on;
|
|
70
|
-
if (!on) {
|
|
71
|
-
this.#log = {
|
|
72
|
-
debug: () => {},
|
|
73
|
-
info: () => {},
|
|
74
|
-
warn: () => {},
|
|
75
|
-
error: () => {},
|
|
76
|
-
time: () => {},
|
|
77
|
-
timeEnd: () => {},
|
|
78
|
-
group: () => {},
|
|
79
|
-
groupEnd: () => {},
|
|
80
|
-
};
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
const tag = (lvl, args) => {
|
|
84
|
-
if (!args || !args.length) return [`${this.#logPrefix}:`];
|
|
85
|
-
const [first, ...rest] = args;
|
|
86
|
-
if (typeof first === "string") return [`${this.#logPrefix} [${lvl}] ${first}`, ...rest];
|
|
87
|
-
return [`${this.#logPrefix} [${lvl}]`, first, ...rest];
|
|
88
|
-
};
|
|
89
|
-
this.#log = {
|
|
90
|
-
debug: (...a) => console.debug(...tag("debug", a)),
|
|
91
|
-
info: (...a) => console.info(...tag("info", a)),
|
|
92
|
-
warn: (...a) => console.warn(...tag("warn", a)),
|
|
93
|
-
error: (...a) => console.error(...tag("error", a)),
|
|
94
|
-
time: (label) => {
|
|
95
|
-
const key = `${label}`;
|
|
96
|
-
this.#timers.set(key, performance.now());
|
|
97
|
-
console.debug(`${this.#logPrefix} [time] ${key} start`);
|
|
98
|
-
},
|
|
99
|
-
timeEnd: (label) => {
|
|
100
|
-
const key = `${label}`;
|
|
101
|
-
if (this.#timers.has(key)) {
|
|
102
|
-
const delta = (performance.now() - this.#timers.get(key)).toFixed(2);
|
|
103
|
-
console.debug(`${this.#logPrefix} [time] ${key} ${delta}ms`);
|
|
104
|
-
this.#timers.delete(key);
|
|
105
|
-
} else {
|
|
106
|
-
console.debug(`${this.#logPrefix} [time] ${key} (no start)`);
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
group: (title) => console.group?.(`${this.#logPrefix} ${title}`),
|
|
110
|
-
groupEnd: () => console.groupEnd?.(),
|
|
111
|
-
};
|
|
52
|
+
// --- logging helper (no functional change) ---
|
|
53
|
+
#logNS = "PrefViewer";
|
|
54
|
+
#log(method, ...args) {
|
|
55
|
+
const fn = console[method] || console.log;
|
|
56
|
+
fn(`[${this.#logNS}]`, ...args);
|
|
112
57
|
}
|
|
113
58
|
|
|
114
|
-
#readDebugAttribute() {
|
|
115
|
-
const v = (this.getAttribute("debug") || "").trim().toLowerCase();
|
|
116
|
-
// true/1/yes/on
|
|
117
|
-
const enabled = v === "true" || v === "1" || v === "yes" || v === "on" || v === "debug";
|
|
118
|
-
this.#enableDebug(enabled);
|
|
119
|
-
}
|
|
120
|
-
// ------------------------------------------------------------------------
|
|
121
|
-
|
|
122
59
|
#data = {
|
|
123
60
|
containers: {
|
|
124
61
|
model: {
|
|
@@ -200,8 +137,6 @@ class PrefViewer extends HTMLElement {
|
|
|
200
137
|
constructor() {
|
|
201
138
|
super();
|
|
202
139
|
this.attachShadow({ mode: "open" });
|
|
203
|
-
this.#readDebugAttribute();
|
|
204
|
-
this.#log.info("constructor()");
|
|
205
140
|
this.#createCanvas();
|
|
206
141
|
this.#wrapCanvas();
|
|
207
142
|
// Point to whichever version you packaged or want to use:
|
|
@@ -214,24 +149,16 @@ class PrefViewer extends HTMLElement {
|
|
|
214
149
|
// JS fallback if WASM isn’t available
|
|
215
150
|
fallbackUrl: `${DRACO_BASE}/draco_decoder_gltf.js`,
|
|
216
151
|
};
|
|
217
|
-
this.#log
|
|
152
|
+
this.#log("info", "constructed");
|
|
218
153
|
}
|
|
219
154
|
|
|
220
155
|
static get observedAttributes() {
|
|
221
|
-
|
|
222
|
-
return ["config", "model", "scene", "show-model", "show-scene", "debug"];
|
|
156
|
+
return ["config", "model", "scene", "show-model", "show-scene"];
|
|
223
157
|
}
|
|
224
158
|
|
|
225
159
|
attributeChangedCallback(name, _old, value) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
this.#enableDebug((value || "").toLowerCase() === "true" || value === "1" || value === "yes" || value === "on" || value === "debug");
|
|
229
|
-
this.#log.info(`attributeChanged: debug -> ${this.#debugEnabled}`);
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
this.#log.debug("attributeChangedCallback()", { name, oldValue: _old, value });
|
|
234
|
-
|
|
160
|
+
this.#log("groupCollapsed", `attributeChanged: ${name}`);
|
|
161
|
+
this.#log("info", "new value:", value);
|
|
235
162
|
let data = null;
|
|
236
163
|
switch (name) {
|
|
237
164
|
case "config":
|
|
@@ -246,7 +173,6 @@ class PrefViewer extends HTMLElement {
|
|
|
246
173
|
case "show-model":
|
|
247
174
|
data = value.toLowerCase?.() === "true";
|
|
248
175
|
if (this.#initialized) {
|
|
249
|
-
this.#log.info(`attr show-model -> ${data}`);
|
|
250
176
|
data ? this.showModel() : this.hideModel();
|
|
251
177
|
} else {
|
|
252
178
|
this.#data.containers.model.show = data;
|
|
@@ -255,17 +181,16 @@ class PrefViewer extends HTMLElement {
|
|
|
255
181
|
case "show-scene":
|
|
256
182
|
data = value.toLowerCase?.() === "true";
|
|
257
183
|
if (this.#initialized) {
|
|
258
|
-
this.#log.info(`attr show-scene -> ${data}`);
|
|
259
184
|
data ? this.showScene() : this.hideScene();
|
|
260
185
|
} else {
|
|
261
186
|
this.#data.containers.environment.show = data;
|
|
262
187
|
}
|
|
263
188
|
break;
|
|
264
189
|
}
|
|
190
|
+
console.groupEnd();
|
|
265
191
|
}
|
|
266
192
|
|
|
267
193
|
connectedCallback() {
|
|
268
|
-
this.#log.info("connectedCallback()");
|
|
269
194
|
if (!this.hasAttribute("config")) {
|
|
270
195
|
const error = 'PrefViewer: provide "models" as array of model and environment';
|
|
271
196
|
console.error(error);
|
|
@@ -279,21 +204,20 @@ class PrefViewer extends HTMLElement {
|
|
|
279
204
|
return false;
|
|
280
205
|
}
|
|
281
206
|
|
|
207
|
+
this.#log("info", "connectedCallback: initializing Babylon and starting initial load");
|
|
282
208
|
this.#initializeBabylon();
|
|
283
209
|
this.#loadContainers(true, true, true);
|
|
284
210
|
this.#initialized = true;
|
|
285
|
-
this.#log.info("initialized = true");
|
|
286
211
|
}
|
|
287
212
|
|
|
288
213
|
disconnectedCallback() {
|
|
289
|
-
this.#log
|
|
214
|
+
this.#log("info", "disconnectedCallback: disposing engine and observers");
|
|
290
215
|
this.#disposeEngine();
|
|
291
216
|
this.#canvasResizeObserver.disconnect();
|
|
292
217
|
}
|
|
293
218
|
|
|
294
219
|
// Web Component
|
|
295
220
|
#createCanvas() {
|
|
296
|
-
this.#log.debug("#createCanvas()");
|
|
297
221
|
this.#canvas = document.createElement("canvas");
|
|
298
222
|
Object.assign(this.#canvas.style, {
|
|
299
223
|
width: "100%",
|
|
@@ -304,7 +228,6 @@ class PrefViewer extends HTMLElement {
|
|
|
304
228
|
}
|
|
305
229
|
|
|
306
230
|
#wrapCanvas() {
|
|
307
|
-
this.#log.debug("#wrapCanvas()");
|
|
308
231
|
this.#wrapper = document.createElement("div");
|
|
309
232
|
Object.assign(this.#wrapper.style, {
|
|
310
233
|
width: "100%",
|
|
@@ -318,48 +241,51 @@ class PrefViewer extends HTMLElement {
|
|
|
318
241
|
// Data
|
|
319
242
|
#checkCameraChanged(options) {
|
|
320
243
|
if (!options || !options.camera) {
|
|
244
|
+
this.#log("debug", "checkCameraChanged: no camera in options");
|
|
321
245
|
return false;
|
|
322
246
|
}
|
|
323
247
|
const prev = this.#data.options.camera.value;
|
|
248
|
+
const next = options.camera;
|
|
324
249
|
this.#data.options.camera.changed = options.camera && options.camera !== prev ? true : false;
|
|
325
|
-
this.#data.options.camera.value = this.#data.options.camera.changed ?
|
|
326
|
-
this.#log
|
|
250
|
+
this.#data.options.camera.value = this.#data.options.camera.changed ? next : prev;
|
|
251
|
+
this.#log("info", "checkCameraChanged:", { prev, next, changed: this.#data.options.camera.changed });
|
|
327
252
|
return this.#data.options.camera.changed;
|
|
328
253
|
}
|
|
329
254
|
|
|
330
255
|
#checkMaterialsChanged(options) {
|
|
331
256
|
if (!options) {
|
|
257
|
+
this.#log("debug", "checkMaterialsChanged: no options object");
|
|
332
258
|
return false;
|
|
333
259
|
}
|
|
334
260
|
let someChanged = false;
|
|
335
261
|
Object.keys(this.#data.options.materials).forEach((material) => {
|
|
336
262
|
const key = `${material}Material`;
|
|
337
263
|
const prev = this.#data.options.materials[material].value;
|
|
338
|
-
|
|
339
|
-
this.#data.options.materials[material].
|
|
264
|
+
const next = options[key];
|
|
265
|
+
this.#data.options.materials[material].changed = next && next !== prev ? true : false;
|
|
266
|
+
this.#data.options.materials[material].value = this.#data.options.materials[material].changed ? next : prev;
|
|
340
267
|
someChanged = someChanged || this.#data.options.materials[material].changed;
|
|
268
|
+
this.#log("info", "checkMaterialsChanged item:", { material, key, prev, next, changed: this.#data.options.materials[material].changed });
|
|
341
269
|
});
|
|
342
|
-
this.#log
|
|
270
|
+
this.#log("info", "checkMaterialsChanged: someChanged =", someChanged);
|
|
343
271
|
return someChanged;
|
|
344
272
|
}
|
|
345
273
|
|
|
346
274
|
#storeChangedFlagsForContainer(container) {
|
|
347
|
-
this.#log.debug("#storeChangedFlagsForContainer()", { name: container.name, changed: container.changed });
|
|
348
275
|
container.timestamp = container.changed.timestamp;
|
|
349
276
|
container.size = container.changed.size;
|
|
277
|
+
this.#log("debug", "storeChangedFlagsForContainer:", { name: container.name, timestamp: container.timestamp, size: container.size });
|
|
350
278
|
}
|
|
351
279
|
|
|
352
280
|
#resetChangedFlags() {
|
|
353
|
-
this.#log.debug("#resetChangedFlags()");
|
|
354
281
|
Object.values(this.#data.containers).forEach((container) => (container.changed = false));
|
|
355
282
|
Object.values(this.#data.options.materials).forEach((material) => (material.changed = false));
|
|
356
283
|
this.#data.options.camera.changed = false;
|
|
284
|
+
this.#log("debug", "resetChangedFlags()");
|
|
357
285
|
}
|
|
358
286
|
|
|
359
287
|
// Babylon.js
|
|
360
288
|
async #initializeBabylon() {
|
|
361
|
-
this.#log.group("#initializeBabylon()");
|
|
362
|
-
this.#log.time("babylon:init");
|
|
363
289
|
this.#engine = new Engine(this.#canvas, true, { alpha: true });
|
|
364
290
|
this.#scene = new Scene(this.#engine);
|
|
365
291
|
this.#scene.clearColor = new Color4(1, 1, 1, 1);
|
|
@@ -370,13 +296,11 @@ class PrefViewer extends HTMLElement {
|
|
|
370
296
|
this.#engine.runRenderLoop(() => this.#scene && this.#scene.render());
|
|
371
297
|
this.#canvasResizeObserver.observe(this.#canvas);
|
|
372
298
|
|
|
299
|
+
this.#log("info", "Babylon initialized: creating XR experience (if supported)...");
|
|
373
300
|
await this.#createXRExperience();
|
|
374
|
-
this.#log.timeEnd("babylon:init");
|
|
375
|
-
this.#log.groupEnd();
|
|
376
301
|
}
|
|
377
302
|
|
|
378
303
|
addStylesToARButton() {
|
|
379
|
-
this.#log.debug("addStylesToARButton()");
|
|
380
304
|
const css = '.babylonVRicon { color: #868686; border-color: #868686; border-style: solid; margin-left: 10px; height: 50px; width: 80px; background-color: rgba(51,51,51,0.7); background-image: url(data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%222048%22%20height%3D%221152%22%20viewBox%3D%220%200%202048%201152%22%20version%3D%221.1%22%3E%3Cpath%20transform%3D%22rotate%28180%201024%2C576.0000000000001%29%22%20d%3D%22m1109%2C896q17%2C0%2030%2C-12t13%2C-30t-12.5%2C-30.5t-30.5%2C-12.5l-170%2C0q-18%2C0%20-30.5%2C12.5t-12.5%2C30.5t13%2C30t30%2C12l170%2C0zm-85%2C256q59%2C0%20132.5%2C-1.5t154.5%2C-5.5t164.5%2C-11.5t163%2C-20t150%2C-30t124.5%2C-41.5q23%2C-11%2042%2C-24t38%2C-30q27%2C-25%2041%2C-61.5t14%2C-72.5l0%2C-257q0%2C-123%20-47%2C-232t-128%2C-190t-190%2C-128t-232%2C-47l-81%2C0q-37%2C0%20-68.5%2C14t-60.5%2C34.5t-55.5%2C45t-53%2C45t-53%2C34.5t-55.5%2C14t-55.5%2C-14t-53%2C-34.5t-53%2C-45t-55.5%2C-45t-60.5%2C-34.5t-68.5%2C-14l-81%2C0q-123%2C0%20-232%2C47t-190%2C128t-128%2C190t-47%2C232l0%2C257q0%2C68%2038%2C115t97%2C73q54%2C24%20124.5%2C41.5t150%2C30t163%2C20t164.5%2C11.5t154.5%2C5.5t132.5%2C1.5zm939%2C-298q0%2C39%20-24.5%2C67t-58.5%2C42q-54%2C23%20-122%2C39.5t-143.5%2C28t-155.5%2C19t-157%2C11t-148.5%2C5t-129.5%2C1.5q-59%2C0%20-130%2C-1.5t-148%2C-5t-157%2C-11t-155.5%2C-19t-143.5%2C-28t-122%2C-39.5q-34%2C-14%20-58.5%2C-42t-24.5%2C-67l0%2C-257q0%2C-106%2040.5%2C-199t110%2C-162.5t162.5%2C-109.5t199%2C-40l81%2C0q27%2C0%2052%2C14t50%2C34.5t51%2C44.5t55.5%2C44.5t63.5%2C34.5t74%2C14t74%2C-14t63.5%2C-34.5t55.5%2C-44.5t51%2C-44.5t50%2C-34.5t52%2C-14l14%2C0q37%2C0%2070%2C0.5t64.5%2C4.5t63.5%2C12t68%2C23q71%2C30%20128.5%2C78.5t98.5%2C110t63.5%2C133.5t22.5%2C149l0%2C257z%22%20fill%3D%22white%22%20/%3E%3C/svg%3E%0A); background-size: 80%; background-repeat:no-repeat; background-position: center; border: none; outline: none; transition: transform 0.125s ease-out } .babylonVRicon:hover { transform: scale(1.05) } .babylonVRicon:active {background-color: rgba(51,51,51,1) } .babylonVRicon:focus {background-color: rgba(51,51,51,1) }.babylonVRicon.vrdisplaypresenting { background-image: none;} .vrdisplaypresenting::after { content: "EXIT"} .xr-error::after { content: "ERROR"}';
|
|
381
305
|
const style = document.createElement("style");
|
|
382
306
|
style.appendChild(document.createTextNode(css));
|
|
@@ -389,15 +313,13 @@ class PrefViewer extends HTMLElement {
|
|
|
389
313
|
}
|
|
390
314
|
|
|
391
315
|
const sessionMode = "immersive-ar";
|
|
392
|
-
this.#log.info("#createXRExperience()", { sessionMode });
|
|
393
316
|
const sessionSupported = await WebXRSessionManager.IsSessionSupportedAsync(sessionMode);
|
|
394
317
|
if (!sessionSupported) {
|
|
395
|
-
|
|
318
|
+
this.#log("info", "WebXR in mode AR is not supported");
|
|
396
319
|
return false;
|
|
397
320
|
}
|
|
398
321
|
|
|
399
322
|
try {
|
|
400
|
-
this.#log.time("xr:create");
|
|
401
323
|
const ground = MeshBuilder.CreateGround("ground", { width: 1000, height: 1000 }, this.#scene);
|
|
402
324
|
ground.isVisible = false;
|
|
403
325
|
|
|
@@ -421,7 +343,6 @@ class PrefViewer extends HTMLElement {
|
|
|
421
343
|
});
|
|
422
344
|
|
|
423
345
|
this.#XRExperience.baseExperience.sessionManager.onXRReady.add(() => {
|
|
424
|
-
this.#log.info("XR onXRReady");
|
|
425
346
|
// Set the initial position of xrCamera: use nonVRCamera, which contains a copy of the original this.#scene.activeCamera before entering XR
|
|
426
347
|
this.#XRExperience.baseExperience.camera.setTransformationFromNonVRCamera(this.#XRExperience.baseExperience._nonVRCamera);
|
|
427
348
|
this.#XRExperience.baseExperience.camera.setTarget(Vector3.Zero());
|
|
@@ -429,21 +350,16 @@ class PrefViewer extends HTMLElement {
|
|
|
429
350
|
});
|
|
430
351
|
|
|
431
352
|
this.addStylesToARButton();
|
|
432
|
-
this.#log
|
|
353
|
+
this.#log("info", "WebXR experience created");
|
|
433
354
|
} catch (error) {
|
|
434
355
|
console.warn("PrefViewer: failed to create WebXR experience", error);
|
|
435
|
-
this.#log.error("XR creation failed", error);
|
|
436
356
|
this.#XRExperience = null;
|
|
437
357
|
}
|
|
438
358
|
}
|
|
439
359
|
|
|
440
|
-
#canvasResizeObserver = new ResizeObserver(() =>
|
|
441
|
-
this.#log.debug("ResizeObserver -> engine.resize()");
|
|
442
|
-
this.#engine && this.#engine.resize();
|
|
443
|
-
});
|
|
360
|
+
#canvasResizeObserver = new ResizeObserver(() => this.#engine && this.#engine.resize());
|
|
444
361
|
|
|
445
362
|
#createCamera() {
|
|
446
|
-
this.#log.debug("#createCamera()");
|
|
447
363
|
this.#camera = new ArcRotateCamera("camera", (3 * Math.PI) / 2, Math.PI * 0.47, 10, Vector3.Zero(), this.#scene);
|
|
448
364
|
this.#camera.upperBetaLimit = Math.PI * 0.48;
|
|
449
365
|
this.#camera.lowerBetaLimit = Math.PI * 0.25;
|
|
@@ -452,10 +368,10 @@ class PrefViewer extends HTMLElement {
|
|
|
452
368
|
this.#camera.metadata = { locked: false }
|
|
453
369
|
this.#camera = this.#camera;
|
|
454
370
|
this.#camera.attachControl(this.#canvas, true);
|
|
371
|
+
this.#log("info", "Default camera created");
|
|
455
372
|
}
|
|
456
373
|
|
|
457
374
|
#createLights() {
|
|
458
|
-
this.#log.debug("#createLights()");
|
|
459
375
|
// 1) Stronger ambient fill
|
|
460
376
|
this.#hemiLight = new HemisphericLight("hemiLight", new Vector3(-10, 10, -10), this.#scene);
|
|
461
377
|
this.#hemiLight.intensity = 0.6;
|
|
@@ -475,14 +391,17 @@ class PrefViewer extends HTMLElement {
|
|
|
475
391
|
this.#cameraLight = new PointLight("pl", this.#camera.position, this.#scene);
|
|
476
392
|
this.#cameraLight.parent = this.#camera;
|
|
477
393
|
this.#cameraLight.intensity = 0.3;
|
|
394
|
+
|
|
395
|
+
this.#log("info", "Lights & shadows configured");
|
|
478
396
|
}
|
|
479
397
|
|
|
480
398
|
#setupInteraction() {
|
|
481
|
-
this.#log.debug("#setupInteraction()");
|
|
482
399
|
this.#canvas.addEventListener("wheel", (event) => {
|
|
483
400
|
if (!this.#scene || !this.#camera) {
|
|
484
401
|
return false;
|
|
485
402
|
}
|
|
403
|
+
//const pick = this.#scene.pick(this.#scene.pointerX, this.#scene.pointerY);
|
|
404
|
+
//this.#camera.target = pick.hit ? pick.pickedPoint.clone() : this.#camera.target;
|
|
486
405
|
if (!this.#scene.activeCamera.metadata?.locked) {
|
|
487
406
|
this.#scene.activeCamera.inertialRadiusOffset -= event.deltaY * this.#scene.activeCamera.wheelPrecision * 0.001;
|
|
488
407
|
}
|
|
@@ -492,16 +411,15 @@ class PrefViewer extends HTMLElement {
|
|
|
492
411
|
|
|
493
412
|
#disposeEngine() {
|
|
494
413
|
if (!this.#engine) return;
|
|
495
|
-
this.#log.info("#disposeEngine()");
|
|
496
414
|
this.#engine.dispose();
|
|
497
415
|
this.#engine = this.#scene = this.#camera = null;
|
|
498
416
|
this.#hemiLight = this.#dirLight = this.#cameraLight = null;
|
|
499
417
|
this.#shadowGen = null;
|
|
418
|
+
this.#log("info", "Engine disposed");
|
|
500
419
|
}
|
|
501
420
|
|
|
502
421
|
// Utility methods for loading gltf/glb
|
|
503
422
|
async #getServerFileDataHeader(uri) {
|
|
504
|
-
this.#log.debug("#getServerFileDataHeader()", { uri });
|
|
505
423
|
return new Promise((resolve) => {
|
|
506
424
|
const xhr = new XMLHttpRequest();
|
|
507
425
|
xhr.open("HEAD", uri, true);
|
|
@@ -510,15 +428,12 @@ class PrefViewer extends HTMLElement {
|
|
|
510
428
|
if (xhr.status === 200) {
|
|
511
429
|
const size = parseInt(xhr.getResponseHeader("Content-Length"));
|
|
512
430
|
const timestamp = new Date(xhr.getResponseHeader("Last-Modified")).toISOString();
|
|
513
|
-
this.#log.debug("HEAD ok", { size, timestamp });
|
|
514
431
|
resolve(size, timestamp);
|
|
515
432
|
} else {
|
|
516
|
-
this.#log.warn("HEAD failed", { status: xhr.status });
|
|
517
433
|
resolve(0, null);
|
|
518
434
|
}
|
|
519
435
|
};
|
|
520
436
|
xhr.onerror = () => {
|
|
521
|
-
this.#log.error("HEAD network error");
|
|
522
437
|
resolve(0, null);
|
|
523
438
|
};
|
|
524
439
|
xhr.send();
|
|
@@ -526,14 +441,12 @@ class PrefViewer extends HTMLElement {
|
|
|
526
441
|
}
|
|
527
442
|
|
|
528
443
|
#transformUrl(url) {
|
|
529
|
-
this.#log.debug("#transformUrl()", { url });
|
|
530
444
|
return new Promise((resolve) => {
|
|
531
445
|
resolve(url.replace(/^blob:[^/]+\//i, "").replace(/\\/g, "/"));
|
|
532
446
|
});
|
|
533
447
|
}
|
|
534
448
|
|
|
535
449
|
#decodeBase64(base64) {
|
|
536
|
-
this.#log.debug("#decodeBase64()", { length: (base64 || "").length });
|
|
537
450
|
const [, payload] = base64.split(",");
|
|
538
451
|
const raw = payload || base64;
|
|
539
452
|
let decoded = "";
|
|
@@ -543,11 +456,10 @@ class PrefViewer extends HTMLElement {
|
|
|
543
456
|
try {
|
|
544
457
|
decoded = atob(raw);
|
|
545
458
|
} catch {
|
|
546
|
-
this.#log.warn("atob failed (not base64?)");
|
|
547
459
|
return { blob, extension, size };
|
|
548
460
|
}
|
|
549
461
|
let isJson = false;
|
|
550
|
-
|
|
462
|
+
try {
|
|
551
463
|
JSON.parse(decoded);
|
|
552
464
|
isJson = true;
|
|
553
465
|
} catch {}
|
|
@@ -559,7 +471,6 @@ class PrefViewer extends HTMLElement {
|
|
|
559
471
|
}
|
|
560
472
|
|
|
561
473
|
async #initStorage(db, table) {
|
|
562
|
-
this.#log.debug("#initStorage()", { db, table });
|
|
563
474
|
if (window.gltfDB && window.gltfDB.name === db && window.gltfDB.objectStoreNames.contains(table)) {
|
|
564
475
|
return true;
|
|
565
476
|
}
|
|
@@ -568,24 +479,25 @@ class PrefViewer extends HTMLElement {
|
|
|
568
479
|
|
|
569
480
|
// Methods for managing Asset Containers
|
|
570
481
|
#setVisibilityOfWallAndFloorInModel(show) {
|
|
571
|
-
this.#log.debug("#setVisibilityOfWallAndFloorInModel()", { show });
|
|
572
482
|
if (!this.#data.containers.model.assetContainer || !this.#data.containers.model.visible) {
|
|
573
483
|
return false;
|
|
574
484
|
}
|
|
575
485
|
show = show !== undefined ? show : this.#data.containers.environment.visible;
|
|
576
486
|
const prefixes = Object.values(this.#data.options.materials).map((material) => material.prefix);
|
|
577
|
-
this.#data.containers.model.assetContainer.meshes.filter((meshToFilter) => prefixes.some((prefix) => meshToFilter.name.startsWith(prefix)))
|
|
487
|
+
const meshes = this.#data.containers.model.assetContainer.meshes.filter((meshToFilter) => prefixes.some((prefix) => meshToFilter.name.startsWith(prefix)));
|
|
488
|
+
this.#log("debug", "setVisibilityOfWallAndFloorInModel:", { show, affectedMeshes: meshes.map(m => m.name) });
|
|
489
|
+
meshes.forEach((mesh) => mesh.setEnabled(show));
|
|
578
490
|
}
|
|
579
491
|
|
|
580
492
|
#setOptionsMaterial(optionMaterial) {
|
|
581
493
|
if (!optionMaterial || !optionMaterial.prefix || !optionMaterial.value) {
|
|
494
|
+
this.#log("debug", "setOptionsMaterial: missing data", optionMaterial);
|
|
582
495
|
return false;
|
|
583
496
|
}
|
|
584
|
-
this.#log.debug("#setOptionsMaterial()", optionMaterial);
|
|
585
497
|
|
|
586
498
|
const material = this.#data.containers.materials.assetContainer?.materials.find((mat) => mat.name === optionMaterial.value) || null;
|
|
587
499
|
if (!material) {
|
|
588
|
-
this.#log
|
|
500
|
+
this.#log("warn", `setOptionsMaterial: material "${optionMaterial.value}" not found in materials container`);
|
|
589
501
|
return false;
|
|
590
502
|
}
|
|
591
503
|
|
|
@@ -597,41 +509,43 @@ class PrefViewer extends HTMLElement {
|
|
|
597
509
|
containers.push(this.#data.containers.environment.assetContainer);
|
|
598
510
|
}
|
|
599
511
|
if (containers.length === 0) {
|
|
512
|
+
this.#log("debug", "setOptionsMaterial: no target containers (unchanged)");
|
|
600
513
|
return false;
|
|
601
514
|
}
|
|
602
515
|
|
|
603
|
-
let
|
|
516
|
+
let count = 0;
|
|
604
517
|
containers.forEach((container) =>
|
|
605
518
|
container.meshes
|
|
606
519
|
.filter((meshToFilter) => meshToFilter.name.startsWith(optionMaterial.prefix))
|
|
607
520
|
.forEach((mesh) => {
|
|
608
521
|
mesh.material = material;
|
|
609
|
-
|
|
522
|
+
count++;
|
|
610
523
|
})
|
|
611
524
|
);
|
|
612
525
|
|
|
613
|
-
|
|
526
|
+
this.#log("info", "setOptionsMaterial applied", { prefix: optionMaterial.prefix, material: optionMaterial.value, meshesUpdated: count });
|
|
527
|
+
return count > 0;
|
|
614
528
|
}
|
|
615
529
|
|
|
616
530
|
#setOptionsMaterials() {
|
|
617
|
-
this.#log.debug("#setOptionsMaterials()");
|
|
618
531
|
let someSetted = false;
|
|
619
532
|
Object.values(this.#data.options.materials).forEach((material) => {
|
|
620
533
|
let settedMaterial = this.#setOptionsMaterial(material);
|
|
621
534
|
someSetted = someSetted || settedMaterial;
|
|
622
535
|
});
|
|
536
|
+
this.#log("info", "setOptionsMaterials: anyApplied =", someSetted);
|
|
623
537
|
return someSetted;
|
|
624
538
|
}
|
|
625
539
|
|
|
626
540
|
#setOptionsCamera() {
|
|
627
|
-
this.#log.debug("#setOptionsCamera()", this.#data.options.camera);
|
|
628
541
|
if (!this.#data.options.camera.value || (!this.#data.options.camera.changed && !this.#data.containers.model.assetContainer.changed)) {
|
|
542
|
+
this.#log("debug", "setOptionsCamera: skipped (no change or no camera specified)");
|
|
629
543
|
return false;
|
|
630
544
|
}
|
|
631
545
|
|
|
632
546
|
let camera = this.#data.containers.model.assetContainer?.cameras.find((cam) => cam.name === this.#data.options.camera.value) || null;
|
|
633
547
|
if (!camera) {
|
|
634
|
-
this.#log
|
|
548
|
+
this.#log("warn", `setOptionsCamera: camera "${this.#data.options.camera.value}" not found in model`);
|
|
635
549
|
return false;
|
|
636
550
|
}
|
|
637
551
|
|
|
@@ -640,28 +554,28 @@ class PrefViewer extends HTMLElement {
|
|
|
640
554
|
camera.attachControl(this.#canvas, true);
|
|
641
555
|
}
|
|
642
556
|
this.#scene.activeCamera = camera;
|
|
557
|
+
this.#log("info", "setOptionsCamera: activated", { name: camera.name, locked: this.#data.options.camera.locked });
|
|
643
558
|
|
|
644
559
|
return true;
|
|
645
560
|
}
|
|
646
561
|
|
|
647
562
|
#addContainer(container) {
|
|
648
563
|
if (container.assetContainer && !container.visible && container.show) {
|
|
649
|
-
this.#log.debug("#addContainer()", { name: container.name });
|
|
650
564
|
container.assetContainer.addAllToScene();
|
|
651
565
|
container.visible = true;
|
|
566
|
+
this.#log("debug", "addContainer -> visible", container.name);
|
|
652
567
|
}
|
|
653
568
|
}
|
|
654
569
|
|
|
655
570
|
#removeContainer(container) {
|
|
656
571
|
if (container.assetContainer && container.visible) {
|
|
657
|
-
this.#log.debug("#removeContainer()", { name: container.name });
|
|
658
572
|
container.assetContainer.removeAllFromScene();
|
|
659
573
|
container.visible = false;
|
|
574
|
+
this.#log("debug", "removeContainer -> hidden", container.name);
|
|
660
575
|
}
|
|
661
576
|
}
|
|
662
577
|
|
|
663
578
|
#replaceContainer(container, newAssetContainer) {
|
|
664
|
-
this.#log.debug("#replaceContainer()", { name: container.name });
|
|
665
579
|
this.#removeContainer(container);
|
|
666
580
|
container.assetContainer = newAssetContainer;
|
|
667
581
|
container.assetContainer.meshes.forEach((mesh) => {
|
|
@@ -669,18 +583,24 @@ class PrefViewer extends HTMLElement {
|
|
|
669
583
|
this.#shadowGen.addShadowCaster(mesh, true);
|
|
670
584
|
});
|
|
671
585
|
this.#addContainer(container);
|
|
586
|
+
this.#log("debug", "replaceContainer:", container.name, {
|
|
587
|
+
meshes: container.assetContainer.meshes?.length,
|
|
588
|
+
materials: container.assetContainer.materials?.length,
|
|
589
|
+
cameras: container.assetContainer.cameras?.length,
|
|
590
|
+
});
|
|
672
591
|
}
|
|
673
592
|
|
|
674
593
|
async #loadAssetContainer(container) {
|
|
675
|
-
this.#log.group(`#loadAssetContainer(${container?.name})`);
|
|
676
594
|
let storage = container?.storage;
|
|
677
595
|
|
|
678
596
|
if (!storage) {
|
|
679
|
-
this.#log
|
|
680
|
-
this.#log.groupEnd();
|
|
597
|
+
this.#log("debug", `loadAssetContainer(${container?.name}): no storage provided`);
|
|
681
598
|
return false;
|
|
682
599
|
}
|
|
683
600
|
|
|
601
|
+
this.#log("groupCollapsed", `loadAssetContainer -> ${container.name}`);
|
|
602
|
+
this.#log("info", "storage:", storage);
|
|
603
|
+
|
|
684
604
|
let source = storage.url || null;
|
|
685
605
|
|
|
686
606
|
if (storage.db && storage.table && storage.id) {
|
|
@@ -688,17 +608,18 @@ class PrefViewer extends HTMLElement {
|
|
|
688
608
|
const object = await loadModel(storage.id, storage.table);
|
|
689
609
|
source = object.data;
|
|
690
610
|
if (object.timestamp === container.timestamp) {
|
|
691
|
-
this.#log
|
|
692
|
-
|
|
611
|
+
this.#log("info", "IndexedDB source unchanged (timestamp match). Skipping reload.");
|
|
612
|
+
console.groupEnd();
|
|
693
613
|
return false;
|
|
694
614
|
} else {
|
|
695
615
|
container.changed = { timestamp: object.timestamp, size: object.size };
|
|
616
|
+
this.#log("info", "IndexedDB source changed:", container.changed);
|
|
696
617
|
}
|
|
697
618
|
}
|
|
698
619
|
|
|
699
620
|
if (!source) {
|
|
700
|
-
this.#log
|
|
701
|
-
|
|
621
|
+
this.#log("warn", "no source (url/db) to load");
|
|
622
|
+
console.groupEnd();
|
|
702
623
|
return false;
|
|
703
624
|
}
|
|
704
625
|
|
|
@@ -706,17 +627,17 @@ class PrefViewer extends HTMLElement {
|
|
|
706
627
|
|
|
707
628
|
let { blob, extension, size } = this.#decodeBase64(source);
|
|
708
629
|
if (blob && extension) {
|
|
709
|
-
this.#log.debug("source is base64", { extension, size });
|
|
710
630
|
file = new File([blob], `${container.name}${extension}`, {
|
|
711
631
|
type: blob.type,
|
|
712
632
|
});
|
|
713
633
|
if (!container.changed) {
|
|
714
634
|
if (container.timestamp === null && container.size === size) {
|
|
715
|
-
this.#log
|
|
716
|
-
|
|
635
|
+
this.#log("info", "Base64 source unchanged (size match). Skipping reload.");
|
|
636
|
+
console.groupEnd();
|
|
717
637
|
return false;
|
|
718
638
|
} else {
|
|
719
639
|
container.changed = { timestamp: null, size: size };
|
|
640
|
+
this.#log("info", "Base64 source changed (size):", container.changed);
|
|
720
641
|
}
|
|
721
642
|
}
|
|
722
643
|
} else {
|
|
@@ -724,11 +645,12 @@ class PrefViewer extends HTMLElement {
|
|
|
724
645
|
extension = extMatch ? `.${extMatch[1].toLowerCase()}` : ".gltf";
|
|
725
646
|
const { fileSize, fileTimestamp } = await this.#getServerFileDataHeader(source);
|
|
726
647
|
if (container.timestamp === fileTimestamp && container.size === fileSize) {
|
|
727
|
-
this.#log
|
|
728
|
-
|
|
648
|
+
this.#log("info", "URL source unchanged (HEAD size/timestamp). Skipping reload.");
|
|
649
|
+
console.groupEnd();
|
|
729
650
|
return false;
|
|
730
651
|
} else {
|
|
731
652
|
container.changed = { timestamp: fileTimestamp, size: fileSize };
|
|
653
|
+
this.#log("info", "URL source changed:", container.changed);
|
|
732
654
|
}
|
|
733
655
|
}
|
|
734
656
|
|
|
@@ -742,15 +664,19 @@ class PrefViewer extends HTMLElement {
|
|
|
742
664
|
},
|
|
743
665
|
};
|
|
744
666
|
|
|
745
|
-
this.#log
|
|
746
|
-
const
|
|
747
|
-
this.#log
|
|
748
|
-
|
|
667
|
+
this.#log("info", "Loading asset container with options:", options);
|
|
668
|
+
const result = await LoadAssetContainerAsync(file || source, this.#scene, options);
|
|
669
|
+
this.#log("info", "Asset container loaded:", {
|
|
670
|
+
meshes: result.meshes?.length,
|
|
671
|
+
materials: result.materials?.length,
|
|
672
|
+
cameras: result.cameras?.length,
|
|
673
|
+
});
|
|
674
|
+
console.groupEnd();
|
|
675
|
+
return result;
|
|
749
676
|
}
|
|
750
677
|
|
|
751
678
|
async #loadContainers(loadModel = true, loadEnvironment = true, loadMaterials = true) {
|
|
752
|
-
this.#log
|
|
753
|
-
this.#log.debug("flags", { loadModel, loadEnvironment, loadMaterials });
|
|
679
|
+
this.#log("groupCollapsed", "loadContainers flags", { loadModel, loadEnvironment, loadMaterials });
|
|
754
680
|
const promiseArray = [];
|
|
755
681
|
promiseArray.push(loadModel ? this.#loadAssetContainer(this.#data.containers.model) : false);
|
|
756
682
|
promiseArray.push(loadEnvironment ? this.#loadAssetContainer(this.#data.containers.environment) : false);
|
|
@@ -762,39 +688,39 @@ class PrefViewer extends HTMLElement {
|
|
|
762
688
|
const environmentContainer = values[1];
|
|
763
689
|
const materialsContainer = values[2];
|
|
764
690
|
|
|
691
|
+
this.#log("info", "loadContainers results:", {
|
|
692
|
+
model: modelContainer?.status,
|
|
693
|
+
environment: environmentContainer?.status,
|
|
694
|
+
materials: materialsContainer?.status,
|
|
695
|
+
});
|
|
696
|
+
|
|
765
697
|
if (modelContainer.status === "fulfilled" && modelContainer.value) {
|
|
766
|
-
this.#log.timeEnd(`babylon:LoadAssetContainerAsync:model`);
|
|
767
698
|
this.#replaceContainer(this.#data.containers.model, modelContainer.value);
|
|
768
699
|
this.#storeChangedFlagsForContainer(this.#data.containers.model);
|
|
769
700
|
} else {
|
|
770
|
-
this.#log.debug("model container unchanged / not loaded");
|
|
771
701
|
this.#data.containers.model.show ? this.#addContainer(this.#data.containers.model) : this.#removeContainer(this.#data.containers.model);
|
|
772
702
|
}
|
|
773
703
|
|
|
774
704
|
if (environmentContainer.status === "fulfilled" && environmentContainer.value) {
|
|
775
|
-
this.#log.timeEnd(`babylon:LoadAssetContainerAsync:environment`);
|
|
776
705
|
this.#replaceContainer(this.#data.containers.environment, environmentContainer.value);
|
|
777
706
|
this.#storeChangedFlagsForContainer(this.#data.containers.environment);
|
|
778
707
|
} else {
|
|
779
|
-
this.#log.debug("environment container unchanged / not loaded");
|
|
780
708
|
this.#data.containers.environment.show ? this.#addContainer(this.#data.containers.environment) : this.#removeContainer(this.#data.containers.environment);
|
|
781
709
|
}
|
|
782
710
|
|
|
783
711
|
if (materialsContainer.status === "fulfilled" && materialsContainer.value) {
|
|
784
|
-
this.#log.timeEnd(`babylon:LoadAssetContainerAsync:materials`);
|
|
785
712
|
this.#replaceContainer(this.#data.containers.materials, materialsContainer.value);
|
|
786
713
|
this.#storeChangedFlagsForContainer(this.#data.containers.materials);
|
|
787
|
-
} else if (loadMaterials) {
|
|
788
|
-
this.#log.debug("materials container unchanged / not loaded");
|
|
789
714
|
}
|
|
790
715
|
|
|
791
|
-
this.#setOptionsMaterials();
|
|
792
|
-
this.#setOptionsCamera();
|
|
716
|
+
const materialsApplied = this.#setOptionsMaterials();
|
|
717
|
+
const cameraApplied = this.#setOptionsCamera();
|
|
793
718
|
this.#setVisibilityOfWallAndFloorInModel();
|
|
794
719
|
|
|
720
|
+
this.#log("info", "post-load options applied", { materialsApplied, cameraApplied });
|
|
721
|
+
|
|
795
722
|
this.#resetChangedFlags();
|
|
796
723
|
|
|
797
|
-
this.#log.info("dispatch: model-loaded");
|
|
798
724
|
this.dispatchEvent(
|
|
799
725
|
new CustomEvent("model-loaded", {
|
|
800
726
|
detail: { success: "" },
|
|
@@ -802,11 +728,11 @@ class PrefViewer extends HTMLElement {
|
|
|
802
728
|
composed: true,
|
|
803
729
|
})
|
|
804
730
|
);
|
|
805
|
-
this.#log
|
|
731
|
+
this.#log("info", "model-loaded event dispatched");
|
|
732
|
+
console.groupEnd();
|
|
806
733
|
})
|
|
807
734
|
.catch((error) => {
|
|
808
735
|
console.error("PrefViewer: failed to load model", error);
|
|
809
|
-
this.#log.error("failed to load model", error);
|
|
810
736
|
this.dispatchEvent(
|
|
811
737
|
new CustomEvent("model-error", {
|
|
812
738
|
detail: { error: error },
|
|
@@ -814,17 +740,18 @@ class PrefViewer extends HTMLElement {
|
|
|
814
740
|
composed: true,
|
|
815
741
|
})
|
|
816
742
|
);
|
|
817
|
-
this.#log
|
|
743
|
+
this.#log("error", "model-error event dispatched");
|
|
744
|
+
console.groupEnd();
|
|
818
745
|
});
|
|
819
746
|
}
|
|
820
747
|
|
|
821
748
|
// Public Methods
|
|
822
749
|
loadConfig(config) {
|
|
823
|
-
this.#log
|
|
750
|
+
this.#log("groupCollapsed", "loadConfig called with:", config);
|
|
824
751
|
config = typeof config === "string" ? JSON.parse(config) : config;
|
|
825
752
|
if (!config) {
|
|
826
|
-
this.#log
|
|
827
|
-
|
|
753
|
+
this.#log("warn", "loadConfig: no config provided");
|
|
754
|
+
console.groupEnd();
|
|
828
755
|
return false;
|
|
829
756
|
}
|
|
830
757
|
|
|
@@ -835,22 +762,30 @@ class PrefViewer extends HTMLElement {
|
|
|
835
762
|
this.#data.containers.environment.show = config.scene?.visible !== undefined ? config.scene.visible : this.#data.containers.environment.show;
|
|
836
763
|
this.#data.containers.materials.storage = config.materials?.storage || null;
|
|
837
764
|
|
|
765
|
+
this.#log("info", "containers set from config", {
|
|
766
|
+
model: this.#data.containers.model,
|
|
767
|
+
environment: this.#data.containers.environment,
|
|
768
|
+
materials: this.#data.containers.materials,
|
|
769
|
+
});
|
|
770
|
+
|
|
838
771
|
// Options
|
|
839
772
|
if (config.options) {
|
|
840
|
-
this.#checkCameraChanged(config.options);
|
|
841
|
-
this.#checkMaterialsChanged(config.options);
|
|
773
|
+
const camChanged = this.#checkCameraChanged(config.options);
|
|
774
|
+
const matsChanged = this.#checkMaterialsChanged(config.options);
|
|
775
|
+
this.#log("info", "options parsed", { camChanged, matsChanged, options: this.#data.options });
|
|
776
|
+
} else {
|
|
777
|
+
this.#log("debug", "no options in config");
|
|
842
778
|
}
|
|
843
779
|
|
|
844
|
-
this.#log.debug("config applied", { containers: this.#data.containers, options: this.#data.options });
|
|
845
780
|
this.#initialized && this.#loadContainers(true, true, true);
|
|
846
|
-
|
|
781
|
+
console.groupEnd();
|
|
847
782
|
}
|
|
848
783
|
|
|
849
784
|
setOptions(options) {
|
|
850
|
-
this.#log
|
|
785
|
+
this.#log("groupCollapsed", "setOptions called with:", options);
|
|
851
786
|
if (!options) {
|
|
852
|
-
this.#log
|
|
853
|
-
|
|
787
|
+
this.#log("warn", "setOptions: no options");
|
|
788
|
+
console.groupEnd();
|
|
854
789
|
return false;
|
|
855
790
|
}
|
|
856
791
|
let someSetted = false;
|
|
@@ -861,74 +796,74 @@ class PrefViewer extends HTMLElement {
|
|
|
861
796
|
someSetted = someSetted || this.#setOptionsMaterials();
|
|
862
797
|
}
|
|
863
798
|
this.#resetChangedFlags();
|
|
799
|
+
this.#log("info", "setOptions result:", { applied: someSetted, currentOptions: this.#data.options });
|
|
864
800
|
debugger;
|
|
865
|
-
|
|
866
|
-
this.#log.groupEnd();
|
|
801
|
+
console.groupEnd();
|
|
867
802
|
return someSetted;
|
|
868
803
|
}
|
|
869
804
|
|
|
870
805
|
loadModel(model) {
|
|
871
|
-
this.#log
|
|
806
|
+
this.#log("groupCollapsed", "loadModel called with:", model);
|
|
872
807
|
model = typeof model === "string" ? JSON.parse(model) : model;
|
|
873
808
|
if (!model) {
|
|
874
|
-
this.#log
|
|
875
|
-
|
|
809
|
+
this.#log("warn", "loadModel: no model object");
|
|
810
|
+
console.groupEnd();
|
|
876
811
|
return false;
|
|
877
812
|
}
|
|
878
813
|
this.#data.containers.model.storage = model.storage || null;
|
|
879
814
|
this.#data.containers.model.show = model.visible !== undefined ? model.visible : this.#data.containers.model.show;
|
|
815
|
+
this.#log("info", "model container updated", this.#data.containers.model);
|
|
880
816
|
this.#initialized && this.#loadContainers(true, false, false);
|
|
881
|
-
|
|
817
|
+
console.groupEnd();
|
|
882
818
|
}
|
|
883
819
|
|
|
884
820
|
loadScene(scene) {
|
|
885
|
-
this.#log
|
|
821
|
+
this.#log("groupCollapsed", "loadScene called with:", scene);
|
|
886
822
|
scene = typeof scene === "string" ? JSON.parse(scene) : scene;
|
|
887
823
|
if (!scene) {
|
|
888
|
-
this.#log
|
|
889
|
-
|
|
824
|
+
this.#log("warn", "loadScene: no scene object");
|
|
825
|
+
console.groupEnd();
|
|
890
826
|
return false;
|
|
891
827
|
}
|
|
892
828
|
this.#data.containers.environment.storage = scene.storage || null;
|
|
893
829
|
this.#data.containers.environment.show = scene.visible !== undefined ? scene.visible : this.#data.containers.environment.show;
|
|
830
|
+
this.#log("info", "environment container updated", this.#data.containers.environment);
|
|
894
831
|
this.#initialized && this.#loadContainers(false, true, false);
|
|
895
|
-
|
|
832
|
+
console.groupEnd();
|
|
896
833
|
}
|
|
897
834
|
|
|
898
835
|
showModel() {
|
|
899
|
-
this.#log
|
|
836
|
+
this.#log("info", "showModel()");
|
|
900
837
|
this.#data.containers.model.show = true;
|
|
901
838
|
this.#addContainer(this.#data.containers.model);
|
|
902
839
|
}
|
|
903
840
|
|
|
904
841
|
hideModel() {
|
|
905
|
-
this.#log
|
|
842
|
+
this.#log("info", "hideModel()");
|
|
906
843
|
this.#data.containers.model.show = false;
|
|
907
844
|
this.#removeContainer(this.#data.containers.model);
|
|
908
845
|
}
|
|
909
846
|
|
|
910
847
|
showScene() {
|
|
911
|
-
this.#log
|
|
848
|
+
this.#log("info", "showScene()");
|
|
912
849
|
this.#data.containers.environment.show = true;
|
|
913
850
|
this.#addContainer(this.#data.containers.environment);
|
|
914
851
|
this.#setVisibilityOfWallAndFloorInModel();
|
|
915
852
|
}
|
|
916
853
|
|
|
917
854
|
hideScene() {
|
|
918
|
-
this.#log
|
|
855
|
+
this.#log("info", "hideScene()");
|
|
919
856
|
this.#data.containers.environment.show = false;
|
|
920
857
|
this.#removeContainer(this.#data.containers.environment);
|
|
921
858
|
this.#setVisibilityOfWallAndFloorInModel();
|
|
922
859
|
}
|
|
923
860
|
|
|
924
861
|
downloadModelGLB() {
|
|
925
|
-
this.#log.info("downloadModelGLB()");
|
|
926
862
|
const fileName = "model";
|
|
927
863
|
GLTF2Export.GLBAsync(this.#data.containers.model.assetContainer, fileName, { exportWithoutWaitingForScene: true }).then((glb) => glb.downloadFiles());
|
|
928
864
|
}
|
|
929
865
|
|
|
930
866
|
downloadModelUSDZ() {
|
|
931
|
-
this.#log.info("downloadModelUSDZ()");
|
|
932
867
|
const fileName = "model";
|
|
933
868
|
USDZExportAsync(this.#data.containers.model.assetContainer).then((response) => {
|
|
934
869
|
if (response) {
|
|
@@ -938,7 +873,6 @@ class PrefViewer extends HTMLElement {
|
|
|
938
873
|
}
|
|
939
874
|
|
|
940
875
|
downloadModelAndSceneUSDZ() {
|
|
941
|
-
this.#log.info("downloadModelAndSceneUSDZ()");
|
|
942
876
|
const fileName = "scene";
|
|
943
877
|
USDZExportAsync(this.#scene).then((response) => {
|
|
944
878
|
if (response) {
|
|
@@ -948,7 +882,6 @@ class PrefViewer extends HTMLElement {
|
|
|
948
882
|
}
|
|
949
883
|
|
|
950
884
|
downloadModelAndSceneGLB() {
|
|
951
|
-
this.#log.info("downloadModelAndSceneGLB()");
|
|
952
885
|
const fileName = "scene";
|
|
953
886
|
GLTF2Export.GLBAsync(this.#scene, fileName, { exportWithoutWaitingForScene: true }).then((glb) => glb.downloadFiles());
|
|
954
887
|
}
|