@onerjs/core 8.30.9 → 8.31.1

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 +52 -0
  4. package/Behaviors/Cameras/interpolatingBehavior.js +105 -0
  5. package/Behaviors/Cameras/interpolatingBehavior.js.map +1 -0
  6. package/Cameras/Inputs/arcRotateCameraPointersInput.d.ts +5 -20
  7. package/Cameras/Inputs/arcRotateCameraPointersInput.js +9 -69
  8. package/Cameras/Inputs/arcRotateCameraPointersInput.js.map +1 -1
  9. package/Cameras/Inputs/geospatialCameraKeyboardInput.d.ts +81 -0
  10. package/Cameras/Inputs/geospatialCameraKeyboardInput.js +223 -0
  11. package/Cameras/Inputs/geospatialCameraKeyboardInput.js.map +1 -0
  12. package/Cameras/Inputs/geospatialCameraMouseWheelInput.js +1 -1
  13. package/Cameras/Inputs/geospatialCameraMouseWheelInput.js.map +1 -1
  14. package/Cameras/Inputs/geospatialCameraPointersInput.d.ts +16 -21
  15. package/Cameras/Inputs/geospatialCameraPointersInput.js +43 -73
  16. package/Cameras/Inputs/geospatialCameraPointersInput.js.map +1 -1
  17. package/Cameras/Inputs/orbitCameraPointersInput.d.ts +49 -0
  18. package/Cameras/Inputs/orbitCameraPointersInput.js +105 -0
  19. package/Cameras/Inputs/orbitCameraPointersInput.js.map +1 -0
  20. package/Cameras/Limits/geospatialLimits.d.ts +60 -0
  21. package/Cameras/Limits/geospatialLimits.js +89 -0
  22. package/Cameras/Limits/geospatialLimits.js.map +1 -0
  23. package/Cameras/cameraMovement.d.ts +150 -0
  24. package/Cameras/cameraMovement.js +190 -0
  25. package/Cameras/cameraMovement.js.map +1 -0
  26. package/Cameras/geospatialCamera.d.ts +53 -49
  27. package/Cameras/geospatialCamera.js +172 -192
  28. package/Cameras/geospatialCamera.js.map +1 -1
  29. package/Cameras/geospatialCameraInputsManager.d.ts +5 -0
  30. package/Cameras/geospatialCameraInputsManager.js +9 -0
  31. package/Cameras/geospatialCameraInputsManager.js.map +1 -1
  32. package/Cameras/geospatialCameraMovement.d.ts +66 -0
  33. package/Cameras/geospatialCameraMovement.js +199 -0
  34. package/Cameras/geospatialCameraMovement.js.map +1 -0
  35. package/Engines/Native/nativeInterfaces.d.ts +14 -6
  36. package/Engines/Native/nativeInterfaces.js +6 -1
  37. package/Engines/Native/nativeInterfaces.js.map +1 -1
  38. package/Engines/nativeEngine.js +2 -2
  39. package/Engines/nativeEngine.js.map +1 -1
  40. package/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.js +1 -1
  41. package/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.js.map +1 -1
  42. package/FlowGraph/flowGraphMath.d.ts +25 -0
  43. package/FlowGraph/flowGraphMath.js +40 -0
  44. package/FlowGraph/flowGraphMath.js.map +1 -0
  45. package/Materials/GaussianSplatting/gaussianSplattingMaterial.js +1 -1
  46. package/Materials/GaussianSplatting/gaussianSplattingMaterial.js.map +1 -1
  47. package/Materials/Node/Blocks/GaussianSplatting/gaussianSplattingBlock.js +5 -1
  48. package/Materials/Node/Blocks/GaussianSplatting/gaussianSplattingBlock.js.map +1 -1
  49. package/Materials/Node/Blocks/GaussianSplatting/splatReaderBlock.js +6 -5
  50. package/Materials/Node/Blocks/GaussianSplatting/splatReaderBlock.js.map +1 -1
  51. package/Materials/shaderMaterial.js +4 -2
  52. package/Materials/shaderMaterial.js.map +1 -1
  53. package/Maths/math.vector.functions.d.ts +5 -24
  54. package/Maths/math.vector.functions.js +32 -35
  55. package/Maths/math.vector.functions.js.map +1 -1
  56. package/Meshes/GaussianSplatting/gaussianSplattingMesh.d.ts +1 -0
  57. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js +51 -16
  58. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js.map +1 -1
  59. package/Meshes/csg2.js +1 -1
  60. package/Meshes/csg2.js.map +1 -1
  61. package/Meshes/thinInstanceMesh.js +15 -0
  62. package/Meshes/thinInstanceMesh.js.map +1 -1
  63. package/Misc/fileTools.js.map +1 -1
  64. package/Misc/tools.d.ts +3 -0
  65. package/Misc/tools.js +43 -4
  66. package/Misc/tools.js.map +1 -1
  67. package/Particles/Node/Blocks/Update/basicColorUpdateBlock.d.ts +1 -1
  68. package/Particles/Node/Blocks/Update/basicColorUpdateBlock.js +1 -1
  69. package/Particles/Node/Blocks/Update/basicColorUpdateBlock.js.map +1 -1
  70. package/Particles/Node/Blocks/Update/basicPositionUpdateBlock.d.ts +1 -1
  71. package/Particles/Node/Blocks/Update/basicPositionUpdateBlock.js +3 -3
  72. package/Particles/Node/Blocks/Update/basicPositionUpdateBlock.js.map +1 -1
  73. package/Particles/Node/Blocks/Update/updateSizeBlock.d.ts +35 -0
  74. package/Particles/Node/Blocks/Update/updateSizeBlock.js +73 -0
  75. package/Particles/Node/Blocks/Update/updateSizeBlock.js.map +1 -0
  76. package/Particles/Node/Blocks/index.d.ts +1 -0
  77. package/Particles/Node/Blocks/index.js +1 -0
  78. package/Particles/Node/Blocks/index.js.map +1 -1
  79. package/Particles/Node/Blocks/particleInputBlock.js +1 -0
  80. package/Particles/Node/Blocks/particleInputBlock.js.map +1 -1
  81. package/Particles/Node/Blocks/particleRandomBlock.d.ts +5 -2
  82. package/Particles/Node/Blocks/particleRandomBlock.js +32 -14
  83. package/Particles/Node/Blocks/particleRandomBlock.js.map +1 -1
  84. package/Particles/Node/Blocks/systemBlock.d.ts +8 -0
  85. package/Particles/Node/Blocks/systemBlock.js +8 -0
  86. package/Particles/Node/Blocks/systemBlock.js.map +1 -1
  87. package/Particles/Node/Enums/nodeParticleContextualSources.d.ts +3 -1
  88. package/Particles/Node/Enums/nodeParticleContextualSources.js +2 -0
  89. package/Particles/Node/Enums/nodeParticleContextualSources.js.map +1 -1
  90. package/Particles/Node/nodeParticleBuildState.js +6 -4
  91. package/Particles/Node/nodeParticleBuildState.js.map +1 -1
  92. package/Particles/Node/nodeParticleSystemSet.helper.d.ts +0 -2
  93. package/Particles/Node/nodeParticleSystemSet.helper.js +279 -161
  94. package/Particles/Node/nodeParticleSystemSet.helper.js.map +1 -1
  95. package/Particles/particle.d.ts +4 -0
  96. package/Particles/particle.js +2 -0
  97. package/Particles/particle.js.map +1 -1
  98. package/Particles/thinParticleSystem.d.ts +3 -7
  99. package/Particles/thinParticleSystem.function.d.ts +1 -1
  100. package/Particles/thinParticleSystem.function.js +9 -6
  101. package/Particles/thinParticleSystem.function.js.map +1 -1
  102. package/Particles/thinParticleSystem.js +4 -6
  103. package/Particles/thinParticleSystem.js.map +1 -1
  104. package/Shaders/ShadersInclude/gaussianSplatting.js +5 -1
  105. package/Shaders/ShadersInclude/gaussianSplatting.js.map +1 -1
  106. package/Shaders/ShadersInclude/gaussianSplattingUboDeclaration.js +2 -1
  107. package/Shaders/ShadersInclude/gaussianSplattingUboDeclaration.js.map +1 -1
  108. package/Shaders/ShadersInclude/gaussianSplattingVertexDeclaration.js +1 -1
  109. package/Shaders/ShadersInclude/gaussianSplattingVertexDeclaration.js.map +1 -1
  110. package/Shaders/gaussianSplatting.vertex.js +3 -3
  111. package/Shaders/gaussianSplatting.vertex.js.map +1 -1
  112. package/Shaders/gaussianSplattingDepth.vertex.js +2 -2
  113. package/Shaders/gaussianSplattingDepth.vertex.js.map +1 -1
  114. package/ShadersWGSL/ShadersInclude/gaussianSplatting.js +35 -1
  115. package/ShadersWGSL/ShadersInclude/gaussianSplatting.js.map +1 -1
  116. package/ShadersWGSL/ShadersInclude/gaussianSplattingUboDeclaration.js +2 -1
  117. package/ShadersWGSL/ShadersInclude/gaussianSplattingUboDeclaration.js.map +1 -1
  118. package/ShadersWGSL/ShadersInclude/gaussianSplattingVertexDeclaration.js +1 -2
  119. package/ShadersWGSL/ShadersInclude/gaussianSplattingVertexDeclaration.js.map +1 -1
  120. package/ShadersWGSL/gaussianSplatting.vertex.js +3 -3
  121. package/ShadersWGSL/gaussianSplatting.vertex.js.map +1 -1
  122. package/ShadersWGSL/gaussianSplattingDepth.vertex.js +2 -2
  123. package/ShadersWGSL/gaussianSplattingDepth.vertex.js.map +1 -1
  124. package/package.json +1 -1
