@@ -59,39 +59,34 @@ 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- TrackShape shape ;
63-
6462 bool dontRender = false ; // Should this shape be left as a static object?
63+ bool removePhys = false ; // Should superelevation physics be removed from this object?
6564 SectionIdx [ ] SectionIdxs ;
6665
67- try
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 ) )
6869 {
69- shape = viewer . Simulator . TSectionDat . TrackShapes . Get ( trackObj . SectionIdx ) ;
70-
7170 if ( shape . RoadShape )
7271 return false ; // Roads don't use superelevation, no use in processing them.
7372
7473 // Can't render superelevation on tunnel shapes
7574 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 ) ;
7677 SectionIdxs = shape . SectionIdxs ;
77- }
78- catch ( Exception )
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 ) )
7980 {
80- // Some route-specific shapes (DynaTrax) won't be populated in the TrackShapes list, check the TrackPaths list
81- if ( viewer . Simulator . TSectionDat . TSectionIdx . TrackPaths . TryGetValue ( trackObj . SectionIdx , out TrackPath path ) )
82- {
83- // Translate given data into a SectionIdx object that the rest of the method can interpret
84- // Assumptions: Each piece of DynaTrax is a single section with origin 0, 0, 0 and 0 angle,
85- // and the entire section of DynaTrax is defined by the track sections given in the track path
86- SectionIdxs = new SectionIdx [ 1 ] ;
87- SectionIdxs [ 0 ] = new SectionIdx ( path ) ;
88- }
89- else
90- return false ; // Not enough info, won't be able to render with superelevation
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 ) ;
9186 }
87+ else
88+ return false ; // Can't find section info, won't be able to render with superelevation
9289
93- // Sometimes junctions get caught here, physics superelevation should be removed for those as well
94- bool removePhys = false ;
9590 // 0 = centered, positive = rotation axis moves to inside of curve, negative = moves to outside of curve
9691 float rollOffsetM = 0.0f ;
9792
@@ -135,27 +130,18 @@ public static bool DecomposeStaticSuperElevation(Viewer viewer, TrackObj trackOb
135130 // Iterate through all subsections
136131 foreach ( SectionIdx id in SectionIdxs )
137132 {
138- // If section angle offset is not zero, that means we have a complicated track shape (eg: junction)
139- // If any sections have identical starting conditions, that means we have a junction
140- // These should not be rendered using superelevation
141- if ( ! dontRender && id . A != 0.0f )
142- dontRender = true ;
143- if ( ! dontRender && ! removePhys
144- && SectionIdxs . Any ( idx => idx != id && idx . X == id . X && idx . Y == id . Y && idx . Z == id . Z ) )
145- {
146- dontRender = true ;
147- removePhys = true ;
148- }
149-
150133 // The following vectors represent local positioning relative to root of original section:
151- Vector3 offset = new Vector3 ( ( float ) id . X , ( float ) id . Y , ( float ) id . Z ) ; // Offset from section origin for this series of sections
134+ Vector3 offset = new Vector3 ( ( float ) id . X , ( float ) id . Y , - ( float ) id . Z ) ; // Offset from section origin for this series of sections
152135 Vector3 localV = Vector3 . Zero ; // Local position of subsection (in x-z plane)
153136 Vector3 heading = Vector3 . Forward ; // Local heading (unit vector)
154137
155138 WorldPosition worldMatrix = new WorldPosition ( worldMatrixInput ) ; // Copy origin location
156139
157140 worldMatrix . XNAMatrix . Translation = Vector3 . Transform ( offset , worldMatrix . XNAMatrix ) ;
158141
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+
159145 WorldPosition nextRoot = new WorldPosition ( worldMatrix ) ; // Will become initial root
160146 Vector3 sectionOrigin = worldMatrix . XNAMatrix . Translation ; // Original position for entire section
161147 worldMatrix . XNAMatrix . Translation = Vector3 . Zero ; // worldMatrix now rotation-only
@@ -235,14 +221,17 @@ public static void ClearJunctionSuperElevation(Viewer viewer, TrackObj trackObj,
235221 foreach ( SectionIdx id in SectionIdxs )
236222 {
237223 // The following vectors represent local positioning relative to root of original section:
238- Vector3 offset = new Vector3 ( ( float ) id . X , ( float ) id . Y , ( float ) id . Z ) ; // Offset from section origin for this series of sections
224+ Vector3 offset = new Vector3 ( ( float ) id . X , ( float ) id . Y , - ( float ) id . Z ) ; // Offset from section origin for this series of sections
239225 Vector3 localV = Vector3 . Zero ; // Local position of subsection (in x-z plane)
240226 Vector3 heading = Vector3 . Forward ; // Local heading (unit vector)
241227
242228 WorldPosition worldMatrix = new WorldPosition ( worldMatrixInput ) ; // Copy origin location
243229
244230 worldMatrix . XNAMatrix . Translation = Vector3 . Transform ( offset , worldMatrix . XNAMatrix ) ;
245231
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+
246235 WorldPosition nextRoot = new WorldPosition ( worldMatrix ) ; // Will become initial root
247236 Vector3 sectionOrigin = worldMatrix . XNAMatrix . Translation ; // Original position for entire section
248237 worldMatrix . XNAMatrix . Translation = Vector3 . Zero ; // worldMatrix now rotation-only
0 commit comments