11import type { Nullable } from "core/types" ;
22import type { ParticleSystem } from "../particleSystem" ;
3- import { NodeParticleSystemSet } from "./nodeParticleSystemSet" ;
4- import { SystemBlock } from "./Blocks/systemBlock" ;
5- import { CreateParticleBlock } from "./Blocks/Emitters/createParticleBlock" ;
6- import { BoxShapeBlock } from "./Blocks/Emitters/boxShapeBlock" ;
73import type { IShapeBlock } from "./Blocks/Emitters/IShapeBlock" ;
84import type { Vector3 } from "core/Maths/math.vector" ;
5+ import type { Color4 } from "core/Maths/math.color" ;
96import type { NodeParticleConnectionPoint } from "./nodeParticleBlockConnectionPoint" ;
107import type { BoxParticleEmitter } from "../EmitterTypes/boxParticleEmitter" ;
118import type { PointParticleEmitter } from "../EmitterTypes/pointParticleEmitter" ;
129import type { SphereParticleEmitter } from "../EmitterTypes/sphereParticleEmitter" ;
1310import type { CylinderParticleEmitter , MeshParticleEmitter } from "../EmitterTypes" ;
1411import type { Mesh } from "core/Meshes/mesh" ;
12+ import type { Texture } from "core/Materials/Textures/texture" ;
13+
14+ import { NodeParticleSystemSet } from "./nodeParticleSystemSet" ;
15+ import { SystemBlock } from "./Blocks/systemBlock" ;
16+ import { CreateParticleBlock } from "./Blocks/Emitters/createParticleBlock" ;
17+ import { BoxShapeBlock } from "./Blocks/Emitters/boxShapeBlock" ;
1518import { ParticleInputBlock } from "./Blocks/particleInputBlock" ;
1619import { PointShapeBlock } from "./Blocks/Emitters/pointShapeBlock" ;
1720import { SphereShapeBlock } from "./Blocks/Emitters/sphereShapeBlock" ;
1821import { CylinderShapeBlock } from "./Blocks/Emitters/cylinderShapeBlock" ;
1922import { MeshShapeBlock } from "./Blocks/Emitters/meshShapeBlock" ;
2023import { ParticleTextureSourceBlock } from "./Blocks/particleSourceTextureBlock" ;
21- import type { Texture } from "../../Materials/Textures/texture" ;
22- import { BasicPositionUpdateBlock } from "./Blocks/Update/basicPositionUpdateBlock" ;
23- import { BasicColorUpdateBlock } from "./Blocks/Update/basicColorUpdateBlock" ;
2424import { ParticleRandomBlock } from "./Blocks/particleRandomBlock" ;
25+ import { ParticleConverterBlock } from "./Blocks/particleConverterBlock" ;
26+ import { ParticleMathBlock , ParticleMathBlockOperations } from "./Blocks/particleMathBlock" ;
27+ import { UpdateColorBlock } from "./Blocks/Update/updateColorBlock" ;
28+ import { UpdatePositionBlock } from "./Blocks/Update/updatePositionBlock" ;
29+ import { NodeParticleContextualSources } from "./Enums/nodeParticleContextualSources" ;
2530
26- function _CreateAndConnectInput ( connectionPoint : NodeParticleConnectionPoint , name : string , defaultValue : Vector3 | number ) {
27- const input = new ParticleInputBlock ( name ) ;
28- input . value = defaultValue ;
29- input . output . connectTo ( connectionPoint ) ;
31+ /**
32+ * Converts a ParticleSystem to a NodeParticleSystemSet.
33+ * @param name The name of the node particle system set.
34+ * @param particleSystems The particle systems to convert.
35+ * @returns The converted node particle system set or null if conversion failed.
36+ * #0K3AQ2#3670
37+ */
38+ export async function ConvertToNodeParticleSystemSetAsync ( name : string , particleSystems : ParticleSystem [ ] ) : Promise < Nullable < NodeParticleSystemSet > > {
39+ if ( ! particleSystems || ! particleSystems . length ) {
40+ return null ;
41+ }
42+
43+ const nodeParticleSystemSet = new NodeParticleSystemSet ( name ) ;
44+ const promises : Promise < void > [ ] = [ ] ;
45+
46+ for ( const particleSystem of particleSystems ) {
47+ promises . push ( _ExtractDatafromParticleSystemAsync ( particleSystem , nodeParticleSystemSet ) ) ;
48+ }
49+
50+ await Promise . all ( promises ) ;
51+ return nodeParticleSystemSet ;
3052}
3153
3254async function _ExtractDatafromParticleSystemAsync ( particleSystem : ParticleSystem , target : NodeParticleSystemSet ) {
@@ -36,59 +58,59 @@ async function _ExtractDatafromParticleSystemAsync(particleSystem: ParticleSyste
3658 system . emitRate = particleSystem . emitRate ;
3759
3860 // Create particle
39- const createParticleBlock = new CreateParticleBlock ( "Create particle " ) ;
61+ const createParticleBlock = new CreateParticleBlock ( "Create Particle " ) ;
4062
4163 // Shape
4264 let shapeBlock : Nullable < IShapeBlock > = null ;
4365 switch ( particleSystem . particleEmitterType . getClassName ( ) ) {
4466 case "BoxParticleEmitter" : {
4567 const source = particleSystem . particleEmitterType as BoxParticleEmitter ;
46- shapeBlock = new BoxShapeBlock ( "Box shape " ) ;
68+ shapeBlock = new BoxShapeBlock ( "Box Shape " ) ;
4769
4870 const target = shapeBlock as BoxShapeBlock ;
49- _CreateAndConnectInput ( target . direction1 , "Direction 1" , source . direction1 ) ;
50- _CreateAndConnectInput ( target . direction2 , "Direction 2" , source . direction2 ) ;
51- _CreateAndConnectInput ( target . minEmitBox , "Min Emit Box" , source . minEmitBox ) ;
52- _CreateAndConnectInput ( target . maxEmitBox , "Max Emit Box" , source . maxEmitBox ) ;
71+ _CreateAndConnectInput ( "Direction 1" , source . direction1 , target . direction1 ) ;
72+ _CreateAndConnectInput ( "Direction 2" , source . direction2 , target . direction2 ) ;
73+ _CreateAndConnectInput ( "Min Emit Box" , source . minEmitBox , target . minEmitBox ) ;
74+ _CreateAndConnectInput ( "Max Emit Box" , source . maxEmitBox , target . maxEmitBox ) ;
5375 break ;
5476 }
5577 case "PointParticleEmitter" : {
5678 const source = particleSystem . particleEmitterType as PointParticleEmitter ;
57- shapeBlock = new PointShapeBlock ( "Point shape " ) ;
79+ shapeBlock = new PointShapeBlock ( "Point Shape " ) ;
5880
5981 const target = shapeBlock as PointShapeBlock ;
60- _CreateAndConnectInput ( target . direction1 , "Direction 1" , source . direction1 ) ;
61- _CreateAndConnectInput ( target . direction2 , "Direction 2" , source . direction2 ) ;
82+ _CreateAndConnectInput ( "Direction 1" , source . direction1 , target . direction1 ) ;
83+ _CreateAndConnectInput ( "Direction 2" , source . direction2 , target . direction2 ) ;
6284 break ;
6385 }
6486 case "SphereParticleEmitter" : {
6587 const source = particleSystem . particleEmitterType as SphereParticleEmitter ;
66- shapeBlock = new SphereShapeBlock ( "Sphere shape " ) ;
88+ shapeBlock = new SphereShapeBlock ( "Sphere Shape " ) ;
6789
6890 const target = shapeBlock as SphereShapeBlock ;
69- _CreateAndConnectInput ( target . radius , "Radius" , source . radius ) ;
70- _CreateAndConnectInput ( target . radiusRange , "Radius Range" , source . radiusRange ) ;
71- _CreateAndConnectInput ( target . directionRandomizer , "Direction Randomizer" , source . directionRandomizer ) ;
91+ _CreateAndConnectInput ( "Radius" , source . radius , target . radius ) ;
92+ _CreateAndConnectInput ( "Radius Range" , source . radiusRange , target . radiusRange ) ;
93+ _CreateAndConnectInput ( "Direction Randomizer" , source . directionRandomizer , target . directionRandomizer ) ;
7294 break ;
7395 }
7496 case "CylinderParticleEmitter" : {
7597 const source = particleSystem . particleEmitterType as CylinderParticleEmitter ;
76- shapeBlock = new CylinderShapeBlock ( "Cylinder shape " ) ;
98+ shapeBlock = new CylinderShapeBlock ( "Cylinder Shape " ) ;
7799
78100 const target = shapeBlock as CylinderShapeBlock ;
79- _CreateAndConnectInput ( target . height , "Height" , source . height ) ;
80- _CreateAndConnectInput ( target . radius , "Radius" , source . radius ) ;
81- _CreateAndConnectInput ( target . radiusRange , "Radius Range" , source . radiusRange ) ;
82- _CreateAndConnectInput ( target . directionRandomizer , "Direction Randomizer" , source . directionRandomizer ) ;
101+ _CreateAndConnectInput ( "Height" , source . height , target . height ) ;
102+ _CreateAndConnectInput ( "Radius" , source . radius , target . radius ) ;
103+ _CreateAndConnectInput ( "Radius Range" , source . radiusRange , target . radiusRange ) ;
104+ _CreateAndConnectInput ( "Direction Randomizer" , source . directionRandomizer , target . directionRandomizer ) ;
83105 break ;
84106 }
85107 case "MeshParticleEmitter" : {
86108 const source = particleSystem . particleEmitterType as MeshParticleEmitter ;
87- shapeBlock = new MeshShapeBlock ( "Mesh shape " ) ;
109+ shapeBlock = new MeshShapeBlock ( "Mesh Shape " ) ;
88110
89111 const target = shapeBlock as MeshShapeBlock ;
90- _CreateAndConnectInput ( target . direction1 , "Direction 1" , source . direction1 ) ;
91- _CreateAndConnectInput ( target . direction2 , "Direction 2" , source . direction2 ) ;
112+ _CreateAndConnectInput ( "Direction 1" , source . direction1 , target . direction1 ) ;
113+ _CreateAndConnectInput ( "Direction 2" , source . direction2 , target . direction2 ) ;
92114
93115 target . mesh = source . mesh as Mesh ;
94116 break ;
@@ -100,45 +122,26 @@ async function _ExtractDatafromParticleSystemAsync(particleSystem: ParticleSyste
100122 }
101123
102124 createParticleBlock . particle . connectTo ( shapeBlock . particle ) ;
103- createParticleBlock . colorDead . value = particleSystem . colorDead ;
104125
105- // Color
106- const color0Block = new ParticleInputBlock ( "Color0" ) ;
107- color0Block . value = particleSystem . color1 ;
108-
109- const color1Block = new ParticleInputBlock ( "Color1" ) ;
110- color1Block . value = particleSystem . color2 ;
126+ // Dead color
127+ _CreateAndConnectInput ( "Dead Color" , particleSystem . colorDead , createParticleBlock . colorDead ) ;
111128
129+ // Color
112130 const randomColorBlock = new ParticleRandomBlock ( "Random Color" ) ;
113- color0Block . output . connectTo ( randomColorBlock . min ) ;
114- color1Block . output . connectTo ( randomColorBlock . max ) ;
115-
131+ _CreateAndConnectInput ( "Color 1" , particleSystem . color1 , randomColorBlock . min ) ;
132+ _CreateAndConnectInput ( "Color 2" , particleSystem . color2 , randomColorBlock . max ) ;
116133 randomColorBlock . output . connectTo ( createParticleBlock . color ) ;
117134
118135 // Emit power
119- const minEmitPowerBlock = new ParticleInputBlock ( "Min Emit Power" ) ;
120- minEmitPowerBlock . value = particleSystem . minEmitPower ;
121-
122- const maxEmitPowerBlock = new ParticleInputBlock ( "Max Emit Power" ) ;
123- maxEmitPowerBlock . value = particleSystem . maxEmitPower ;
124-
125136 const randomEmitPowerBlock = new ParticleRandomBlock ( "Random Emit Power" ) ;
126- minEmitPowerBlock . output . connectTo ( randomEmitPowerBlock . min ) ;
127- maxEmitPowerBlock . output . connectTo ( randomEmitPowerBlock . max ) ;
128-
137+ _CreateAndConnectInput ( "Min Emit Power" , particleSystem . minEmitPower , randomEmitPowerBlock . min ) ;
138+ _CreateAndConnectInput ( "Max Emit Power" , particleSystem . maxEmitPower , randomEmitPowerBlock . max ) ;
129139 randomEmitPowerBlock . output . connectTo ( createParticleBlock . emitPower ) ;
130140
131141 // Lifetime
132- const minLifetimeBlock = new ParticleInputBlock ( "Min Lifetime" ) ;
133- minLifetimeBlock . value = particleSystem . minLifeTime ;
134-
135- const maxLifetimeBlock = new ParticleInputBlock ( "Max Lifetime" ) ;
136- maxLifetimeBlock . value = particleSystem . maxLifeTime ;
137-
138142 const randomLifetimeBlock = new ParticleRandomBlock ( "Random Lifetime" ) ;
139- minLifetimeBlock . output . connectTo ( randomLifetimeBlock . min ) ;
140- maxLifetimeBlock . output . connectTo ( randomLifetimeBlock . max ) ;
141-
143+ _CreateAndConnectInput ( "Min Lifetime" , particleSystem . minLifeTime , randomLifetimeBlock . min ) ;
144+ _CreateAndConnectInput ( "Max Lifetime" , particleSystem . maxLifeTime , randomLifetimeBlock . max ) ;
142145 randomLifetimeBlock . output . connectTo ( createParticleBlock . lifeTime ) ;
143146
144147 // Texture
@@ -152,37 +155,53 @@ async function _ExtractDatafromParticleSystemAsync(particleSystem: ParticleSyste
152155 textureBlock . texture . connectTo ( system . texture ) ;
153156
154157 // Default position update
155- const basicPositionUpdateBlock = new BasicPositionUpdateBlock ( "Position update" ) ;
156- shapeBlock . output . connectTo ( basicPositionUpdateBlock . particle ) ;
158+ const positionUpdateblock = new UpdatePositionBlock ( "Position update" ) ;
159+ shapeBlock . output . connectTo ( positionUpdateblock . particle ) ;
160+
161+ const addPositionBlock = new ParticleMathBlock ( "Add Position" ) ;
162+ addPositionBlock . operation = ParticleMathBlockOperations . Add ;
163+ _CreateAndConnectContextual ( "Position" , NodeParticleContextualSources . Position , addPositionBlock . left ) ;
164+ _CreateAndConnectContextual ( "Scaled Direction" , NodeParticleContextualSources . ScaledDirection , addPositionBlock . right ) ;
165+ addPositionBlock . output . connectTo ( positionUpdateblock . position ) ;
157166
158167 // Default color update
159- const basicColorUpdateBlock = new BasicColorUpdateBlock ( "Color update" ) ;
160- basicPositionUpdateBlock . output . connectTo ( basicColorUpdateBlock . particle ) ;
161- basicColorUpdateBlock . output . connectTo ( system . particle ) ;
168+ const colorUpdateblock = new UpdateColorBlock ( "Color update" ) ;
169+ positionUpdateblock . output . connectTo ( colorUpdateblock . particle ) ;
170+
171+ const addColorBlock = new ParticleMathBlock ( "Add Color" ) ;
172+ addColorBlock . operation = ParticleMathBlockOperations . Add ;
173+ _CreateAndConnectContextual ( "Color" , NodeParticleContextualSources . Color , addColorBlock . left ) ;
174+ _CreateAndConnectContextual ( "Scaled Color Step" , NodeParticleContextualSources . ScaledColorStep , addColorBlock . right ) ;
175+ addColorBlock . output . connectTo ( colorUpdateblock . color ) ;
176+
177+ const decomposeColorBlock = new ParticleConverterBlock ( "Decompose Color" ) ;
178+ addColorBlock . output . connectTo ( decomposeColorBlock . colorIn ) ;
179+
180+ // Clamp alpha to be >= 0
181+ const maxAlphaBlock = new ParticleMathBlock ( "Alpha >= 0" ) ;
182+ maxAlphaBlock . operation = ParticleMathBlockOperations . Max ;
183+ decomposeColorBlock . wOut . connectTo ( maxAlphaBlock . left ) ;
184+ _CreateAndConnectInput ( "Zero" , 0 , maxAlphaBlock . right ) ;
185+
186+ const composeColorBlock = new ParticleConverterBlock ( "Compose Color" ) ;
187+ decomposeColorBlock . xyzOut . connectTo ( composeColorBlock . xyzIn ) ;
188+ maxAlphaBlock . output . connectTo ( composeColorBlock . wIn ) ;
189+ composeColorBlock . colorOut . connectTo ( colorUpdateblock . color ) ;
190+
191+ colorUpdateblock . output . connectTo ( system . particle ) ;
162192
163193 // Register
164194 target . systemBlocks . push ( system ) ;
165195}
166196
167- /**
168- * Converts a ParticleSystem to a NodeParticleSystemSet.
169- * @param name The name of the node particle system set.
170- * @param particleSystems The particle systems to convert.
171- * @returns The converted node particle system set or null if conversion failed.
172- * #0K3AQ2#3627
173- */
174- export async function ConvertToNodeParticleSystemSetAsync ( name : string , particleSystems : ParticleSystem [ ] ) : Promise < Nullable < NodeParticleSystemSet > > {
175- if ( ! particleSystems || ! particleSystems . length ) {
176- return null ;
177- }
178-
179- const nodeParticleSystemSet = new NodeParticleSystemSet ( name ) ;
180- const promises : Promise < void > [ ] = [ ] ;
181-
182- for ( const particleSystem of particleSystems ) {
183- promises . push ( _ExtractDatafromParticleSystemAsync ( particleSystem , nodeParticleSystemSet ) ) ;
184- }
197+ function _CreateAndConnectInput ( inputBlockName : string , value : number | Vector3 | Color4 , outputToConnectTo : NodeParticleConnectionPoint ) {
198+ const input = new ParticleInputBlock ( inputBlockName ) ;
199+ input . value = value ;
200+ input . output . connectTo ( outputToConnectTo ) ;
201+ }
185202
186- await Promise . all ( promises ) ;
187- return nodeParticleSystemSet ;
203+ function _CreateAndConnectContextual ( contextualBlockName : string , contextValue : NodeParticleContextualSources , outputToConnectTo : NodeParticleConnectionPoint ) : void {
204+ const input = new ParticleInputBlock ( contextualBlockName ) ;
205+ input . contextualValue = contextValue ;
206+ input . output . connectTo ( outputToConnectTo ) ;
188207}
0 commit comments