@combeenation/3d-viewer 4.0.0-alpha7 → 4.0.0-beta2

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 (57) hide show
  1. package/README.md +1 -0
  2. package/dist/lib-cjs/api/classes/element.d.ts +12 -16
  3. package/dist/lib-cjs/api/classes/element.js +125 -180
  4. package/dist/lib-cjs/api/classes/element.js.map +1 -1
  5. package/dist/lib-cjs/api/classes/event.d.ts +1 -15
  6. package/dist/lib-cjs/api/classes/event.js +1 -15
  7. package/dist/lib-cjs/api/classes/event.js.map +1 -1
  8. package/dist/lib-cjs/api/classes/parameter.d.ts +7 -101
  9. package/dist/lib-cjs/api/classes/parameter.js +21 -141
  10. package/dist/lib-cjs/api/classes/parameter.js.map +1 -1
  11. package/dist/lib-cjs/api/classes/parameterObservable.js +36 -11
  12. package/dist/lib-cjs/api/classes/parameterObservable.js.map +1 -1
  13. package/dist/lib-cjs/api/classes/variant.d.ts +14 -48
  14. package/dist/lib-cjs/api/classes/variant.js +56 -315
  15. package/dist/lib-cjs/api/classes/variant.js.map +1 -1
  16. package/dist/lib-cjs/api/classes/variantInstance.d.ts +1 -5
  17. package/dist/lib-cjs/api/classes/variantInstance.js +0 -10
  18. package/dist/lib-cjs/api/classes/variantInstance.js.map +1 -1
  19. package/dist/lib-cjs/api/classes/viewer.d.ts +1 -0
  20. package/dist/lib-cjs/api/classes/viewer.js.map +1 -1
  21. package/dist/lib-cjs/api/classes/viewerLight.js +27 -19
  22. package/dist/lib-cjs/api/classes/viewerLight.js.map +1 -1
  23. package/dist/lib-cjs/api/internal/sceneSetup.d.ts +1 -5
  24. package/dist/lib-cjs/api/internal/sceneSetup.js +71 -75
  25. package/dist/lib-cjs/api/internal/sceneSetup.js.map +1 -1
  26. package/dist/lib-cjs/api/util/babylonHelper.d.ts +4 -51
  27. package/dist/lib-cjs/api/util/babylonHelper.js +8 -141
  28. package/dist/lib-cjs/api/util/babylonHelper.js.map +1 -1
  29. package/dist/lib-cjs/api/util/globalTypes.d.ts +11 -53
  30. package/dist/lib-cjs/api/util/resourceHelper.d.ts +8 -4
  31. package/dist/lib-cjs/api/util/resourceHelper.js +25 -59
  32. package/dist/lib-cjs/api/util/resourceHelper.js.map +1 -1
  33. package/dist/lib-cjs/index.d.ts +22 -24
  34. package/dist/lib-cjs/index.js +38 -42
  35. package/dist/lib-cjs/index.js.map +1 -1
  36. package/package.json +1 -1
  37. package/src/api/classes/element.ts +112 -133
  38. package/src/api/classes/{parameterizable.ts → elementParameterizable.ts} +1 -12
  39. package/src/api/classes/event.ts +1 -16
  40. package/src/api/classes/parameter.ts +22 -153
  41. package/src/api/classes/parameterObservable.ts +31 -9
  42. package/src/api/classes/variant.ts +51 -184
  43. package/src/api/classes/variantInstance.ts +1 -8
  44. package/src/api/classes/viewer.ts +1 -0
  45. package/src/api/internal/sceneSetup.ts +109 -99
  46. package/src/api/util/babylonHelper.ts +9 -153
  47. package/src/api/util/globalTypes.ts +13 -64
  48. package/src/api/util/resourceHelper.ts +24 -26
  49. package/src/dev.ts +7 -5
  50. package/src/index.ts +23 -27
  51. package/src/pagesconfig.json +13 -8
  52. package/dist/lib-cjs/api/emitter.d.ts +0 -35
  53. package/dist/lib-cjs/api/emitter.js +0 -61
  54. package/dist/lib-cjs/api/emitter.js.map +0 -1
  55. package/src/api/classes/variantParameterizable.ts +0 -73
  56. package/src/api/classes/viewerLight.ts +0 -326
  57. package/src/api/util/stringHelper.ts +0 -26
