@@ -646,6 +646,8 @@ public float TenderCoalMassKG // Decreased by firing and increased
646646
647647 public readonly SmoothedData StackSteamVelocityMpS = new SmoothedData ( 2 ) ;
648648 public float StackSteamVolumeM3pS ;
649+ public float StackParticleDurationS ;
650+ public float StackCount ;
649651 public float Cylinders1SteamVelocityMpS ;
650652 public float Cylinders1SteamVolumeM3pS ;
651653 public float Cylinders2SteamVelocityMpS ;
@@ -2097,7 +2099,7 @@ private void UpdateFX(float elapsedClockSeconds)
20972099 // Find
20982100 for ( int i = 0 ; i < NumCylinders ; i ++ )
20992101 {
2100- // float realCrankAngleRad = (float)(LocomotiveAxle.AxlePositionRad + i * WheelCrankAngleDiffRad[i]);
2102+ // float realCrankAngleRad = (float)(LocomotiveAxle.AxlePositionRad + i * WheelCrankAngleDiffRad[i]);
21012103 float realCrankAngleRad = ( float ) ( LocomotiveAxle . AxlePositionRad ) ;
21022104 float normalisedCrankAngleRad = 0 ;
21032105
@@ -2130,44 +2132,46 @@ private void UpdateFX(float elapsedClockSeconds)
21302132 exhaustCrankAngleRad = CylinderExhaustOpenFactor * ( float ) Math . PI + ( float ) Math . PI ;
21312133 }
21322134
2133-
2134- if ( i == 0 && ( normalisedCrankAngleRad <= MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) || ( normalisedCrankAngleRad < 2 * MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) )
2135- {
2136- CylinderSteamExhaust1On = true ;
2137- }
2138- else
2135+ if ( absSpeedMpS > 0.001 )
21392136 {
2140- CylinderSteamExhaust1On = false ;
2141- }
2137+ if ( i == 0 && ( normalisedCrankAngleRad <= MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) || ( normalisedCrankAngleRad < 2 * MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) )
2138+ {
2139+ CylinderSteamExhaust1On = true ;
2140+ }
2141+ else
2142+ {
2143+ CylinderSteamExhaust1On = false ;
2144+ }
21422145
2143- if ( i == 1 && ( normalisedCrankAngleRad <= MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) || ( normalisedCrankAngleRad < 2 * MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) )
2144- {
2145- CylinderSteamExhaust2On = true ;
2146- }
2147- else
2148- {
2149- CylinderSteamExhaust2On = false ;
2150- }
2146+ if ( i == 1 && ( normalisedCrankAngleRad <= MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) || ( normalisedCrankAngleRad < 2 * MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) )
2147+ {
2148+ CylinderSteamExhaust2On = true ;
2149+ }
2150+ else
2151+ {
2152+ CylinderSteamExhaust2On = false ;
2153+ }
21512154
2152- // Trace.TraceInformation("Exhaust - Factor {0} ExhaustCrank {1} RealCrank {2} NormalCrank {3} ExhaustOn {4} Cylinder {5}", CylinderExhaustOpenFactor, MathHelper.ToDegrees(exhaustCrankAngleRad), MathHelper.ToDegrees(realCrankAngleRad), MathHelper.ToDegrees(normalisedCrankAngleRad), SteamExhaust1On, i+1);
2155+ // Trace.TraceInformation("Exhaust - Factor {0} ExhaustCrank {1} RealCrank {2} NormalCrank {3} ExhaustOn {4} Cylinder {5}", CylinderExhaustOpenFactor, MathHelper.ToDegrees(exhaustCrankAngleRad), MathHelper.ToDegrees(realCrankAngleRad), MathHelper.ToDegrees(normalisedCrankAngleRad), SteamExhaust1On, i+1);
21532156
21542157
2155- if ( i == 2 && ( normalisedCrankAngleRad <= MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) || ( normalisedCrankAngleRad < 2 * MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) )
2156- {
2157- CylinderSteamExhaust3On = true ;
2158- }
2159- else
2160- {
2161- CylinderSteamExhaust3On = false ;
2162- }
2158+ if ( i == 2 && ( normalisedCrankAngleRad <= MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) || ( normalisedCrankAngleRad < 2 * MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) )
2159+ {
2160+ CylinderSteamExhaust3On = true ;
2161+ }
2162+ else
2163+ {
2164+ CylinderSteamExhaust3On = false ;
2165+ }
21632166
2164- if ( i == 3 && ( normalisedCrankAngleRad <= MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) || ( normalisedCrankAngleRad < 2 * MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) )
2165- {
2166- CylinderSteamExhaust4On = true ;
2167- }
2168- else
2169- {
2170- CylinderSteamExhaust4On = false ;
2167+ if ( i == 3 && ( normalisedCrankAngleRad <= MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) || ( normalisedCrankAngleRad < 2 * MathHelper . Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad ) )
2168+ {
2169+ CylinderSteamExhaust4On = true ;
2170+ }
2171+ else
2172+ {
2173+ CylinderSteamExhaust4On = false ;
2174+ }
21712175 }
21722176
21732177
@@ -2469,25 +2473,48 @@ private void UpdateFX(float elapsedClockSeconds)
24692473 float SmokeColorFireMass = ( FireMassKG / IdealFireMassKG ) ; // As firemass exceeds the ideal mass the fire becomes 'blocked', when firemass is < ideal then fire burns more freely.
24702474 SmokeColorFireMass = ( 1.0f / SmokeColorFireMass ) * ( 1.0f / SmokeColorFireMass ) * ( 1.0f / SmokeColorFireMass ) ; // Inverse the firemass value, then cube it to make it a bit more significant
24712475
2476+ float Throttlepercent = ThrottlePercent > 0 ? ThrottlePercent / 10f : 0f ;
2477+
24722478 if ( CylinderAdvancedSteamExhaustEffects )
24732479 {
24742480
24752481 if ( CylinderSteamExhaust1On || CylinderSteamExhaust2On || CylinderSteamExhaust3On || CylinderSteamExhaust4On )
24762482 {
2477- StackSteamVelocityMpS . Update ( elapsedClockSeconds , ( float ) Math . Sqrt ( KPa . FromPSI ( Pressure_c_AtmPSI ) * 1000 * 50 / WaterDensityAt100DegC1BarKGpM3 ) ) ;
2478- StackSteamVolumeM3pS = Kg . FromLb ( CylinderSteamUsageLBpS + BlowerSteamUsageLBpS + RadiationSteamLossLBpS + CompSteamUsageLBpS + GeneratorSteamUsageLBpS ) * 20 * SteamVaporSpecVolumeAt100DegC1BarM3pKG ;
2483+ float smokeVelocityVariationFactor = 5 * cutoff ; // adjust smoke velocity based upon throttle and cutoff settings
2484+ float smokeVolumeVariationFactor = 1.5f * cutoff ; // adjust smoke volume based upon throttle and cutoff settings
2485+
2486+ StackSteamVelocityMpS . Update ( elapsedClockSeconds , ( float ) Math . Sqrt ( KPa . FromPSI ( Pressure_c_AtmPSI ) * 1000 * smokeVelocityVariationFactor / WaterDensityAt100DegC1BarKGpM3 ) ) ;
2487+ StackSteamVolumeM3pS = Kg . FromLb ( CylinderSteamUsageLBpS + BlowerSteamUsageLBpS + RadiationSteamLossLBpS + CompSteamUsageLBpS + GeneratorSteamUsageLBpS ) * smokeVolumeVariationFactor * SteamVaporSpecVolumeAt100DegC1BarM3pKG ;
2488+ StackSteamVolumeM3pS = StackSteamVolumeM3pS / StackCount ;
2489+ StackParticleDurationS = Throttlepercent + FireRatio ;
2490+ // Trace.TraceInformation("Puff - cutoff {0} Throttle {1} Velocity {2} Volume {3} Duration {4}", cutoff, throttle, StackSteamVelocityMpS.Value, StackSteamVolumeM3pS, StackParticleDurationS);
2491+
24792492 }
2480- else
2493+ else // when not exhausting
24812494 {
2482- StackSteamVelocityMpS . Update ( elapsedClockSeconds , ( float ) Math . Sqrt ( KPa . FromPSI ( Pressure_c_AtmPSI ) * 0.5f * 1000 / WaterDensityAt100DegC1BarKGpM3 ) ) ;
2483- StackSteamVolumeM3pS = Kg . FromLb ( CylinderSteamUsageLBpS + BlowerSteamUsageLBpS + RadiationSteamLossLBpS + CompSteamUsageLBpS + GeneratorSteamUsageLBpS ) * 0.25f * SteamVaporSpecVolumeAt100DegC1BarM3pKG ;
2495+ if ( absSpeedMpS < 10 )
2496+ {
2497+ float smokeRestVelocityVariationFactor = 2 * cutoff ; // adjust smoke velocity based upon throttle and cutoff settings
2498+ float smokeRestVolumeVariationFactor = 1 * cutoff ; // adjust smoke volume based upon throttle and cutoff settings
24842499
2500+ float velocityRate = ( absSpeedMpS < 1 ? 1.0f : 1.0f / AbsSpeedMpS ) ;
2501+ StackSteamVelocityMpS . Update ( elapsedClockSeconds , velocityRate ) ;
2502+ StackSteamVolumeM3pS = Kg . FromLb ( BlowerSteamUsageLBpS + RadiationSteamLossLBpS + CompSteamUsageLBpS + GeneratorSteamUsageLBpS ) * smokeRestVolumeVariationFactor * SteamVaporSpecVolumeAt100DegC1BarM3pKG ;
2503+ StackSteamVolumeM3pS = StackSteamVolumeM3pS / StackCount + FireRatio ;
2504+ StackParticleDurationS = Throttlepercent + FireRatio ;
2505+ // Trace.TraceInformation("Rest - cutoff {0} Velocity {1} Volume {2} Duration {3} VelocityRate {4} Throttle% {5}", cutoff, StackSteamVelocityMpS.SmoothedValue, StackSteamVolumeM3pS, StackParticleDurationS, velocityRate, Throttlepercent);
2506+ }
24852507 }
2508+
24862509 }
2487- else
2510+ else // Legacy smoke implementation
24882511 {
2512+ float velocityRate = ( float ) Math . Sqrt ( KPa . FromPSI ( Pressure_c_AtmPSI ) * 1000 * 2 / WaterDensityAt100DegC1BarKGpM3 ) ;
24892513 StackSteamVelocityMpS . Update ( elapsedClockSeconds , ( float ) Math . Sqrt ( KPa . FromPSI ( Pressure_c_AtmPSI ) * 1000 * 2 / WaterDensityAt100DegC1BarKGpM3 ) ) ;
24902514 StackSteamVolumeM3pS = Kg . FromLb ( CylinderSteamUsageLBpS + BlowerSteamUsageLBpS + RadiationSteamLossLBpS + CompSteamUsageLBpS + GeneratorSteamUsageLBpS ) * SteamVaporSpecVolumeAt100DegC1BarM3pKG ;
2515+ StackSteamVolumeM3pS = StackSteamVolumeM3pS / StackCount + FireRatio ;
2516+ StackParticleDurationS = Throttlepercent + FireRatio ;
2517+ // Trace.TraceInformation("Legacy - cutoff {0} Throttle {1} Velocity {2} Volume {3} Duration {4} VelocityRate {5}", cutoff, throttle, StackSteamVelocityMpS.SmoothedValue, StackSteamVolumeM3pS, StackParticleDurationS, velocityRate);
24912518 }
24922519
24932520
0 commit comments