@onerjs/core 8.31.0 → 8.31.2

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 (124) hide show
  1. package/Animations/animationGroup.js +1 -4
  2. package/Animations/animationGroup.js.map +1 -1
  3. package/Behaviors/Cameras/interpolatingBehavior.d.ts +8 -2
  4. package/Behaviors/Cameras/interpolatingBehavior.js +58 -6
  5. package/Behaviors/Cameras/interpolatingBehavior.js.map +1 -1
  6. package/Cameras/Inputs/freeCameraDeviceOrientationInput.js +11 -9
  7. package/Cameras/Inputs/freeCameraDeviceOrientationInput.js.map +1 -1
  8. package/Cameras/Inputs/geospatialCameraKeyboardInput.d.ts +81 -0
  9. package/Cameras/Inputs/geospatialCameraKeyboardInput.js +223 -0
  10. package/Cameras/Inputs/geospatialCameraKeyboardInput.js.map +1 -0
  11. package/Cameras/Inputs/geospatialCameraMouseWheelInput.js +1 -1
  12. package/Cameras/Inputs/geospatialCameraMouseWheelInput.js.map +1 -1
  13. package/Cameras/Inputs/geospatialCameraPointersInput.d.ts +8 -20
  14. package/Cameras/Inputs/geospatialCameraPointersInput.js +35 -75
  15. package/Cameras/Inputs/geospatialCameraPointersInput.js.map +1 -1
  16. package/Cameras/Limits/geospatialLimits.d.ts +60 -0
  17. package/Cameras/Limits/geospatialLimits.js +89 -0
  18. package/Cameras/Limits/geospatialLimits.js.map +1 -0
  19. package/Cameras/Stereoscopic/stereoscopicScreenUniversalCamera.js +1 -1
  20. package/Cameras/Stereoscopic/stereoscopicScreenUniversalCamera.js.map +1 -1
  21. package/Cameras/VR/vrExperienceHelper.js +2 -2
  22. package/Cameras/VR/vrExperienceHelper.js.map +1 -1
  23. package/Cameras/cameraMovement.js +1 -1
  24. package/Cameras/cameraMovement.js.map +1 -1
  25. package/Cameras/deviceOrientationCamera.js +5 -3
  26. package/Cameras/deviceOrientationCamera.js.map +1 -1
  27. package/Cameras/flyCamera.d.ts +2 -1
  28. package/Cameras/flyCamera.js.map +1 -1
  29. package/Cameras/geospatialCamera.d.ts +78 -49
  30. package/Cameras/geospatialCamera.js +210 -191
  31. package/Cameras/geospatialCamera.js.map +1 -1
  32. package/Cameras/geospatialCameraInputsManager.d.ts +5 -0
  33. package/Cameras/geospatialCameraInputsManager.js +9 -0
  34. package/Cameras/geospatialCameraInputsManager.js.map +1 -1
  35. package/Cameras/geospatialCameraMovement.d.ts +66 -0
  36. package/Cameras/geospatialCameraMovement.js +199 -0
  37. package/Cameras/geospatialCameraMovement.js.map +1 -0
  38. package/Cameras/targetCamera.d.ts +1 -1
  39. package/Cameras/targetCamera.js +2 -2
  40. package/Cameras/targetCamera.js.map +1 -1
  41. package/Engines/Native/nativeInterfaces.d.ts +14 -6
  42. package/Engines/Native/nativeInterfaces.js +6 -1
  43. package/Engines/Native/nativeInterfaces.js.map +1 -1
  44. package/Engines/abstractEngine.js +2 -2
  45. package/Engines/abstractEngine.js.map +1 -1
  46. package/Engines/nativeEngine.js +2 -2
  47. package/Engines/nativeEngine.js.map +1 -1
  48. package/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.js +1 -1
  49. package/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.js.map +1 -1
  50. package/FlowGraph/flowGraphMath.d.ts +25 -0
  51. package/FlowGraph/flowGraphMath.js +40 -0
  52. package/FlowGraph/flowGraphMath.js.map +1 -0
  53. package/Materials/GaussianSplatting/gaussianSplattingMaterial.js +1 -1
  54. package/Materials/GaussianSplatting/gaussianSplattingMaterial.js.map +1 -1
  55. package/Materials/Node/Blocks/GaussianSplatting/gaussianSplattingBlock.js +5 -1
  56. package/Materials/Node/Blocks/GaussianSplatting/gaussianSplattingBlock.js.map +1 -1
  57. package/Materials/Node/Blocks/GaussianSplatting/splatReaderBlock.js +6 -5
  58. package/Materials/Node/Blocks/GaussianSplatting/splatReaderBlock.js.map +1 -1
  59. package/Materials/shaderMaterial.js +4 -2
  60. package/Materials/shaderMaterial.js.map +1 -1
  61. package/Maths/math.vector.functions.d.ts +5 -24
  62. package/Maths/math.vector.functions.js +32 -35
  63. package/Maths/math.vector.functions.js.map +1 -1
  64. package/Meshes/GaussianSplatting/gaussianSplattingMesh.d.ts +1 -0
  65. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js +51 -16
  66. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js.map +1 -1
  67. package/Meshes/csg2.js +1 -1
  68. package/Meshes/csg2.js.map +1 -1
  69. package/Meshes/thinInstanceMesh.js +15 -0
  70. package/Meshes/thinInstanceMesh.js.map +1 -1
  71. package/Misc/fileTools.js.map +1 -1
  72. package/Misc/tools.d.ts +3 -0
  73. package/Misc/tools.js +43 -4
  74. package/Misc/tools.js.map +1 -1
  75. package/Particles/Node/Blocks/Update/basicPositionUpdateBlock.js +2 -2
  76. package/Particles/Node/Blocks/Update/basicPositionUpdateBlock.js.map +1 -1
  77. package/Particles/Node/Blocks/particleInputBlock.js +1 -0
  78. package/Particles/Node/Blocks/particleInputBlock.js.map +1 -1
  79. package/Particles/Node/Blocks/systemBlock.d.ts +8 -8
  80. package/Particles/Node/Blocks/systemBlock.js +12 -12
  81. package/Particles/Node/Blocks/systemBlock.js.map +1 -1
  82. package/Particles/Node/Enums/nodeParticleContextualSources.d.ts +3 -1
  83. package/Particles/Node/Enums/nodeParticleContextualSources.js +2 -0
  84. package/Particles/Node/Enums/nodeParticleContextualSources.js.map +1 -1
  85. package/Particles/Node/nodeParticleBuildState.d.ts +5 -5
  86. package/Particles/Node/nodeParticleBuildState.js +9 -7
  87. package/Particles/Node/nodeParticleBuildState.js.map +1 -1
  88. package/Particles/Node/nodeParticleSystemSet.helper.js +288 -149
  89. package/Particles/Node/nodeParticleSystemSet.helper.js.map +1 -1
  90. package/Particles/particle.d.ts +4 -0
  91. package/Particles/particle.js +2 -0
  92. package/Particles/particle.js.map +1 -1
  93. package/Particles/thinParticleSystem.d.ts +0 -4
  94. package/Particles/thinParticleSystem.function.d.ts +1 -1
  95. package/Particles/thinParticleSystem.function.js +9 -6
  96. package/Particles/thinParticleSystem.function.js.map +1 -1
  97. package/Particles/thinParticleSystem.js +1 -3
  98. package/Particles/thinParticleSystem.js.map +1 -1
  99. package/Shaders/ShadersInclude/gaussianSplatting.js +5 -1
  100. package/Shaders/ShadersInclude/gaussianSplatting.js.map +1 -1
  101. package/Shaders/ShadersInclude/gaussianSplattingUboDeclaration.js +2 -1
  102. package/Shaders/ShadersInclude/gaussianSplattingUboDeclaration.js.map +1 -1
  103. package/Shaders/ShadersInclude/gaussianSplattingVertexDeclaration.js +1 -1
  104. package/Shaders/ShadersInclude/gaussianSplattingVertexDeclaration.js.map +1 -1
  105. package/Shaders/gaussianSplatting.vertex.js +3 -3
  106. package/Shaders/gaussianSplatting.vertex.js.map +1 -1
  107. package/Shaders/gaussianSplattingDepth.vertex.js +2 -2
  108. package/Shaders/gaussianSplattingDepth.vertex.js.map +1 -1
  109. package/ShadersWGSL/ShadersInclude/gaussianSplatting.js +35 -1
  110. package/ShadersWGSL/ShadersInclude/gaussianSplatting.js.map +1 -1
  111. package/ShadersWGSL/ShadersInclude/gaussianSplattingUboDeclaration.js +2 -1
  112. package/ShadersWGSL/ShadersInclude/gaussianSplattingUboDeclaration.js.map +1 -1
  113. package/ShadersWGSL/ShadersInclude/gaussianSplattingVertexDeclaration.js +1 -2
  114. package/ShadersWGSL/ShadersInclude/gaussianSplattingVertexDeclaration.js.map +1 -1
  115. package/ShadersWGSL/gaussianSplatting.vertex.js +3 -3
  116. package/ShadersWGSL/gaussianSplatting.vertex.js.map +1 -1
  117. package/ShadersWGSL/gaussianSplattingDepth.vertex.js +2 -2
  118. package/ShadersWGSL/gaussianSplattingDepth.vertex.js.map +1 -1
  119. package/XR/webXRCamera.d.ts +5 -1
  120. package/XR/webXRCamera.js +2 -2
  121. package/XR/webXRCamera.js.map +1 -1
  122. package/XR/webXRExperienceHelper.js +1 -1
  123. package/XR/webXRExperienceHelper.js.map +1 -1
  124. package/package.json +1 -1
