@preference-sl/pref-viewer 2.10.0-beta.14 → 2.10.0-beta.15
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 +171 -46
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -47,7 +47,9 @@ import { DracoCompression } from "@babylonjs/core/Meshes/Compression/dracoCompre
|
|
|
47
47
|
import { initDb, loadModel } from "./gltf-storage.js";
|
|
48
48
|
|
|
49
49
|
class PrefViewer extends HTMLElement {
|
|
50
|
-
|
|
50
|
+
initialized = false;
|
|
51
|
+
loaded = false;
|
|
52
|
+
loading = false;
|
|
51
53
|
|
|
52
54
|
#data = {
|
|
53
55
|
containers: {
|
|
@@ -162,7 +164,7 @@ class PrefViewer extends HTMLElement {
|
|
|
162
164
|
break;
|
|
163
165
|
case "show-model":
|
|
164
166
|
data = value.toLowerCase?.() === "true";
|
|
165
|
-
if (this
|
|
167
|
+
if (this.initialized) {
|
|
166
168
|
data ? this.showModel() : this.hideModel();
|
|
167
169
|
} else {
|
|
168
170
|
this.#data.containers.model.show = data;
|
|
@@ -170,7 +172,7 @@ class PrefViewer extends HTMLElement {
|
|
|
170
172
|
break;
|
|
171
173
|
case "show-scene":
|
|
172
174
|
data = value.toLowerCase?.() === "true";
|
|
173
|
-
if (this
|
|
175
|
+
if (this.initialized) {
|
|
174
176
|
data ? this.showScene() : this.hideScene();
|
|
175
177
|
} else {
|
|
176
178
|
this.#data.containers.environment.show = data;
|
|
@@ -184,18 +186,19 @@ class PrefViewer extends HTMLElement {
|
|
|
184
186
|
const error = 'PrefViewer: provide "models" as array of model and environment';
|
|
185
187
|
console.error(error);
|
|
186
188
|
this.dispatchEvent(
|
|
187
|
-
new CustomEvent("
|
|
188
|
-
detail: { error: new Error(error) },
|
|
189
|
+
new CustomEvent("scene-error", {
|
|
189
190
|
bubbles: true,
|
|
191
|
+
cancelable: false,
|
|
190
192
|
composed: true,
|
|
193
|
+
detail: { error: new Error(error) },
|
|
191
194
|
})
|
|
192
195
|
);
|
|
193
196
|
return false;
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
this.#initializeBabylon();
|
|
200
|
+
this.initialized = true;
|
|
197
201
|
this.#loadContainers(true, true, true);
|
|
198
|
-
this.#initialized = true;
|
|
199
202
|
}
|
|
200
203
|
|
|
201
204
|
disconnectedCallback() {
|
|
@@ -225,14 +228,71 @@ class PrefViewer extends HTMLElement {
|
|
|
225
228
|
this.shadowRoot.append(this.#wrapper);
|
|
226
229
|
}
|
|
227
230
|
|
|
231
|
+
#setStatusSceneLoading(detail) {
|
|
232
|
+
this.loaded = false;
|
|
233
|
+
this.loading = true;
|
|
234
|
+
if (this.hasAttribute("loaded")) {
|
|
235
|
+
this.removeAttribute("loaded");
|
|
236
|
+
}
|
|
237
|
+
this.setAttribute("loading", "");
|
|
238
|
+
this.dispatchEvent(
|
|
239
|
+
new CustomEvent("scene-loading", {
|
|
240
|
+
bubbles: true,
|
|
241
|
+
cancelable: false,
|
|
242
|
+
composed: true,
|
|
243
|
+
detail: detail,
|
|
244
|
+
})
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
#setStatusSceneLoaded(detail) {
|
|
249
|
+
this.loaded = true;
|
|
250
|
+
this.loading = false;
|
|
251
|
+
if (this.hasAttribute("loading")) {
|
|
252
|
+
this.removeAttribute("loading");
|
|
253
|
+
}
|
|
254
|
+
this.setAttribute("loaded", "");
|
|
255
|
+
this.dispatchEvent(
|
|
256
|
+
new CustomEvent("scene-loaded", {
|
|
257
|
+
bubbles: true,
|
|
258
|
+
cancelable: false,
|
|
259
|
+
composed: true,
|
|
260
|
+
detail: detail,
|
|
261
|
+
})
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
#setStatusOptionsLoading(detail) {
|
|
266
|
+
this.dispatchEvent(
|
|
267
|
+
new CustomEvent("options-loading", {
|
|
268
|
+
bubbles: true,
|
|
269
|
+
cancelable: false,
|
|
270
|
+
composed: true,
|
|
271
|
+
detail: detail,
|
|
272
|
+
})
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
#setStatusOptionsLoaded(detail) {
|
|
277
|
+
this.dispatchEvent(
|
|
278
|
+
new CustomEvent("options-loaded", {
|
|
279
|
+
bubbles: true,
|
|
280
|
+
cancelable: false,
|
|
281
|
+
composed: true,
|
|
282
|
+
detail: detail,
|
|
283
|
+
})
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
228
287
|
// Data
|
|
229
288
|
#checkCameraChanged(options) {
|
|
230
289
|
if (!options || !options.camera) {
|
|
231
290
|
return false;
|
|
232
291
|
}
|
|
233
|
-
|
|
234
|
-
this.#data.options.camera.
|
|
235
|
-
|
|
292
|
+
const cameraChanged = options.camera && options.camera !== this.#data.options.camera.value ? true : false
|
|
293
|
+
this.#data.options.camera.changed = cameraChanged ? { oldValue: this.#data.options.camera.value, success: false } : false;
|
|
294
|
+
this.#data.options.camera.value = cameraChanged ? options.camera : this.#data.options.camera.value;
|
|
295
|
+
return cameraChanged;
|
|
236
296
|
}
|
|
237
297
|
|
|
238
298
|
#checkMaterialsChanged(options) {
|
|
@@ -242,8 +302,9 @@ class PrefViewer extends HTMLElement {
|
|
|
242
302
|
let someChanged = false;
|
|
243
303
|
Object.keys(this.#data.options.materials).forEach((material) => {
|
|
244
304
|
const key = `${material}Material`;
|
|
245
|
-
|
|
246
|
-
this.#data.options.materials[material].
|
|
305
|
+
const materialChanged = options[key] && options[key] !== this.#data.options.materials[material].value ? true : false;
|
|
306
|
+
this.#data.options.materials[material].changed = materialChanged ? { oldValue: this.#data.options.materials[material].value, success: false } : false;
|
|
307
|
+
this.#data.options.materials[material].value = materialChanged ? options[key] : this.#data.options.materials[material].value;
|
|
247
308
|
someChanged = someChanged || this.#data.options.materials[material].changed;
|
|
248
309
|
});
|
|
249
310
|
return someChanged;
|
|
@@ -252,6 +313,7 @@ class PrefViewer extends HTMLElement {
|
|
|
252
313
|
#storeChangedFlagsForContainer(container) {
|
|
253
314
|
container.timestamp = container.changed.timestamp;
|
|
254
315
|
container.size = container.changed.size;
|
|
316
|
+
container.changed.success = true;
|
|
255
317
|
}
|
|
256
318
|
|
|
257
319
|
#resetChangedFlags() {
|
|
@@ -340,8 +402,8 @@ class PrefViewer extends HTMLElement {
|
|
|
340
402
|
this.#camera.lowerRadiusLimit = 5;
|
|
341
403
|
this.#camera.upperRadiusLimit = 20;
|
|
342
404
|
this.#camera.metadata = { locked: false }
|
|
343
|
-
this.#camera = this.#camera;
|
|
344
405
|
this.#camera.attachControl(this.#canvas, true);
|
|
406
|
+
this.#scene.activeCamera = this.#camera;
|
|
345
407
|
}
|
|
346
408
|
|
|
347
409
|
#createLights() {
|
|
@@ -398,13 +460,13 @@ class PrefViewer extends HTMLElement {
|
|
|
398
460
|
if (xhr.status === 200) {
|
|
399
461
|
const size = parseInt(xhr.getResponseHeader("Content-Length"));
|
|
400
462
|
const timestamp = new Date(xhr.getResponseHeader("Last-Modified")).toISOString();
|
|
401
|
-
resolve(size, timestamp);
|
|
463
|
+
resolve([size, timestamp]);
|
|
402
464
|
} else {
|
|
403
|
-
resolve(0, null);
|
|
465
|
+
resolve([0, null]);
|
|
404
466
|
}
|
|
405
467
|
};
|
|
406
468
|
xhr.onerror = () => {
|
|
407
|
-
resolve(0, null);
|
|
469
|
+
resolve([0, null]);
|
|
408
470
|
};
|
|
409
471
|
xhr.send();
|
|
410
472
|
});
|
|
@@ -468,10 +530,10 @@ class PrefViewer extends HTMLElement {
|
|
|
468
530
|
}
|
|
469
531
|
|
|
470
532
|
const containers = [];
|
|
471
|
-
if (this.#data.containers.model.assetContainer && (this.#data.containers.model.
|
|
533
|
+
if (this.#data.containers.model.assetContainer && (this.#data.containers.model.changed || optionMaterial.changed)) {
|
|
472
534
|
containers.push(this.#data.containers.model.assetContainer);
|
|
473
535
|
}
|
|
474
|
-
if (this.#data.containers.environment.assetContainer && (this.#data.containers.environment.
|
|
536
|
+
if (this.#data.containers.environment.assetContainer && (this.#data.containers.environment.changed || optionMaterial.changed)) {
|
|
475
537
|
containers.push(this.#data.containers.environment.assetContainer);
|
|
476
538
|
}
|
|
477
539
|
if (containers.length === 0) {
|
|
@@ -488,6 +550,12 @@ class PrefViewer extends HTMLElement {
|
|
|
488
550
|
})
|
|
489
551
|
);
|
|
490
552
|
|
|
553
|
+
if (someSetted) {
|
|
554
|
+
optionMaterial.changed.success = true;
|
|
555
|
+
} else {
|
|
556
|
+
optionMaterial.value = optionMaterial.changed.oldValue;
|
|
557
|
+
}
|
|
558
|
+
|
|
491
559
|
return someSetted;
|
|
492
560
|
}
|
|
493
561
|
|
|
@@ -501,21 +569,32 @@ class PrefViewer extends HTMLElement {
|
|
|
501
569
|
}
|
|
502
570
|
|
|
503
571
|
#setOptionsCamera() {
|
|
504
|
-
if (!this.#data.options.camera.value || (!this.#data.options.camera.changed && !this.#data.containers.model.
|
|
572
|
+
if (!this.#data.options.camera.value || (!this.#data.options.camera.changed && !this.#data.containers.model.changed && !this.#data.containers.environment.changed)) {
|
|
505
573
|
return false;
|
|
506
574
|
}
|
|
507
575
|
|
|
508
|
-
let camera = this.#data.containers.model.assetContainer?.cameras.find((
|
|
576
|
+
let camera = this.#data.containers.model.assetContainer?.cameras.find((thisCamera) => thisCamera.name === this.#data.options.camera.value) || this.#data.containers.environment.assetContainer?.cameras.find((thisCamera) => thisCamera.name === this.#data.options.camera.value) || null;
|
|
509
577
|
if (!camera) {
|
|
510
|
-
|
|
578
|
+
if (this.#data.options.camera.changed?.oldValue && this.#data.options.camera.changed?.oldValue !== this.#data.options.camera.value) {
|
|
579
|
+
camera = this.#data.containers.model.assetContainer?.cameras.find((thisCamera) => thisCamera.name === this.#data.options.camera.changed.oldValue) || this.#data.containers.environment.assetContainer?.cameras.find((thisCamera) => thisCamera.name === his.#data.options.camera.changed.oldValue) || null;
|
|
580
|
+
}
|
|
581
|
+
if (camera){
|
|
582
|
+
camera.metadata = { locked: this.#data.options.camera.changed.oldLocked };
|
|
583
|
+
this.#data.options.camera.value = this.#data.options.camera.changed.oldValue;
|
|
584
|
+
this.#data.options.camera.locked = this.#data.options.camera.changed.oldLocked;
|
|
585
|
+
} else {
|
|
586
|
+
camera = this.#camera;
|
|
587
|
+
this.#data.options.camera.value = null;
|
|
588
|
+
this.#data.options.camera.locked = this.#camera.metadata.locked;
|
|
589
|
+
}
|
|
590
|
+
this.#data.options.camera.changed.success = false;
|
|
591
|
+
} else {
|
|
592
|
+
camera.metadata = { locked: this.#data.options.camera.locked };
|
|
511
593
|
}
|
|
512
|
-
|
|
513
|
-
camera.metadata = { locked: this.#data.options.camera.locked };
|
|
514
|
-
if (!this.#data.options.camera.locked) {
|
|
594
|
+
if (!this.#data.options.camera.locked && this.#data.options.camera.value !== null) {
|
|
515
595
|
camera.attachControl(this.#canvas, true);
|
|
516
596
|
}
|
|
517
597
|
this.#scene.activeCamera = camera;
|
|
518
|
-
|
|
519
598
|
return true;
|
|
520
599
|
}
|
|
521
600
|
|
|
@@ -559,7 +638,7 @@ class PrefViewer extends HTMLElement {
|
|
|
559
638
|
if (object.timestamp === container.timestamp) {
|
|
560
639
|
return false;
|
|
561
640
|
} else {
|
|
562
|
-
container.changed = { timestamp: object.timestamp, size: object.size };
|
|
641
|
+
container.changed = { timestamp: object.timestamp, size: object.size, success: false };
|
|
563
642
|
}
|
|
564
643
|
}
|
|
565
644
|
|
|
@@ -578,17 +657,17 @@ class PrefViewer extends HTMLElement {
|
|
|
578
657
|
if (container.timestamp === null && container.size === size) {
|
|
579
658
|
return false;
|
|
580
659
|
} else {
|
|
581
|
-
container.changed = { timestamp: null, size: size };
|
|
660
|
+
container.changed = { timestamp: null, size: size, success: false };
|
|
582
661
|
}
|
|
583
662
|
}
|
|
584
663
|
} else {
|
|
585
664
|
const extMatch = source.match(/\.(gltf|glb)(\?|#|$)/i);
|
|
586
665
|
extension = extMatch ? `.${extMatch[1].toLowerCase()}` : ".gltf";
|
|
587
|
-
const
|
|
588
|
-
if (container.
|
|
666
|
+
const [fileSize, fileTimestamp ] = await this.#getServerFileDataHeader(source);
|
|
667
|
+
if (container.size === fileSize && container.timestamp === fileTimestamp) {
|
|
589
668
|
return false;
|
|
590
669
|
} else {
|
|
591
|
-
container.changed = { timestamp: fileTimestamp, size: fileSize };
|
|
670
|
+
container.changed = { timestamp: fileTimestamp, size: fileSize, success: false };
|
|
592
671
|
}
|
|
593
672
|
}
|
|
594
673
|
|
|
@@ -605,12 +684,26 @@ class PrefViewer extends HTMLElement {
|
|
|
605
684
|
return LoadAssetContainerAsync(file || source, this.#scene, options);
|
|
606
685
|
}
|
|
607
686
|
|
|
608
|
-
async #loadContainers(loadModel = true, loadEnvironment = true, loadMaterials = true) {
|
|
687
|
+
async #loadContainers(loadModel = true, loadEnvironment = true, loadMaterials = true) {
|
|
609
688
|
const promiseArray = [];
|
|
610
689
|
promiseArray.push(loadModel ? this.#loadAssetContainer(this.#data.containers.model) : false);
|
|
611
690
|
promiseArray.push(loadEnvironment ? this.#loadAssetContainer(this.#data.containers.environment) : false);
|
|
612
691
|
promiseArray.push(loadMaterials ? this.#loadAssetContainer(this.#data.containers.materials) : false);
|
|
613
692
|
|
|
693
|
+
const loadingDetail = {
|
|
694
|
+
model: !!this.#data.containers.model.changed,
|
|
695
|
+
environment: !!this.#data.containers.environment.changed,
|
|
696
|
+
materials: !!this.#data.containers.materials.changed,
|
|
697
|
+
options: {
|
|
698
|
+
camera: !!this.#data.options.camera.changed,
|
|
699
|
+
inneWallMaterial: !!this.#data.options.materials.innerWall.changed,
|
|
700
|
+
outerWallMaterial: !!this.#data.options.materials.outerWall.changed,
|
|
701
|
+
innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed,
|
|
702
|
+
outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed,
|
|
703
|
+
},
|
|
704
|
+
};
|
|
705
|
+
this.#setStatusSceneLoading(loadingDetail);
|
|
706
|
+
|
|
614
707
|
Promise.allSettled(promiseArray)
|
|
615
708
|
.then(async (values) => {
|
|
616
709
|
const modelContainer = values[0];
|
|
@@ -639,24 +732,33 @@ class PrefViewer extends HTMLElement {
|
|
|
639
732
|
this.#setOptionsMaterials();
|
|
640
733
|
this.#setOptionsCamera();
|
|
641
734
|
this.#setVisibilityOfWallAndFloorInModel();
|
|
735
|
+
|
|
736
|
+
const loadedDetail = {
|
|
737
|
+
model: !!this.#data.containers.model.changed?.success,
|
|
738
|
+
environment: !!this.#data.containers.environment.changed?.success,
|
|
739
|
+
materials: !!this.#data.containers.materials.changed?.success,
|
|
740
|
+
options: {
|
|
741
|
+
camera: !!this.#data.options.camera.changed?.success,
|
|
742
|
+
inneWallMaterial: !!this.#data.options.materials.innerWall.changed?.success,
|
|
743
|
+
outerWallMaterial: !!this.#data.options.materials.outerWall.changed?.success,
|
|
744
|
+
innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed?.success,
|
|
745
|
+
outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed?.success,
|
|
746
|
+
},
|
|
747
|
+
};
|
|
748
|
+
|
|
749
|
+
this.#setStatusSceneLoaded(loadedDetail);
|
|
642
750
|
|
|
643
751
|
this.#resetChangedFlags();
|
|
644
|
-
|
|
645
|
-
this.dispatchEvent(
|
|
646
|
-
new CustomEvent("model-loaded", {
|
|
647
|
-
detail: { success: "" },
|
|
648
|
-
bubbles: true,
|
|
649
|
-
composed: true,
|
|
650
|
-
})
|
|
651
|
-
);
|
|
652
752
|
})
|
|
653
753
|
.catch((error) => {
|
|
754
|
+
this.loaded = true;
|
|
654
755
|
console.error("PrefViewer: failed to load model", error);
|
|
655
756
|
this.dispatchEvent(
|
|
656
|
-
new CustomEvent("
|
|
657
|
-
detail: { error: error },
|
|
757
|
+
new CustomEvent("scene-error", {
|
|
658
758
|
bubbles: true,
|
|
759
|
+
cancelable: false,
|
|
659
760
|
composed: true,
|
|
761
|
+
detail: { error: error },
|
|
660
762
|
})
|
|
661
763
|
);
|
|
662
764
|
});
|
|
@@ -682,22 +784,45 @@ class PrefViewer extends HTMLElement {
|
|
|
682
784
|
this.#checkMaterialsChanged(config.options);
|
|
683
785
|
}
|
|
684
786
|
|
|
685
|
-
this
|
|
787
|
+
this.initialized && this.#loadContainers(true, true, true);
|
|
686
788
|
}
|
|
687
789
|
|
|
688
790
|
setOptions(options) {
|
|
689
791
|
if (!options) {
|
|
690
792
|
return false;
|
|
691
793
|
}
|
|
794
|
+
|
|
795
|
+
const cameraChanged = this.#checkCameraChanged(options);
|
|
796
|
+
const materialsChanged = this.#checkMaterialsChanged(options);
|
|
797
|
+
|
|
798
|
+
const loadingDetail = {
|
|
799
|
+
camera: !!this.#data.options.camera.changed,
|
|
800
|
+
inneWallMaterial: !!this.#data.options.materials.innerWall.changed,
|
|
801
|
+
outerWallMaterial: !!this.#data.options.materials.outerWall.changed,
|
|
802
|
+
innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed,
|
|
803
|
+
outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed,
|
|
804
|
+
};
|
|
805
|
+
this.#setStatusOptionsLoading(loadingDetail);
|
|
806
|
+
|
|
692
807
|
let someSetted = false;
|
|
693
|
-
if (
|
|
808
|
+
if (cameraChanged) {
|
|
694
809
|
someSetted = someSetted || this.#setOptionsCamera();
|
|
695
810
|
}
|
|
696
|
-
if (
|
|
811
|
+
if (materialsChanged) {
|
|
697
812
|
someSetted = someSetted || this.#setOptionsMaterials();
|
|
698
813
|
}
|
|
814
|
+
|
|
815
|
+
const loadedDetail = {
|
|
816
|
+
camera: !!this.#data.options.camera.changed?.success,
|
|
817
|
+
inneWallMaterial: !!this.#data.options.materials.innerWall.changed?.success,
|
|
818
|
+
outerWallMaterial: !!this.#data.options.materials.outerWall.changed?.success,
|
|
819
|
+
innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed?.success,
|
|
820
|
+
outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed?.success,
|
|
821
|
+
};
|
|
822
|
+
this.#setStatusOptionsLoaded(loadedDetail);
|
|
823
|
+
|
|
699
824
|
this.#resetChangedFlags();
|
|
700
|
-
|
|
825
|
+
|
|
701
826
|
return someSetted;
|
|
702
827
|
}
|
|
703
828
|
|
|
@@ -708,7 +833,7 @@ class PrefViewer extends HTMLElement {
|
|
|
708
833
|
}
|
|
709
834
|
this.#data.containers.model.storage = model.storage || null;
|
|
710
835
|
this.#data.containers.model.show = model.visible !== undefined ? model.visible : this.#data.containers.model.show;
|
|
711
|
-
this
|
|
836
|
+
this.initialized && this.#loadContainers(true, false, false);
|
|
712
837
|
}
|
|
713
838
|
|
|
714
839
|
loadScene(scene) {
|
|
@@ -718,7 +843,7 @@ class PrefViewer extends HTMLElement {
|
|
|
718
843
|
}
|
|
719
844
|
this.#data.containers.environment.storage = scene.storage || null;
|
|
720
845
|
this.#data.containers.environment.show = scene.visible !== undefined ? scene.visible : this.#data.containers.environment.show;
|
|
721
|
-
this
|
|
846
|
+
this.initialized && this.#loadContainers(false, true, false);
|
|
722
847
|
}
|
|
723
848
|
|
|
724
849
|
showModel() {
|