@onerjs/core 8.48.4 → 8.48.6

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 (119) hide show
  1. package/Animations/animatable.core.d.ts +13 -0
  2. package/Animations/animatable.core.js +46 -7
  3. package/Animations/animatable.core.js.map +1 -1
  4. package/Cameras/Inputs/geospatialCameraPointersInput.js +10 -8
  5. package/Cameras/Inputs/geospatialCameraPointersInput.js.map +1 -1
  6. package/Cameras/geospatialCameraMovement.js +2 -2
  7. package/Cameras/geospatialCameraMovement.js.map +1 -1
  8. package/FrameGraph/Node/Blocks/Rendering/iblShadowsRendererBlock.d.ts +105 -0
  9. package/FrameGraph/Node/Blocks/Rendering/iblShadowsRendererBlock.js +318 -0
  10. package/FrameGraph/Node/Blocks/Rendering/iblShadowsRendererBlock.js.map +1 -0
  11. package/FrameGraph/Node/Blocks/index.d.ts +1 -0
  12. package/FrameGraph/Node/Blocks/index.js +1 -0
  13. package/FrameGraph/Node/Blocks/index.js.map +1 -1
  14. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsAccumulationTask.d.ts +34 -0
  15. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsAccumulationTask.js +144 -0
  16. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsAccumulationTask.js.map +1 -0
  17. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsSpatialBlurTask.d.ts +26 -0
  18. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsSpatialBlurTask.js +82 -0
  19. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsSpatialBlurTask.js.map +1 -0
  20. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsTracingTask.d.ts +61 -0
  21. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsTracingTask.js +207 -0
  22. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsTracingTask.js.map +1 -0
  23. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsVoxelizationTask.d.ts +104 -0
  24. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsVoxelizationTask.js +218 -0
  25. package/FrameGraph/Tasks/Rendering/iblShadows/iblShadowsVoxelizationTask.js.map +1 -0
  26. package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.d.ts +217 -0
  27. package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.js +640 -0
  28. package/FrameGraph/Tasks/Rendering/iblShadowsRendererTask.js.map +1 -0
  29. package/FrameGraph/frameGraph.js +1 -0
  30. package/FrameGraph/frameGraph.js.map +1 -1
  31. package/FrameGraph/index.d.ts +1 -0
  32. package/FrameGraph/index.js +1 -0
  33. package/FrameGraph/index.js.map +1 -1
  34. package/Materials/PBR/openpbrMaterial.d.ts +13 -2
  35. package/Materials/PBR/openpbrMaterial.js +47 -16
  36. package/Materials/PBR/openpbrMaterial.js.map +1 -1
  37. package/Materials/PBR/pbrBRDFConfiguration.js +1 -1
  38. package/Materials/PBR/pbrBRDFConfiguration.js.map +1 -1
  39. package/Materials/Textures/Filtering/hdrFiltering.js +6 -0
  40. package/Materials/Textures/Filtering/hdrFiltering.js.map +1 -1
  41. package/Materials/Textures/envCubeTexture.js +13 -13
  42. package/Materials/Textures/envCubeTexture.js.map +1 -1
  43. package/Materials/materialHelper.functions.js +1 -1
  44. package/Materials/materialHelper.functions.js.map +1 -1
  45. package/Misc/textureTools.d.ts +3 -1
  46. package/Misc/textureTools.js +74 -13
  47. package/Misc/textureTools.js.map +1 -1
  48. package/Particles/baseParticleSystem.d.ts +33 -1
  49. package/Particles/baseParticleSystem.js +65 -0
  50. package/Particles/baseParticleSystem.js.map +1 -1
  51. package/Particles/computeShaderParticleSystem.js +6 -0
  52. package/Particles/computeShaderParticleSystem.js.map +1 -1
  53. package/Particles/gpuParticleSystem.d.ts +24 -6
  54. package/Particles/gpuParticleSystem.js +85 -36
  55. package/Particles/gpuParticleSystem.js.map +1 -1
  56. package/Particles/particleSystem.d.ts +0 -7
  57. package/Particles/particleSystem.js +3 -15
  58. package/Particles/particleSystem.js.map +1 -1
  59. package/Particles/thinParticleSystem.d.ts +1 -3
  60. package/Particles/thinParticleSystem.js +1 -27
  61. package/Particles/thinParticleSystem.js.map +1 -1
  62. package/Particles/webgl2ParticleSystem.js +7 -0
  63. package/Particles/webgl2ParticleSystem.js.map +1 -1
  64. package/Rendering/IBLShadows/iblShadowsAccumulationPass.js +1 -1
  65. package/Rendering/IBLShadows/iblShadowsAccumulationPass.js.map +1 -1
  66. package/Rendering/IBLShadows/iblShadowsPluginMaterial.d.ts +3 -1
  67. package/Rendering/IBLShadows/iblShadowsPluginMaterial.js +11 -1
  68. package/Rendering/IBLShadows/iblShadowsPluginMaterial.js.map +1 -1
  69. package/Rendering/IBLShadows/iblShadowsRenderPipeline.d.ts +0 -19
  70. package/Rendering/IBLShadows/iblShadowsRenderPipeline.js +21 -65
  71. package/Rendering/IBLShadows/iblShadowsRenderPipeline.js.map +1 -1
  72. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.d.ts +15 -52
  73. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js +129 -220
  74. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js.map +1 -1
  75. package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.js +3 -0
  76. package/Rendering/IBLShadows/iblShadowsVoxelTracingPass.js.map +1 -1
  77. package/Rendering/geometryBufferRenderer.d.ts +14 -5
  78. package/Rendering/geometryBufferRenderer.js +6 -2
  79. package/Rendering/geometryBufferRenderer.js.map +1 -1
  80. package/Rendering/geometryBufferRendererSceneComponent.d.ts +4 -6
  81. package/Rendering/geometryBufferRendererSceneComponent.js.map +1 -1
  82. package/Rendering/iblCdfGenerator.d.ts +10 -0
  83. package/Rendering/iblCdfGenerator.js +52 -17
  84. package/Rendering/iblCdfGenerator.js.map +1 -1
  85. package/Rendering/index.d.ts +0 -6
  86. package/Rendering/index.js +0 -6
  87. package/Rendering/index.js.map +1 -1
  88. package/Shaders/ShadersInclude/openpbrDirectLighting.js +6 -1
  89. package/Shaders/ShadersInclude/openpbrDirectLighting.js.map +1 -1
  90. package/Shaders/ShadersInclude/openpbrEnvironmentLighting.js +1 -1
  91. package/Shaders/ShadersInclude/openpbrEnvironmentLighting.js.map +1 -1
  92. package/Shaders/gpuUpdateParticles.vertex.js +12 -6
  93. package/Shaders/gpuUpdateParticles.vertex.js.map +1 -1
  94. package/Shaders/iblShadowVoxelTracing.fragment.js +5 -1
  95. package/Shaders/iblShadowVoxelTracing.fragment.js.map +1 -1
  96. package/Shaders/iblVoxelGrid.fragment.d.ts +1 -0
  97. package/Shaders/iblVoxelGrid.fragment.js +33 -5
  98. package/Shaders/iblVoxelGrid.fragment.js.map +1 -1
  99. package/Shaders/lod3D.fragment.d.ts +5 -0
  100. package/Shaders/lod3D.fragment.js +13 -0
  101. package/Shaders/lod3D.fragment.js.map +1 -0
  102. package/Shaders/openpbr.fragment.js +5 -0
  103. package/Shaders/openpbr.fragment.js.map +1 -1
  104. package/ShadersWGSL/ShadersInclude/openpbrDirectLighting.js +6 -1
  105. package/ShadersWGSL/ShadersInclude/openpbrDirectLighting.js.map +1 -1
  106. package/ShadersWGSL/ShadersInclude/openpbrEnvironmentLighting.js +1 -1
  107. package/ShadersWGSL/ShadersInclude/openpbrEnvironmentLighting.js.map +1 -1
  108. package/ShadersWGSL/gpuUpdateParticles.compute.js +14 -7
  109. package/ShadersWGSL/gpuUpdateParticles.compute.js.map +1 -1
  110. package/ShadersWGSL/iblShadowVoxelTracing.fragment.js +5 -1
  111. package/ShadersWGSL/iblShadowVoxelTracing.fragment.js.map +1 -1
  112. package/ShadersWGSL/iblVoxelGrid.fragment.js +1 -1
  113. package/ShadersWGSL/iblVoxelGrid.fragment.js.map +1 -1
  114. package/ShadersWGSL/lod3D.fragment.d.ts +5 -0
  115. package/ShadersWGSL/lod3D.fragment.js +13 -0
  116. package/ShadersWGSL/lod3D.fragment.js.map +1 -0
  117. package/ShadersWGSL/openpbr.fragment.js +5 -0
  118. package/ShadersWGSL/openpbr.fragment.js.map +1 -1
  119. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { FactorGradient, ColorGradient, GradientHelper } from "../Misc/gradients.js";
