@@ -59,34 +59,27 @@ public static bool DecomposeStaticSuperElevation(Viewer viewer, TrackObj trackOb
5959 // each subsection. The rotation component changes only in heading. The translation
6060 // component steps along the path to reflect the root of each subsection.
6161
62- bool dontRender = false ; // Should this shape be left as a static object?
63- bool removePhys = false ; // Should superelevation physics be removed from this object?
64- SectionIdx [ ] SectionIdxs ;
62+ TrackShape shape ;
6563
66- // Using the track object, determine the track sections
67- // Most track sections can be recovered directly from a TrackShape object
68- if ( viewer . Simulator . TSectionDat . TrackShapes . TryGetValue ( trackObj . SectionIdx , out TrackShape shape ) )
64+ try
6965 {
70- if ( shape . RoadShape )
71- return false ; // Roads don't use superelevation, no use in processing them.
66+ shape = viewer . Simulator . TSectionDat . TrackShapes . Get ( trackObj . SectionIdx ) ;
7267
73- // Can't render superelevation on tunnel shapes
74- dontRender = shape . TunnelShape ;
75- // Can't render superelevation and shouldn't have physics superelevation on junctions and crossovers
76- dontRender |= removePhys = ( shape . NumPaths > 1 && shape . ClearanceDistance != 0 ) ;
77- SectionIdxs = shape . SectionIdxs ;
78- } // Some route-specific shapes (DynaTrax) won't be populated in the TrackShapes list, check the TrackPaths list
79- else if ( viewer . Simulator . TSectionDat . TSectionIdx . TrackPaths . TryGetValue ( trackObj . SectionIdx , out TrackPath path ) )
68+ if ( shape . RoadShape == true )
69+ return false ; // Roads don't use superelevation, no use in processing them.
70+ }
71+ catch ( Exception )
8072 {
81- // Translate given data into a SectionIdx object that the rest of the method can interpret
82- // Assumptions: Each piece of DynaTrax is a single section with origin 0, 0, 0 and 0 angle,
83- // and the entire section of DynaTrax is defined by the track sections given in the track path
84- SectionIdxs = new SectionIdx [ 1 ] ;
85- SectionIdxs [ 0 ] = new SectionIdx ( path ) ;
73+ return false ; // Won't be able to render with superelevation
8674 }
87- else
88- return false ; // Can't find section info, won't be able to render with superelevation
8975
76+ SectionIdx [ ] SectionIdxs = shape . SectionIdxs ;
77+
78+ // Can't render superelevation on tunnel shapes
79+ // NOTE: Even if we don't render superelevation, we still need to run through processing to remove superelevation from track sections
80+ bool dontRender = shape . TunnelShape ;
81+ // Sometimes junctions get caught here, physics superelevation should be removed for those as well
82+ bool removePhys = false ;
9083 // 0 = centered, positive = rotation axis moves to inside of curve, negative = moves to outside of curve
9184 float rollOffsetM = 0.0f ;
9285
@@ -130,18 +123,27 @@ public static bool DecomposeStaticSuperElevation(Viewer viewer, TrackObj trackOb
130123 // Iterate through all subsections
131124 foreach ( SectionIdx id in SectionIdxs )
132125 {
126+ // If section angle offset is not zero, that means we have a complicated track shape (eg: junction)
127+ // If any sections have identical starting conditions, that means we have a junction
128+ // These should not be rendered using superelevation
129+ if ( ! dontRender && id . A != 0.0f )
130+ dontRender = true ;
131+ if ( ! dontRender && ! removePhys
132+ && SectionIdxs . Any ( idx => idx != id && idx . X == id . X && idx . Y == id . Y && idx . Z == id . Z ) )
133+ {
134+ dontRender = true ;
135+ removePhys = true ;
136+ }
137+
133138 // The following vectors represent local positioning relative to root of original section:
134- Vector3 offset = new Vector3 ( ( float ) id . X , ( float ) id . Y , - ( float ) id . Z ) ; // Offset from section origin for this series of sections
139+ Vector3 offset = new Vector3 ( ( float ) id . X , ( float ) id . Y , ( float ) id . Z ) ; // Offset from section origin for this series of sections
135140 Vector3 localV = Vector3 . Zero ; // Local position of subsection (in x-z plane)
136141 Vector3 heading = Vector3 . Forward ; // Local heading (unit vector)
137142
138143 WorldPosition worldMatrix = new WorldPosition ( worldMatrixInput ) ; // Copy origin location
139144
140145 worldMatrix . XNAMatrix . Translation = Vector3 . Transform ( offset , worldMatrix . XNAMatrix ) ;
141146
142- // If the section is rotated, apply that rotation now so we don't need to in the future
143- worldMatrix . XNAMatrix = Matrix . CreateRotationY ( MathHelper . ToRadians ( - ( float ) id . A ) ) * worldMatrix . XNAMatrix ;
144-
145147 WorldPosition nextRoot = new WorldPosition ( worldMatrix ) ; // Will become initial root
146148 Vector3 sectionOrigin = worldMatrix . XNAMatrix . Translation ; // Original position for entire section
147149 worldMatrix . XNAMatrix . Translation = Vector3 . Zero ; // worldMatrix now rotation-only
@@ -221,17 +223,14 @@ public static void ClearJunctionSuperElevation(Viewer viewer, TrackObj trackObj,
221223 foreach ( SectionIdx id in SectionIdxs )
222224 {
223225 // The following vectors represent local positioning relative to root of original section:
224- Vector3 offset = new Vector3 ( ( float ) id . X , ( float ) id . Y , - ( float ) id . Z ) ; // Offset from section origin for this series of sections
226+ Vector3 offset = new Vector3 ( ( float ) id . X , ( float ) id . Y , ( float ) id . Z ) ; // Offset from section origin for this series of sections
225227 Vector3 localV = Vector3 . Zero ; // Local position of subsection (in x-z plane)
226228 Vector3 heading = Vector3 . Forward ; // Local heading (unit vector)
227229
228230 WorldPosition worldMatrix = new WorldPosition ( worldMatrixInput ) ; // Copy origin location
229231
230232 worldMatrix . XNAMatrix . Translation = Vector3 . Transform ( offset , worldMatrix . XNAMatrix ) ;
231233
232- // If the section is rotated, apply that rotation now so we don't need to in the future
233- worldMatrix . XNAMatrix = Matrix . CreateRotationY ( MathHelper . ToRadians ( - ( float ) id . A ) ) * worldMatrix . XNAMatrix ;
234-
235234 WorldPosition nextRoot = new WorldPosition ( worldMatrix ) ; // Will become initial root
236235 Vector3 sectionOrigin = worldMatrix . XNAMatrix . Translation ; // Original position for entire section
237236 worldMatrix . XNAMatrix . Translation = Vector3 . Zero ; // worldMatrix now rotation-only
@@ -827,9 +826,6 @@ public override void LinearGen()
827826 // Very short length track, use minimum of two sections
828827 if ( NumSections == 0 )
829828 NumSections = 2 ;
830- // Limit the number of sections to prevent overflowing the number of triangles
831- else if ( NumSections > 250 )
832- NumSections = 250 ;
833829 // Ensure an even number of sections
834830 if ( NumSections % 2 == 1 )
835831 NumSections ++ ;
0 commit comments