@combeenation/3d-viewer 4.2.0 → 4.3.0-alpha1

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 (80) hide show
  1. package/README.md +2 -2
  2. package/dist/lib-cjs/api/classes/dottedPath.js +2 -5
  3. package/dist/lib-cjs/api/classes/dottedPath.js.map +1 -1
  4. package/dist/lib-cjs/api/classes/element.js +89 -66
  5. package/dist/lib-cjs/api/classes/element.js.map +1 -1
  6. package/dist/lib-cjs/api/classes/event.js.map +1 -1
  7. package/dist/lib-cjs/api/classes/eventBroadcaster.js.map +1 -1
  8. package/dist/lib-cjs/api/classes/parameter.js +3 -2
  9. package/dist/lib-cjs/api/classes/parameter.js.map +1 -1
  10. package/dist/lib-cjs/api/classes/parameterObservable.js.map +1 -1
  11. package/dist/lib-cjs/api/classes/parameterizable.js.map +1 -1
  12. package/dist/lib-cjs/api/classes/placementAnimation.js +2 -2
  13. package/dist/lib-cjs/api/classes/placementAnimation.js.map +1 -1
  14. package/dist/lib-cjs/api/classes/variant.js +26 -19
  15. package/dist/lib-cjs/api/classes/variant.js.map +1 -1
  16. package/dist/lib-cjs/api/classes/variantInstance.js +19 -19
  17. package/dist/lib-cjs/api/classes/variantInstance.js.map +1 -1
  18. package/dist/lib-cjs/api/classes/variantParameterizable.js.map +1 -1
  19. package/dist/lib-cjs/api/classes/viewer.d.ts +5 -0
  20. package/dist/lib-cjs/api/classes/viewer.js +32 -17
  21. package/dist/lib-cjs/api/classes/viewer.js.map +1 -1
  22. package/dist/lib-cjs/api/classes/viewerLight.js +24 -24
  23. package/dist/lib-cjs/api/classes/viewerLight.js.map +1 -1
  24. package/dist/lib-cjs/api/internal/debugViewer.js +1 -2
  25. package/dist/lib-cjs/api/internal/debugViewer.js.map +1 -1
  26. package/dist/lib-cjs/api/internal/lensRendering.js.map +1 -1
  27. package/dist/lib-cjs/api/internal/sceneSetup.js +25 -22
  28. package/dist/lib-cjs/api/internal/sceneSetup.js.map +1 -1
  29. package/dist/lib-cjs/api/manager/animationManager.js +24 -15
  30. package/dist/lib-cjs/api/manager/animationManager.js.map +1 -1
  31. package/dist/lib-cjs/api/manager/sceneManager.js +3 -3
  32. package/dist/lib-cjs/api/manager/sceneManager.js.map +1 -1
  33. package/dist/lib-cjs/api/manager/variantInstanceManager.js +10 -7
  34. package/dist/lib-cjs/api/manager/variantInstanceManager.js.map +1 -1
  35. package/dist/lib-cjs/api/store/specStorage.js.map +1 -1
  36. package/dist/lib-cjs/api/util/babylonHelper.d.ts +1 -1
  37. package/dist/lib-cjs/api/util/babylonHelper.js +12 -15
  38. package/dist/lib-cjs/api/util/babylonHelper.js.map +1 -1
  39. package/dist/lib-cjs/api/util/globalTypes.d.ts +25 -24
  40. package/dist/lib-cjs/api/util/resourceHelper.js +3 -1
  41. package/dist/lib-cjs/api/util/resourceHelper.js.map +1 -1
  42. package/dist/lib-cjs/api/util/stringHelper.d.ts +1 -1
  43. package/dist/lib-cjs/api/util/stringHelper.js +2 -2
  44. package/dist/lib-cjs/api/util/stringHelper.js.map +1 -1
  45. package/dist/lib-cjs/index.js.map +1 -1
  46. package/package.json +7 -3
  47. package/src/api/classes/animationInterface.ts +4 -6
  48. package/src/api/classes/dottedPath.ts +179 -187
  49. package/src/api/classes/element.ts +644 -621
  50. package/src/api/classes/event.ts +310 -313
  51. package/src/api/classes/eventBroadcaster.ts +47 -49
  52. package/src/api/classes/parameter.ts +394 -397
  53. package/src/api/classes/parameterObservable.ts +84 -83
  54. package/src/api/classes/parameterizable.ts +71 -73
  55. package/src/api/classes/placementAnimation.ts +130 -130
  56. package/src/api/classes/variant.ts +806 -778
  57. package/src/api/classes/variantInstance.ts +60 -52
  58. package/src/api/classes/variantParameterizable.ts +72 -67
  59. package/src/api/classes/viewer.ts +531 -489
  60. package/src/api/classes/viewerLight.ts +300 -300
  61. package/src/api/internal/debugViewer.ts +61 -53
  62. package/src/api/internal/lensRendering.ts +2 -3
  63. package/src/api/internal/sceneSetup.ts +144 -137
  64. package/src/api/manager/animationManager.ts +122 -97
  65. package/src/api/manager/sceneManager.ts +83 -86
  66. package/src/api/manager/variantInstanceManager.ts +234 -224
  67. package/src/api/store/specStorage.ts +48 -51
  68. package/src/api/util/babylonHelper.ts +329 -325
  69. package/src/api/util/globalTypes.ts +244 -245
  70. package/src/api/util/resourceHelper.ts +97 -109
  71. package/src/api/util/stringHelper.ts +13 -16
  72. package/src/buildinfo.json +2 -2
  73. package/src/commonjs.tsconfig.json +8 -11
  74. package/src/declaration.tsconfig.json +6 -8
  75. package/src/dev.ts +28 -28
  76. package/src/es6.tsconfig.json +8 -11
  77. package/src/index.ts +39 -39
  78. package/src/tsconfig.json +30 -41
  79. package/src/tsconfig.types.json +8 -9
  80. package/src/types.d.ts +0 -1
