Skip to content

Commit 2b5ad1d

Browse files
authored
Merge pull request #392 from Csantucci/elevator
Blueprint https://blueprints.launchpad.net/or/+spec/trainset-elevator Trainset elevator
2 parents 71798ba + 2320462 commit 2b5ad1d

File tree

3 files changed

+130
-21
lines changed

3 files changed

+130
-21
lines changed

Source/Documentation/Manual/features-route.rst

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,98 @@ The animation block for the above transfertable is as follows::
313313
3600 is not a mandatory value, however to have a reasonable transfer speed a number of
314314
animation keys equal to 60 - 90 every meter should be selected.
315315

316+
317+
Locomotive and wagon elevators
318+
------------------------------
319+
.. index::
320+
single: Elevator
321+
322+
The elevator is managed by ORTS as a vertically moving transfertable. So files needed
323+
are the same as used for a transfertable, with content modified where needed.
324+
325+
Info to identify an elevator in a route is stored in file turntables.dat, as it is
326+
for turntables and transfertables. The same file can store info for moving tables of
327+
different types. Here a turntables.dat file that contains info for an elevator::
328+
329+
1
330+
Transfertable(
331+
WFile ( "w-005578+014976.w" )
332+
UiD ( 75 )
333+
XOffset ( 0 )
334+
YOffset ( -0.18 )
335+
ZOffset ( 13.405)
336+
VerticalTransfer ( 1 )
337+
TrackShapeIndex ( 37301 )
338+
Animation ( "TRACKPIECE" )
339+
Length ( 26.81 )
340+
)
341+
342+
What identifies this as an elevator is the presence of the VerticalTransfer parameter
343+
with value 1. The other difference to a transfertable is the presence of the YOffset
344+
parameter, which is the vertical offset of the zero position of the elevator with respect to
345+
the shape file zero.
346+
347+
An example of the animation block in the elevator shape file is shown here below::
348+
349+
animations ( 1
350+
animation ( 1800 30
351+
anim_nodes ( 2
352+
anim_node BASIN (
353+
controllers ( 0 )
354+
)
355+
anim_node TRACKPIECE (
356+
controllers ( 1
357+
linear_pos ( 2
358+
linear_key ( 0 0 -1.92177 0 )
359+
linear_key ( 1800 0 6.07823 0 )
360+
)
361+
)
362+
)
363+
)
364+
)
365+
)
366+
367+
wich generates a vertical movement with a span of 8 meters which is covered in 60
368+
seconds. Of course the 1800 value may be modified to get the desired motion speed.
369+
370+
The elevator must also be defined as a TrackShape in tsection.dat. It is suggested
371+
to define it in a route specific ``tsection.dat`` extension file, which, for the
372+
sample elevator, is as follows::
373+
374+
375+
376+
include ( "../../../Global/tsection.dat" )
377+
_INFO ( Track section and shape addition for transfer table derived from turntable 27m )
378+
379+
TrackSections ( 40000
380+
381+
_SKIP ( No change here )
382+
383+
)
384+
385+
386+
TrackShapes ( 40000
387+
388+
_INFO(TrackShape for for vertical transfer table derived from turntable 27m)
389+
390+
TrackShape ( 37301
391+
FileName ( A1t27mVerticalTransfertable.s )
392+
NumPaths ( 2 )
393+
SectionIdx ( 1 0 -0.18 0.0000 0 338 )
394+
SectionIdx ( 1 0 7.82 0.0000 0 338 )
395+
)
396+
)
397+
398+
To insert the elevator in a route using TSRE5 it must be reminded that the latter
399+
doesn't look at the tsection.dat file within the Openrails subfolder. So, for the sole
400+
time of the editing of the route, the TrackShape() block must be inserted in the global
401+
tsection.dat. After route editing is terminated, the block may be removed.
402+
Tsection.dat build 38 or higher is required within the main Global folder.
403+
404+
At runtime the elevator is moved with the keys used for transfertables and turntables.
405+
Alt-C moves the elevator upwards, while Ctrl-C moves the elevator downwards.
406+
407+
316408
.. _features-route-turntable-operation:
317409

318410
Path laying and operation considerations

Source/Orts.Simulation/Simulation/Transfertables.cs

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,21 @@ namespace Orts.Simulation
4040

