@combeenation/3d-viewer 12.4.1 → 12.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/dist/lib-cjs/api/classes/animationInterface.d.ts +8 -8
- package/dist/lib-cjs/api/classes/animationInterface.js +2 -2
- package/dist/lib-cjs/api/classes/dottedPath.d.ts +79 -79
- package/dist/lib-cjs/api/classes/dottedPath.js +166 -166
- package/dist/lib-cjs/api/classes/element.d.ts +153 -153
- package/dist/lib-cjs/api/classes/element.js +702 -702
- package/dist/lib-cjs/api/classes/event.d.ts +401 -401
- package/dist/lib-cjs/api/classes/event.js +424 -424
- package/dist/lib-cjs/api/classes/eventBroadcaster.d.ts +26 -26
- package/dist/lib-cjs/api/classes/eventBroadcaster.js +49 -49
- package/dist/lib-cjs/api/classes/fuzzyMap.d.ts +7 -7
- package/dist/lib-cjs/api/classes/fuzzyMap.js +21 -21
- package/dist/lib-cjs/api/classes/parameter.d.ts +410 -410
- package/dist/lib-cjs/api/classes/parameter.js +642 -642
- package/dist/lib-cjs/api/classes/parameterObservable.d.ts +36 -36
- package/dist/lib-cjs/api/classes/parameterObservable.js +72 -72
- package/dist/lib-cjs/api/classes/parameterizable.d.ts +15 -15
- package/dist/lib-cjs/api/classes/parameterizable.js +102 -102
- package/dist/lib-cjs/api/classes/placementAnimation.d.ts +45 -45
- package/dist/lib-cjs/api/classes/placementAnimation.js +176 -176
- package/dist/lib-cjs/api/classes/variant.d.ts +261 -261
- package/dist/lib-cjs/api/classes/variant.js +872 -872
- package/dist/lib-cjs/api/classes/variantInstance.d.ts +53 -53
- package/dist/lib-cjs/api/classes/variantInstance.js +125 -125
- package/dist/lib-cjs/api/classes/variantParameterizable.d.ts +17 -17
- package/dist/lib-cjs/api/classes/variantParameterizable.js +86 -86
- package/dist/lib-cjs/api/classes/viewer.d.ts +215 -215
- package/dist/lib-cjs/api/classes/viewer.js +708 -708
- package/dist/lib-cjs/api/classes/viewerError.d.ts +43 -43
- package/dist/lib-cjs/api/classes/viewerError.js +55 -55
- package/dist/lib-cjs/api/classes/viewerLight.d.ts +66 -66
- package/dist/lib-cjs/api/classes/viewerLight.js +344 -344
- package/dist/lib-cjs/api/internal/lensRendering.d.ts +8 -8
- package/dist/lib-cjs/api/internal/lensRendering.js +11 -11
- package/dist/lib-cjs/api/internal/sceneSetup.d.ts +13 -13
- package/dist/lib-cjs/api/internal/sceneSetup.js +227 -227
- package/dist/lib-cjs/api/manager/animationManager.d.ts +30 -30
- package/dist/lib-cjs/api/manager/animationManager.js +126 -126
- package/dist/lib-cjs/api/manager/gltfExportManager.d.ts +80 -80
- package/dist/lib-cjs/api/manager/gltfExportManager.js +300 -299
- package/dist/lib-cjs/api/manager/gltfExportManager.js.map +1 -1
- package/dist/lib-cjs/api/manager/sceneManager.d.ts +33 -33
- package/dist/lib-cjs/api/manager/sceneManager.js +128 -128
- package/dist/lib-cjs/api/manager/tagManager.d.ts +118 -118
- package/dist/lib-cjs/api/manager/tagManager.js +530 -530
- package/dist/lib-cjs/api/manager/textureLoadManager.d.ts +22 -22
- package/dist/lib-cjs/api/manager/textureLoadManager.js +107 -107
- package/dist/lib-cjs/api/manager/variantInstanceManager.d.ts +106 -106
- package/dist/lib-cjs/api/manager/variantInstanceManager.js +290 -290
- package/dist/lib-cjs/api/store/specStorage.d.ts +32 -32
- package/dist/lib-cjs/api/store/specStorage.js +65 -65
- package/dist/lib-cjs/api/util/babylonHelper.d.ts +238 -238
- package/dist/lib-cjs/api/util/babylonHelper.js +825 -825
- package/dist/lib-cjs/api/util/debugHelper.d.ts +9 -9
- package/dist/lib-cjs/api/util/debugHelper.js +93 -93
- package/dist/lib-cjs/api/util/deviceHelper.d.ts +9 -9
- package/dist/lib-cjs/api/util/deviceHelper.js +28 -28
- package/dist/lib-cjs/api/util/geometryHelper.d.ts +17 -17
- package/dist/lib-cjs/api/util/geometryHelper.js +112 -112
- package/dist/lib-cjs/api/util/globalTypes.d.ts +490 -490
- package/dist/lib-cjs/api/util/globalTypes.js +1 -1
- package/dist/lib-cjs/api/util/resourceHelper.d.ts +58 -58
- package/dist/lib-cjs/api/util/resourceHelper.js +214 -214
- package/dist/lib-cjs/api/util/sceneLoaderHelper.d.ts +58 -58
- package/dist/lib-cjs/api/util/sceneLoaderHelper.js +228 -228
- package/dist/lib-cjs/api/util/stringHelper.d.ts +13 -13
- package/dist/lib-cjs/api/util/stringHelper.js +32 -32
- package/dist/lib-cjs/api/util/structureHelper.d.ts +9 -9
- package/dist/lib-cjs/api/util/structureHelper.js +57 -57
- package/dist/lib-cjs/buildinfo.json +3 -3
- package/dist/lib-cjs/commonjs.tsconfig.tsbuildinfo +1 -1
- package/dist/lib-cjs/index.d.ts +63 -63
- package/dist/lib-cjs/index.js +128 -128
- package/package.json +93 -92
- package/src/api/classes/animationInterface.ts +10 -10
- package/src/api/classes/dottedPath.ts +181 -181
- package/src/api/classes/element.ts +766 -766
- package/src/api/classes/event.ts +457 -457
- package/src/api/classes/eventBroadcaster.ts +52 -52
- package/src/api/classes/fuzzyMap.ts +21 -21
- package/src/api/classes/parameter.ts +686 -686
- package/src/api/classes/parameterObservable.ts +73 -73
- package/src/api/classes/parameterizable.ts +87 -87
- package/src/api/classes/placementAnimation.ts +162 -162
- package/src/api/classes/variant.ts +965 -965
- package/src/api/classes/variantInstance.ts +123 -123
- package/src/api/classes/variantParameterizable.ts +83 -83
- package/src/api/classes/viewer.ts +751 -751
- package/src/api/classes/viewerError.ts +63 -63
- package/src/api/classes/viewerLight.ts +335 -335
- package/src/api/internal/debugViewer.ts +90 -90
- package/src/api/internal/lensRendering.ts +9 -9
- package/src/api/internal/sceneSetup.ts +208 -208
- package/src/api/manager/animationManager.ts +143 -143
- package/src/api/manager/gltfExportManager.ts +337 -334
- package/src/api/manager/sceneManager.ts +134 -134
- package/src/api/manager/tagManager.ts +572 -572
- package/src/api/manager/textureLoadManager.ts +107 -107
- package/src/api/manager/variantInstanceManager.ts +306 -306
- package/src/api/store/specStorage.ts +68 -68
- package/src/api/util/babylonHelper.ts +915 -915
- package/src/api/util/debugHelper.ts +121 -121
- package/src/api/util/deviceHelper.ts +31 -31
- package/src/api/util/geometryHelper.ts +142 -142
- package/src/api/util/globalTypes.ts +566 -566
- package/src/api/util/resourceHelper.ts +201 -201
- package/src/api/util/sceneLoaderHelper.ts +247 -247
- package/src/api/util/stringHelper.ts +30 -30
- package/src/api/util/structureHelper.ts +62 -62
- package/src/buildinfo.json +3 -3
- package/src/dev.ts +70 -70
- package/src/index.ts +116 -116
- package/src/types.d.ts +49 -49
|
@@ -1,873 +1,873 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.Variant = void 0;
|
|
13
|
-
const babylonHelper_1 = require("../util/babylonHelper");
|
|
14
|
-
const resourceHelper_1 = require("../util/resourceHelper");
|
|
15
|
-
const dottedPath_1 = require("./dottedPath");
|
|
16
|
-
const element_1 = require("./element");
|
|
17
|
-
const event_1 = require("./event");
|
|
18
|
-
const parameter_1 = require("./parameter");
|
|
19
|
-
const parameterizable_1 = require("./parameterizable");
|
|
20
|
-
const viewerError_1 = require("./viewerError");
|
|
21
|
-
const viewerLight_1 = require("./viewerLight");
|
|
22
|
-
require("@babylonjs/core/Loading/Plugins/babylonFileLoader");
|
|
23
|
-
const sceneLoader_1 = require("@babylonjs/core/Loading/sceneLoader");
|
|
24
|
-
const transformNode_1 = require("@babylonjs/core/Meshes/transformNode");
|
|
25
|
-
const assetContainer_1 = require("@babylonjs/core/assetContainer");
|
|
26
|
-
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_draco_mesh_compression");
|
|
27
|
-
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_clearcoat");
|
|
28
|
-
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_ior");
|
|
29
|
-
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness");
|
|
30
|
-
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_sheen");
|
|
31
|
-
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_specular");
|
|
32
|
-
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_translucency");
|
|
33
|
-
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_transmission");
|
|
34
|
-
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_unlit");
|
|
35
|
-
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_variants");
|
|
36
|
-
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_texture_basisu");
|
|
37
|
-
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_texture_transform");
|
|
38
|
-
require("@babylonjs/loaders/glTF/2.0/glTFLoader");
|
|
39
|
-
const lodash_es_1 = require("lodash-es");
|
|
40
|
-
/**
|
|
41
|
-
* A concrete "Variant". Most of these are handled by either the {@link Viewer} or {@link VariantInstance}.
|
|
42
|
-
*/
|
|
43
|
-
class Variant extends parameterizable_1.Parameterizable {
|
|
44
|
-
/**
|
|
45
|
-
* Constructor.
|
|
46
|
-
*/
|
|
47
|
-
constructor(_variantInstance, name, _structureJson, viewer, parent) {
|
|
48
|
-
super((0, lodash_es_1.cloneDeep)(_structureJson.parameterDeclaration), (0, lodash_es_1.cloneDeep)(_structureJson.parameters));
|
|
49
|
-
this._variantInstance = _variantInstance;
|
|
50
|
-
this.name = name;
|
|
51
|
-
this._structureJson = _structureJson;
|
|
52
|
-
this.viewer = viewer;
|
|
53
|
-
this.parent = parent;
|
|
54
|
-
this.elements = [];
|
|
55
|
-
this.viewerLights = [];
|
|
56
|
-
this._children = new Map();
|
|
57
|
-
this._parameterObservers = new Map();
|
|
58
|
-
/**
|
|
59
|
-
* @internal
|
|
60
|
-
*/
|
|
61
|
-
this.parametersInitialized = false;
|
|
62
|
-
for (const parameter in _structureJson.parameterDeclaration) {
|
|
63
|
-
if (!(parameter in (_structureJson.parameters || []))) {
|
|
64
|
-
throw new Error(`No default value for parameter "${parameter}" defined.`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
this.assetContainer = new assetContainer_1.AssetContainer(viewer.scene);
|
|
68
|
-
this.structureJson = (0, lodash_es_1.cloneDeep)(_structureJson);
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Creates the root {@link Variant}.
|
|
72
|
-
*/
|
|
73
|
-
static createRoot(structureJson, viewer) {
|
|
74
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
75
|
-
return Variant.create(null, '_', structureJson, viewer);
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Creates a {@link Variant} based on given parameters.
|
|
80
|
-
*
|
|
81
|
-
* @throws Error if "gltf" property is provided without a filename
|
|
82
|
-
*/
|
|
83
|
-
static create(variantInstance, name, structureJson, viewer, parent) {
|
|
84
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
-
const variant = new Variant(variantInstance, name, structureJson, viewer, parent);
|
|
86
|
-
yield variant.loadAssets();
|
|
87
|
-
return variant;
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* The ancestor {@link Variant}s ordered from top to bottom in the built tree.
|
|
92
|
-
*/
|
|
93
|
-
get ancestors() {
|
|
94
|
-
const ancestors = [];
|
|
95
|
-
let variant = this;
|
|
96
|
-
while (variant.parent) {
|
|
97
|
-
ancestors.unshift(variant.parent);
|
|
98
|
-
variant = variant.parent;
|
|
99
|
-
}
|
|
100
|
-
return ancestors;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* The root {@link Variant}.
|
|
104
|
-
*/
|
|
105
|
-
get root() {
|
|
106
|
-
var _a;
|
|
107
|
-
return (_a = this.ancestors[0]) !== null && _a !== void 0 ? _a : this;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* The {@link DottedPath} in the built tree of {@link Variant}s.
|
|
111
|
-
* E.g. "_.top-1.sub-2.sub-sub-3"
|
|
112
|
-
*/
|
|
113
|
-
get dottedPath() {
|
|
114
|
-
const parentIds = this.ancestors.map(ancestor => {
|
|
115
|
-
return ancestor.name;
|
|
116
|
-
});
|
|
117
|
-
return dottedPath_1.DottedPath.createFromParts(parentIds).addPart(this.name);
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Gets the {@link VariantInstance} this variant was created for. There are variants without an instance (the "ghost"
|
|
121
|
-
* ones used for bootstrapping instances). The usage of {@link Variant}s without an instance is an absolute edge-case
|
|
122
|
-
* when deeply using the viewer api and working abroad best practices.
|
|
123
|
-
*/
|
|
124
|
-
get variantInstance() {
|
|
125
|
-
return this._variantInstance;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* The id representing a {@link DottedPath}.
|
|
129
|
-
*/
|
|
130
|
-
get id() {
|
|
131
|
-
const dottedPath = dottedPath_1.DottedPath.create(this.dottedPath);
|
|
132
|
-
dottedPath.shiftPart(); // remove root
|
|
133
|
-
return dottedPath.path || '_';
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* The defined glTF Asset.
|
|
137
|
-
*/
|
|
138
|
-
get glTF() {
|
|
139
|
-
if (this.structureJson.glTF) {
|
|
140
|
-
if ((0, lodash_es_1.isString)(this.structureJson.glTF)) {
|
|
141
|
-
return {
|
|
142
|
-
rootUrl: this.structureJson.glTF,
|
|
143
|
-
fileName: undefined,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
if ((0, lodash_es_1.isEmpty)(this.structureJson.glTF.rootUrl)) {
|
|
147
|
-
throw new Error(`No "rootUrl" defined in "glTF" definition for variant "${this.id}".`);
|
|
148
|
-
}
|
|
149
|
-
return this.structureJson.glTF;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* The defined glTF URI.
|
|
154
|
-
*/
|
|
155
|
-
get glTFUri() {
|
|
156
|
-
if (this.glTF) {
|
|
157
|
-
return [this.glTF.rootUrl, this.glTF.fileName].join('');
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* The inherited defined glTF URI.
|
|
162
|
-
*/
|
|
163
|
-
get inheritedGlTFUri() {
|
|
164
|
-
if (!this.glTFUri && this.parent) {
|
|
165
|
-
return this.parent.inheritedGlTFUri;
|
|
166
|
-
}
|
|
167
|
-
return this.glTFUri;
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* The TransformNodes of the {@link Variant}.
|
|
171
|
-
*/
|
|
172
|
-
get nodes() {
|
|
173
|
-
const rootNodes = this.assetContainer
|
|
174
|
-
.getNodes()
|
|
175
|
-
.filter(n => n instanceof transformNode_1.TransformNode && !n.parent);
|
|
176
|
-
return rootNodes;
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* The {@link ViewerLight}s of the {@link Variant}.
|
|
180
|
-
*/
|
|
181
|
-
get lights() {
|
|
182
|
-
return this.assetContainer.lights;
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* All TransformNodes of the {@link Variant} mapped flat with a {@link DottedPath}.
|
|
186
|
-
*/
|
|
187
|
-
get dottedNodes() {
|
|
188
|
-
if (!this._dottedNodes) {
|
|
189
|
-
const nodes = this.assetContainer.getNodes().filter(n => n instanceof transformNode_1.TransformNode);
|
|
190
|
-
const dottedNodes = new Map();
|
|
191
|
-
nodes.forEach(node => {
|
|
192
|
-
dottedNodes.set(node.metadata.dottedPath, node);
|
|
193
|
-
});
|
|
194
|
-
this._dottedNodes = dottedNodes;
|
|
195
|
-
}
|
|
196
|
-
return this._dottedNodes;
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* The Materials of the {@link Variant}.
|
|
200
|
-
*/
|
|
201
|
-
get materials() {
|
|
202
|
-
return this.assetContainer.materials;
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* The cloned TransformNodes of all {@link Element}s created for this {@link Variant}.
|
|
206
|
-
*/
|
|
207
|
-
get elementNodes() {
|
|
208
|
-
return this.elements.reduce((a, c) => a.concat(c.nodes), []);
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* The cloned TransformNodes of all {@link Element}s created for this {@link Variant} flattened.
|
|
212
|
-
*/
|
|
213
|
-
get elementNodesFlat() {
|
|
214
|
-
return this.elements.reduce((a, c) => [...a, ...c.nodesFlat], []);
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* The cloned Meshes of all {@link Element}s created for this {@link Variant} flattened.
|
|
218
|
-
*/
|
|
219
|
-
get elementMeshesFlat() {
|
|
220
|
-
return this.elements.reduce((a, c) => [...a, ...c.meshesFlat], []);
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* The cloned Meshes of all {@link Element}s created for this {@link Variant} flattened.
|
|
224
|
-
*/
|
|
225
|
-
get elementAbstractMeshesFlat() {
|
|
226
|
-
return this.elements.reduce((a, c) => [...a, ...c.abstractMeshesFlat], []);
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* All {@link Element}s from this {@link Variant}'s parents.
|
|
230
|
-
*/
|
|
231
|
-
get inheritedElements() {
|
|
232
|
-
let elements = [];
|
|
233
|
-
this.ancestors.forEach(ancestor => {
|
|
234
|
-
elements = (0, lodash_es_1.concat)(elements, ancestor.elements);
|
|
235
|
-
});
|
|
236
|
-
return (0, lodash_es_1.concat)(elements, this.elements);
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* All {@link ViewerLight}s inherited from this {@link Variant}'s parents.
|
|
240
|
-
*/
|
|
241
|
-
get inheritedViewerLights() {
|
|
242
|
-
let viewerLights = [];
|
|
243
|
-
this.ancestors.forEach(ancestor => {
|
|
244
|
-
viewerLights = (0, lodash_es_1.concat)(viewerLights, ancestor.viewerLights);
|
|
245
|
-
});
|
|
246
|
-
return (0, lodash_es_1.concat)(viewerLights, this.viewerLights);
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* All TransformNodes inherited from this {@link Variant}'s parents.
|
|
250
|
-
*/
|
|
251
|
-
get inheritedNodes() {
|
|
252
|
-
let nodes = [];
|
|
253
|
-
this.ancestors.forEach(ancestor => {
|
|
254
|
-
nodes = (0, lodash_es_1.concat)(nodes, ancestor.nodes);
|
|
255
|
-
});
|
|
256
|
-
return (0, lodash_es_1.concat)(nodes, this.nodes);
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* All TransformNodes inherited from this {@link Variant}'s parents mapped flat with a {@link DottedPath}.
|
|
260
|
-
*/
|
|
261
|
-
get inheritedDottedNodes() {
|
|
262
|
-
let dottedNodes = this.dottedNodes;
|
|
263
|
-
this.ancestors.forEach(ancestor => {
|
|
264
|
-
dottedNodes = (0, resourceHelper_1.mergeMaps)(dottedNodes, ancestor.dottedNodes);
|
|
265
|
-
});
|
|
266
|
-
return dottedNodes;
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* All Lights inherited from this {@link Variant}'s parents.
|
|
270
|
-
*/
|
|
271
|
-
get inheritedLights() {
|
|
272
|
-
let lights = [];
|
|
273
|
-
this.ancestors.forEach(ancestor => {
|
|
274
|
-
lights = (0, lodash_es_1.concat)(lights, ancestor.lights);
|
|
275
|
-
});
|
|
276
|
-
return (0, lodash_es_1.concat)(lights, this.lights);
|
|
277
|
-
}
|
|
278
|
-
/**
|
|
279
|
-
* The {@link ParameterDeclarations} inherited from this {@link Variant}'s parents.
|
|
280
|
-
*/
|
|
281
|
-
get inheritedParameterDeclaration() {
|
|
282
|
-
const declaration = {};
|
|
283
|
-
this.ancestors.forEach(ancestor => {
|
|
284
|
-
(0, lodash_es_1.merge)(declaration, ancestor.parameterDeclaration);
|
|
285
|
-
});
|
|
286
|
-
return (0, lodash_es_1.merge)(declaration, this.parameterDeclaration);
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* The {@link ParameterBag} inherited from this {@link Variant}'s parents.
|
|
290
|
-
*/
|
|
291
|
-
get inheritedParameters() {
|
|
292
|
-
const parameters = {};
|
|
293
|
-
this.ancestors.forEach(ancestor => {
|
|
294
|
-
(0, lodash_es_1.merge)(parameters, ancestor.parameters);
|
|
295
|
-
});
|
|
296
|
-
return (0, lodash_es_1.merge)(parameters, this.parameters);
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* All Materials from this {@link Variant}'s parents.
|
|
300
|
-
*/
|
|
301
|
-
get inheritedMaterials() {
|
|
302
|
-
let materials = [];
|
|
303
|
-
this.ancestors.forEach(ancestor => {
|
|
304
|
-
materials = (0, lodash_es_1.concat)(materials, ancestor.materials);
|
|
305
|
-
});
|
|
306
|
-
return (0, lodash_es_1.concat)(materials, this.materials);
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Gets the direct children of the current {@link Variant}.
|
|
310
|
-
*/
|
|
311
|
-
getChildren() {
|
|
312
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
313
|
-
const children = [];
|
|
314
|
-
for (const name in this.structureJson.variants) {
|
|
315
|
-
children.push(yield this.getDescendant(name));
|
|
316
|
-
}
|
|
317
|
-
return children;
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Gets a descendant {@link Variant} of the current {@link Variant} relative to its {@link DottedPath}.
|
|
322
|
-
* If you have the dotted path `_.product_x.variant_blue.with_yellow_highlight` in a tree and you operate on the
|
|
323
|
-
* `product_x`, you can call `this.getDescendant('variant_blue.with_yellow_highlight')` to get the lowermost
|
|
324
|
-
* {@link Variant}.
|
|
325
|
-
*/
|
|
326
|
-
getDescendant(dottedPath) {
|
|
327
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
328
|
-
const _dottedPath = dottedPath_1.DottedPath.create(dottedPath);
|
|
329
|
-
const [name, ...descendantParts] = _dottedPath.parts;
|
|
330
|
-
let variant;
|
|
331
|
-
if (this._children.has(name)) {
|
|
332
|
-
variant = this._children.get(name);
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
if (!this.structureJson.variants) {
|
|
336
|
-
throw new Error(`Missing key "variants" in JSON structure for variant "${this.id}".`);
|
|
337
|
-
}
|
|
338
|
-
if (!this.structureJson.variants[name]) {
|
|
339
|
-
throw new Error(`Variant "${_dottedPath.path}" not defined in JSON structure for variant "${this.id}".`);
|
|
340
|
-
}
|
|
341
|
-
if (this.structureJson.variants[name].file) {
|
|
342
|
-
const file = this.structureJson.variants[name].file;
|
|
343
|
-
variant = yield Variant.create(this.variantInstance, name, yield (0, resourceHelper_1.loadJson)(file), this.viewer, this);
|
|
344
|
-
}
|
|
345
|
-
else {
|
|
346
|
-
variant = yield Variant.create(this.variantInstance, name, this.structureJson.variants[name], this.viewer, this);
|
|
347
|
-
}
|
|
348
|
-
this._children.set(name, variant);
|
|
349
|
-
}
|
|
350
|
-
if (!variant) {
|
|
351
|
-
throw new Error(`Variant "${_dottedPath.path}" was not created.`);
|
|
352
|
-
}
|
|
353
|
-
if (descendantParts.length > 0) {
|
|
354
|
-
return yield variant.getDescendant(dottedPath_1.DottedPath.createFromParts(descendantParts));
|
|
355
|
-
}
|
|
356
|
-
return variant;
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
/**
|
|
360
|
-
* Gets the desired {@link Element} of the current {@link Variant} relative to its {@link DottedPath}.
|
|
361
|
-
* Uses the mechanism of {@link getDescendant} to resolve the appropriate variant in tree.
|
|
362
|
-
*/
|
|
363
|
-
getElement(dottedPath) {
|
|
364
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
365
|
-
const _dottedPath = dottedPath_1.DottedPath.create(dottedPath);
|
|
366
|
-
const elementName = _dottedPath.popPart();
|
|
367
|
-
let variant = this;
|
|
368
|
-
if (_dottedPath.parts.length > 0) {
|
|
369
|
-
variant = yield this.getDescendant(_dottedPath);
|
|
370
|
-
}
|
|
371
|
-
if (variant.inheritedElements.length === 0) {
|
|
372
|
-
throw new Error(`No elements for variant "${variant.id}" found. ` +
|
|
373
|
-
`Either none are defined or they are not initialized (are you operating on the appropriate living?).`);
|
|
374
|
-
}
|
|
375
|
-
let element;
|
|
376
|
-
variant.inheritedElements.forEach(_element => {
|
|
377
|
-
if (_element.name === elementName) {
|
|
378
|
-
element = _element;
|
|
379
|
-
}
|
|
380
|
-
});
|
|
381
|
-
if (!element) {
|
|
382
|
-
throw new Error(`Element with name "${elementName}" does not exist for variant "${variant.id}".`);
|
|
383
|
-
}
|
|
384
|
-
return element;
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Gets the desired {@link ViewerLight} of the current {@link Variant} relative to its {@link DottedPath}.
|
|
389
|
-
* Uses the mechanism of {@link getDescendant} to resolve the appropriate variant in tree.
|
|
390
|
-
*/
|
|
391
|
-
getViewerLight(dottedPath) {
|
|
392
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
393
|
-
const _dottedPath = dottedPath_1.DottedPath.create(dottedPath);
|
|
394
|
-
const viewerLightName = _dottedPath.popPart();
|
|
395
|
-
let variant = this;
|
|
396
|
-
if (_dottedPath.parts.length > 0) {
|
|
397
|
-
variant = yield this.getDescendant(_dottedPath);
|
|
398
|
-
}
|
|
399
|
-
if (variant.inheritedViewerLights.length === 0) {
|
|
400
|
-
throw new Error(`No viewerLights for variant "${variant.id}" found. ` +
|
|
401
|
-
`Either none are defined or they are not initialized (are you operating on the appropriate living?).`);
|
|
402
|
-
}
|
|
403
|
-
let viewerLight;
|
|
404
|
-
variant.inheritedViewerLights.forEach(_viewerLight => {
|
|
405
|
-
if (_viewerLight.name === viewerLightName) {
|
|
406
|
-
viewerLight = _viewerLight;
|
|
407
|
-
}
|
|
408
|
-
});
|
|
409
|
-
if (!viewerLight) {
|
|
410
|
-
throw new Error(`ViewerLight with name "${viewerLightName}" does not exist for variant "${variant.id}".`);
|
|
411
|
-
}
|
|
412
|
-
return viewerLight;
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* A proxy for directly getting a Node from an {@link Element} by its {@link DottedPath}s.
|
|
417
|
-
*/
|
|
418
|
-
getNode(elementDottedPath, nodeDottedPath) {
|
|
419
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
420
|
-
const element = yield this.getElement(elementDottedPath);
|
|
421
|
-
return element.getNode(nodeDottedPath);
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
/**
|
|
425
|
-
* A proxy for directly getting a Mesh from an {@link Element} by its {@link DottedPath}s.
|
|
426
|
-
*/
|
|
427
|
-
getMesh(elementDottedPath, meshDottedPath) {
|
|
428
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
429
|
-
const element = yield this.getElement(elementDottedPath);
|
|
430
|
-
return element.getMesh(meshDottedPath);
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
/**
|
|
434
|
-
* Creates a living clone of this {@link Variant}. Will clone all parent {@link Variant}s in tree.
|
|
435
|
-
*
|
|
436
|
-
* @emit {@link Event.VARIANT_CREATED}
|
|
437
|
-
* @ignore
|
|
438
|
-
*/
|
|
439
|
-
createLiving(variantInstance, parameters) {
|
|
440
|
-
var _a;
|
|
441
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
442
|
-
const parent = yield ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.createLiving(variantInstance));
|
|
443
|
-
const variant = new Variant(variantInstance, this.name, this._structureJson, this.viewer, parent);
|
|
444
|
-
parent === null || parent === void 0 ? void 0 : parent._children.set(variant.name, variant);
|
|
445
|
-
variant.assetContainer = this.assetContainer;
|
|
446
|
-
variant.parameterObservers = (0, lodash_es_1.cloneDeep)(this.parameterObservers);
|
|
447
|
-
yield variant.createElements();
|
|
448
|
-
yield variant.createViewerLights();
|
|
449
|
-
variant.addParameterObservers();
|
|
450
|
-
yield variant.bootstrapParameters(parameters);
|
|
451
|
-
this.viewer.broadcastEvent(event_1.Event.VARIANT_CREATED, variant);
|
|
452
|
-
return variant;
|
|
453
|
-
});
|
|
454
|
-
}
|
|
455
|
-
/**
|
|
456
|
-
* Destroys this {@link Variant}, all parents and destroy the {@link Element}s.
|
|
457
|
-
*/
|
|
458
|
-
destroy() {
|
|
459
|
-
this.elements.forEach(element => element.destroy());
|
|
460
|
-
if (this.parent) {
|
|
461
|
-
this.parent.destroy();
|
|
462
|
-
}
|
|
463
|
-
this.broadcastEvent(event_1.Event.VARIANT_DESTROYED, this);
|
|
464
|
-
return this;
|
|
465
|
-
}
|
|
466
|
-
/**
|
|
467
|
-
* Places the given {@link ParameterBag} in the {@link Variant}'s parameters, replaces all patterns in the
|
|
468
|
-
* {@link StructureJson}, broadcasts all {@link ParameterObserver}s and delegates them to its {@link Element}s.
|
|
469
|
-
*
|
|
470
|
-
* @emit {@link Event.VARIANT_PARAMETER_COMMITTED}
|
|
471
|
-
*/
|
|
472
|
-
commitParameters(parameters) {
|
|
473
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
474
|
-
parameters = (0, lodash_es_1.merge)({}, parameters);
|
|
475
|
-
// remember old parameter values for later comparison
|
|
476
|
-
const oldParameters = (0, lodash_es_1.cloneDeep)(this.inheritedParameters);
|
|
477
|
-
// replace patterns in given parameters
|
|
478
|
-
let _parameters = JSON.stringify(parameters);
|
|
479
|
-
for (const parameter in this.inheritedParameters) {
|
|
480
|
-
const value = this.inheritedParameters[parameter];
|
|
481
|
-
const search = new RegExp(`\\$\\{${parameter}\\}`, 'g');
|
|
482
|
-
_parameters = _parameters.replace(search, value.toString());
|
|
483
|
-
}
|
|
484
|
-
(0, lodash_es_1.merge)(parameters, JSON.parse(_parameters));
|
|
485
|
-
// merge inherited parameters and replaced given parameters
|
|
486
|
-
const mergedParameters = (0, lodash_es_1.merge)({}, this.inheritedParameters, parameters);
|
|
487
|
-
// replace patterns in structure parameters
|
|
488
|
-
const structureParameters = this._structureJson.parameters || {};
|
|
489
|
-
let _structureParameters = JSON.stringify(structureParameters);
|
|
490
|
-
for (const parameter in mergedParameters) {
|
|
491
|
-
const value = mergedParameters[parameter];
|
|
492
|
-
const search = new RegExp(`\\$\\{${parameter}\\}`, 'g');
|
|
493
|
-
_structureParameters = _structureParameters.replace(search, value.toString());
|
|
494
|
-
}
|
|
495
|
-
const replacedStructureParameters = JSON.parse(_structureParameters);
|
|
496
|
-
// calculate which replaced structure parameters have changed and should overload given parameters
|
|
497
|
-
const differentStructureParameters = {};
|
|
498
|
-
for (const parameter in replacedStructureParameters) {
|
|
499
|
-
if (!(0, lodash_es_1.isEqual)(structureParameters[parameter], replacedStructureParameters[parameter])) {
|
|
500
|
-
differentStructureParameters[parameter] = replacedStructureParameters[parameter];
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
// merge replaced structure parameters and given inherited parameters to structure parameters
|
|
504
|
-
(0, lodash_es_1.merge)(this.parameters, mergedParameters, differentStructureParameters);
|
|
505
|
-
// inherited parameters are now the new parameters to process
|
|
506
|
-
const newParameters = this.inheritedParameters;
|
|
507
|
-
// replace all parameter patterns in structure json
|
|
508
|
-
let structure = JSON.stringify(this._structureJson);
|
|
509
|
-
for (const parameter in newParameters) {
|
|
510
|
-
const value = newParameters[parameter];
|
|
511
|
-
const search = new RegExp(`\\$\\{${parameter}\\}`, 'g');
|
|
512
|
-
structure = structure.replace(search, value.toString());
|
|
513
|
-
}
|
|
514
|
-
this.structureJson = JSON.parse(structure);
|
|
515
|
-
// handle parameter observers
|
|
516
|
-
let observerPromises = [];
|
|
517
|
-
for (const parameter in newParameters) {
|
|
518
|
-
const oldParameterValue = oldParameters[parameter];
|
|
519
|
-
const newParameterValue = newParameters[parameter];
|
|
520
|
-
this.assertParameter(this.inheritedParameterDeclaration, parameter, newParameterValue);
|
|
521
|
-
if (oldParameterValue === newParameterValue && this.parametersInitialized) {
|
|
522
|
-
continue;
|
|
523
|
-
}
|
|
524
|
-
// parameter changed
|
|
525
|
-
const parameterObservers = (0, resourceHelper_1.mergeMaps)(this._parameterObservers, this.parameterObservers);
|
|
526
|
-
if (parameterObservers.has(parameter)) {
|
|
527
|
-
const observers = parameterObservers.get(parameter);
|
|
528
|
-
observerPromises = (0, lodash_es_1.concat)(observerPromises, observers.map(observer => {
|
|
529
|
-
const observerResult = observer(this, oldParameterValue, newParameterValue);
|
|
530
|
-
return Promise.resolve(observerResult).then(() => {
|
|
531
|
-
if (this.parametersInitialized) {
|
|
532
|
-
this.broadcastEvent(event_1.Event.VARIANT_PARAMETER_COMMITTED, this, parameter, oldParameterValue, newParameterValue);
|
|
533
|
-
}
|
|
534
|
-
});
|
|
535
|
-
}));
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
yield Promise.all(observerPromises);
|
|
539
|
-
// broadcast that bag has been committed
|
|
540
|
-
this.broadcastEvent(event_1.Event.VARIANT_PARAMETER_BAG_COMMITTED, this, oldParameters, newParameters);
|
|
541
|
-
// commit parameters to elements
|
|
542
|
-
yield this.commitParametersToElements(newParameters);
|
|
543
|
-
// commit parameters to lights
|
|
544
|
-
yield this.commitParametersToViewerLights(newParameters);
|
|
545
|
-
// propagate parameters to parent
|
|
546
|
-
if (this.parent) {
|
|
547
|
-
yield this.parent.commitParameters(this.parameters);
|
|
548
|
-
}
|
|
549
|
-
return this;
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
/**
|
|
553
|
-
* Adds an observer function for camera matrix changes for given `dottedPath` representing the {@link Element}
|
|
554
|
-
* and the `traceable`. The `observer` gets 2 parameters: the `AbstractMesh` and a `ClientRect` object.
|
|
555
|
-
*/
|
|
556
|
-
addTraceableObserver(dottedPath, observer, payload) {
|
|
557
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
558
|
-
const _dottedPath = dottedPath_1.DottedPath.create(dottedPath);
|
|
559
|
-
const traceableName = _dottedPath.popPart();
|
|
560
|
-
if (!traceableName) {
|
|
561
|
-
throw new Error(`The dottedPath must consist of the element and the name of the defined corresponding ` +
|
|
562
|
-
`traceable ("${_dottedPath.path}" given).`);
|
|
563
|
-
}
|
|
564
|
-
const element = yield this.getElement(_dottedPath);
|
|
565
|
-
return element.addTraceableObserver(traceableName, observer, payload);
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
|
-
/**
|
|
569
|
-
* Loads {@link glTFUri} with assets, adds them to the {@link Variant}'s `assetContainer` and deactivates the meshes.
|
|
570
|
-
* (for further processing).
|
|
571
|
-
* @emits {@link Event.ASSET_LOADING_START}
|
|
572
|
-
* @emits {@link Event.ASSET_LOADING_END}
|
|
573
|
-
*/
|
|
574
|
-
loadAssets() {
|
|
575
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
576
|
-
this.broadcastEvent(event_1.Event.ASSET_LOADING_START, this);
|
|
577
|
-
return new Promise((resolve, reject) => {
|
|
578
|
-
if (!this.structureJson) {
|
|
579
|
-
this.broadcastEvent(event_1.Event.ASSET_LOADING_END, this);
|
|
580
|
-
return resolve(this);
|
|
581
|
-
}
|
|
582
|
-
if (!this.glTF) {
|
|
583
|
-
this.broadcastEvent(event_1.Event.ASSET_LOADING_END, this);
|
|
584
|
-
return resolve(this);
|
|
585
|
-
}
|
|
586
|
-
sceneLoader_1.SceneLoader.LoadAssetContainer(this.glTF.rootUrl, this.glTF.fileName, this.viewer.scene,
|
|
587
|
-
// on success
|
|
588
|
-
container => {
|
|
589
|
-
this.assetContainer = container;
|
|
590
|
-
const nodes = this.assetContainer.getNodes().filter(n => n instanceof transformNode_1.TransformNode);
|
|
591
|
-
(0, babylonHelper_1.reportDuplicateNodeNames)((0, babylonHelper_1.intersectingNodeNames)(nodes, this.viewer.scene.getNodes(), n => n instanceof transformNode_1.TransformNode));
|
|
592
|
-
nodes.forEach(node => {
|
|
593
|
-
(0, babylonHelper_1.deactivateTransformNode)(node, false);
|
|
594
|
-
(0, babylonHelper_1.injectMetadata)(node, { dottedPath: (0, babylonHelper_1.getDottedPathForNode)(node), originalName: node.name }, false);
|
|
595
|
-
});
|
|
596
|
-
this.assetContainer.lights.forEach(light => {
|
|
597
|
-
light.setEnabled(false);
|
|
598
|
-
(0, babylonHelper_1.injectMetadata)(light, { dottedPath: (0, babylonHelper_1.getDottedPathForNode)(light), originalName: light.name }, false);
|
|
599
|
-
this.viewer.scene.addLight(light);
|
|
600
|
-
});
|
|
601
|
-
this.assetContainer.cameras.forEach(camera => {
|
|
602
|
-
camera.setEnabled(false);
|
|
603
|
-
(0, babylonHelper_1.injectMetadata)(camera, { dottedPath: (0, babylonHelper_1.getDottedPathForNode)(camera), originalName: camera.name }, false);
|
|
604
|
-
this.viewer.scene.addCamera(camera);
|
|
605
|
-
});
|
|
606
|
-
this.assetContainer.materials.forEach(material => this.viewer.scene.materials.push(material));
|
|
607
|
-
this.assetContainer.textures.forEach(texture => this.viewer.scene.textures.push(texture));
|
|
608
|
-
this.assetContainer.skeletons.forEach(skeleton => this.viewer.scene.skeletons.push(skeleton));
|
|
609
|
-
this.broadcastEvent(event_1.Event.ASSET_LOADING_END, this);
|
|
610
|
-
resolve(this);
|
|
611
|
-
},
|
|
612
|
-
// on progress
|
|
613
|
-
undefined,
|
|
614
|
-
// on error
|
|
615
|
-
(scene, msg, exc) => {
|
|
616
|
-
this.broadcastEvent(event_1.Event.ASSET_LOADING_END, this);
|
|
617
|
-
/**
|
|
618
|
-
* @preserve (4 webpack terser plugin)
|
|
619
|
-
* If you're here and the shown error doesn't seem to make any sense:
|
|
620
|
-
* BJS "swallows" all exceptions within our success callback above and reports some generic error like
|
|
621
|
-
* "Unable to load from https://some/url.babylon" etc.
|
|
622
|
-
* -> The real reason for the error **could** be that some of our code within the above success callback has
|
|
623
|
-
* thrown.
|
|
624
|
-
*/
|
|
625
|
-
const error = new viewerError_1.ViewerError({
|
|
626
|
-
id: viewerError_1.ViewerErrorIds.AssetLoadingFailed,
|
|
627
|
-
message: `Error loading assets for variant "${this.id}": ${msg}.`,
|
|
628
|
-
});
|
|
629
|
-
reject(error);
|
|
630
|
-
});
|
|
631
|
-
});
|
|
632
|
-
});
|
|
633
|
-
}
|
|
634
|
-
/**
|
|
635
|
-
* Commits given parameters to all {@link Element}s.
|
|
636
|
-
*/
|
|
637
|
-
commitParametersToElements(parameters) {
|
|
638
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
639
|
-
yield Promise.all(this.elements.map(element => this.commitParametersToVariantParameterizable(parameters, element, 'elements')));
|
|
640
|
-
});
|
|
641
|
-
}
|
|
642
|
-
/**
|
|
643
|
-
* Commits given parameters to all {@link ViewerLight}s.
|
|
644
|
-
*/
|
|
645
|
-
commitParametersToViewerLights(parameters) {
|
|
646
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
647
|
-
yield Promise.all(this.viewerLights.map(viewerLight => this.commitParametersToVariantParameterizable(parameters, viewerLight, 'lights')));
|
|
648
|
-
});
|
|
649
|
-
}
|
|
650
|
-
/**
|
|
651
|
-
* Commits given parameters to a {@link VariantParameterizable} and updates the according definition with given
|
|
652
|
-
* key in the {@link StructureJson}. The `definitionKey` "elements" for example will update the definition in
|
|
653
|
-
* `this.structureJson.elements`.
|
|
654
|
-
*/
|
|
655
|
-
commitParametersToVariantParameterizable(parameters, parameterizable, definitionKey) {
|
|
656
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
657
|
-
const initialDefinition = (0, lodash_es_1.get)(this._structureJson, definitionKey)[parameterizable.name];
|
|
658
|
-
let initialDefinitionStr = JSON.stringify(initialDefinition);
|
|
659
|
-
const _parameters = {};
|
|
660
|
-
for (const parameter in parameters) {
|
|
661
|
-
const dpp = dottedPath_1.DottedPath.create(parameter);
|
|
662
|
-
if (dpp.shiftPart() !== parameterizable.name) {
|
|
663
|
-
continue;
|
|
664
|
-
}
|
|
665
|
-
// we got a parameterizable ("element") parameter
|
|
666
|
-
let parameterValue = parameters[parameter];
|
|
667
|
-
const parameterizableParameter = dpp.path;
|
|
668
|
-
// If the variant is explicitly hidden, we must not override the visibility with element parameters. We need
|
|
669
|
-
// an exception for visibility to avoid overloading already applied element parameters with element parameters
|
|
670
|
-
// defined in the variant spec ("dotted parameters").
|
|
671
|
-
// @see https://github.com/Combeenation/3d-viewer/issues/44
|
|
672
|
-
const visibleParamValue = parameters[parameter_1.Parameter.VISIBLE];
|
|
673
|
-
const isVisible = undefined === visibleParamValue || parameter_1.Parameter.parseBoolean(visibleParamValue);
|
|
674
|
-
if (parameterizableParameter === parameter_1.Parameter.VISIBLE && !isVisible) {
|
|
675
|
-
parameterValue = false;
|
|
676
|
-
}
|
|
677
|
-
_parameters[parameterizableParameter] = parameterValue;
|
|
678
|
-
const search = new RegExp(`\\$\\{${parameterizableParameter}\\}`, 'g');
|
|
679
|
-
initialDefinitionStr = initialDefinitionStr.replace(search, parameterValue.toString());
|
|
680
|
-
}
|
|
681
|
-
const definition = (0, lodash_es_1.get)(this.structureJson, definitionKey);
|
|
682
|
-
definition[this.name] = JSON.parse(initialDefinitionStr);
|
|
683
|
-
(0, lodash_es_1.set)(this.structureJson, definitionKey, definition);
|
|
684
|
-
return yield parameterizable.commitParameters(_parameters);
|
|
685
|
-
});
|
|
686
|
-
}
|
|
687
|
-
/**
|
|
688
|
-
* Commits given {@link Parameter} to the {@link Variant}'s {@link Element}s.
|
|
689
|
-
*/
|
|
690
|
-
commitParameterToElements(parameter, value) {
|
|
691
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
692
|
-
const promises = [];
|
|
693
|
-
for (const element of this.elements) {
|
|
694
|
-
const paramShowsVariant = parameter_1.Parameter.VISIBLE === parameter && value;
|
|
695
|
-
// Fixes https://combeenation.youtrack.cloud/issue/CB-7773
|
|
696
|
-
// Don't enable/show the variants element if it is explicitly hidden via its element parameters.
|
|
697
|
-
// E.g. via spec:
|
|
698
|
-
// ```
|
|
699
|
-
// variants: {
|
|
700
|
-
// theVariant: {
|
|
701
|
-
// elements: {
|
|
702
|
-
// Main: ['root.main'],
|
|
703
|
-
// Secondary: ['root.secondary'],
|
|
704
|
-
// },
|
|
705
|
-
// parameters: {
|
|
706
|
-
// // !!! The element `Secondary` should **not** be enabled when its containing variant is enabled !!!
|
|
707
|
-
// 'Secondary.visible': false,
|
|
708
|
-
// }
|
|
709
|
-
// }
|
|
710
|
-
// }
|
|
711
|
-
// ```
|
|
712
|
-
const elVisibleParamPath = dottedPath_1.DottedPath.create([element.name, parameter_1.Parameter.VISIBLE]).toString();
|
|
713
|
-
const elVisibleParamValue = this.inheritedParameters[elVisibleParamPath];
|
|
714
|
-
const elVisibleParamValueParsed = elVisibleParamValue && parameter_1.Parameter.parseBoolean(elVisibleParamValue);
|
|
715
|
-
const elIsHiddenViaParams = elVisibleParamValueParsed === false;
|
|
716
|
-
if (paramShowsVariant && elIsHiddenViaParams)
|
|
717
|
-
continue;
|
|
718
|
-
// Fixes https://combeenation.youtrack.cloud/issue/CB-7809
|
|
719
|
-
// Apply element material before showing the element to prevent loading of the elements "original" material which
|
|
720
|
-
// is never shown when "overwritten" by elements material param.
|
|
721
|
-
const elMaterialParamPath = dottedPath_1.DottedPath.create([element.name, parameter_1.Parameter.MATERIAL]).toString();
|
|
722
|
-
const elMaterialParamValue = this.inheritedParameters[elMaterialParamPath];
|
|
723
|
-
if (paramShowsVariant && elMaterialParamValue) {
|
|
724
|
-
yield element.commitParameter(parameter_1.Parameter.MATERIAL, elMaterialParamValue);
|
|
725
|
-
}
|
|
726
|
-
promises.push(element.commitParameter(parameter, value));
|
|
727
|
-
}
|
|
728
|
-
yield Promise.all(promises);
|
|
729
|
-
return this;
|
|
730
|
-
});
|
|
731
|
-
}
|
|
732
|
-
/**
|
|
733
|
-
* Commits given {@link Parameter} to the {@link Variant}'s {@link Element}s.
|
|
734
|
-
*/
|
|
735
|
-
commitParameterToViewerLights(parameter, value) {
|
|
736
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
737
|
-
const promises = [];
|
|
738
|
-
for (const viewerLight of this.viewerLights) {
|
|
739
|
-
promises.push(viewerLight.commitParameter(parameter, value));
|
|
740
|
-
}
|
|
741
|
-
yield Promise.all(promises);
|
|
742
|
-
return this;
|
|
743
|
-
});
|
|
744
|
-
}
|
|
745
|
-
/**
|
|
746
|
-
* Adds the default {@link ParameterObserver}s which are called every time {@link commitParameters} is called.
|
|
747
|
-
*/
|
|
748
|
-
addParameterObservers() {
|
|
749
|
-
this._parameterObservers.set(parameter_1.Parameter.VISIBLE, [
|
|
750
|
-
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
751
|
-
yield variant.commitParameterToElements(parameter_1.Parameter.VISIBLE, newValue);
|
|
752
|
-
yield variant.commitParameterToViewerLights(parameter_1.Parameter.VISIBLE, newValue);
|
|
753
|
-
}),
|
|
754
|
-
]);
|
|
755
|
-
this._parameterObservers.set(parameter_1.Parameter.SCALING, [
|
|
756
|
-
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
757
|
-
yield variant.commitParameterToElements(parameter_1.Parameter.SCALING, newValue);
|
|
758
|
-
yield variant.commitParameterToViewerLights(parameter_1.Parameter.SCALING, newValue);
|
|
759
|
-
}),
|
|
760
|
-
]);
|
|
761
|
-
this._parameterObservers.set(parameter_1.Parameter.MATERIAL, [
|
|
762
|
-
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
763
|
-
yield variant.commitParameterToElements(parameter_1.Parameter.MATERIAL, newValue);
|
|
764
|
-
}),
|
|
765
|
-
]);
|
|
766
|
-
this._parameterObservers.set(parameter_1.Parameter.MATERIAL_COLOR, [
|
|
767
|
-
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
768
|
-
yield variant.commitParameterToElements(parameter_1.Parameter.MATERIAL_COLOR, newValue);
|
|
769
|
-
}),
|
|
770
|
-
]);
|
|
771
|
-
this._parameterObservers.set(parameter_1.Parameter.MATERIAL_METALLNESS, [
|
|
772
|
-
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
773
|
-
yield variant.commitParameterToElements(parameter_1.Parameter.MATERIAL_METALLNESS, newValue);
|
|
774
|
-
}),
|
|
775
|
-
]);
|
|
776
|
-
this._parameterObservers.set(parameter_1.Parameter.MATERIAL_ROUGHNESS, [
|
|
777
|
-
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
778
|
-
yield variant.commitParameterToElements(parameter_1.Parameter.MATERIAL_ROUGHNESS, newValue);
|
|
779
|
-
}),
|
|
780
|
-
]);
|
|
781
|
-
this._parameterObservers.set(parameter_1.Parameter.HIGHLIGHT_COLOR, [
|
|
782
|
-
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
783
|
-
yield variant.commitParameterToElements(parameter_1.Parameter.HIGHLIGHT_COLOR, newValue);
|
|
784
|
-
}),
|
|
785
|
-
]);
|
|
786
|
-
this._parameterObservers.set(parameter_1.Parameter.HIGHLIGHTED, [
|
|
787
|
-
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
788
|
-
yield variant.commitParameterToElements(parameter_1.Parameter.HIGHLIGHTED, newValue);
|
|
789
|
-
}),
|
|
790
|
-
]);
|
|
791
|
-
this._parameterObservers.set(parameter_1.Parameter.POSITION, [
|
|
792
|
-
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
793
|
-
yield variant.commitParameterToElements(parameter_1.Parameter.POSITION, newValue);
|
|
794
|
-
yield variant.commitParameterToViewerLights(parameter_1.Parameter.POSITION, newValue);
|
|
795
|
-
}),
|
|
796
|
-
]);
|
|
797
|
-
this._parameterObservers.set(parameter_1.Parameter.ROTATION, [
|
|
798
|
-
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
799
|
-
yield variant.commitParameterToElements(parameter_1.Parameter.ROTATION, newValue);
|
|
800
|
-
yield variant.commitParameterToViewerLights(parameter_1.Parameter.ROTATION, newValue);
|
|
801
|
-
}),
|
|
802
|
-
]);
|
|
803
|
-
this._parameterObservers.set(parameter_1.Parameter.CAST_SHADOW, [
|
|
804
|
-
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
805
|
-
yield variant.commitParameterToElements(parameter_1.Parameter.CAST_SHADOW, newValue);
|
|
806
|
-
}),
|
|
807
|
-
]);
|
|
808
|
-
this._parameterObservers.set(parameter_1.Parameter.CAST_SHADOW_FROM_LIGHTS, [
|
|
809
|
-
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
810
|
-
yield variant.commitParameterToElements(parameter_1.Parameter.CAST_SHADOW_FROM_LIGHTS, newValue);
|
|
811
|
-
}),
|
|
812
|
-
]);
|
|
813
|
-
this._parameterObservers.set(parameter_1.Parameter.RECEIVE_SHADOWS, [
|
|
814
|
-
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
815
|
-
yield variant.commitParameterToElements(parameter_1.Parameter.RECEIVE_SHADOWS, newValue);
|
|
816
|
-
}),
|
|
817
|
-
]);
|
|
818
|
-
return this;
|
|
819
|
-
}
|
|
820
|
-
/**
|
|
821
|
-
* Creates {@link Element}s and clones nodes into them.
|
|
822
|
-
*/
|
|
823
|
-
createElements(forInstance) {
|
|
824
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
825
|
-
this.createElementDefinitionsIfNotExist();
|
|
826
|
-
for (const name in this.structureJson.elements || {}) {
|
|
827
|
-
this.elements.push(yield element_1.Element.create(this, name));
|
|
828
|
-
}
|
|
829
|
-
// inject node meta to all inherited elements
|
|
830
|
-
// we do this to inject the deepest and most concrete variant information to all cloned nodes in the tree
|
|
831
|
-
this.inheritedElements.forEach(element => element.nodes.forEach(node => (0, babylonHelper_1.injectMetadata)(node, { variant: this, variantParameterizable: element })));
|
|
832
|
-
return this;
|
|
833
|
-
});
|
|
834
|
-
}
|
|
835
|
-
/**
|
|
836
|
-
* Creates {@link ViewerLight}s.
|
|
837
|
-
*/
|
|
838
|
-
createViewerLights() {
|
|
839
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
840
|
-
for (const name in this.structureJson.lights || {}) {
|
|
841
|
-
this.viewerLights.push(yield viewerLight_1.ViewerLight.create(this, name));
|
|
842
|
-
}
|
|
843
|
-
this.inheritedViewerLights.forEach(viewerLight => {
|
|
844
|
-
(0, babylonHelper_1.injectMetadata)(viewerLight.light, { variant: this, variantParameterizable: viewerLight });
|
|
845
|
-
});
|
|
846
|
-
return this;
|
|
847
|
-
});
|
|
848
|
-
}
|
|
849
|
-
/**
|
|
850
|
-
* Bootstrapping for parameters. It sets the `parametersInitialized` to true for all ancestors.
|
|
851
|
-
*/
|
|
852
|
-
bootstrapParameters(parameters) {
|
|
853
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
854
|
-
yield this.commitParameters((0, lodash_es_1.merge)((0, lodash_es_1.cloneDeep)(this.parameters), parameters));
|
|
855
|
-
(0, lodash_es_1.concat)(this.ancestors, this).forEach(ancestor => (ancestor.parametersInitialized = true));
|
|
856
|
-
return this;
|
|
857
|
-
});
|
|
858
|
-
}
|
|
859
|
-
/**
|
|
860
|
-
* Ensures there is at least one "Main" {@link Element} for the {@link Variant} with all "root nodes" defined in path.
|
|
861
|
-
*/
|
|
862
|
-
createElementDefinitionsIfNotExist() {
|
|
863
|
-
if (this._structureJson.elements || this.inheritedNodes.length === 0) {
|
|
864
|
-
return;
|
|
865
|
-
}
|
|
866
|
-
this._structureJson.elements = {
|
|
867
|
-
Main: { paths: { include: this.inheritedNodes.map(node => node.metadata.dottedPath.path) } },
|
|
868
|
-
};
|
|
869
|
-
this.structureJson.elements = (0, lodash_es_1.cloneDeep)(this._structureJson.elements);
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
exports.Variant = Variant;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.Variant = void 0;
|
|
13
|
+
const babylonHelper_1 = require("../util/babylonHelper");
|
|
14
|
+
const resourceHelper_1 = require("../util/resourceHelper");
|
|
15
|
+
const dottedPath_1 = require("./dottedPath");
|
|
16
|
+
const element_1 = require("./element");
|
|
17
|
+
const event_1 = require("./event");
|
|
18
|
+
const parameter_1 = require("./parameter");
|
|
19
|
+
const parameterizable_1 = require("./parameterizable");
|
|
20
|
+
const viewerError_1 = require("./viewerError");
|
|
21
|
+
const viewerLight_1 = require("./viewerLight");
|
|
22
|
+
require("@babylonjs/core/Loading/Plugins/babylonFileLoader");
|
|
23
|
+
const sceneLoader_1 = require("@babylonjs/core/Loading/sceneLoader");
|
|
24
|
+
const transformNode_1 = require("@babylonjs/core/Meshes/transformNode");
|
|
25
|
+
const assetContainer_1 = require("@babylonjs/core/assetContainer");
|
|
26
|
+
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_draco_mesh_compression");
|
|
27
|
+
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_clearcoat");
|
|
28
|
+
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_ior");
|
|
29
|
+
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness");
|
|
30
|
+
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_sheen");
|
|
31
|
+
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_specular");
|
|
32
|
+
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_translucency");
|
|
33
|
+
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_transmission");
|
|
34
|
+
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_unlit");
|
|
35
|
+
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_variants");
|
|
36
|
+
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_texture_basisu");
|
|
37
|
+
require("@babylonjs/loaders/glTF/2.0/Extensions/KHR_texture_transform");
|
|
38
|
+
require("@babylonjs/loaders/glTF/2.0/glTFLoader");
|
|
39
|
+
const lodash_es_1 = require("lodash-es");
|
|
40
|
+
/**
|
|
41
|
+
* A concrete "Variant". Most of these are handled by either the {@link Viewer} or {@link VariantInstance}.
|
|
42
|
+
*/
|
|
43
|
+
class Variant extends parameterizable_1.Parameterizable {
|
|
44
|
+
/**
|
|
45
|
+
* Constructor.
|
|
46
|
+
*/
|
|
47
|
+
constructor(_variantInstance, name, _structureJson, viewer, parent) {
|
|
48
|
+
super((0, lodash_es_1.cloneDeep)(_structureJson.parameterDeclaration), (0, lodash_es_1.cloneDeep)(_structureJson.parameters));
|
|
49
|
+
this._variantInstance = _variantInstance;
|
|
50
|
+
this.name = name;
|
|
51
|
+
this._structureJson = _structureJson;
|
|
52
|
+
this.viewer = viewer;
|
|
53
|
+
this.parent = parent;
|
|
54
|
+
this.elements = [];
|
|
55
|
+
this.viewerLights = [];
|
|
56
|
+
this._children = new Map();
|
|
57
|
+
this._parameterObservers = new Map();
|
|
58
|
+
/**
|
|
59
|
+
* @internal
|
|
60
|
+
*/
|
|
61
|
+
this.parametersInitialized = false;
|
|
62
|
+
for (const parameter in _structureJson.parameterDeclaration) {
|
|
63
|
+
if (!(parameter in (_structureJson.parameters || []))) {
|
|
64
|
+
throw new Error(`No default value for parameter "${parameter}" defined.`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
this.assetContainer = new assetContainer_1.AssetContainer(viewer.scene);
|
|
68
|
+
this.structureJson = (0, lodash_es_1.cloneDeep)(_structureJson);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Creates the root {@link Variant}.
|
|
72
|
+
*/
|
|
73
|
+
static createRoot(structureJson, viewer) {
|
|
74
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
75
|
+
return Variant.create(null, '_', structureJson, viewer);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Creates a {@link Variant} based on given parameters.
|
|
80
|
+
*
|
|
81
|
+
* @throws Error if "gltf" property is provided without a filename
|
|
82
|
+
*/
|
|
83
|
+
static create(variantInstance, name, structureJson, viewer, parent) {
|
|
84
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
const variant = new Variant(variantInstance, name, structureJson, viewer, parent);
|
|
86
|
+
yield variant.loadAssets();
|
|
87
|
+
return variant;
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The ancestor {@link Variant}s ordered from top to bottom in the built tree.
|
|
92
|
+
*/
|
|
93
|
+
get ancestors() {
|
|
94
|
+
const ancestors = [];
|
|
95
|
+
let variant = this;
|
|
96
|
+
while (variant.parent) {
|
|
97
|
+
ancestors.unshift(variant.parent);
|
|
98
|
+
variant = variant.parent;
|
|
99
|
+
}
|
|
100
|
+
return ancestors;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The root {@link Variant}.
|
|
104
|
+
*/
|
|
105
|
+
get root() {
|
|
106
|
+
var _a;
|
|
107
|
+
return (_a = this.ancestors[0]) !== null && _a !== void 0 ? _a : this;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The {@link DottedPath} in the built tree of {@link Variant}s.
|
|
111
|
+
* E.g. "_.top-1.sub-2.sub-sub-3"
|
|
112
|
+
*/
|
|
113
|
+
get dottedPath() {
|
|
114
|
+
const parentIds = this.ancestors.map(ancestor => {
|
|
115
|
+
return ancestor.name;
|
|
116
|
+
});
|
|
117
|
+
return dottedPath_1.DottedPath.createFromParts(parentIds).addPart(this.name);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Gets the {@link VariantInstance} this variant was created for. There are variants without an instance (the "ghost"
|
|
121
|
+
* ones used for bootstrapping instances). The usage of {@link Variant}s without an instance is an absolute edge-case
|
|
122
|
+
* when deeply using the viewer api and working abroad best practices.
|
|
123
|
+
*/
|
|
124
|
+
get variantInstance() {
|
|
125
|
+
return this._variantInstance;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The id representing a {@link DottedPath}.
|
|
129
|
+
*/
|
|
130
|
+
get id() {
|
|
131
|
+
const dottedPath = dottedPath_1.DottedPath.create(this.dottedPath);
|
|
132
|
+
dottedPath.shiftPart(); // remove root
|
|
133
|
+
return dottedPath.path || '_';
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The defined glTF Asset.
|
|
137
|
+
*/
|
|
138
|
+
get glTF() {
|
|
139
|
+
if (this.structureJson.glTF) {
|
|
140
|
+
if ((0, lodash_es_1.isString)(this.structureJson.glTF)) {
|
|
141
|
+
return {
|
|
142
|
+
rootUrl: this.structureJson.glTF,
|
|
143
|
+
fileName: undefined,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
if ((0, lodash_es_1.isEmpty)(this.structureJson.glTF.rootUrl)) {
|
|
147
|
+
throw new Error(`No "rootUrl" defined in "glTF" definition for variant "${this.id}".`);
|
|
148
|
+
}
|
|
149
|
+
return this.structureJson.glTF;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* The defined glTF URI.
|
|
154
|
+
*/
|
|
155
|
+
get glTFUri() {
|
|
156
|
+
if (this.glTF) {
|
|
157
|
+
return [this.glTF.rootUrl, this.glTF.fileName].join('');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* The inherited defined glTF URI.
|
|
162
|
+
*/
|
|
163
|
+
get inheritedGlTFUri() {
|
|
164
|
+
if (!this.glTFUri && this.parent) {
|
|
165
|
+
return this.parent.inheritedGlTFUri;
|
|
166
|
+
}
|
|
167
|
+
return this.glTFUri;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* The TransformNodes of the {@link Variant}.
|
|
171
|
+
*/
|
|
172
|
+
get nodes() {
|
|
173
|
+
const rootNodes = this.assetContainer
|
|
174
|
+
.getNodes()
|
|
175
|
+
.filter(n => n instanceof transformNode_1.TransformNode && !n.parent);
|
|
176
|
+
return rootNodes;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* The {@link ViewerLight}s of the {@link Variant}.
|
|
180
|
+
*/
|
|
181
|
+
get lights() {
|
|
182
|
+
return this.assetContainer.lights;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* All TransformNodes of the {@link Variant} mapped flat with a {@link DottedPath}.
|
|
186
|
+
*/
|
|
187
|
+
get dottedNodes() {
|
|
188
|
+
if (!this._dottedNodes) {
|
|
189
|
+
const nodes = this.assetContainer.getNodes().filter(n => n instanceof transformNode_1.TransformNode);
|
|
190
|
+
const dottedNodes = new Map();
|
|
191
|
+
nodes.forEach(node => {
|
|
192
|
+
dottedNodes.set(node.metadata.dottedPath, node);
|
|
193
|
+
});
|
|
194
|
+
this._dottedNodes = dottedNodes;
|
|
195
|
+
}
|
|
196
|
+
return this._dottedNodes;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* The Materials of the {@link Variant}.
|
|
200
|
+
*/
|
|
201
|
+
get materials() {
|
|
202
|
+
return this.assetContainer.materials;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* The cloned TransformNodes of all {@link Element}s created for this {@link Variant}.
|
|
206
|
+
*/
|
|
207
|
+
get elementNodes() {
|
|
208
|
+
return this.elements.reduce((a, c) => a.concat(c.nodes), []);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* The cloned TransformNodes of all {@link Element}s created for this {@link Variant} flattened.
|
|
212
|
+
*/
|
|
213
|
+
get elementNodesFlat() {
|
|
214
|
+
return this.elements.reduce((a, c) => [...a, ...c.nodesFlat], []);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* The cloned Meshes of all {@link Element}s created for this {@link Variant} flattened.
|
|
218
|
+
*/
|
|
219
|
+
get elementMeshesFlat() {
|
|
220
|
+
return this.elements.reduce((a, c) => [...a, ...c.meshesFlat], []);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* The cloned Meshes of all {@link Element}s created for this {@link Variant} flattened.
|
|
224
|
+
*/
|
|
225
|
+
get elementAbstractMeshesFlat() {
|
|
226
|
+
return this.elements.reduce((a, c) => [...a, ...c.abstractMeshesFlat], []);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* All {@link Element}s from this {@link Variant}'s parents.
|
|
230
|
+
*/
|
|
231
|
+
get inheritedElements() {
|
|
232
|
+
let elements = [];
|
|
233
|
+
this.ancestors.forEach(ancestor => {
|
|
234
|
+
elements = (0, lodash_es_1.concat)(elements, ancestor.elements);
|
|
235
|
+
});
|
|
236
|
+
return (0, lodash_es_1.concat)(elements, this.elements);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* All {@link ViewerLight}s inherited from this {@link Variant}'s parents.
|
|
240
|
+
*/
|
|
241
|
+
get inheritedViewerLights() {
|
|
242
|
+
let viewerLights = [];
|
|
243
|
+
this.ancestors.forEach(ancestor => {
|
|
244
|
+
viewerLights = (0, lodash_es_1.concat)(viewerLights, ancestor.viewerLights);
|
|
245
|
+
});
|
|
246
|
+
return (0, lodash_es_1.concat)(viewerLights, this.viewerLights);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* All TransformNodes inherited from this {@link Variant}'s parents.
|
|
250
|
+
*/
|
|
251
|
+
get inheritedNodes() {
|
|
252
|
+
let nodes = [];
|
|
253
|
+
this.ancestors.forEach(ancestor => {
|
|
254
|
+
nodes = (0, lodash_es_1.concat)(nodes, ancestor.nodes);
|
|
255
|
+
});
|
|
256
|
+
return (0, lodash_es_1.concat)(nodes, this.nodes);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* All TransformNodes inherited from this {@link Variant}'s parents mapped flat with a {@link DottedPath}.
|
|
260
|
+
*/
|
|
261
|
+
get inheritedDottedNodes() {
|
|
262
|
+
let dottedNodes = this.dottedNodes;
|
|
263
|
+
this.ancestors.forEach(ancestor => {
|
|
264
|
+
dottedNodes = (0, resourceHelper_1.mergeMaps)(dottedNodes, ancestor.dottedNodes);
|
|
265
|
+
});
|
|
266
|
+
return dottedNodes;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* All Lights inherited from this {@link Variant}'s parents.
|
|
270
|
+
*/
|
|
271
|
+
get inheritedLights() {
|
|
272
|
+
let lights = [];
|
|
273
|
+
this.ancestors.forEach(ancestor => {
|
|
274
|
+
lights = (0, lodash_es_1.concat)(lights, ancestor.lights);
|
|
275
|
+
});
|
|
276
|
+
return (0, lodash_es_1.concat)(lights, this.lights);
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* The {@link ParameterDeclarations} inherited from this {@link Variant}'s parents.
|
|
280
|
+
*/
|
|
281
|
+
get inheritedParameterDeclaration() {
|
|
282
|
+
const declaration = {};
|
|
283
|
+
this.ancestors.forEach(ancestor => {
|
|
284
|
+
(0, lodash_es_1.merge)(declaration, ancestor.parameterDeclaration);
|
|
285
|
+
});
|
|
286
|
+
return (0, lodash_es_1.merge)(declaration, this.parameterDeclaration);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* The {@link ParameterBag} inherited from this {@link Variant}'s parents.
|
|
290
|
+
*/
|
|
291
|
+
get inheritedParameters() {
|
|
292
|
+
const parameters = {};
|
|
293
|
+
this.ancestors.forEach(ancestor => {
|
|
294
|
+
(0, lodash_es_1.merge)(parameters, ancestor.parameters);
|
|
295
|
+
});
|
|
296
|
+
return (0, lodash_es_1.merge)(parameters, this.parameters);
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* All Materials from this {@link Variant}'s parents.
|
|
300
|
+
*/
|
|
301
|
+
get inheritedMaterials() {
|
|
302
|
+
let materials = [];
|
|
303
|
+
this.ancestors.forEach(ancestor => {
|
|
304
|
+
materials = (0, lodash_es_1.concat)(materials, ancestor.materials);
|
|
305
|
+
});
|
|
306
|
+
return (0, lodash_es_1.concat)(materials, this.materials);
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Gets the direct children of the current {@link Variant}.
|
|
310
|
+
*/
|
|
311
|
+
getChildren() {
|
|
312
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
313
|
+
const children = [];
|
|
314
|
+
for (const name in this.structureJson.variants) {
|
|
315
|
+
children.push(yield this.getDescendant(name));
|
|
316
|
+
}
|
|
317
|
+
return children;
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Gets a descendant {@link Variant} of the current {@link Variant} relative to its {@link DottedPath}.
|
|
322
|
+
* If you have the dotted path `_.product_x.variant_blue.with_yellow_highlight` in a tree and you operate on the
|
|
323
|
+
* `product_x`, you can call `this.getDescendant('variant_blue.with_yellow_highlight')` to get the lowermost
|
|
324
|
+
* {@link Variant}.
|
|
325
|
+
*/
|
|
326
|
+
getDescendant(dottedPath) {
|
|
327
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
328
|
+
const _dottedPath = dottedPath_1.DottedPath.create(dottedPath);
|
|
329
|
+
const [name, ...descendantParts] = _dottedPath.parts;
|
|
330
|
+
let variant;
|
|
331
|
+
if (this._children.has(name)) {
|
|
332
|
+
variant = this._children.get(name);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
if (!this.structureJson.variants) {
|
|
336
|
+
throw new Error(`Missing key "variants" in JSON structure for variant "${this.id}".`);
|
|
337
|
+
}
|
|
338
|
+
if (!this.structureJson.variants[name]) {
|
|
339
|
+
throw new Error(`Variant "${_dottedPath.path}" not defined in JSON structure for variant "${this.id}".`);
|
|
340
|
+
}
|
|
341
|
+
if (this.structureJson.variants[name].file) {
|
|
342
|
+
const file = this.structureJson.variants[name].file;
|
|
343
|
+
variant = yield Variant.create(this.variantInstance, name, yield (0, resourceHelper_1.loadJson)(file), this.viewer, this);
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
variant = yield Variant.create(this.variantInstance, name, this.structureJson.variants[name], this.viewer, this);
|
|
347
|
+
}
|
|
348
|
+
this._children.set(name, variant);
|
|
349
|
+
}
|
|
350
|
+
if (!variant) {
|
|
351
|
+
throw new Error(`Variant "${_dottedPath.path}" was not created.`);
|
|
352
|
+
}
|
|
353
|
+
if (descendantParts.length > 0) {
|
|
354
|
+
return yield variant.getDescendant(dottedPath_1.DottedPath.createFromParts(descendantParts));
|
|
355
|
+
}
|
|
356
|
+
return variant;
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Gets the desired {@link Element} of the current {@link Variant} relative to its {@link DottedPath}.
|
|
361
|
+
* Uses the mechanism of {@link getDescendant} to resolve the appropriate variant in tree.
|
|
362
|
+
*/
|
|
363
|
+
getElement(dottedPath) {
|
|
364
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
365
|
+
const _dottedPath = dottedPath_1.DottedPath.create(dottedPath);
|
|
366
|
+
const elementName = _dottedPath.popPart();
|
|
367
|
+
let variant = this;
|
|
368
|
+
if (_dottedPath.parts.length > 0) {
|
|
369
|
+
variant = yield this.getDescendant(_dottedPath);
|
|
370
|
+
}
|
|
371
|
+
if (variant.inheritedElements.length === 0) {
|
|
372
|
+
throw new Error(`No elements for variant "${variant.id}" found. ` +
|
|
373
|
+
`Either none are defined or they are not initialized (are you operating on the appropriate living?).`);
|
|
374
|
+
}
|
|
375
|
+
let element;
|
|
376
|
+
variant.inheritedElements.forEach(_element => {
|
|
377
|
+
if (_element.name === elementName) {
|
|
378
|
+
element = _element;
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
if (!element) {
|
|
382
|
+
throw new Error(`Element with name "${elementName}" does not exist for variant "${variant.id}".`);
|
|
383
|
+
}
|
|
384
|
+
return element;
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Gets the desired {@link ViewerLight} of the current {@link Variant} relative to its {@link DottedPath}.
|
|
389
|
+
* Uses the mechanism of {@link getDescendant} to resolve the appropriate variant in tree.
|
|
390
|
+
*/
|
|
391
|
+
getViewerLight(dottedPath) {
|
|
392
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
393
|
+
const _dottedPath = dottedPath_1.DottedPath.create(dottedPath);
|
|
394
|
+
const viewerLightName = _dottedPath.popPart();
|
|
395
|
+
let variant = this;
|
|
396
|
+
if (_dottedPath.parts.length > 0) {
|
|
397
|
+
variant = yield this.getDescendant(_dottedPath);
|
|
398
|
+
}
|
|
399
|
+
if (variant.inheritedViewerLights.length === 0) {
|
|
400
|
+
throw new Error(`No viewerLights for variant "${variant.id}" found. ` +
|
|
401
|
+
`Either none are defined or they are not initialized (are you operating on the appropriate living?).`);
|
|
402
|
+
}
|
|
403
|
+
let viewerLight;
|
|
404
|
+
variant.inheritedViewerLights.forEach(_viewerLight => {
|
|
405
|
+
if (_viewerLight.name === viewerLightName) {
|
|
406
|
+
viewerLight = _viewerLight;
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
if (!viewerLight) {
|
|
410
|
+
throw new Error(`ViewerLight with name "${viewerLightName}" does not exist for variant "${variant.id}".`);
|
|
411
|
+
}
|
|
412
|
+
return viewerLight;
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* A proxy for directly getting a Node from an {@link Element} by its {@link DottedPath}s.
|
|
417
|
+
*/
|
|
418
|
+
getNode(elementDottedPath, nodeDottedPath) {
|
|
419
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
420
|
+
const element = yield this.getElement(elementDottedPath);
|
|
421
|
+
return element.getNode(nodeDottedPath);
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* A proxy for directly getting a Mesh from an {@link Element} by its {@link DottedPath}s.
|
|
426
|
+
*/
|
|
427
|
+
getMesh(elementDottedPath, meshDottedPath) {
|
|
428
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
429
|
+
const element = yield this.getElement(elementDottedPath);
|
|
430
|
+
return element.getMesh(meshDottedPath);
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Creates a living clone of this {@link Variant}. Will clone all parent {@link Variant}s in tree.
|
|
435
|
+
*
|
|
436
|
+
* @emit {@link Event.VARIANT_CREATED}
|
|
437
|
+
* @ignore
|
|
438
|
+
*/
|
|
439
|
+
createLiving(variantInstance, parameters) {
|
|
440
|
+
var _a;
|
|
441
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
442
|
+
const parent = yield ((_a = this.parent) === null || _a === void 0 ? void 0 : _a.createLiving(variantInstance));
|
|
443
|
+
const variant = new Variant(variantInstance, this.name, this._structureJson, this.viewer, parent);
|
|
444
|
+
parent === null || parent === void 0 ? void 0 : parent._children.set(variant.name, variant);
|
|
445
|
+
variant.assetContainer = this.assetContainer;
|
|
446
|
+
variant.parameterObservers = (0, lodash_es_1.cloneDeep)(this.parameterObservers);
|
|
447
|
+
yield variant.createElements();
|
|
448
|
+
yield variant.createViewerLights();
|
|
449
|
+
variant.addParameterObservers();
|
|
450
|
+
yield variant.bootstrapParameters(parameters);
|
|
451
|
+
this.viewer.broadcastEvent(event_1.Event.VARIANT_CREATED, variant);
|
|
452
|
+
return variant;
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Destroys this {@link Variant}, all parents and destroy the {@link Element}s.
|
|
457
|
+
*/
|
|
458
|
+
destroy() {
|
|
459
|
+
this.elements.forEach(element => element.destroy());
|
|
460
|
+
if (this.parent) {
|
|
461
|
+
this.parent.destroy();
|
|
462
|
+
}
|
|
463
|
+
this.broadcastEvent(event_1.Event.VARIANT_DESTROYED, this);
|
|
464
|
+
return this;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Places the given {@link ParameterBag} in the {@link Variant}'s parameters, replaces all patterns in the
|
|
468
|
+
* {@link StructureJson}, broadcasts all {@link ParameterObserver}s and delegates them to its {@link Element}s.
|
|
469
|
+
*
|
|
470
|
+
* @emit {@link Event.VARIANT_PARAMETER_COMMITTED}
|
|
471
|
+
*/
|
|
472
|
+
commitParameters(parameters) {
|
|
473
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
474
|
+
parameters = (0, lodash_es_1.merge)({}, parameters);
|
|
475
|
+
// remember old parameter values for later comparison
|
|
476
|
+
const oldParameters = (0, lodash_es_1.cloneDeep)(this.inheritedParameters);
|
|
477
|
+
// replace patterns in given parameters
|
|
478
|
+
let _parameters = JSON.stringify(parameters);
|
|
479
|
+
for (const parameter in this.inheritedParameters) {
|
|
480
|
+
const value = this.inheritedParameters[parameter];
|
|
481
|
+
const search = new RegExp(`\\$\\{${parameter}\\}`, 'g');
|
|
482
|
+
_parameters = _parameters.replace(search, value.toString());
|
|
483
|
+
}
|
|
484
|
+
(0, lodash_es_1.merge)(parameters, JSON.parse(_parameters));
|
|
485
|
+
// merge inherited parameters and replaced given parameters
|
|
486
|
+
const mergedParameters = (0, lodash_es_1.merge)({}, this.inheritedParameters, parameters);
|
|
487
|
+
// replace patterns in structure parameters
|
|
488
|
+
const structureParameters = this._structureJson.parameters || {};
|
|
489
|
+
let _structureParameters = JSON.stringify(structureParameters);
|
|
490
|
+
for (const parameter in mergedParameters) {
|
|
491
|
+
const value = mergedParameters[parameter];
|
|
492
|
+
const search = new RegExp(`\\$\\{${parameter}\\}`, 'g');
|
|
493
|
+
_structureParameters = _structureParameters.replace(search, value.toString());
|
|
494
|
+
}
|
|
495
|
+
const replacedStructureParameters = JSON.parse(_structureParameters);
|
|
496
|
+
// calculate which replaced structure parameters have changed and should overload given parameters
|
|
497
|
+
const differentStructureParameters = {};
|
|
498
|
+
for (const parameter in replacedStructureParameters) {
|
|
499
|
+
if (!(0, lodash_es_1.isEqual)(structureParameters[parameter], replacedStructureParameters[parameter])) {
|
|
500
|
+
differentStructureParameters[parameter] = replacedStructureParameters[parameter];
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
// merge replaced structure parameters and given inherited parameters to structure parameters
|
|
504
|
+
(0, lodash_es_1.merge)(this.parameters, mergedParameters, differentStructureParameters);
|
|
505
|
+
// inherited parameters are now the new parameters to process
|
|
506
|
+
const newParameters = this.inheritedParameters;
|
|
507
|
+
// replace all parameter patterns in structure json
|
|
508
|
+
let structure = JSON.stringify(this._structureJson);
|
|
509
|
+
for (const parameter in newParameters) {
|
|
510
|
+
const value = newParameters[parameter];
|
|
511
|
+
const search = new RegExp(`\\$\\{${parameter}\\}`, 'g');
|
|
512
|
+
structure = structure.replace(search, value.toString());
|
|
513
|
+
}
|
|
514
|
+
this.structureJson = JSON.parse(structure);
|
|
515
|
+
// handle parameter observers
|
|
516
|
+
let observerPromises = [];
|
|
517
|
+
for (const parameter in newParameters) {
|
|
518
|
+
const oldParameterValue = oldParameters[parameter];
|
|
519
|
+
const newParameterValue = newParameters[parameter];
|
|
520
|
+
this.assertParameter(this.inheritedParameterDeclaration, parameter, newParameterValue);
|
|
521
|
+
if (oldParameterValue === newParameterValue && this.parametersInitialized) {
|
|
522
|
+
continue;
|
|
523
|
+
}
|
|
524
|
+
// parameter changed
|
|
525
|
+
const parameterObservers = (0, resourceHelper_1.mergeMaps)(this._parameterObservers, this.parameterObservers);
|
|
526
|
+
if (parameterObservers.has(parameter)) {
|
|
527
|
+
const observers = parameterObservers.get(parameter);
|
|
528
|
+
observerPromises = (0, lodash_es_1.concat)(observerPromises, observers.map(observer => {
|
|
529
|
+
const observerResult = observer(this, oldParameterValue, newParameterValue);
|
|
530
|
+
return Promise.resolve(observerResult).then(() => {
|
|
531
|
+
if (this.parametersInitialized) {
|
|
532
|
+
this.broadcastEvent(event_1.Event.VARIANT_PARAMETER_COMMITTED, this, parameter, oldParameterValue, newParameterValue);
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
}));
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
yield Promise.all(observerPromises);
|
|
539
|
+
// broadcast that bag has been committed
|
|
540
|
+
this.broadcastEvent(event_1.Event.VARIANT_PARAMETER_BAG_COMMITTED, this, oldParameters, newParameters);
|
|
541
|
+
// commit parameters to elements
|
|
542
|
+
yield this.commitParametersToElements(newParameters);
|
|
543
|
+
// commit parameters to lights
|
|
544
|
+
yield this.commitParametersToViewerLights(newParameters);
|
|
545
|
+
// propagate parameters to parent
|
|
546
|
+
if (this.parent) {
|
|
547
|
+
yield this.parent.commitParameters(this.parameters);
|
|
548
|
+
}
|
|
549
|
+
return this;
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Adds an observer function for camera matrix changes for given `dottedPath` representing the {@link Element}
|
|
554
|
+
* and the `traceable`. The `observer` gets 2 parameters: the `AbstractMesh` and a `ClientRect` object.
|
|
555
|
+
*/
|
|
556
|
+
addTraceableObserver(dottedPath, observer, payload) {
|
|
557
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
558
|
+
const _dottedPath = dottedPath_1.DottedPath.create(dottedPath);
|
|
559
|
+
const traceableName = _dottedPath.popPart();
|
|
560
|
+
if (!traceableName) {
|
|
561
|
+
throw new Error(`The dottedPath must consist of the element and the name of the defined corresponding ` +
|
|
562
|
+
`traceable ("${_dottedPath.path}" given).`);
|
|
563
|
+
}
|
|
564
|
+
const element = yield this.getElement(_dottedPath);
|
|
565
|
+
return element.addTraceableObserver(traceableName, observer, payload);
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Loads {@link glTFUri} with assets, adds them to the {@link Variant}'s `assetContainer` and deactivates the meshes.
|
|
570
|
+
* (for further processing).
|
|
571
|
+
* @emits {@link Event.ASSET_LOADING_START}
|
|
572
|
+
* @emits {@link Event.ASSET_LOADING_END}
|
|
573
|
+
*/
|
|
574
|
+
loadAssets() {
|
|
575
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
576
|
+
this.broadcastEvent(event_1.Event.ASSET_LOADING_START, this);
|
|
577
|
+
return new Promise((resolve, reject) => {
|
|
578
|
+
if (!this.structureJson) {
|
|
579
|
+
this.broadcastEvent(event_1.Event.ASSET_LOADING_END, this);
|
|
580
|
+
return resolve(this);
|
|
581
|
+
}
|
|
582
|
+
if (!this.glTF) {
|
|
583
|
+
this.broadcastEvent(event_1.Event.ASSET_LOADING_END, this);
|
|
584
|
+
return resolve(this);
|
|
585
|
+
}
|
|
586
|
+
sceneLoader_1.SceneLoader.LoadAssetContainer(this.glTF.rootUrl, this.glTF.fileName, this.viewer.scene,
|
|
587
|
+
// on success
|
|
588
|
+
container => {
|
|
589
|
+
this.assetContainer = container;
|
|
590
|
+
const nodes = this.assetContainer.getNodes().filter(n => n instanceof transformNode_1.TransformNode);
|
|
591
|
+
(0, babylonHelper_1.reportDuplicateNodeNames)((0, babylonHelper_1.intersectingNodeNames)(nodes, this.viewer.scene.getNodes(), n => n instanceof transformNode_1.TransformNode));
|
|
592
|
+
nodes.forEach(node => {
|
|
593
|
+
(0, babylonHelper_1.deactivateTransformNode)(node, false);
|
|
594
|
+
(0, babylonHelper_1.injectMetadata)(node, { dottedPath: (0, babylonHelper_1.getDottedPathForNode)(node), originalName: node.name }, false);
|
|
595
|
+
});
|
|
596
|
+
this.assetContainer.lights.forEach(light => {
|
|
597
|
+
light.setEnabled(false);
|
|
598
|
+
(0, babylonHelper_1.injectMetadata)(light, { dottedPath: (0, babylonHelper_1.getDottedPathForNode)(light), originalName: light.name }, false);
|
|
599
|
+
this.viewer.scene.addLight(light);
|
|
600
|
+
});
|
|
601
|
+
this.assetContainer.cameras.forEach(camera => {
|
|
602
|
+
camera.setEnabled(false);
|
|
603
|
+
(0, babylonHelper_1.injectMetadata)(camera, { dottedPath: (0, babylonHelper_1.getDottedPathForNode)(camera), originalName: camera.name }, false);
|
|
604
|
+
this.viewer.scene.addCamera(camera);
|
|
605
|
+
});
|
|
606
|
+
this.assetContainer.materials.forEach(material => this.viewer.scene.materials.push(material));
|
|
607
|
+
this.assetContainer.textures.forEach(texture => this.viewer.scene.textures.push(texture));
|
|
608
|
+
this.assetContainer.skeletons.forEach(skeleton => this.viewer.scene.skeletons.push(skeleton));
|
|
609
|
+
this.broadcastEvent(event_1.Event.ASSET_LOADING_END, this);
|
|
610
|
+
resolve(this);
|
|
611
|
+
},
|
|
612
|
+
// on progress
|
|
613
|
+
undefined,
|
|
614
|
+
// on error
|
|
615
|
+
(scene, msg, exc) => {
|
|
616
|
+
this.broadcastEvent(event_1.Event.ASSET_LOADING_END, this);
|
|
617
|
+
/**
|
|
618
|
+
* @preserve (4 webpack terser plugin)
|
|
619
|
+
* If you're here and the shown error doesn't seem to make any sense:
|
|
620
|
+
* BJS "swallows" all exceptions within our success callback above and reports some generic error like
|
|
621
|
+
* "Unable to load from https://some/url.babylon" etc.
|
|
622
|
+
* -> The real reason for the error **could** be that some of our code within the above success callback has
|
|
623
|
+
* thrown.
|
|
624
|
+
*/
|
|
625
|
+
const error = new viewerError_1.ViewerError({
|
|
626
|
+
id: viewerError_1.ViewerErrorIds.AssetLoadingFailed,
|
|
627
|
+
message: `Error loading assets for variant "${this.id}": ${msg}.`,
|
|
628
|
+
});
|
|
629
|
+
reject(error);
|
|
630
|
+
});
|
|
631
|
+
});
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Commits given parameters to all {@link Element}s.
|
|
636
|
+
*/
|
|
637
|
+
commitParametersToElements(parameters) {
|
|
638
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
639
|
+
yield Promise.all(this.elements.map(element => this.commitParametersToVariantParameterizable(parameters, element, 'elements')));
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Commits given parameters to all {@link ViewerLight}s.
|
|
644
|
+
*/
|
|
645
|
+
commitParametersToViewerLights(parameters) {
|
|
646
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
647
|
+
yield Promise.all(this.viewerLights.map(viewerLight => this.commitParametersToVariantParameterizable(parameters, viewerLight, 'lights')));
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Commits given parameters to a {@link VariantParameterizable} and updates the according definition with given
|
|
652
|
+
* key in the {@link StructureJson}. The `definitionKey` "elements" for example will update the definition in
|
|
653
|
+
* `this.structureJson.elements`.
|
|
654
|
+
*/
|
|
655
|
+
commitParametersToVariantParameterizable(parameters, parameterizable, definitionKey) {
|
|
656
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
657
|
+
const initialDefinition = (0, lodash_es_1.get)(this._structureJson, definitionKey)[parameterizable.name];
|
|
658
|
+
let initialDefinitionStr = JSON.stringify(initialDefinition);
|
|
659
|
+
const _parameters = {};
|
|
660
|
+
for (const parameter in parameters) {
|
|
661
|
+
const dpp = dottedPath_1.DottedPath.create(parameter);
|
|
662
|
+
if (dpp.shiftPart() !== parameterizable.name) {
|
|
663
|
+
continue;
|
|
664
|
+
}
|
|
665
|
+
// we got a parameterizable ("element") parameter
|
|
666
|
+
let parameterValue = parameters[parameter];
|
|
667
|
+
const parameterizableParameter = dpp.path;
|
|
668
|
+
// If the variant is explicitly hidden, we must not override the visibility with element parameters. We need
|
|
669
|
+
// an exception for visibility to avoid overloading already applied element parameters with element parameters
|
|
670
|
+
// defined in the variant spec ("dotted parameters").
|
|
671
|
+
// @see https://github.com/Combeenation/3d-viewer/issues/44
|
|
672
|
+
const visibleParamValue = parameters[parameter_1.Parameter.VISIBLE];
|
|
673
|
+
const isVisible = undefined === visibleParamValue || parameter_1.Parameter.parseBoolean(visibleParamValue);
|
|
674
|
+
if (parameterizableParameter === parameter_1.Parameter.VISIBLE && !isVisible) {
|
|
675
|
+
parameterValue = false;
|
|
676
|
+
}
|
|
677
|
+
_parameters[parameterizableParameter] = parameterValue;
|
|
678
|
+
const search = new RegExp(`\\$\\{${parameterizableParameter}\\}`, 'g');
|
|
679
|
+
initialDefinitionStr = initialDefinitionStr.replace(search, parameterValue.toString());
|
|
680
|
+
}
|
|
681
|
+
const definition = (0, lodash_es_1.get)(this.structureJson, definitionKey);
|
|
682
|
+
definition[this.name] = JSON.parse(initialDefinitionStr);
|
|
683
|
+
(0, lodash_es_1.set)(this.structureJson, definitionKey, definition);
|
|
684
|
+
return yield parameterizable.commitParameters(_parameters);
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Commits given {@link Parameter} to the {@link Variant}'s {@link Element}s.
|
|
689
|
+
*/
|
|
690
|
+
commitParameterToElements(parameter, value) {
|
|
691
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
692
|
+
const promises = [];
|
|
693
|
+
for (const element of this.elements) {
|
|
694
|
+
const paramShowsVariant = parameter_1.Parameter.VISIBLE === parameter && value;
|
|
695
|
+
// Fixes https://combeenation.youtrack.cloud/issue/CB-7773
|
|
696
|
+
// Don't enable/show the variants element if it is explicitly hidden via its element parameters.
|
|
697
|
+
// E.g. via spec:
|
|
698
|
+
// ```
|
|
699
|
+
// variants: {
|
|
700
|
+
// theVariant: {
|
|
701
|
+
// elements: {
|
|
702
|
+
// Main: ['root.main'],
|
|
703
|
+
// Secondary: ['root.secondary'],
|
|
704
|
+
// },
|
|
705
|
+
// parameters: {
|
|
706
|
+
// // !!! The element `Secondary` should **not** be enabled when its containing variant is enabled !!!
|
|
707
|
+
// 'Secondary.visible': false,
|
|
708
|
+
// }
|
|
709
|
+
// }
|
|
710
|
+
// }
|
|
711
|
+
// ```
|
|
712
|
+
const elVisibleParamPath = dottedPath_1.DottedPath.create([element.name, parameter_1.Parameter.VISIBLE]).toString();
|
|
713
|
+
const elVisibleParamValue = this.inheritedParameters[elVisibleParamPath];
|
|
714
|
+
const elVisibleParamValueParsed = elVisibleParamValue && parameter_1.Parameter.parseBoolean(elVisibleParamValue);
|
|
715
|
+
const elIsHiddenViaParams = elVisibleParamValueParsed === false;
|
|
716
|
+
if (paramShowsVariant && elIsHiddenViaParams)
|
|
717
|
+
continue;
|
|
718
|
+
// Fixes https://combeenation.youtrack.cloud/issue/CB-7809
|
|
719
|
+
// Apply element material before showing the element to prevent loading of the elements "original" material which
|
|
720
|
+
// is never shown when "overwritten" by elements material param.
|
|
721
|
+
const elMaterialParamPath = dottedPath_1.DottedPath.create([element.name, parameter_1.Parameter.MATERIAL]).toString();
|
|
722
|
+
const elMaterialParamValue = this.inheritedParameters[elMaterialParamPath];
|
|
723
|
+
if (paramShowsVariant && elMaterialParamValue) {
|
|
724
|
+
yield element.commitParameter(parameter_1.Parameter.MATERIAL, elMaterialParamValue);
|
|
725
|
+
}
|
|
726
|
+
promises.push(element.commitParameter(parameter, value));
|
|
727
|
+
}
|
|
728
|
+
yield Promise.all(promises);
|
|
729
|
+
return this;
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Commits given {@link Parameter} to the {@link Variant}'s {@link Element}s.
|
|
734
|
+
*/
|
|
735
|
+
commitParameterToViewerLights(parameter, value) {
|
|
736
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
737
|
+
const promises = [];
|
|
738
|
+
for (const viewerLight of this.viewerLights) {
|
|
739
|
+
promises.push(viewerLight.commitParameter(parameter, value));
|
|
740
|
+
}
|
|
741
|
+
yield Promise.all(promises);
|
|
742
|
+
return this;
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
/**
|
|
746
|
+
* Adds the default {@link ParameterObserver}s which are called every time {@link commitParameters} is called.
|
|
747
|
+
*/
|
|
748
|
+
addParameterObservers() {
|
|
749
|
+
this._parameterObservers.set(parameter_1.Parameter.VISIBLE, [
|
|
750
|
+
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
751
|
+
yield variant.commitParameterToElements(parameter_1.Parameter.VISIBLE, newValue);
|
|
752
|
+
yield variant.commitParameterToViewerLights(parameter_1.Parameter.VISIBLE, newValue);
|
|
753
|
+
}),
|
|
754
|
+
]);
|
|
755
|
+
this._parameterObservers.set(parameter_1.Parameter.SCALING, [
|
|
756
|
+
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
757
|
+
yield variant.commitParameterToElements(parameter_1.Parameter.SCALING, newValue);
|
|
758
|
+
yield variant.commitParameterToViewerLights(parameter_1.Parameter.SCALING, newValue);
|
|
759
|
+
}),
|
|
760
|
+
]);
|
|
761
|
+
this._parameterObservers.set(parameter_1.Parameter.MATERIAL, [
|
|
762
|
+
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
763
|
+
yield variant.commitParameterToElements(parameter_1.Parameter.MATERIAL, newValue);
|
|
764
|
+
}),
|
|
765
|
+
]);
|
|
766
|
+
this._parameterObservers.set(parameter_1.Parameter.MATERIAL_COLOR, [
|
|
767
|
+
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
768
|
+
yield variant.commitParameterToElements(parameter_1.Parameter.MATERIAL_COLOR, newValue);
|
|
769
|
+
}),
|
|
770
|
+
]);
|
|
771
|
+
this._parameterObservers.set(parameter_1.Parameter.MATERIAL_METALLNESS, [
|
|
772
|
+
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
773
|
+
yield variant.commitParameterToElements(parameter_1.Parameter.MATERIAL_METALLNESS, newValue);
|
|
774
|
+
}),
|
|
775
|
+
]);
|
|
776
|
+
this._parameterObservers.set(parameter_1.Parameter.MATERIAL_ROUGHNESS, [
|
|
777
|
+
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
778
|
+
yield variant.commitParameterToElements(parameter_1.Parameter.MATERIAL_ROUGHNESS, newValue);
|
|
779
|
+
}),
|
|
780
|
+
]);
|
|
781
|
+
this._parameterObservers.set(parameter_1.Parameter.HIGHLIGHT_COLOR, [
|
|
782
|
+
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
783
|
+
yield variant.commitParameterToElements(parameter_1.Parameter.HIGHLIGHT_COLOR, newValue);
|
|
784
|
+
}),
|
|
785
|
+
]);
|
|
786
|
+
this._parameterObservers.set(parameter_1.Parameter.HIGHLIGHTED, [
|
|
787
|
+
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
788
|
+
yield variant.commitParameterToElements(parameter_1.Parameter.HIGHLIGHTED, newValue);
|
|
789
|
+
}),
|
|
790
|
+
]);
|
|
791
|
+
this._parameterObservers.set(parameter_1.Parameter.POSITION, [
|
|
792
|
+
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
793
|
+
yield variant.commitParameterToElements(parameter_1.Parameter.POSITION, newValue);
|
|
794
|
+
yield variant.commitParameterToViewerLights(parameter_1.Parameter.POSITION, newValue);
|
|
795
|
+
}),
|
|
796
|
+
]);
|
|
797
|
+
this._parameterObservers.set(parameter_1.Parameter.ROTATION, [
|
|
798
|
+
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
799
|
+
yield variant.commitParameterToElements(parameter_1.Parameter.ROTATION, newValue);
|
|
800
|
+
yield variant.commitParameterToViewerLights(parameter_1.Parameter.ROTATION, newValue);
|
|
801
|
+
}),
|
|
802
|
+
]);
|
|
803
|
+
this._parameterObservers.set(parameter_1.Parameter.CAST_SHADOW, [
|
|
804
|
+
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
805
|
+
yield variant.commitParameterToElements(parameter_1.Parameter.CAST_SHADOW, newValue);
|
|
806
|
+
}),
|
|
807
|
+
]);
|
|
808
|
+
this._parameterObservers.set(parameter_1.Parameter.CAST_SHADOW_FROM_LIGHTS, [
|
|
809
|
+
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
810
|
+
yield variant.commitParameterToElements(parameter_1.Parameter.CAST_SHADOW_FROM_LIGHTS, newValue);
|
|
811
|
+
}),
|
|
812
|
+
]);
|
|
813
|
+
this._parameterObservers.set(parameter_1.Parameter.RECEIVE_SHADOWS, [
|
|
814
|
+
(variant, oldValue, newValue) => __awaiter(this, void 0, void 0, function* () {
|
|
815
|
+
yield variant.commitParameterToElements(parameter_1.Parameter.RECEIVE_SHADOWS, newValue);
|
|
816
|
+
}),
|
|
817
|
+
]);
|
|
818
|
+
return this;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Creates {@link Element}s and clones nodes into them.
|
|
822
|
+
*/
|
|
823
|
+
createElements(forInstance) {
|
|
824
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
825
|
+
this.createElementDefinitionsIfNotExist();
|
|
826
|
+
for (const name in this.structureJson.elements || {}) {
|
|
827
|
+
this.elements.push(yield element_1.Element.create(this, name));
|
|
828
|
+
}
|
|
829
|
+
// inject node meta to all inherited elements
|
|
830
|
+
// we do this to inject the deepest and most concrete variant information to all cloned nodes in the tree
|
|
831
|
+
this.inheritedElements.forEach(element => element.nodes.forEach(node => (0, babylonHelper_1.injectMetadata)(node, { variant: this, variantParameterizable: element })));
|
|
832
|
+
return this;
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
/**
|
|
836
|
+
* Creates {@link ViewerLight}s.
|
|
837
|
+
*/
|
|
838
|
+
createViewerLights() {
|
|
839
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
840
|
+
for (const name in this.structureJson.lights || {}) {
|
|
841
|
+
this.viewerLights.push(yield viewerLight_1.ViewerLight.create(this, name));
|
|
842
|
+
}
|
|
843
|
+
this.inheritedViewerLights.forEach(viewerLight => {
|
|
844
|
+
(0, babylonHelper_1.injectMetadata)(viewerLight.light, { variant: this, variantParameterizable: viewerLight });
|
|
845
|
+
});
|
|
846
|
+
return this;
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Bootstrapping for parameters. It sets the `parametersInitialized` to true for all ancestors.
|
|
851
|
+
*/
|
|
852
|
+
bootstrapParameters(parameters) {
|
|
853
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
854
|
+
yield this.commitParameters((0, lodash_es_1.merge)((0, lodash_es_1.cloneDeep)(this.parameters), parameters));
|
|
855
|
+
(0, lodash_es_1.concat)(this.ancestors, this).forEach(ancestor => (ancestor.parametersInitialized = true));
|
|
856
|
+
return this;
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
/**
|
|
860
|
+
* Ensures there is at least one "Main" {@link Element} for the {@link Variant} with all "root nodes" defined in path.
|
|
861
|
+
*/
|
|
862
|
+
createElementDefinitionsIfNotExist() {
|
|
863
|
+
if (this._structureJson.elements || this.inheritedNodes.length === 0) {
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
this._structureJson.elements = {
|
|
867
|
+
Main: { paths: { include: this.inheritedNodes.map(node => node.metadata.dottedPath.path) } },
|
|
868
|
+
};
|
|
869
|
+
this.structureJson.elements = (0, lodash_es_1.cloneDeep)(this._structureJson.elements);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
exports.Variant = Variant;
|
|
873
873
|
//# sourceMappingURL=variant.js.map
|