@@ -1,40 +1,35 @@
1
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
2
  import { Material } from '@babylonjs/core/Materials/material';
5
3
  import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
6
- import { DynamicTexture } from '@babylonjs/core/Materials/Textures/dynamicTexture';
4
+ import { Axis, Space } from '@babylonjs/core/Maths/math.axis';
7
5
  import { Color3 } from '@babylonjs/core/Maths/math.color';
8
6
  import { AbstractMesh } from '@babylonjs/core/Meshes/abstractMesh';
9
7
  import { InstancedMesh } from '@babylonjs/core/Meshes/instancedMesh';
10
8
  import { Mesh } from '@babylonjs/core/Meshes/mesh';
11
9
  import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
12
- import { get, isArray, isNumber, isPlainObject, merge, union } from 'lodash-es';
10
+ import { Texture } from '@babylonjs/core/Materials/Textures/texture';
11
+ import { cloneDeep, concat, get, isArray, merge, union } from 'lodash-es';
13
12
  import {
14
13
  activateTransformNode as activate,
15
14
  addToHighlightLayer,
16
- addToShadowGenerator,
17
15
  assertTransformNode,
18
16
  cloneTransformNode,
19
17
  cloneTransformNodeMaterial,
20
18
  deactivateTransformNode as deactivate,
21
19
  getClientRectFromMesh,
22
- injectNodeMetadata,
20
+ injectTransformNodeMetadata,
23
21
  mapToDottedNodes,
24
- moveTransformNode,
25
22
  removeFromHighlightLayer,
26
- removeFromShadowGenerator,
27
- rotateTransformNode,
28
23
  setMaterial,
29
24
  setMaterialColor,
30
25
  setMaterialMetallness,
31
26
  setMaterialRoughness,
32
- setMaterialTexture,
33
- setReceiveShadows
27
+ setMaterialTexture
34
28
  } from '../util/babylonHelper';
35
- import { createImageBitmapFromImgSrc, createImageBitmapFromSvg } from '../util/resourceHelper';
36
- import { VariantParameterizable } from './../classes/variantParameterizable';
29
+ import { createImageUrlFromSvg, mergeMaps } from '../util/resourceHelper';
37
30
  import { DottedPath } from './dottedPath';
31
+ import { ElementParameterizable } from './elementParameterizable';
32
+ import { Event } from './event';
38
33
  import { Parameter } from './parameter';
39
34
  import { Variant } from './variant';
40
35
 
@@ -45,20 +40,24 @@ import { Variant } from './variant';
45
40
  * When used in typings, refer to via its alias {@link VariantElement} to prevent name clashes with the web APIs
46
41
  * [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) class
47
42
  */
