@preference-sl/pref-viewer 2.10.0-beta.20 → 2.10.0-beta.22

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +123 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@preference-sl/pref-viewer",
3
- "version": "2.10.0-beta.20",
3
+ "version": "2.10.0-beta.22",
4
4
  "description": "Web Component to preview GLTF models with Babylon.js",
5
5
  "author": "Alex Moreno Palacio <amoreno@preference.es>",
6
6
  "scripts": {
package/src/index.js CHANGED
@@ -131,11 +131,13 @@ class PrefViewer extends HTMLElement {
131
131
 
132
132
  constructor() {
133
133
  super();
134
+ console.log("PrefViewer: constructor()");
134
135
  this.attachShadow({ mode: "open" });
135
136
  this.#createCanvas();
136
137
  this.#wrapCanvas();
137
138
  // Point to whichever version you packaged or want to use:
138
139
  const DRACO_BASE = "https://www.gstatic.com/draco/versioned/decoders/1.5.7";
140
+ console.log("PrefViewer: DRACO config base =", DRACO_BASE);
139
141
  DracoCompression.Configuration.decoder = {
140
142
  // loader for the “wrapper” that pulls in the real WASM
141
143
  wasmUrl: `${DRACO_BASE}/draco_wasm_wrapper_gltf.js`,
@@ -151,6 +153,7 @@ class PrefViewer extends HTMLElement {
151
153
  }
152
154
 
153
155
  attributeChangedCallback(name, _old, value) {
156
+ console.log("PrefViewer: attributeChangedCallback()", { name, old: _old, value });
154
157
  let data = null;
155
158
  switch (name) {
156
159
  case "config":
@@ -165,6 +168,7 @@ class PrefViewer extends HTMLElement {
165
168
  case "show-model":
166
169
  data = value.toLowerCase?.() === "true";
167
170
  if (this.initialized) {
171
+ console.log("PrefViewer: toggling model visibility (attr)", data);
168
172
  data ? this.showModel() : this.hideModel();
169
173
  } else {
170
174
  this.#data.containers.model.show = data;
@@ -173,6 +177,7 @@ class PrefViewer extends HTMLElement {
173
177
  case "show-scene":
174
178
  data = value.toLowerCase?.() === "true";
175
179
  if (this.initialized) {
180
+ console.log("PrefViewer: toggling scene visibility (attr)", data);
176
181
  data ? this.showScene() : this.hideScene();
177
182
  } else {
178
183
  this.#data.containers.environment.show = data;
@@ -182,6 +187,7 @@ class PrefViewer extends HTMLElement {
182
187
  }
183
188
 
184
189
  connectedCallback() {
190
+ console.log("PrefViewer: connectedCallback()");
185
191
  if (!this.hasAttribute("config")) {
186
192
  const error = 'PrefViewer: provide "models" as array of model and environment';
187
193
  console.error(error);
@@ -198,16 +204,19 @@ class PrefViewer extends HTMLElement {
198
204
 
199
205
  this.#initializeBabylon();
200
206
  this.initialized = true;
207
+ console.log("PrefViewer: initialized = true, loading containers…");
201
208
  this.#loadContainers(true, true, true);
202
209
  }
203
210
 
204
211
  disconnectedCallback() {
212
+ console.log("PrefViewer: disconnectedCallback()");
205
213
  this.#disposeEngine();
206
214
  this.#canvasResizeObserver.disconnect();
207
215
  }
208
216
 
209
217
  // Web Component
210
218
  #createCanvas() {
219
+ console.log("PrefViewer: #createCanvas()");
211
220
  this.#canvas = document.createElement("canvas");
212
221
  Object.assign(this.#canvas.style, {
213
222
  width: "100%",
@@ -218,6 +227,7 @@ class PrefViewer extends HTMLElement {
218
227
  }
219
228
 
220
229
  #wrapCanvas() {
230
+ console.log("PrefViewer: #wrapCanvas()");
221
231
  this.#wrapper = document.createElement("div");
222
232
  Object.assign(this.#wrapper.style, {
223
233
  width: "100%",
@@ -229,6 +239,7 @@ class PrefViewer extends HTMLElement {
229
239
  }
230
240
 
231
241
  #setStatusSceneLoading() {
242
+ console.log("PrefViewer: #setStatusSceneLoading()");
232
243
  this.loaded = false;
233
244
  this.loading = true;
234
245
  if (this.hasAttribute("loaded")) {
@@ -245,6 +256,7 @@ class PrefViewer extends HTMLElement {
245
256
  }
246
257
 
247
258
  #setStatusSceneLoaded() {
259
+ console.log("PrefViewer: #setStatusSceneLoaded()");
248
260
  this.loaded = true;
249
261
  this.loading = false;
250
262
 
@@ -286,9 +298,11 @@ class PrefViewer extends HTMLElement {
286
298
  detail: detail,
287
299
  })
288
300
  );
301
+ console.log("PrefViewer: scene-loaded detail =", detail);
289
302
  }
290
303
 
291
304
  #setStatusOptionsLoading() {
305
+ console.log("PrefViewer: #setStatusOptionsLoading()");
292
306
  this.dispatchEvent(
293
307
  new CustomEvent("options-loading", {
294
308
  bubbles: true,
@@ -299,6 +313,7 @@ class PrefViewer extends HTMLElement {
299
313
  }
300
314
 
301
315
  #setStatusOptionsLoaded() {
316
+ console.log("PrefViewer: #setStatusOptionsLoaded()");
302
317
  const toLoadDetail = {
303
318
  innerWallMaterial: !!this.#data.options.materials.innerWall.changed,
304
319
  outerWallMaterial: !!this.#data.options.materials.outerWall.changed,
@@ -325,6 +340,7 @@ class PrefViewer extends HTMLElement {
325
340
  detail: detail,
326
341
  })
327
342
  );
343
+ console.log("PrefViewer: options-loaded detail =", detail);
328
344
  }
329
345
 
330
346
  // Data
@@ -332,8 +348,8 @@ class PrefViewer extends HTMLElement {
332
348
  if (!options || !options.camera) {
333
349
  return false;
334
350
  }
335
-
336
351
  const changed = options.camera !== this.#data.options.camera.value;
352
+ console.log("PrefViewer: #checkCameraChanged()", { incoming: options.camera, previous: this.#data.options.camera.value, changed });
337
353
  this.#data.options.camera.changed = changed ? { oldValue: this.#data.options.camera.value, oldLocked: this.#data.options.camera.locked, success: false } : false;
338
354
  if (changed) this.#data.options.camera.value = options.camera;
339
355
 
@@ -348,6 +364,7 @@ class PrefViewer extends HTMLElement {
348
364
  Object.keys(this.#data.options.materials).forEach((material) => {
349
365
  const key = `${material}Material`;
350
366
  const materialChanged = options[key] && options[key] !== this.#data.options.materials[material].value ? true : false;
367
+ console.log("PrefViewer: #checkMaterialsChanged()", { key, incoming: options[key], previous: this.#data.options.materials[material].value, materialChanged });
351
368
  this.#data.options.materials[material].changed = materialChanged ? { oldValue: this.#data.options.materials[material].value, success: false } : false;
352
369
  this.#data.options.materials[material].value = materialChanged ? options[key] : this.#data.options.materials[material].value;
353
370
  someChanged = someChanged || this.#data.options.materials[material].changed;
@@ -356,12 +373,14 @@ class PrefViewer extends HTMLElement {
356
373
  }
357
374
 
358
375
  #storeChangedFlagsForContainer(container) {
376
+ console.log("PrefViewer: #storeChangedFlagsForContainer()", { name: container.name, changed: container.changed });
359
377
  container.timeStamp = container.changed.timeStamp;
360
378
  container.size = container.changed.size;
361
379
  container.changed.success = true;
362
380
  }
363
381
 
364
382
  #resetChangedFlags() {
383
+ console.log("PrefViewer: #resetChangedFlags()");
365
384
  Object.values(this.#data.containers).forEach((container) => (container.changed = false));
366
385
  Object.values(this.#data.options.materials).forEach((material) => (material.changed = false));
367
386
  this.#data.options.camera.changed = false;
@@ -369,22 +388,30 @@ class PrefViewer extends HTMLElement {
369
388
 
370
389
  // Babylon.js
371
390
  async #initializeBabylon() {
391
+ console.log("PrefViewer: #initializeBabylon() START");
372
392
  this.#engine = new Engine(this.#canvas, true, { alpha: true });
373
393
  this.#engine.disableUniformBuffers = true; // <- evita el límite de GL_MAX_*_UNIFORM_BUFFERS // PROVISIONAL, YA QUE ESTO ES UN POCO OVERKILL
394
+ console.log("PrefViewer: Engine created", { disableUBO: this.#engine.disableUniformBuffers });
374
395
 
375
396
  this.#scene = new Scene(this.#engine);
376
397
  this.#scene.clearColor = new Color4(1, 1, 1, 1);
398
+ console.log("PrefViewer: Scene created, clearColor set to white");
399
+
377
400
  this.#createCamera();
378
401
  this.#createLights();
379
402
  this.#setupInteraction();
380
403
 
381
404
  this.#engine.runRenderLoop(() => this.#scene && this.#scene.render());
405
+ console.log("PrefViewer: runRenderLoop started");
382
406
  this.#canvasResizeObserver.observe(this.#canvas);
407
+ console.log("PrefViewer: ResizeObserver attached");
383
408
 
384
409
  await this.#createXRExperience();
410
+ console.log("PrefViewer: #initializeBabylon() END");
385
411
  }
386
412
 
387
413
  addStylesToARButton() {
414
+ console.log("PrefViewer: addStylesToARButton()");
388
415
  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"}';
389
416
  const style = document.createElement("style");
390
417
  style.appendChild(document.createTextNode(css));
@@ -392,12 +419,15 @@ class PrefViewer extends HTMLElement {
392
419
  }
393
420
 
394
421
  async #createXRExperience() {
422
+ console.log("PrefViewer: #createXRExperience() START");
395
423
  if (this.#XRExperience) {
424
+ console.log("PrefViewer: XR already exists, skipping.");
396
425
  return true;
397
426
  }
398
427
 
399
428
  const sessionMode = "immersive-ar";
400
429
  const sessionSupported = await WebXRSessionManager.IsSessionSupportedAsync(sessionMode);
430
+ console.log("PrefViewer: WebXR session supported =", sessionSupported);
401
431
  if (!sessionSupported) {
402
432
  console.info("PrefViewer: WebXR in mode AR is not supported");
403
433
  return false;
@@ -418,6 +448,7 @@ class PrefViewer extends HTMLElement {
418
448
  };
419
449
 
420
450
  this.#XRExperience = await WebXRDefaultExperience.CreateAsync(this.#scene, options);
451
+ console.log("PrefViewer: XR experience created");
421
452
 
422
453
  const featuresManager = this.#XRExperience.baseExperience.featuresManager;
423
454
  featuresManager.enableFeature(WebXRFeatureName.TELEPORTATION, "stable", {
@@ -427,6 +458,7 @@ class PrefViewer extends HTMLElement {
427
458
  });
428
459
 
429
460
  this.#XRExperience.baseExperience.sessionManager.onXRReady.add(() => {
461
+ console.log("PrefViewer: onXRReady - syncing camera pose");
430
462
  // Set the initial position of xrCamera: use nonVRCamera, which contains a copy of the original this.#scene.activeCamera before entering XR
431
463
  this.#XRExperience.baseExperience.camera.setTransformationFromNonVRCamera(this.#XRExperience.baseExperience._nonVRCamera);
432
464
  this.#XRExperience.baseExperience.camera.setTarget(Vector3.Zero());
@@ -438,11 +470,13 @@ class PrefViewer extends HTMLElement {
438
470
  console.warn("PrefViewer: failed to create WebXR experience", error);
439
471
  this.#XRExperience = null;
440
472
  }
473
+ console.log("PrefViewer: #createXRExperience() END");
441
474
  }
442
475
 
443
476
  #canvasResizeObserver = new ResizeObserver(() => this.#engine && this.#engine.resize());
444
477
 
445
478
  #createCamera() {
479
+ console.log("PrefViewer: #createCamera()");
446
480
  this.#camera = new ArcRotateCamera("camera", (3 * Math.PI) / 2, Math.PI * 0.47, 10, Vector3.Zero(), this.#scene);
447
481
  this.#camera.upperBetaLimit = Math.PI * 0.48;
448
482
  this.#camera.lowerBetaLimit = Math.PI * 0.25;
@@ -451,9 +485,16 @@ class PrefViewer extends HTMLElement {
451
485
  this.#camera.metadata = { locked: false }
452
486
  this.#camera.attachControl(this.#canvas, true);
453
487
  this.#scene.activeCamera = this.#camera;
488
+ console.log("PrefViewer: camera configured", {
489
+ upperBetaLimit: this.#camera.upperBetaLimit,
490
+ lowerBetaLimit: this.#camera.lowerBetaLimit,
491
+ lowerRadiusLimit: this.#camera.lowerRadiusLimit,
492
+ upperRadiusLimit: this.#camera.upperRadiusLimit
493
+ });
454
494
  }
455
495
 
456
496
  #createLights() {
497
+ console.log("PrefViewer: #createLights()");
457
498
  // 1) Stronger ambient fill
458
499
  this.#hemiLight = new HemisphericLight("hemiLight", new Vector3(-10, 10, -10), this.#scene);
459
500
  this.#hemiLight.intensity = 0.6;
@@ -473,15 +514,21 @@ class PrefViewer extends HTMLElement {
473
514
  this.#cameraLight = new PointLight("pl", this.#camera.position, this.#scene);
474
515
  this.#cameraLight.parent = this.#camera;
475
516
  this.#cameraLight.intensity = 0.3;
517
+
518
+ console.log("PrefViewer: lights created", {
519
+ hemiIntensity: this.#hemiLight.intensity,
520
+ dirIntensity: this.#dirLight.intensity,
521
+ shadowMapSize: 1024,
522
+ pointIntensity: this.#cameraLight.intensity
523
+ });
476
524
  }
477
525
 
478
526
  #setupInteraction() {
527
+ console.log("PrefViewer: #setupInteraction()");
479
528
  this.#canvas.addEventListener("wheel", (event) => {
480
529
  if (!this.#scene || !this.#camera) {
481
530
  return false;
482
531
  }
483
- //const pick = this.#scene.pick(this.#scene.pointerX, this.#scene.pointerY);
484
- //this.#camera.target = pick.hit ? pick.pickedPoint.clone() : this.#camera.target;
485
532
  if (!this.#scene.activeCamera.metadata?.locked) {
486
533
  this.#scene.activeCamera.inertialRadiusOffset -= event.deltaY * this.#scene.activeCamera.wheelPrecision * 0.001;
487
534
  }
@@ -490,6 +537,7 @@ class PrefViewer extends HTMLElement {
490
537
  }
491
538
 
492
539
  #disposeEngine() {
540
+ console.log("PrefViewer: #disposeEngine()");
493
541
  if (!this.#engine) return;
494
542
  this.#shadowGen?.dispose();
495
543
  this.#scene?.lights?.slice().forEach(l => l.dispose());
@@ -501,6 +549,7 @@ class PrefViewer extends HTMLElement {
501
549
 
502
550
  // Utility methods for loading gltf/glb
503
551
  async #getServerFileDataHeader(uri) {
552
+ console.log("PrefViewer: #getServerFileDataHeader()", uri);
504
553
  return new Promise((resolve) => {
505
554
  const xhr = new XMLHttpRequest();
506
555
  xhr.open("HEAD", uri, true);
@@ -509,12 +558,15 @@ class PrefViewer extends HTMLElement {
509
558
  if (xhr.status === 200) {
510
559
  const size = parseInt(xhr.getResponseHeader("Content-Length"));
511
560
  const timeStamp = new Date(xhr.getResponseHeader("Last-Modified")).toISOString();
561
+ console.log("PrefViewer: HEAD ok", { size, timeStamp });
512
562
  resolve([size, timeStamp]);
513
563
  } else {
564
+ console.warn("PrefViewer: HEAD failed", xhr.status);
514
565
  resolve([0, null]);
515
566
  }
516
567
  };
517
568
  xhr.onerror = () => {
569
+ console.warn("PrefViewer: HEAD network error");
518
570
  resolve([0, null]);
519
571
  };
520
572
  xhr.send();
@@ -523,11 +575,14 @@ class PrefViewer extends HTMLElement {
523
575
 
524
576
  #transformUrl(url) {
525
577
  return new Promise((resolve) => {
526
- resolve(url.replace(/^blob:[^/]+\//i, "").replace(/\\/g, "/"));
578
+ const transformed = url.replace(/^blob:[^/]+\//i, "").replace(/\\/g, "/");
579
+ console.log("PrefViewer: #transformUrl()", { in: url, out: transformed });
580
+ resolve(transformed);
527
581
  });
528
582
  }
529
583
 
530
584
  #decodeBase64(base64) {
585
+ console.log("PrefViewer: #decodeBase64() START");
531
586
  const [, payload] = base64.split(",");
532
587
  const raw = payload || base64;
533
588
  let decoded = "";
@@ -537,6 +592,7 @@ class PrefViewer extends HTMLElement {
537
592
  try {
538
593
  decoded = atob(raw);
539
594
  } catch {
595
+ console.warn("PrefViewer: base64 decode failed (not base64?)");
540
596
  return { blob, extension, size };
541
597
  }
542
598
  let isJson = false;
@@ -548,33 +604,43 @@ class PrefViewer extends HTMLElement {
548
604
  const type = isJson ? "model/gltf+json" : "model/gltf-binary";
549
605
  const array = Uint8Array.from(decoded, (c) => c.charCodeAt(0));
550
606
  blob = new Blob([array], { type });
607
+ console.log("PrefViewer: #decodeBase64() END", { extension, size, type });
551
608
  return { blob, extension, size };
552
609
  }
553
610
 
554
611
  async #initStorage(db, table) {
612
+ console.log("PrefViewer: #initStorage()", { db, table });
555
613
  if (window.gltfDB && window.gltfDB.name === db && window.gltfDB.objectStoreNames.contains(table)) {
614
+ console.log("PrefViewer: existing DB connection reused");
556
615
  return true;
557
616
  }
558
617
  await initDb(db, table);
618
+ console.log("PrefViewer: DB initialized");
559
619
  }
560
620
 
561
621
  // Methods for managing Asset Containers
562
622
  #setVisibilityOfWallAndFloorInModel(show) {
623
+ console.log("PrefViewer: #setVisibilityOfWallAndFloorInModel()", { incomingShow: show });
563
624
  if (!this.#data.containers.model.assetContainer || !this.#data.containers.model.visible) {
625
+ console.log("PrefViewer: no model assetContainer or not visible, skip visibility set");
564
626
  return false;
565
627
  }
566
628
  show = show !== undefined ? show : this.#data.containers.environment.visible;
567
629
  const prefixes = Object.values(this.#data.options.materials).map((material) => material.prefix);
630
+ console.log("PrefViewer: toggling meshes with prefixes", prefixes, "->", show);
568
631
  this.#data.containers.model.assetContainer.meshes.filter((meshToFilter) => prefixes.some((prefix) => meshToFilter.name.startsWith(prefix))).forEach((mesh) => mesh.setEnabled(show));
569
632
  }
570
633
 
571
634
  #setOptionsMaterial(optionMaterial) {
635
+ console.log("PrefViewer: #setOptionsMaterial()", { optionMaterial });
572
636
  if (!optionMaterial || !optionMaterial.prefix || !optionMaterial.value) {
637
+ console.log("PrefViewer: optionMaterial incomplete, skipping");
573
638
  return false;
574
639
  }
575
640
 
576
641
  const material = this.#data.containers.materials.assetContainer?.materials.find((mat) => mat.name === optionMaterial.value) || null;
577
642
  if (!material) {
643
+ console.warn("PrefViewer: material not found", optionMaterial.value);
578
644
  return false;
579
645
  }
580
646
 
@@ -586,6 +652,7 @@ class PrefViewer extends HTMLElement {
586
652
  containers.push(this.#data.containers.environment.assetContainer);
587
653
  }
588
654
  if (containers.length === 0) {
655
+ console.log("PrefViewer: no containers require material update");
589
656
  return false;
590
657
  }
591
658
 
@@ -599,6 +666,8 @@ class PrefViewer extends HTMLElement {
599
666
  })
600
667
  );
601
668
 
669
+ console.log("PrefViewer: material assignment result", { prefix: optionMaterial.prefix, material: optionMaterial.value, someSetted });
670
+
602
671
  if (someSetted) {
603
672
  optionMaterial.changed.success = true;
604
673
  } else {
@@ -609,15 +678,23 @@ class PrefViewer extends HTMLElement {
609
678
  }
610
679
 
611
680
  #setOptionsMaterials() {
681
+ console.log("PrefViewer: #setOptionsMaterials() START");
612
682
  let someSetted = false;
613
683
  Object.values(this.#data.options.materials).forEach((material) => {
614
684
  let settedMaterial = this.#setOptionsMaterial(material);
615
685
  someSetted = someSetted || settedMaterial;
616
686
  });
687
+ console.log("PrefViewer: #setOptionsMaterials() END", { someSetted });
617
688
  return someSetted;
618
689
  }
619
690
 
620
691
  #setOptionsCamera() {
692
+ console.log("PrefViewer: #setOptionsCamera()", {
693
+ requested: this.#data.options.camera.value,
694
+ changed: this.#data.options.camera.changed,
695
+ modelChanged: this.#data.containers.model.changed,
696
+ envChanged: this.#data.containers.environment.changed
697
+ });
621
698
  if (!this.#data.options.camera.value || (!this.#data.options.camera.changed && !this.#data.containers.model.changed && !this.#data.containers.environment.changed)) {
622
699
  return false;
623
700
  }
@@ -644,29 +721,36 @@ class PrefViewer extends HTMLElement {
644
721
  camera.attachControl(this.#canvas, true);
645
722
  }
646
723
  this.#scene.activeCamera = camera;
724
+ console.log("PrefViewer: active camera set", { name: camera.name, locked: camera.metadata?.locked });
647
725
  return true;
648
726
  }
649
727
 
650
728
  #addContainer(container) {
729
+ console.log("PrefViewer: #addContainer()", { name: container.name, hasContainer: !!container.assetContainer, visible: container.visible, show: container.show });
651
730
  if (container.assetContainer && !container.visible && container.show) {
652
731
  container.assetContainer.addAllToScene();
653
732
  container.visible = true;
733
+ console.log("PrefViewer: container added to scene", container.name);
654
734
  }
655
735
  }
656
736
 
657
737
  #removeContainer(container) {
738
+ console.log("PrefViewer: #removeContainer()", { name: container.name, hasContainer: !!container.assetContainer, visible: container.visible });
658
739
  if (container.assetContainer && container.visible) {
659
740
  container.assetContainer.removeAllFromScene();
660
741
  container.visible = false;
742
+ console.log("PrefViewer: container removed from scene", container.name);
661
743
  }
662
744
  }
663
745
 
664
746
  #replaceContainer(container, newAssetContainer) {
747
+ console.log("PrefViewer: #replaceContainer()", { name: container.name, hadContainer: !!container.assetContainer });
665
748
  // 1) quita y destruye el anterior si existía
666
749
  const old = container.assetContainer;
667
750
  if (old) {
668
751
  if (container.visible) { old.removeAllFromScene(); }
669
752
  old.dispose(); // <- importante
753
+ console.log("PrefViewer: old container disposed", container.name);
670
754
  }
671
755
 
672
756
  // 2) asigna el nuevo y prepara
@@ -690,12 +774,15 @@ class PrefViewer extends HTMLElement {
690
774
 
691
775
  // 5) fuerza recompilación con defines correctos del nuevo estado
692
776
  this.#scene.getEngine().releaseEffects();
777
+ console.log("PrefViewer: container replaced and effects released", container.name);
693
778
  }
694
779
 
695
780
  async #loadAssetContainer(container) {
781
+ console.log("PrefViewer: #loadAssetContainer() START", { name: container?.name, storage: container?.storage });
696
782
  let storage = container?.storage;
697
783
 
698
784
  if (!storage) {
785
+ console.log("PrefViewer: no storage, skipping", container?.name);
699
786
  return false;
700
787
  }
701
788
 
@@ -706,13 +793,16 @@ class PrefViewer extends HTMLElement {
706
793
  const object = await loadModel(storage.id, storage.table);
707
794
  source = object.data;
708
795
  if (object.timeStamp === container.timeStamp) {
796
+ console.log("PrefViewer: DB entry unchanged, skipping", container.name);
709
797
  return false;
710
798
  } else {
711
799
  container.changed = { timeStamp: object.timeStamp, size: object.size, success: false };
800
+ console.log("PrefViewer: DB entry changed", container.changed);
712
801
  }
713
802
  }
714
803
 
715
804
  if (!source) {
805
+ console.log("PrefViewer: no source after storage resolution", container.name);
716
806
  return false;
717
807
  }
718
808
 
@@ -725,19 +815,23 @@ class PrefViewer extends HTMLElement {
725
815
  });
726
816
  if (!container.changed) {
727
817
  if (container.timeStamp === null && container.size === size) {
818
+ console.log("PrefViewer: same base64 size and null timestamp, skipping", container.name);
728
819
  return false;
729
820
  } else {
730
821
  container.changed = { timeStamp: null, size: size, success: false };
731
822
  }
732
823
  }
824
+ console.log("PrefViewer: prepared File from base64", { name: file.name, size: file.size, type: file.type });
733
825
  } else {
734
826
  const extMatch = source.match(/\.(gltf|glb)(\?|#|$)/i);
735
827
  extension = extMatch ? `.${extMatch[1].toLowerCase()}` : ".gltf";
736
828
  const [fileSize, fileTimeStamp] = await this.#getServerFileDataHeader(source);
737
829
  if (container.size === fileSize && container.timeStamp === fileTimeStamp) {
830
+ console.log("PrefViewer: remote file unchanged, skipping", container.name);
738
831
  return false;
739
832
  } else {
740
833
  container.changed = { timeStamp: fileTimeStamp, size: fileSize, success: false };
834
+ console.log("PrefViewer: remote file changed", container.changed);
741
835
  }
742
836
  }
743
837
 
@@ -751,10 +845,12 @@ class PrefViewer extends HTMLElement {
751
845
  },
752
846
  };
753
847
 
848
+ console.log("PrefViewer: calling LoadAssetContainerAsync()", { extension });
754
849
  return LoadAssetContainerAsync(file || source, this.#scene, options);
755
850
  }
756
851
 
757
852
  async #loadContainers(loadModel = true, loadEnvironment = true, loadMaterials = true) {
853
+ console.log("PrefViewer: #loadContainers()", { loadModel, loadEnvironment, loadMaterials });
758
854
  const promiseArray = [];
759
855
  promiseArray.push(loadModel ? this.#loadAssetContainer(this.#data.containers.model) : false);
760
856
  promiseArray.push(loadEnvironment ? this.#loadAssetContainer(this.#data.containers.environment) : false);
@@ -764,27 +860,33 @@ class PrefViewer extends HTMLElement {
764
860
 
765
861
  Promise.allSettled(promiseArray)
766
862
  .then(async (values) => {
863
+ console.log("PrefViewer: Promise.allSettled results", values);
767
864
  const modelContainer = values[0];
768
865
  const environmentContainer = values[1];
769
866
  const materialsContainer = values[2];
770
867
 
771
868
  if (modelContainer.status === "fulfilled" && modelContainer.value) {
869
+ console.log("PrefViewer: model container fulfilled, applying");
772
870
  this.#stripImportedLights(modelContainer.value);
773
871
  this.#replaceContainer(this.#data.containers.model, modelContainer.value);
774
872
  this.#storeChangedFlagsForContainer(this.#data.containers.model);
775
873
  } else {
874
+ console.log("PrefViewer: model container not fulfilled or unchanged; ensuring visibility state");
776
875
  this.#data.containers.model.show ? this.#addContainer(this.#data.containers.model) : this.#removeContainer(this.#data.containers.model);
777
876
  }
778
877
 
779
878
  if (environmentContainer.status === "fulfilled" && environmentContainer.value) {
879
+ console.log("PrefViewer: environment container fulfilled, applying");
780
880
  this.#stripImportedLights(environmentContainer.value);
781
881
  this.#replaceContainer(this.#data.containers.environment, environmentContainer.value);
782
882
  this.#storeChangedFlagsForContainer(this.#data.containers.environment);
783
883
  } else {
884
+ console.log("PrefViewer: environment container not fulfilled or unchanged; ensuring visibility state");
784
885
  this.#data.containers.environment.show ? this.#addContainer(this.#data.containers.environment) : this.#removeContainer(this.#data.containers.environment);
785
886
  }
786
887
 
787
888
  if (materialsContainer.status === "fulfilled" && materialsContainer.value) {
889
+ console.log("PrefViewer: materials container fulfilled, applying");
788
890
  this.#stripImportedLights(materialsContainer.value);
789
891
  this.#replaceContainer(this.#data.containers.materials, materialsContainer.value);
790
892
  this.#storeChangedFlagsForContainer(this.#data.containers.materials);
@@ -811,17 +913,21 @@ class PrefViewer extends HTMLElement {
811
913
  }
812
914
 
813
915
  #stripImportedLights(container) {
916
+ console.log("PrefViewer: #stripImportedLights()", { lights: container?.lights?.length || 0 });
814
917
  // El glTF puede traer KHR_lights_punctual: bórralas antes de añadir a la escena
815
918
  if (container?.lights?.length) {
816
919
  // Clonar para no mutar mientras iteras
817
920
  container.lights.slice().forEach(l => l.dispose());
921
+ console.log("PrefViewer: stripped punctual lights from imported asset");
818
922
  }
819
923
  }
820
924
 
821
925
  // Public Methods
822
926
  loadConfig(config) {
927
+ console.log("PrefViewer: loadConfig()", config);
823
928
  config = typeof config === "string" ? JSON.parse(config) : config;
824
929
  if (!config) {
930
+ console.warn("PrefViewer: loadConfig() no config provided");
825
931
  return false;
826
932
  }
827
933
 
@@ -842,6 +948,7 @@ class PrefViewer extends HTMLElement {
842
948
  }
843
949
 
844
950
  setOptions(options) {
951
+ console.log("PrefViewer: setOptions()", options);
845
952
  if (!options) {
846
953
  return false;
847
954
  }
@@ -863,8 +970,10 @@ class PrefViewer extends HTMLElement {
863
970
  }
864
971
 
865
972
  loadModel(model) {
973
+ console.log("PrefViewer: loadModel()", model);
866
974
  model = typeof model === "string" ? JSON.parse(model) : model;
867
975
  if (!model) {
976
+ console.warn("PrefViewer: loadModel() no model provided");
868
977
  return false;
869
978
  }
870
979
  this.#data.containers.model.storage = model.storage || null;
@@ -873,8 +982,10 @@ class PrefViewer extends HTMLElement {
873
982
  }
874
983
 
875
984
  loadScene(scene) {
985
+ console.log("PrefViewer: loadScene()", scene);
876
986
  scene = typeof scene === "string" ? JSON.parse(scene) : scene;
877
987
  if (!scene) {
988
+ console.warn("PrefViewer: loadScene() no scene provided");
878
989
  return false;
879
990
  }
880
991
  this.#data.containers.environment.storage = scene.storage || null;
@@ -883,33 +994,39 @@ class PrefViewer extends HTMLElement {
883
994
  }
884
995
 
885
996
  showModel() {
997
+ console.log("PrefViewer: showModel()");
886
998
  this.#data.containers.model.show = true;
887
999
  this.#addContainer(this.#data.containers.model);
888
1000
  }
889
1001
 
890
1002
  hideModel() {
1003
+ console.log("PrefViewer: hideModel()");
891
1004
  this.#data.containers.model.show = false;
892
1005
  this.#removeContainer(this.#data.containers.model);
893
1006
  }
894
1007
 
895
1008
  showScene() {
1009
+ console.log("PrefViewer: showScene()");
896
1010
  this.#data.containers.environment.show = true;
897
1011
  this.#addContainer(this.#data.containers.environment);
898
1012
  this.#setVisibilityOfWallAndFloorInModel();
899
1013
  }
900
1014
 
901
1015
  hideScene() {
1016
+ console.log("PrefViewer: hideScene()");
902
1017
  this.#data.containers.environment.show = false;
903
1018
  this.#removeContainer(this.#data.containers.environment);
904
1019
  this.#setVisibilityOfWallAndFloorInModel();
905
1020
  }
906
1021
 
907
1022
  downloadModelGLB() {
1023
+ console.log("PrefViewer: downloadModelGLB()");
908
1024
  const fileName = "model";
909
1025
  GLTF2Export.GLBAsync(this.#data.containers.model.assetContainer, fileName, { exportWithoutWaitingForScene: true }).then((glb) => glb.downloadFiles());
910
1026
  }
911
1027
 
912
1028
  downloadModelUSDZ() {
1029
+ console.log("PrefViewer: downloadModelUSDZ()");
913
1030
  const fileName = "model";
914
1031
  USDZExportAsync(this.#data.containers.model.assetContainer).then((response) => {
915
1032
  if (response) {
@@ -919,6 +1036,7 @@ class PrefViewer extends HTMLElement {
919
1036
  }
920
1037
 
921
1038
  downloadModelAndSceneUSDZ() {
1039
+ console.log("PrefViewer: downloadModelAndSceneUSDZ()");
922
1040
  const fileName = "scene";
923
1041
  USDZExportAsync(this.#scene).then((response) => {
924
1042
  if (response) {
@@ -928,6 +1046,7 @@ class PrefViewer extends HTMLElement {
928
1046
  }
929
1047
 
930
1048
  downloadModelAndSceneGLB() {
1049
+ console.log("PrefViewer: downloadModelAndSceneGLB()");
931
1050
  const fileName = "scene";
932
1051
  GLTF2Export.GLBAsync(this.#scene, fileName, { exportWithoutWaitingForScene: true }).then((glb) => glb.downloadFiles());
933
1052
  }