@@ -130,21 +130,13 @@ public class DynamicTrackViewer
130130 WorldPosition worldPosition ;
131131 public DynamicTrackPrimitive Primitive ;
132132
133- public DynamicTrackViewer ( Viewer viewer , DyntrackObj dtrack , WorldPosition position , WorldPosition endPosition )
133+ public DynamicTrackViewer ( Viewer viewer , DyntrackObj dtrack , WorldPosition position , WorldPosition endPosition , int trpIndex = 0 )
134134 {
135135 Viewer = viewer ;
136136 worldPosition = position ;
137137
138- if ( viewer . TRP == null )
139- {
140- // First to need a track profile creates it
141- Trace . Write ( " TRP" ) ;
142- // Creates profile and loads materials into SceneryMaterials
143- TRPFile . CreateTrackProfile ( viewer , viewer . Simulator . RoutePath , out viewer . TRP ) ;
144- }
145-
146138 // Instantiate classes
147- Primitive = new DynamicTrackPrimitive ( Viewer , dtrack , worldPosition , endPosition ) ;
139+ Primitive = new DynamicTrackPrimitive ( Viewer , dtrack , worldPosition , endPosition , trpIndex ) ;
148140 }
149141
150142 public DynamicTrackViewer ( Viewer viewer , WorldPosition position , WorldPosition endPosition )
@@ -219,6 +211,26 @@ public void Mark()
219211 foreach ( LOD lod in Primitive . TrProfile . LODs )
220212 lod . Mark ( ) ;
221213 }
214+
215+ /// <summary>
216+ /// Returns the index of the track profile that best suits the given TrVectorSection
217+ /// The result is cached in the section object for future use
218+ /// </summary>
219+ /// <returns>Index of viewer.TRPs</returns>
220+ public static int GetBestTrackProfile ( Viewer viewer , TrVectorSection trSection )
221+ {
222+ string shapeName = "" ;
223+ if ( viewer . Simulator . TSectionDat . TrackShapes . ContainsKey ( trSection . ShapeIndex ) )
224+ shapeName = viewer . Simulator . TSectionDat . TrackShapes . Get ( trSection . ShapeIndex ) . FileName ;
225+
226+ viewer . TrackProfileIndicies . TryGetValue ( shapeName , out int trpIndex ) ;
227+
228+ trSection . TRPIndex = trpIndex ;
229+ return trpIndex ;
230+ }
231+ // Note: Dynamic track objects will ALWAYS use TRPIndex = 0
232+ // This is because dynamic tracks don't have shapes, and as such lack the information needed
233+ // to select a specific track profile.
222234 }
223235
224236 // A track profile consists of a number of groups used for LOD considerations. There are LODs,
@@ -242,26 +254,40 @@ public class TRPFile
242254 /// </summary>
243255 /// <param name="viewer">Viewer.</param>
244256 /// <param name="routePath">Path to route.</param>
245- /// <param name="trpFile"> TRPFile created (out).</param>
246- public static void CreateTrackProfile ( Viewer viewer , string routePath , out TRPFile trpFile )
257+ /// <param name="trpFiles">List of TRPFile(s) created (out).</param>
258+ public static void CreateTrackProfile ( Viewer viewer , string routePath , out List < TRPFile > trpFiles )
247259 {
248260 string path = routePath + @"\TrackProfiles" ;
249- //Establish default track profile
250- if ( Directory . Exists ( path ) && File . Exists ( path + @"\TrProfile.xml" ) )
251- {
252- // XML-style
253- trpFile = new TRPFile ( viewer , path + @"\TrProfile.xml" ) ;
254- }
255- else if ( Directory . Exists ( path ) && File . Exists ( path + @"\TrProfile.stf" ) )
256- {
257- // MSTS-style
258- trpFile = new TRPFile ( viewer , path + @"\TrProfile.stf" ) ;
259- }
260- else
261+ List < string > profileNames = new List < string > ( ) ;
262+ trpFiles = new List < TRPFile > ( ) ;
263+
264+ if ( Directory . Exists ( path ) )
261265 {
262- // default
263- trpFile = new TRPFile ( viewer , "" ) ;
266+ // Get all .xml/.stf files that start with "TrProfile"
267+ string [ ] xmlProfiles = Directory . GetFiles ( path , "TrProfile*.xml" ) ;
268+ string [ ] stfProfiles = Directory . GetFiles ( path , "TrProfile*.stf" ) ;
269+
270+ foreach ( string xmlProfile in xmlProfiles )
271+ {
272+ trpFiles . Add ( new TRPFile ( viewer , xmlProfile ) ) ;
273+ profileNames . Add ( Path . GetFileNameWithoutExtension ( xmlProfile ) ) ;
274+ }
275+ foreach ( string stfProfile in stfProfiles )
276+ {
277+ string stfName = Path . GetFileNameWithoutExtension ( stfProfile ) ;
278+ // If an .stf profile and .xml profile have the same name, prefer the xml profile
279+ if ( ! profileNames . Contains ( stfName ) )
280+ {
281+ trpFiles . Add ( new TRPFile ( viewer , stfProfile ) ) ;
282+ profileNames . Add ( stfName ) ;
283+ }
284+ }
264285 }
286+
287+ // Add default profile only if no other profiles were added
288+ if ( trpFiles . Count <= 0 )
289+ trpFiles . Add ( new TRPFile ( viewer , "" ) ) ;
290+
265291 // FOR DEBUGGING: Writes XML file from current TRP
266292 //TRP.TrackProfile.SaveAsXML(@"C:/Users/Walt/Desktop/TrProfile.xml");
267293 }
@@ -390,6 +416,7 @@ public class TrProfile
390416 public PitchControls PitchControl = PitchControls . None ; // Method of control for profile replication pitch
391417 public float PitchControlScalar ; // Scalar parameter for PitchControls
392418 public ArrayList LODs = new ArrayList ( ) ; // Array of Levels-Of-Detail
419+ public List < string > Images = new List < string > ( ) ;
393420
394421 /// <summary>
395422 /// Enumeration of LOD control methods
@@ -552,6 +579,17 @@ public TrProfile(Viewer viewer)
552579
553580 lod . LODItems . Add ( lodItem ) ; // Append this LODItem to LODItems array
554581 LODs . Add ( lod ) ; // Append this LOD to LODs array
582+
583+ // Add textures
584+ foreach ( LOD level in LODs )
585+ {
586+ foreach ( LODItem item in level . LODItems )
587+ {
588+ string texFileName = Path . GetFileNameWithoutExtension ( item . TexName ) ;
589+ if ( ! Images . Contains ( texFileName ) )
590+ Images . Add ( texFileName ) ;
591+ }
592+ }
555593 }
556594
557595 /// <summary>
@@ -571,7 +609,20 @@ public TrProfile(Viewer viewer, STFReader stf)
571609 new STFReader . TokenProcessor ( "lod" , ( ) => { LODs . Add ( new LOD ( viewer , stf ) ) ; } ) ,
572610 } ) ;
573611
574- if ( LODs . Count == 0 ) throw new Exception ( "missing LODs" ) ;
612+ if ( LODs . Count == 0 )
613+ throw new Exception ( "missing LODs" ) ;
614+ else // Add textures
615+ {
616+ foreach ( LOD level in LODs )
617+ {
618+ foreach ( LODItem item in level . LODItems )
619+ {
620+ string texFileName = Path . GetFileNameWithoutExtension ( item . TexName ) ;
621+ if ( ! Images . Contains ( texFileName ) )
622+ Images . Add ( texFileName ) ;
623+ }
624+ }
625+ }
575626 }
576627
577628 /// <summary>
@@ -649,7 +700,20 @@ public TrProfile(Viewer viewer, XmlReader reader)
649700 }
650701 }
651702 }
652- if ( LODs . Count == 0 ) throw new Exception ( "missing LODs" ) ;
703+ if ( LODs . Count == 0 )
704+ throw new Exception ( "missing LODs" ) ;
705+ else // Add textures
706+ {
707+ foreach ( LOD level in LODs )
708+ {
709+ foreach ( LODItem item in level . LODItems )
710+ {
711+ string texFileName = Path . GetFileNameWithoutExtension ( item . TexName ) ;
712+ if ( ! Images . Contains ( texFileName ) )
713+ Images . Add ( texFileName ) ;
714+ }
715+ }
716+ }
653717 }
654718
655719 /// <summary>
@@ -986,7 +1050,7 @@ public DynamicTrackPrimitive()
9861050 /// Constructor.
9871051 /// </summary>
9881052 public DynamicTrackPrimitive ( Viewer viewer , DyntrackObj track , WorldPosition worldPosition ,
989- WorldPosition endPosition )
1053+ WorldPosition endPosition , int trpIndex = 0 )
9901054 {
9911055 // DynamicTrackPrimitive is responsible for creating a mesh for a section with a single subsection.
9921056 // It also must update worldPosition to reflect the end of this subsection, subsequently to
@@ -1013,7 +1077,7 @@ public DynamicTrackPrimitive(Viewer viewer, DyntrackObj track, WorldPosition wor
10131077
10141078 XNAEnd = endPosition . XNAMatrix . Translation ;
10151079
1016- TrProfile = viewer . TRP . TrackProfile ;
1080+ TrProfile = viewer . TRPs [ trpIndex ] . TrackProfile ;
10171081 // Count all of the LODItems in all the LODs
10181082 int count = 0 ;
10191083 for ( int i = 0 ; i < TrProfile . LODs . Count ; i ++ )
0 commit comments