4141
public class Transfertable : MovingTable
4242
{
43-
public float Width;
43+
public float Span; // horizontal or vertical
4444
public List<float> Offsets = new List<float>();
45+
private bool VerticalTransfer = false;
46+
public float CenterOffsetComponent
47+
{
48+
get => VerticalTransfer ? CenterOffset.Y : CenterOffset.X;
49+
}
4550
// Dynamic data
4651
public bool Forward; // forward motion on
4752
public bool Reverse; // reverse motion on
48-
public float XPos = 0; // X Position of animated part, to be compared with X positions of endpoints
53+
public float OffsetPos = 0; // Offset Position of animated part, to be compared with offset positions of endpoints
4954
public bool Connected = true; // Transfertable is connected to a track
5055
public bool SaveConnected = true; // Transfertable is connected to a track
5156
public int ConnectedTarget = -1; // index of trackend connected
52-
public float TargetX = 0; //final target for Viewer;
57+
public float TargetOffset = 0; //final target for Viewer;
5358

5459
public Signals signalRef { get; protected set; }
5560

@@ -68,9 +73,11 @@ public Transfertable(STFReader stf, Simulator simulator): base(stf, simulator)
6873
new STFReader.TokenProcessor("uid", ()=>{ UID = stf.ReadIntBlock(-1); }),
6974
new STFReader.TokenProcessor("animation", ()=>{ animation = stf.ReadStringBlock(null);
7075
Animations.Add(animation.ToLower());}),
76+
new STFReader.TokenProcessor("verticaltransfer", ()=>{ VerticalTransfer = stf.ReadBoolBlock(false);}),
7177
new STFReader.TokenProcessor("length", ()=>{ Length = stf.ReadFloatBlock(STFReader.UNITS.None , null);}),
7278
new STFReader.TokenProcessor("xoffset", ()=>{ CenterOffset.X = stf.ReadFloatBlock(STFReader.UNITS.None , null);}),
7379
new STFReader.TokenProcessor("zoffset", ()=>{ CenterOffset.Z = -stf.ReadFloatBlock(STFReader.UNITS.None , null);}),
80+
new STFReader.TokenProcessor("yoffset", ()=>{ CenterOffset.Y = stf.ReadFloatBlock(STFReader.UNITS.None , null);}),
7481
new STFReader.TokenProcessor("trackshapeindex", ()=>
7582
{
7683
TrackShapeIndex = stf.ReadIntBlock(-1);
@@ -88,11 +95,11 @@ public override void Save(BinaryWriter outf)
8895
base.Save(outf);
8996
outf.Write(Forward);
9097
outf.Write(Reverse);
91-
outf.Write(XPos);
98+
outf.Write(OffsetPos);
9299
outf.Write(Connected);
93100
outf.Write(SaveConnected);
94101
outf.Write(ConnectedTarget);
95-
outf.Write(TargetX);
102+
outf.Write(TargetOffset);
96103
}
97104

98105

@@ -105,11 +112,11 @@ public override void Restore(BinaryReader inf, Simulator simulator)
105112
base.Restore(inf, simulator);
106113
Forward = inf.ReadBoolean();
107114
Reverse = inf.ReadBoolean();
108-
XPos = inf.ReadSingle();
115+
OffsetPos = inf.ReadSingle();
109116
Connected = inf.ReadBoolean();
110117
SaveConnected = inf.ReadBoolean();
111118
ConnectedTarget = inf.ReadInt32();
112-
TargetX = inf.ReadSingle();
119+
TargetOffset = inf.ReadSingle();
113120
}
114121

115122
protected void InitializeOffsetsAndTrackNodes()
@@ -122,7 +129,7 @@ protected void InitializeOffsetsAndTrackNodes()
122129
var iMyTrackNodes = 0;
123130
foreach (var sectionIdx in trackShape.SectionIdxs)
124131
{
125-
Offsets.Add((float)sectionIdx.X);
132+
Offsets.Add(VerticalTransfer ? (float)sectionIdx.Y : (float)sectionIdx.X);
126133
MyTrackNodesIndex[iMyTrackNodes] = -1;
127134
MyTrVectorSectionsIndex[iMyTrackNodes] = -1;
128135
iMyTrackNodes++;
@@ -148,9 +155,16 @@ protected void InitializeOffsetsAndTrackNodes()
148155
}
149156
}
150157
}
151-
XPos = CenterOffset.X;
152-
// Compute width of transfer table
153-
Width = (float)(trackShape.SectionIdxs[trackShape.SectionIdxs.Length - 1].X - trackShape.SectionIdxs[0].X);
158+
if (VerticalTransfer)
159+
{
160+
OffsetPos = CenterOffset.Y;
161+
Span = (float)(trackShape.SectionIdxs[trackShape.SectionIdxs.Length - 1].Y - trackShape.SectionIdxs[0].Y);
162+
}
163+
else
164+
{
165+
OffsetPos = CenterOffset.X;
166+
Span = (float)(trackShape.SectionIdxs[trackShape.SectionIdxs.Length - 1].X - trackShape.SectionIdxs[0].X);
167+
}
154168
}
155169

