2222
2323using System ;
2424using System . Collections . Generic ;
25+ using System . Diagnostics ;
26+ using System . IO ;
2527using Microsoft . Xna . Framework ;
2628using Microsoft . Xna . Framework . Graphics ;
27- using ORTS . Common ;
2829using Orts . Simulation . RollingStocks ;
2930using Orts . Viewer3D . RollingStock ;
31+ using ORTS . Common ;
3032
3133namespace Orts . Viewer3D
3234{
@@ -39,6 +41,7 @@ public class ParticleEmitterViewer
3941 public readonly float ParticleVolumeM3 = 0.001f ;
4042 public readonly ParticleEmitterPrimitive Emitter ;
4143
44+ public string TexturePath ;
4245 ParticleEmitterMaterial Material ;
4346
4447#if DEBUG_EMITTER_INPUT
@@ -66,15 +69,40 @@ public ParticleEmitterViewer(Viewer viewer, ParticleEmitterData data, MSTSWagonV
6669 // Particles expand over time, this is just the initial volume, useful for calculating initial velocity
6770 ParticleVolumeM3 = 4.0f / 3.0f * MathHelper . Pi * ( ( EmitterData . NozzleDiameterM * EmitterData . NozzleDiameterM * EmitterData . NozzleDiameterM ) / 8.0f ) ;
6871 Emitter = new ParticleEmitterPrimitive ( this , data , car , worldPosition ) ;
72+
73+ if ( ! String . IsNullOrEmpty ( EmitterData . Graphic ) )
74+ TexturePath = EmitterData . Graphic ;
6975#if DEBUG_EMITTER_INPUT
7076 EmitterID = ++ EmitterIDIndex ;
7177 InputCycle = Viewer . Random . Next ( InputCycleLimit ) ;
7278#endif
73- }
79+ }
7480
75- public void Initialize ( string textureName )
81+ public void Initialize ( string defaultTextureName )
7682 {
77- Material = ( ParticleEmitterMaterial ) Viewer . MaterialManager . Load ( "ParticleEmitter" , textureName ) ;
83+ bool customTexture = false ;
84+
85+ if ( ! String . IsNullOrEmpty ( TexturePath ) )
86+ customTexture = true ;
87+ else
88+ TexturePath = defaultTextureName ;
89+
90+ // Texture location preference is eng/wag folder -> MSTS GLOBAL\TEXTURES folder -> OR CONTENT folder
91+ if ( File . Exists ( Path . Combine ( Path . GetDirectoryName ( Emitter . CarViewer . Car . WagFilePath ) , TexturePath ) ) )
92+ TexturePath = Path . Combine ( Path . GetDirectoryName ( Emitter . CarViewer . Car . WagFilePath ) , TexturePath ) ;
93+ else if ( File . Exists ( Path . Combine ( Viewer . Simulator . BasePath + @"\GLOBAL\TEXTURES\" , TexturePath ) ) )
94+ TexturePath = Path . Combine ( Viewer . Simulator . BasePath + @"\GLOBAL\TEXTURES\" , TexturePath ) ;
95+ else if ( customTexture && File . Exists ( Path . Combine ( Viewer . ContentPath , TexturePath ) ) )
96+ TexturePath = Path . Combine ( Viewer . ContentPath , TexturePath ) ;
97+ else // Fall back to default texture in CONTENT folder
98+ {
99+ TexturePath = Path . Combine ( Viewer . ContentPath , defaultTextureName ) ;
100+
101+ if ( customTexture )
102+ Trace . TraceWarning ( "Could not find particle graphic {0} at {1}" , TexturePath , Path . Combine ( Path . GetDirectoryName ( Emitter . CarViewer . Car . WagFilePath ) , TexturePath ) ) ;
103+ }
104+
105+ Material = ( ParticleEmitterMaterial ) Viewer . MaterialManager . Load ( "ParticleEmitter" , TexturePath ) ;
78106 }
79107
80108 /// <summary>
@@ -335,6 +363,8 @@ struct ParticleVertex
335363 internal float ParticleDuration ;
336364 internal Color ParticleColor ;
337365
366+ internal int SpriteCount ;
367+
338368 internal float CompressionFactor = 1.0f ;
339369
340370 internal WorldPosition WorldPosition ;
@@ -373,6 +403,8 @@ public ParticleEmitterPrimitive(ParticleEmitterViewer particleViewer, ParticleEm
373403 ParticleDuration = 3 ;
374404 ParticleColor = Color . White ;
375405
406+ SpriteCount = EmitterData . AtlasWidth * EmitterData . AtlasHeight ;
407+
376408 CarViewer = car ;
377409 WorldPosition = worldPosition ;
378410
@@ -548,6 +580,7 @@ public void Update(float currentTime, ElapsedTime elapsedTime)
548580 rotY . Normalize ( ) ;
549581
550582 float initialSpeed = XNAInitialVelocity . Length ( ) ;
583+ Vector3 carVelocity = new Vector3 ( CarViewer . Velocity [ 0 ] , CarViewer . Velocity [ 1 ] , - CarViewer . Velocity [ 2 ] ) ;
551584
552585 float time = currentTime - elapsedTime . ClockSeconds ;
553586
@@ -559,12 +592,11 @@ public void Update(float currentTime, ElapsedTime elapsedTime)
559592
560593 int nextFreeParticle = ( FirstFreeParticle + 1 ) % EmitterData . MaxParticles ;
561594 int vertex = FirstFreeParticle * VerticesPerParticle ;
562- int texture = Viewer . Random . Next ( 16 ) ; // Randomizes emissions .
595+ int texture = Viewer . Random . Next ( SpriteCount ) ; // Randomizes particle texture to any texture on the sheet .
563596 // Alpha value of color is just a random number, not used (maybe allow for alpha changes?)
564597 Color color_Random = new Color ( ParticleColor . R , ParticleColor . G , ParticleColor . B , ( int ) ( ( float ) Viewer . Random . NextDouble ( ) * 255f ) ) ;
565598
566599 Vector3 position = EmitterData . PositionM ;
567- Vector3 carVelocity = new Vector3 ( CarViewer . Velocity [ 0 ] , CarViewer . Velocity [ 1 ] , - CarViewer . Velocity [ 2 ] ) ;
568600
569601 Vector3 initialVelocity = XNAInitialVelocity ;
570602 Vector3 finalVelocity = XNAFinalVelocity ;
@@ -764,6 +796,7 @@ public override void Render(GraphicsDevice graphicsDevice, IEnumerable<RenderIte
764796 var emitter = ( ParticleEmitterPrimitive ) item . RenderPrimitive ;
765797 shader . EmitSize = emitter . EmitSize ;
766798 shader . Texture = Texture ;
799+ shader . TextureAtlasSizeXY = new Vector2 ( emitter . EmitterData . AtlasWidth , emitter . EmitterData . AtlasHeight ) ;
767800 shader . SetMatrix ( Matrix . Identity , ref XNAViewMatrix , ref XNAProjectionMatrix ) ;
768801 ShaderPasses . Current . Apply ( ) ;
769802 item . RenderPrimitive . Draw ( graphicsDevice ) ;
0 commit comments