@combeenation/3d-viewer 3.0.0-rc2 → 4.0.0-alpha6

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 (212) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +111 -111
  3. package/dist/lib-cjs/api/classes/animationInterface.d.ts +8 -8
  4. package/dist/lib-cjs/api/classes/animationInterface.js +1 -1
  5. package/dist/lib-cjs/api/classes/animationInterface.js.map +0 -0
  6. package/dist/lib-cjs/api/classes/dottedPath.d.ts +79 -79
  7. package/dist/lib-cjs/api/classes/dottedPath.js +190 -190
  8. package/dist/lib-cjs/api/classes/dottedPath.js.map +0 -0
  9. package/dist/lib-cjs/api/classes/element.d.ts +130 -125
  10. package/dist/lib-cjs/api/classes/element.js +752 -638
  11. package/dist/lib-cjs/api/classes/element.js.map +1 -1
  12. package/dist/lib-cjs/api/classes/elementParameterizable.d.ts +14 -14
  13. package/dist/lib-cjs/api/classes/elementParameterizable.js +134 -134
  14. package/dist/lib-cjs/api/classes/elementParameterizable.js.map +0 -0
  15. package/dist/lib-cjs/api/classes/event.d.ts +326 -312
  16. package/dist/lib-cjs/api/classes/event.js +371 -357
  17. package/dist/lib-cjs/api/classes/event.js.map +1 -1
  18. package/dist/lib-cjs/api/classes/eventBroadcaster.d.ts +26 -26
  19. package/dist/lib-cjs/api/classes/eventBroadcaster.js +53 -53
  20. package/dist/lib-cjs/api/classes/eventBroadcaster.js.map +0 -0
  21. package/dist/lib-cjs/api/classes/parameter.d.ts +259 -161
  22. package/dist/lib-cjs/api/classes/parameter.js +387 -261
  23. package/dist/lib-cjs/api/classes/parameter.js.map +1 -1
  24. package/dist/lib-cjs/api/classes/parameterObservable.d.ts +36 -36
  25. package/dist/lib-cjs/api/classes/parameterObservable.js +101 -126
  26. package/dist/lib-cjs/api/classes/parameterObservable.js.map +1 -1
  27. package/dist/lib-cjs/api/classes/parameterizable.d.ts +15 -0
  28. package/dist/lib-cjs/api/classes/parameterizable.js +150 -0
  29. package/dist/lib-cjs/api/classes/parameterizable.js.map +1 -0
  30. package/dist/lib-cjs/api/classes/placementAnimation.d.ts +38 -38
  31. package/dist/lib-cjs/api/classes/placementAnimation.js +138 -138
  32. package/dist/lib-cjs/api/classes/placementAnimation.js.map +0 -0
  33. package/dist/lib-cjs/api/classes/variant.d.ts +224 -176
  34. package/dist/lib-cjs/api/classes/variant.js +1126 -770
  35. package/dist/lib-cjs/api/classes/variant.js.map +1 -1
  36. package/dist/lib-cjs/api/classes/variantInstance.d.ts +45 -41
  37. package/dist/lib-cjs/api/classes/variantInstance.js +108 -98
  38. package/dist/lib-cjs/api/classes/variantInstance.js.map +1 -1
  39. package/dist/lib-cjs/api/classes/variantParameterizable.d.ts +17 -0
  40. package/dist/lib-cjs/api/classes/variantParameterizable.js +93 -0
  41. package/dist/lib-cjs/api/classes/variantParameterizable.js.map +1 -0
  42. package/dist/lib-cjs/api/classes/viewer.d.ts +127 -128
  43. package/dist/lib-cjs/api/classes/viewer.js +486 -486
  44. package/dist/lib-cjs/api/classes/viewer.js.map +1 -1
  45. package/dist/lib-cjs/api/classes/viewerLight.d.ts +66 -0
  46. package/dist/lib-cjs/api/classes/viewerLight.js +350 -0
  47. package/dist/lib-cjs/api/classes/viewerLight.js.map +1 -0
  48. package/dist/lib-cjs/api/emitter.d.ts +35 -0
  49. package/dist/lib-cjs/api/emitter.js +61 -0
  50. package/dist/lib-cjs/api/emitter.js.map +1 -0
  51. package/dist/lib-cjs/api/internal/debugViewer.d.ts +13 -13
  52. package/dist/lib-cjs/api/internal/debugViewer.js +87 -87
  53. package/dist/lib-cjs/api/internal/debugViewer.js.map +0 -0
  54. package/dist/lib-cjs/api/internal/lensRendering.d.ts +8 -8
  55. package/dist/lib-cjs/api/internal/lensRendering.js +11 -11
  56. package/dist/lib-cjs/api/internal/lensRendering.js.map +0 -0
  57. package/dist/lib-cjs/api/internal/sceneSetup.d.ts +10 -6
  58. package/dist/lib-cjs/api/internal/sceneSetup.js +231 -227
  59. package/dist/lib-cjs/api/internal/sceneSetup.js.map +1 -1
  60. package/dist/lib-cjs/api/manager/animationManager.d.ts +29 -29
  61. package/dist/lib-cjs/api/manager/animationManager.js +121 -121
  62. package/dist/lib-cjs/api/manager/animationManager.js.map +0 -0
  63. package/dist/lib-cjs/api/manager/sceneManager.d.ts +32 -32
  64. package/dist/lib-cjs/api/manager/sceneManager.js +132 -132
  65. package/dist/lib-cjs/api/manager/sceneManager.js.map +0 -0
  66. package/dist/lib-cjs/api/manager/variantInstanceManager.d.ts +90 -90
  67. package/dist/lib-cjs/api/manager/variantInstanceManager.js +321 -321
  68. package/dist/lib-cjs/api/manager/variantInstanceManager.js.map +0 -0
  69. package/dist/lib-cjs/api/store/specStorage.d.ts +24 -24
  70. package/dist/lib-cjs/api/store/specStorage.js +51 -51
  71. package/dist/lib-cjs/api/store/specStorage.js.map +0 -0
  72. package/dist/lib-cjs/api/util/babylonHelper.d.ts +160 -125
  73. package/dist/lib-cjs/api/util/babylonHelper.js +465 -368
  74. package/dist/lib-cjs/api/util/babylonHelper.js.map +1 -1
  75. package/dist/lib-cjs/api/util/globalTypes.d.ts +321 -275
  76. package/dist/lib-cjs/api/util/globalTypes.js +1 -1
  77. package/dist/lib-cjs/api/util/globalTypes.js.map +0 -0
  78. package/dist/lib-cjs/api/util/resourceHelper.d.ts +26 -30
  79. package/dist/lib-cjs/api/util/resourceHelper.js +237 -247
  80. package/dist/lib-cjs/api/util/resourceHelper.js.map +1 -1
  81. package/dist/lib-cjs/api/util/stringHelper.d.ts +9 -0
  82. package/dist/lib-cjs/api/util/stringHelper.js +26 -0
  83. package/dist/lib-cjs/api/util/stringHelper.js.map +1 -0
  84. package/dist/lib-cjs/buildinfo.json +3 -3
  85. package/dist/lib-cjs/index.d.ts +48 -46
  86. package/dist/lib-cjs/index.js +86 -82
  87. package/dist/lib-cjs/index.js.map +1 -1
  88. package/package.json +83 -83
  89. package/src/api/classes/animationInterface.ts +11 -11
  90. package/src/api/classes/dottedPath.ts +189 -189
  91. package/src/api/classes/element.ts +648 -606
  92. package/src/api/classes/event.ts +370 -355
  93. package/src/api/classes/eventBroadcaster.ts +54 -54
  94. package/src/api/classes/parameter.ts +408 -270
  95. package/src/api/classes/parameterObservable.ts +99 -121
  96. package/src/api/classes/{elementParameterizable.ts → parameterizable.ts} +89 -78
  97. package/src/api/classes/placementAnimation.ts +133 -133
  98. package/src/api/classes/variant.ts +799 -652
  99. package/src/api/classes/variantInstance.ts +88 -81
  100. package/src/api/classes/variantParameterizable.ts +73 -0
  101. package/src/api/classes/viewer.ts +420 -421
  102. package/src/api/classes/viewerLight.ts +295 -0
  103. package/src/api/internal/debugViewer.ts +81 -81
  104. package/src/api/internal/lensRendering.ts +10 -10
  105. package/src/api/internal/sceneSetup.ts +194 -204
  106. package/src/api/manager/animationManager.ts +116 -116
  107. package/src/api/manager/sceneManager.ts +105 -105
  108. package/src/api/manager/variantInstanceManager.ts +236 -236
  109. package/src/api/store/specStorage.ts +53 -53
  110. package/src/api/util/babylonHelper.ts +497 -392
  111. package/src/api/util/globalTypes.ts +369 -314
  112. package/src/api/util/resourceHelper.ts +157 -168
  113. package/src/api/util/stringHelper.ts +26 -0
  114. package/src/buildinfo.json +2 -2
  115. package/src/commonjs.tsconfig.json +13 -13
  116. package/src/declaration.tsconfig.json +10 -10
  117. package/src/dev.ts +45 -60
  118. package/src/es6.tsconfig.json +13 -13
  119. package/src/index.ts +91 -87
  120. package/src/pagesconfig.json +51 -47
  121. package/src/tsconfig.json +43 -43
  122. package/src/tsconfig.types.json +9 -9
  123. package/src/types.d.ts +4 -4
  124. package/src/assets/02_environment.env +0 -0
  125. package/src/assets/02_test_hdri_flipped.hdr +0 -0
  126. package/src/assets/07rDvxP2xTk.glb +0 -0
  127. package/src/assets/08L8DrdZt8y.glb +0 -0
  128. package/src/assets/CB-6250/main.js +0 -427
  129. package/src/assets/CB-6250/models/.gitkeep +0 -1
  130. package/src/assets/CB-6250/models/candle.glb +0 -0
  131. package/src/assets/CB-6250/models/lamp.glb +0 -0
  132. package/src/assets/CB-6250/models/molto-bido.glb +0 -0
  133. package/src/assets/CB-6250/models/mtron.glb +0 -0
  134. package/src/assets/CB-6250/models/mtron_split_geometry.glb +0 -0
  135. package/src/assets/CB-6250/models/mtron_split_material.glb +0 -0
  136. package/src/assets/KTM1290SA/AvatarAdv.glb +0 -0
  137. package/src/assets/KTM1290SA/ktm1290SA.ts +0 -77
  138. package/src/assets/KTM1290SA/scene.json +0 -16
  139. package/src/assets/_draft/main.js +0 -117
  140. package/src/assets/_draft/models/.gitkeep +0 -1
  141. package/src/assets/_draft/models/_demo.glb +0 -0
  142. package/src/assets/_draft/studio.env +0 -0
  143. package/src/assets/bike/CompleteBike_Optim_986K_01.glb +0 -0
  144. package/src/assets/bike/complete.json +0 -19
  145. package/src/assets/bike/index.json +0 -9
  146. package/src/assets/bike/setup.json +0 -11
  147. package/src/assets/ctrls-helper.ts +0 -89
  148. package/src/assets/cube/10 environment.env +0 -0
  149. package/src/assets/cube/bin_svg_logo_test.glb +0 -0
  150. package/src/assets/cube/cube.ts +0 -42
  151. package/src/assets/cube/cube_v2.glb +0 -0
  152. package/src/assets/cube/scene.ts +0 -83
  153. package/src/assets/cube/testCylinderUVs.glb +0 -0
  154. package/src/assets/environment.env +0 -0
  155. package/src/assets/hoferkerzen/hoferkerzen.glb +0 -0
  156. package/src/assets/hoferkerzen/index.json +0 -9
  157. package/src/assets/hoferkerzen/setup.json +0 -11
  158. package/src/assets/hoferkerzen/variant_kgl.json +0 -41
  159. package/src/assets/husqvarna-instanced-meshes/husqvarna.env +0 -0
  160. package/src/assets/husqvarna-instanced-meshes/husqvarna.glb +0 -0
  161. package/src/assets/husqvarna-instanced-meshes/main.ts +0 -108
  162. package/src/assets/index.html +0 -144
  163. package/src/assets/index.json +0 -9
  164. package/src/assets/linkeddups/example_2_instances.glb +0 -0
  165. package/src/assets/linkeddups/spec.ts +0 -32
  166. package/src/assets/molto-mova-multi-instance-shown-bug/main.ts +0 -106
  167. package/src/assets/molto-mova-multi-instance-shown-bug/molto-mova-rc82.glb +0 -0
  168. package/src/assets/molto-mova-multi-instance-shown-bug/molto-mova-volare.glb +0 -0
  169. package/src/assets/molto-mova-multi-instance-shown-bug/studio.env +0 -0
  170. package/src/assets/moltomova/10 environment.env +0 -0
  171. package/src/assets/moltomova/RC65.glb +0 -0
  172. package/src/assets/moltomova/RC82.glb +0 -0
  173. package/src/assets/moltomova/TPH67.glb +0 -0
  174. package/src/assets/moltomova/TPH82.glb +0 -0
  175. package/src/assets/moltomova/Volare.glb +0 -0
  176. package/src/assets/moltomova/moltomova-cl3d-spec-rc65.ts +0 -159
  177. package/src/assets/moltomova/moltomova-cl3d-spec-rc82.ts +0 -118
  178. package/src/assets/moltomova/moltomova-cl3d-spec-scene.ts +0 -57
  179. package/src/assets/moltomova/moltomova-cl3d-spec-tph67.ts +0 -199
  180. package/src/assets/moltomova/moltomova-cl3d-spec-tph82.ts +0 -173
  181. package/src/assets/moltomova/moltomova-cl3d-spec-volare65.ts +0 -173
  182. package/src/assets/moltomova/moltomova.ts +0 -175
  183. package/src/assets/mova.json +0 -18
  184. package/src/assets/mova_3_phase_rail.glb +0 -0
  185. package/src/assets/mova_3_phase_rail.json +0 -86
  186. package/src/assets/mova_recessed_luminaire.glb +0 -0
  187. package/src/assets/mova_recessed_luminaire.json +0 -81
  188. package/src/assets/nessie/gltf-test-no-material.gltf +0 -142
  189. package/src/assets/nessie/gltf-test-no-material_data.bin +0 -0
  190. package/src/assets/nessie/gltf-test-rotation.gltf +0 -142
  191. package/src/assets/nessie/gltf-test-rotation_data.bin +0 -0
  192. package/src/assets/nessie/gltf-test.gltf +0 -178
  193. package/src/assets/nessie/gltf-test_data.bin +0 -0
  194. package/src/assets/nessie/index.json +0 -9
  195. package/src/assets/nessie/nessie_basic.json +0 -24
  196. package/src/assets/nessie/setup.json +0 -12
  197. package/src/assets/scene.json +0 -64
  198. package/src/assets/setup.json +0 -25
  199. package/src/assets/small_cave_1k.hdr +0 -0
  200. package/src/assets/svgTo3D/09aJssVZrjk.env +0 -0
  201. package/src/assets/svgTo3D/09f0zfBQBWK.glb +0 -0
  202. package/src/assets/svgTo3D/9bae062709f8a7803769ba955cde3c4a.jpg +0 -0
  203. package/src/assets/svgTo3D/logo-cyledge.svg +0 -19
  204. package/src/assets/svgTo3D/spec.ts +0 -56
  205. package/src/assets/svgTo3D/svg_assets/09fmVjc59hQ.png +0 -0
  206. package/src/assets/svgTo3D/svg_assets/LDI2apCSOBg7S-QT7pb0EPOreec.woff2 +0 -0
  207. package/src/assets/svgTo3D/svg_assets/unineue_regular.woff2 +0 -0
  208. package/src/assets/svgTo3D/testCube.glb +0 -0
  209. package/src/assets/svgTo3D/testCube001.glb +0 -0
  210. package/src/assets/svgTo3D/testCubeSpec.ts +0 -49
  211. package/src/assets/textures/grass.png +0 -0
  212. package/src/assets/textures/seamless-grunge-scratched-texture.jpg +0 -0
