@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
@@ -9,12 +9,12 @@ import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
9
9
  import '@babylonjs/loaders/glTF/2.0/Extensions/KHR_lights_punctual';
10
10
  import { get, isEmpty, isString, set } from 'lodash-es';
11
11
  import {
12
- cloneNodeWithParents,
13
- disableNodeWithParents,
14
- enableNodeWithParents,
15
- getRootNode,
16
- injectNodeMetadata,
17
- transformTransformNode
12
+ cloneNodeWithParents,
13
+ disableNodeWithParents,
14
+ enableNodeWithParents,
15
+ getRootNode,
16
+ injectNodeMetadata,
17
+ transformTransformNode,
18
18
  } from './../util/babylonHelper';
19
19
  import { DottedPath } from './dottedPath';
20
20
  import { Parameter } from './parameter';
@@ -26,309 +26,309 @@ import { VariantParameterizable } from './variantParameterizable';
26
26
  * {@link Variant}.
27
27
  */
28
28
  export class ViewerLight extends VariantParameterizable {
29
+ protected _light: Light | undefined;
29
30
 
30
- protected _light: Light | undefined;
31
+ /**
32
+ * Constructor.
33
+ */
34
+ protected constructor(public readonly variant: Variant, public readonly name: string) {
35
+ super(variant, name);
36
+ this.addParameterObservers();
37
+ }
31
38
 
32
- /**
33
- * Constructor.
34
- */
35
- protected constructor( public readonly variant: Variant,
36
- public readonly name: string ) {
37
- super( variant, name );
38
- this.addParameterObservers();
39
- }
39
+ /**
40
+ * Creates a {@link ViewerLight} with given name.
41
+ */
42
+ public static async create(variant: Variant, name: string): Promise<ViewerLight> {
43
+ const viewerLight = new ViewerLight(variant, name);
44
+ viewerLight._light = await viewerLight.createBabylonLightFromDefinition(viewerLight.definition);
45
+ return viewerLight;
46
+ }
40
47
 
41
- /**
42
- * Creates a {@link ViewerLight} with given name.
43
- */
44
- public static async create( variant: Variant, name: string ): Promise<ViewerLight> {
45
- const viewerLight = new ViewerLight( variant, name );
46
- viewerLight._light = await viewerLight.createBabylonLightFromDefinition( viewerLight.definition );
47
- return viewerLight;
48
- }
48
+ /**
49
+ * The wrapped Light.
50
+ */
51
+ get light(): Light {
52
+ if (!this._light) {
53
+ throw new Error(`Light for ViewerLight "${this.name}" has not been properly initialized.`);
54
+ }
55
+ return this._light!;
56
+ }
49
57
 
50
- /**
51
- * The wrapped Light.
52
- */
53
- get light(): Light {
54
- if( !this._light ) {
55
- throw new Error( `Light for ViewerLight "${this.name}" has not been properly initialized.` );
56
- }
57
- return this._light!;
58
- }
58
+ /**
59
+ * The {@link DottedPath} in the built tree of {@link ViewerLight}s.
60
+ * E.g. "_.top-1.sub-2.sub-sub-3.el-1"
61
+ */
62
+ get dottedPath(): DottedPath {
63
+ return DottedPath.create(this.variant.dottedPath).addPart(this.name);
64
+ }
59
65
 
60
- /**
61
- * The {@link DottedPath} in the built tree of {@link ViewerLight}s.
62
- * E.g. "_.top-1.sub-2.sub-sub-3.el-1"
63
- */
64
- get dottedPath(): DottedPath {
65
- return DottedPath.create( this.variant.dottedPath ).addPart( this.name );
66
- }
66
+ /**
67
+ * The id representing a {@link DottedPath}.
68
+ */
69
+ get id(): string {
70
+ const dottedPath = DottedPath.create(this.dottedPath);
71
+ dottedPath.shiftPart(); // remove root
72
+ return dottedPath.path;
73
+ }
67
74
 
68
- /**
69
- * The id representing a {@link DottedPath}.
70
- */
71
- get id(): string {
72
- const dottedPath = DottedPath.create( this.dottedPath );
73
- dottedPath.shiftPart(); // remove root
74
- return dottedPath.path;
75
- }
75
+ /**
76
+ * The {@link LightDefinition} of the {@link ViewerLight}.
77
+ */
78
+ get definition(): LightDefinition {
79
+ const definition = this.variant.structureJson.lights![this.name];
80
+ if (isString(definition)) {
81
+ return {
82
+ type: 'baked',
83
+ path: definition,
84
+ } as LightDefinition;
85
+ }
86
+ return definition as LightDefinition;
87
+ }
76
88
 
77
- /**
78
- * The {@link LightDefinition} of the {@link ViewerLight}.
79
- */
80
- get definition(): LightDefinition {
81
- const definition = this.variant.structureJson.lights![this.name];
82
- if( isString( definition ) ) {
83
- return {
84
- type: 'baked',
85
- path: definition
86
- } as LightDefinition;
87
- }
88
- return definition as LightDefinition;
89
- }
89
+ /**
90
+ * The type of the {@link ViewerLight}'s light.
91
+ */
92
+ get type(): string {
93
+ return this.light.constructor.name.replace(/light/i, '').toLowerCase();
94
+ }
90
95
 
91
- /**
92
- * The type of the {@link ViewerLight}'s light.
93
- */
94
- get type(): string {
95
- return this.light.constructor.name.replace( /light/i, '' ).toLowerCase();
96
- }
96
+ /**
97
+ * @see {@link VariantParameterizable.commitParameters}
98
+ * @emit {@link Event.VIEWER_LIGHT_PARAMETER_COMMITTED}
99
+ */
100
+ public async commitParameters(parameters?: ParameterBag): Promise<VariantParameterizable> {
101
+ return super.commitParameters(parameters);
102
+ }
97
103
 
98
- /**
99
- * @see {@link VariantParameterizable.commitParameters}
100
- * @emit {@link Event.VIEWER_LIGHT_PARAMETER_COMMITTED}
101
- */
102
- public async commitParameters( parameters?: ParameterBag ): Promise<VariantParameterizable> {
103
- return super.commitParameters( parameters );
104
- }
104
+ /**
105
+ * Adds the default {@link ParameterObserver}s which are called every time {@link commitParameters} is called.
106
+ */
107
+ protected addParameterObservers(): ViewerLight {
108
+ this._parameterObservers.set(Parameter.VISIBLE, [
109
+ async (light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue) => {
110
+ let visible;
111
+ try {
112
+ visible = Parameter.parseBoolean(newValue);
113
+ } catch (e) {
114
+ return;
115
+ }
116
+ if (visible === true) {
117
+ enableNodeWithParents(light.light);
118
+ } else if (visible === false) {
119
+ disableNodeWithParents(light.light);
120
+ }
121
+ },
122
+ ]);
123
+ this._parameterObservers.set(Parameter.INTENSITY, [
124
+ async (light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue) => {
125
+ set(light.light, 'intensity', Parameter.parseNumber(newValue));
126
+ },
127
+ ]);
128
+ this._parameterObservers.set(Parameter.SCALING, [
129
+ async (light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue) => {
130
+ // we have to deal just with root nodes here due to relative impacts in a node tree
131
+ const rootNode = getRootNode(light.light);
132
+ if (rootNode instanceof TransformNode) {
133
+ transformTransformNode(rootNode, {
134
+ scaling: Parameter.parseScaling(newValue),
135
+ position: Parameter.parseVector(light.inheritedParameters[Parameter.POSITION] || '(0, 0, 0)'),
136
+ rotation: Parameter.parseRotation(light.inheritedParameters[Parameter.ROTATION] || '(0, 0, 0)'),
137
+ });
138
+ }
139
+ },
140
+ ]);
141
+ this._parameterObservers.set(Parameter.POSITION, [
142
+ async (light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue) => {
143
+ // we have to deal just with root nodes here due to relative impacts in a node tree
144
+ const rootNode = getRootNode(light.light);
145
+ if (rootNode instanceof TransformNode) {
146
+ transformTransformNode(rootNode, {
147
+ scaling: Parameter.parseVector(light.inheritedParameters[Parameter.SCALING] || '(1, 1, 1)'),
148
+ position: Parameter.parseVector(newValue),
149
+ rotation: Parameter.parseRotation(light.inheritedParameters[Parameter.ROTATION] || '(0, 0, 0)'),
150
+ });
151
+ }
152
+ },
153
+ ]);
154
+ this._parameterObservers.set(Parameter.ROTATION, [
155
+ async (light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue) => {
156
+ // we have to deal just with root nodes here due to relative impacts in a node tree
157
+ const rootNode = getRootNode(light.light);
158
+ if (rootNode instanceof TransformNode) {
159
+ transformTransformNode(rootNode, {
160
+ scaling: Parameter.parseVector(light.inheritedParameters[Parameter.SCALING] || '(1, 1, 1)'),
161
+ position: Parameter.parseVector(light.inheritedParameters[Parameter.POSITION] || '(0, 0, 0)'),
162
+ rotation: Parameter.parseRotation(newValue),
163
+ });
164
+ }
165
+ },
166
+ ]);
167
+ this._parameterObservers.set(Parameter.DIRECTION, [
168
+ async (light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue) => {
169
+ if (
170
+ (light.light instanceof ShadowLight && !(light.light instanceof PointLight)) ||
171
+ light.light instanceof HemisphericLight
172
+ ) {
173
+ set(light.light, 'direction', Parameter.parseVector(newValue));
174
+ }
175
+ },
176
+ ]);
177
+ this._parameterObservers.set(Parameter.ANGLE, [
178
+ async (light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue) => {
179
+ if (light.light.getClassName() === 'SpotLight') {
180
+ set(light.light, 'angle', Parameter.parseNumber(newValue));
181
+ }
182
+ },
183
+ ]);
184
+ this._parameterObservers.set(Parameter.EXPONENT, [
185
+ async (light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue) => {
186
+ if (light.light.getClassName() === 'SpotLight') {
187
+ set(light.light, 'exponent', Parameter.parseNumber(newValue));
188
+ }
189
+ },
190
+ ]);
191
+ this._parameterObservers.set(Parameter.DIFFUSE, [
192
+ async (light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue) => {
193
+ set(light.light, 'diffuse', Parameter.parseColor(newValue));
194
+ },
195
+ ]);
196
+ this._parameterObservers.set(Parameter.SPECULAR, [
197
+ async (light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue) => {
198
+ set(light.light, 'specular', Parameter.parseColor(newValue));
199
+ },
200
+ ]);
201
+ return this;
202
+ }
105
203
 
106
- /**
107
- * Adds the default {@link ParameterObserver}s which are called every time {@link commitParameters} is called.
108
- */
109
- protected addParameterObservers(): ViewerLight {
110
- this._parameterObservers.set( Parameter.VISIBLE, [
111
- async ( light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue ) => {
112
- let visible;
113
- try {
114
- visible = Parameter.parseBoolean( newValue );
115
- } catch( e ) {
116
- return;
117
- }
118
- if( visible === true ) {
119
- enableNodeWithParents( light.light );
120
- } else if( visible === false ) {
121
- disableNodeWithParents( light.light );
122
- }
123
- }
124
- ] );
125
- this._parameterObservers.set( Parameter.INTENSITY, [
126
- async ( light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue ) => {
127
- set( light.light, 'intensity', Parameter.parseNumber( newValue ) );
128
- }
129
- ] );
130
- this._parameterObservers.set( Parameter.SCALING, [
131
- async ( light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue ) => {
132
- // we have to deal just with root nodes here due to relative impacts in a node tree
133
- const rootNode = getRootNode( light.light );
134
- if( rootNode instanceof TransformNode ) {
135
- transformTransformNode( rootNode, {
136
- scaling: Parameter.parseScaling( newValue ),
137
- position: Parameter.parseVector( light.inheritedParameters[Parameter.POSITION] || '(0, 0, 0)' ),
138
- rotation: Parameter.parseRotation( light.inheritedParameters[Parameter.ROTATION] || '(0, 0, 0)' )
139
- } );
140
- }
141
- }
142
- ] );
143
- this._parameterObservers.set( Parameter.POSITION, [
144
- async ( light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue ) => {
145
- // we have to deal just with root nodes here due to relative impacts in a node tree
146
- const rootNode = getRootNode( light.light );
147
- if( rootNode instanceof TransformNode ) {
148
- transformTransformNode( rootNode, {
149
- scaling: Parameter.parseVector( light.inheritedParameters[Parameter.SCALING] || '(1, 1, 1)' ),
150
- position: Parameter.parseVector( newValue ),
151
- rotation: Parameter.parseRotation( light.inheritedParameters[Parameter.ROTATION] || '(0, 0, 0)' )
152
- } );
153
- }
154
- }
155
- ] );
156
- this._parameterObservers.set( Parameter.ROTATION, [
157
- async ( light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue ) => {
158
- // we have to deal just with root nodes here due to relative impacts in a node tree
159
- const rootNode = getRootNode( light.light );
160
- if( rootNode instanceof TransformNode ) {
161
- transformTransformNode( rootNode, {
162
- scaling: Parameter.parseVector( light.inheritedParameters[Parameter.SCALING] || '(1, 1, 1)' ),
163
- position: Parameter.parseVector( light.inheritedParameters[Parameter.POSITION] || '(0, 0, 0)' ),
164
- rotation: Parameter.parseRotation( newValue )
165
- } );
166
- }
167
- }
168
- ] );
169
- this._parameterObservers.set( Parameter.DIRECTION, [
170
- async ( light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue ) => {
171
- if(
172
- (light.light instanceof ShadowLight && !(light.light instanceof PointLight))
173
- || light.light instanceof HemisphericLight
174
- ) {
175
- set( light.light, 'direction', Parameter.parseVector( newValue ) );
176
- }
177
- }
178
- ] );
179
- this._parameterObservers.set( Parameter.ANGLE, [
180
- async ( light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue ) => {
181
- if( light.light.getClassName() === 'SpotLight' ) {
182
- set( light.light, 'angle', Parameter.parseNumber( newValue ) );
183
- }
184
- }
185
- ] );
186
- this._parameterObservers.set( Parameter.EXPONENT, [
187
- async ( light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue ) => {
188
- if( light.light.getClassName() === 'SpotLight' ) {
189
- set( light.light, 'exponent', Parameter.parseNumber( newValue ) );
190
- }
191
- }
192
- ] );
193
- this._parameterObservers.set( Parameter.DIFFUSE, [
194
- async ( light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue ) => {
195
- set( light.light, 'diffuse', Parameter.parseColor( newValue ) );
196
- }
197
- ] );
198
- this._parameterObservers.set( Parameter.SPECULAR, [
199
- async ( light: ViewerLight, oldValue: ParameterValue, newValue: ParameterValue ) => {
200
- set( light.light, 'specular', Parameter.parseColor( newValue ) );
201
- }
202
- ] );
203
- return this;
204
- }
205
-
206
- /**
207
- * @param definition
208
- * @protected
209
- */
210
- protected async createBabylonLightFromDefinition( definition: LightDefinition ): Promise<Light> {
211
- const parameters = Parameter.parseFromDeclarations( Parameter.declarations, this.inheritedParameters );
212
- const scene = this.variant.viewer.scene;
213
- let lightId = this.id;
214
- let babylonLight;
215
- switch( definition.type ) {
216
- case 'baked':
217
- if( !definition['path'] ) {
218
- throw new Error( `The light "${lightId}" of type "${definition.type}" needs a "path".` );
219
- }
220
- const bakedLight = this.variant.inheritedLights.find( l => l.metadata.dottedPath.path === definition['path'] );
221
- if( bakedLight ) {
222
- lightId = bakedLight.metadata.dottedPath.clone().unshiftPart( this.id ).path;
223
- babylonLight = cloneNodeWithParents( bakedLight ) as Light;
224
- babylonLight!.name = lightId;
225
- babylonLight!.id = lightId;
226
- } else {
227
- throw new Error( `No light found for path "${definition['path']}" in ViewerLight "${lightId}".` );
228
- }
229
- break;
230
- case 'hemispheric':
231
- if( !parameters['direction'] ) {
232
- throw new Error( `The ViewerLight "${lightId}" of type "${definition.type}" needs a "direction".` );
233
- }
234
- // @ts-ignore
235
- const hemisphericLightModule = await import(/* webpackChunkName: "hemispheric-light" */ '@babylonjs/core/Lights/hemisphericLight');
236
- babylonLight = new hemisphericLightModule.HemisphericLight(
237
- lightId,
238
- parameters['direction'],
239
- scene
240
- );
241
- break;
242
- case 'point':
243
- // @ts-ignore
244
- const pointLightModule = await import(/* webpackChunkName: "point-light" */ '@babylonjs/core/Lights/pointLight');
245
- babylonLight = new pointLightModule.PointLight(
246
- lightId,
247
- Vector3.Zero(), // position is set via parent TransformNode
248
- scene
249
- );
250
- break;
251
- case 'directional':
252
- if( !parameters['direction'] ) {
253
- throw new Error( `The ViewerLight "${lightId}" of type "${definition.type}" needs a "direction".` );
254
- }
255
- // @ts-ignore
256
- const directionalLightModule = await import(/* webpackChunkName: "directional-light" */ '@babylonjs/core/Lights/directionalLight');
257
- babylonLight = new directionalLightModule.DirectionalLight(
258
- lightId,
259
- parameters['direction'],
260
- scene
261
- );
262
- break;
263
- case 'spot':
264
- if( !parameters['direction'] ) {
265
- throw new Error( `The ViewerLight "${lightId}" of type "${definition.type}" needs a "direction".` );
266
- }
267
- if( !parameters['angle'] ) {
268
- throw new Error( `A ViewerLight of type "${definition.type}" needs an "angle".` );
269
- }
270
- if( !parameters['exponent'] ) {
271
- throw new Error( `The ViewerLight "${lightId}" of type "${definition.type}" needs an "exponent".` );
272
- }
273
- // @ts-ignore
274
- const spotLightModule = await import(/* webpackChunkName: "spot-light" */ '@babylonjs/core/Lights/spotLight');
275
- babylonLight = new spotLightModule.SpotLight(
276
- lightId,
277
- Vector3.Zero(), // position is set via parent TransformNode
278
- parameters['direction'],
279
- parameters['angle'],
280
- parameters['exponent'],
281
- scene
282
- );
283
- break;
284
- default:
285
- throw new Error( `The type "${definition.type}" for ViewerLight "${lightId}" is not implemented (yet).` );
286
- }
287
- if( !babylonLight ) {
288
- throw new Error( `The Light for ViewerLight "${lightId}" of type "${definition.type}" could no be created ` +
289
- `or found.` );
290
- }
291
- if( !babylonLight.parent ) {
292
- // Create pseudo parent since lights do not implement mutations like "rotation" by itself.
293
- babylonLight.parent = new TransformNode( '__light__', this.variant.viewer.scene, true );
294
- }
295
- injectNodeMetadata( babylonLight.parent, {
296
- variant: this.variant,
297
- variantParameterizable: this
298
- } );
299
- // disable/hide by default
300
- disableNodeWithParents( babylonLight );
301
- // process shadow generator
302
- const shadowGeneratorDefinition = get( definition, 'shadowGenerator' ) as ShadowGeneratorDefinition;
303
- if( !isEmpty( shadowGeneratorDefinition ) ) {
304
- if( !(babylonLight instanceof ShadowLight) ) {
305
- throw new Error( `Using a ShadowGenerator with light type "${definition.type}" is not supported for ` +
306
- `"${lightId}". Use lights deriving from ShadowLight.` );
307
- }
308
- await this.processShadowGenerator( babylonLight, shadowGeneratorDefinition );
309
- }
310
- return babylonLight;
311
- };
312
-
313
- /**
314
- * @param babylonLight
315
- * @param definition
316
- * @protected
317
- */
318
- protected async processShadowGenerator( babylonLight: ShadowLight,
319
- definition: ShadowGeneratorDefinition ): Promise<ShadowGenerator> {
320
- const parameterDeclarations: ParameterDeclarations = {};
321
- // define declarations here if needed in future
322
- const parameterBag = definition as {} as ParameterBag;
323
- const parameters = Parameter.parseFromDeclarations( parameterDeclarations, parameterBag );
324
- const shadowGenerator = new ShadowGenerator( parameters['mapSize'], babylonLight );
325
- for( const parameter in parameters ) {
326
- if( parameter === 'mapSize' ) {
327
- continue;
328
- }
329
- set( shadowGenerator, parameter, get( parameters, parameter ) );
330
- }
331
- return shadowGenerator;
332
- };
204
+ /**
205
+ * @param definition
206
+ * @protected
207
+ */
208
+ protected async createBabylonLightFromDefinition(definition: LightDefinition): Promise<Light> {
209
+ const parameters = Parameter.parseFromDeclarations(Parameter.declarations, this.inheritedParameters);
210
+ const scene = this.variant.viewer.scene;
211
+ let lightId = this.id;
212
+ let babylonLight;
213
+ switch (definition.type) {
214
+ case 'baked':
215
+ if (!definition['path']) {
216
+ throw new Error(`The light "${lightId}" of type "${definition.type}" needs a "path".`);
217
+ }
218
+ const bakedLight = this.variant.inheritedLights.find(l => l.metadata.dottedPath.path === definition['path']);
219
+ if (bakedLight) {
220
+ lightId = bakedLight.metadata.dottedPath.clone().unshiftPart(this.id).path;
221
+ babylonLight = cloneNodeWithParents(bakedLight) as Light;
222
+ babylonLight!.name = lightId;
223
+ babylonLight!.id = lightId;
224
+ } else {
225
+ throw new Error(`No light found for path "${definition['path']}" in ViewerLight "${lightId}".`);
226
+ }
227
+ break;
228
+ case 'hemispheric':
229
+ if (!parameters['direction']) {
230
+ throw new Error(`The ViewerLight "${lightId}" of type "${definition.type}" needs a "direction".`);
231
+ }
232
+ // @ts-ignore
233
+ const hemisphericLightModule = await import(
234
+ /* webpackChunkName: "hemispheric-light" */ '@babylonjs/core/Lights/hemisphericLight'
235
+ );
236
+ babylonLight = new hemisphericLightModule.HemisphericLight(lightId, parameters['direction'], scene);
237
+ break;
238
+ case 'point':
239
+ // @ts-ignore
240
+ const pointLightModule = await import(
241
+ /* webpackChunkName: "point-light" */ '@babylonjs/core/Lights/pointLight'
242
+ );
243
+ babylonLight = new pointLightModule.PointLight(
244
+ lightId,
245
+ Vector3.Zero(), // position is set via parent TransformNode
246
+ scene
247
+ );
248
+ break;
249
+ case 'directional':
250
+ if (!parameters['direction']) {
251
+ throw new Error(`The ViewerLight "${lightId}" of type "${definition.type}" needs a "direction".`);
252
+ }
253
+ // @ts-ignore
254
+ const directionalLightModule = await import(
255
+ /* webpackChunkName: "directional-light" */ '@babylonjs/core/Lights/directionalLight'
256
+ );
257
+ babylonLight = new directionalLightModule.DirectionalLight(lightId, parameters['direction'], scene);
258
+ break;
259
+ case 'spot':
260
+ if (!parameters['direction']) {
261
+ throw new Error(`The ViewerLight "${lightId}" of type "${definition.type}" needs a "direction".`);
262
+ }
263
+ if (!parameters['angle']) {
264
+ throw new Error(`A ViewerLight of type "${definition.type}" needs an "angle".`);
265
+ }
266
+ if (!parameters['exponent']) {
267
+ throw new Error(`The ViewerLight "${lightId}" of type "${definition.type}" needs an "exponent".`);
268
+ }
269
+ // @ts-ignore
270
+ const spotLightModule = await import(/* webpackChunkName: "spot-light" */ '@babylonjs/core/Lights/spotLight');
271
+ babylonLight = new spotLightModule.SpotLight(
272
+ lightId,
273
+ Vector3.Zero(), // position is set via parent TransformNode
274
+ parameters['direction'],
275
+ parameters['angle'],
276
+ parameters['exponent'],
277
+ scene
278
+ );
279
+ break;
280
+ default:
281
+ throw new Error(`The type "${definition.type}" for ViewerLight "${lightId}" is not implemented (yet).`);
282
+ }
283
+ if (!babylonLight) {
284
+ throw new Error(
285
+ `The Light for ViewerLight "${lightId}" of type "${definition.type}" could no be created ` + `or found.`
286
+ );
287
+ }
288
+ if (!babylonLight.parent) {
289
+ // Create pseudo parent since lights do not implement mutations like "rotation" by itself.
290
+ babylonLight.parent = new TransformNode('__light__', this.variant.viewer.scene, true);
291
+ }
292
+ injectNodeMetadata(babylonLight.parent, {
293
+ variant: this.variant,
294
+ variantParameterizable: this,
295
+ });
296
+ // disable/hide by default
297
+ disableNodeWithParents(babylonLight);
298
+ // process shadow generator
299
+ const shadowGeneratorDefinition = get(definition, 'shadowGenerator') as ShadowGeneratorDefinition;
300
+ if (!isEmpty(shadowGeneratorDefinition)) {
301
+ if (!(babylonLight instanceof ShadowLight)) {
302
+ throw new Error(
303
+ `Using a ShadowGenerator with light type "${definition.type}" is not supported for ` +
304
+ `"${lightId}". Use lights deriving from ShadowLight.`
305
+ );
306
+ }
307
+ await this.processShadowGenerator(babylonLight, shadowGeneratorDefinition);
308
+ }
309
+ return babylonLight;
310
+ }
333
311
 
312
+ /**
313
+ * @param babylonLight
314
+ * @param definition
315
+ * @protected
316
+ */
317
+ protected async processShadowGenerator(
318
+ babylonLight: ShadowLight,
319
+ definition: ShadowGeneratorDefinition
320
+ ): Promise<ShadowGenerator> {
321
+ const parameterDeclarations: ParameterDeclarations = {};
322
+ // define declarations here if needed in future
323
+ const parameterBag = definition as {} as ParameterBag;
324
+ const parameters = Parameter.parseFromDeclarations(parameterDeclarations, parameterBag);
325
+ const shadowGenerator = new ShadowGenerator(parameters['mapSize'], babylonLight);
326
+ for (const parameter in parameters) {
327
+ if (parameter === 'mapSize') {
328
+ continue;
329
+ }
330
+ set(shadowGenerator, parameter, get(parameters, parameter));
331
+ }
332
+ return shadowGenerator;
333
+ }
334
334
  }