Skip to content

Commit 46cea5d

Browse files
authored
Merge pull request #373 from Csantucci/inclined-gauges-for-master
https://trello.com/c/Ek3wMQRs/484-enable-rotation-of-gauges-in-2d-cabs Enable inclined gauges in 2D cabs
2 parents 218a195 + 794654f commit 46cea5d

File tree

4 files changed

+62
-28
lines changed

4 files changed

+62
-28
lines changed

Source/Documentation/Manual/cabs.rst

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -411,28 +411,38 @@ Note that you cannot use the MS Cabview editor on the .cvf file after having
411411
inserted these optional lines, because the editor will delete these added
412412
lines when the file is saved.
413413

414-
Rotation of Digital controls
415-
----------------------------
414+
Rotation of Gauges and Digital controls
415+
---------------------------------------
416416

417417
.. index::
418418
single: ORTSAngle
419419

420420
One of the drawbacks of rendering a cabview in 2D is that some parts of it
421-
are not shown with a frontal, horizontal, view. Displaying a horizontal digital
422-
control on it generates an unrealistc effect. This is the rationale of following
423-
entry, to be added within a Digital cabview control block in the .cvf file::
421+
are not shown with a frontal, precisely vertical or horizontal, view.
422+
Displaying a vertical gauge or a horizontal digital control on it generates an
423+
unrealistic effect. This is the rationale of following entry, to be added
424+
within a Gauge or Digital cabview control block in the .cvf file::
424425

425426
ORTSAngle ( 5 )
426427

427428
The number in parenthesis is the angle in degrees with respect to the horizontal
428-
(positive for counterclockwise rotation).
429+
(or to the vertical for vertical gauges). Positive values produce
430+
counterclockwise rotation.
431+
432+
At the left of the picture an example of a white vertical gauge that has been rotated
433+
by 12 degrees
434+
435+
.. image:: images/cabs-gauges-rotation.png
429436

430437
Here an example of a red max speed indication that has been rotated by 5 degrees
431438

432439
.. image:: images/cabs-digitals-rotation.png
433440

441+
Gauges may have Style POINTER or SOLID.
442+
434443
Rotation may be applied, with the same syntax, also to DigitalClock cab controls.
435444

445+
436446
3D cabs
437447
=======
438448

87.7 KB
Loading

Source/Orts.Formats.Msts/CabViewFile.cs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,13 @@ protected virtual float ParseSwitchVal(STFReader stf)
446446
stf.SkipRestOfBlock();
447447
return switchVal;
448448
}
449+
protected virtual float ParseRotation(STFReader stf)
450+
{
451+
stf.MustMatch("(");
452+
var rotation = -MathHelper.ToRadians((float)stf.ReadDouble(0));
453+
stf.SkipRestOfBlock();
454+
return rotation;
455+
}
449456
}
450457
#endregion
451458

@@ -516,6 +523,7 @@ public class CVCGauge : CabViewControl
516523
public int NumPositiveColors { get; set; }
517524
public int NumNegativeColors { get; set; }
518525
public color DecreaseColor { get; set; }
526+
public float Rotation { get; set; }
519527

520528
public CVCGauge() { }
521529

@@ -576,7 +584,8 @@ public CVCGauge(STFReader stf, string basepath)
576584
stf.ParseBlock(new STFReader.TokenProcessor[] {
577585
new STFReader.TokenProcessor("controlcolour", ()=>{ DecreaseColor = ParseControlColor(stf); }) });
578586
}
579-
})
587+
}),
588+
new STFReader.TokenProcessor("ortsangle", () =>{ Rotation = ParseRotation(stf); })
580589
});
581590
}
582591
}
@@ -697,7 +706,7 @@ public CVCDigital(STFReader stf, string basepath)
697706
}
698707
}),
699708
new STFReader.TokenProcessor("ortsfont", ()=>{ParseFont(stf); }),
700-
new STFReader.TokenProcessor("ortsangle", () => { ParseRotation(stf); }),
709+
new STFReader.TokenProcessor("ortsangle", () => {Rotation = ParseRotation(stf); }),
701710
});
702711
}
703712