1
+ import { ColorGradient, GradientHelper } from "../Misc/gradients.js";
2
2
  import { Observable } from "../Misc/observable.js";
3
3
  import { Vector3, Matrix, TmpVectors } from "../Maths/math.vector.js";
4
4
  import { Color4, TmpColors } from "../Maths/math.color.js";
@@ -6,6 +6,8 @@ import { Lerp } from "../Maths/math.scalar.functions.js";
6
6
  import { VertexBuffer, Buffer } from "../Buffers/buffer.js";
7
7
  import { BaseParticleSystem } from "./baseParticleSystem.js";
8
8
  import { ParticleSystem } from "./particleSystem.js";
9
+ import { Attractor } from "./attractor.js";
10
+ import { Logger } from "../Misc/logger.js";
9
11
  import { BoxParticleEmitter } from "../Particles/EmitterTypes/boxParticleEmitter.js";
10
12
  import { Scene } from "../scene.js";
11
13
  import { ImageProcessingConfiguration } from "../Materials/imageProcessingConfiguration.js";
@@ -79,6 +81,17 @@ export class GPUParticleSystem extends BaseParticleSystem {
79
81
  set activeParticleCount(value) {
80
82
  this.maxActiveParticleCount = value;
81
83
  }
84
+ /**
85
+ * Add an attractor to the particle system. Attractors are used to change the direction of the particles in the system.
86
+ * @param attractor - The attractor to add to the particle system
87
+ */
88
+ addAttractor(attractor) {
89
+ if (this._attractors.length >= this.maxAttractors) {
90
+ Logger.Warn(`GPU particle system supports a maximum of ${this.maxAttractors} attractors. Ignoring additional attractor.`);
91
+ return;
92
+ }
93
+ super.addAttractor(attractor);
94
+ }
82
95
  /**
83
96
  * Creates a Point Emitter for the particle system (emits directly from the emitter position)
84
97
  * @param direction1 Particles are emitted between the direction1 and direction2 from within the box
@@ -430,23 +443,19 @@ export class GPUParticleSystem extends BaseParticleSystem {
430
443
  drawWrapper.drawContext?.reset();
431
444
  }
432
445
  }
433
- _addFactorGradient(factorGradients, gradient, factor) {
434
- const valueGradient = new FactorGradient(gradient, factor);
435
- factorGradients.push(valueGradient);
436
- this._releaseBuffers();
437
- }
438
446
  /**
439
447
  * Adds a new size gradient
440
448
  * @param gradient defines the gradient to use (between 0 and 1)
441
449
  * @param factor defines the size factor to affect to the specified gradient
450
+ * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
442
451
  * @returns the current particle system
443
452
  */
444
- addSizeGradient(gradient, factor) {
453
+ addSizeGradient(gradient, factor, factor2) {
445
454
  if (!this._sizeGradients) {
446
455
  this._sizeGradients = [];
447
456
  }
448
- this._addFactorGradient(this._sizeGradients, gradient, factor);
449
- this._refreshFactorGradient(this._sizeGradients, "_sizeGradientsTexture", true);
457
+ this._addFactorGradient(this._sizeGradients, gradient, factor, factor2);
458
+ this._refreshFactorGradient(this._sizeGradients, "_sizeGradientsTexture");
450
459
  this._releaseBuffers();
451
460
  return this;
452
461
  }
@@ -460,21 +469,10 @@ export class GPUParticleSystem extends BaseParticleSystem {
460
469
  this._sizeGradientsTexture = null;
461
470
  return this;
462
471
  }
463
- _refreshFactorGradient(factorGradients, textureName, reorder = false) {
472
+ _refreshFactorGradient(factorGradients, textureName) {
464
473
  if (!factorGradients) {
465
474
  return;
466
475
  }
467
- if (reorder) {
468
- factorGradients.sort((a, b) => {
469
- if (a.gradient < b.gradient) {
470
- return -1;
471
- }
472
- else if (a.gradient > b.gradient) {
473
- return 1;
474
- }
475
- return 0;
476
- });
477
- }
478
476
  const that = this;
479
477
  if (that[textureName]) {
480
478
  that[textureName].dispose();
@@ -485,14 +483,15 @@ export class GPUParticleSystem extends BaseParticleSystem {
485
483
  * Adds a new angular speed gradient
486
484
  * @param gradient defines the gradient to use (between 0 and 1)
487
485
  * @param factor defines the angular speed to affect to the specified gradient
486
+ * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
488
487
  * @returns the current particle system
489
488
  */
490
- addAngularSpeedGradient(gradient, factor) {
489
+ addAngularSpeedGradient(gradient, factor, factor2) {
491
490
  if (!this._angularSpeedGradients) {
492
491
  this._angularSpeedGradients = [];
493
492
  }
494
- this._addFactorGradient(this._angularSpeedGradients, gradient, factor);
495
- this._refreshFactorGradient(this._angularSpeedGradients, "_angularSpeedGradientsTexture", true);
493
+ this._addFactorGradient(this._angularSpeedGradients, gradient, factor, factor2);
494
+ this._refreshFactorGradient(this._angularSpeedGradients, "_angularSpeedGradientsTexture");
496
495
  this._releaseBuffers();
497
496
  return this;
498
497
  }
@@ -510,14 +509,15 @@ export class GPUParticleSystem extends BaseParticleSystem {
510
509
  * Adds a new velocity gradient
511
510
  * @param gradient defines the gradient to use (between 0 and 1)
512
511
  * @param factor defines the velocity to affect to the specified gradient
512
+ * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
513
513
  * @returns the current particle system
514
514
  */
515
- addVelocityGradient(gradient, factor) {
515
+ addVelocityGradient(gradient, factor, factor2) {
516
516
  if (!this._velocityGradients) {
517
517
  this._velocityGradients = [];
518
518
  }
519
- this._addFactorGradient(this._velocityGradients, gradient, factor);
520
- this._refreshFactorGradient(this._velocityGradients, "_velocityGradientsTexture", true);
519
+ this._addFactorGradient(this._velocityGradients, gradient, factor, factor2);
520
+ this._refreshFactorGradient(this._velocityGradients, "_velocityGradientsTexture");
521
521
  this._releaseBuffers();
522
522
  return this;
523
523
  }
@@ -535,14 +535,15 @@ export class GPUParticleSystem extends BaseParticleSystem {
535
535
  * Adds a new limit velocity gradient
536
536
  * @param gradient defines the gradient to use (between 0 and 1)
537
537
  * @param factor defines the limit velocity value to affect to the specified gradient
538
+ * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
538
539
  * @returns the current particle system
539
540
  */
540
- addLimitVelocityGradient(gradient, factor) {
541
+ addLimitVelocityGradient(gradient, factor, factor2) {
541
542
  if (!this._limitVelocityGradients) {
542
543
  this._limitVelocityGradients = [];
543
544
  }
544
- this._addFactorGradient(this._limitVelocityGradients, gradient, factor);
545
- this._refreshFactorGradient(this._limitVelocityGradients, "_limitVelocityGradientsTexture", true);
545
+ this._addFactorGradient(this._limitVelocityGradients, gradient, factor, factor2);
546
+ this._refreshFactorGradient(this._limitVelocityGradients, "_limitVelocityGradientsTexture");
546
547
  this._releaseBuffers();
547
548
  return this;
548
549
  }
@@ -560,14 +561,15 @@ export class GPUParticleSystem extends BaseParticleSystem {
560
561
  * Adds a new drag gradient
561
562
  * @param gradient defines the gradient to use (between 0 and 1)
562
563
  * @param factor defines the drag value to affect to the specified gradient
564
+ * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
563
565
  * @returns the current particle system
564
566
  */
565
- addDragGradient(gradient, factor) {
567
+ addDragGradient(gradient, factor, factor2) {
566
568
  if (!this._dragGradients) {
567
569
  this._dragGradients = [];
568
570
  }
569
- this._addFactorGradient(this._dragGradients, gradient, factor);
570
- this._refreshFactorGradient(this._dragGradients, "_dragGradientsTexture", true);
571
+ this._addFactorGradient(this._dragGradients, gradient, factor, factor2);
572
+ this._refreshFactorGradient(this._dragGradients, "_dragGradientsTexture");
571
573
  this._releaseBuffers();
572
574
  return this;
573
575
  }
@@ -817,6 +819,7 @@ export class GPUParticleSystem extends BaseParticleSystem {
817
819
  this._currentActiveCount = 0;
818
820
  this._isAnimationSheetEnabled = isAnimationSheetEnabled;
819
821
  this._emitRateControl = !!options.emitRateControl;
822
+ this.maxAttractors = options.maxAttractors ?? 8;
820
823
  this.particleEmitterType = new BoxParticleEmitter();
821
824
  // Random data
822
825
  const maxTextureSize = Math.min(this._engine.getCaps().maxTextureSize, fullOptions.randomTextureSize);
@@ -1123,6 +1126,10 @@ export class GPUParticleSystem extends BaseParticleSystem {
1123
1126
  if (this.isLocal) {
1124
1127
  defines += "\n#define LOCAL";
1125
1128
  }
1129
+ if (this._attractors.length > 0) {
1130
+ defines += "\n#define ATTRACTORS";
1131
+ defines += "\n#define MAX_ATTRACTORS " + this.maxAttractors;
1132
+ }
1126
1133
  if (this._emitRateControl) {
1127
1134
  defines += "\n#define EMITRATECTRL";
1128
1135
  }
@@ -1288,14 +1295,17 @@ export class GPUParticleSystem extends BaseParticleSystem {
1288
1295
  if (!factorGradients || !factorGradients.length || texture) {
1289
1296
  return;
1290
1297
  }
1291
- const data = new Float32Array(this._rawTextureWidth);
1298
+ const data = new Float32Array(this._rawTextureWidth * 2);
1292
1299
  for (let x = 0; x < this._rawTextureWidth; x++) {
1293
1300
  const ratio = x / this._rawTextureWidth;
1294
1301
  GradientHelper.GetCurrentGradient(ratio, factorGradients, (currentGradient, nextGradient, scale) => {
1295
- data[x] = Lerp(currentGradient.factor1, nextGradient.factor1, scale);
1302
+ const cg = currentGradient;
1303
+ const ng = nextGradient;
1304
+ data[x * 2] = Lerp(cg.factor1, ng.factor1, scale);
1305
+ data[x * 2 + 1] = Lerp(cg.factor2 ?? cg.factor1, ng.factor2 ?? ng.factor1, scale);
1296
1306
  });
1297
1307
  }
1298
- this[textureName] = RawTexture.CreateRTexture(data, this._rawTextureWidth, 1, this._scene || this._engine, false, false, 1);
1308
+ this[textureName] = new RawTexture(data, this._rawTextureWidth, 1, 7, this._scene || this._engine, false, false, 1, 1);
1299
1309
  this[textureName].name = textureName.substring(1);
1300
1310
  }
1301
1311
  _createSizeGradientTexture() {
@@ -1460,6 +1470,27 @@ export class GPUParticleSystem extends BaseParticleSystem {
1460
1470
  if (!this.isLocal) {
1461
1471
  this._updateBuffer.setMatrix("emitterWM", emitterWM);
1462
1472
  }
1473
+ if (this._attractors.length > 0) {
1474
+ this._updateBuffer.setInt("attractorCount", this._attractors.length);
1475
+ // Compute inverse world matrix once for all attractors when in local space
1476
+ let invWorld;
1477
+ if (this.isLocal) {
1478
+ invWorld = TmpVectors.Matrix[1];
1479
+ emitterWM.invertToRef(invWorld);
1480
+ }
1481
+ for (let i = 0; i < this._attractors.length; i++) {
1482
+ const attractor = this._attractors[i];
1483
+ const name = "attractorPositionAndStrength[" + i + "]";
1484
+ if (invWorld) {
1485
+ const localPos = TmpVectors.Vector3[0];
1486
+ Vector3.TransformCoordinatesToRef(attractor.position, invWorld, localPos);
1487
+ this._updateBuffer.setFloat4(name, localPos.x, localPos.y, localPos.z, attractor.strength);
1488
+ }
1489
+ else {
1490
+ this._updateBuffer.setFloat4(name, attractor.position.x, attractor.position.y, attractor.position.z, attractor.strength);
1491
+ }
1492
+ }
1493
+ }
1463
1494
  this._platform.updateParticleBuffer(this._targetIndex, this._targetBuffer, this._currentActiveCount);
1464
1495
  // Switch VAOs
1465
1496
  this._targetIndex++;
@@ -1750,12 +1781,20 @@ export class GPUParticleSystem extends BaseParticleSystem {
1750
1781
  serializationObject.activeParticleCount = this.activeParticleCount;
1751
1782
  serializationObject.randomTextureSize = this._randomTextureSize;
1752
1783
  serializationObject.emitRateControl = this._emitRateControl;
1784
+ serializationObject.maxAttractors = this.maxAttractors;
1753
1785
  serializationObject.customShader = this.customShader;
1754
1786
  serializationObject.preventAutoStart = this.preventAutoStart;
1755
1787
  serializationObject.worldOffset = this.worldOffset.asArray();
1756
1788
  if (this.metadata) {
1757
1789
  serializationObject.metadata = this.metadata;
1758
1790
  }
1791
+ // Attractors
1792
+ if (this._attractors.length > 0) {
1793
+ serializationObject.attractors = [];
1794
+ for (const attractor of this._attractors) {
1795
+ serializationObject.attractors.push(attractor.serialize());
1796
+ }
1797
+ }
1759
1798
  return serializationObject;
1760
1799
  }
1761
1800
  /**
@@ -1782,6 +1821,7 @@ export class GPUParticleSystem extends BaseParticleSystem {
1782
1821
  capacity: capacity || parsedParticleSystem.capacity,
1783
1822
  randomTextureSize: parsedParticleSystem.randomTextureSize,
1784
1823
  emitRateControl: parsedParticleSystem.emitRateControl,
1824
+ maxAttractors: parsedParticleSystem.maxAttractors,
1785
1825
  }, sceneOrEngine, null, parsedParticleSystem.isAnimationSheetEnabled);
1786
1826
  particleSystem._rootUrl = rootUrl;
1787
1827
  if (parsedParticleSystem.customShader && engine.createEffectForParticles) {
@@ -1808,6 +1848,15 @@ export class GPUParticleSystem extends BaseParticleSystem {
1808
1848
  if (parsedParticleSystem.metadata) {
1809
1849
  particleSystem.metadata = parsedParticleSystem.metadata;
1810
1850
  }
1851
+ // Attractors
1852
+ if (parsedParticleSystem.attractors) {
1853
+ for (const attractorData of parsedParticleSystem.attractors) {
1854
+ const attractor = new Attractor();
1855
+ attractor.position = Vector3.FromArray(attractorData.position);
1856
+ attractor.strength = attractorData.strength;
1857
+ particleSystem.addAttractor(attractor);
1858
+ }
1859
+ }
1811
1860
  if (!doNotStart && !particleSystem.preventAutoStart) {
1812
1861
  particleSystem.start();
1813
1862
  }