@combeenation/3d-viewer 6.5.0 → 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.
Files changed (69) hide show
  1. package/dist/lib-cjs/api/classes/element.d.ts +4 -0
  2. package/dist/lib-cjs/api/classes/element.js +59 -58
  3. package/dist/lib-cjs/api/classes/element.js.map +1 -1
  4. package/dist/lib-cjs/api/classes/event.d.ts +55 -1
  5. package/dist/lib-cjs/api/classes/event.js +55 -1
  6. package/dist/lib-cjs/api/classes/event.js.map +1 -1
  7. package/dist/lib-cjs/api/classes/fuzzyMap.d.ts +7 -0
  8. package/dist/lib-cjs/api/classes/fuzzyMap.js +22 -0
  9. package/dist/lib-cjs/api/classes/fuzzyMap.js.map +1 -0
  10. package/dist/lib-cjs/api/classes/parameter.d.ts +12 -0
  11. package/dist/lib-cjs/api/classes/parameter.js +86 -33
  12. package/dist/lib-cjs/api/classes/parameter.js.map +1 -1
  13. package/dist/lib-cjs/api/classes/parameterObservable.js +2 -27
  14. package/dist/lib-cjs/api/classes/parameterObservable.js.map +1 -1
  15. package/dist/lib-cjs/api/classes/variant.d.ts +23 -4
  16. package/dist/lib-cjs/api/classes/variant.js +45 -20
  17. package/dist/lib-cjs/api/classes/variant.js.map +1 -1
  18. package/dist/lib-cjs/api/classes/variantInstance.d.ts +11 -2
  19. package/dist/lib-cjs/api/classes/variantInstance.js +22 -2
  20. package/dist/lib-cjs/api/classes/variantInstance.js.map +1 -1
  21. package/dist/lib-cjs/api/classes/viewer.d.ts +13 -1
  22. package/dist/lib-cjs/api/classes/viewer.js +57 -7
  23. package/dist/lib-cjs/api/classes/viewer.js.map +1 -1
  24. package/dist/lib-cjs/api/classes/viewerLight.js.map +1 -1
  25. package/dist/lib-cjs/api/manager/animationManager.d.ts +3 -3
  26. package/dist/lib-cjs/api/manager/animationManager.js.map +1 -1
  27. package/dist/lib-cjs/api/manager/sceneManager.js.map +1 -1
  28. package/dist/lib-cjs/api/manager/tagManager.d.ts +108 -0
  29. package/dist/lib-cjs/api/manager/tagManager.js +420 -0
  30. package/dist/lib-cjs/api/manager/tagManager.js.map +1 -0
  31. package/dist/lib-cjs/api/manager/variantInstanceManager.d.ts +8 -3
  32. package/dist/lib-cjs/api/manager/variantInstanceManager.js +27 -8
  33. package/dist/lib-cjs/api/manager/variantInstanceManager.js.map +1 -1
  34. package/dist/lib-cjs/api/store/specStorage.d.ts +8 -0
  35. package/dist/lib-cjs/api/store/specStorage.js +15 -0
  36. package/dist/lib-cjs/api/store/specStorage.js.map +1 -1
  37. package/dist/lib-cjs/api/util/babylonHelper.d.ts +36 -7
  38. package/dist/lib-cjs/api/util/babylonHelper.js +92 -15
  39. package/dist/lib-cjs/api/util/babylonHelper.js.map +1 -1
  40. package/dist/lib-cjs/api/util/globalTypes.d.ts +38 -1
  41. package/dist/lib-cjs/api/util/sceneLoaderHelper.d.ts +1 -0
  42. package/dist/lib-cjs/api/util/sceneLoaderHelper.js +20 -2
  43. package/dist/lib-cjs/api/util/sceneLoaderHelper.js.map +1 -1
  44. package/dist/lib-cjs/buildinfo.json +1 -1
  45. package/dist/lib-cjs/commonjs.tsconfig.tsbuildinfo +1 -1
  46. package/dist/lib-cjs/index.d.ts +2 -1
  47. package/dist/lib-cjs/index.js +3 -1
  48. package/dist/lib-cjs/index.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/api/classes/element.ts +96 -82
  51. package/src/api/classes/event.ts +68 -1
  52. package/src/api/classes/fuzzyMap.ts +21 -0
  53. package/src/api/classes/parameter.ts +91 -34
  54. package/src/api/classes/parameterObservable.ts +2 -29
  55. package/src/api/classes/variant.ts +82 -33
  56. package/src/api/classes/variantInstance.ts +27 -1
  57. package/src/api/classes/viewer.ts +63 -12
  58. package/src/api/classes/viewerLight.ts +10 -10
  59. package/src/api/manager/animationManager.ts +2 -2
  60. package/src/api/manager/sceneManager.ts +5 -1
  61. package/src/api/manager/tagManager.ts +451 -0
  62. package/src/api/manager/variantInstanceManager.ts +35 -8
  63. package/src/api/store/specStorage.ts +17 -0
  64. package/src/api/util/babylonHelper.ts +99 -21
  65. package/src/api/util/globalTypes.ts +56 -1
  66. package/src/api/util/sceneLoaderHelper.ts +21 -2
  67. package/src/dev.ts +3 -1
  68. package/src/index.ts +2 -0
  69. package/src/types.d.ts +7 -0
@@ -16,6 +16,7 @@ import { ViewerLight } from './api/classes/viewerLight';
16
16
  import { AnimationManager } from './api/manager/animationManager';
17
17
  import { GltfExportManager } from './api/manager/gltfExportManager';
18
18
  import { SceneManager } from './api/manager/sceneManager';
19
+ import { TagManager } from './api/manager/tagManager';
19
20
  import { VariantInstanceManager } from './api/manager/variantInstanceManager';