@@ -738,14 +747,6 @@ protected void ParseFont(STFReader stf)
738747
if (fontFamily != null) FontFamily = fontFamily;
739748
stf.SkipRestOfBlock();
740749
}
741-
742-
protected virtual void ParseRotation(STFReader stf)
743-
{
744-
stf.MustMatch("(");
745-
Rotation = - MathHelper.ToRadians((float)stf.ReadDouble(0));
746-
stf.SkipRestOfBlock();
747-
}
748-
749750
}
750751

751752
public class CVCDigitalClock : CVCDigital
@@ -764,7 +765,7 @@ public CVCDigitalClock(STFReader stf, string basepath)
764765
new STFReader.TokenProcessor("accuracy", ()=>{ ParseAccuracy(stf); }),
765766
new STFReader.TokenProcessor("controlcolour", ()=>{ PositiveColor = ParseControlColor(stf); }),
766767
new STFReader.TokenProcessor("ortsfont", ()=>{ParseFont(stf); }),
767-
new STFReader.TokenProcessor("ortsangle", () => { ParseRotation(stf); })
768+
new STFReader.TokenProcessor("ortsangle", () => { Rotation = ParseRotation(stf); })
768769
});
769770
}
770771

Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,7 @@ public class CabViewGaugeRenderer : CabViewControlRenderer
15221522
Rectangle DestinationRectangle = new Rectangle();
15231523
// bool LoadMeterPositive = true;
15241524
Color DrawColor;
1525+
float DrawRotation;
15251526
Double Num;
15261527
bool IsFire;
15271528