@@ -10,6 +10,8 @@ import { ParticleMathBlock, ParticleMathBlockOperations } from "./Blocks/particl
10
10
  import { ParticleRandomBlock, ParticleRandomBlockLocks } from "./Blocks/particleRandomBlock.js";
11
11
  import { ParticleTextureSourceBlock } from "./Blocks/particleSourceTextureBlock.js";
12
12
  import { SystemBlock } from "./Blocks/systemBlock.js";
13
+ import { ParticleVectorLengthBlock } from "./Blocks/particleVectorLengthBlock.js";
14
+ import { ParticleConditionBlock, ParticleConditionBlockTests } from "./Blocks/Conditions/particleConditionBlock.js";
13
15
  import { CreateParticleBlock } from "./Blocks/Emitters/createParticleBlock.js";
14
16
  import { BoxShapeBlock } from "./Blocks/Emitters/boxShapeBlock.js";
15
17
  import { ConeShapeBlock } from "./Blocks/Emitters/coneShapeBlock.js";
@@ -42,19 +44,16 @@ export async function ConvertToNodeParticleSystemSetAsync(name, particleSystemsL
42
44
  return nodeParticleSystemSet;
43
45
  }
44
46
  async function _ExtractDatafromParticleSystemAsync(newSet, oldSystem, context) {
45
- // CreateParticle block
46
- const createParticleBlock = _CreateParticleBlockGroup(oldSystem, context);
47
+ // CreateParticle block group
48
+ const createParticleOutput = _CreateParticleBlockGroup(oldSystem, context);
47
49
  // Emitter Shape block
48
- const shapeBlock = _EmitterShapeBlock(oldSystem);
49
- createParticleBlock.particle.connectTo(shapeBlock.particle);
50
- // Update the particle position
51
- const positionUpdatedParticle = _UpdateParticleBlockGroup(shapeBlock.output, oldSystem, context);
52
- // Color update
53
- const colorUpdateBlock = _CreateColorUpdateBlock(oldSystem, createParticleBlock);
54
- positionUpdatedParticle.connectTo(colorUpdateBlock.particle);
50
+ const shapeOutput = _EmitterShapeBlock(oldSystem);
51
+ createParticleOutput.particle.connectTo(shapeOutput.particle);
52
+ // UpdateParticle block group
53
+ const updateParticleOutput = _UpdateParticleBlockGroup(shapeOutput.output, oldSystem, context);
55
54
  // System block
56
55
  const newSystem = _SystemBlockGroup(oldSystem, context);
57
- colorUpdateBlock.output.connectTo(newSystem.particle);
56
+ updateParticleOutput.connectTo(newSystem.particle);
58
57
  // Register
59
58
  newSet.systemBlocks.push(newSystem);
60
59
  }