20
21
  import { SpecStorage } from './api/store/specStorage';
21
22
  import * as BabylonHelper from './api/util/babylonHelper';
@@ -49,4 +50,4 @@ import { EventEmitter } from 'eventemitter3';
49
50
  /**
50
51
  * Expose some frequently used babylon modules by our consumers.
51
52
  */
52
- export { AnimationManager, AnimationInterface, Variant, VariantInstanceManager, Viewer, ParameterObservable, Parameterizable, VariantParameterizable, ViewerLight, emitter as Emitter, EventEmitter, Event, Parameter, VariantInstance, Color3, Color4, Vector3, AbstractMesh, InstancedMesh, Mesh, TransformNode, Node, Material, PBRMaterial, StandardMaterial, Scene, Engine, ArcRotateCamera, DynamicTexture, CubeTexture, MeshBuilder, Texture, BabylonAnimation, HemisphericLight, DirectionalLight, Element, EventBroadcaster, SceneManager, PlacementAnimation, BabylonHelper, GltfExportManager, SpecStorage, };
53
+ export { AnimationManager, AnimationInterface, Variant, VariantInstanceManager, Viewer, ParameterObservable, Parameterizable, VariantParameterizable, ViewerLight, emitter as Emitter, EventEmitter, Event, Parameter, VariantInstance, Color3, Color4, Vector3, AbstractMesh, InstancedMesh, Mesh, TransformNode, Node, Material, PBRMaterial, StandardMaterial, Scene, Engine, ArcRotateCamera, DynamicTexture, CubeTexture, MeshBuilder, Texture, BabylonAnimation, HemisphericLight, DirectionalLight, Element, EventBroadcaster, SceneManager, PlacementAnimation, BabylonHelper, GltfExportManager, SpecStorage, TagManager, };
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.SpecStorage = exports.GltfExportManager = exports.BabylonHelper = exports.PlacementAnimation = exports.SceneManager = exports.EventBroadcaster = exports.Element = exports.DirectionalLight = exports.HemisphericLight = exports.BabylonAnimation = exports.Texture = exports.MeshBuilder = exports.CubeTexture = exports.DynamicTexture = exports.ArcRotateCamera = exports.Engine = exports.Scene = exports.StandardMaterial = exports.PBRMaterial = exports.Material = exports.Node = exports.TransformNode = exports.Mesh = exports.InstancedMesh = exports.AbstractMesh = exports.Vector3 = exports.Color4 = exports.Color3 = exports.VariantInstance = exports.Parameter = exports.Event = exports.EventEmitter = exports.Emitter = exports.ViewerLight = exports.VariantParameterizable = exports.Parameterizable = exports.ParameterObservable = exports.Viewer = exports.VariantInstanceManager = exports.Variant = exports.AnimationManager = void 0;
26
+ exports.TagManager = exports.SpecStorage = exports.GltfExportManager = exports.BabylonHelper = exports.PlacementAnimation = exports.SceneManager = exports.EventBroadcaster = exports.Element = exports.DirectionalLight = exports.HemisphericLight = exports.BabylonAnimation = exports.Texture = exports.MeshBuilder = exports.CubeTexture = exports.DynamicTexture = exports.ArcRotateCamera = exports.Engine = exports.Scene = exports.StandardMaterial = exports.PBRMaterial = exports.Material = exports.Node = exports.TransformNode = exports.Mesh = exports.InstancedMesh = exports.AbstractMesh = exports.Vector3 = exports.Color4 = exports.Color3 = exports.VariantInstance = exports.Parameter = exports.Event = exports.EventEmitter = exports.Emitter = exports.ViewerLight = exports.VariantParameterizable = exports.Parameterizable = exports.ParameterObservable = exports.Viewer = exports.VariantInstanceManager = exports.Variant = exports.AnimationManager = void 0;
27
27
  const element_1 = require("./api/classes/element");
28
28
  Object.defineProperty(exports, "Element", { enumerable: true, get: function () { return element_1.Element; } });
29
29
  const event_1 = require("./api/classes/event");
@@ -55,6 +55,8 @@ const gltfExportManager_1 = require("./api/manager/gltfExportManager");
55
55
  Object.defineProperty(exports, "GltfExportManager", { enumerable: true, get: function () { return gltfExportManager_1.GltfExportManager; } });
56
56
  const sceneManager_1 = require("./api/manager/sceneManager");
57
57
  Object.defineProperty(exports, "SceneManager", { enumerable: true, get: function () { return sceneManager_1.SceneManager; } });
58
+ const tagManager_1 = require("./api/manager/tagManager");
59
+ Object.defineProperty(exports, "TagManager", { enumerable: true, get: function () { return tagManager_1.TagManager; } });
58
60
  const variantInstanceManager_1 = require("./api/manager/variantInstanceManager");
59
61
  Object.defineProperty(exports, "VariantInstanceManager", { enumerable: true, get: function () { return variantInstanceManager_1.VariantInstanceManager; } });
