@combeenation/3d-viewer 6.4.1-beta1 → 7.0.0-beta1
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/dist/lib-cjs/api/classes/element.d.ts +4 -0
- package/dist/lib-cjs/api/classes/element.js +59 -58
- package/dist/lib-cjs/api/classes/element.js.map +1 -1
- package/dist/lib-cjs/api/classes/event.d.ts +55 -1
- package/dist/lib-cjs/api/classes/event.js +55 -1
- package/dist/lib-cjs/api/classes/event.js.map +1 -1
- package/dist/lib-cjs/api/classes/fuzzyMap.d.ts +7 -0
- package/dist/lib-cjs/api/classes/fuzzyMap.js +22 -0
- package/dist/lib-cjs/api/classes/fuzzyMap.js.map +1 -0
- package/dist/lib-cjs/api/classes/parameter.d.ts +12 -0
- package/dist/lib-cjs/api/classes/parameter.js +86 -33
- package/dist/lib-cjs/api/classes/parameter.js.map +1 -1
- package/dist/lib-cjs/api/classes/parameterObservable.js +2 -27
- package/dist/lib-cjs/api/classes/parameterObservable.js.map +1 -1
- package/dist/lib-cjs/api/classes/variant.d.ts +23 -4
- package/dist/lib-cjs/api/classes/variant.js +45 -20
- package/dist/lib-cjs/api/classes/variant.js.map +1 -1
- package/dist/lib-cjs/api/classes/variantInstance.d.ts +11 -2
- package/dist/lib-cjs/api/classes/variantInstance.js +22 -2
- package/dist/lib-cjs/api/classes/variantInstance.js.map +1 -1
- package/dist/lib-cjs/api/classes/viewer.d.ts +13 -1
- package/dist/lib-cjs/api/classes/viewer.js +57 -7
- package/dist/lib-cjs/api/classes/viewer.js.map +1 -1
- package/dist/lib-cjs/api/classes/viewerLight.js.map +1 -1
- package/dist/lib-cjs/api/manager/animationManager.d.ts +3 -3
- package/dist/lib-cjs/api/manager/animationManager.js.map +1 -1
- package/dist/lib-cjs/api/manager/sceneManager.js.map +1 -1
- package/dist/lib-cjs/api/manager/tagManager.d.ts +108 -0
- package/dist/lib-cjs/api/manager/tagManager.js +420 -0
- package/dist/lib-cjs/api/manager/tagManager.js.map +1 -0
- package/dist/lib-cjs/api/manager/variantInstanceManager.d.ts +8 -3
- package/dist/lib-cjs/api/manager/variantInstanceManager.js +27 -8
- package/dist/lib-cjs/api/manager/variantInstanceManager.js.map +1 -1
- package/dist/lib-cjs/api/store/specStorage.d.ts +8 -0
- package/dist/lib-cjs/api/store/specStorage.js +15 -0
- package/dist/lib-cjs/api/store/specStorage.js.map +1 -1
- package/dist/lib-cjs/api/util/babylonHelper.d.ts +36 -7
- package/dist/lib-cjs/api/util/babylonHelper.js +92 -15
- package/dist/lib-cjs/api/util/babylonHelper.js.map +1 -1
- package/dist/lib-cjs/api/util/globalTypes.d.ts +38 -1
- package/dist/lib-cjs/api/util/sceneLoaderHelper.d.ts +1 -0
- package/dist/lib-cjs/api/util/sceneLoaderHelper.js +20 -2
- package/dist/lib-cjs/api/util/sceneLoaderHelper.js.map +1 -1
- package/dist/lib-cjs/buildinfo.json +1 -1
- package/dist/lib-cjs/commonjs.tsconfig.tsbuildinfo +1 -1
- package/dist/lib-cjs/index.d.ts +3 -1
- package/dist/lib-cjs/index.js +5 -1
- package/dist/lib-cjs/index.js.map +1 -1
- package/package.json +1 -1
- package/src/api/classes/element.ts +96 -82
- package/src/api/classes/event.ts +68 -1
- package/src/api/classes/fuzzyMap.ts +21 -0
- package/src/api/classes/parameter.ts +91 -34
- package/src/api/classes/parameterObservable.ts +2 -29
- package/src/api/classes/variant.ts +82 -33
- package/src/api/classes/variantInstance.ts +27 -1
- package/src/api/classes/viewer.ts +63 -12
- package/src/api/classes/viewerLight.ts +10 -10
- package/src/api/manager/animationManager.ts +2 -2
- package/src/api/manager/sceneManager.ts +5 -1
- package/src/api/manager/tagManager.ts +451 -0
- package/src/api/manager/variantInstanceManager.ts +35 -8
- package/src/api/store/specStorage.ts +17 -0
- package/src/api/util/babylonHelper.ts +99 -21
- package/src/api/util/globalTypes.ts +56 -1
- package/src/api/util/sceneLoaderHelper.ts +21 -2
- package/src/dev.ts +3 -1
- package/src/index.ts +4 -0
- package/src/types.d.ts +7 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DottedPath } from '../classes/dottedPath';
|
|
2
|
+
import { Event, emitter } from '../classes/event';
|
|
2
3
|
import { defaultEnvHelperColor, defaultSceneClearColor } from '../internal/sceneSetup';
|
|
3
4
|
import {
|
|
4
5
|
addMissingMaterialObserver,
|
|
@@ -23,11 +24,12 @@ import { InstancedMesh } from '@babylonjs/core/Meshes/instancedMesh';
|
|
|
23
24
|
import { Mesh } from '@babylonjs/core/Meshes/mesh';
|
|
24
25
|
import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
|
|
25
26
|
import { Observable } from '@babylonjs/core/Misc/observable';
|
|
27
|
+
import { Tags } from '@babylonjs/core/Misc/tags';
|
|
26
28
|
import { Tools } from '@babylonjs/core/Misc/tools';
|
|
27
29
|
import { Node } from '@babylonjs/core/node';
|
|
28
30
|
import { Scene } from '@babylonjs/core/scene';
|
|
29
31
|
import { Nullable } from '@babylonjs/core/types';
|
|
30
|
-
import { cloneDeep, get, has, merge } from 'lodash-es';
|
|
32
|
+
import { cloneDeep, get, has, merge, uniq } from 'lodash-es';
|
|
31
33
|
|
|
32
34
|
const backgroundDomeName = 'BackgroundDome_ViewerGenerated';
|
|
33
35
|
const envHelperMetadataName = 'viewerEnvHelper';
|
|
@@ -82,21 +84,26 @@ const getDottedPathForNode = function (node: Node): DottedPath {
|
|
|
82
84
|
|
|
83
85
|
/**
|
|
84
86
|
* @param node
|
|
87
|
+
* @param nodeNamingStrategy
|
|
85
88
|
* @param predicate
|
|
86
89
|
* @param deep
|
|
87
90
|
* @return TransformNode | null
|
|
88
91
|
*/
|
|
89
92
|
const cloneTransformNode = function (
|
|
90
93
|
node: TransformNode,
|
|
94
|
+
nodeNamingStrategy: NodeNamingStrategy,
|
|
91
95
|
predicate?: (node: TransformNode) => boolean,
|
|
92
96
|
deep: boolean = true
|
|
93
97
|
): TransformNode | null {
|
|
94
98
|
if (predicate && !predicate(node)) {
|
|
95
99
|
return null;
|
|
96
100
|
}
|
|
97
|
-
const
|
|
101
|
+
const newName = nodeNamingStrategy.handler(node, nodeNamingStrategy.payload);
|
|
102
|
+
const clone = node.clone(newName, node.parent, true);
|
|
98
103
|
if (clone) {
|
|
104
|
+
clone.id = newName;
|
|
99
105
|
clone.metadata = cloneDeep(node.metadata);
|
|
106
|
+
injectNodeMetadata(clone, { cloneSource: node }, false);
|
|
100
107
|
// if the cloned node is of type InstancedMesh, due to a bug(?),
|
|
101
108
|
// the InstancedMesh.isEnabled state may have changed after cloning.
|
|
102
109
|
// in that case, set the clone's enabled state to the original's state
|
|
@@ -107,7 +114,7 @@ const cloneTransformNode = function (
|
|
|
107
114
|
if (deep) {
|
|
108
115
|
const children = node.getChildTransformNodes(true);
|
|
109
116
|
children.forEach(child => {
|
|
110
|
-
const clonedChild = cloneTransformNode(child, predicate, deep);
|
|
117
|
+
const clonedChild = cloneTransformNode(child, nodeNamingStrategy, predicate, deep);
|
|
111
118
|
if (clonedChild) {
|
|
112
119
|
clonedChild.parent = clone;
|
|
113
120
|
}
|
|
@@ -174,7 +181,7 @@ const injectNodeMetadata = function (node: Node, metadata: {}, deep: boolean = t
|
|
|
174
181
|
*/
|
|
175
182
|
const assertTransformNode = function (
|
|
176
183
|
node: TransformNode,
|
|
177
|
-
assertCallable:
|
|
184
|
+
assertCallable: (node: TransformNode, ...args: any[]) => void,
|
|
178
185
|
callableParameters: any[] = [],
|
|
179
186
|
deep: boolean = true
|
|
180
187
|
) {
|
|
@@ -185,6 +192,24 @@ const assertTransformNode = function (
|
|
|
185
192
|
}
|
|
186
193
|
};
|
|
187
194
|
|
|
195
|
+
/**
|
|
196
|
+
* @param node
|
|
197
|
+
* @param parameter
|
|
198
|
+
*/
|
|
199
|
+
const assertMeshCapability = function (node: TransformNode, parameter: string) {
|
|
200
|
+
if (!(node instanceof AbstractMesh)) {
|
|
201
|
+
const cls = node.getClassName();
|
|
202
|
+
throw new Error(
|
|
203
|
+
`Changing parameter "${parameter}" of a(n) ${cls} is not supported. Tried to change node "${node.id}".`
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
if (node instanceof InstancedMesh) {
|
|
207
|
+
throw new Error(
|
|
208
|
+
`Changing parameter "${parameter}" of an InstancedMesh is not supported. Tried to change node "${node.id}".`
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
|
|
188
213
|
/**
|
|
189
214
|
* @param node
|
|
190
215
|
* @param deep
|
|
@@ -372,15 +397,9 @@ const changeEnvironment = function (scene: Scene, envDef: EnvironmentDefinition)
|
|
|
372
397
|
* Finally the material will not be applied before all its textures have been loaded. In this way "flickering" effects
|
|
373
398
|
* will be avoided, since the material would be incomplete without its loaded textures.
|
|
374
399
|
*/
|
|
375
|
-
const setMaterial = function (
|
|
376
|
-
scene: Scene,
|
|
377
|
-
node: TransformNode,
|
|
378
|
-
materialId: string,
|
|
379
|
-
deep: boolean = true,
|
|
380
|
-
variant?: Variant
|
|
381
|
-
) {
|
|
400
|
+
const setMaterial = function (node: TransformNode, materialId: string, deep: boolean = true, variant?: Variant) {
|
|
382
401
|
if (node instanceof AbstractMesh) {
|
|
383
|
-
const materialExists =
|
|
402
|
+
const materialExists = node.getScene().getMaterialById(materialId);
|
|
384
403
|
const hasMissingMaterial = has(node.metadata, missingMaterialMetadataName);
|
|
385
404
|
const deferMaterialCreation = !materialExists && !node.isEnabled();
|
|
386
405
|
if (deferMaterialCreation) {
|
|
@@ -391,9 +410,9 @@ const setMaterial = function (
|
|
|
391
410
|
addMissingMaterialObserver(node);
|
|
392
411
|
}
|
|
393
412
|
} else {
|
|
394
|
-
// create material
|
|
395
|
-
const material = getOrCreateMaterial(
|
|
396
|
-
|
|
413
|
+
// create material and apply it when textures have been loaded
|
|
414
|
+
const material = getOrCreateMaterial(node.getScene(), materialId, variant);
|
|
415
|
+
applyMaterial(material, node).then(() => emitter.emit(Event.MESH_MATERIAL_APPLIED, node, material));
|
|
397
416
|
|
|
398
417
|
if (hasMissingMaterial) {
|
|
399
418
|
delete node.metadata[missingMaterialMetadataName];
|
|
@@ -403,7 +422,7 @@ const setMaterial = function (
|
|
|
403
422
|
// recursively set materials on children (if desired)
|
|
404
423
|
if (deep) {
|
|
405
424
|
for (const child of node.getChildTransformNodes(true)) {
|
|
406
|
-
setMaterial(
|
|
425
|
+
setMaterial(child, materialId, deep, variant);
|
|
407
426
|
}
|
|
408
427
|
}
|
|
409
428
|
};
|
|
@@ -429,10 +448,10 @@ const getOrCreateMaterial = function (scene: Scene, materialId: string, variant?
|
|
|
429
448
|
};
|
|
430
449
|
|
|
431
450
|
/**
|
|
432
|
-
* Waits until the materials textures are loaded and
|
|
433
|
-
* request
|
|
451
|
+
* Waits until the materials textures are loaded and shaders are compiled.
|
|
452
|
+
* Then sets the material on the node if there is no newer "set material" request
|
|
434
453
|
*/
|
|
435
|
-
const
|
|
454
|
+
const applyMaterial = async function (material: Material, node: AbstractMesh) {
|
|
436
455
|
// set current material id as last valid id, in this case all previously set materials on the node will be invalidated
|
|
437
456
|
injectNodeMetadata(node, { [materialWaitingToBeSetMetadataName]: material.id }, false);
|
|
438
457
|
|
|
@@ -451,7 +470,7 @@ const applyMaterialAfterTexturesLoaded = async function (material: Material, nod
|
|
|
451
470
|
await Promise.all([promTexturesReady, promMaterialCompiled]);
|
|
452
471
|
|
|
453
472
|
// textures ready, now check if the material is still up-to-date
|
|
454
|
-
if (material.id === node.metadata[materialWaitingToBeSetMetadataName]) {
|
|
473
|
+
if (material.id === node.metadata?.[materialWaitingToBeSetMetadataName]) {
|
|
455
474
|
node.material = material;
|
|
456
475
|
delete node.metadata[materialWaitingToBeSetMetadataName];
|
|
457
476
|
}
|
|
@@ -505,6 +524,7 @@ const setMaterialColor = function (node: TransformNode, color: Color3, deep: boo
|
|
|
505
524
|
default:
|
|
506
525
|
throw new Error(`Setting color for material of instance "${materialCls}" not implemented (yet).`);
|
|
507
526
|
}
|
|
527
|
+
setMaterial(node, node.material.id, false);
|
|
508
528
|
}
|
|
509
529
|
if (deep) {
|
|
510
530
|
node.getChildTransformNodes(true).forEach(child => setMaterialColor(child, color, deep));
|
|
@@ -529,6 +549,7 @@ const setMaterialTexture = function (node: TransformNode, texture: Texture, deep
|
|
|
529
549
|
default:
|
|
530
550
|
throw new Error(`Setting texture for material of instance "${materialCls}" not implemented (yet).`);
|
|
531
551
|
}
|
|
552
|
+
setMaterial(node, node.material.id, false);
|
|
532
553
|
}
|
|
533
554
|
if (deep) {
|
|
534
555
|
node.getChildTransformNodes(true).forEach(child => setMaterialTexture(child, texture, deep));
|
|
@@ -550,6 +571,7 @@ const setMaterialMetallness = function (node: TransformNode, metallness: number,
|
|
|
550
571
|
default:
|
|
551
572
|
throw new Error(`Setting metallness for material of instance "${materialCls}" not implemented (yet).`);
|
|
552
573
|
}
|
|
574
|
+
setMaterial(node, node.material.id, false);
|
|
553
575
|
}
|
|
554
576
|
if (deep) {
|
|
555
577
|
node.getChildTransformNodes(true).forEach(child => setMaterialMetallness(child, metallness, deep));
|
|
@@ -574,6 +596,7 @@ const setMaterialRoughness = function (node: TransformNode, roughness: number, d
|
|
|
574
596
|
default:
|
|
575
597
|
throw new Error(`Setting roughness for material of instance "${materialCls}" not implemented (yet).`);
|
|
576
598
|
}
|
|
599
|
+
setMaterial(node, node.material.id, false);
|
|
577
600
|
}
|
|
578
601
|
if (deep) {
|
|
579
602
|
node.getChildTransformNodes(true).forEach(child => setMaterialRoughness(child, roughness, deep));
|
|
@@ -704,6 +727,56 @@ const isTextureWithOnLoadObservable = function (texture: BaseTexture): texture i
|
|
|
704
727
|
return !!(texture as BaseTextureWithOnLoadObservable).onLoadObservable;
|
|
705
728
|
};
|
|
706
729
|
|
|
730
|
+
/**
|
|
731
|
+
* @param objects
|
|
732
|
+
* @param tagMapping
|
|
733
|
+
*/
|
|
734
|
+
const mapTags = function (objects: object[], tagMapping: TagMapping): string[] {
|
|
735
|
+
let affectedTags: string[] = [];
|
|
736
|
+
for (const object of objects) {
|
|
737
|
+
const oldTags = Object.keys(Tags.GetTags(object, false) ?? {});
|
|
738
|
+
const mappedTags = oldTags.map(t => tagMapping[t] || t);
|
|
739
|
+
Tags.RemoveTagsFrom(object, oldTags.join(' '));
|
|
740
|
+
Tags.AddTagsTo(object, mappedTags.join(' '));
|
|
741
|
+
affectedTags = [...affectedTags, ...mappedTags];
|
|
742
|
+
}
|
|
743
|
+
return uniq(affectedTags);
|
|
744
|
+
};
|
|
745
|
+
|
|
746
|
+
/**
|
|
747
|
+
* Gets an array of ids for nodeIds that exist in both TransformNode arrays.
|
|
748
|
+
* @param nodes1
|
|
749
|
+
* @param nodes2
|
|
750
|
+
* @param predicate
|
|
751
|
+
*/
|
|
752
|
+
const intersectingNodeNames = function (nodes1: Node[], nodes2: Node[], predicate?: (node: Node) => boolean): string[] {
|
|
753
|
+
const nodeNames1 = nodes1.filter(n => !predicate || predicate(n)).map(n => n.name);
|
|
754
|
+
const nodesNames2 = nodes2.filter(n => !predicate || predicate(n)).map(n => n.name);
|
|
755
|
+
return nodeNames1.filter(n1 => nodesNames2.includes(n1));
|
|
756
|
+
};
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* Gets an array of ids for duplicate nodeIds in given node array.
|
|
760
|
+
* @param nodes
|
|
761
|
+
* @param predicate
|
|
762
|
+
*/
|
|
763
|
+
const duplicateNodeNames = function (nodes: Node[], predicate?: (node: Node) => boolean): string[] {
|
|
764
|
+
const nodeNames = nodes.filter(n => !predicate || predicate(n)).map(n => n.name);
|
|
765
|
+
return nodeNames.filter((v, i, self) => self.indexOf(v) !== i);
|
|
766
|
+
};
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* Reports duplicate nodeIds.
|
|
770
|
+
* @param nodeNames
|
|
771
|
+
*/
|
|
772
|
+
const reportDuplicateNodeNames = function (nodeNames: string[]): void {
|
|
773
|
+
if (nodeNames.length > 0) {
|
|
774
|
+
const warn = `There are duplicate nodeNames: ${nodeNames.join(', ')}`;
|
|
775
|
+
console.warn(`!!! Warning !!!\n${warn}`);
|
|
776
|
+
window.Cbn?.Assets.reportDuplicateNodeName(nodeNames);
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
|
|
707
780
|
export {
|
|
708
781
|
getRootNode,
|
|
709
782
|
isTextureWithOnLoadObservable,
|
|
@@ -713,9 +786,10 @@ export {
|
|
|
713
786
|
cloneNodeWithParents,
|
|
714
787
|
cloneTransformNodeMaterial,
|
|
715
788
|
getOrCreateMaterial,
|
|
716
|
-
|
|
789
|
+
applyMaterial,
|
|
717
790
|
injectNodeMetadata,
|
|
718
791
|
assertTransformNode,
|
|
792
|
+
assertMeshCapability,
|
|
719
793
|
activateTransformNode,
|
|
720
794
|
deactivateTransformNode,
|
|
721
795
|
enableNodeWithParents,
|
|
@@ -736,4 +810,8 @@ export {
|
|
|
736
810
|
changeEnvironment,
|
|
737
811
|
backgroundDomeName,
|
|
738
812
|
envHelperMetadataName,
|
|
813
|
+
mapTags,
|
|
814
|
+
intersectingNodeNames,
|
|
815
|
+
duplicateNodeNames,
|
|
816
|
+
reportDuplicateNodeNames,
|
|
739
817
|
};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
type Viewer = import('../classes/viewer').Viewer;
|
|
3
3
|
type Variant = import('../classes/variant').Variant;
|
|
4
4
|
type VariantInstance = import('../classes/variantInstance').VariantInstance;
|
|
5
|
+
type VariantParameterizable = import('../classes/variantParameterizable').VariantParameterizable;
|
|
5
6
|
/**
|
|
6
7
|
* Alias for {@link Element} which can be used to prevent name clashes with the web APIs
|
|
7
8
|
* [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) class
|
|
@@ -11,6 +12,8 @@ type DottedPath = import('../classes/dottedPath').DottedPath;
|
|
|
11
12
|
type ViewerLight = import('../classes/viewerLight').ViewerLight;
|
|
12
13
|
type SceneManager = import('../manager/sceneManager').SceneManager;
|
|
13
14
|
|
|
15
|
+
type FuzzyMap<K, V> = import('../classes/fuzzyMap').FuzzyMap<K, V>;
|
|
16
|
+
|
|
14
17
|
// global accessible types imported from BabylonJS
|
|
15
18
|
type Scene = import('@babylonjs/core/scene').Scene;
|
|
16
19
|
type Vector3 = import('@babylonjs/core/Maths/math.vector').Vector3;
|
|
@@ -42,6 +45,10 @@ type IExportOptions = import('@babylonjs/serializers/glTF/2.0').IExportOptions;
|
|
|
42
45
|
|
|
43
46
|
type EventEmitter = import('eventemitter3');
|
|
44
47
|
|
|
48
|
+
type Undefinable<T> = T | undefined;
|
|
49
|
+
|
|
50
|
+
type Nullable<T> = T | null;
|
|
51
|
+
|
|
45
52
|
// some more global accessible types
|
|
46
53
|
type PathDefinitions = {
|
|
47
54
|
include: string[];
|
|
@@ -368,7 +375,13 @@ type ParsedParameterBag = {
|
|
|
368
375
|
|
|
369
376
|
type DottedPathArgument = string | string[] | DottedPath;
|
|
370
377
|
|
|
371
|
-
type
|
|
378
|
+
type ParameterObserverResult = any;
|
|
379
|
+
|
|
380
|
+
type ParameterObserver = (
|
|
381
|
+
payload: any,
|
|
382
|
+
oldValue: Undefinable<ParameterValue>,
|
|
383
|
+
newValue: ParameterValue
|
|
384
|
+
) => ParameterObserverResult;
|
|
372
385
|
|
|
373
386
|
type PlacementDefinitions = {
|
|
374
387
|
[name: string]: PlacementDefinition;
|
|
@@ -435,3 +448,45 @@ type SpecGenerationData = {
|
|
|
435
448
|
name: string;
|
|
436
449
|
url: string;
|
|
437
450
|
};
|
|
451
|
+
|
|
452
|
+
type TagMapping = {
|
|
453
|
+
[tagName: string]: string;
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
type TagManagerSubject = {
|
|
457
|
+
tagName?: string;
|
|
458
|
+
nodeName?: string;
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
type TagManagerParameterObserver = (payload: TagManagerParameterObserverPayload) => ParameterObserverResult;
|
|
462
|
+
|
|
463
|
+
type TagManagerParameterBag = FuzzyMap<TagManagerSubject, ParameterBag>;
|
|
464
|
+
|
|
465
|
+
type TagManagerParameterObserverBag = Map<string, TagManagerParameterObserver>;
|
|
466
|
+
|
|
467
|
+
type TagManagerParameterObserverPayload = {
|
|
468
|
+
subject: TagManagerSubject;
|
|
469
|
+
nodes: TransformNode[];
|
|
470
|
+
newValue: ParameterValue;
|
|
471
|
+
oldValue: Undefinable<ParameterValue>;
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
type TagManagerParameterValue = {
|
|
475
|
+
tagName?: string;
|
|
476
|
+
nodeName?: string;
|
|
477
|
+
parameterName: string;
|
|
478
|
+
value: ParameterValue;
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
type NodeNamingStrategyPayload = {
|
|
482
|
+
variantInstance: VariantInstance;
|
|
483
|
+
variant: Variant;
|
|
484
|
+
variantParameterizable: VariantParameterizable;
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
type NodeNamingStrategyHandler = (node: TransformNode, payload: NodeNamingStrategyPayload) => string;
|
|
488
|
+
|
|
489
|
+
type NodeNamingStrategy = {
|
|
490
|
+
handler: NodeNamingStrategyHandler;
|
|
491
|
+
payload: NodeNamingStrategyPayload;
|
|
492
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Event, emitter } from '../classes/event';
|
|
2
|
+
import { applyMaterial, getOrCreateMaterial, injectNodeMetadata } from './babylonHelper';
|
|
2
3
|
import { sleep } from './resourceHelper';
|
|
3
4
|
import { ISceneLoaderPlugin } from '@babylonjs/core/Loading/sceneLoader';
|
|
4
5
|
import { Material } from '@babylonjs/core/Materials/material';
|
|
@@ -67,7 +68,9 @@ export const getMaterialPostLoadObserver = function (concerningMesh: Mesh) {
|
|
|
67
68
|
const missingMatId = concerningMesh.metadata[missingMaterialMetadataName];
|
|
68
69
|
// get material and apply it on the concerning mesh after all textures have been loaded
|
|
69
70
|
const material = getOrCreateMaterial(concerningMesh.getScene(), missingMatId);
|
|
70
|
-
|
|
71
|
+
applyMaterial(material, concerningMesh).then(() =>
|
|
72
|
+
emitter.emit(Event.MESH_MATERIAL_APPLIED, concerningMesh, material)
|
|
73
|
+
);
|
|
71
74
|
// since the material is there now, we do not need the related metadata tag anymore
|
|
72
75
|
delete concerningMesh.metadata[missingMaterialMetadataName];
|
|
73
76
|
|
|
@@ -134,6 +137,22 @@ export const addMissingMaterialObserver = function (node: BjsNode) {
|
|
|
134
137
|
}
|
|
135
138
|
};
|
|
136
139
|
|
|
140
|
+
export const removeMissingMaterialObserver = function (node: BjsNode) {
|
|
141
|
+
// set the concerning node, i.e. the node the observer should check for missing material.
|
|
142
|
+
// for instanced meshes, we want the sourcemesh here.
|
|
143
|
+
const concerningNode = node instanceof InstancedMesh ? node.sourceMesh : (node as Mesh);
|
|
144
|
+
let currNode: Nullable<BjsNode> = node;
|
|
145
|
+
while (currNode) {
|
|
146
|
+
enableObserverMap[concerningNode.id]?.forEach(entry => {
|
|
147
|
+
if (entry.currNodeId === currNode?.id) {
|
|
148
|
+
currNode.onEnabledStateChangedObservable.remove(entry.observer);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
currNode = currNode.parent;
|
|
152
|
+
}
|
|
153
|
+
delete enableObserverMap[concerningNode.id];
|
|
154
|
+
};
|
|
155
|
+
|
|
137
156
|
/**
|
|
138
157
|
* Look up the provided materials (see library import) and create and return one if found.
|
|
139
158
|
*
|
package/src/dev.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
afterBootstrap,
|
|
4
4
|
beforeBootstrap,
|
|
5
5
|
createSpec,
|
|
6
|
+
createTagManagerParameterValues,
|
|
6
7
|
createUIelements,
|
|
7
8
|
getMaterial,
|
|
8
9
|
mockMaterials,
|
|
@@ -33,6 +34,7 @@ window.Cbn = {
|
|
|
33
34
|
assertMaterialExists(materialId: string): boolean {
|
|
34
35
|
return true;
|
|
35
36
|
},
|
|
37
|
+
reportDuplicateNodeName(nodeNameOrArrayOfNodeNames: string | string[]): void {},
|
|
36
38
|
},
|
|
37
39
|
};
|
|
38
40
|
|
|
@@ -50,7 +52,7 @@ async function bootstrapViewer() {
|
|
|
50
52
|
const viewer = new Viewer(canvas, createSpec());
|
|
51
53
|
await beforeBootstrap(viewer);
|
|
52
54
|
try {
|
|
53
|
-
await viewer.bootstrap();
|
|
55
|
+
await viewer.bootstrap(createTagManagerParameterValues(viewer));
|
|
54
56
|
} catch (e) {
|
|
55
57
|
console.error(e);
|
|
56
58
|
}
|
package/src/index.ts
CHANGED
|
@@ -17,7 +17,9 @@ import { ViewerLight } from './api/classes/viewerLight';
|
|
|
17
17
|
import { AnimationManager } from './api/manager/animationManager';
|
|
18
18
|
import { GltfExportManager } from './api/manager/gltfExportManager';
|
|
19
19
|
import { SceneManager } from './api/manager/sceneManager';
|
|
20
|
+
import { TagManager } from './api/manager/tagManager';
|
|
20
21
|
import { VariantInstanceManager } from './api/manager/variantInstanceManager';
|
|
22
|
+
import { SpecStorage } from './api/store/specStorage';
|
|
21
23
|
import * as BabylonHelper from './api/util/babylonHelper';
|
|
22
24
|
import { Animation as BabylonAnimation } from '@babylonjs/core/Animations/animation';
|
|
23
25
|
import { ArcRotateCamera } from '@babylonjs/core/Cameras/arcRotateCamera';
|
|
@@ -93,4 +95,6 @@ export {
|
|
|
93
95
|
PlacementAnimation,
|
|
94
96
|
BabylonHelper,
|
|
95
97
|
GltfExportManager,
|
|
98
|
+
SpecStorage,
|
|
99
|
+
TagManager,
|
|
96
100
|
};
|
package/src/types.d.ts
CHANGED
|
@@ -23,6 +23,13 @@ interface Window {
|
|
|
23
23
|
* @param materialId
|
|
24
24
|
*/
|
|
25
25
|
assertMaterialExists(materialId: string): boolean;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Warns user about duplicate nodeNames on scene.
|
|
29
|
+
*
|
|
30
|
+
* @param nodeNameOrArrayOfNodeNames
|
|
31
|
+
*/
|
|
32
|
+
reportDuplicateNodeName(nodeNameOrArrayOfNodeNames: string | string[]): void;
|
|
26
33
|
};
|
|
27
34
|
};
|
|
28
35
|
}
|