@@ -22,13 +22,12 @@ import { UpdateAngleBlock } from "./Blocks/Update/updateAngleBlock.js";
22
22
  import { UpdateColorBlock } from "./Blocks/Update/updateColorBlock.js";
23
23
  import { UpdateDirectionBlock } from "./Blocks/Update/updateDirectionBlock.js";
24
24
  import { UpdatePositionBlock } from "./Blocks/Update/updatePositionBlock.js";
25
+ import { UpdateSizeBlock } from "./Blocks/Update/updateSizeBlock.js";
25
26
  /**
26
27
  * Converts a ParticleSystem to a NodeParticleSystemSet.
27
28
  * @param name The name of the node particle system set.
28
29
  * @param particleSystemsList The particle systems to convert.
29
30
  * @returns The converted node particle system set or null if conversion failed.
30
- * #0K3AQ2#3672
31
- * #7J0NXA#4
32
31
  */
33
32
  export async function ConvertToNodeParticleSystemSetAsync(name, particleSystemsList) {
34
33
  if (!particleSystemsList || !particleSystemsList.length) {
@@ -43,28 +42,25 @@ export async function ConvertToNodeParticleSystemSetAsync(name, particleSystemsL
43
42
  return nodeParticleSystemSet;
44
43
  }
45
44
  async function _ExtractDatafromParticleSystemAsync(newSet, oldSystem, context) {
46
- // CreateParticle block
47
- const createParticleBlock = _CreateCreateParticleBlockGroup(oldSystem, context);
45
+ // CreateParticle block group
46
+ const createParticleOutput = _CreateParticleBlockGroup(oldSystem, context);
48
47
  // Emitter Shape block
49
- const shapeBlock = _CreateEmitterShapeBlock(oldSystem);
50
- createParticleBlock.particle.connectTo(shapeBlock.particle);
51
- // Update the particle position
52
- const positionUpdatedParticle = _CreateUpdateSystem(shapeBlock.output, oldSystem);
53
- // Color update
54
- const colorUpdateBlock = _CreateColorUpdateBlock(oldSystem, createParticleBlock);
55
- positionUpdatedParticle.connectTo(colorUpdateBlock.particle);
48
+ const shapeOutput = _EmitterShapeBlock(oldSystem);
49
+ createParticleOutput.particle.connectTo(shapeOutput.particle);
50
+ // UpdateParticle block group
51
+ const updateParticleOutput = _UpdateParticleBlockGroup(shapeOutput.output, oldSystem, context);
56
52
  // System block
57
- const newSystem = _CreateSystemBlock(oldSystem, context);
58
- colorUpdateBlock.output.connectTo(newSystem.particle);
53
+ const newSystem = _SystemBlockGroup(oldSystem, context);
54
+ updateParticleOutput.connectTo(newSystem.particle);
59
55
  // Register
60
56
  newSet.systemBlocks.push(newSystem);
61
57
  }
62
- function _CreateSystemBlock(oldSystem, context) {
58
+ // ------------- SYSTEM FUNCTIONS -------------
59
+ function _SystemBlockGroup(oldSystem, context) {
63
60
  const newSystem = new SystemBlock(oldSystem.name);
64
61
  _CreateAndConnectInput("Translation pivot", oldSystem.translationPivot, newSystem.translationPivot);
65
62
  _CreateAndConnectInput("Texture mask", oldSystem.textureMask, newSystem.textureMask);
66
- const targetStopDurationOutput = _CreateTargetStopDurationInputBlock(oldSystem, context);
67
- targetStopDurationOutput.connectTo(newSystem.targetStopDuration);
63
+ _CreateTargetStopDurationInputBlock(oldSystem, context).connectTo(newSystem.targetStopDuration);
68
64
  newSystem.emitRate = oldSystem.emitRate;
69
65
  newSystem.manualEmitCount = oldSystem.manualEmitCount;
70
66
  newSystem.blendMode = oldSystem.blendMode;
@@ -88,47 +84,32 @@ function _CreateSystemBlock(oldSystem, context) {
88
84
  textureBlock.texture.connectTo(newSystem.texture);
89
85
  return newSystem;
90
86
  }
91
- // Create Particle Block Group functions
92
- function _CreateCreateParticleBlockGroup(oldSystem, context) {
93
- // Create particle
87
+ // ------------- CREATE PARTICLE FUNCTIONS -------------
88
+ // The creation of the different properties follows the order they are added to the CreationQueue in ThinParticleSystem:
89
+ // Lifetime, Emit Power, Size, Scale/StartSize, Angle, Velocity, VelocityLimit, Color, Drag, Noise, ColorDead, Ramp, Sheet
90
+ function _CreateParticleBlockGroup(oldSystem, context) {
91
+ // Create particle block
94
92
  const createParticleBlock = new CreateParticleBlock("Create Particle");
95
- // Lifetime
96
93
  _CreateParticleLifetimeBlockGroup(oldSystem, context).connectTo(createParticleBlock.lifeTime);
97
- // Size
98
- const randomSizeBlock = new ParticleRandomBlock("Random size");
99
- _CreateAndConnectInput("Min size", oldSystem.minSize, randomSizeBlock.min);
100
- _CreateAndConnectInput("Max size", oldSystem.maxSize, randomSizeBlock.max);
101
- randomSizeBlock.output.connectTo(createParticleBlock.size);
102
- // Scale
103
- const randomScaleBlock = new ParticleRandomBlock("Random Scale");
104
- _CreateAndConnectInput("Min Scale", new Vector2(oldSystem.minScaleX, oldSystem.minScaleY), randomScaleBlock.min);
105
- _CreateAndConnectInput("Max Scale", new Vector2(oldSystem.maxScaleX, oldSystem.maxScaleY), randomScaleBlock.max);
106
- randomScaleBlock.output.connectTo(createParticleBlock.scale);
107
- // Color is handled when we do the color update block to manage gradients
94
+ _CreateParticleEmitPowerBlockGroup(oldSystem).connectTo(createParticleBlock.emitPower);
95
+ _CreateParticleSizeBlockGroup(oldSystem, context).connectTo(createParticleBlock.size);
96
+ _CreateParticleScaleBlockGroup(oldSystem, context).connectTo(createParticleBlock.scale);
97
+ _CreateParticleAngleBlockGroup(oldSystem).connectTo(createParticleBlock.angle);
98
+ _CreateParticleColorBlockGroup(oldSystem, context).connectTo(createParticleBlock.color);
108
99
  // Dead color
109
100
  _CreateAndConnectInput("Dead Color", oldSystem.colorDead, createParticleBlock.colorDead);
110
- // Emit power (Speed)
111
- const randomEmitPowerBlock = new ParticleRandomBlock("Random Emit Power");
112
- _CreateAndConnectInput("Min Emit Power", oldSystem.minEmitPower, randomEmitPowerBlock.min);
113
- _CreateAndConnectInput("Max Emit Power", oldSystem.maxEmitPower, randomEmitPowerBlock.max);
114
- randomEmitPowerBlock.output.connectTo(createParticleBlock.emitPower);
115
- // Angle (rotation)
116
- const randomRotationBlock = new ParticleRandomBlock("Random Rotation");
117
- _CreateAndConnectInput("Min Rotation", oldSystem.minInitialRotation, randomRotationBlock.min);
118
- _CreateAndConnectInput("Max Rotation", oldSystem.maxInitialRotation, randomRotationBlock.max);
119
- randomRotationBlock.output.connectTo(createParticleBlock.angle);
120
101
  return createParticleBlock;
121
102
  }
122
103
  /**
123
104
  * Creates the group of blocks that represent the particle lifetime
124
- * @param oldSystem The old particle system to migrate
125
- * @param context The system migration context
105
+ * @param oldSystem The old particle system to convert
106
+ * @param context The context of the current conversion
126
107
  * @returns The output of the group of blocks that represent the particle lifetime
127
108
  */
128
109
  function _CreateParticleLifetimeBlockGroup(oldSystem, context) {
129
110
  if (oldSystem.targetStopDuration && oldSystem._lifeTimeGradients && oldSystem._lifeTimeGradients.length > 0) {
130
111
  context.timeToStopTimeRatioBlockGroupOutput = _CreateTimeToStopTimeRatioBlockGroup(oldSystem, context);
131
- const gradientBlockGroupOutput = _CreateGradientBlockGroup(context.timeToStopTimeRatioBlockGroupOutput, oldSystem._lifeTimeGradients);
112
+ const gradientBlockGroupOutput = _CreateGradientBlockGroup(context.timeToStopTimeRatioBlockGroupOutput, oldSystem._lifeTimeGradients, ParticleRandomBlockLocks.PerParticle, "Lifetime");
132
113
  return gradientBlockGroupOutput;
133
114
  }
134
115
  else {
@@ -138,7 +119,114 @@ function _CreateParticleLifetimeBlockGroup(oldSystem, context) {
138
119
  return randomLifetimeBlock.output;
139
120
  }
140
121
  }
141
- function _CreateEmitterShapeBlock(oldSystem) {
122
+ /**
123
+ * Creates the group of blocks that represent the particle emit power
124
+ * @param oldSystem The old particle system to convert
125
+ * @returns The output of the group of blocks that represent the particle emit power
126
+ */
127
+ function _CreateParticleEmitPowerBlockGroup(oldSystem) {
128
+ const randomEmitPowerBlock = new ParticleRandomBlock("Random Emit Power");
129
+ _CreateAndConnectInput("Min Emit Power", oldSystem.minEmitPower, randomEmitPowerBlock.min);
130
+ _CreateAndConnectInput("Max Emit Power", oldSystem.maxEmitPower, randomEmitPowerBlock.max);
131
+ return randomEmitPowerBlock.output;
132
+ }
133
+ /**
134
+ * Creates the group of blocks that represent the particle size
135
+ * @param oldSystem The old particle system to convert
136
+ * @param context The context of the current conversion
137
+ * @returns The output of the group of blocks that represent the particle size
138
+ */
139
+ function _CreateParticleSizeBlockGroup(oldSystem, context) {
140
+ if (oldSystem._sizeGradients && oldSystem._sizeGradients.length > 0) {
141
+ context.sizeGradientValue0Output = _CreateParticleInitialValueFromGradient(oldSystem._sizeGradients);
142
+ return context.sizeGradientValue0Output;
143
+ }
144
+ else {
145
+ const randomSizeBlock = new ParticleRandomBlock("Random size");
146
+ _CreateAndConnectInput("Min size", oldSystem.minSize, randomSizeBlock.min);
147
+ _CreateAndConnectInput("Max size", oldSystem.maxSize, randomSizeBlock.max);
148
+ return randomSizeBlock.output;
149
+ }
150
+ }
151
+ /**
152
+ * Creates the group of blocks that represent the particle scale
153
+ * @param oldSystem The old particle system to convert
154
+ * @param context The context of the current conversion
155
+ * @returns The output of the group of blocks that represent the particle scale
156
+ */
157
+ function _CreateParticleScaleBlockGroup(oldSystem, context) {
158
+ // Create the random scale
159
+ const randomScaleBlock = new ParticleRandomBlock("Random Scale");
160
+ _CreateAndConnectInput("Min Scale", new Vector2(oldSystem.minScaleX, oldSystem.minScaleY), randomScaleBlock.min);
161
+ _CreateAndConnectInput("Max Scale", new Vector2(oldSystem.maxScaleX, oldSystem.maxScaleY), randomScaleBlock.max);
162
+ if (oldSystem.targetStopDuration && oldSystem._startSizeGradients && oldSystem._startSizeGradients.length > 0) {
163
+ // Create the start size gradient
164
+ context.timeToStopTimeRatioBlockGroupOutput = _CreateTimeToStopTimeRatioBlockGroup(oldSystem, context);
165
+ const gradientBlockGroupOutput = _CreateGradientBlockGroup(context.timeToStopTimeRatioBlockGroupOutput, oldSystem._startSizeGradients, ParticleRandomBlockLocks.PerParticle, "Start Size");
166
+ // Multiply the initial random scale by the start size gradient
167
+ const multiplyScaleBlock = new ParticleMathBlock("Multiply Scale by Start Size Gradient");
168
+ multiplyScaleBlock.operation = ParticleMathBlockOperations.Multiply;
169
+ randomScaleBlock.output.connectTo(multiplyScaleBlock.left);
170
+ gradientBlockGroupOutput.connectTo(multiplyScaleBlock.right);
171
+ return multiplyScaleBlock.output;
172
+ }
173
+ else {
174
+ return randomScaleBlock.output;
175
+ }
176
+ }
177
+ /**
178
+ * Creates the group of blocks that represent the particle angle (rotation)
179
+ * @param oldSystem The old particle system to convert
180
+ * @returns The output of the group of blocks that represent the particle angle (rotation)
181
+ */
182
+ function _CreateParticleAngleBlockGroup(oldSystem) {
183
+ const randomRotationBlock = new ParticleRandomBlock("Random Rotation");
184
+ _CreateAndConnectInput("Min Rotation", oldSystem.minInitialRotation, randomRotationBlock.min);
185
+ _CreateAndConnectInput("Max Rotation", oldSystem.maxInitialRotation, randomRotationBlock.max);
186
+ return randomRotationBlock.output;
187
+ }
188
+ /**
189
+ * Creates the group of blocks that represent the particle color
190
+ * @param oldSystem The old particle system to convert
191
+ * @param context The context of the current conversion
192
+ * @returns The output of the group of blocks that represent the particle color
193
+ */
194
+ function _CreateParticleColorBlockGroup(oldSystem, context) {
195
+ if (oldSystem._colorGradients && oldSystem._colorGradients.length > 0) {
196
+ context.colorGradientValue0Output = _CreateParticleInitialValueFromGradient(oldSystem._colorGradients);
197
+ return context.colorGradientValue0Output;
198
+ }
199
+ else {
200
+ const randomColorBlock = new ParticleRandomBlock("Random color");
201
+ _CreateAndConnectInput("Color 1", oldSystem.color1, randomColorBlock.min);
202
+ _CreateAndConnectInput("Color 2", oldSystem.color2, randomColorBlock.max);
203
+ return randomColorBlock.output;
204
+ }
205
+ }
206
+ function _CreateParticleInitialValueFromGradient(gradients) {
207
+ if (gradients.length === 0) {
208
+ throw new Error("No gradients provided.");
209
+ }
210
+ const gradientStep = gradients[0];
211
+ const value1 = gradientStep.factor1 ?? gradientStep.color1;
212
+ const value2 = gradientStep.factor2 ?? gradientStep.color2;
213
+ if (value2 !== undefined) {
214
+ // Create a random between value1 and value2
215
+ const randomBlock = new ParticleRandomBlock("Random Value 0");
216
+ randomBlock.lockMode = ParticleRandomBlockLocks.OncePerParticle;
217
+ _CreateAndConnectInput("Value 1", value1, randomBlock.min);
218
+ _CreateAndConnectInput("Value 2", value2, randomBlock.max);
219
+ return randomBlock.output;
220
+ }
221
+ else {
222
+ // Single value
223
+ const sizeBlock = new ParticleInputBlock("Value");
224
+ sizeBlock.value = value1;
225
+ return sizeBlock.output;
226
+ }
227
+ }
228
+ // ------------- EMITTER SHAPE FUNCTIONS -------------
229
+ function _EmitterShapeBlock(oldSystem) {
142
230
  const emitter = oldSystem.particleEmitterType;
143
231
  if (!emitter) {
144
232
  throw new Error("Particle system has no emitter type.");
@@ -263,36 +351,93 @@ function _CreateEmitterShapeBlock(oldSystem) {
263
351
  }
264
352
  return shapeBlock;
265
353
  }
266
- function _CreateUpdateSystem(inputParticle, oldSystem) {
267
- let outputUpdate = inputParticle;
268
- if (oldSystem.minAngularSpeed !== 0 || oldSystem.maxAngularSpeed !== 0) {
269
- outputUpdate = _CreateAngularSpeedUpdate(outputUpdate, oldSystem.minAngularSpeed, oldSystem.maxAngularSpeed);
354
+ // ------------- UPDATE PARTICLE FUNCTIONS -------------
355
+ /**
356
+ * Creates the group of blocks that represent the particle system update
357
+ * The creation of the different properties follows the order they are added to the ProcessQueue in ThinParticleSystem:
358
+ * Color, AngularSpeedGradients, AngularSpeed, VelocityGradients, Direction, LimitVelocityGradients, DragGradients, Position, Noise, SizeGradients, Gravity, RemapGradients
359
+ * @param inputParticle The particle input connection point
360
+ * @param oldSystem The old particle system to convert
361
+ * @param context The runtime conversion context
362
+ * @returns The output connection point after all updates have been applied
363
+ */
364
+ function _UpdateParticleBlockGroup(inputParticle, oldSystem, context) {
365
+ let updateBlockGroupOutput = inputParticle;
366
+ updateBlockGroupOutput = _UpdateParticleColorBlockGroup(updateBlockGroupOutput, oldSystem._colorGradients, context);
367
+ updateBlockGroupOutput = _UpdateParticleAngleBlockGroup(updateBlockGroupOutput, oldSystem, context);
368
+ updateBlockGroupOutput = _UpdateParticlePositionBlockGroup(updateBlockGroupOutput, oldSystem.isLocal);
369
+ if (oldSystem._sizeGradients && oldSystem._sizeGradients.length > 0) {
370
+ updateBlockGroupOutput = _UpdateParticleSizeGradientBlockGroup(updateBlockGroupOutput, oldSystem._sizeGradients, context);
270
371
  }
271
- outputUpdate = _CreatePositionUpdate(outputUpdate, oldSystem.isLocal);
272
372
  if (oldSystem.gravity.equalsToFloats(0, 0, 0) === false) {
273
- outputUpdate = _CreateGravityUpdate(outputUpdate, oldSystem.gravity);
373
+ updateBlockGroupOutput = _UpdateParticleGravityBlockGroup(updateBlockGroupOutput, oldSystem.gravity);
374
+ }
375
+ return updateBlockGroupOutput;
376
+ }
377
+ function _UpdateParticleColorBlockGroup(inputParticle, colorGradients, context) {
378
+ let colorCalculation = undefined;
379
+ if (colorGradients && colorGradients.length > 0) {
380
+ if (context.colorGradientValue0Output === undefined) {
381
+ throw new Error("Initial color gradient values not found in context.");
382
+ }
383
+ context.ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup(context);
384
+ colorCalculation = _CreateGradientBlockGroup(context.ageToLifeTimeRatioBlockGroupOutput, colorGradients, ParticleRandomBlockLocks.OncePerParticle, "Color", [
385
+ context.colorGradientValue0Output,
386
+ ]);
387
+ }
388
+ else {
389
+ colorCalculation = _CreateBasicColorUpdate();
390
+ }
391
+ // Create the color update block clamping alpha >= 0
392
+ const colorUpdateBlock = new UpdateColorBlock("Color update");
393
+ inputParticle.connectTo(colorUpdateBlock.particle);
394
+ _ClampUpdateColorAlpha(colorCalculation).connectTo(colorUpdateBlock.color);
395
+ return colorUpdateBlock.output;
396
+ }
397
+ function _UpdateParticleAngleBlockGroup(inputParticle, oldSystem, context) {
398
+ // We will try to use gradients if they exist
399
+ // If not, we will try to use min/max angular speed
400
+ let angularSpeedCalculation = null;
401
+ if (oldSystem._angularSpeedGradients && oldSystem._angularSpeedGradients.length > 0) {
402
+ angularSpeedCalculation = _UpdateParticleAngularSpeedGradientBlockGroup(oldSystem._angularSpeedGradients, context);
274
403
  }
275
- return outputUpdate;
404
+ else if (oldSystem.minAngularSpeed !== 0 || oldSystem.maxAngularSpeed !== 0) {
405
+ angularSpeedCalculation = _UpdateParticleAngularSpeedBlockGroup(oldSystem.minAngularSpeed, oldSystem.maxAngularSpeed);
406
+ }
407
+ // If we have an angular speed calculation, then update the angle
408
+ if (angularSpeedCalculation) {
409
+ // Create the angular speed delta
410
+ const angleSpeedDeltaOutput = _CreateDeltaModifiedInput("Angular Speed", angularSpeedCalculation);
411
+ // Add it to the angle
412
+ const addAngle = new ParticleMathBlock("Add Angular Speed to Angle");
413
+ addAngle.operation = ParticleMathBlockOperations.Add;
414
+ _CreateAndConnectContextualSource("Angle", NodeParticleContextualSources.Angle, addAngle.left);
415
+ angleSpeedDeltaOutput.connectTo(addAngle.right);
416
+ // Update the particle angle
417
+ const updateAngle = new UpdateAngleBlock("Angle Update with Angular Speed");
418
+ inputParticle.connectTo(updateAngle.particle);
419
+ addAngle.output.connectTo(updateAngle.angle);
420
+ return updateAngle.output;
421
+ }
422
+ else {
423
+ return inputParticle;
424
+ }
425
+ }
426
+ function _UpdateParticleAngularSpeedGradientBlockGroup(angularSpeedGradients, context) {
427
+ context.ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup(context);
428
+ // Generate the gradient
429
+ const angularSpeedValueOutput = _CreateGradientBlockGroup(context.ageToLifeTimeRatioBlockGroupOutput, angularSpeedGradients, ParticleRandomBlockLocks.OncePerParticle, "Angular Speed");
430
+ return angularSpeedValueOutput;
276
431
  }
277
- function _CreateAngularSpeedUpdate(inputParticle, minAngularSpeed, maxAngularSpeed) {
432
+ function _UpdateParticleAngularSpeedBlockGroup(minAngularSpeed, maxAngularSpeed) {
278
433
  // Random value between for the angular speed of the particle
279
434
  const randomAngularSpeedBlock = new ParticleRandomBlock("Random Angular Speed");
435
+ randomAngularSpeedBlock.lockMode = ParticleRandomBlockLocks.OncePerParticle;
280
436
  _CreateAndConnectInput("Min Angular Speed", minAngularSpeed, randomAngularSpeedBlock.min);
281
437
  _CreateAndConnectInput("Max Angular Speed", maxAngularSpeed, randomAngularSpeedBlock.max);
282
- // Create the angular speed delta
283
- const angleSpeedDeltaOutput = _CreateDeltaModifiedInput("Angular Speed", randomAngularSpeedBlock.output);
284
- // Add it to the angle
285
- const addAngle = new ParticleMathBlock("Add Angular Speed to Angle");
286
- addAngle.operation = ParticleMathBlockOperations.Add;
287
- _CreateAndConnectContextualSource("Angle", NodeParticleContextualSources.Angle, addAngle.left);
288
- angleSpeedDeltaOutput.connectTo(addAngle.right);
289
- // Update the particle angle
290
- const updateAngle = new UpdateAngleBlock("Angle Update with Angular Speed");
291
- inputParticle.connectTo(updateAngle.particle);
292
- addAngle.output.connectTo(updateAngle.angle);
293
- return updateAngle.output;
438
+ return randomAngularSpeedBlock.output;
294
439
  }
295
- function _CreatePositionUpdate(inputParticle, isLocal) {
440
+ function _UpdateParticlePositionBlockGroup(inputParticle, isLocal) {
296
441
  // Update the particle position
297
442
  const updatePosition = new UpdatePositionBlock("Position Update");
298
443
  inputParticle.connectTo(updatePosition.particle);
@@ -309,7 +454,22 @@ function _CreatePositionUpdate(inputParticle, isLocal) {
309
454
  }
310
455
  return updatePosition.output;
311
456
  }
312
- function _CreateGravityUpdate(inputParticle, gravity) {
457
+ function _UpdateParticleSizeGradientBlockGroup(inputParticle, sizeGradients, context) {
458
+ if (context.sizeGradientValue0Output === undefined) {
459
+ throw new Error("Initial size gradient values not found in context.");
460
+ }
461
+ context.ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup(context);
462
+ // Generate the gradient
463
+ const sizeValueOutput = _CreateGradientBlockGroup(context.ageToLifeTimeRatioBlockGroupOutput, sizeGradients, ParticleRandomBlockLocks.OncePerParticle, "Size", [
464
+ context.sizeGradientValue0Output,
465
+ ]);
466
+ // Create the update size
467
+ const updateSizeBlock = new UpdateSizeBlock("Size Update");
468
+ inputParticle.connectTo(updateSizeBlock.particle);
469
+ sizeValueOutput.connectTo(updateSizeBlock.size);
470
+ return updateSizeBlock.output;
471
+ }
472
+ function _UpdateParticleGravityBlockGroup(inputParticle, gravity) {
313
473
  // Create the gravity delta
314
474
  const gravityDeltaOutput = _CreateDeltaModifiedInput("Gravity", gravity);
315
475
  // Add it to the direction
@@ -323,90 +483,17 @@ function _CreateGravityUpdate(inputParticle, gravity) {
323
483
  addDirectionBlock.output.connectTo(updateDirection.direction);
324
484
  return updateDirection.output;
325
485
  }
326
- function _CreateColorUpdateBlock(oldSystem, createParticleBlock) {
327
- if (!oldSystem) {
328
- throw new Error("Invalid particle system");
329
- }
330
- // Calculate the color
331
- const colorGradients = oldSystem.getColorGradients();
332
- let colorBlock = null;
333
- if (colorGradients && colorGradients.length > 0) {
334
- colorBlock = _CreateGradientColorUpdate(oldSystem, colorGradients, createParticleBlock);
335
- }
336
- else {
337
- colorBlock = _CreateBasicColorUpdate(oldSystem, createParticleBlock);
338
- }
339
- // Clamp alpha >= 0
340
- const clampedColor = _ClampUpdateColorAlpha(colorBlock);
341
- // Create the color update block
342
- const colorUpdateBlock = new UpdateColorBlock("Color update");
343
- clampedColor.colorOut.connectTo(colorUpdateBlock.color);
344
- return colorUpdateBlock;
345
- }
346
- function _CreateGradientColorUpdate(oldSystem, gradient, createParticleBlock) {
347
- const colorGradientBlock = new ParticleGradientBlock("Color Gradient");
348
- _CreateAndConnectContextualSource("gradient", NodeParticleContextualSources.Age, colorGradientBlock.gradient);
349
- let tempColor = null;
350
- let colorStart = null;
351
- let colorEnd = null;
352
- for (let i = 0; i < gradient.length; i++) {
353
- const gradientStep = gradient[i];
354
- const gradientValueBlock = new ParticleGradientValueBlock("Color Gradient Value " + i);
355
- gradientValueBlock.reference = gradientStep.gradient;
356
- if (gradientStep.color2) {
357
- // Create a random between color1 and color2
358
- const randomColorBlock = new ParticleRandomBlock("Random Color for Gradient " + i);
359
- randomColorBlock.lockMode = ParticleRandomBlockLocks.PerSystem;
360
- _CreateAndConnectInput("Color 1", gradientStep.color1, randomColorBlock.min);
361
- _CreateAndConnectInput("Color 2", gradientStep.color2, randomColorBlock.max);
362
- randomColorBlock.output.connectTo(gradientValueBlock.value);
363
- tempColor = randomColorBlock;
364
- }
365
- else {
366
- // Single color
367
- const input = new ParticleInputBlock("Color " + i);
368
- input.value = gradientStep.color1;
369
- input.output.connectTo(gradientValueBlock.value);
370
- tempColor = input;
371
- }
372
- if (gradientStep.gradient === 0) {
373
- colorStart = tempColor;
374
- }
375
- else if (gradientStep.gradient === 1) {
376
- colorEnd = tempColor;
377
- }
378
- gradientValueBlock.output.connectTo(colorGradientBlock.inputs[i + 1]);
379
- }
380
- _UpdateCreateParticleColor(oldSystem, colorStart, colorEnd, createParticleBlock);
381
- return colorGradientBlock;
382
- }
383
- function _CreateBasicColorUpdate(oldSystem, createParticleBlock) {
486
+ function _CreateBasicColorUpdate() {
384
487
  const addColorBlock = new ParticleMathBlock("Add Color");
385
488
  addColorBlock.operation = ParticleMathBlockOperations.Add;
386
489
  _CreateAndConnectContextualSource("Color", NodeParticleContextualSources.Color, addColorBlock.left);
387
490
  _CreateAndConnectContextualSource("Scaled Color Step", NodeParticleContextualSources.ScaledColorStep, addColorBlock.right);
388
- _UpdateCreateParticleColor(oldSystem, null, null, createParticleBlock);
389
- return addColorBlock;
390
- }
391
- function _UpdateCreateParticleColor(oldSystem, colorStart, colorEnd, createParticleBlock) {
392
- if (colorStart === null) {
393
- colorStart = new ParticleInputBlock("Color Start");
394
- colorStart.value = oldSystem.color1;
395
- }
396
- if (colorEnd === null) {
397
- colorEnd = new ParticleInputBlock("Color End");
398
- colorEnd.value = oldSystem.color2;
399
- }
400
- const randomColorBlock = new ParticleRandomBlock("Random color");
401
- randomColorBlock.lockMode = ParticleRandomBlockLocks.PerParticle;
402
- colorStart.output.connectTo(randomColorBlock.min);
403
- colorEnd.output.connectTo(randomColorBlock.max);
404
- randomColorBlock.output.connectTo(createParticleBlock.color);
491
+ return addColorBlock.output;
405
492
  }
406
- function _ClampUpdateColorAlpha(colorBlock) {
493
+ function _ClampUpdateColorAlpha(colorCalculationOutput) {
407
494
  // Decompose color to clamp alpha
408
495
  const decomposeColorBlock = new ParticleConverterBlock("Decompose Color");
409
- colorBlock.outputs[0].connectTo(decomposeColorBlock.colorIn);
496
+ colorCalculationOutput.connectTo(decomposeColorBlock.colorIn);
410
497
  // Clamp alpha to be >= 0
411
498
  const maxAlphaBlock = new ParticleMathBlock("Alpha >= 0");
412
499
  maxAlphaBlock.operation = ParticleMathBlockOperations.Max;
@@ -416,8 +503,9 @@ function _ClampUpdateColorAlpha(colorBlock) {
416
503
  const composeColorBlock = new ParticleConverterBlock("Compose Color");
417
504
  decomposeColorBlock.xyzOut.connectTo(composeColorBlock.xyzIn);
418
505
  maxAlphaBlock.output.connectTo(composeColorBlock.wIn);
419
- return composeColorBlock;
506
+ return composeColorBlock.colorOut;
420
507
  }
508
+ // ------------- UTILITY FUNCTIONS -------------
421
509
  function _CreateDeltaModifiedInput(name, value) {
422
510
  const multiplyBlock = new ParticleMathBlock("Multiply by Delta");
423
511
  multiplyBlock.operation = ParticleMathBlockOperations.Multiply;
@@ -448,8 +536,8 @@ function _CreateAndConnectSystemSource(systemBlockName, systemSource, targetToCo
448
536
  /**
449
537
  * Creates the target stop duration input block, as it can be shared in multiple places
450
538
  * This block is stored in the context so the same block is shared in the graph
451
- * @param oldSystem The old particle system to migrate
452
- * @param context The system migration context
539
+ * @param oldSystem The old particle system to convert
540
+ * @param context The context of the current conversion
453
541
  * @returns
454
542
  */
455
543
  function _CreateTargetStopDurationInputBlock(oldSystem, context) {
@@ -468,8 +556,8 @@ function _CreateTargetStopDurationInputBlock(oldSystem, context) {
468
556
  * Create a group of blocks that calculates the ratio between the actual frame and the target stop duration, clamped between 0 and 1.
469
557
  * This is used to simulate the behavior of the old particle system where several particle gradient values are affected by the target stop duration.
470
558
  * This block group is stored in the context so the same group is shared in the graph
471
- * @param oldSystem The old particle system to migrate
472
- * @param context The system migration context
559
+ * @param oldSystem The old particle system to convert
560
+ * @param context The context of the current conversion
473
561
  * @returns The ratio block output connection point
474
562
  */
475
563
  function _CreateTimeToStopTimeRatioBlockGroup(oldSystem, context) {
@@ -497,19 +585,45 @@ function _CreateTimeToStopTimeRatioBlockGroup(oldSystem, context) {
497
585
  context.timeToStopTimeRatioBlockGroupOutput = clampMax.output;
498
586
  return context.timeToStopTimeRatioBlockGroupOutput;
499
587
  }
588
+ function _CreateAgeToLifeTimeRatioBlockGroup(context) {
589
+ // If we have already generated this group, return it
590
+ if (context.ageToLifeTimeRatioBlockGroupOutput) {
591
+ return context.ageToLifeTimeRatioBlockGroupOutput;
592
+ }
593
+ // Find the ratio between the age and the lifetime
594
+ const ratio = new ParticleMathBlock("Age/LifeTime Ratio");
595
+ ratio.operation = ParticleMathBlockOperations.Divide;
596
+ _CreateAndConnectContextualSource("Age", NodeParticleContextualSources.Age, ratio.left);
597
+ _CreateAndConnectContextualSource("LifeTime", NodeParticleContextualSources.Lifetime, ratio.right);
598
+ // Save the group output in our context to avoid regenerating it again
599
+ context.ageToLifeTimeRatioBlockGroupOutput = ratio.output;
600
+ return ratio.output;
601
+ }
500
602
  /**
501
603
  * Creates the blocks that represent a gradient
502
604
  * @param gradientSelector The value that determines which gradient to use
503
605
  * @param gradientValues The list of gradient values
606
+ * @param randomLockMode The type of random to use for the gradient values
607
+ * @param prefix The prefix to use for naming the blocks
608
+ * @param initialValues Optional initial values to connect to the gradient inputs that were calculated during other steps of the conversion
504
609
  * @returns The output connection point of the gradient block
505
610
  */
506
- function _CreateGradientBlockGroup(gradientSelector, gradientValues) {
611
+ function _CreateGradientBlockGroup(gradientSelector, gradientValues, randomLockMode, prefix, initialValues = []) {
507
612
  // Create the gradient block and connect the value that controls the gradient selection
508
- const gradientBlock = new ParticleGradientBlock("Gradient Block");
613
+ const gradientBlock = new ParticleGradientBlock(prefix + " Gradient Block");
509
614
  gradientSelector.connectTo(gradientBlock.gradient);
615
+ // If initial values are provided, we use them instead of the values in the gradientValues array
616
+ // These means this values were already transformed into blocks on a previous step of the conversion and we must reuse them
617
+ for (let i = 0; i < initialValues.length; i++) {
618
+ const reference = i < gradientValues.length ? gradientValues[i].gradient : 1;
619
+ const gradientValueBlock = new ParticleGradientValueBlock(prefix + " Gradient Value " + i);
620
+ gradientValueBlock.reference = reference;
621
+ initialValues[i].connectTo(gradientValueBlock.value);
622
+ gradientValueBlock.output.connectTo(gradientBlock.inputs[i + 1]);
623
+ }
510
624
  // Create the gradient values
511
- for (let i = 0; i < gradientValues.length; i++) {
512
- const gradientValueBlockGroupOutput = _CreateGradientValueBlockGroup(gradientValues[i], i);
625
+ for (let i = 0 + initialValues.length; i < gradientValues.length; i++) {
626
+ const gradientValueBlockGroupOutput = _CreateGradientValueBlockGroup(gradientValues[i], randomLockMode, prefix, i);
513
627
  gradientValueBlockGroupOutput.connectTo(gradientBlock.inputs[i + 1]);
514
628
  }
515
629
  return gradientBlock.output;
@@ -518,23 +632,27 @@ function _CreateGradientBlockGroup(gradientSelector, gradientValues) {
518
632
  * Creates the blocks that represent a gradient value
519
633
  * This can be either a single value or a random between two values
520
634
  * @param gradientStep The gradient step data
635
+ * @param randomLockMode The lock mode to use for random values
636
+ * @param prefix The prefix to use for naming the blocks
521
637
  * @param index The index of the gradient step
522
638
  * @returns The output connection point of the gradient value block
523
639
  */
524
- function _CreateGradientValueBlockGroup(gradientStep, index) {
525
- const gradientValueBlock = new ParticleGradientValueBlock("Gradient Value " + index);
640
+ function _CreateGradientValueBlockGroup(gradientStep, randomLockMode, prefix, index) {
641
+ const gradientValueBlock = new ParticleGradientValueBlock(prefix + " Gradient Value " + index);
526
642
  gradientValueBlock.reference = gradientStep.gradient;
527
- if (gradientStep.factor2 !== undefined) {
643
+ const value1 = gradientStep.factor1 ?? gradientStep.color1;
644
+ const value2 = gradientStep.factor2 ?? gradientStep.color2;
645
+ if (value2 !== undefined) {
528
646
  // Create a random between value1 and value2
529
- const randomBlock = new ParticleRandomBlock("Random Gradient Value " + index);
530
- randomBlock.lockMode = ParticleRandomBlockLocks.PerParticle;
531
- _CreateAndConnectInput("Value 1", gradientStep.factor1, randomBlock.min);
532
- _CreateAndConnectInput("Value 2", gradientStep.factor2, randomBlock.max);
647
+ const randomBlock = new ParticleRandomBlock("Random Value " + index);
648
+ randomBlock.lockMode = randomLockMode;
649
+ _CreateAndConnectInput("Value 1", value1, randomBlock.min);
650
+ _CreateAndConnectInput("Value 2", value2, randomBlock.max);
533
651
  randomBlock.output.connectTo(gradientValueBlock.value);
534
652
  }
535
653
  else {
536
654
  // Single value
537
- _CreateAndConnectInput("Value", gradientStep.factor1, gradientValueBlock.value);
655
+ _CreateAndConnectInput("Value", value1, gradientValueBlock.value);
538
656
  }
539
657
  return gradientValueBlock.output;
540
658
  }