48
- export class Element extends VariantParameterizable {
49
-
50
- public readonly nodes: TransformNode[] = [];
43
+ export class Element extends ElementParameterizable {
51
44
 
52
45
  protected readonly _dottedNodes: Map<DottedPath, TransformNode> = new Map();
53
46
 
47
+ protected readonly _parameterObservers: Map<string, ParameterObserver[]> = new Map();
48
+
54
49
  protected _highlightLayer?: HighlightLayer;
55
50
 
51
+ protected _paintableTextureId: number = 0;
52
+
53
+ public readonly nodes: TransformNode[] = [];
54
+
56
55
  /**
57
56
  * Constructor.
58
57
  */
59
- protected constructor( public readonly variant: Variant,
58
+ public constructor( public readonly variant: Variant,
60
59
  public readonly name: string ) {
61
- super( variant, name );
60
+ super();
62
61
  if ( process.env.NODE_ENV?.toLowerCase().includes('dev')) {
63
62
  this.assertPathDefinitions();
64
63
  }
@@ -73,13 +72,6 @@ export class Element extends VariantParameterizable {
73
72
  this.addParameterObservers();
74
73
  }
75
74
 
76
- /**
77
- * Creates an {@link Element} with given name.
78
- */
79
- public static async create( variant: Variant, name: string ): Promise<Element> {
80
- return new Element( variant, name );
81
- }
82
-
83
75
  /**
84
76
  * The {@link DottedPath} in the built tree of {@link Element}s.
85
77
  * E.g. "_.top-1.sub-2.sub-sub-3.el-1"
@@ -166,9 +158,10 @@ export class Element extends VariantParameterizable {
166
158
  * Gets a node by its {@link DottedPath}.
167
159
  */
168
160
  public getNode( dottedPath: DottedPathArgument ): TransformNode {
169
- // TODO: fix, currently broken
170
161
  const _dottedPath = DottedPath.create( dottedPath );
171
- const node = this._dottedNodes.get( _dottedPath );
162
+ const keys = Array.from( this._dottedNodes.keys() ).map( dp => dp.path );
163
+ const values = Array.from( this._dottedNodes.values() );
164
+ const node = values[keys.indexOf( _dottedPath.path )];
172
165
  if( !node ) {
173
166
  throw new Error( `Node with path "${_dottedPath.path}" does not exist for element "${this.id}".` );
174
167
  }
@@ -221,11 +214,41 @@ export class Element extends VariantParameterizable {
221
214
  }
222
215
 
223
216
  /**
224
- * @see {@link VariantParameterizable.commitParameters}
217
+ * Places the given {@link ParameterBag} in the {@link Element}'s parameters, replaces all patterns in the
218
+ * {@link StructureJson} and broadcasts all {@link ParameterObserver}s.
219
+ *
225
220
  * @emit {@link Event.ELEMENT_PARAMETER_COMMITTED}
226
221
  */
227
- public async commitParameters( parameters?: ParameterBag ): Promise<VariantParameterizable> {
228
- return super.commitParameters( parameters );
222
+ public async commitParameters( parameters?: ParameterBag ): Promise<Element> {
223
+ if( !parameters ) {
224
+ parameters = {};
225
+ }
226
+ const oldParameters = cloneDeep( this.parameters );
227
+ merge( this.parameters, parameters );
228
+ // handle parameter observers
229
+ let observerPromises: Promise<void | ParameterObserver>[] = [];
230
+ for( const parameter in this.parameters ) {
231
+ const oldParameterValue = oldParameters[parameter];
232
+ const newParameterValue = this.parameters[parameter];
233
+ this.variant.assertParameter( this.variant.inheritedParameterDeclaration, parameter, newParameterValue );
234
+ if( oldParameterValue === newParameterValue ) {
235
+ continue;
236
+ }
237
+ // parameter changed
238
+ const parameterObservers = mergeMaps( this._parameterObservers, this.parameterObservers );
239
+ if( parameterObservers.has( parameter ) ) {
240
+ const observers = parameterObservers.get( parameter )!;
241
+ observerPromises = concat(observerPromises, observers.map( observer => {
242
+ const observerResult = observer( this, oldParameterValue, newParameterValue );
243
+ return Promise.resolve( observerResult ).then( () => {
244
+ this.broadcastEvent( Event.ELEMENT_PARAMETER_COMMITTED,
245
+ this, parameter, oldParameterValue, newParameterValue );
246
+ } );
247
+ } ) );
248
+ }
249
+ }
250
+ await Promise.all( observerPromises );
251
+ return this;
229
252
  }
230
253
 
231
254
  /**
@@ -257,10 +280,9 @@ export class Element extends VariantParameterizable {
257
280
  }
258
281
 
259
282
  /**
260
- * Draws a `ImageBitmap` or `OffscreenCanvas` onto a `paintable` defined via {@link PaintableDefinition}.
283
+ * Draws a image onto a `paintable` defined via {@link PaintableDefinition}.
261
284
  */
262
- public drawPaintable( paintable: string, imageSource: CanvasImageSource ): Element {
263
- const paintableDefinition = this.getPaintableDefinition( paintable );
285
+ public async drawPaintable( paintable: string, imageSource: string ): Promise<Element> {
264
286
  const node = this.getPaintableNode( paintable );
265
287
  if( !(node instanceof AbstractMesh) ) {
266
288
  throw new Error( `The path must be an instance of "AbstractMesh" for paintable "${paintable}" ` +
@@ -275,30 +297,28 @@ export class Element extends VariantParameterizable {
275
297
  node.material.transparencyMode = Material.MATERIAL_ALPHATESTANDBLEND;
276
298
  if( !get( node.metadata, 'dirty.material.texture' ) ) {
277
299
  // inject initial value and mark as dirty
278
- injectNodeMetadata( node, { dirty: { material: { texture: true } } } );
300
+ injectTransformNodeMetadata( node, { dirty: { material: { texture: true } } }, false );
279
301
  }
280
- const widthAndHeight = {
281
- width: imageSource.width,
282
- height: imageSource.height
283
- };
284
- if( isNumber( paintableDefinition.textureOptions ) ) {
285
- widthAndHeight.width = paintableDefinition.textureOptions;
286
- widthAndHeight.height = paintableDefinition.textureOptions;
287
- } else if( isPlainObject( paintableDefinition.textureOptions ) ) {
288
- widthAndHeight.width = paintableDefinition.textureOptions.width;
289
- widthAndHeight.height = paintableDefinition.textureOptions.height;
290
- }
291
- const texture = new DynamicTexture(
292
- `${this.id}.${paintable}.texture`,
293
- widthAndHeight,
294
- this.variant.viewer.scene,
295
- false
296
- );
297
- setMaterialTexture( node, texture, false );
298
- const ctx = texture.getContext();
299
- // flip texture context horizontal with translate and scale
300
- ctx.drawImage( imageSource, 0, 0);
301
- texture.update( false );
302
+
303
+ await new Promise<void>(resolve => {
304
+ const paintableTexture = Texture.CreateFromBase64String(
305
+ imageSource,
306
+ `${this.id}.${paintable}.texture.${this._paintableTextureId}`,
307
+ this.variant.viewer.scene,
308
+ undefined,
309
+ false,
310
+ undefined,
311
+ () => {
312
+ setMaterialTexture( node, paintableTexture, false );
313
+ resolve();
314
+ }
315
+ );
316
+
317
+ // NOTE: Paintable texture need an individual id, otherwise the already existing texture on this id does not get overwritten
318
+ // Maybe think of a disposal logic here in the future
319
+ this._paintableTextureId++;
320
+ });
321
+
302
322
  return this;
303
323
  }
304
324
 
@@ -306,16 +326,15 @@ export class Element extends VariantParameterizable {
306
326
  * Draws a SVG string onto a `paintable` defined via {@link PaintableDefinition}.
307
327
  */
308
328
  public async drawPaintableFromSvg( paintable: string, svgSource: string ): Promise<Element> {
309
- const source = await createImageBitmapFromSvg( svgSource );
310
- return this.drawPaintable( paintable, source );
329
+ const imageUrl = await createImageUrlFromSvg( svgSource );
330
+ return this.drawPaintable( paintable, imageUrl );
311
331
  }
312
332
 
313
333
  /**
314
334
  * Draws an Image from source (URL/URI) onto a `paintable` defined via {@link PaintableDefinition}.
315
335
  */
316
336
  public async drawPaintableFromImgSrc( paintable: string, imgSource: string ): Promise<Element> {
317
- const source = await createImageBitmapFromImgSrc( imgSource );
318
- return this.drawPaintable( paintable, source );
337
+ return this.drawPaintable( paintable, imgSource );
319
338
  }
320
339
 
321
340
  /**
@@ -332,12 +351,12 @@ export class Element extends VariantParameterizable {
332
351
  }
333
352
  if( visible === true ) {
334
353
  element.nodes.forEach( node => {
335
- injectNodeMetadata( node, { visibility: node.isEnabled() } );
354
+ injectTransformNodeMetadata( node, { visibility: node.isEnabled() } );
336
355
  activate( node );
337
356
  } );
338
357
  } else if( visible === false ) {
339
358
  element.nodes.forEach( node => {
340
- injectNodeMetadata( node, { visibility: node.isEnabled() } );
359
+ injectTransformNodeMetadata( node, { visibility: node.isEnabled() } );
341
360
  deactivate( node );
342
361
  } );
343
362
  }
@@ -353,7 +372,7 @@ export class Element extends VariantParameterizable {
353
372
  async ( element: Element, oldValue: ParameterValue, newValue: ParameterValue ) => {
354
373
  const material = element.variant.getMaterial( newValue.toString() );
355
374
  element.nodes.forEach( node => {
356
- assertTransformNode(node, (node: AbstractMesh) => {
375
+ assertTransformNode(node, (node: TransformNode) => {
357
376
  if( node instanceof InstancedMesh ) {
358
377
  throw new Error( `Changing parameter "${Parameter.MATERIAL}" ` +
359
378
  `of an InstancedMesh is not supported. ` +
@@ -368,7 +387,7 @@ export class Element extends VariantParameterizable {
368
387
  async ( element: Element, oldValue: ParameterValue, newValue: ParameterValue ) => {
369
388
  const color = Parameter.parseColor( newValue );
370
389
  element.nodes.forEach( node => {
371
- assertTransformNode(node, (node: AbstractMesh) => {
390
+ assertTransformNode(node, (node: TransformNode) => {
372
391
  if( node instanceof InstancedMesh ) {
373
392
  throw new Error( `Changing parameter "${Parameter.MATERIAL_COLOR}" ` +
374
393
  `of an InstancedMesh is not supported. ` +
@@ -380,7 +399,7 @@ export class Element extends VariantParameterizable {
380
399
  }
381
400
  if( !get( node.metadata, 'dirty.material.color' ) ) {
382
401
  // inject initial value and mark as dirty
383
- injectNodeMetadata( node, { dirty: { material: { color: oldValue } } } );
402
+ injectTransformNodeMetadata( node, { dirty: { material: { color: oldValue } } } );
384
403
  }
385
404
  setMaterialColor( node, color );
386
405
  } );
@@ -390,7 +409,7 @@ export class Element extends VariantParameterizable {
390
409
  async ( element: Element, oldValue: ParameterValue, newValue: ParameterValue ) => {
391
410
  const metallness = Parameter.parseNumber( newValue );
392
411
  element.nodes.forEach( node => {
393
- assertTransformNode(node, (node: AbstractMesh) => {
412
+ assertTransformNode(node, (node: TransformNode) => {
394
413
  if( node instanceof InstancedMesh ) {
395
414
  throw new Error( `Changing parameter "${Parameter.MATERIAL_METALLNESS}" ` +
396
415
  `of an InstancedMesh is not supported. ` +
@@ -402,7 +421,7 @@ export class Element extends VariantParameterizable {
402
421
  }
403
422
  if( !get( node.metadata, 'dirty.material.metallness' ) ) {
404
423
  // inject initial value and mark as dirty
405
- injectNodeMetadata( node, { dirty: { material: { metallness: oldValue } } } );
424
+ injectTransformNodeMetadata( node, { dirty: { material: { metallness: oldValue } } } );
406
425
  }
407
426
  setMaterialMetallness( node, metallness );
408
427
  } );
@@ -412,7 +431,7 @@ export class Element extends VariantParameterizable {
412
431
  async ( element: Element, oldValue: ParameterValue, newValue: ParameterValue ) => {
413
432
  const roughness = Parameter.parseNumber( newValue );
414
433
  element.nodes.forEach( node => {
415
- assertTransformNode(node, (node: AbstractMesh) => {
434
+ assertTransformNode(node, (node: TransformNode) => {
416
435
  if( node instanceof InstancedMesh ) {
417
436
  throw new Error( `Changing parameter "${Parameter.MATERIAL_ROUGHNESS}" ` +
418
437
  `of an InstancedMesh is not supported. ` +
@@ -424,7 +443,7 @@ export class Element extends VariantParameterizable {
424
443
  }
425
444
  if( !get( node.metadata, 'dirty.material.roughness' ) ) {
426
445
  // inject initial value and mark as dirty
427
- injectNodeMetadata( node, { dirty: { material: { roughness: oldValue } } } );
446
+ injectTransformNodeMetadata( node, { dirty: { material: { roughness: oldValue } } } );
428
447
  }
429
448
  setMaterialRoughness( node, roughness );
430
449
  } );
@@ -480,7 +499,7 @@ export class Element extends VariantParameterizable {
480
499
  // Add/Remove meshes to previously created highlight layers.
481
500
  if( highlighted === true ) {
482
501
  element.nodes.forEach( node => {
483
- assertTransformNode(node, (node: AbstractMesh) => {
502
+ assertTransformNode(node, (node: TransformNode) => {
484
503
  if( node instanceof InstancedMesh ) {
485
504
  throw new Error( `Changing parameter "${Parameter.HIGHLIGHTED}" ` +
486
505
  `of an InstancedMesh is not supported. ` +
@@ -507,54 +526,35 @@ export class Element extends VariantParameterizable {
507
526
  this._parameterObservers.set( Parameter.POSITION, [
508
527
  async ( element: Element, oldValue: ParameterValue, newValue: ParameterValue ) => {
509
528
  // we have to deal just with root nodes here due to relative impacts in a node tree
510
- element.nodes.forEach( node => moveTransformNode( node, Parameter.parseVector( newValue ) ) );
529
+ element.nodes.forEach( node => {
530
+ // remember absolute position and reset it before translating
531
+ if( !get( node.metadata, 'position' ) ) {
532
+ node.metadata.position = node.absolutePosition.clone();
533
+ }
534
+ node.setAbsolutePosition( node.metadata.position );
535
+ // move
536
+ const distance = Parameter.parseVector( newValue );
537
+ node.translate( Axis.X, distance.x, Space.WORLD );
538
+ node.translate( Axis.Y, distance.y, Space.WORLD );
539
+ node.translate( Axis.Z, distance.z, Space.WORLD );
540
+ } );
511
541
  }
512
542
  ] );
513
543
  this._parameterObservers.set( Parameter.ROTATION, [
514
544
  async ( element: Element, oldValue: ParameterValue, newValue: ParameterValue ) => {
515
545
  // we have to deal just with root nodes here due to relative impacts in a node tree
516
- element.nodes.forEach( node => rotateTransformNode( node, Parameter.parseRotation( newValue ) ) );
517
- }
518
- ] );
519
- this._parameterObservers.set( Parameter.CAST_SHADOW, [
520
- async ( element: Element, oldValue: ParameterValue, newValue: ParameterValue ) => {
521
- let castShadow;
522
- try {
523
- castShadow = Parameter.parseBoolean( newValue );
524
- } catch( e ) {
525
- return;
526
- }
527
- let lightCsl = element.inheritedParameters[Parameter.CAST_SHADOW_FROM_LIGHTS];
528
- if( ! lightCsl ) {
529
- lightCsl = element.variant.inheritedViewerLights.map( l => l.name ).join( ',' );
530
- }
531
- if( castShadow === true ) {
532
- await this.castShadowValueHandler( lightCsl, addToShadowGenerator );
533
- }
534
- if( castShadow === false ) {
535
- await this.castShadowValueHandler( lightCsl, removeFromShadowGenerator );
536
- }
537
- }
538
- ] );
539
- this._parameterObservers.set( Parameter.CAST_SHADOW_FROM_LIGHTS, [
540
- async ( element: Element, oldValue: ParameterValue, newValue: ParameterValue ) => {
541
- // TODO: Possible performance issue in combination with CAST_SHADOW, since both observers are initially called
542
- // when CAST_SHADOW and CAST_SHADOW_FROM_LIGHTS are defined in the spec.
543
- const lightCsl = element.variant.inheritedViewerLights.map( l => l.name ).join( ',' );
544
- // cleanup all shadow generators
545
- await this.castShadowValueHandler( lightCsl, removeFromShadowGenerator );
546
- if( element.castShadow === true ) {
547
- // if newValue is undefined or '' then set newValue to lightCsl (use all lights)
548
- if( !newValue ) {
549
- newValue = lightCsl;
546
+ element.nodes.forEach( node => {
547
+ // remember absolute rotation and reset it before translating
548
+ if(!get( node.metadata, 'rotation' ) ) {
549
+ node.metadata.rotation = node.rotation.clone();
550
550
  }
551
- await this.castShadowValueHandler( newValue, addToShadowGenerator );
552
- }
553
- }
554
- ] );
555
- this._parameterObservers.set( Parameter.RECEIVE_SHADOWS, [
556
- async ( element: Element, oldValue: ParameterValue, newValue: ParameterValue ) => {
557
- element.nodes.forEach( node => setReceiveShadows( node, Parameter.parseBoolean( newValue ) ) );
551
+ node.rotation = node.metadata.rotation;
552
+ // rotate
553
+ const rotation = Parameter.parseRotation( newValue );
554
+ node.rotate( Axis.X, rotation.x, Space.WORLD );
555
+ node.rotate( Axis.Y, rotation.y, Space.WORLD );
556
+ node.rotate( Axis.Z, rotation.z, Space.WORLD );
557
+ } );
558
558
  }
559
559
  ] );
560
560
  return this;
@@ -603,25 +603,4 @@ export class Element extends VariantParameterizable {
603
603
  } );
604
604
  }
605
605
 
606
- /**
607
- * Handles callback for given light parameter.
608
- */
609
- private async castShadowValueHandler( lightCsl: ParameterValue, mutator: CallableFunction ) {
610
- let lights: Light[] = [];
611
- for( const lightName of Parameter.parseCommaSeparatedList( lightCsl ) ) {
612
- const viewerLight = await this.variant.getViewerLight( lightName );
613
- if( viewerLight ) {
614
- lights.push( viewerLight.light );
615
- }
616
- }
617
- const shadowGenerators = lights
618
- .map( light => light?.getShadowGenerator() as ShadowGenerator )
619
- .filter( Boolean );
620
- shadowGenerators.forEach( generator => {
621
- this.nodes.forEach( node => {
622
- mutator( generator, node );
623
- } );
624
- } );
625
- }
626
-
627
606
  }
@@ -1,7 +1,7 @@
1
1
  import { Parameter } from './parameter';
2
2
  import { ParameterObservable } from './parameterObservable';
3
3
 
4
- export abstract class Parameterizable extends ParameterObservable {
4
+ export abstract class ElementParameterizable extends ParameterObservable {
5
5
 
6
6
  protected parameterDeclaration: ParameterDeclarations = Parameter.declarations;
7
7
 
@@ -55,17 +55,6 @@ export abstract class Parameterizable extends ParameterObservable {
55
55
  return this.parameters[Parameter.ROTATION].toString();
56
56
  }
57
57
 
58
- get castShadow(): boolean | undefined {
59
- if( !(Parameter.CAST_SHADOW in this.parameters) ) {
60
- return undefined;
61
- }
62
- try {
63
- return Parameter.parseBoolean( this.parameters[Parameter.CAST_SHADOW] );
64
- } catch( e ) {
65
- return undefined;
66
- }
67
- }
68
-
69
58
  public async show(): Promise<ParameterObservable> {
70
59
  await this.commitParameter( Parameter.VISIBLE, true );
71
60
  return this;
@@ -262,28 +262,13 @@ export class Event {
262
262
  * * {@link Element}
263
263
  *
264
264
  * Payload:
265
- * * element: {@link Element}
265
+ * * variant: {@link Element}
266
266
  * * parameter: string
267
267
  * * oldValue: string
268
268
  * * newValue: string
269
269
  */
270
270
  public static readonly ELEMENT_PARAMETER_COMMITTED = 'elementParameterCommitted';
271
271
 
272
- /**
273
- * Fired after a parameter on an {@link ViewerLight} has been committed.
274
- *
275
- * Scopes:
276
- * * Global
277
- * * {@link ViewerLight}
278
- *
279
- * Payload:
280
- * * light: {@link ViewerLight}
281
- * * parameter: string
282
- * * oldValue: string
283
- * * newValue: string
284
- */
285
- public static readonly VIEWER_LIGHT_PARAMETER_COMMITTED = 'viewerLightParameterCommitted';
286
-
287
272
  /**
288
273
  * Fired after a parameter on an {@link SceneManager} has been committed.
289
274
  *