@preference-sl/pref-viewer 2.10.0-beta.28 → 2.10.0-beta.29
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 +163 -96
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -46,10 +46,40 @@ import "@babylonjs/loaders/glTF/2.0/Extensions/KHR_draco_mesh_compression";
|
|
|
46
46
|
import { DracoCompression } from "@babylonjs/core/Meshes/Compression/dracoCompression";
|
|
47
47
|
import { initDb, loadModel } from "./gltf-storage.js";
|
|
48
48
|
|
|
49
|
+
class PrefViewerTask {
|
|
50
|
+
static Types = Object.freeze({
|
|
51
|
+
Config: "config",
|
|
52
|
+
Environment: "environment",
|
|
53
|
+
Materials: "materials",
|
|
54
|
+
Model: "model",
|
|
55
|
+
Options: "options",
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* value: any payload for the task
|
|
60
|
+
* type: must match one of PrefViewerTask.Types values (case-insensitive)
|
|
61
|
+
*/
|
|
62
|
+
constructor(value, type) {
|
|
63
|
+
this.value = value;
|
|
64
|
+
|
|
65
|
+
const t = typeof type === "string" ? type.toLowerCase() : String(type).toLowerCase();
|
|
66
|
+
const allowed = Object.values(PrefViewerTask.Types);
|
|
67
|
+
if (!allowed.includes(t)) {
|
|
68
|
+
throw new TypeError(
|
|
69
|
+
`PrefViewerTask: invalid type "${type}". Allowed types: ${allowed.join(", ")}`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
this.type = t;
|
|
73
|
+
|
|
74
|
+
Object.freeze(this);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
49
78
|
class PrefViewer extends HTMLElement {
|
|
50
79
|
initialized = false;
|
|
51
80
|
loaded = false;
|
|
52
81
|
loading = false;
|
|
82
|
+
#taskQueue = [];
|
|
53
83
|
|
|
54
84
|
#data = {
|
|
55
85
|
containers: {
|
|
@@ -162,6 +192,12 @@ class PrefViewer extends HTMLElement {
|
|
|
162
192
|
case "scene":
|
|
163
193
|
this.loadScene(value);
|
|
164
194
|
break;
|
|
195
|
+
case "materials":
|
|
196
|
+
this.loadMaterials(value);
|
|
197
|
+
break;
|
|
198
|
+
case "options":
|
|
199
|
+
this.setOptions(value);
|
|
200
|
+
break;
|
|
165
201
|
case "show-model":
|
|
166
202
|
data = value.toLowerCase?.() === "true";
|
|
167
203
|
if (this.initialized) {
|
|
@@ -198,7 +234,7 @@ class PrefViewer extends HTMLElement {
|
|
|
198
234
|
|
|
199
235
|
this.#initializeBabylon();
|
|
200
236
|
this.initialized = true;
|
|
201
|
-
this.#
|
|
237
|
+
this.#processNextTask();
|
|
202
238
|
}
|
|
203
239
|
|
|
204
240
|
disconnectedCallback() {
|
|
@@ -228,7 +264,7 @@ class PrefViewer extends HTMLElement {
|
|
|
228
264
|
this.shadowRoot.append(this.#wrapper);
|
|
229
265
|
}
|
|
230
266
|
|
|
231
|
-
#
|
|
267
|
+
#setStatusLoading() {
|
|
232
268
|
this.loaded = false;
|
|
233
269
|
this.loading = true;
|
|
234
270
|
if (this.hasAttribute("loaded")) {
|
|
@@ -242,12 +278,10 @@ class PrefViewer extends HTMLElement {
|
|
|
242
278
|
composed: true,
|
|
243
279
|
})
|
|
244
280
|
);
|
|
281
|
+
this.#engine.stopRenderLoop(this.#renderLoop);
|
|
245
282
|
}
|
|
246
283
|
|
|
247
|
-
#
|
|
248
|
-
this.loaded = true;
|
|
249
|
-
this.loading = false;
|
|
250
|
-
|
|
284
|
+
async #setStatusLoaded() {
|
|
251
285
|
const toLoadDetail = {
|
|
252
286
|
container_model: !!this.#data.containers.model.changed.pending,
|
|
253
287
|
container_environment: !!this.#data.containers.environment.changed.pending,
|
|
@@ -268,16 +302,11 @@ class PrefViewer extends HTMLElement {
|
|
|
268
302
|
options_innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed.success,
|
|
269
303
|
options_outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed.success,
|
|
270
304
|
};
|
|
271
|
-
|
|
272
305
|
const detail = {
|
|
273
306
|
tried: toLoadDetail,
|
|
274
307
|
success: loadedDetail,
|
|
275
308
|
};
|
|
276
|
-
|
|
277
|
-
if (this.hasAttribute("loading")) {
|
|
278
|
-
this.removeAttribute("loading");
|
|
279
|
-
}
|
|
280
|
-
this.setAttribute("loaded", "");
|
|
309
|
+
|
|
281
310
|
this.dispatchEvent(
|
|
282
311
|
new CustomEvent("scene-loaded", {
|
|
283
312
|
bubbles: true,
|
|
@@ -286,49 +315,21 @@ class PrefViewer extends HTMLElement {
|
|
|
286
315
|
detail: detail,
|
|
287
316
|
})
|
|
288
317
|
);
|
|
289
|
-
this.#resetChangedFlags();
|
|
290
|
-
}
|
|
291
318
|
|
|
292
|
-
|
|
293
|
-
this.
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
cancelable: false,
|
|
297
|
-
composed: true,
|
|
298
|
-
})
|
|
299
|
-
);
|
|
300
|
-
}
|
|
319
|
+
await this.#scene.whenReadyAsync();
|
|
320
|
+
this.#engine.runRenderLoop(this.#renderLoop);
|
|
321
|
+
|
|
322
|
+
this.#resetChangedFlags();
|
|
301
323
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
outerWallMaterial: !!this.#data.options.materials.outerWall.changed.pending,
|
|
307
|
-
innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed.pending,
|
|
308
|
-
outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed.pending,
|
|
309
|
-
};
|
|
310
|
-
const loadedDetail = {
|
|
311
|
-
camera: !!this.#data.options.camera.changed.success,
|
|
312
|
-
innerWallMaterial: !!this.#data.options.materials.innerWall.changed.success,
|
|
313
|
-
outerWallMaterial: !!this.#data.options.materials.outerWall.changed.success,
|
|
314
|
-
innerFloorMaterial: !!this.#data.options.materials.innerFloor.changed.success,
|
|
315
|
-
outerFloorMaterial: !!this.#data.options.materials.outerFloor.changed.success,
|
|
316
|
-
};
|
|
324
|
+
if (this.hasAttribute("loading")) {
|
|
325
|
+
this.removeAttribute("loading");
|
|
326
|
+
}
|
|
327
|
+
this.setAttribute("loaded", "");
|
|
317
328
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
success: loadedDetail,
|
|
321
|
-
};
|
|
329
|
+
this.loaded = true;
|
|
330
|
+
this.loading = false;
|
|
322
331
|
|
|
323
|
-
this
|
|
324
|
-
new CustomEvent("options-loaded", {
|
|
325
|
-
bubbles: true,
|
|
326
|
-
cancelable: false,
|
|
327
|
-
composed: true,
|
|
328
|
-
detail: detail,
|
|
329
|
-
})
|
|
330
|
-
);
|
|
331
|
-
this.#resetChangedFlags();
|
|
332
|
+
this.#processNextTask();
|
|
332
333
|
}
|
|
333
334
|
|
|
334
335
|
// Data
|
|
@@ -771,17 +772,23 @@ class PrefViewer extends HTMLElement {
|
|
|
771
772
|
}
|
|
772
773
|
|
|
773
774
|
#addContainer(container) {
|
|
774
|
-
if (container.assetContainer
|
|
775
|
-
|
|
776
|
-
container.visible = true;
|
|
775
|
+
if (!container.assetContainer || container.visible || !container.show) {
|
|
776
|
+
return false;
|
|
777
777
|
}
|
|
778
|
+
|
|
779
|
+
container.assetContainer.addAllToScene();
|
|
780
|
+
container.visible = true;
|
|
781
|
+
return true;
|
|
778
782
|
}
|
|
779
783
|
|
|
780
784
|
#removeContainer(container) {
|
|
781
|
-
if (container.assetContainer
|
|
782
|
-
|
|
783
|
-
container.visible = false;
|
|
785
|
+
if (!container.assetContainer || !container.visible) {
|
|
786
|
+
return false;
|
|
784
787
|
}
|
|
788
|
+
|
|
789
|
+
container.assetContainer.removeAllFromScene();
|
|
790
|
+
container.visible = false;
|
|
791
|
+
return true;
|
|
785
792
|
}
|
|
786
793
|
|
|
787
794
|
#replaceContainer(container, newAssetContainer) {
|
|
@@ -793,6 +800,7 @@ class PrefViewer extends HTMLElement {
|
|
|
793
800
|
this.#scene.getEngine().releaseEffects();
|
|
794
801
|
container.assetContainer = newAssetContainer;
|
|
795
802
|
this.#addContainer(container);
|
|
803
|
+
return true;
|
|
796
804
|
}
|
|
797
805
|
|
|
798
806
|
async #loadAssetContainer(container) {
|
|
@@ -864,7 +872,6 @@ class PrefViewer extends HTMLElement {
|
|
|
864
872
|
}
|
|
865
873
|
|
|
866
874
|
async #loadContainers(loadModel = true, loadEnvironment = true, loadMaterials = true) {
|
|
867
|
-
this.#setStatusSceneLoading();
|
|
868
875
|
this.#engine.stopRenderLoop(this.#renderLoop);
|
|
869
876
|
|
|
870
877
|
const promiseArray = [];
|
|
@@ -873,7 +880,7 @@ class PrefViewer extends HTMLElement {
|
|
|
873
880
|
promiseArray.push(loadMaterials ? this.#loadAssetContainer(this.#data.containers.materials) : false);
|
|
874
881
|
|
|
875
882
|
Promise.allSettled(promiseArray)
|
|
876
|
-
.then(
|
|
883
|
+
.then((values) => {
|
|
877
884
|
const modelContainer = values[0];
|
|
878
885
|
const environmentContainer = values[1];
|
|
879
886
|
const materialsContainer = values[2];
|
|
@@ -906,7 +913,6 @@ class PrefViewer extends HTMLElement {
|
|
|
906
913
|
this.#storeChangedFlagsForContainer(this.#data.containers.materials, false);
|
|
907
914
|
}
|
|
908
915
|
|
|
909
|
-
await this.#scene.whenReadyAsync();
|
|
910
916
|
this.#setOptionsMaterials();
|
|
911
917
|
this.#setOptionsCamera();
|
|
912
918
|
this.#setVisibilityOfWallAndFloorInModel();
|
|
@@ -923,24 +929,51 @@ class PrefViewer extends HTMLElement {
|
|
|
923
929
|
})
|
|
924
930
|
);
|
|
925
931
|
})
|
|
926
|
-
.finally(() => {
|
|
932
|
+
.finally(async () => {
|
|
927
933
|
this.#setMaxSimultaneousLights();
|
|
928
934
|
this.#initShadows();
|
|
929
|
-
this.#
|
|
930
|
-
this.#engine.runRenderLoop(this.#renderLoop);
|
|
935
|
+
await this.#setStatusLoaded();
|
|
931
936
|
});
|
|
932
937
|
}
|
|
933
938
|
|
|
934
|
-
//
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
if (!
|
|
939
|
+
// Tasks
|
|
940
|
+
#addTaskToQueue(value, type) {
|
|
941
|
+
this.#taskQueue.push(new PrefViewerTask(value, type));
|
|
942
|
+
if (this.initialized && !this.loading) {
|
|
943
|
+
this.#processNextTask();
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
#processNextTask() {
|
|
948
|
+
if (!this.#taskQueue.length) {
|
|
938
949
|
return false;
|
|
939
950
|
}
|
|
951
|
+
const task = this.#taskQueue[0];
|
|
952
|
+
this.#taskQueue.shift();
|
|
953
|
+
switch (task.type) {
|
|
954
|
+
case PrefViewerTask.Types.Config:
|
|
955
|
+
this.#processConfig(task.value);
|
|
956
|
+
break;
|
|
957
|
+
case PrefViewerTask.Types.Model:
|
|
958
|
+
this.#processModel(task.value);
|
|
959
|
+
break;
|
|
960
|
+
case PrefViewerTask.Types.Environment:
|
|
961
|
+
this.#processEnvironment(task.value);
|
|
962
|
+
break;
|
|
963
|
+
case PrefViewerTask.Types.Materials:
|
|
964
|
+
this.#processMaterials(task.value);
|
|
965
|
+
break;
|
|
966
|
+
case PrefViewerTask.Types.Options:
|
|
967
|
+
this.#processOptions(task.value);
|
|
968
|
+
break;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
#processConfig(config) {
|
|
973
|
+
this.#setStatusLoading();
|
|
940
974
|
|
|
941
975
|
// Containers
|
|
942
976
|
const loadModel = !!config.model?.storage;
|
|
943
|
-
// CHANGED: marcar pending, no boolean
|
|
944
977
|
this.#data.containers.model.changed.pending = loadModel;
|
|
945
978
|
this.#data.containers.model.changed.success = false;
|
|
946
979
|
this.#data.containers.model.changed.storage = this.#data.containers.model.storage;
|
|
@@ -966,15 +999,49 @@ class PrefViewer extends HTMLElement {
|
|
|
966
999
|
this.#checkMaterialsChanged(config.options);
|
|
967
1000
|
}
|
|
968
1001
|
|
|
969
|
-
this
|
|
1002
|
+
this.#loadContainers(loadModel, loadEnvironment, loadMaterials);
|
|
970
1003
|
}
|
|
971
1004
|
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
1005
|
+
#processModel(model) {
|
|
1006
|
+
this.#setStatusLoading();
|
|
1007
|
+
|
|
1008
|
+
const loadModel = !!model.storage;
|
|
1009
|
+
this.#data.containers.model.changed.pending = loadModel;
|
|
1010
|
+
this.#data.containers.model.changed.success = false;
|
|
1011
|
+
this.#data.containers.model.changed.storage = this.#data.containers.model.storage;
|
|
1012
|
+
this.#data.containers.model.storage = loadModel ? model.storage : this.#data.containers.model.storage;
|
|
1013
|
+
this.#data.containers.model.show = model.visible !== undefined ? model.visible : this.#data.containers.model.show;
|
|
1014
|
+
|
|
1015
|
+
this.initialized && this.#loadContainers(loadModel, false, false);
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
#processEnvironment(environment) {
|
|
1019
|
+
this.#setStatusLoading();
|
|
1020
|
+
|
|
1021
|
+
const loadEnvironment = !!environment.storage;
|
|
1022
|
+
this.#data.containers.environment.changed.pending = loadEnvironment;
|
|
1023
|
+
this.#data.containers.environment.changed.success = false;
|
|
1024
|
+
this.#data.containers.environment.changed.storage = this.#data.containers.environment.storage;
|
|
1025
|
+
this.#data.containers.environment.storage = loadEnvironment ? environment.storage : this.#data.containers.environment.storage;
|
|
1026
|
+
this.#data.containers.environment.show = environment.visible !== undefined ? environment.visible : this.#data.containers.environment.show;
|
|
1027
|
+
|
|
1028
|
+
this.#loadContainers(false, loadEnvironment, false);
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
#processMaterials(materials) {
|
|
1032
|
+
this.#setStatusLoading();
|
|
1033
|
+
|
|
1034
|
+
const loadMaterials = !!materials.storage;
|
|
1035
|
+
this.#data.containers.materials.changed.pending = loadMaterials;
|
|
1036
|
+
this.#data.containers.materials.changed.success = false;
|
|
1037
|
+
this.#data.containers.materials.changed.storage = this.#data.containers.materials.storage;
|
|
1038
|
+
this.#data.containers.materials.storage = loadMaterials ? materials.storage : this.#data.containers.materials.storage;
|
|
1039
|
+
|
|
1040
|
+
this.#loadContainers(false, false, loadMaterials);
|
|
1041
|
+
}
|
|
976
1042
|
|
|
977
|
-
|
|
1043
|
+
async #processOptions(options) {
|
|
1044
|
+
this.#setStatusLoading();
|
|
978
1045
|
|
|
979
1046
|
let someSetted = false;
|
|
980
1047
|
if (this.#checkCameraChanged(options)) {
|
|
@@ -983,24 +1050,27 @@ class PrefViewer extends HTMLElement {
|
|
|
983
1050
|
if (this.#checkMaterialsChanged(options)) {
|
|
984
1051
|
someSetted = someSetted || this.#setOptionsMaterials();
|
|
985
1052
|
}
|
|
986
|
-
|
|
987
|
-
this.#
|
|
1053
|
+
|
|
1054
|
+
await this.#setStatusLoaded();
|
|
988
1055
|
|
|
989
1056
|
return someSetted;
|
|
990
1057
|
}
|
|
991
1058
|
|
|
1059
|
+
// Public Methods
|
|
1060
|
+
loadConfig(config) {
|
|
1061
|
+
config = typeof config === "string" ? JSON.parse(config) : config;
|
|
1062
|
+
if (!config) {
|
|
1063
|
+
return false;
|
|
1064
|
+
}
|
|
1065
|
+
this.#addTaskToQueue(config, "config");
|
|
1066
|
+
}
|
|
1067
|
+
|
|
992
1068
|
loadModel(model) {
|
|
993
1069
|
model = typeof model === "string" ? JSON.parse(model) : model;
|
|
994
1070
|
if (!model) {
|
|
995
1071
|
return false;
|
|
996
1072
|
}
|
|
997
|
-
|
|
998
|
-
this.#data.containers.model.changed.pending = loadModel;
|
|
999
|
-
this.#data.containers.model.changed.success = false;
|
|
1000
|
-
this.#data.containers.model.changed.storage = this.#data.containers.model.storage;
|
|
1001
|
-
this.#data.containers.model.storage = loadModel ? model.storage : this.#data.containers.model.storage;
|
|
1002
|
-
this.#data.containers.model.show = model.visible !== undefined ? model.visible : this.#data.containers.model.show;
|
|
1003
|
-
this.initialized && this.#loadContainers(loadModel, false, false);
|
|
1073
|
+
this.#addTaskToQueue(model, "model");
|
|
1004
1074
|
}
|
|
1005
1075
|
|
|
1006
1076
|
loadScene(scene) {
|
|
@@ -1008,13 +1078,7 @@ class PrefViewer extends HTMLElement {
|
|
|
1008
1078
|
if (!scene) {
|
|
1009
1079
|
return false;
|
|
1010
1080
|
}
|
|
1011
|
-
|
|
1012
|
-
this.#data.containers.environment.changed.pending = loadEnvironment;
|
|
1013
|
-
this.#data.containers.environment.changed.success = false;
|
|
1014
|
-
this.#data.containers.environment.changed.storage = this.#data.containers.environment.storage;
|
|
1015
|
-
this.#data.containers.environment.storage = loadEnvironment ? scene.storage : this.#data.containers.environment.storage;
|
|
1016
|
-
this.#data.containers.environment.show = scene.visible !== undefined ? scene.visible : this.#data.containers.environment.show;
|
|
1017
|
-
this.initialized && this.#loadContainers(false, loadEnvironment, false);
|
|
1081
|
+
this.#addTaskToQueue(scene, "environment");
|
|
1018
1082
|
}
|
|
1019
1083
|
|
|
1020
1084
|
loadMaterials(materials) {
|
|
@@ -1022,12 +1086,15 @@ class PrefViewer extends HTMLElement {
|
|
|
1022
1086
|
if (!materials) {
|
|
1023
1087
|
return false;
|
|
1024
1088
|
}
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1089
|
+
this.#addTaskToQueue(materials, "materials");
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
setOptions(options) {
|
|
1093
|
+
options = typeof options === "string" ? JSON.parse(options) : options;
|
|
1094
|
+
if (!options) {
|
|
1095
|
+
return false;
|
|
1096
|
+
}
|
|
1097
|
+
this.#addTaskToQueue(options, "options");
|
|
1031
1098
|
}
|
|
1032
1099
|
|
|
1033
1100
|
showModel() {
|