@@ -1,392 +1,497 @@
1
- import { HighlightLayer } from '@babylonjs/core/Layers/highlightLayer';
2
- import { Material } from '@babylonjs/core/Materials/material';
3
- import { PBRMaterial } from '@babylonjs/core/Materials/PBR/pbrMaterial';
4
- import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
5
- import { Color3 } from '@babylonjs/core/Maths/math.color';
6
- import { Vector3 } from '@babylonjs/core/Maths/math.vector';
7
- import { AbstractMesh } from '@babylonjs/core/Meshes/abstractMesh';
8
- import { InstancedMesh } from '@babylonjs/core/Meshes/instancedMesh';
9
- import { Mesh } from '@babylonjs/core/Meshes/mesh';
10
- import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
11
- import { Node } from '@babylonjs/core/node';
12
- import { Scene } from '@babylonjs/core/scene';
13
- import { cloneDeep, merge } from 'lodash-es';
14
- import { DottedPath } from '../classes/dottedPath';
15
-
16
- /**
17
- * @param nodes
18
- * @param predicate
19
- * @return Map<DottedPath, T>
20
- */
21
- const mapToDottedNodes = function <T>( nodes: Node[],
22
- predicate?: ( node: Node ) => boolean ): Map<DottedPath, T> {
23
- const map = new Map<DottedPath, T>();
24
- const addNodes = function( _node: Node ) {
25
- if( predicate && predicate( _node ) ) {
26
- map.set( _node.metadata.dottedPath, _node as any );
27
- }
28
- _node.getChildren().forEach( child => {
29
- addNodes( child );
30
- } );
31
- };
32
- nodes.forEach( node => {
33
- addNodes( node );
34
- } );
35
- return map;
36
- };
37
-
38
- /**
39
- * @param node
40
- * @return DottedPath
41
- */
42
- const getDottedPathForTransformNode = function( node: TransformNode ): DottedPath {
43
- const dottedPath = DottedPath.create( node.name );
44
- let _parent = node;
45
- while( _parent.parent ) {
46
- _parent = _parent.parent as TransformNode;
47
- dottedPath.unshiftPart( _parent.name );
48
- }
49
- return dottedPath;
50
- };
51
-
52
- /**
53
- *
54
- * @param node
55
- * @param predicate
56
- * @param deep
57
- * @return TransformNode | null
58
- */
59
- const cloneTransformNode = function( node: TransformNode,
60
- predicate?: ( node: TransformNode ) => boolean,
61
- deep: boolean = true ): TransformNode | null {
62
- if( predicate && !predicate( node ) ) {
63
- return null;
64
- }
65
- const clone = node.clone( node.name, node.parent, true );
66
- if( clone ) {
67
- clone.metadata = cloneDeep( node.metadata );
68
- }
69
- if( deep ) {
70
- const children = node.getChildTransformNodes( true );
71
- children.forEach( child => {
72
- const clonedChild = cloneTransformNode( child, predicate, deep );
73
- if( clonedChild ) {
74
- clonedChild.parent = clone;
75
- }
76
- } );
77
- }
78
- return clone;
79
- };
80
-
81
- /**
82
- * @param node
83
- * @param deep
84
- * @param prefix
85
- * @return TransformNode
86
- */
87
- const cloneTransformNodeMaterial = function( node: TransformNode,
88
- prefix: DottedPathArgument = '',
89
- deep: boolean = true ): TransformNode {
90
- if( node instanceof AbstractMesh && node.material ) {
91
- const _prefix = DottedPath.create( prefix ).addParts([
92
- 'node',
93
- node.uniqueId.toString()
94
- ]);
95
- node.material = node.material.clone( _prefix.path );
96
- }
97
- if( deep ) {
98
- const children = node.getChildTransformNodes( true );
99
- children.forEach( child => cloneTransformNodeMaterial( child, prefix, deep ) );
100
- }
101
- return node;
102
- };
103
-
104
- /**
105
- * @param node
106
- * @param deep
107
- * @param metadata
108
- */
109
- const injectTransformNodeMetadata = function( node: TransformNode, metadata: {}, deep: boolean = true ) {
110
- node.metadata = merge( {}, node.metadata, metadata );
111
- if( deep ) {
112
- const children = node.getChildTransformNodes( true );
113
- children.forEach( child => injectTransformNodeMetadata( child, metadata, deep ) );
114
- }
115
- };
116
-
117
- /**
118
- * @param node
119
- * @param assertCallable
120
- * @param callableParameters
121
- * @param deep
122
- */
123
- const assertTransformNode = function( node: TransformNode,
124
- assertCallable: CallableFunction,
125
- callableParameters: any[] = [],
126
- deep: boolean = true ) {
127
- assertCallable(node, ...callableParameters);
128
- if( deep ) {
129
- const children = node.getChildTransformNodes( true );
130
- children.forEach( child => assertTransformNode( child, assertCallable, callableParameters, deep ) );
131
- }
132
- };
133
-
134
- /**
135
- * @param node
136
- * @param deep
137
- */
138
- const activateTransformNode = function( node: TransformNode, deep: boolean = true ) {
139
- node.setEnabled( true );
140
- /*
141
- if( node instanceof AbstractMesh ) {
142
- node.visibility = 1;
143
- node.isPickable = true;
144
- }
145
- */
146
- if( deep ) {
147
- node.getChildTransformNodes( true ).forEach( child => activateTransformNode( child, deep ) );
148
- }
149
- };
150
-
151
- /**
152
- * @param node
153
- * @param deep
154
- */
155
- const deactivateTransformNode = function( node: TransformNode, deep: boolean = true ) {
156
- node.setEnabled( false );
157
- /*
158
- if( node instanceof AbstractMesh ) {
159
- node.visibility = 0;
160
- node.isPickable = false;
161
- }
162
- */
163
- if( deep ) {
164
- node.getChildTransformNodes( true ).forEach( child => deactivateTransformNode( child, deep ) );
165
- }
166
- };
167
-
168
- /**
169
- * @param node
170
- * @param material
171
- * @param deep
172
- */
173
- const setMaterial = function( node: TransformNode, material: Material, deep: boolean = true ) {
174
- if( node instanceof AbstractMesh ) {
175
- node.material = material;
176
- }
177
- if( deep ) {
178
- node.getChildTransformNodes( true ).forEach( child => setMaterial( child, material, deep ) );
179
- }
180
- };
181
-
182
- /**
183
- * !!! Warning !!!
184
- * This function is not public API. Whilst it can help solving certain problems, it only works reliably in well defined
185
- * situations and can cause unwanted side effects under some conditions. Use carefully at your own risk!
186
- *
187
- * See https://combeenation.myjetbrains.com/youtrack/issue/CB-5906 for further details regarding this warning.
188
- *
189
- * Set material of an instanced meshes source mesh.
190
- * Changes the material of all instanced meshes which have the same source mesh.
191
- *
192
- * @param node
193
- * @param material
194
- * @param deep
195
- *
196
- * @ignore
197
- */
198
- const setSourceNodeMaterial = function( node: TransformNode, material: Material, deep: boolean = true ) {
199
- const warn = ` You're using "setSourceNodeMaterial" which is not public API.
200
- Whilst it can help solving certain problems, it only works reliably in well defined situations and can cause unwanted side effects under some conditions.
201
- Use carefully at your own risk!`;
202
- console.warn(`!!! Warning !!!\n${warn}`);
203
-
204
- if( node instanceof InstancedMesh ) {
205
- node.sourceMesh.material = material;
206
- }
207
- if( deep ) {
208
- node.getChildTransformNodes( true ).forEach( child => setSourceNodeMaterial( child, material, deep ) );
209
- }
210
- };
211
-
212
- /**
213
- * @param node
214
- * @param color
215
- * @param deep
216
- */
217
- const setMaterialColor = function( node: TransformNode, color: Color3, deep: boolean = true ) {
218
- if( node instanceof AbstractMesh && node.material ) {
219
- const materialCls = node.material.getClassName();
220
- switch( materialCls ) {
221
- case 'PBRMaterial':
222
- (node.material as PBRMaterial).albedoColor = color.toLinearSpace();
223
- break;
224
- case 'StandardMaterial':
225
- (node.material as StandardMaterial).diffuseColor = color;
226
- break;
227
- default:
228
- throw new Error( `Setting color for material of instance "${materialCls}" not implemented (yet).` );
229
- }
230
- }
231
- if( deep ) {
232
- node.getChildTransformNodes( true ).forEach( child => setMaterialColor( child, color, deep ) );
233
- }
234
- };
235
-
236
- /**
237
- * @param node
238
- * @param texture
239
- * @param deep
240
- */
241
- const setMaterialTexture = function( node: TransformNode, texture: Texture, deep: boolean = true ) {
242
- if( node instanceof AbstractMesh && node.material ) {
243
- const materialCls = node.material.getClassName();
244
- switch( materialCls ) {
245
- case 'PBRMaterial':
246
- (node.material as PBRMaterial).albedoTexture = texture;
247
- break;
248
- case 'StandardMaterial':
249
- (node.material as StandardMaterial).diffuseTexture = texture;
250
- break;
251
- default:
252
- throw new Error( `Setting texture for material of instance "${materialCls}" not implemented (yet).` );
253
- }
254
- }
255
- if( deep ) {
256
- node.getChildTransformNodes( true ).forEach( child => setMaterialTexture( child, texture, deep ) );
257
- }
258
- };
259
-
260
- /**
261
- * @param node
262
- * @param metallness
263
- * @param deep
264
- */
265
- const setMaterialMetallness = function( node: TransformNode, metallness: number, deep: boolean = true ) {
266
- if( node instanceof AbstractMesh && node.material ) {
267
- const materialCls = node.material.getClassName();
268
- switch( materialCls ) {
269
- case 'PBRMaterial':
270
- (node.material as PBRMaterial).metallic = metallness;
271
- break;
272
- default:
273
- throw new Error( `Setting metallness for material of instance "${materialCls}" not implemented (yet).` );
274
- }
275
- }
276
- if( deep ) {
277
- node.getChildTransformNodes( true ).forEach( child => setMaterialMetallness( child, metallness, deep ) );
278
- }
279
- };
280
-
281
- /**
282
- * @param node
283
- * @param roughness
284
- * @param deep
285
- */
286
- const setMaterialRoughness = function( node: TransformNode, roughness: number, deep: boolean = true ) {
287
- if( node instanceof AbstractMesh && node.material ) {
288
- const materialCls = node.material.getClassName();
289
- switch( materialCls ) {
290
- case 'PBRMaterial':
291
- (node.material as PBRMaterial).roughness = roughness;
292
- break;
293
- case 'StandardMaterial':
294
- (node.material as StandardMaterial).roughness = roughness;
295
- break;
296
- default:
297
- throw new Error( `Setting roughness for material of instance "${materialCls}" not implemented (yet).` );
298
- }
299
- }
300
- if( deep ) {
301
- node.getChildTransformNodes( true ).forEach( child => setMaterialRoughness( child, roughness, deep ) );
302
- }
303
- };
304
-
305
- /**
306
- * @param node
307
- * @param layer
308
- * @param color
309
- * @param deep
310
- */
311
- const addToHighlightLayer = function( layer: HighlightLayer, color: Color3, node: TransformNode, deep: boolean = true ) {
312
- if( node instanceof AbstractMesh ) {
313
- layer.addMesh( (node as Mesh), color );
314
- }
315
- if( deep ) {
316
- node.getChildTransformNodes( true ).forEach(
317
- child => addToHighlightLayer( layer, color, child, deep )
318
- );
319
- }
320
- };
321
-
322
- /**
323
- * @param node
324
- * @param layer
325
- * @param deep
326
- */
327
- const removeFromHighlightLayer = function( layer: HighlightLayer, node: TransformNode, deep: boolean = true ) {
328
- if( node instanceof AbstractMesh ) {
329
- layer.removeMesh( (node as Mesh) );
330
- }
331
- if( deep ) {
332
- node.getChildTransformNodes( true ).forEach(
333
- child => removeFromHighlightLayer( layer, child, deep )
334
- );
335
- }
336
- };
337
-
338
- /**
339
- * https://forum.babylonjs.com/t/get-mesh-bounding-box-position-and-size-in-2d-screen-coordinates/1058/3
340
- * @param mesh
341
- * @param scene
342
- * @param canvas
343
- */
344
- const getClientRectFromMesh = function( mesh: AbstractMesh, scene: Scene, canvas: HTMLCanvasElement ): ClientRect {
345
- // get bounding box of the mesh
346
- const meshVectors = mesh.getBoundingInfo().boundingBox.vectors;
347
- // get the matrix and viewport needed to project the vectors onto the screen
348
- const worldMatrix = mesh.getWorldMatrix();
349
- const transformMatrix = scene.getTransformMatrix();
350
- const viewport = scene.activeCamera!.viewport;
351
- // loop though all the vectors and project them against the current camera viewport to get a set of coordinates
352
- const coordinates = meshVectors.map( vector => {
353
- const projection = Vector3.Project( vector, worldMatrix, transformMatrix, viewport );
354
- projection.x = projection.x * canvas.clientWidth;
355
- projection.y = projection.y * canvas.clientHeight;
356
- return projection;
357
- } );
358
- // get the min and max for all the coordinates so we can calculate the largest possible screen size
359
- const maxX = Math.max.apply( Math, coordinates.map( o => o.x ) );
360
- const minX = Math.min.apply( Math, coordinates.map( o => o.x ) );
361
- const maxY = Math.max.apply( Math, coordinates.map( o => o.y ) );
362
- const minY = Math.min.apply( Math, coordinates.map( o => o.y ) );
363
- // return a ClientRect from this
364
- return {
365
- width: maxX - minX,
366
- height: maxY - minY,
367
- left: minX,
368
- top: minY,
369
- right: maxX,
370
- bottom: maxY,
371
- } as ClientRect;
372
- };
373
-
374
- export {
375
- mapToDottedNodes,
376
- getDottedPathForTransformNode,
377
- cloneTransformNode,
378
- cloneTransformNodeMaterial,
379
- injectTransformNodeMetadata,
380
- assertTransformNode,
381
- activateTransformNode,
382
- deactivateTransformNode,
383
- setMaterial,
384
- setSourceNodeMaterial,
385
- setMaterialColor,
386
- setMaterialTexture,
387
- setMaterialMetallness,
388
- setMaterialRoughness,
389
- addToHighlightLayer,
390
- removeFromHighlightLayer,
391
- getClientRectFromMesh
392
- };
1
+ import { HighlightLayer } from '@babylonjs/core/Layers/highlightLayer';
2
+ import { Light } from '@babylonjs/core/Lights/light';
3
+ import { ShadowGenerator } from '@babylonjs/core/Lights/Shadows/shadowGenerator';
4
+ import { Material } from '@babylonjs/core/Materials/material';
5
+ import { PBRMaterial } from '@babylonjs/core/Materials/PBR/pbrMaterial';
6
+ import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
7
+ import { Color3 } from '@babylonjs/core/Maths/math.color';
8
+ import { Vector3 } from '@babylonjs/core/Maths/math.vector';
9
+ import { AbstractMesh } from '@babylonjs/core/Meshes/abstractMesh';
10
+ import { InstancedMesh } from '@babylonjs/core/Meshes/instancedMesh';
11
+ import { Mesh } from '@babylonjs/core/Meshes/mesh';
12
+ import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
13
+ import { Node } from '@babylonjs/core/node';
14
+ import { Scene } from '@babylonjs/core/scene';
15
+ import { cloneDeep, merge } from 'lodash-es';
16
+ import { DottedPath } from '../classes/dottedPath';
17
+
18
+ /**
19
+ * @param node
20
+ * @return Node
21
+ */
22
+ const getRootNode = function( node: Node ): Node {
23
+ let _node = node;
24
+ while( _node.parent ) {
25
+ _node = _node.parent;
26
+ }
27
+ return _node;
28
+ }
29
+
30
+ /**
31
+ * @param nodes
32
+ * @param predicate
33
+ * @return Map<DottedPath, T>
34
+ */
35
+ const mapToDottedNodes = function <T>( nodes: Node[],
36
+ predicate?: ( node: Node ) => boolean ): Map<DottedPath, T> {
37
+ const map = new Map<DottedPath, T>();
38
+ const addNodes = function( _node: Node ) {
39
+ if( predicate && predicate( _node ) ) {
40
+ map.set( _node.metadata.dottedPath, _node as any );
41
+ }
42
+ _node.getChildren().forEach( child => {
43
+ addNodes( child );
44
+ } );
45
+ };
46
+ nodes.forEach( node => {
47
+ addNodes( node );
48
+ } );
49
+ return map;
50
+ };
51
+
52
+ /**
53
+ * @param node
54
+ * @return DottedPath
55
+ */
56
+ const getDottedPathForNode = function( node: Node ): DottedPath {
57
+ const dottedPath = DottedPath.create( node.name );
58
+ let _parent = node;
59
+ while( _parent.parent ) {
60
+ _parent = _parent.parent;
61
+ dottedPath.unshiftPart( _parent.name );
62
+ }
63
+ return dottedPath;
64
+ };
65
+
66
+ /**
67
+ * @param node
68
+ * @param predicate
69
+ * @param deep
70
+ * @return TransformNode | null
71
+ */
72
+ const cloneTransformNode = function( node: TransformNode,
73
+ predicate?: ( node: TransformNode ) => boolean,
74
+ deep: boolean = true ): TransformNode | null {
75
+ if( predicate && !predicate( node ) ) {
76
+ return null;
77
+ }
78
+ const clone = node.clone( node.name, node.parent, true );
79
+ if( clone ) {
80
+ clone.metadata = cloneDeep( node.metadata );
81
+ }
82
+ if( deep ) {
83
+ const children = node.getChildTransformNodes( true );
84
+ children.forEach( child => {
85
+ const clonedChild = cloneTransformNode( child, predicate, deep );
86
+ if( clonedChild ) {
87
+ clonedChild.parent = clone;
88
+ }
89
+ } );
90
+ }
91
+ return clone;
92
+ };
93
+
94
+ /**
95
+ * @param node
96
+ */
97
+ const cloneNodeWithParents = function( node: Node | null ): Node | null {
98
+ let clone = null;
99
+ if( node instanceof TransformNode ) {
100
+ clone = node.clone( node.name, cloneNodeWithParents( node.parent ), true );
101
+ } else if( node instanceof Light ) {
102
+ clone = node.clone( node.name, cloneNodeWithParents( node.parent ) );
103
+ } else if( node ) {
104
+ throw new Error( `Cloning of "${node?.constructor.name}" is not implemented (yet).` );
105
+ }
106
+ return clone;
107
+ };
108
+
109
+ /**
110
+ * @param node
111
+ * @param deep
112
+ * @param prefix
113
+ * @return TransformNode
114
+ */
115
+ const cloneTransformNodeMaterial = function( node: TransformNode,
116
+ prefix: DottedPathArgument = '',
117
+ deep: boolean = true ): TransformNode {
118
+ if( node instanceof AbstractMesh && node.material ) {
119
+ const _prefix = DottedPath.create( prefix ).addParts([
120
+ 'node',
121
+ node.uniqueId.toString()
122
+ ]);
123
+ node.material = node.material.clone( _prefix.path );
124
+ }
125
+ if( deep ) {
126
+ const children = node.getChildTransformNodes( true );
127
+ children.forEach( child => cloneTransformNodeMaterial( child, prefix, deep ) );
128
+ }
129
+ return node;
130
+ };
131
+
132
+ /**
133
+ * @param node
134
+ * @param deep
135
+ * @param metadata
136
+ */
137
+ const injectNodeMetadata = function( node: Node, metadata: {}, deep: boolean = true ) {
138
+ node.metadata = merge( {}, node.metadata, metadata );
139
+ if( deep && node instanceof TransformNode ) {
140
+ const children = node.getChildTransformNodes( true );
141
+ children.forEach( child => injectNodeMetadata( child, metadata, deep ) );
142
+ }
143
+ };
144
+
145
+ /**
146
+ * @param node
147
+ * @param assertCallable
148
+ * @param callableParameters
149
+ * @param deep
150
+ */
151
+ const assertTransformNode = function( node: TransformNode,
152
+ assertCallable: CallableFunction,
153
+ callableParameters: any[] = [],
154
+ deep: boolean = true ) {
155
+ assertCallable(node, ...callableParameters);
156
+ if( deep ) {
157
+ const children = node.getChildTransformNodes( true );
158
+ children.forEach( child => assertTransformNode( child, assertCallable, callableParameters, deep ) );
159
+ }
160
+ };
161
+
162
+ /**
163
+ * @param node
164
+ * @param deep
165
+ */
166
+ const activateTransformNode = function( node: TransformNode, deep: boolean = true ) {
167
+ node.setEnabled( true );
168
+ /*
169
+ if( node instanceof AbstractMesh ) {
170
+ node.visibility = 1;
171
+ node.isPickable = true;
172
+ }
173
+ */
174
+ if( deep ) {
175
+ node.getChildTransformNodes( true ).forEach( child => activateTransformNode( child, deep ) );
176
+ }
177
+ };
178
+
179
+ /**
180
+ * @param node
181
+ * @param deep
182
+ */
183
+ const deactivateTransformNode = function( node: TransformNode, deep: boolean = true ) {
184
+ node.setEnabled( false );
185
+ /*
186
+ if( node instanceof AbstractMesh ) {
187
+ node.visibility = 0;
188
+ node.isPickable = false;
189
+ }
190
+ */
191
+ if( deep ) {
192
+ node.getChildTransformNodes( true ).forEach( child => deactivateTransformNode( child, deep ) );
193
+ }
194
+ };
195
+
196
+ /**
197
+ * @param node
198
+ */
199
+ const enableNodeWithParents = function( node: Node ) {
200
+ node.setEnabled( true );
201
+ if ( node.parent ) {
202
+ enableNodeWithParents( node.parent );
203
+ }
204
+ };
205
+
206
+ /**
207
+ * @param node
208
+ */
209
+ const disableNodeWithParents = function( node: Node ) {
210
+ node.setEnabled( false );
211
+ if ( node.parent ) {
212
+ disableNodeWithParents( node.parent );
213
+ }
214
+ };
215
+
216
+ /**
217
+ * @param node
218
+ * @param material
219
+ * @param deep
220
+ */
221
+ const setMaterial = function( node: TransformNode, material: Material, deep: boolean = true ) {
222
+ if( node instanceof AbstractMesh ) {
223
+ node.material = material;
224
+ }
225
+ if( deep ) {
226
+ node.getChildTransformNodes( true ).forEach( child => setMaterial( child, material, deep ) );
227
+ }
228
+ };
229
+
230
+ /**
231
+ * !!! Warning !!!
232
+ * This function is not public API. Whilst it can help solving certain problems, it only works reliably in well defined
233
+ * situations and can cause unwanted side effects under some conditions. Use carefully at your own risk!
234
+ *
235
+ * See https://combeenation.myjetbrains.com/youtrack/issue/CB-5906 for further details regarding this warning.
236
+ *
237
+ * Set material of an instanced meshes source mesh.
238
+ * Changes the material of all instanced meshes which have the same source mesh.
239
+ *
240
+ * @param node
241
+ * @param material
242
+ * @param deep
243
+ *
244
+ * @ignore
245
+ */
246
+ const setSourceNodeMaterial = function( node: TransformNode, material: Material, deep: boolean = true ) {
247
+ const warn = ` You're using "setSourceNodeMaterial" which is not public API.
248
+ Whilst it can help solving certain problems, it only works reliably in well defined situations and can cause unwanted side effects under some conditions.
249
+ Use carefully at your own risk!`;
250
+ console.warn(`!!! Warning !!!\n${warn}`);
251
+
252
+ if( node instanceof InstancedMesh ) {
253
+ node.sourceMesh.material = material;
254
+ }
255
+ if( deep ) {
256
+ node.getChildTransformNodes( true ).forEach( child => setSourceNodeMaterial( child, material, deep ) );
257
+ }
258
+ };
259
+
260
+ /**
261
+ * @param node
262
+ * @param color
263
+ * @param deep
264
+ */
265
+ const setMaterialColor = function( node: TransformNode, color: Color3, deep: boolean = true ) {
266
+ if( node instanceof AbstractMesh && node.material ) {
267
+ const materialCls = node.material.getClassName();
268
+ switch( materialCls ) {
269
+ case 'PBRMaterial':
270
+ (node.material as PBRMaterial).albedoColor = color.toLinearSpace();
271
+ break;
272
+ case 'StandardMaterial':
273
+ (node.material as StandardMaterial).diffuseColor = color;
274
+ break;
275
+ default:
276
+ throw new Error( `Setting color for material of instance "${materialCls}" not implemented (yet).` );
277
+ }
278
+ }
279
+ if( deep ) {
280
+ node.getChildTransformNodes( true ).forEach( child => setMaterialColor( child, color, deep ) );
281
+ }
282
+ };
283
+
284
+ /**
285
+ * @param node
286
+ * @param texture
287
+ * @param deep
288
+ */
289
+ const setMaterialTexture = function( node: TransformNode, texture: Texture, deep: boolean = true ) {
290
+ if( node instanceof AbstractMesh && node.material ) {
291
+ const materialCls = node.material.getClassName();
292
+ switch( materialCls ) {
293
+ case 'PBRMaterial':
294
+ (node.material as PBRMaterial).albedoTexture = texture;
295
+ break;
296
+ case 'StandardMaterial':
297
+ (node.material as StandardMaterial).diffuseTexture = texture;
298
+ break;
299
+ default:
300
+ throw new Error( `Setting texture for material of instance "${materialCls}" not implemented (yet).` );
301
+ }
302
+ }
303
+ if( deep ) {
304
+ node.getChildTransformNodes( true ).forEach( child => setMaterialTexture( child, texture, deep ) );
305
+ }
306
+ };
307
+
308
+ /**
309
+ * @param node
310
+ * @param metallness
311
+ * @param deep
312
+ */
313
+ const setMaterialMetallness = function( node: TransformNode, metallness: number, deep: boolean = true ) {
314
+ if( node instanceof AbstractMesh && node.material ) {
315
+ const materialCls = node.material.getClassName();
316
+ switch( materialCls ) {
317
+ case 'PBRMaterial':
318
+ (node.material as PBRMaterial).metallic = metallness;
319
+ break;
320
+ default:
321
+ throw new Error( `Setting metallness for material of instance "${materialCls}" not implemented (yet).` );
322
+ }
323
+ }
324
+ if( deep ) {
325
+ node.getChildTransformNodes( true ).forEach( child => setMaterialMetallness( child, metallness, deep ) );
326
+ }
327
+ };
328
+
329
+ /**
330
+ * @param node
331
+ * @param roughness
332
+ * @param deep
333
+ */
334
+ const setMaterialRoughness = function( node: TransformNode, roughness: number, deep: boolean = true ) {
335
+ if( node instanceof AbstractMesh && node.material ) {
336
+ const materialCls = node.material.getClassName();
337
+ switch( materialCls ) {
338
+ case 'PBRMaterial':
339
+ (node.material as PBRMaterial).roughness = roughness;
340
+ break;
341
+ case 'StandardMaterial':
342
+ (node.material as StandardMaterial).roughness = roughness;
343
+ break;
344
+ default:
345
+ throw new Error( `Setting roughness for material of instance "${materialCls}" not implemented (yet).` );
346
+ }
347
+ }
348
+ if( deep ) {
349
+ node.getChildTransformNodes( true ).forEach( child => setMaterialRoughness( child, roughness, deep ) );
350
+ }
351
+ };
352
+
353
+ /**
354
+ * @param node
355
+ * @param layer
356
+ * @param color
357
+ * @param deep
358
+ */
359
+ const addToHighlightLayer = function( layer: HighlightLayer, color: Color3, node: TransformNode, deep: boolean = true ) {
360
+ if( node instanceof AbstractMesh ) {
361
+ layer.addMesh( (node as Mesh), color );
362
+ }
363
+ if( deep ) {
364
+ node.getChildTransformNodes( true ).forEach(
365
+ child => addToHighlightLayer( layer, color, child, deep )
366
+ );
367
+ }
368
+ };
369
+
370
+ /**
371
+ * @param node
372
+ * @param layer
373
+ * @param deep
374
+ */
375
+ const removeFromHighlightLayer = function( layer: HighlightLayer, node: TransformNode, deep: boolean = true ) {
376
+ if( node instanceof AbstractMesh ) {
377
+ layer.removeMesh( (node as Mesh) );
378
+ }
379
+ if( deep ) {
380
+ node.getChildTransformNodes( true ).forEach(
381
+ child => removeFromHighlightLayer( layer, child, deep )
382
+ );
383
+ }
384
+ };
385
+
386
+ /**
387
+ * @param node
388
+ * @param receiveShadows
389
+ * @param deep
390
+ */
391
+ const setReceiveShadows = function( node: TransformNode, receiveShadows: boolean, deep: boolean = true ) {
392
+ if( node instanceof AbstractMesh ) {
393
+ node.receiveShadows = receiveShadows;
394
+ }
395
+ if( deep ) {
396
+ node.getChildTransformNodes( true ).forEach(
397
+ child => setReceiveShadows( child, receiveShadows, deep )
398
+ );
399
+ }
400
+ };
401
+
402
+ /**
403
+ * @param node
404
+ * @param generator
405
+ * @param deep
406
+ */
407
+ const addToShadowGenerator = function( generator: ShadowGenerator, node: TransformNode, deep: boolean = true ) {
408
+ if( node instanceof AbstractMesh ) {
409
+ // We have to remove the node because there's no duplicate check in babylon
410
+ generator.removeShadowCaster( node, false );
411
+ generator.addShadowCaster( node, false );
412
+ }
413
+ if( deep ) {
414
+ node.getChildTransformNodes( true ).forEach(
415
+ child => addToShadowGenerator( generator, child, deep )
416
+ );
417
+ }
418
+ };
419
+
420
+ /**
421
+ * @param node
422
+ * @param generator
423
+ * @param deep
424
+ */
425
+ const removeFromShadowGenerator = function( generator: ShadowGenerator, node: TransformNode, deep: boolean = true ) {
426
+ if( node instanceof AbstractMesh ) {
427
+ generator.removeShadowCaster( node, false );
428
+ }
429
+ if( deep ) {
430
+ node.getChildTransformNodes( true ).forEach(
431
+ child => removeFromShadowGenerator( generator, child, deep )
432
+ );
433
+ }
434
+ };
435
+
436
+ /**
437
+ * https://forum.babylonjs.com/t/get-mesh-bounding-box-position-and-size-in-2d-screen-coordinates/1058/3
438
+ * @param mesh
439
+ * @param scene
440
+ * @param canvas
441
+ */
442
+ const getClientRectFromMesh = function( mesh: AbstractMesh, scene: Scene, canvas: HTMLCanvasElement ): ClientRect {
443
+ // get bounding box of the mesh
444
+ const meshVectors = mesh.getBoundingInfo().boundingBox.vectors;
445
+ // get the matrix and viewport needed to project the vectors onto the screen
446
+ const worldMatrix = mesh.getWorldMatrix();
447
+ const transformMatrix = scene.getTransformMatrix();
448
+ const viewport = scene.activeCamera!.viewport;
449
+ // loop though all the vectors and project them against the current camera viewport to get a set of coordinates
450
+ const coordinates = meshVectors.map( vector => {
451
+ const projection = Vector3.Project( vector, worldMatrix, transformMatrix, viewport );
452
+ projection.x = projection.x * canvas.clientWidth;
453
+ projection.y = projection.y * canvas.clientHeight;
454
+ return projection;
455
+ } );
456
+ // get the min and max for all the coordinates so we can calculate the largest possible screen size
457
+ const maxX = Math.max.apply( Math, coordinates.map( o => o.x ) );
458
+ const minX = Math.min.apply( Math, coordinates.map( o => o.x ) );
459
+ const maxY = Math.max.apply( Math, coordinates.map( o => o.y ) );
460
+ const minY = Math.min.apply( Math, coordinates.map( o => o.y ) );
461
+ // return a ClientRect from this
462
+ return {
463
+ width: maxX - minX,
464
+ height: maxY - minY,
465
+ left: minX,
466
+ top: minY,
467
+ right: maxX,
468
+ bottom: maxY,
469
+ } as ClientRect;
470
+ };
471
+
472
+ export {
473
+ getRootNode,
474
+ mapToDottedNodes,
475
+ getDottedPathForNode,
476
+ cloneTransformNode,
477
+ cloneNodeWithParents,
478
+ cloneTransformNodeMaterial,
479
+ injectNodeMetadata,
480
+ assertTransformNode,
481
+ activateTransformNode,
482
+ deactivateTransformNode,
483
+ enableNodeWithParents,
484
+ disableNodeWithParents,
485
+ setMaterial,
486
+ setSourceNodeMaterial,
487
+ setMaterialColor,
488
+ setMaterialTexture,
489
+ setMaterialMetallness,
490
+ setMaterialRoughness,
491
+ addToHighlightLayer,
492
+ removeFromHighlightLayer,
493
+ setReceiveShadows,
494
+ addToShadowGenerator,
495
+ removeFromShadowGenerator,
496
+ getClientRectFromMesh
497
+ };