60
62
  const specStorage_1 = require("./api/store/specStorage");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,mDAAgD;AAsF9C,wFAtFO,iBAAO,OAsFP;AArFT,+CAAqD;AA6DnD,sFA7DO,aAAK,OA6DP;AAFM,wFA3DG,eAAO,OA2DH;AA1DpB,qEAAkE;AAqFhE,iGArFO,mCAAgB,OAqFP;AApFlB,uDAAoD;AA4DlD,0FA5DO,qBAAS,OA4DP;AA3DX,2EAAwE;AAoDtE,oGApDO,yCAAmB,OAoDP;AAnDrB,mEAAgE;AAoD9D,gGApDO,iCAAe,OAoDP;AAnDjB,yEAAsE;AAmFpE,mGAnFO,uCAAkB,OAmFP;AAlFpB,mDAAgD;AA8C9C,wFA9CO,iBAAO,OA8CP;AA7CT,mEAAgE;AAwD9D,gGAxDO,iCAAe,OAwDP;AAvDjB,iFAA8E;AAiD5E,uGAjDO,+CAAsB,OAiDP;AAhDxB,iDAA8C;AA6C5C,uFA7CO,eAAM,OA6CP;AA5CR,2DAAwD;AAgDtD,4FAhDO,yBAAW,OAgDP;AA/Cb,qEAAkE;AAuChE,iGAvCO,mCAAgB,OAuCP;AAtClB,uEAAoE;AA8ElE,kGA9EO,qCAAiB,OA8EP;AA7EnB,6DAA0D;AA0ExD,6FA1EO,2BAAY,OA0EP;AAzEd,iFAA8E;AAuC5E,uGAvCO,+CAAsB,OAuCP;AAtCxB,yDAAsD;AA4EpD,4FA5EO,yBAAW,OA4EP;AA3Eb,wEAA0D;AAyExD,sCAAa;AAxEf,oEAAqF;AAiEnF,iGAjEoB,qBAAgB,OAiEpB;AAhElB,6EAA0E;AA2DxE,gGA3DO,iCAAe,OA2DP;AA1DjB,2DAAwD;AAyDtD,uFAzDO,eAAM,OAyDP;AAxDR,8EAA2E;AAgEzE,iGAhEO,mCAAgB,OAgEP;AA/DlB,8EAA2E;AA8DzE,iGA9DO,mCAAgB,OA8DP;AA7DlB,2EAAwE;AAmDtE,4FAnDO,yBAAW,OAmDP;AAlDb,gFAA6E;AAwD3E,4FAxDO,yBAAW,OAwDP;AAvDb,sFAAmF;AAsDjF,+FAtDO,+BAAc,OAsDP;AArDhB,wEAAqE;AAwDnE,wFAxDO,iBAAO,OAwDP;AAvDT,iEAA8D;AA8C5D,yFA9CO,mBAAQ,OA8CP;AA7CV,iFAA8E;AA+C5E,iGA/CO,mCAAgB,OA+CP;AA9ClB,iEAAkE;AAoChE,uFApCO,mBAAM,OAoCP;AACN,uFArCe,mBAAM,OAqCf;AApCR,mEAA4D;AAqC1D,wFArCO,qBAAO,OAqCP;AApCT,sEAAmE;AAqCjE,6FArCO,2BAAY,OAqCP;AApCd,wEAAqE;AAqCnE,8FArCO,6BAAa,OAqCP;AApCf,sDAAmD;AAqCjD,qFArCO,WAAI,OAqCP;AApCN,oEAAiE;AA+C/D,4FA/CO,yBAAW,OA+CP;AA9Cb,wEAAqE;AAoCnE,8FApCO,6BAAa,OAoCP;AAlCf;;;;GAIG;AACH,yDAAuD;AACvD,+CAA4C;AA6B1C,qFA7BO,WAAI,OA6BP;AA5BN,iDAA8C;AAgC5C,sFAhCO,aAAK,OAgCP;AA/BP,iDAA6C;AAgB3C,6FAhBO,4BAAY,OAgBP"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,mDAAgD;AAuF9C,wFAvFO,iBAAO,OAuFP;AAtFT,+CAAqD;AA8DnD,sFA9DO,aAAK,OA8DP;AAFM,wFA5DG,eAAO,OA4DH;AA3DpB,qEAAkE;AAsFhE,iGAtFO,mCAAgB,OAsFP;AArFlB,uDAAoD;AA6DlD,0FA7DO,qBAAS,OA6DP;AA5DX,2EAAwE;AAqDtE,oGArDO,yCAAmB,OAqDP;AApDrB,mEAAgE;AAqD9D,gGArDO,iCAAe,OAqDP;AApDjB,yEAAsE;AAoFpE,mGApFO,uCAAkB,OAoFP;AAnFpB,mDAAgD;AA+C9C,wFA/CO,iBAAO,OA+CP;AA9CT,mEAAgE;AAyD9D,gGAzDO,iCAAe,OAyDP;AAxDjB,iFAA8E;AAkD5E,uGAlDO,+CAAsB,OAkDP;AAjDxB,iDAA8C;AA8C5C,uFA9CO,eAAM,OA8CP;AA7CR,2DAAwD;AAiDtD,4FAjDO,yBAAW,OAiDP;AAhDb,qEAAkE;AAwChE,iGAxCO,mCAAgB,OAwCP;AAvClB,uEAAoE;AA+ElE,kGA/EO,qCAAiB,OA+EP;AA9EnB,6DAA0D;AA2ExD,6FA3EO,2BAAY,OA2EP;AA1Ed,yDAAsD;AA+EpD,2FA/EO,uBAAU,OA+EP;AA9EZ,iFAA8E;AAuC5E,uGAvCO,+CAAsB,OAuCP;AAtCxB,yDAAsD;AA4EpD,4FA5EO,yBAAW,OA4EP;AA3Eb,wEAA0D;AAyExD,sCAAa;AAxEf,oEAAqF;AAiEnF,iGAjEoB,qBAAgB,OAiEpB;AAhElB,6EAA0E;AA2DxE,gGA3DO,iCAAe,OA2DP;AA1DjB,2DAAwD;AAyDtD,uFAzDO,eAAM,OAyDP;AAxDR,8EAA2E;AAgEzE,iGAhEO,mCAAgB,OAgEP;AA/DlB,8EAA2E;AA8DzE,iGA9DO,mCAAgB,OA8DP;AA7DlB,2EAAwE;AAmDtE,4FAnDO,yBAAW,OAmDP;AAlDb,gFAA6E;AAwD3E,4FAxDO,yBAAW,OAwDP;AAvDb,sFAAmF;AAsDjF,+FAtDO,+BAAc,OAsDP;AArDhB,wEAAqE;AAwDnE,wFAxDO,iBAAO,OAwDP;AAvDT,iEAA8D;AA8C5D,yFA9CO,mBAAQ,OA8CP;AA7CV,iFAA8E;AA+C5E,iGA/CO,mCAAgB,OA+CP;AA9ClB,iEAAkE;AAoChE,uFApCO,mBAAM,OAoCP;AACN,uFArCe,mBAAM,OAqCf;AApCR,mEAA4D;AAqC1D,wFArCO,qBAAO,OAqCP;AApCT,sEAAmE;AAqCjE,6FArCO,2BAAY,OAqCP;AApCd,wEAAqE;AAqCnE,8FArCO,6BAAa,OAqCP;AApCf,sDAAmD;AAqCjD,qFArCO,WAAI,OAqCP;AApCN,oEAAiE;AA+C/D,4FA/CO,yBAAW,OA+CP;AA9Cb,wEAAqE;AAoCnE,8FApCO,6BAAa,OAoCP;AAlCf;;;;GAIG;AACH,yDAAuD;AACvD,+CAA4C;AA6B1C,qFA7BO,WAAI,OA6BP;AA5BN,iDAA8C;AAgC5C,sFAhCO,aAAK,OAgCP;AA/BP,iDAA6C;AAgB3C,6FAhBO,4BAAY,OAgBP"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@combeenation/3d-viewer",
