Skip to content

Commit 2c6e60d

Browse files
committed
Some tweaks, new vertex PositionControl feature for track profiles
1 parent de77b9c commit 2c6e60d

File tree

4 files changed

+83
-9
lines changed

4 files changed

+83
-9
lines changed
Binary file not shown.

Source/Orts.Simulation/Simulation/SuperElevation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ void MarkSections(Simulator simulator, List<TrVectorSection> SectionList, float
300300
// Special case: Next section is a short straight, but isn't the end of the curve
301301
// In this case, we force the straight section to maintain nonzero superelevation
302302
if (count < SectionList.Count - 2 && SectionList[count + 1].NomElevM == 0.0f
303-
&& lengths[count + 1] < (SectionList[count].NomElevM / effectiveRunoffSlope) * 2.0f)
303+
&& lengths[count + 1] < (SectionList[count].NomElevM / effectiveRunoffSlope) * 1.5f)
304304
SectionList[count + 1].NomElevM = (SectionList[count].NomElevM + SectionList[count + 2].NomElevM) / 2.0f;
305305

306306
endElevs[count] = Math.Min((SectionList[count].NomElevM + SectionList[count + 1].NomElevM) / 2.0f,

Source/RunActivity/Viewer3D/DynamicTrack.cs

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,7 @@ public TrProfile(Viewer viewer, XmlReader reader)
863863
v.Normal = new Vector3(float.Parse(s[0]), float.Parse(s[1]), float.Parse(s[2]));
864864
s = reader.GetAttribute("TexCoord").Split(sep, StringSplitOptions.RemoveEmptyEntries);
865865
v.TexCoord = new Vector2(float.Parse(s[0]), float.Parse(s[1]));
866+
v.PositionControl = Vertex.GetPositionControl(reader.GetAttribute("PositionControl"));
866867
pl.Vertices.Add(v);
867868
lodItem.NumVertices++; // Bump vertex count
868869
if (pl.Vertices.Count > 1) lodItem.NumSegments++;
@@ -1171,21 +1172,54 @@ public struct Vertex
11711172
public Vector3 Normal; // Normal vector (nx, ny, nz)
11721173
public Vector2 TexCoord; // Texture coordinate (u, v)
11731174

1175+
/// <summary>
1176+
/// Enumeration of controls for vertex displacement
1177+
/// </summary>
1178+
public enum VertexPositionControl
1179+
{
1180+
/// <summary>
1181+
/// None -- The vertex position won't be adjusted by superelevation.
1182+
/// </summary>
1183+
None = 0,
1184+
1185+
/// <summary>
1186+
/// All -- The vertex position will be adjusted by superelevation.
1187+
/// </summary>
1188+
All,
1189+
1190+
/// <summary>
1191+
/// Inside -- The vertex position will only be adjusted when on the inside of the curve.
1192+
/// </summary>
1193+
Inside,
1194+
1195+
/// <summary>
1196+
/// Outside -- The vertex position will only be adjusted when on the outside of the curve.
1197+
/// </summary>
1198+
Outside
1199+
}
1200+
1201+
public VertexPositionControl PositionControl;
1202+
11741203
// Vertex constructor (default)
1175-
public Vertex(float x, float y, float z, float nx, float ny, float nz, float u, float v)
1204+
public Vertex(float x, float y, float z, float nx, float ny, float nz, float u, float v,
1205+
VertexPositionControl control = VertexPositionControl.All)
11761206
{
11771207
Position = new Vector3(x, y, z);
11781208
Normal = new Vector3(nx, ny, nz);
11791209
TexCoord = new Vector2(u, v);
1210+
PositionControl = control;
11801211
}
11811212

11821213
// Vertex constructor (DAT)
11831214
public Vertex(STFReader stf)
11841215
{
1185-
Vertex v = new Vertex(); // Temp variable used to construct the struct in ParseBlock
1186-
v.Position = new Vector3();
1187-
v.Normal = new Vector3();
1188-
v.TexCoord = new Vector2();
1216+
Vertex v = new Vertex
1217+
{
1218+
Position = new Vector3(),
1219+
Normal = new Vector3(),
1220+
TexCoord = new Vector2(),
1221+
PositionControl = VertexPositionControl.All
1222+
}; // Temp variable used to construct the struct in ParseBlock
11891223
stf.MustMatch("(");
11901224
stf.ParseBlock(new STFReader.TokenProcessor[] {
11911225
new STFReader.TokenProcessor("position", ()=>{
@@ -1208,13 +1242,42 @@ public Vertex(STFReader stf)
12081242
v.TexCoord.Y = stf.ReadFloat(STFReader.UNITS.None, null);
12091243
stf.SkipRestOfBlock();
12101244
}),
1245+
new STFReader.TokenProcessor("positioncontrol", ()=>{
1246+
v.PositionControl = GetPositionControl(stf.ReadStringBlock(null));
1247+
}),
12111248
});
12121249
this = v;
12131250
// Checks for required member variables
12141251
// No way to check for missing Position.
12151252
if (Normal == Vector3.Zero) throw new Exception("improper Normal");
12161253
// No way to check for missing TexCoord
12171254
}
1255+
1256+
/// <summary>
1257+
/// Gets a member of the VertexPositionControl enumeration that corresponds to sPositionControl.
1258+
/// </summary>
1259+
/// <param name="sPositionControl">String that identifies desired PositionControl.</param>
1260+
/// <returns></returns>
1261+
public static VertexPositionControl GetPositionControl(string sPositionControl)
1262+
{
1263+
string s = sPositionControl.ToLower();
1264+
switch (s)
1265+
{
1266+
case "none":
1267+
return VertexPositionControl.None;
1268+
1269+
case "inside":
1270+
return VertexPositionControl.Inside;
1271+
1272+
case "outside":
1273+
return VertexPositionControl.Outside;
1274+
1275+
case "all":
1276+
default:
1277+
return VertexPositionControl.All;
1278+
1279+
}
1280+
}
12181281
}
12191282

12201283
public class DynamicTrackPrimitive : ShapePrimitive //RenderPrimitive

Source/RunActivity/Viewer3D/SuperElevation.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -740,9 +740,20 @@ public override ShapePrimitive BuildPrimitive(Viewer viewer, int iLOD, int iLODI
740740
// Rotate the vertex position based on superelevation
741741
if (Direction != 0)
742742
{
743-
p -= RollOffset;
744-
p = Vector3.Transform(p, SuperElevationRoll);
745-
p += RollOffset;
743+
// Check if this vertex should be translated by superelevation
744+
bool reposition = v.PositionControl != Vertex.VertexPositionControl.None;
745+
746+
if (Math.Sign(p.X) == Direction && v.PositionControl == Vertex.VertexPositionControl.Inside)
747+
reposition = false;
748+
else if (Math.Sign(p.X) == -Direction && v.PositionControl == Vertex.VertexPositionControl.Outside)
749+
reposition = false;
750+
751+
if (reposition)
752+
{
753+
p -= RollOffset;
754+
p = Vector3.Transform(p, SuperElevationRoll);
755+
p += RollOffset;
756+
}
746757
}
747758

748759
// In some extreme cases, track may have been rotated so much it's upside down

0 commit comments

Comments
 (0)