@@ -52,6 +52,8 @@ type ConversionContext = {
5252 // Connections for the start value of a gradient. These are stored so they can be reused for the Creation phase and the Update phase of the particle
5353 sizeGradientValue0Output : NodeParticleConnectionPoint ;
5454 colorGradientValue0Output : NodeParticleConnectionPoint ;
55+ // Updated scaled direction direction based on velocity and drag
56+ scaledDirection : NodeParticleConnectionPoint ;
5557} ;
5658
5759type RuntimeConversionContext = Partial < ConversionContext > ;
@@ -134,7 +136,7 @@ function _SystemBlockGroup(oldSystem: ParticleSystem, context: RuntimeConversion
134136// ------------- CREATE PARTICLE FUNCTIONS -------------
135137
136138// The creation of the different properties follows the order they are added to the CreationQueue in ThinParticleSystem:
137- // Lifetime, Emit Power, Size, Scale/StartSize, Angle, Velocity, VelocityLimit, Color, Drag, Noise, ColorDead, Ramp, Sheet
139+ // Lifetime, Emit Power, Size, Scale/StartSize, Angle, VelocityLimit, Color, Drag, Noise, ColorDead, Ramp, Sheet
138140function _CreateParticleBlockGroup ( oldSystem : ParticleSystem , context : RuntimeConversionContext ) : CreateParticleBlock {
139141 // Create particle block
140142 const createParticleBlock = new CreateParticleBlock ( "Create Particle" ) ;
@@ -453,7 +455,12 @@ function _UpdateParticleBlockGroup(inputParticle: NodeParticleConnectionPoint, o
453455
454456 updateBlockGroupOutput = _UpdateParticleColorBlockGroup ( updateBlockGroupOutput , oldSystem . _colorGradients , context ) ;
455457 updateBlockGroupOutput = _UpdateParticleAngleBlockGroup ( updateBlockGroupOutput , oldSystem , context ) ;
456- updateBlockGroupOutput = _UpdateParticlePositionBlockGroup ( updateBlockGroupOutput , oldSystem . isLocal ) ;
458+
459+ if ( oldSystem . _velocityGradients && oldSystem . _velocityGradients . length > 0 ) {
460+ context . scaledDirection = _UpdateParticleVelocityGradientBlockGroup ( updateBlockGroupOutput , oldSystem . _velocityGradients , context ) ;
461+ }
462+
463+ updateBlockGroupOutput = _UpdateParticlePositionBlockGroup ( updateBlockGroupOutput , oldSystem . isLocal , context ) ;
457464
458465 if ( oldSystem . _sizeGradients && oldSystem . _sizeGradients . length > 0 ) {
459466 updateBlockGroupOutput = _UpdateParticleSizeGradientBlockGroup ( updateBlockGroupOutput , oldSystem . _sizeGradients , context ) ;
@@ -466,6 +473,13 @@ function _UpdateParticleBlockGroup(inputParticle: NodeParticleConnectionPoint, o
466473 return updateBlockGroupOutput ;
467474}
468475
476+ /**
477+ * Creates the group of blocks that represent the particle color update
478+ * @param inputParticle The input particle to update
479+ * @param colorGradients The color gradients (if any)
480+ * @param context The context of the current conversion
481+ * @returns The output of the group of blocks that represent the particle color update
482+ */
469483function _UpdateParticleColorBlockGroup (
470484 inputParticle : NodeParticleConnectionPoint ,
471485 colorGradients : Nullable < Array < ColorGradient > > ,
@@ -482,7 +496,7 @@ function _UpdateParticleColorBlockGroup(
482496 context . colorGradientValue0Output ,
483497 ] ) ;
484498 } else {
485- colorCalculation = _CreateBasicColorUpdate ( ) ;
499+ colorCalculation = _BasicColorUpdateBlockGroup ( ) ;
486500 }
487501
488502 // Create the color update block clamping alpha >= 0
@@ -493,6 +507,13 @@ function _UpdateParticleColorBlockGroup(
493507 return colorUpdateBlock . output ;
494508}
495509
510+ /**
511+ * Creates the group of blocks that represent the particle angle update
512+ * @param inputParticle The input particle to update
513+ * @param oldSystem The old particle system to convert
514+ * @param context The context of the current conversion
515+ * @returns The output of the group of blocks that represent the particle color update
516+ */
496517function _UpdateParticleAngleBlockGroup ( inputParticle : NodeParticleConnectionPoint , oldSystem : ParticleSystem , context : RuntimeConversionContext ) : NodeParticleConnectionPoint {
497518 // We will try to use gradients if they exist
498519 // If not, we will try to use min/max angular speed
@@ -525,29 +546,48 @@ function _UpdateParticleAngleBlockGroup(inputParticle: NodeParticleConnectionPoi
525546 }
526547}
527548
528- function _UpdateParticleAngularSpeedGradientBlockGroup ( angularSpeedGradients : Array < FactorGradient > , context : RuntimeConversionContext ) : NodeParticleConnectionPoint {
549+ /**
550+ * Creates the group of blocks that represent the particle velocity update
551+ * @param inputParticle The input particle to update
552+ * @param velocityGradients The velocity gradients (if any)
553+ * @param context The context of the current conversion
554+ * @returns The output of the group of blocks that represent the particle velocity update
555+ */
556+ function _UpdateParticleVelocityGradientBlockGroup (
557+ inputParticle : NodeParticleConnectionPoint ,
558+ velocityGradients : Array < FactorGradient > ,
559+ context : RuntimeConversionContext
560+ ) : NodeParticleConnectionPoint {
529561 context . ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup ( context ) ;
530562
531563 // Generate the gradient
532- const angularSpeedValueOutput = _CreateGradientBlockGroup (
533- context . ageToLifeTimeRatioBlockGroupOutput ,
534- angularSpeedGradients ,
535- ParticleRandomBlockLocks . OncePerParticle ,
536- "Angular Speed"
537- ) ;
538- return angularSpeedValueOutput ;
539- }
540-
541- function _UpdateParticleAngularSpeedBlockGroup ( minAngularSpeed : number , maxAngularSpeed : number ) : NodeParticleConnectionPoint {
542- // Random value between for the angular speed of the particle
543- const randomAngularSpeedBlock = new ParticleRandomBlock ( "Random Angular Speed" ) ;
544- randomAngularSpeedBlock . lockMode = ParticleRandomBlockLocks . OncePerParticle ;
545- _CreateAndConnectInput ( "Min Angular Speed" , minAngularSpeed , randomAngularSpeedBlock . min ) ;
546- _CreateAndConnectInput ( "Max Angular Speed" , maxAngularSpeed , randomAngularSpeedBlock . max ) ;
547- return randomAngularSpeedBlock . output ;
564+ const velocityValueOutput = _CreateGradientBlockGroup ( context . ageToLifeTimeRatioBlockGroupOutput , velocityGradients , ParticleRandomBlockLocks . OncePerParticle , "Velocity" ) ;
565+
566+ // Update the direction scale based on the velocity
567+ const multiplyScaleByVelocity = new ParticleMathBlock ( "Multiply Direction Scale by Velocity" ) ;
568+ multiplyScaleByVelocity . operation = ParticleMathBlockOperations . Multiply ;
569+ velocityValueOutput . connectTo ( multiplyScaleByVelocity . left ) ;
570+ _CreateAndConnectContextualSource ( "Direction Scale" , NodeParticleContextualSources . DirectionScale , multiplyScaleByVelocity . right ) ;
571+
572+ // Update the particle direction scale
573+ const multiplyDirection = new ParticleMathBlock ( "Multiply Direction" ) ;
574+ multiplyDirection . operation = ParticleMathBlockOperations . Multiply ;
575+ multiplyScaleByVelocity . output . connectTo ( multiplyDirection . left ) ;
576+ _CreateAndConnectContextualSource ( "Direction" , NodeParticleContextualSources . Direction , multiplyDirection . right ) ;
577+
578+ // Store the new calculation of the scaled direction in the context
579+ context . scaledDirection = multiplyDirection . output ;
580+ return multiplyDirection . output ;
548581}
549582
550- function _UpdateParticlePositionBlockGroup ( inputParticle : NodeParticleConnectionPoint , isLocal : boolean ) : NodeParticleConnectionPoint {
583+ /**
584+ * Creates the group of blocks that represent the particle position update
585+ * @param inputParticle The input particle to update
586+ * @param isLocal Whether the particle coordinate system is local or not
587+ * @param context The context of the current conversion
588+ * @returns The output of the group of blocks that represent the particle position update
589+ */
590+ function _UpdateParticlePositionBlockGroup ( inputParticle : NodeParticleConnectionPoint , isLocal : boolean , context : RuntimeConversionContext ) : NodeParticleConnectionPoint {
551591 // Update the particle position
552592 const updatePosition = new UpdatePositionBlock ( "Position Update" ) ;
553593 inputParticle . connectTo ( updatePosition . particle ) ;
@@ -559,13 +599,25 @@ function _UpdateParticlePositionBlockGroup(inputParticle: NodeParticleConnection
559599 const addPositionBlock = new ParticleMathBlock ( "Add Position" ) ;
560600 addPositionBlock . operation = ParticleMathBlockOperations . Add ;
561601 _CreateAndConnectContextualSource ( "Position" , NodeParticleContextualSources . Position , addPositionBlock . left ) ;
562- _CreateAndConnectContextualSource ( "Scaled Direction" , NodeParticleContextualSources . ScaledDirection , addPositionBlock . right ) ;
602+ if ( context . scaledDirection === undefined ) {
603+ _CreateAndConnectContextualSource ( "Scaled Direction" , NodeParticleContextualSources . ScaledDirection , addPositionBlock . right ) ;
604+ } else {
605+ context . scaledDirection . connectTo ( addPositionBlock . right ) ;
606+ }
607+
563608 addPositionBlock . output . connectTo ( updatePosition . position ) ;
564609 }
565610
566611 return updatePosition . output ;
567612}
568613
614+ /**
615+ * Creates the group of blocks that represent the particle size update
616+ * @param inputParticle The input particle to update
617+ * @param sizeGradients The size gradients (if any)
618+ * @param context The context of the current conversion
619+ * @returns The output of the group of blocks that represent the particle size update
620+ */
569621function _UpdateParticleSizeGradientBlockGroup (
570622 inputParticle : NodeParticleConnectionPoint ,
571623 sizeGradients : Array < FactorGradient > ,
@@ -590,6 +642,12 @@ function _UpdateParticleSizeGradientBlockGroup(
590642 return updateSizeBlock . output ;
591643}
592644
645+ /**
646+ * Creates the group of blocks that represent the particle gravity update
647+ * @param inputParticle The input particle to update
648+ * @param gravity The gravity vector to apply
649+ * @returns The output of the group of blocks that represent the particle gravity update
650+ */
593651function _UpdateParticleGravityBlockGroup ( inputParticle : NodeParticleConnectionPoint , gravity : Vector3 ) : NodeParticleConnectionPoint {
594652 // Create the gravity delta
595653 const gravityDeltaOutput = _CreateDeltaModifiedInput ( "Gravity" , gravity ) ;
@@ -608,12 +666,33 @@ function _UpdateParticleGravityBlockGroup(inputParticle: NodeParticleConnectionP
608666 return updateDirection . output ;
609667}
610668
611- function _CreateBasicColorUpdate ( ) : NodeParticleConnectionPoint {
669+ function _UpdateParticleAngularSpeedGradientBlockGroup ( angularSpeedGradients : Array < FactorGradient > , context : RuntimeConversionContext ) : NodeParticleConnectionPoint {
670+ context . ageToLifeTimeRatioBlockGroupOutput = _CreateAgeToLifeTimeRatioBlockGroup ( context ) ;
671+
672+ // Generate the gradient
673+ const angularSpeedValueOutput = _CreateGradientBlockGroup (
674+ context . ageToLifeTimeRatioBlockGroupOutput ,
675+ angularSpeedGradients ,
676+ ParticleRandomBlockLocks . OncePerParticle ,
677+ "Angular Speed"
678+ ) ;
679+ return angularSpeedValueOutput ;
680+ }
681+
682+ function _UpdateParticleAngularSpeedBlockGroup ( minAngularSpeed : number , maxAngularSpeed : number ) : NodeParticleConnectionPoint {
683+ // Random value between for the angular speed of the particle
684+ const randomAngularSpeedBlock = new ParticleRandomBlock ( "Random Angular Speed" ) ;
685+ randomAngularSpeedBlock . lockMode = ParticleRandomBlockLocks . OncePerParticle ;
686+ _CreateAndConnectInput ( "Min Angular Speed" , minAngularSpeed , randomAngularSpeedBlock . min ) ;
687+ _CreateAndConnectInput ( "Max Angular Speed" , maxAngularSpeed , randomAngularSpeedBlock . max ) ;
688+ return randomAngularSpeedBlock . output ;
689+ }
690+
691+ function _BasicColorUpdateBlockGroup ( ) : NodeParticleConnectionPoint {
612692 const addColorBlock = new ParticleMathBlock ( "Add Color" ) ;
613693 addColorBlock . operation = ParticleMathBlockOperations . Add ;
614694 _CreateAndConnectContextualSource ( "Color" , NodeParticleContextualSources . Color , addColorBlock . left ) ;
615695 _CreateAndConnectContextualSource ( "Scaled Color Step" , NodeParticleContextualSources . ScaledColorStep , addColorBlock . right ) ;
616-
617696 return addColorBlock . output ;
618697}
619698
0 commit comments