156170
/// <summary>
@@ -179,7 +193,7 @@ public override void ComputeTarget(bool isForward)
179193
{
180194
if (MyTrackNodesIndex[iOffset] != -1 && MyTrVectorSectionsIndex[iOffset] != -1)
181195
{
182-
var thisOffsetDiff = Offsets[iOffset] - XPos;
196+
var thisOffsetDiff = Offsets[iOffset] - OffsetPos;
183197
if (thisOffsetDiff < offsetDiff && thisOffsetDiff >= 0)
184198
{
185199
ConnectedTarget = iOffset;
@@ -210,7 +224,7 @@ public override void ComputeTarget(bool isForward)
210224
{
211225
if (MyTrackNodesIndex[iOffset] != -1 && MyTrVectorSectionsIndex[iOffset] != -1)
212226
{
213-
var thisOffsetDiff = Offsets[iOffset] - XPos;
227+
var thisOffsetDiff = Offsets[iOffset] - OffsetPos;
214228
if (thisOffsetDiff > offsetDiff && thisOffsetDiff <= 0)
215229
{
216230
ConnectedTarget = iOffset;
@@ -292,7 +306,10 @@ public override void StartContinuous(bool isForward)
292306
public void ComputeCenter(WorldPosition worldPosition)
293307
{
294308
Vector3 movingCenterOffset = CenterOffset;
295-
movingCenterOffset.X = XPos;
309+
if (VerticalTransfer)
310+
movingCenterOffset.Y = OffsetPos;
311+
else
312+
movingCenterOffset.X = OffsetPos;
296313
Vector3 originCoordinates;
297314
Vector3.Transform(ref movingCenterOffset, ref worldPosition.XNAMatrix, out originCoordinates);
298315
WorldPosition = new WorldPosition(worldPosition);
@@ -340,14 +357,14 @@ public override void Update()
340357
Connected = false;
341358
if (ConnectedTarget != -1)
342359
{
343-
if (Offsets[ConnectedTarget] - XPos < 0.005)
360+
if (Offsets[ConnectedTarget] - OffsetPos < 0.005)
344361
{
345362
Connected = true;
346363
Forward = false;
347364
ConnectedTrackEnd = ConnectedTarget;
348365
Simulator.Confirmer.Information (Simulator.Catalog.GetStringFmt("Transfertable connected"));
349366
GoToTarget = true;
350-
TargetX = Offsets[ConnectedTarget];
367+
TargetOffset = Offsets[ConnectedTarget];
351368
}
352369
}
353370
}
@@ -356,14 +373,14 @@ public override void Update()
356373
Connected = false;
357374
if (ConnectedTarget != -1)
358375
{
359-
if (XPos - Offsets[ConnectedTarget] < 0.005)
376+
if (OffsetPos - Offsets[ConnectedTarget] < 0.005)
360377
{
361378
Connected = true;
362379
Reverse = false;
363380
ConnectedTrackEnd = ConnectedTarget;
364381
Simulator.Confirmer.Information(Simulator.Catalog.GetStringFmt("Transfertable connected"));
365382
GoToTarget = true;
366-
TargetX = Offsets[ConnectedTarget];
383+
TargetOffset = Offsets[ConnectedTarget];
367384
}
368385
}
369386
}

Source/RunActivity/Viewer3D/Shapes.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,7 +1256,7 @@ public TransfertableShape(Viewer viewer, string path, WorldPosition initialPosit
12561256
: base(viewer, path, initialPosition, flags)
12571257
{
12581258
Transfertable = transfertable;
1259-
AnimationKey = (Transfertable.XPos - Transfertable.CenterOffset.X)/ Transfertable.Width * SharedShape.Animations[0].FrameCount;
1259+
AnimationKey = (Transfertable.OffsetPos - Transfertable.CenterOffsetComponent) / Transfertable.Span * SharedShape.Animations[0].FrameCount;
12601260
for (var imatrix = 0; imatrix < SharedShape.Matrices.Length; ++imatrix)
12611261
{
12621262
if (SharedShape.MatrixNames[imatrix].ToLower() == transfertable.Animations[0].ToLower())
@@ -1299,7 +1299,7 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
12991299
{
13001300
if (Transfertable.GoToTarget)
13011301
{
1302-
AnimationKey = (Transfertable.TargetX - Transfertable.CenterOffset.X) / Transfertable.Width * SharedShape.Animations[0].FrameCount;
1302+
AnimationKey = (Transfertable.TargetOffset - Transfertable.CenterOffsetComponent) / Transfertable.Span * SharedShape.Animations[0].FrameCount;
13031303
}
13041304

13051305
else if (Transfertable.Forward)
@@ -1313,7 +1313,7 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
13131313
if (AnimationKey > SharedShape.Animations[0].FrameCount) AnimationKey = SharedShape.Animations[0].FrameCount;
13141314
if (AnimationKey < 0) AnimationKey = 0;
13151315

1316-
Transfertable.XPos = AnimationKey / SharedShape.Animations[0].FrameCount * Transfertable.Width + Transfertable.CenterOffset.X;
1316+
Transfertable.OffsetPos = AnimationKey / SharedShape.Animations[0].FrameCount * Transfertable.Span + Transfertable.CenterOffsetComponent;
13171317

13181318
if ((Transfertable.Forward || Transfertable.Reverse) && !Translating)
13191319
{

0 commit comments

Comments
 (0)