@@ -21,48 +21,47 @@ import { DottedPath } from '../classes/dottedPath';
21
21
  * @param node
22
22
  * @return Node
23
23
  */
24
- const getRootNode = function( node: Node ): Node {
25
- let _node = node;
26
- while( _node.parent ) {
27
- _node = _node.parent;
28
- }
29
- return _node;
30
- }
24
+ const getRootNode = function (node: Node): Node {
25
+ let _node = node;
26
+ while (_node.parent) {
27
+ _node = _node.parent;
28
+ }
29
+ return _node;
30
+ };
31
31
 
32
32
  /**
33
33
  * @param nodes
34
34
  * @param predicate
35
35
  * @return Map<DottedPath, T>
36
36
  */
37
- const mapToDottedNodes = function <T>( nodes: Node[],
38
- predicate?: ( node: Node ) => boolean ): Map<DottedPath, T> {
39
- const map = new Map<DottedPath, T>();
40
- const addNodes = function( _node: Node ) {
41
- if( predicate && predicate( _node ) ) {
42
- map.set( _node.metadata.dottedPath, _node as any );
43
- }
44
- _node.getChildren().forEach( child => {
45
- addNodes( child );
46
- } );
47
- };
48
- nodes.forEach( node => {
49
- addNodes( node );
50
- } );
51
- return map;
37
+ const mapToDottedNodes = function <T>(nodes: Node[], predicate?: (node: Node) => boolean): Map<DottedPath, T> {
38
+ const map = new Map<DottedPath, T>();
39
+ const addNodes = function (_node: Node) {
40
+ if (predicate && predicate(_node)) {
41
+ map.set(_node.metadata.dottedPath, _node as any);
42
+ }
43
+ _node.getChildren().forEach(child => {
44
+ addNodes(child);
45
+ });
46
+ };
47
+ nodes.forEach(node => {
48
+ addNodes(node);
49
+ });
50
+ return map;
52
51
  };
53
52
 
54
53
  /**
55
54
  * @param node
56
55
  * @return DottedPath
57
56
  */
58
- const getDottedPathForNode = function( node: Node ): DottedPath {
59
- const dottedPath = DottedPath.create( node.name );
60
- let _parent = node;
61
- while( _parent.parent ) {
62
- _parent = _parent.parent;
63
- dottedPath.unshiftPart( _parent.name );
64
- }
65
- return dottedPath;
57
+ const getDottedPathForNode = function (node: Node): DottedPath {
58
+ const dottedPath = DottedPath.create(node.name);
59
+ let _parent = node;
60
+ while (_parent.parent) {
61
+ _parent = _parent.parent;
62
+ dottedPath.unshiftPart(_parent.name);
63
+ }
64
+ return dottedPath;
66
65
  };
67
66
 
68
67
  /**
@@ -71,41 +70,43 @@ const getDottedPathForNode = function( node: Node ): DottedPath {
71
70
  * @param deep
72
71
  * @return TransformNode | null
73
72
  */
74
- const cloneTransformNode = function( node: TransformNode,
75
- predicate?: ( node: TransformNode ) => boolean,
76
- deep: boolean = true ): TransformNode | null {
77
- if( predicate && !predicate( node ) ) {
78
- return null;
79
- }
80
- const clone = node.clone( node.name, node.parent, true );
81
- if( clone ) {
82
- clone.metadata = cloneDeep( node.metadata );
83
- }
84
- if( deep ) {
85
- const children = node.getChildTransformNodes( true );
86
- children.forEach( child => {
87
- const clonedChild = cloneTransformNode( child, predicate, deep );
88
- if( clonedChild ) {
89
- clonedChild.parent = clone;
90
- }
91
- } );
92
- }
93
- return clone;
73
+ const cloneTransformNode = function (
74
+ node: TransformNode,
75
+ predicate?: (node: TransformNode) => boolean,
76
+ deep: boolean = true
77
+ ): TransformNode | null {
78
+ if (predicate && !predicate(node)) {
79
+ return null;
80
+ }
81
+ const clone = node.clone(node.name, node.parent, true);
82
+ if (clone) {
83
+ clone.metadata = cloneDeep(node.metadata);
84
+ }
85
+ if (deep) {
86
+ const children = node.getChildTransformNodes(true);
87
+ children.forEach(child => {
88
+ const clonedChild = cloneTransformNode(child, predicate, deep);
89
+ if (clonedChild) {
90
+ clonedChild.parent = clone;
91
+ }
92
+ });
93
+ }
94
+ return clone;
94
95
  };
95
96
 
96
97
  /**
97
98
  * @param node
98
99
  */
99
- const cloneNodeWithParents = function( node: Node | null ): Node | null {
100
- let clone = null;
101
- if( node instanceof TransformNode ) {
102
- clone = node.clone( node.name, cloneNodeWithParents( node.parent ) as Nullable<Node>, true );
103
- } else if( node instanceof Light ) {
104
- clone = node.clone( node.name, cloneNodeWithParents( node.parent ) as Nullable<Node> );
105
- } else if( node ) {
106
- throw new Error( `Cloning of "${node?.constructor.name}" is not implemented (yet).` );
107
- }
108
- return clone;
100
+ const cloneNodeWithParents = function (node: Node | null): Node | null {
101
+ let clone = null;
102
+ if (node instanceof TransformNode) {
103
+ clone = node.clone(node.name, cloneNodeWithParents(node.parent) as Nullable<Node>, true);
104
+ } else if (node instanceof Light) {
105
+ clone = node.clone(node.name, cloneNodeWithParents(node.parent) as Nullable<Node>);
106
+ } else if (node) {
107
+ throw new Error(`Cloning of "${node?.constructor.name}" is not implemented (yet).`);
108
+ }
109
+ return clone;
109
110
  };
110
111
 
111
112
  /**
@@ -114,21 +115,20 @@ const cloneNodeWithParents = function( node: Node | null ): Node | null {
114
115
  * @param prefix
115
116
  * @return TransformNode
116
117
  */
117
- const cloneTransformNodeMaterial = function( node: TransformNode,
118
- prefix: DottedPathArgument = '',
119
- deep: boolean = true ): TransformNode {
120
- if( node instanceof AbstractMesh && node.material ) {
121
- const _prefix = DottedPath.create( prefix ).addParts([
122
- 'node',
123
- node.uniqueId.toString()
124
- ]);
125
- node.material = node.material.clone( _prefix.path );
126
- }
127
- if( deep ) {
128
- const children = node.getChildTransformNodes( true );
129
- children.forEach( child => cloneTransformNodeMaterial( child, prefix, deep ) );
130
- }
131
- return node;
118
+ const cloneTransformNodeMaterial = function (
119
+ node: TransformNode,
120
+ prefix: DottedPathArgument = '',
121
+ deep: boolean = true
122
+ ): TransformNode {
123
+ if (node instanceof AbstractMesh && node.material) {
124
+ const newMatName = DottedPath.create(prefix).addParts([node.material.name, 'clone', node.uniqueId.toString()]);
125
+ node.material = node.material.clone(newMatName.path);
126
+ }
127
+ if (deep) {
128
+ const children = node.getChildTransformNodes(true);
129
+ children.forEach(child => cloneTransformNodeMaterial(child, prefix, deep));
130
+ }
131
+ return node;
132
132
  };
133
133
 
134
134
  /**
@@ -136,12 +136,12 @@ const cloneTransformNodeMaterial = function( node: TransformNode,
136
136
  * @param deep
137
137
  * @param metadata
138
138
  */
139
- const injectNodeMetadata = function( node: Node, metadata: {}, deep: boolean = true ) {
140
- node.metadata = merge( {}, node.metadata, metadata );
141
- if( deep && node instanceof TransformNode ) {
142
- const children = node.getChildTransformNodes( true );
143
- children.forEach( child => injectNodeMetadata( child, metadata, deep ) );
144
- }
139
+ const injectNodeMetadata = function (node: Node, metadata: {}, deep: boolean = true) {
140
+ node.metadata = merge({}, node.metadata, metadata);
141
+ if (deep && node instanceof TransformNode) {
142
+ const children = node.getChildTransformNodes(true);
143
+ children.forEach(child => injectNodeMetadata(child, metadata, deep));
144
+ }
145
145
  };
146
146
 
147
147
  /**
@@ -150,69 +150,71 @@ const injectNodeMetadata = function( node: Node, metadata: {}, deep: boolean = t
150
150
  * @param callableParameters
151
151
  * @param deep
152
152
  */
153
- const assertTransformNode = function( node: TransformNode,
154
- assertCallable: CallableFunction,
155
- callableParameters: any[] = [],
156
- deep: boolean = true ) {
157
- assertCallable(node, ...callableParameters);
158
- if( deep ) {
159
- const children = node.getChildTransformNodes( true );
160
- children.forEach( child => assertTransformNode( child, assertCallable, callableParameters, deep ) );
161
- }
153
+ const assertTransformNode = function (
154
+ node: TransformNode,
155
+ assertCallable: CallableFunction,
156
+ callableParameters: any[] = [],
157
+ deep: boolean = true
158
+ ) {
159
+ assertCallable(node, ...callableParameters);
160
+ if (deep) {
161
+ const children = node.getChildTransformNodes(true);
162
+ children.forEach(child => assertTransformNode(child, assertCallable, callableParameters, deep));
163
+ }
162
164
  };
163
165
 
164
166
  /**
165
167
  * @param node
166
168
  * @param deep
167
169
  */
168
- const activateTransformNode = function( node: TransformNode, deep: boolean = true ) {
169
- node.setEnabled( true );
170
- /*
170
+ const activateTransformNode = function (node: TransformNode, deep: boolean = true) {
171
+ node.setEnabled(true);
172
+ /*
171
173
  if( node instanceof AbstractMesh ) {
172
174
  node.visibility = 1;
173
175
  node.isPickable = true;
174
176
  }
175
177
  */
176
- if( deep ) {
177
- node.getChildTransformNodes( true ).forEach( child => activateTransformNode( child, deep ) );
178
- }
178
+ if (deep) {
179
+ node.getChildTransformNodes(true).forEach(child => activateTransformNode(child, deep));
180
+ }
179
181
  };
180
182
 
181
183
  /**
182
184
  * @param node
183
185
  * @param deep
184
186
  */
185
- const deactivateTransformNode = function( node: TransformNode, deep: boolean = true ) {
186
- node.setEnabled( false );
187
- /*
187
+ const deactivateTransformNode = function (node: TransformNode, deep: boolean = true) {
188
+ node.setEnabled(false);
189
+ /*
188
190
  if( node instanceof AbstractMesh ) {
189
191
  node.visibility = 0;
190
192
  node.isPickable = false;
191
193
  }
192
194
  */
193
- if( deep ) {
194
- node.getChildTransformNodes( true ).forEach( child => deactivateTransformNode( child, deep ) );
195
- }
195
+ if (deep) {
196
+ node.getChildTransformNodes(true).forEach(child => deactivateTransformNode(child, deep));
197
+ }
196
198
  };
197
199
 
198
200
  /**
199
201
  * @param node
200
202
  */
201
- const enableNodeWithParents = function( node: Node ) {
202
- node.setEnabled( true );
203
- if ( node.parent ) {
204
- enableNodeWithParents( node.parent );
205
- }
203
+ const enableNodeWithParents = function (node: Node) {
204
+ node.setEnabled(true);
205
+ if (node.parent) {
206
+ enableNodeWithParents(node.parent);
207
+ }
206
208
  };
207
209
 
208
210
  /**
209
211
  * @param node
210
212
  */
211
- const disableNodeWithParents = function( node: Node ) {
212
- node.setEnabled( false );
213
- if ( node.parent ) {
214
- disableNodeWithParents( node.parent );
215
- }
213
+ const disableNodeWithParents = function (node: Node) {
214
+ node.setEnabled(false);
215
+ if (node.parent) {
216
+ disableNodeWithParents(node.parent);
217
+ }
216
218
  };
217
219
 
218
220
  /**
@@ -220,33 +222,33 @@ const disableNodeWithParents = function( node: Node ) {
220
222
  * @param node
221
223
  * @param transformation
222
224
  */
223
- const transformTransformNode = function( node: TransformNode, transformation: TransformationDefinition ) {
224
- // scaling
225
- if( !has( node.metadata, 'scaling.initial' ) ) {
226
- injectNodeMetadata( node, { 'scaling.initial': node.scaling }, false );
227
- }
228
- const initialScaling = get( node.metadata, 'scaling.initial' ) as Vector3;
229
- node.scaling = initialScaling.multiply( transformation.scaling );
230
- // position
231
- if( !has( node.metadata, 'position.initial' ) ) {
232
- injectNodeMetadata( node, { 'position.initial': node.absolutePosition.clone() }, false );
233
- }
234
- const initialPosition = get( node.metadata, 'position.initial' ) as Vector3;
235
- node.setAbsolutePosition( initialPosition.add( transformation.position ).multiply( transformation.scaling ) );
236
- // rotation
237
- if( !has( node.metadata, 'rotation.initial' ) ) {
238
- let rotationQuaternion = node.rotationQuaternion;
239
- if( !rotationQuaternion ) {
240
- rotationQuaternion = Quaternion.RotationYawPitchRoll( node.rotation.x, node.rotation.y, node.rotation.z );
241
- }
242
- injectNodeMetadata( node, { 'rotation.initial': rotationQuaternion.asArray() }, false );
243
- }
244
- const initialRotationQuaternion = Quaternion.FromArray( get( node.metadata, 'rotation.initial' ) as [] );
245
- node.rotationQuaternion = initialRotationQuaternion;
246
- node.rotateAround( Vector3.Zero(), Axis.X, transformation.rotation.x );
247
- node.rotateAround( Vector3.Zero(), Axis.Y, transformation.rotation.y );
248
- node.rotateAround( Vector3.Zero(), Axis.Z, transformation.rotation.z );
249
- node.computeWorldMatrix( true );
225
+ const transformTransformNode = function (node: TransformNode, transformation: TransformationDefinition) {
226
+ // scaling
227
+ if (!has(node.metadata, 'scaling.initial')) {
228
+ injectNodeMetadata(node, { 'scaling.initial': node.scaling }, false);
229
+ }
230
+ const initialScaling = get(node.metadata, 'scaling.initial') as Vector3;
231
+ node.scaling = initialScaling.multiply(transformation.scaling);
232
+ // position
233
+ if (!has(node.metadata, 'position.initial')) {
234
+ injectNodeMetadata(node, { 'position.initial': node.absolutePosition.clone() }, false);
235
+ }
236
+ const initialPosition = get(node.metadata, 'position.initial') as Vector3;
237
+ node.setAbsolutePosition(initialPosition.add(transformation.position).multiply(transformation.scaling));
238
+ // rotation
239
+ if (!has(node.metadata, 'rotation.initial')) {
240
+ let rotationQuaternion = node.rotationQuaternion;
241
+ if (!rotationQuaternion) {
242
+ rotationQuaternion = Quaternion.RotationYawPitchRoll(node.rotation.x, node.rotation.y, node.rotation.z);
243
+ }
244
+ injectNodeMetadata(node, { 'rotation.initial': rotationQuaternion.asArray() }, false);
245
+ }
246
+ const initialRotationQuaternion = Quaternion.FromArray(get(node.metadata, 'rotation.initial') as []);
247
+ node.rotationQuaternion = initialRotationQuaternion;
248
+ node.rotateAround(Vector3.Zero(), Axis.X, transformation.rotation.x);
249
+ node.rotateAround(Vector3.Zero(), Axis.Y, transformation.rotation.y);
250
+ node.rotateAround(Vector3.Zero(), Axis.Z, transformation.rotation.z);
251
+ node.computeWorldMatrix(true);
250
252
  };
251
253
 
252
254
  /**
@@ -254,43 +256,43 @@ const transformTransformNode = function( node: TransformNode, transformation: Tr
254
256
  * @param material
255
257
  * @param deep
256
258
  */
257
- const setMaterial = function( node: TransformNode, material: Material, deep: boolean = true ) {
258
- if( node instanceof AbstractMesh ) {
259
- node.material = material;
260
- }
261
- if( deep ) {
262
- node.getChildTransformNodes( true ).forEach( child => setMaterial( child, material, deep ) );
263
- }
259
+ const setMaterial = function (node: TransformNode, material: Material, deep: boolean = true) {
260
+ if (node instanceof AbstractMesh) {
261
+ node.material = material;
262
+ }
263
+ if (deep) {
264
+ node.getChildTransformNodes(true).forEach(child => setMaterial(child, material, deep));
265
+ }
264
266
  };
265
267
 
266
268
  /**
267
269
  * !!! Warning !!!
268
270
  * This function is not public API. Whilst it can help solving certain problems, it only works reliably in well defined
269
271
  * situations and can cause unwanted side effects under some conditions. Use carefully at your own risk!
270
- *
272
+ *
271
273
  * See https://combeenation.myjetbrains.com/youtrack/issue/CB-5906 for further details regarding this warning.
272
- *
274
+ *
273
275
  * Set material of an instanced meshes source mesh.
274
276
  * Changes the material of all instanced meshes which have the same source mesh.
275
- *
277
+ *
276
278
  * @param node
277
279
  * @param material
278
280
  * @param deep
279
- *
281
+ *
280
282
  * @ignore
281
283
  */
282
- const setSourceNodeMaterial = function( node: TransformNode, material: Material, deep: boolean = true ) {
283
- const warn = ` You're using "setSourceNodeMaterial" which is not public API.
284
+ const setSourceNodeMaterial = function (node: TransformNode, material: Material, deep: boolean = true) {
285
+ const warn = ` You're using "setSourceNodeMaterial" which is not public API.
284
286
  Whilst it can help solving certain problems, it only works reliably in well defined situations and can cause unwanted side effects under some conditions.
285
287
  Use carefully at your own risk!`;
286
- console.warn(`!!! Warning !!!\n${warn}`);
287
-
288
- if( node instanceof InstancedMesh ) {
289
- node.sourceMesh.material = material;
290
- }
291
- if( deep ) {
292
- node.getChildTransformNodes( true ).forEach( child => setSourceNodeMaterial( child, material, deep ) );
293
- }
288
+ console.warn(`!!! Warning !!!\n${warn}`);
289
+
290
+ if (node instanceof InstancedMesh) {
291
+ node.sourceMesh.material = material;
292
+ }
293
+ if (deep) {
294
+ node.getChildTransformNodes(true).forEach(child => setSourceNodeMaterial(child, material, deep));
295
+ }
294
296
  };
295
297
 
296
298
  /**
@@ -298,23 +300,23 @@ const setSourceNodeMaterial = function( node: TransformNode, material: Material,
298
300
  * @param color
299
301
  * @param deep
300
302
  */
301
- const setMaterialColor = function( node: TransformNode, color: Color3, deep: boolean = true ) {
302
- if( node instanceof AbstractMesh && node.material ) {
303
- const materialCls = node.material.getClassName();
304
- switch( materialCls ) {
305
- case 'PBRMaterial':
306
- (node.material as PBRMaterial).albedoColor = color.toLinearSpace();
307
- break;
308
- case 'StandardMaterial':
309
- (node.material as StandardMaterial).diffuseColor = color;
310
- break;
311
- default:
312
- throw new Error( `Setting color for material of instance "${materialCls}" not implemented (yet).` );
313
- }
314
- }
315
- if( deep ) {
316
- node.getChildTransformNodes( true ).forEach( child => setMaterialColor( child, color, deep ) );
317
- }
303
+ const setMaterialColor = function (node: TransformNode, color: Color3, deep: boolean = true) {
304
+ if (node instanceof AbstractMesh && node.material) {
305
+ const materialCls = node.material.getClassName();
306
+ switch (materialCls) {
307
+ case 'PBRMaterial':
308
+ (node.material as PBRMaterial).albedoColor = color.toLinearSpace();
309
+ break;
310
+ case 'StandardMaterial':
311
+ (node.material as StandardMaterial).diffuseColor = color;
312
+ break;
313
+ default:
314
+ throw new Error(`Setting color for material of instance "${materialCls}" not implemented (yet).`);
315
+ }
316
+ }
317
+ if (deep) {
318
+ node.getChildTransformNodes(true).forEach(child => setMaterialColor(child, color, deep));
319
+ }
318
320
  };
319
321
 
320
322
  /**
@@ -322,23 +324,23 @@ const setMaterialColor = function( node: TransformNode, color: Color3, deep: boo
322
324
  * @param texture
323
325
  * @param deep
324
326
  */
325
- const setMaterialTexture = function( node: TransformNode, texture: Texture, deep: boolean = true ) {
326
- if( node instanceof AbstractMesh && node.material ) {
327
- const materialCls = node.material.getClassName();
328
- switch( materialCls ) {
329
- case 'PBRMaterial':
330
- (node.material as PBRMaterial).albedoTexture = texture;
331
- break;
332
- case 'StandardMaterial':
333
- (node.material as StandardMaterial).diffuseTexture = texture;
334
- break;
335
- default:
336
- throw new Error( `Setting texture for material of instance "${materialCls}" not implemented (yet).` );
337
- }
338
- }
339
- if( deep ) {
340
- node.getChildTransformNodes( true ).forEach( child => setMaterialTexture( child, texture, deep ) );
341
- }
327
+ const setMaterialTexture = function (node: TransformNode, texture: Texture, deep: boolean = true) {
328
+ if (node instanceof AbstractMesh && node.material) {
329
+ const materialCls = node.material.getClassName();
330
+ switch (materialCls) {
331
+ case 'PBRMaterial':
332
+ (node.material as PBRMaterial).albedoTexture = texture;
333
+ break;
334
+ case 'StandardMaterial':
335
+ (node.material as StandardMaterial).diffuseTexture = texture;
336
+ break;
337
+ default:
338
+ throw new Error(`Setting texture for material of instance "${materialCls}" not implemented (yet).`);
339
+ }
340
+ }
341
+ if (deep) {
342
+ node.getChildTransformNodes(true).forEach(child => setMaterialTexture(child, texture, deep));
343
+ }
342
344
  };
343
345
 
344
346
  /**
@@ -346,20 +348,20 @@ const setMaterialTexture = function( node: TransformNode, texture: Texture, deep
346
348
  * @param metallness
347
349
  * @param deep
348
350
  */
349
- const setMaterialMetallness = function( node: TransformNode, metallness: number, deep: boolean = true ) {
350
- if( node instanceof AbstractMesh && node.material ) {
351
- const materialCls = node.material.getClassName();
352
- switch( materialCls ) {
353
- case 'PBRMaterial':
354
- (node.material as PBRMaterial).metallic = metallness;
355
- break;
356
- default:
357
- throw new Error( `Setting metallness for material of instance "${materialCls}" not implemented (yet).` );
358
- }
359
- }
360
- if( deep ) {
361
- node.getChildTransformNodes( true ).forEach( child => setMaterialMetallness( child, metallness, deep ) );
362
- }
351
+ const setMaterialMetallness = function (node: TransformNode, metallness: number, deep: boolean = true) {
352
+ if (node instanceof AbstractMesh && node.material) {
353
+ const materialCls = node.material.getClassName();
354
+ switch (materialCls) {
355
+ case 'PBRMaterial':
356
+ (node.material as PBRMaterial).metallic = metallness;
357
+ break;
358
+ default:
359
+ throw new Error(`Setting metallness for material of instance "${materialCls}" not implemented (yet).`);
360
+ }
361
+ }
362
+ if (deep) {
363
+ node.getChildTransformNodes(true).forEach(child => setMaterialMetallness(child, metallness, deep));
364
+ }
363
365
  };
364
366
 
365
367
  /**
@@ -367,23 +369,23 @@ const setMaterialMetallness = function( node: TransformNode, metallness: number,
367
369
  * @param roughness
368
370
  * @param deep
369
371
  */
370
- const setMaterialRoughness = function( node: TransformNode, roughness: number, deep: boolean = true ) {
371
- if( node instanceof AbstractMesh && node.material ) {
372
- const materialCls = node.material.getClassName();
373
- switch( materialCls ) {
374
- case 'PBRMaterial':
375
- (node.material as PBRMaterial).roughness = roughness;
376
- break;
377
- case 'StandardMaterial':
378
- (node.material as StandardMaterial).roughness = roughness;
379
- break;
380
- default:
381
- throw new Error( `Setting roughness for material of instance "${materialCls}" not implemented (yet).` );
382
- }
383
- }
384
- if( deep ) {
385
- node.getChildTransformNodes( true ).forEach( child => setMaterialRoughness( child, roughness, deep ) );
386
- }
372
+ const setMaterialRoughness = function (node: TransformNode, roughness: number, deep: boolean = true) {
373
+ if (node instanceof AbstractMesh && node.material) {
374
+ const materialCls = node.material.getClassName();
375
+ switch (materialCls) {
376
+ case 'PBRMaterial':
377
+ (node.material as PBRMaterial).roughness = roughness;
378
+ break;
379
+ case 'StandardMaterial':
380
+ (node.material as StandardMaterial).roughness = roughness;
381
+ break;
382
+ default:
383
+ throw new Error(`Setting roughness for material of instance "${materialCls}" not implemented (yet).`);
384
+ }
385
+ }
386
+ if (deep) {
387
+ node.getChildTransformNodes(true).forEach(child => setMaterialRoughness(child, roughness, deep));
388
+ }
387
389
  };
388
390
 
389
391
  /**
@@ -392,15 +394,13 @@ const setMaterialRoughness = function( node: TransformNode, roughness: number, d
392
394
  * @param color
393
395
  * @param deep
394
396
  */
395
- const addToHighlightLayer = function( layer: HighlightLayer, color: Color3, node: TransformNode, deep: boolean = true ) {
396
- if( node instanceof AbstractMesh ) {
397
- layer.addMesh( (node as Mesh), color );
398
- }
399
- if( deep ) {
400
- node.getChildTransformNodes( true ).forEach(
401
- child => addToHighlightLayer( layer, color, child, deep )
402
- );
403
- }
397
+ const addToHighlightLayer = function (layer: HighlightLayer, color: Color3, node: TransformNode, deep: boolean = true) {
398
+ if (node instanceof AbstractMesh) {
399
+ layer.addMesh(node as Mesh, color);
400
+ }
401
+ if (deep) {
402
+ node.getChildTransformNodes(true).forEach(child => addToHighlightLayer(layer, color, child, deep));
403
+ }
404
404
  };
405
405
 
406
406
  /**
@@ -408,15 +408,13 @@ const addToHighlightLayer = function( layer: HighlightLayer, color: Color3, node
408
408
  * @param layer
409
409
  * @param deep
410
410
  */
411
- const removeFromHighlightLayer = function( layer: HighlightLayer, node: TransformNode, deep: boolean = true ) {
412
- if( node instanceof AbstractMesh ) {
413
- layer.removeMesh( (node as Mesh) );
414
- }
415
- if( deep ) {
416
- node.getChildTransformNodes( true ).forEach(
417
- child => removeFromHighlightLayer( layer, child, deep )
418
- );
419
- }
411
+ const removeFromHighlightLayer = function (layer: HighlightLayer, node: TransformNode, deep: boolean = true) {
412
+ if (node instanceof AbstractMesh) {
413
+ layer.removeMesh(node as Mesh);
414
+ }
415
+ if (deep) {
416
+ node.getChildTransformNodes(true).forEach(child => removeFromHighlightLayer(layer, child, deep));
417
+ }
420
418
  };
421
419
 
422
420
  /**
@@ -424,15 +422,13 @@ const removeFromHighlightLayer = function( layer: HighlightLayer, node: Transfor
424
422
  * @param receiveShadows
425
423
  * @param deep
426
424
  */
427
- const setReceiveShadows = function( node: TransformNode, receiveShadows: boolean, deep: boolean = true ) {
428
- if( node instanceof AbstractMesh ) {
429
- node.receiveShadows = receiveShadows;
430
- }
431
- if( deep ) {
432
- node.getChildTransformNodes( true ).forEach(
433
- child => setReceiveShadows( child, receiveShadows, deep )
434
- );
435
- }
425
+ const setReceiveShadows = function (node: TransformNode, receiveShadows: boolean, deep: boolean = true) {
426
+ if (node instanceof AbstractMesh) {
427
+ node.receiveShadows = receiveShadows;
428
+ }
429
+ if (deep) {
430
+ node.getChildTransformNodes(true).forEach(child => setReceiveShadows(child, receiveShadows, deep));
431
+ }
436
432
  };
437
433
 
438
434
  /**
@@ -440,17 +436,15 @@ const setReceiveShadows = function( node: TransformNode, receiveShadows: boolean
440
436
  * @param generator
441
437
  * @param deep
442
438
  */
443
- const addToShadowGenerator = function( generator: ShadowGenerator, node: TransformNode, deep: boolean = true ) {
444
- if( node instanceof AbstractMesh ) {
445
- // We have to remove the node because there's no duplicate check in babylon
446
- generator.removeShadowCaster( node, false );
447
- generator.addShadowCaster( node, false );
448
- }
449
- if( deep ) {
450
- node.getChildTransformNodes( true ).forEach(
451
- child => addToShadowGenerator( generator, child, deep )
452
- );
453
- }
439
+ const addToShadowGenerator = function (generator: ShadowGenerator, node: TransformNode, deep: boolean = true) {
440
+ if (node instanceof AbstractMesh) {
441
+ // We have to remove the node because there's no duplicate check in babylon
442
+ generator.removeShadowCaster(node, false);
443
+ generator.addShadowCaster(node, false);
444
+ }
445
+ if (deep) {
446
+ node.getChildTransformNodes(true).forEach(child => addToShadowGenerator(generator, child, deep));
447
+ }
454
448
  };
455
449
 
456
450
  /**
@@ -458,15 +452,13 @@ const addToShadowGenerator = function( generator: ShadowGenerator, node: Transfo
458
452
  * @param generator
459
453
  * @param deep
460
454
  */
461
- const removeFromShadowGenerator = function( generator: ShadowGenerator, node: TransformNode, deep: boolean = true ) {
462
- if( node instanceof AbstractMesh ) {
463
- generator.removeShadowCaster( node, false );
464
- }
465
- if( deep ) {
466
- node.getChildTransformNodes( true ).forEach(
467
- child => removeFromShadowGenerator( generator, child, deep )
468
- );
469
- }
455
+ const removeFromShadowGenerator = function (generator: ShadowGenerator, node: TransformNode, deep: boolean = true) {
456
+ if (node instanceof AbstractMesh) {
457
+ generator.removeShadowCaster(node, false);
458
+ }
459
+ if (deep) {
460
+ node.getChildTransformNodes(true).forEach(child => removeFromShadowGenerator(generator, child, deep));
461
+ }
470
462
  };
471
463
 
472
464
  /**
@@ -475,60 +467,72 @@ const removeFromShadowGenerator = function( generator: ShadowGenerator, node: Tr
475
467
  * @param scene
476
468
  * @param canvas
477
469
  */
478
- const getClientRectFromMesh = function( mesh: AbstractMesh, scene: Scene, canvas: HTMLCanvasElement ): ClientRect {
479
- // get bounding box of the mesh
480
- const meshVectors = mesh.getBoundingInfo().boundingBox.vectors;
481
- // get the matrix and viewport needed to project the vectors onto the screen
482
- const worldMatrix = mesh.getWorldMatrix();
483
- const transformMatrix = scene.getTransformMatrix();
484
- const viewport = scene.activeCamera!.viewport;
485
- // loop though all the vectors and project them against the current camera viewport to get a set of coordinates
486
- const coordinates = meshVectors.map( vector => {
487
- const projection = Vector3.Project( vector, worldMatrix, transformMatrix, viewport );
488
- projection.x = projection.x * canvas.clientWidth;
489
- projection.y = projection.y * canvas.clientHeight;
490
- return projection;
491
- } );
492
- // get the min and max for all the coordinates so we can calculate the largest possible screen size
493
- const maxX = Math.max.apply( Math, coordinates.map( o => o.x ) );
494
- const minX = Math.min.apply( Math, coordinates.map( o => o.x ) );
495
- const maxY = Math.max.apply( Math, coordinates.map( o => o.y ) );
496
- const minY = Math.min.apply( Math, coordinates.map( o => o.y ) );
497
- // return a ClientRect from this
498
- return {
499
- width: maxX - minX,
500
- height: maxY - minY,
501
- left: minX,
502
- top: minY,
503
- right: maxX,
504
- bottom: maxY,
505
- } as ClientRect;
470
+ const getClientRectFromMesh = function (mesh: AbstractMesh, scene: Scene, canvas: HTMLCanvasElement): ClientRect {
471
+ // get bounding box of the mesh
472
+ const meshVectors = mesh.getBoundingInfo().boundingBox.vectors;
473
+ // get the matrix and viewport needed to project the vectors onto the screen
474
+ const worldMatrix = mesh.getWorldMatrix();
475
+ const transformMatrix = scene.getTransformMatrix();
476
+ const viewport = scene.activeCamera!.viewport;
477
+ // loop though all the vectors and project them against the current camera viewport to get a set of coordinates
478
+ const coordinates = meshVectors.map(vector => {
479
+ const projection = Vector3.Project(vector, worldMatrix, transformMatrix, viewport);
480
+ projection.x = projection.x * canvas.clientWidth;
481
+ projection.y = projection.y * canvas.clientHeight;
482
+ return projection;
483
+ });
484
+ // get the min and max for all the coordinates so we can calculate the largest possible screen size
485
+ const maxX = Math.max.apply(
486
+ Math,
487
+ coordinates.map(o => o.x)
488
+ );
489
+ const minX = Math.min.apply(
490
+ Math,
491
+ coordinates.map(o => o.x)
492
+ );
493
+ const maxY = Math.max.apply(
494
+ Math,
495
+ coordinates.map(o => o.y)
496
+ );
497
+ const minY = Math.min.apply(
498
+ Math,
499
+ coordinates.map(o => o.y)
500
+ );
501
+ // return a ClientRect from this
502
+ return {
503
+ width: maxX - minX,
504
+ height: maxY - minY,
505
+ left: minX,
506
+ top: minY,
507
+ right: maxX,
508
+ bottom: maxY,
509
+ } as ClientRect;
506
510
  };
507
511
 
508
512
  export {
509
- getRootNode,
510
- mapToDottedNodes,
511
- getDottedPathForNode,
512
- cloneTransformNode,
513
- cloneNodeWithParents,
514
- cloneTransformNodeMaterial,
515
- injectNodeMetadata,
516
- assertTransformNode,
517
- activateTransformNode,
518
- deactivateTransformNode,
519
- enableNodeWithParents,
520
- disableNodeWithParents,
521
- transformTransformNode,
522
- setMaterial,
523
- setSourceNodeMaterial,
524
- setMaterialColor,
525
- setMaterialTexture,
526
- setMaterialMetallness,
527
- setMaterialRoughness,
528
- addToHighlightLayer,
529
- removeFromHighlightLayer,
530
- setReceiveShadows,
531
- addToShadowGenerator,
532
- removeFromShadowGenerator,
533
- getClientRectFromMesh
513
+ getRootNode,
514
+ mapToDottedNodes,
515
+ getDottedPathForNode,
516
+ cloneTransformNode,
517
+ cloneNodeWithParents,
518
+ cloneTransformNodeMaterial,
519
+ injectNodeMetadata,
520
+ assertTransformNode,
521
+ activateTransformNode,
522
+ deactivateTransformNode,
523
+ enableNodeWithParents,
524
+ disableNodeWithParents,
525
+ transformTransformNode,
526
+ setMaterial,
527
+ setSourceNodeMaterial,
528
+ setMaterialColor,
529
+ setMaterialTexture,
530
+ setMaterialMetallness,
531
+ setMaterialRoughness,
532
+ addToHighlightLayer,
533
+ removeFromHighlightLayer,
534
+ setReceiveShadows,
535
+ addToShadowGenerator,
536
+ removeFromShadowGenerator,
537
+ getClientRectFromMesh,
534
538
  };