@@ -89,27 +88,16 @@ function _SystemBlockGroup(oldSystem, context) {
89
88
  }
90
89
  // ------------- CREATE PARTICLE FUNCTIONS -------------
91
90
  // The creation of the different properties follows the order they are added to the CreationQueue in ThinParticleSystem:
92
- // Lifetime, Position, Direction, Emit, Size, Scale/StartSize, Angle, Velocity, VelocityLimit, Color, Drag, Noise, ColorDead, Ramp, Sheet
91
+ // Lifetime, Emit Power, Size, Scale/StartSize, Angle, Color, Noise, ColorDead, Ramp, Sheet
93
92
  function _CreateParticleBlockGroup(oldSystem, context) {
94
- // Create particle
93
+ // Create particle block
95
94
  const createParticleBlock = new CreateParticleBlock("Create Particle");
96
- // Lifetime
97
95
  _CreateParticleLifetimeBlockGroup(oldSystem, context).connectTo(createParticleBlock.lifeTime);
98
- // Emit power (Speed)
99
- const randomEmitPowerBlock = new ParticleRandomBlock("Random Emit Power");
100
- _CreateAndConnectInput("Min Emit Power", oldSystem.minEmitPower, randomEmitPowerBlock.min);
101
- _CreateAndConnectInput("Max Emit Power", oldSystem.maxEmitPower, randomEmitPowerBlock.max);
102
- randomEmitPowerBlock.output.connectTo(createParticleBlock.emitPower);
103
- // Size
96
+ _CreateParticleEmitPowerBlockGroup(oldSystem).connectTo(createParticleBlock.emitPower);
104
97
  _CreateParticleSizeBlockGroup(oldSystem, context).connectTo(createParticleBlock.size);
105
- // Scale/Start Size
106
98
  _CreateParticleScaleBlockGroup(oldSystem, context).connectTo(createParticleBlock.scale);
107
- // Angle (rotation)
108
- const randomRotationBlock = new ParticleRandomBlock("Random Rotation");
109
- _CreateAndConnectInput("Min Rotation", oldSystem.minInitialRotation, randomRotationBlock.min);
110
- _CreateAndConnectInput("Max Rotation", oldSystem.maxInitialRotation, randomRotationBlock.max);
111
- randomRotationBlock.output.connectTo(createParticleBlock.angle);
112
- // Color is handled when we do the color update block to manage gradients
99
+ _CreateParticleAngleBlockGroup(oldSystem).connectTo(createParticleBlock.angle);
100
+ _CreateParticleColorBlockGroup(oldSystem, context).connectTo(createParticleBlock.color);
113
101
  // Dead color
114
102
  _CreateAndConnectInput("Dead Color", oldSystem.colorDead, createParticleBlock.colorDead);
115
103
  return createParticleBlock;
@@ -133,16 +121,27 @@ function _CreateParticleLifetimeBlockGroup(oldSystem, context) {
133
121
  return randomLifetimeBlock.output;
134
122
  }
135
123
  }
124
+ /**
125
+ * Creates the group of blocks that represent the particle emit power
126
+ * @param oldSystem The old particle system to convert
127
+ * @returns The output of the group of blocks that represent the particle emit power
128
+ */
129
+ function _CreateParticleEmitPowerBlockGroup(oldSystem) {
130
+ const randomEmitPowerBlock = new ParticleRandomBlock("Random Emit Power");
131
+ _CreateAndConnectInput("Min Emit Power", oldSystem.minEmitPower, randomEmitPowerBlock.min);
132
+ _CreateAndConnectInput("Max Emit Power", oldSystem.maxEmitPower, randomEmitPowerBlock.max);
133
+ return randomEmitPowerBlock.output;
134
+ }
136
135
  /**
137
136
  * Creates the group of blocks that represent the particle size
138
137
  * @param oldSystem The old particle system to convert
139
138
  * @param context The context of the current conversion
140
- * @returns The output of the group of blocks that represent the particle lifetime
139
+ * @returns The output of the group of blocks that represent the particle size
141
140
  */
