@@ -59,39 +59,34 @@ public static bool DecomposeStaticSuperElevation(Viewer viewer, TrackObj trackOb
59
59
// each subsection. The rotation component changes only in heading. The translation
60
60
// component steps along the path to reflect the root of each subsection.
61
61
62
- TrackShape shape ;
63
-
64
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?
65
64
SectionIdx [ ] SectionIdxs ;
66
65
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 ) )
68
69
{
69
- shape = viewer . Simulator . TSectionDat . TrackShapes . Get ( trackObj . SectionIdx ) ;
70
-
71
70
if ( shape . RoadShape )
72
71
return false ; // Roads don't use superelevation, no use in processing them.
73
72
74
73
// Can't render superelevation on tunnel shapes
75
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 ) ;
76
77
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 ) )
79
80
{
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 ) ;
91
86
}
87
+ else
88
+ return false ; // Can't find section info, won't be able to render with superelevation
92
89
93
- // Sometimes junctions get caught here, physics superelevation should be removed for those as well
94
- bool removePhys = false ;
95
90
// 0 = centered, positive = rotation axis moves to inside of curve, negative = moves to outside of curve
96
91
float rollOffsetM = 0.0f ;
97
92
@@ -135,27 +130,18 @@ public static bool DecomposeStaticSuperElevation(Viewer viewer, TrackObj trackOb
135
130
// Iterate through all subsections
136
131
foreach ( SectionIdx id in SectionIdxs )
137
132
{
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
-
150
133
// 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
152
135
Vector3 localV = Vector3 . Zero ; // Local position of subsection (in x-z plane)
153
136
Vector3 heading = Vector3 . Forward ; // Local heading (unit vector)
154
137
155
138
WorldPosition worldMatrix = new WorldPosition ( worldMatrixInput ) ; // Copy origin location
156
139
157
140
worldMatrix . XNAMatrix . Translation = Vector3 . Transform ( offset , worldMatrix . XNAMatrix ) ;
158
141
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
+
159
145
WorldPosition nextRoot = new WorldPosition ( worldMatrix ) ; // Will become initial root
160
146
Vector3 sectionOrigin = worldMatrix . XNAMatrix . Translation ; // Original position for entire section
161
147
worldMatrix . XNAMatrix . Translation = Vector3 . Zero ; // worldMatrix now rotation-only
@@ -235,14 +221,17 @@ public static void ClearJunctionSuperElevation(Viewer viewer, TrackObj trackObj,
235
221
foreach ( SectionIdx id in SectionIdxs )
236
222
{
237
223
// 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
239
225
Vector3 localV = Vector3 . Zero ; // Local position of subsection (in x-z plane)
240
226
Vector3 heading = Vector3 . Forward ; // Local heading (unit vector)
241
227
242
228
WorldPosition worldMatrix = new WorldPosition ( worldMatrixInput ) ; // Copy origin location
243
229
244
230
worldMatrix . XNAMatrix . Translation = Vector3 . Transform ( offset , worldMatrix . XNAMatrix ) ;
245
231
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
+
246
235
WorldPosition nextRoot = new WorldPosition ( worldMatrix ) ; // Will become initial root
247
236
Vector3 sectionOrigin = worldMatrix . XNAMatrix . Translation ; // Original position for entire section
248
237
worldMatrix . XNAMatrix . Translation = Vector3 . Zero ; // worldMatrix now rotation-only
0 commit comments