@@ -1605,30 +1606,38 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
16051606
{
16061607
if (Gauge.Orientation == 0)
16071608
{
1608-
destX = (int)(xratio * (Control.PositionX + (zeropos < xpos ? zeropos : xpos)));
1609-
destY = (int)(yratio * Control.PositionY);
1610-
destW = (int)(xratio * (xpos > zeropos ? xpos - zeropos : zeropos - xpos));
1609+
destX = (int)(xratio * (Control.PositionX)) + (int)(xratio * (zeropos < xpos ? zeropos : xpos));
1610+
// destY = (int)(yratio * Control.PositionY);
1611+
destY = (int)(yratio * (Control.PositionY) - (int)(yratio * (Gauge.Direction == 0 && zeropos > xpos ? (zeropos - xpos) * Math.Sin(DrawRotation) : 0)));
1612+
destW = ((int)(xratio * xpos) - (int)(xratio * zeropos)) * (xpos >= zeropos ? 1 : -1);
16111613
destH = (int)(yratio * ypos);
16121614
}
16131615
else
16141616
{
1615-
destX = (int)(xratio * Control.PositionX);
1617+
destX = (int)(xratio * Control.PositionX) +(int)(xratio * (Gauge.Direction == 0 && ypos > zeropos ? (ypos - zeropos) * Math.Sin(DrawRotation) : 0));
16161618
if (Gauge.Direction != 1 && !IsFire)
1617-
destY = (int)(yratio * (Control.PositionY + (zeropos > ypos ? zeropos : 2 * zeropos - ypos)));
1619+
destY = (int)(yratio * (Control.PositionY + zeropos)) + (ypos > zeropos ? (int)(yratio * (zeropos - ypos)) : 0);
16181620
else
16191621
destY = (int)(yratio * (Control.PositionY + (zeropos < ypos ? zeropos : ypos)));
16201622
destW = (int)(xratio * xpos);
1621-
destH = (int)(yratio * (ypos > zeropos ? ypos - zeropos : zeropos - ypos));
1623+
destH = ((int)(yratio * (ypos - zeropos))) * (ypos > zeropos ? 1 : -1);
16221624
}
16231625
}
16241626
else
16251627
{
16261628
var topY = Control.PositionY; // top of visible column. +ve Y is downwards
16271629
if (Gauge.Direction != 0) // column grows from bottom or from right
16281630
{
1629-
destX = (int)(xratio * (Control.PositionX + Gauge.Width - xpos));
16301631
if (Gauge.Orientation != 0)
1632+
{
16311633
topY += Gauge.Height * (1 - percent);
1634+
destX = (int)(xratio * (Control.PositionX + Gauge.Width - xpos + ypos * Math.Sin(DrawRotation)));
1635+
}
1636+
else
1637+
{
1638+
topY -= xpos * Math.Sin(DrawRotation);
1639+
destX = (int)(xratio * (Control.PositionX + Gauge.Width - xpos));
1640+
}
16321641
}
16331642
else
16341643
{
@@ -1641,20 +1650,33 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
16411650
}
16421651
else // pointer gauge using texture
16431652
{
1653+
// even if there is a rotation, we leave the X position unaltered (for small angles Cos(alpha) = 1)
16441654
var topY = Control.PositionY; // top of visible column. +ve Y is downwards
16451655
if (Gauge.Orientation == 0) // gauge horizontal
16461656
{
1657+
16471658
if (Gauge.Direction != 0) // column grows from right
1659+
{
16481660
destX = (int)(xratio * (Control.PositionX + Gauge.Width - 0.5 * Gauge.Area.Width - xpos));
1661+
topY -= xpos * Math.Sin(DrawRotation);
1662+
}
16491663
else
1664+
{
16501665
destX = (int)(xratio * (Control.PositionX - 0.5 * Gauge.Area.Width + xpos));
1666+
topY += xpos * Math.Sin(DrawRotation);
1667+
}
16511668
}
16521669
else // gauge vertical
16531670
{
1671+
// even if there is a rotation, we leave the Y position unaltered (for small angles Cos(alpha) = 1)
16541672
topY += ypos - 0.5 * Gauge.Area.Height;
1655-
destX = (int)(xratio * Control.PositionX);
1656-
if (Gauge.Direction != 0) // column grows from bottom
1657-
topY += Gauge.Height - 2 * ypos;
1673+
if (Gauge.Direction == 0)
1674+
destX = (int)(xratio * (Control.PositionX - ypos * Math.Sin(DrawRotation)));
1675+
else // column grows from bottom
1676+
{
1677+
topY += Gauge.Height - 2.0f * ypos;
1678+
destX = (int)(xratio * (Control.PositionX + ypos * Math.Sin(DrawRotation)));
1679+
}
16581680
}
16591681
destY = (int)(yratio * topY);
16601682
destW = (int)(xratio * Gauge.Area.Width);
@@ -1693,6 +1715,7 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
16931715
DestinationRectangle.Y = destY;
16941716
DestinationRectangle.Width = destW;
16951717
DestinationRectangle.Height = destH;
1718+
DrawRotation = Gauge.Rotation;
16961719
}
16971720

16981721
public override void Draw(GraphicsDevice graphicsDevice)
@@ -1701,7 +1724,7 @@ public override void Draw(GraphicsDevice graphicsDevice)
17011724
{
17021725
Shader.SetTextureData(DestinationRectangle.Left, DestinationRectangle.Top, DestinationRectangle.Width, DestinationRectangle.Height);
17031726
}
1704-
ControlView.SpriteBatch.Draw(Texture, DestinationRectangle, SourceRectangle, DrawColor);
1727+
ControlView.SpriteBatch.Draw(Texture, DestinationRectangle, SourceRectangle, DrawColor, DrawRotation, origin: Vector2.Zero, SpriteEffects.None, layerDepth: 0);
17051728
}
17061729
}
17071730

0 commit comments

Comments
 (0)