142
141
  function _CreateParticleSizeBlockGroup(oldSystem, context) {
143
142
  if (oldSystem._sizeGradients && oldSystem._sizeGradients.length > 0) {
144
- const sizeGradientBlockGroupOutput = _CreateParticleSizeGradientBlockGroup(oldSystem._sizeGradients, context);
145
- return sizeGradientBlockGroupOutput;
143
+ context.sizeGradientValue0Output = _CreateParticleInitialValueFromGradient(oldSystem._sizeGradients);
144
+ return context.sizeGradientValue0Output;
146
145
  }
147
146
  else {
148
147
  const randomSizeBlock = new ParticleRandomBlock("Random size");
@@ -151,6 +150,12 @@ function _CreateParticleSizeBlockGroup(oldSystem, context) {
151
150
  return randomSizeBlock.output;
152
151
  }
153
152
  }
153
+ /**
154
+ * Creates the group of blocks that represent the particle scale
155
+ * @param oldSystem The old particle system to convert
156
+ * @param context The context of the current conversion
157
+ * @returns The output of the group of blocks that represent the particle scale
158
+ */
154
159
  function _CreateParticleScaleBlockGroup(oldSystem, context) {
155
160
  // Create the random scale
156
161
  const randomScaleBlock = new ParticleRandomBlock("Random Scale");
@@ -171,27 +176,54 @@ function _CreateParticleScaleBlockGroup(oldSystem, context) {
171
176
  return randomScaleBlock.output;
172
177
  }
173
178
  }
174
- function _CreateParticleSizeGradientBlockGroup(sizeGradients, context) {
175
- if (sizeGradients.length === 0) {
176
- throw new Error("No size gradients provided.");
179
+ /**
180
+ * Creates the group of blocks that represent the particle angle (rotation)
181
+ * @param oldSystem The old particle system to convert
182
+ * @returns The output of the group of blocks that represent the particle angle (rotation)
183
+ */
184
+ function _CreateParticleAngleBlockGroup(oldSystem) {
185
+ const randomRotationBlock = new ParticleRandomBlock("Random Rotation");
186
+ _CreateAndConnectInput("Min Rotation", oldSystem.minInitialRotation, randomRotationBlock.min);
187
+ _CreateAndConnectInput("Max Rotation", oldSystem.maxInitialRotation, randomRotationBlock.max);
188
+ return randomRotationBlock.output;
189
+ }
190
+ /**
191
+ * Creates the group of blocks that represent the particle color
192
+ * @param oldSystem The old particle system to convert
193
+ * @param context The context of the current conversion
194
+ * @returns The output of the group of blocks that represent the particle color
195
+ */
196
+ function _CreateParticleColorBlockGroup(oldSystem, context) {
197
+ if (oldSystem._colorGradients && oldSystem._colorGradients.length > 0) {
198
+ context.colorGradientValue0Output = _CreateParticleInitialValueFromGradient(oldSystem._colorGradients);
199
+ return context.colorGradientValue0Output;
200
+ }
201
+ else {
202
+ const randomColorBlock = new ParticleRandomBlock("Random color");
203
+ _CreateAndConnectInput("Color 1", oldSystem.color1, randomColorBlock.min);
204
+ _CreateAndConnectInput("Color 2", oldSystem.color2, randomColorBlock.max);
205
+ return randomColorBlock.output;
177
206
  }
178
- const initialParticleSize = _CreateSizeFromGradientStep(sizeGradients[0], 0);
179
- context.sizeGradientValue0Output = initialParticleSize;
180
- return initialParticleSize;
181
207
  }
182
- function _CreateSizeFromGradientStep(gradientStep, index) {
183
- if (gradientStep.factor2 !== undefined) {
208
+ function _CreateParticleInitialValueFromGradient(gradients) {
209
+ if (gradients.length === 0) {
210
+ throw new Error("No gradients provided.");
211
+ }
212
+ const gradientStep = gradients[0];
213
+ const value1 = gradientStep.factor1 ?? gradientStep.color1;
214
+ const value2 = gradientStep.factor2 ?? gradientStep.color2;
215
+ if (value2 !== undefined) {
184
216
  // Create a random between value1 and value2
185
- const randomBlock = new ParticleRandomBlock("Random Value " + index);
217
+ const randomBlock = new ParticleRandomBlock("Random Value 0");
186
218
  randomBlock.lockMode = ParticleRandomBlockLocks.OncePerParticle;
187
- _CreateAndConnectInput("Value 1", gradientStep.factor1, randomBlock.min);
188
- _CreateAndConnectInput("Value 2", gradientStep.factor2, randomBlock.max);
219
+ _CreateAndConnectInput("Value 1", value1, randomBlock.min);
220
+ _CreateAndConnectInput("Value 2", value2, randomBlock.max);
189
221
  return randomBlock.output;
190
222
  }
191
223
  else {
192
224
  // Single value
193
225
  const sizeBlock = new ParticleInputBlock("Value");
194
- sizeBlock.value = gradientStep.factor1;
226
+ sizeBlock.value = value1;
195
227
  return sizeBlock.output;
196
228
  }
197
229
  }
@@ -332,38 +364,184 @@ function _EmitterShapeBlock(oldSystem) {
332
364
  * @returns The output connection point after all updates have been applied
333
365
  */
334
366
  function _UpdateParticleBlockGroup(inputParticle, oldSystem, context) {
335
- let outputUpdate = inputParticle;
336
- if (oldSystem.minAngularSpeed !== 0 || oldSystem.maxAngularSpeed !== 0) {
337
- outputUpdate = _UpdateParticleAngularSpeedBlockGroup(outputUpdate, oldSystem.minAngularSpeed, oldSystem.maxAngularSpeed);
367
+ let updateBlockGroupOutput = inputParticle;
368
+ updateBlockGroupOutput = _UpdateParticleColorBlockGroup(updateBlockGroupOutput, oldSystem._colorGradients, context);
369
+ updateBlockGroupOutput = _UpdateParticleAngleBlockGroup(updateBlockGroupOutput, oldSystem, context);
370
+ if (oldSystem._velocityGradients && oldSystem._velocityGradients.length > 0) {
371
+ context.scaledDirection = _UpdateParticleVelocityGradientBlockGroup(oldSystem._velocityGradients, context);
372
+ }
373
+ if (oldSystem._dragGradients && oldSystem._dragGradients.length > 0) {
374
+ context.scaledDirection = _UpdateParticleDragGradientBlockGroup(oldSystem._dragGradients, context);
375
+ }
376
+ updateBlockGroupOutput = _UpdateParticlePositionBlockGroup(updateBlockGroupOutput, oldSystem.isLocal, context);
377
+ if (oldSystem._limitVelocityGradients && oldSystem._limitVelocityGradients.length > 0 && oldSystem.limitVelocityDamping !== 0) {
378
+ updateBlockGroupOutput = _UpdateParticleVelocityLimitGradientBlockGroup(updateBlockGroupOutput, oldSystem._limitVelocityGradients, oldSystem.limitVelocityDamping, context);
338
379
  }
339
- outputUpdate = _UpdateParticlePositionBlockGroup(outputUpdate, oldSystem.isLocal);
340
380
  if (oldSystem._sizeGradients && oldSystem._sizeGradients.length > 0) {
341
- outputUpdate = _UpdateParticleSizeGradientBlockGroup(outputUpdate, oldSystem._sizeGradients, context);
381
+ updateBlockGroupOutput = _UpdateParticleSizeGradientBlockGroup(updateBlockGroupOutput, oldSystem._sizeGradients, context);
342
382
  }
343
383
  if (oldSystem.gravity.equalsToFloats(0, 0, 0) === false) {
344
- outputUpdate = _UpdateParticleGravityBlockGroup(outputUpdate, oldSystem.gravity);
384
+ updateBlockGroupOutput = _UpdateParticleGravityBlockGroup(updateBlockGroupOutput, oldSystem.gravity);
345
385
  }
346
- return outputUpdate;
386
+ return updateBlockGroupOutput;
347
387
  }
348
- function _UpdateParticleAngularSpeedBlockGroup(inputParticle, minAngularSpeed, maxAngularSpeed) {
349
- // Random value between for the angular speed of the particle
350
- const randomAngularSpeedBlock = new ParticleRandomBlock("Random Angular Speed");
351
- _CreateAndConnectInput("Min Angular Speed", minAngularSpeed, randomAngularSpeedBlock.min);
352
- _CreateAndConnectInput("Max Angular Speed", maxAngularSpeed, randomAngularSpeedBlock.max);
353
- // Create the angular speed delta
354
- const angleSpeedDeltaOutput = _CreateDeltaModifiedInput("Angular Speed", randomAngularSpeedBlock.output);
355
- // Add it to the angle
356
- const addAngle = new ParticleMathBlock("Add Angular Speed to Angle");
357
- addAngle.operation = ParticleMathBlockOperations.Add;
358
- _CreateAndConnectContextualSource("Angle", NodeParticleContextualSources.Angle, addAngle.left);
359
- angleSpeedDeltaOutput.connectTo(addAngle.right);
360
- // Update the particle angle
361
- const updateAngle = new UpdateAngleBlock("Angle Update with Angular Speed");
362
- inputParticle.connectTo(updateAngle.particle);
363
- addAngle.output.connectTo(updateAngle.angle);
364
- return updateAngle.output;
365
- }
366
- function _UpdateParticlePositionBlockGroup(inputParticle, isLocal) {
388
+ /**
389
+ * Creates the group of blocks that represent the particle color update
390
+ * @param inputParticle The input particle to update
391
+ * @param colorGradients The color gradients (if any)
392
+ * @param context The context of the current conversion
393
+ * @returns The output of the group of blocks that represent the particle color update
394
+ */
395
+ function _UpdateParticleColorBlockGroup(inputParticle, colorGradients, context) {
396
+ let colorCalculation = undefined;
397
+ if (colorGradients && colorGradients.length > 0) {
398
+ if (context.colorGradientValue0Output === undefined) {
399
+ throw new Error("Initial color gradient values not found in context.");
400
+ }
401
+ context.ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup(context);
402
+ colorCalculation = _CreateGradientBlockGroup(context.ageToLifeTimeRatioBlockGroupOutput, colorGradients, ParticleRandomBlockLocks.OncePerParticle, "Color", [
403
+ context.colorGradientValue0Output,
404
+ ]);
405
+ }
406
+ else {
407
+ colorCalculation = _BasicColorUpdateBlockGroup();
408
+ }
409
+ // Create the color update block clamping alpha >= 0
410
+ const colorUpdateBlock = new UpdateColorBlock("Color update");
411
+ inputParticle.connectTo(colorUpdateBlock.particle);
412
+ _ClampUpdateColorAlpha(colorCalculation).connectTo(colorUpdateBlock.color);
413
+ return colorUpdateBlock.output;
414
+ }
415
+ /**
416
+ * Creates the group of blocks that represent the particle angle update
417
+ * @param inputParticle The input particle to update
418
+ * @param oldSystem The old particle system to convert
419
+ * @param context The context of the current conversion
420
+ * @returns The output of the group of blocks that represent the particle color update
421
+ */
422
+ function _UpdateParticleAngleBlockGroup(inputParticle, oldSystem, context) {
423
+ // We will try to use gradients if they exist
424
+ // If not, we will try to use min/max angular speed
425
+ let angularSpeedCalculation = null;
426
+ if (oldSystem._angularSpeedGradients && oldSystem._angularSpeedGradients.length > 0) {
427
+ angularSpeedCalculation = _UpdateParticleAngularSpeedGradientBlockGroup(oldSystem._angularSpeedGradients, context);
428
+ }
429
+ else if (oldSystem.minAngularSpeed !== 0 || oldSystem.maxAngularSpeed !== 0) {
430
+ angularSpeedCalculation = _UpdateParticleAngularSpeedBlockGroup(oldSystem.minAngularSpeed, oldSystem.maxAngularSpeed);
431
+ }
432
+ // If we have an angular speed calculation, then update the angle
433
+ if (angularSpeedCalculation) {
434
+ // Create the angular speed delta
435
+ const angleSpeedDeltaOutput = _CreateDeltaModifiedInput("Angular Speed", angularSpeedCalculation);
436
+ // Add it to the angle
437
+ const addAngle = new ParticleMathBlock("Add Angular Speed to Angle");
438
+ addAngle.operation = ParticleMathBlockOperations.Add;
439
+ _CreateAndConnectContextualSource("Angle", NodeParticleContextualSources.Angle, addAngle.left);
440
+ angleSpeedDeltaOutput.connectTo(addAngle.right);
441
+ // Update the particle angle
442
+ const updateAngle = new UpdateAngleBlock("Angle Update with Angular Speed");
443
+ inputParticle.connectTo(updateAngle.particle);
444
+ addAngle.output.connectTo(updateAngle.angle);
445
+ return updateAngle.output;
446
+ }
447
+ else {
448
+ return inputParticle;
449
+ }
450
+ }
451
+ /**
452
+ * Creates the group of blocks that represent the particle velocity update
453
+ * @param velocityGradients The velocity gradients
454
+ * @param context The context of the current conversion
455
+ * @returns The output of the group of blocks that represent the particle velocity update
456
+ */
457
+ function _UpdateParticleVelocityGradientBlockGroup(velocityGradients, context) {
458
+ context.ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup(context);
459
+ // Generate the gradient
460
+ const velocityValueOutput = _CreateGradientBlockGroup(context.ageToLifeTimeRatioBlockGroupOutput, velocityGradients, ParticleRandomBlockLocks.OncePerParticle, "Velocity");
461
+ // Update the direction scale based on the velocity
462
+ const multiplyScaleByVelocity = new ParticleMathBlock("Multiply Direction Scale by Velocity");
463
+ multiplyScaleByVelocity.operation = ParticleMathBlockOperations.Multiply;
464
+ velocityValueOutput.connectTo(multiplyScaleByVelocity.left);
465
+ _CreateAndConnectContextualSource("Direction Scale", NodeParticleContextualSources.DirectionScale, multiplyScaleByVelocity.right);
466
+ // Update the particle direction scale
467
+ const multiplyDirection = new ParticleMathBlock("Scaled Direction");
468
+ multiplyDirection.operation = ParticleMathBlockOperations.Multiply;
469
+ multiplyScaleByVelocity.output.connectTo(multiplyDirection.left);
470
+ _CreateAndConnectContextualSource("Direction", NodeParticleContextualSources.Direction, multiplyDirection.right);
471
+ // Store the new calculation of the scaled direction in the context
472
+ context.scaledDirection = multiplyDirection.output;
473
+ return multiplyDirection.output;
474
+ }
475
+ /**
476
+ * Creates the group of blocks that represent the particle velocity limit update
477
+ * @param inputParticle The input particle to update
478
+ * @param velocityLimitGradients The velocity limit gradients
479
+ * @param limitVelocityDamping The limit velocity damping factor
480
+ * @param context The context of the current conversion
481
+ * @returns The output of the group of blocks that represent the particle velocity limit update
482
+ */
483
+ function _UpdateParticleVelocityLimitGradientBlockGroup(inputParticle, velocityLimitGradients, limitVelocityDamping, context) {
484
+ context.ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup(context);
485
+ // Calculate the current speed
486
+ const currentSpeedBlock = new ParticleVectorLengthBlock("Current Speed");
487
+ _CreateAndConnectContextualSource("Direction", NodeParticleContextualSources.Direction, currentSpeedBlock.input);
488
+ // Calculate the velocity limit from the gradient
489
+ const velocityLimitValueOutput = _CreateGradientBlockGroup(context.ageToLifeTimeRatioBlockGroupOutput, velocityLimitGradients, ParticleRandomBlockLocks.OncePerParticle, "Velocity Limit");
490
+ // Blocks that will calculate the new velocity if over the limit
491
+ const damped = new ParticleMathBlock("Damped Speed");
492
+ damped.operation = ParticleMathBlockOperations.Multiply;
493
+ _CreateAndConnectContextualSource("Direction", NodeParticleContextualSources.Direction, damped.left);
494
+ _CreateAndConnectInput("Limit Velocity Damping", limitVelocityDamping, damped.right);
495
+ // Compare current speed and limit
496
+ const compareSpeed = new ParticleConditionBlock("Compare Speed to Limit");
497
+ compareSpeed.test = ParticleConditionBlockTests.GreaterThan;
498
+ currentSpeedBlock.output.connectTo(compareSpeed.left);
499
+ velocityLimitValueOutput.connectTo(compareSpeed.right);
500
+ damped.output.connectTo(compareSpeed.ifTrue);
501
+ _CreateAndConnectContextualSource("Direction", NodeParticleContextualSources.Direction, compareSpeed.ifFalse);
502
+ // Update the direction based on the calculted value
503
+ const updateDirection = new UpdateDirectionBlock("Direction Update");
504
+ inputParticle.connectTo(updateDirection.particle);
505
+ compareSpeed.output.connectTo(updateDirection.direction);
506
+ return updateDirection.output;
507
+ }
508
+ /**
509
+ * Creates the group of blocks that represent the particle drag update
510
+ * @param dragGradients The drag gradients
511
+ * @param context The context of the current conversion
512
+ * @returns The output of the group of blocks that represent the particle drag update
513
+ */
514
+ function _UpdateParticleDragGradientBlockGroup(dragGradients, context) {
515
+ context.ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup(context);
516
+ // Generate the gradient
517
+ const dragValueOutput = _CreateGradientBlockGroup(context.ageToLifeTimeRatioBlockGroupOutput, dragGradients, ParticleRandomBlockLocks.OncePerParticle, "Drag");
518
+ // Calculate drag factor
519
+ const oneMinusDragBlock = new ParticleMathBlock("1 - Drag");
520
+ oneMinusDragBlock.operation = ParticleMathBlockOperations.Subtract;
521
+ _CreateAndConnectInput("One", 1, oneMinusDragBlock.left);
522
+ dragValueOutput.connectTo(oneMinusDragBlock.right);
523
+ // Multiply the scaled direction by drag factor
524
+ const multiplyDirection = new ParticleMathBlock("Scaled Direction with Drag");
525
+ multiplyDirection.operation = ParticleMathBlockOperations.Multiply;
526
+ oneMinusDragBlock.output.connectTo(multiplyDirection.left);
527
+ if (context.scaledDirection === undefined) {
528
+ _CreateAndConnectContextualSource("Scaled Direction", NodeParticleContextualSources.ScaledDirection, multiplyDirection.right);
529
+ }
530
+ else {
531
+ context.scaledDirection.connectTo(multiplyDirection.right);
532
+ }
533
+ // Store the new calculation of the scaled direction in the context
534
+ context.scaledDirection = multiplyDirection.output;
535
+ return multiplyDirection.output;
536
+ }
537
+ /**
538
+ * Creates the group of blocks that represent the particle position update
539
+ * @param inputParticle The input particle to update
540
+ * @param isLocal Whether the particle coordinate system is local or not
541
+ * @param context The context of the current conversion
542
+ * @returns The output of the group of blocks that represent the particle position update
543
+ */
544
+ function _UpdateParticlePositionBlockGroup(inputParticle, isLocal, context) {
367
545
  // Update the particle position
368
546
  const updatePosition = new UpdatePositionBlock("Position Update");
369
547
  inputParticle.connectTo(updatePosition.particle);
@@ -375,11 +553,23 @@ function _UpdateParticlePositionBlockGroup(inputParticle, isLocal) {
375
553
  const addPositionBlock = new ParticleMathBlock("Add Position");
376
554
  addPositionBlock.operation = ParticleMathBlockOperations.Add;
377
555
  _CreateAndConnectContextualSource("Position", NodeParticleContextualSources.Position, addPositionBlock.left);
378
- _CreateAndConnectContextualSource("Scaled Direction", NodeParticleContextualSources.ScaledDirection, addPositionBlock.right);
556
+ if (context.scaledDirection === undefined) {
557
+ _CreateAndConnectContextualSource("Scaled Direction", NodeParticleContextualSources.ScaledDirection, addPositionBlock.right);
558
+ }
559
+ else {
560
+ context.scaledDirection.connectTo(addPositionBlock.right);
561
+ }
379
562
  addPositionBlock.output.connectTo(updatePosition.position);
380
563
  }
381
564
  return updatePosition.output;
382
565
  }
566
+ /**
567
+ * Creates the group of blocks that represent the particle size update
568
+ * @param inputParticle The input particle to update
569
+ * @param sizeGradients The size gradients (if any)
570
+ * @param context The context of the current conversion
571
+ * @returns The output of the group of blocks that represent the particle size update
572
+ */
383
573
  function _UpdateParticleSizeGradientBlockGroup(inputParticle, sizeGradients, context) {
384
574
  if (context.sizeGradientValue0Output === undefined) {
385
575
  throw new Error("Initial size gradient values not found in context.");
@@ -395,6 +585,12 @@ function _UpdateParticleSizeGradientBlockGroup(inputParticle, sizeGradients, con
395
585
  sizeValueOutput.connectTo(updateSizeBlock.size);
396
586
  return updateSizeBlock.output;
397
587
  }
588
+ /**
589
+ * Creates the group of blocks that represent the particle gravity update
590
+ * @param inputParticle The input particle to update
591
+ * @param gravity The gravity vector to apply
592
+ * @returns The output of the group of blocks that represent the particle gravity update
593
+ */
398
594
  function _UpdateParticleGravityBlockGroup(inputParticle, gravity) {
399
595
  // Create the gravity delta
400
596
  const gravityDeltaOutput = _CreateDeltaModifiedInput("Gravity", gravity);
@@ -409,90 +605,31 @@ function _UpdateParticleGravityBlockGroup(inputParticle, gravity) {
409
605
  addDirectionBlock.output.connectTo(updateDirection.direction);
410
606
  return updateDirection.output;
411
607
  }
412
- function _CreateColorUpdateBlock(oldSystem, createParticleBlock) {
413
- if (!oldSystem) {
414
- throw new Error("Invalid particle system");
415
- }
416
- // Calculate the color
417
- const colorGradients = oldSystem.getColorGradients();
418
- let colorBlock = null;
419
- if (colorGradients && colorGradients.length > 0) {
420
- colorBlock = _CreateGradientColorUpdate(oldSystem, colorGradients, createParticleBlock);
421
- }
422
- else {
423
- colorBlock = _CreateBasicColorUpdate(oldSystem, createParticleBlock);
424
- }
425
- // Clamp alpha >= 0
426
- const clampedColor = _ClampUpdateColorAlpha(colorBlock);
427
- // Create the color update block
428
- const colorUpdateBlock = new UpdateColorBlock("Color update");
429
- clampedColor.colorOut.connectTo(colorUpdateBlock.color);
430
- return colorUpdateBlock;
431
- }
432
- function _CreateGradientColorUpdate(oldSystem, gradient, createParticleBlock) {
433
- const colorGradientBlock = new ParticleGradientBlock("Color Gradient");
434
- _CreateAndConnectContextualSource("gradient", NodeParticleContextualSources.Age, colorGradientBlock.gradient);
435
- let tempColor = null;
436
- let colorStart = null;
437
- let colorEnd = null;
438
- for (let i = 0; i < gradient.length; i++) {
439
- const gradientStep = gradient[i];
440
- const gradientValueBlock = new ParticleGradientValueBlock("Color Gradient Value " + i);
441
- gradientValueBlock.reference = gradientStep.gradient;
442
- if (gradientStep.color2) {
443
- // Create a random between color1 and color2
444
- const randomColorBlock = new ParticleRandomBlock("Random Color for Gradient " + i);
445
- randomColorBlock.lockMode = ParticleRandomBlockLocks.PerSystem;
446
- _CreateAndConnectInput("Color 1", gradientStep.color1, randomColorBlock.min);
447
- _CreateAndConnectInput("Color 2", gradientStep.color2, randomColorBlock.max);
448
- randomColorBlock.output.connectTo(gradientValueBlock.value);
449
- tempColor = randomColorBlock;
450
- }
451
- else {
452
- // Single color
453
- const input = new ParticleInputBlock("Color " + i);
454
- input.value = gradientStep.color1;
455
- input.output.connectTo(gradientValueBlock.value);
456
- tempColor = input;
457
- }
458
- if (gradientStep.gradient === 0) {
459
- colorStart = tempColor;
460
- }
461
- else if (gradientStep.gradient === 1) {
462
- colorEnd = tempColor;
463
- }
464
- gradientValueBlock.output.connectTo(colorGradientBlock.inputs[i + 1]);
465
- }
466
- _UpdateCreateParticleColor(oldSystem, colorStart, colorEnd, createParticleBlock);
467
- return colorGradientBlock;
608
+ function _UpdateParticleAngularSpeedGradientBlockGroup(angularSpeedGradients, context) {
609
+ context.ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup(context);
610
+ // Generate the gradient
611
+ const angularSpeedValueOutput = _CreateGradientBlockGroup(context.ageToLifeTimeRatioBlockGroupOutput, angularSpeedGradients, ParticleRandomBlockLocks.OncePerParticle, "Angular Speed");
612
+ return angularSpeedValueOutput;
613
+ }
614
+ function _UpdateParticleAngularSpeedBlockGroup(minAngularSpeed, maxAngularSpeed) {
615
+ // Random value between for the angular speed of the particle
616
+ const randomAngularSpeedBlock = new ParticleRandomBlock("Random Angular Speed");
617
+ randomAngularSpeedBlock.lockMode = ParticleRandomBlockLocks.OncePerParticle;
618
+ _CreateAndConnectInput("Min Angular Speed", minAngularSpeed, randomAngularSpeedBlock.min);
619
+ _CreateAndConnectInput("Max Angular Speed", maxAngularSpeed, randomAngularSpeedBlock.max);
620
+ return randomAngularSpeedBlock.output;
468
621
  }
469
- function _CreateBasicColorUpdate(oldSystem, createParticleBlock) {
622
+ function _BasicColorUpdateBlockGroup() {
470
623
  const addColorBlock = new ParticleMathBlock("Add Color");
471
624
  addColorBlock.operation = ParticleMathBlockOperations.Add;
472
625
  _CreateAndConnectContextualSource("Color", NodeParticleContextualSources.Color, addColorBlock.left);
473
626
  _CreateAndConnectContextualSource("Scaled Color Step", NodeParticleContextualSources.ScaledColorStep, addColorBlock.right);
474
- _UpdateCreateParticleColor(oldSystem, null, null, createParticleBlock);
475
- return addColorBlock;
476
- }
477
- function _UpdateCreateParticleColor(oldSystem, colorStart, colorEnd, createParticleBlock) {
478
- if (colorStart === null) {
479
- colorStart = new ParticleInputBlock("Color Start");
480
- colorStart.value = oldSystem.color1;
481
- }
482
- if (colorEnd === null) {
483
- colorEnd = new ParticleInputBlock("Color End");
484
- colorEnd.value = oldSystem.color2;
485
- }
486
- const randomColorBlock = new ParticleRandomBlock("Random color");
487
- randomColorBlock.lockMode = ParticleRandomBlockLocks.PerParticle;
488
- colorStart.output.connectTo(randomColorBlock.min);
489
- colorEnd.output.connectTo(randomColorBlock.max);
490
- randomColorBlock.output.connectTo(createParticleBlock.color);
627
+ return addColorBlock.output;
491
628
  }
492
- function _ClampUpdateColorAlpha(colorBlock) {
629
+ function _ClampUpdateColorAlpha(colorCalculationOutput) {
493
630
  // Decompose color to clamp alpha
494
631
  const decomposeColorBlock = new ParticleConverterBlock("Decompose Color");
495
- colorBlock.outputs[0].connectTo(decomposeColorBlock.colorIn);
632
+ colorCalculationOutput.connectTo(decomposeColorBlock.colorIn);
496
633
  // Clamp alpha to be >= 0
497
634
  const maxAlphaBlock = new ParticleMathBlock("Alpha >= 0");
498
635
  maxAlphaBlock.operation = ParticleMathBlockOperations.Max;
@@ -502,7 +639,7 @@ function _ClampUpdateColorAlpha(colorBlock) {
502
639
  const composeColorBlock = new ParticleConverterBlock("Compose Color");
503
640
  decomposeColorBlock.xyzOut.connectTo(composeColorBlock.xyzIn);
504
641
  maxAlphaBlock.output.connectTo(composeColorBlock.wIn);
505
- return composeColorBlock;
642
+ return composeColorBlock.colorOut;
506
643
  }
507
644
  // ------------- UTILITY FUNCTIONS -------------
508
645
  function _CreateDeltaModifiedInput(name, value) {
@@ -639,17 +776,19 @@ function _CreateGradientBlockGroup(gradientSelector, gradientValues, randomLockM
639
776
  function _CreateGradientValueBlockGroup(gradientStep, randomLockMode, prefix, index) {
640
777
  const gradientValueBlock = new ParticleGradientValueBlock(prefix + " Gradient Value " + index);
641
778
  gradientValueBlock.reference = gradientStep.gradient;
642
- if (gradientStep.factor2 !== undefined) {
779
+ const value1 = gradientStep.factor1 ?? gradientStep.color1;
780
+ const value2 = gradientStep.factor2 ?? gradientStep.color2;
781
+ if (value2 !== undefined) {
643
782
  // Create a random between value1 and value2
644
783
  const randomBlock = new ParticleRandomBlock("Random Value " + index);
645
784
  randomBlock.lockMode = randomLockMode;
646
- _CreateAndConnectInput("Value 1", gradientStep.factor1, randomBlock.min);
647
- _CreateAndConnectInput("Value 2", gradientStep.factor2, randomBlock.max);
785
+ _CreateAndConnectInput("Value 1", value1, randomBlock.min);
786
+ _CreateAndConnectInput("Value 2", value2, randomBlock.max);
648
787
  randomBlock.output.connectTo(gradientValueBlock.value);
649
788
  }
650
789
  else {
651
790
  // Single value
652
- _CreateAndConnectInput("Value", gradientStep.factor1, gradientValueBlock.value);
791
+ _CreateAndConnectInput("Value", value1, gradientValueBlock.value);
653
792
  }
654
793
  return gradientValueBlock.output;
655
794
  }