3
- "version": "6.5.0",
3
+ "version": "7.0.0-beta1",
4
4
  "description": "Combeenation 3D Viewer",
5
5
  "homepage": "https://github.com/Combeenation/3d-viewer#readme",
6
6
  "bugs": {
@@ -2,6 +2,7 @@ import {
2
2
  activateTransformNode as activate,
3
3
  addToHighlightLayer,
4
4
  addToShadowGenerator,
5
+ assertMeshCapability,
5
6
  assertTransformNode,
6
7
  cloneTransformNode,
7
8
  cloneTransformNodeMaterial,
@@ -23,6 +24,7 @@ import { createImageFromImgSrc, createImageFromSvg } from '../util/resourceHelpe
23
24
  import { addMissingMaterialObserver } from '../util/sceneLoaderHelper';
24
25
  import { VariantParameterizable } from './../classes/variantParameterizable';
25
26
  import { DottedPath } from './dottedPath';
27
+ import { Event } from './event';
26
28
  import { Parameter } from './parameter';
27
29
  import { Variant } from './variant';
28
30
  import { HighlightLayer } from '@babylonjs/core/Layers/highlightLayer';
@@ -33,7 +35,6 @@ import { DynamicTexture } from '@babylonjs/core/Materials/Textures/dynamicTextur
33
35
  import { Material } from '@babylonjs/core/Materials/material';
34
36
  import { Color3 } from '@babylonjs/core/Maths/math.color';
35
37
  import { AbstractMesh } from '@babylonjs/core/Meshes/abstractMesh';
36
- import { InstancedMesh } from '@babylonjs/core/Meshes/instancedMesh';
37
38
  import { Mesh } from '@babylonjs/core/Meshes/mesh';
38
39
  import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
39
40
  import { has, isArray, isNumber, isPlainObject, merge, union } from 'lodash-es';
@@ -60,9 +61,20 @@ export class Element extends VariantParameterizable {
60
61
  if (process.env.NODE_ENV?.toLowerCase().includes('dev')) {
61
62
  this.assertPathDefinitions();
62
63
  }
63
- const nodes = this.variant.inheritedNodes.map(node => cloneTransformNode(node, this.filterNode.bind(this)));
64
+ const nodes = this.variant.inheritedNodes.map(node => {
65
+ const nodeNamingStrategy = {
66
+ handler: variant.viewer.nodeNamingStrategyHandler,
67
+ payload: {
68
+ variantInstance: variant.variantInstance!,
69
+ variant: variant,
70
+ variantParameterizable: this,
71
+ },
72
+ };
73
+ return cloneTransformNode(node, nodeNamingStrategy, this.filterNode.bind(this), true);
74
+ });
64
75
  this.nodes = nodes.filter(node => !!node) as TransformNode[];
65
76
  this._dottedNodes = mapToDottedNodes<TransformNode>(this.nodes, node => node instanceof TransformNode);
77
+ variant.broadcastEvent(Event.ELEMENT_NODES_CLONED, this);
66
78
  this.addMissingMaterialObservers();
67
79
  this.addParameterObservers();
68
80
  }
@@ -71,7 +83,9 @@ export class Element extends VariantParameterizable {
71
83
  * Creates an {@link Element} with given name.
72
84
  */
73
85
  public static async create(variant: Variant, name: string): Promise<Element> {
74
- return new Element(variant, name);
86
+ const element = new Element(variant, name);
87
+ variant.broadcastEvent(Event.ELEMENT_CREATED, element);
88
+ return element;
75
89
  }
76
90
 
77
91
  /**
@@ -135,16 +149,25 @@ export class Element extends VariantParameterizable {
135
149
  return merge({}, this.variant.inheritedParameters, this.parameters);
136
150
  }
137
151
 
152
+ /**
153
+ * The actual {@link TransformNode}s that make up this {@link Element}.
154
+ */
155
+ get nodesFlat(): TransformNode[] {
156
+ return this.nodes.reduce(
157
+ (acc, cur) => [...acc, ...(cur.getChildren(n => n instanceof TransformNode, false) as TransformNode[])],
158
+ this.nodes
159
+ );
160
+ }
161
+
138
162
  /**
139
163
  * The actual {@link Mesh}es that make up this {@link Element}.
140
164
  * Handy for e.g. creating a bounding box around an entire element.
141
165
  */
142
166
  get meshesFlat(): Mesh[] {
143
- const flatMeshes = this.nodes.reduce((accFlatMeshes, curNode) => {
144
- const currMeshes = curNode.getChildMeshes(false, n => n instanceof Mesh) as Mesh[];
145
- return [...accFlatMeshes, ...currMeshes];
146
- }, [] as Mesh[]);
147
- return flatMeshes;
167
+ return this.nodes.reduce(
168
+ (acc, cur) => [...acc, ...(cur.getChildren(n => n instanceof Mesh, false) as Mesh[])],
169
+ this.nodes.filter(n => n instanceof Mesh) as Mesh[]
170
+ );
148
171
  }
149
172
 
150
173
  /**
@@ -152,14 +175,10 @@ export class Element extends VariantParameterizable {
152
175
  * I.e. (real) Meshes as well as InstancedMeshes.
153
176
  */
154
177
  get abstractMeshesFlat(): AbstractMesh[] {
155
- const allAbstractMeshes = this.nodes.reduce((acc, currNode) => {
156
- const currAbstractMeshes = currNode.getChildMeshes(false, n => n instanceof AbstractMesh);
157
- if (currNode instanceof AbstractMesh) {
158
- currAbstractMeshes.unshift(currNode);
159
- }
160
- return [...acc, ...currAbstractMeshes];
161
- }, [] as AbstractMesh[]); // initial accumulator value
162
- return allAbstractMeshes;
178
+ return this.nodes.reduce(
179
+ (acc, cur) => [...acc, ...(cur.getChildren(n => n instanceof AbstractMesh, false) as AbstractMesh[])],
180
+ this.nodes.filter(n => n instanceof AbstractMesh) as AbstractMesh[]
181
+ );
163
182
  }
164
183
 
165
184
  /**
@@ -382,7 +401,7 @@ export class Element extends VariantParameterizable {
382
401
  */
383
402
  protected addParameterObservers(): Element {
384
403
  this._parameterObservers.set(Parameter.VISIBLE, [
385
- async (element: Element, oldValue: ParameterValue, newValue: ParameterValue) => {
404
+ async (element: Element, oldValue: Undefinable<ParameterValue>, newValue: ParameterValue) => {
386
405
  let visible;
387
406
  try {
388
407
  visible = Parameter.parseBoolean(newValue);
@@ -390,6 +409,29 @@ export class Element extends VariantParameterizable {
390
409
  return;
391
410
  }
392
411
  if (visible === true) {
412
+ // Override visible state and materials if tag manager is in use to support texture lazy loading
413
+ if (element.variant.viewer.tagManager.parameters.size > 0) {
414
+ const hiddenNodeNames: string[] = [];
415
+ element.variant.viewer.tagManager.parameters.forEach((parameterBag, subject) => {
416
+ const nodes = element.variant.viewer.tagManager.getNodesBySubject(subject);
417
+ if (parameterBag[Parameter.VISIBLE] === false) {
418
+ hiddenNodeNames.push(...nodes.map(node => node.name));
419
+ }
420
+ // overwrite materials immediatly, so that original material of node doesn't get loaded, since it could
421
+ // be exchanged by the tag manager
422
+ if (parameterBag[Parameter.MATERIAL]) {
423
+ nodes.forEach(node => setMaterial(node, parameterBag[Parameter.MATERIAL], false));
424
+ }
425
+ });
426
+ // enable all nodes that are not explicitely hidden by the tag manager
427
+ element.nodesFlat.map(node => {
428
+ if (!hiddenNodeNames.includes(node.name)) {
429
+ node.setEnabled(true);
430
+ }
431
+ });
432
+ return;
433
+ }
434
+ // The default behaviour.
393
435
  element.nodes.forEach(node => {
394
436
  injectNodeMetadata(node, { visibility: node.isEnabled() });
395
437
  activate(node);
@@ -403,71 +445,67 @@ export class Element extends VariantParameterizable {
403
445
  },
404
446
  ]);
405
447
  this._parameterObservers.set(Parameter.SCALING, [
406
- async (element: Element, oldValue: ParameterValue, newValue: ParameterValue) => {
448
+ async (element: Element, oldValue: Undefinable<ParameterValue>, newValue: ParameterValue) => {
407
449
  // we have to deal just with root nodes here due to relative impacts in a node tree
408
450
  element.nodes.forEach(node =>
409
451
  transformTransformNode(node, {
410
452
  scaling: Parameter.parseVector(newValue),
411
- position: Parameter.parseVector(element.inheritedParameters[Parameter.POSITION] || '(0, 0, 0)'),
412
- rotation: Parameter.parseRotation(element.inheritedParameters[Parameter.ROTATION] || '(0, 0, 0)'),
453
+ position: Parameter.parseVector(
454
+ element.inheritedParameters[Parameter.POSITION] || Parameter.getDefaultValue(Parameter.POSITION)
455
+ ),
456
+ rotation: Parameter.parseRotation(
457
+ element.inheritedParameters[Parameter.ROTATION] || Parameter.getDefaultValue(Parameter.ROTATION)
458
+ ),
413
459
  })
414
460
  );
415
461
  },
416
462
  ]);
417
463
  this._parameterObservers.set(Parameter.POSITION, [
418
- async (element: Element, oldValue: ParameterValue, newValue: ParameterValue) => {
464
+ async (element: Element, oldValue: Undefinable<ParameterValue>, newValue: ParameterValue) => {
419
465
  // we have to deal just with root nodes here due to relative impacts in a node tree
420
466
  element.nodes.forEach(node =>
421
467
  transformTransformNode(node, {
422
- scaling: Parameter.parseVector(element.inheritedParameters[Parameter.SCALING] || '(1, 1, 1)'),
468
+ scaling: Parameter.parseVector(
469
+ element.inheritedParameters[Parameter.SCALING] || Parameter.getDefaultValue(Parameter.SCALING)
470
+ ),
423
471
  position: Parameter.parseVector(newValue),
424
- rotation: Parameter.parseRotation(element.inheritedParameters[Parameter.ROTATION] || '(0, 0, 0)'),
472
+ rotation: Parameter.parseRotation(
473
+ element.inheritedParameters[Parameter.ROTATION] || Parameter.getDefaultValue(Parameter.ROTATION)
474
+ ),
425
475
  })
426
476
  );
427
477
  },
428
478
  ]);
429
479
  this._parameterObservers.set(Parameter.ROTATION, [
430
- async (element: Element, oldValue: ParameterValue, newValue: ParameterValue) => {
480
+ async (element: Element, oldValue: Undefinable<ParameterValue>, newValue: ParameterValue) => {
431
481
  // we have to deal just with root nodes here due to relative impacts in a node tree
432
482
  element.nodes.forEach(node =>
433
483
  transformTransformNode(node, {
434
- scaling: Parameter.parseVector(element.inheritedParameters[Parameter.SCALING] || '(1, 1, 1)'),
435
- position: Parameter.parseVector(element.inheritedParameters[Parameter.POSITION] || '(0, 0, 0)'),
484
+ scaling: Parameter.parseVector(
485
+ element.inheritedParameters[Parameter.SCALING] || Parameter.getDefaultValue(Parameter.SCALING)
486
+ ),
487
+ position: Parameter.parseVector(
488
+ element.inheritedParameters[Parameter.POSITION] || Parameter.getDefaultValue(Parameter.POSITION)
489
+ ),
436
490
  rotation: Parameter.parseRotation(newValue),
437
491
  })
438
492
  );
439
493
  },
440
494
  ]);
441
495
  this._parameterObservers.set(Parameter.MATERIAL, [
442
- async (element: Element, oldValue: ParameterValue, newValue: ParameterValue) => {
496
+ async (element: Element, oldValue: Undefinable<ParameterValue>, newValue: ParameterValue) => {
443
497
  const materialName = newValue.toString();
444
498
  for (const node of element.nodes) {
445
- assertTransformNode(node, (node: AbstractMesh) => {
446
- if (node instanceof InstancedMesh) {
447
- throw new Error(
448
- `Changing parameter "${Parameter.MATERIAL}" ` +
449
- `of an InstancedMesh is not supported. ` +
450
- `Tried to change node "${node.id}" on element "${element.id}".`
451
- );
452
- }
453
- });
454
- setMaterial(element.variant.viewer.scene, node, materialName, true, element.variant);
499
+ assertTransformNode(node, node => assertMeshCapability(node, Parameter.MATERIAL));
500
+ setMaterial(node, materialName, true, element.variant);
455
501
  }
456
502
  },
457
503
  ]);
458
504
  this._parameterObservers.set(Parameter.MATERIAL_COLOR, [
459
- async (element: Element, oldValue: ParameterValue, newValue: ParameterValue) => {
505
+ async (element: Element, oldValue: Undefinable<ParameterValue>, newValue: ParameterValue) => {
460
506
  const color = Parameter.parseColor(newValue);
461
507
  element.nodes.forEach(node => {
462
- assertTransformNode(node, (node: AbstractMesh) => {
463
- if (node instanceof InstancedMesh) {
464
- throw new Error(
465
- `Changing parameter "${Parameter.MATERIAL_COLOR}" ` +
466
- `of an InstancedMesh is not supported. ` +
467
- `Tried to change node "${node.id}" on element "${element.id}".`
468
- );
469
- }
470
- });
508
+ assertTransformNode(node, node => assertMeshCapability(node, Parameter.MATERIAL_COLOR));
471
509
  if (this.variant.viewer.cloneMaterialsOnMutation) {
472
510
  if (!has(node.metadata, 'dirty.material')) {
473
511
  cloneTransformNodeMaterial(node);
@@ -482,18 +520,10 @@ export class Element extends VariantParameterizable {
482
520
  },
483
521
  ]);
484
522
  this._parameterObservers.set(Parameter.MATERIAL_METALLNESS, [
485
- async (element: Element, oldValue: ParameterValue, newValue: ParameterValue) => {
523
+ async (element: Element, oldValue: Undefinable<ParameterValue>, newValue: ParameterValue) => {
486
524
  const metallness = Parameter.parseNumber(newValue);
487
525
  element.nodes.forEach(node => {
488
- assertTransformNode(node, (node: AbstractMesh) => {
489
- if (node instanceof InstancedMesh) {
490
- throw new Error(
491
- `Changing parameter "${Parameter.MATERIAL_METALLNESS}" ` +
492
- `of an InstancedMesh is not supported. ` +
493
- `Tried to change node "${node.id}" on element "${element.id}".`
494
- );
495
- }
496
- });
526
+ assertTransformNode(node, node => assertMeshCapability(node, Parameter.MATERIAL_METALLNESS));
497
527
  if (this.variant.viewer.cloneMaterialsOnMutation) {
498
528
  if (!has(node.metadata, 'dirty.material')) {
499
529
  cloneTransformNodeMaterial(node);
@@ -508,18 +538,10 @@ export class Element extends VariantParameterizable {
508
538
  },
509
539
  ]);
510
540
  this._parameterObservers.set(Parameter.MATERIAL_ROUGHNESS, [
511
- async (element: Element, oldValue: ParameterValue, newValue: ParameterValue) => {
541
+ async (element: Element, oldValue: Undefinable<ParameterValue>, newValue: ParameterValue) => {
512
542
  const roughness = Parameter.parseNumber(newValue);
513
543
  element.nodes.forEach(node => {
514
- assertTransformNode(node, (node: AbstractMesh) => {
515
- if (node instanceof InstancedMesh) {
516
- throw new Error(
517
- `Changing parameter "${Parameter.MATERIAL_ROUGHNESS}" ` +
518
- `of an InstancedMesh is not supported. ` +
519
- `Tried to change node "${node.id}" on element "${element.id}".`
520
- );
521
- }
522
- });
544
+ assertTransformNode(node, node => assertMeshCapability(node, Parameter.MATERIAL_ROUGHNESS));
523
545
  if (this.variant.viewer.cloneMaterialsOnMutation) {
524
546
  if (!has(node.metadata, 'dirty.material')) {
525
547
  cloneTransformNodeMaterial(node);
@@ -534,7 +556,7 @@ export class Element extends VariantParameterizable {
534
556
  },
535
557
  ]);
536
558
  this._parameterObservers.set(Parameter.HIGHLIGHT_COLOR, [
537
- async (element: Element, oldValue: ParameterValue, newValue: ParameterValue) => {
559
+ async (element: Element, oldValue: Undefinable<ParameterValue>, newValue: ParameterValue) => {
538
560
  // trigger Parameter.HIGHLIGHTED observers
539
561
  this._parameterObservers.get(Parameter.HIGHLIGHTED)?.forEach(observer => {
540
562
  observer(element, !!element.highlighted, !!element.highlighted);
@@ -542,7 +564,7 @@ export class Element extends VariantParameterizable {
542
564
  },
543
565
  ]);
544
566
  this._parameterObservers.set(Parameter.HIGHLIGHT_ENABLED, [
545
- async (element: Element, oldValue: ParameterValue, newValue: ParameterValue) => {
567
+ async (element: Element, oldValue: Undefinable<ParameterValue>, newValue: ParameterValue) => {
546
568
  let curr;
547
569
  try {
548
570
  curr = Parameter.parseBoolean(newValue);
@@ -566,7 +588,7 @@ export class Element extends VariantParameterizable {
566
588
  },
567
589
  ]);
568
590
  this._parameterObservers.set(Parameter.HIGHLIGHTED, [
569
- async (element: Element, oldValue: ParameterValue, newValue: ParameterValue) => {
591
+ async (element: Element, oldValue: Undefinable<ParameterValue>, newValue: ParameterValue) => {
570
592
  if (!element.inheritedParameters[Parameter.HIGHLIGHT_ENABLED]) {
571
593
  return;
572
594
  }
@@ -583,15 +605,7 @@ export class Element extends VariantParameterizable {
583
605
  // Add/Remove meshes to previously created highlight layers.
584
606
  if (highlighted === true) {
585
607
  element.nodes.forEach(node => {
586
- assertTransformNode(node, (node: AbstractMesh) => {
587
- if (node instanceof InstancedMesh) {
588
- throw new Error(
589
- `Changing parameter "${Parameter.HIGHLIGHTED}" ` +
590
- `of an InstancedMesh is not supported. ` +
591
- `Tried to change node "${node.id}" on element "${element.id}".`
592
- );
593
- }
594
- });
608
+ assertTransformNode(node, node => assertMeshCapability(node, Parameter.HIGHLIGHTED));
595
609
  let color = Color3.Green();
596
610
  if (element.inheritedParameters[Parameter.HIGHLIGHT_COLOR]) {
597
611
  color = Parameter.parseColor(element.inheritedParameters[Parameter.HIGHLIGHT_COLOR]);
@@ -610,7 +624,7 @@ export class Element extends VariantParameterizable {
610
624
  },
611
625
  ]);
612
626
  this._parameterObservers.set(Parameter.CAST_SHADOW, [
613
- async (element: Element, oldValue: ParameterValue, newValue: ParameterValue) => {
627
+ async (element: Element, oldValue: Undefinable<ParameterValue>, newValue: ParameterValue) => {
614
628
  let castShadow;
615
629
  try {
616
630
  castShadow = Parameter.parseBoolean(newValue);
@@ -630,7 +644,7 @@ export class Element extends VariantParameterizable {
630
644
  },
631
645
  ]);
632
646
  this._parameterObservers.set(Parameter.CAST_SHADOW_FROM_LIGHTS, [
633
- async (element: Element, oldValue: ParameterValue, newValue: ParameterValue) => {
647
+ async (element: Element, oldValue: Undefinable<ParameterValue>, newValue: ParameterValue) => {
634
648
  // TODO: Possible performance issue in combination with CAST_SHADOW, since both observers are initially called
635
649
  // when CAST_SHADOW and CAST_SHADOW_FROM_LIGHTS are defined in the spec.
636
650
  const lightCsl = element.variant.inheritedViewerLights.map(l => l.name).join(',');
@@ -646,7 +660,7 @@ export class Element extends VariantParameterizable {
646
660
  },
647
661
  ]);
648
662
  this._parameterObservers.set(Parameter.RECEIVE_SHADOWS, [
649
- async (element: Element, oldValue: ParameterValue, newValue: ParameterValue) => {
663
+ async (element: Element, oldValue: Undefinable<ParameterValue>, newValue: ParameterValue) => {
650
664
  element.nodes.forEach(node => setReceiveShadows(node, Parameter.parseBoolean(newValue)));
651
665
  },
652
666
  ]);
@@ -50,6 +50,7 @@ export class Event {
50
50
  * * viewer: {@link Viewer}
51
51
  */
52
52
  public static readonly BOOTSTRAP_START = 'bootstrapStart';
53
+
53
54
  /**
54
55
  * Fired after bootstrapping of the {@link Viewer} finished.
55
56
  *
@@ -72,6 +73,7 @@ export class Event {
72
73
  * * path: string
73
74
  */
74
75
  public static readonly LOADING_START = 'loadingStart';
76
+
75
77
  /**
76
78
  * Fired after loading any type of JSON or resource finished.
77
79
  *
@@ -94,6 +96,7 @@ export class Event {
94
96
  * * variant: {@link Variant}
95
97
  */
96
98
  public static readonly ASSET_LOADING_START = 'assetLoadingStart';
99
+
97
100
  /**
98
101
  * Fired after loading an asset (e.g. glTF) onto the scene finished.
99
102
  *
@@ -117,6 +120,7 @@ export class Event {
117
120
  * * sceneJson: {@link SceneJson}
118
121
  */
119
122
  public static readonly SCENE_PROCESSING_START = 'sceneProcessingStart';
123
+
120
124
  /**
121
125
  * Fired after scene initialization end when bootstrapping the {@link Viewer}.
122
126
  *
@@ -134,12 +138,13 @@ export class Event {
134
138
  *
135
139
  * Scopes:
136
140
  * * Global
137
- * * {@link Variant}
141
+ * * {@link Viewer}
138
142
  *
139
143
  * Payload:
140
144
  * * variant: {@link Variant}
141
145
  */
142
146
  public static readonly VARIANT_CREATED = 'variantCreated';
147
+
143
148
  /**
144
149
  * Fired after a {@link Variant} has been destroyed.
145
150
  *
@@ -217,6 +222,7 @@ export class Event {
217
222
  * * variantInstance: {@link VariantInstance}
218
223
  */
219
224
  public static readonly VARIANT_INSTANCE_CREATED = 'variantInstanceCreated';
225
+
220
226
  /**
221
227
  * Fired after a {@link VariantInstance} has been registered. This is the case when the {@link VariantInstance} is
222
228
  * considered "lazy".
@@ -229,6 +235,7 @@ export class Event {
229
235
  * * variantInstanceDefinition: {@link VariantInstanceDefinition}
230
236
  */
231
237
  public static readonly VARIANT_INSTANCE_REGISTERED = 'variantInstanceRegistered';
238
+
232
239
  /**
233
240
  * Fired after a {@link VariantInstance} has been cloned.
234
241
  *
@@ -240,6 +247,7 @@ export class Event {
240
247
  * * variantInstanceClone: {@link VariantInstance}
241
248
  */
242
249
  public static readonly VARIANT_INSTANCE_CLONED = 'variantInstanceCloned';
250
+
243
251
  /**
244
252
  * Fired after a {@link VariantInstance} has been destroyed.
245
253
  *
@@ -252,6 +260,42 @@ export class Event {
252
260
  */
253
261
  public static readonly VARIANT_INSTANCE_DESTROYED = 'variantInstanceDestroyed';
254
262
 
263
+ /**
264
+ * Fired after all {@link VariantInstance}s have been either created or registered.
265
+ *
266
+ * Scopes:
267
+ * * Global
268
+ * * {@link Viewer}
269
+ *
270
+ * Payload:
271
+ * * viewer: {@link viewer}
272
+ */
273
+ public static readonly VARIANT_INSTANCES_READY = 'variantInstancesReady';
274
+
275
+ /**
276
+ * Fired after the nodes of a {@link Variant} has been cloned to the {@link Element}.
277
+ *
278
+ * Scopes:
279
+ * * Global
280
+ * * {@link Variant}
281
+ *
282
+ * Payload:
283
+ * * element: {@link Element}
284
+ */
285
+ public static readonly ELEMENT_NODES_CLONED = 'elementNodesCloned';
286
+
287
+ /**
288
+ * Fired after an {@link Element} has been created.
289
+ *
290
+ * Scopes:
291
+ * * Global
292
+ * * {@link Variant}
293
+ *
294
+ * Payload:
295
+ * * element: {@link Element}
296
+ */
297
+ public static readonly ELEMENT_CREATED = 'elementCreated';
298
+
255
299
  /**
256
300
  * Fired after a parameter on an {@link Element} has been committed.
257
301
  *
@@ -341,6 +385,29 @@ export class Event {
341
385
  */
342
386
  public static readonly TEXTURE_LOADING_END = 'textureLoadingEnd';
343
387
 
388
+ /**
389
+ * Fired after a {@link Material} has been applied to a {@link Mesh}.
390
+ *
391
+ * Scopes:
392
+ * * Global
393
+ *
394
+ * Payload:
395
+ * * mesh: {@link Mesh}
396
+ * * material: {@link Material}
397
+ */
398
+ public static readonly MESH_MATERIAL_APPLIED = 'meshMaterialApplied';
399
+
400
+ /**
401
+ * Fired after a {@link TagManagerParameterObserver} has been called.
402
+ *
403
+ * Scopes:
404
+ * * Global
405
+ *
406
+ * Payload:
407
+ * * payload: {@link ParameterObserverResult}
408
+ */
409
+ public static readonly TAG_MANAGER_PARAMETER_COMMITTED = 'tagManagerParameterCommitted';
410
+
344
411
  /**
345
412
  * All events defined in this class.
346
413
  */
@@ -0,0 +1,21 @@
1
+ export class FuzzyMap<K, V> extends Map {
2
+ get(key: K): V | undefined {
3
+ return super.get(this._key(key));
4
+ }
5
+
6
+ has(key: K): boolean {
7
+ return super.has(this._key(key));
8
+ }
9
+
10
+ set(key: K, value: V): this {
11
+ return super.set(this._key(key) || key, value);
12
+ }
13
+
14
+ delete(key: K): boolean {
15
+ return super.delete(this._key(key));
16
+ }
17
+
18
+ _key(key: K): K {
19
+ return [...super.keys()].find(k => JSON.stringify(k) === JSON.stringify(key));
20
+ }
21
+ }