Skip to content

Commit fdbea15

Browse files
authored
DMI in 3D cab + two more dials
Merge pull request #900 from pzgulyas/dmi280
2 parents 959de23 + 4629736 commit fdbea15

File tree

6 files changed

+241
-104
lines changed

6 files changed

+241
-104
lines changed

Source/Documentation/Manual/cabs.rst

+47-28
Original file line numberDiff line numberDiff line change
@@ -20,46 +20,65 @@ next paragraphs.
2020
ETCS circular speed gauge
2121
-------------------------
2222

23-
You can add to the cabview a
24-
circular speed gauge accordingly to the European standard train control
25-
system ETCS.
23+
A circular speed gauge accordingly to the standard European Train Control System
24+
(ETCS) can be added to the cabview. The information displayed in the Driver
25+
Machine Interface (DMI) is controlled via the TCS script. For more details,
26+
see :ref:`C# engine scripting - Train Control System <features-scripting-tcs>`.
27+
2628

2729
.. image:: images/options-etcs.png
2830
:scale: 60 %
2931
:align: center
3032

3133

32-
.. admonition:: For content developers
33-
34-
The gauge is added by the insertion of a block like the following
35-
into the .cvf file::
34+
The gauge is added by the insertion of a block like the following
35+
into the .cvf file::
3636

37-
Digital (
38-
Type ( SPEEDOMETER DIGITAL )
39-
Style ( NEEDLE )
40-
Position ( 160 255 56 56 )
41-
ScaleRange ( 0 250 )
42-
Units ( KM_PER_HOUR )
43-
)
37+
Digital (
38+
Type ( SPEEDOMETER DIGITAL )
39+
Style ( NEEDLE )
40+
Position ( 160 255 56 56 )
41+
ScaleRange ( 0 250 )
42+
Units ( KM_PER_HOUR )
43+
)
4444

4545
It is also possible to display the full ETCS display using the following block
4646
instead::
4747

48-
ScreenDisplay (
49-
Type ( ORTS_ETCS SCREEN_DISPLAY )
50-
Position ( 280 272 320 240 )
51-
Units ( KM_PER_HOUR )
52-
Parameters (
53-
Mode FullSize
54-
)
55-
)
56-
57-
The following DMI size variants are available: FullSize (displays the whole DMI), SpeedArea
58-
(displays only the left part with information about distance and speed) and PlanningArea
59-
(displays only the planning area and navigation buttons).
48+
ScreenDisplay (
49+
Type ( ORTS_ETCS SCREEN_DISPLAY )
50+
Graphic ( statictexture.ace ) Comment( 3D cab only, mandatory there )
51+
Position ( 280 272 320 240 ) Comment( 2D cab only )
52+
Units ( KM_PER_HOUR )
53+
Parameters (
54+
Mode FullSize
55+
MaxSpeed 180
56+
DisplayUnits 0
57+
)
58+
)
6059

61-
The information displayed in the DMI is controlled via the TCS script. For more details,
62-
see :ref:`C# engine scripting - Train Control System <features-scripting-tcs>`.
60+
The following commonly used ``MaxSpeed`` or ``ScaleRange`` values can be set
61+
* 140, 150, 180, 240, 250, 260, 280, 400 for ``KM_PER_HOUR`` unit
62+
* 87, 111, 155, 248 for ``MILES_PER_HOUR`` unit
63+
The default value is 400 with KM_PER_HOUR unit.
64+
65+
The following DMI size variants are available:
66+
``FullSize`` displays the whole DMI,
67+
``SpeedArea`` displays only the left part with information about distance and speed,
68+
``PlanningArea`` displays only the right side planning area and navigation buttons.
69+
The default value is FullSize
70+
71+
Use the ``MaxVisibleSpeed`` to set the highest speed displayed as a number,
72+
if literal numbering is undesirable above this number on the circular speed gauge.
73+
The default value is the MaxSpeed rounded to the highest tens below.
74+
75+
Use the ``DisplayUnits`` parameter to suppress diplaying the speed unit at the
76+
bottom of the circular speed gauge. The default is 1, displaying the units.
77+
78+
Use the ``Graphic`` parameter in 3D cabs to designate the static texture inside
79+
the .s file that will be replaced at runtime with the dynamic picture of the
80+
display. This parameter is mandatory. If omitted, or the named texture cannot
81+
be found in the model, no display will be shown.
6382

6483
.. _cabs-battery:
6584

Source/RunActivity/Viewer3D/Materials.cs

+42-1
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ public class SharedMaterialManager
294294
public readonly ShadowMapShader ShadowMapShader;
295295
public readonly SkyShader SkyShader;
296296
public readonly DebugShader DebugShader;
297+
public readonly CabShader CabShader;
297298

298299
public static Texture2D MissingTexture;
299300
public static Texture2D DefaultSnowTexture;
@@ -329,6 +330,7 @@ public SharedMaterialManager(Viewer viewer)
329330
ShadowMapShader = new ShadowMapShader(viewer.RenderProcess.GraphicsDevice);
330331
SkyShader = new SkyShader(viewer.RenderProcess.GraphicsDevice);
331332
DebugShader = new DebugShader(viewer.RenderProcess.GraphicsDevice);
333+
CabShader = new CabShader(viewer.RenderProcess.GraphicsDevice, Vector4.One, Vector4.One, Vector3.One, Vector3.One);
332334

333335
// TODO: This should happen on the loader thread.
334336
MissingTexture = SharedTextureManager.Get(viewer.RenderProcess.GraphicsDevice, Path.Combine(viewer.ContentPath, "blank.bmp"));
@@ -414,6 +416,9 @@ public Material Load(string materialName, string textureName = null, int options
414416
case "Water":
415417
Materials[materialKey] = new WaterMaterial(Viewer, textureName);
416418
break;
419+
case "Screen":
420+
Materials[materialKey] = new ScreenMaterial(Viewer, textureName, options);
421+
break;
417422
default:
418423
Trace.TraceInformation("Skipped unknown material type {0}", materialName);
419424
Materials[materialKey] = new YellowMaterial(Viewer);
@@ -606,7 +611,7 @@ internal void UpdateShaders()
606611
public abstract class Material
607612
{
608613
public readonly Viewer Viewer;
609-
readonly string Key;
614+
public readonly string Key;
610615

611616
protected Material(Viewer viewer, string key)
612617
{
@@ -1211,6 +1216,42 @@ public override bool GetBlending()
12111216
}
12121217
}
12131218

1219+
public class ScreenMaterial : SceneryMaterial
1220+
{
1221+
RollingStock.CabViewControlRenderer ScreenRenderer;
1222+
public readonly int HierarchyIndex;
1223+
1224+
public ScreenMaterial(Viewer viewer, string key, int hierarchyIndex)
1225+
: base(viewer, key, SceneryMaterialOptions.ShaderFullBright, 0)
1226+
{
1227+
HierarchyIndex = hierarchyIndex;
1228+
}
1229+
1230+
public void Set2DRenderer(RollingStock.CabViewControlRenderer cabViewControlRenderer)
1231+
{
1232+
ScreenRenderer = cabViewControlRenderer;
1233+
Texture = new RenderTarget2D(Viewer.GraphicsDevice,
1234+
(int)ScreenRenderer.Control.Width, (int)ScreenRenderer.Control.Height, false, SurfaceFormat.Color, DepthFormat.None, 8, RenderTargetUsage.DiscardContents);
1235+
}
1236+
1237+
public override void Render(GraphicsDevice graphicsDevice, IEnumerable<RenderItem> renderItems, ref Matrix XNAViewMatrix, ref Matrix XNAProjectionMatrix)
1238+
{
1239+
if (ScreenRenderer != null)
1240+
{
1241+
var originalRenderTargets = graphicsDevice.GetRenderTargets();
1242+
graphicsDevice.SetRenderTarget(Texture as RenderTarget2D);
1243+
ScreenRenderer.ControlView.SpriteBatch.Begin();
1244+
ScreenRenderer.Draw(graphicsDevice);
1245+
ScreenRenderer.ControlView.SpriteBatch.End();
1246+
graphicsDevice.SetRenderTargets(originalRenderTargets);
1247+
}
1248+
1249+
Viewer.MaterialManager.SceneryShader.ImageTexture = Texture;
1250+
1251+
base.Render(graphicsDevice, renderItems, ref XNAViewMatrix, ref XNAProjectionMatrix);
1252+
}
1253+
}
1254+
12141255
public class YellowMaterial : Material
12151256
{
12161257
static BasicEffect basicEffect;

Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs

+39-1
Original file line numberDiff line numberDiff line change
@@ -1603,7 +1603,7 @@ public abstract class CabViewControlRenderer : RenderPrimitive
16031603
protected readonly MSTSLocomotive Locomotive;
16041604
public readonly CabViewControl Control;
16051605
protected readonly CabShader Shader;
1606-
protected readonly SpriteBatchMaterial ControlView;
1606+
public readonly SpriteBatchMaterial ControlView;
16071607

16081608
protected Vector2 Position;
16091609
protected Texture2D Texture;
@@ -3376,6 +3376,7 @@ public class ThreeDimentionCabViewer : TrainCarViewer
33763376
//Dictionary<int, DigitalDisplay> DigitParts = null;
33773377
Dictionary<(CabViewControlType, int), ThreeDimCabDigit> DigitParts3D = null;
33783378
Dictionary<(CabViewControlType, int), ThreeDimCabDPI> DPIDisplays3D = null;
3379+
Dictionary<(CabViewControlType, int), ThreeDimCabScreen> ScreenDisplays3D = null;
33793380
AnimatedPart ExternalWipers = null; // setting to zero to prevent a warning. Probably this will be used later. TODO
33803381
protected MSTSLocomotive MSTSLocomotive { get { return (MSTSLocomotive)Car; } }
33813382
MSTSLocomotiveViewer LocoViewer;
@@ -3399,6 +3400,7 @@ public ThreeDimentionCabViewer(Viewer viewer, MSTSLocomotive car, MSTSLocomotive
33993400
DigitParts3D = new Dictionary<(CabViewControlType, int), ThreeDimCabDigit>();
34003401
Gauges = new Dictionary<(CabViewControlType, int), ThreeDimCabGaugeNative>();
34013402
DPIDisplays3D = new Dictionary<(CabViewControlType, int), ThreeDimCabDPI>();
3403+
ScreenDisplays3D = new Dictionary<(CabViewControlType, int), ThreeDimCabScreen>();
34023404
OnDemandAnimateParts = new Dictionary<(CabViewControlType, int), AnimatedPart>();
34033405

34043406
// Find the animated parts
@@ -3519,7 +3521,25 @@ public ThreeDimentionCabViewer(Viewer viewer, MSTSLocomotive car, MSTSLocomotive
35193521
}
35203522
}
35213523
}
3524+
3525+
// Find the animated textures, like screens
3526+
if (locoViewer.ThreeDimentionCabRenderer.ControlMap.Values.FirstOrDefault(c => c is DriverMachineInterfaceRenderer) is DriverMachineInterfaceRenderer cvcr
3527+
&& cvcr.Control?.ACEFile is var textureName && textureName != null)
3528+
{
3529+
textureName = Path.GetFileName(textureName).ToLower();
3530+
if (TrainCarShape?.SharedShape?.LodControls?.FirstOrDefault()?.DistanceLevels?.FirstOrDefault()?
3531+
.SubObjects?.SelectMany(s => s.ShapePrimitives).Where(p => p.Material.Key.Contains(textureName)).FirstOrDefault() is var primitive && primitive != null)
3532+
{
3533+
cvcr.SetTexture3D();
3534+
var material = Viewer.MaterialManager.Load("Screen", TrainCarShape.SharedShape.ReferencePath + cvcr.Control.ACEFile, primitive.HierarchyIndex) as ScreenMaterial;
3535+
material.Set2DRenderer(cvcr);
3536+
primitive.SetMaterial(material);
3537+
ScreenDisplays3D.Add((new CabViewControlType(CABViewControlTypes.ORTS_ETCS), 0),
3538+
new ThreeDimCabScreen(Viewer, material.HierarchyIndex, TrainCarShape, cvcr));
3539+
}
3540+
}
35223541
}
3542+
35233543
public override void InitializeUserInputCommands() { }
35243544

35253545
/// <summary>
@@ -3658,6 +3678,24 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
36583678
p.Value.PrepareFrame(frame, elapsedTime);
36593679
}
36603680

3681+
foreach (var p in ScreenDisplays3D)
3682+
{
3683+
var screen = p.Value.CVFR.Control;
3684+
if (screen.Screens != null && screen.Screens[0] != "all")
3685+
{
3686+
foreach (var scr in screen.Screens)
3687+
{
3688+
if (LocoViewer.ThreeDimentionCabRenderer.ActiveScreen[screen.Display] == scr)
3689+
{
3690+
p.Value.PrepareFrame(frame, elapsedTime);
3691+
break;
3692+
}
3693+
}
3694+
continue;
3695+
}
3696+
p.Value.PrepareFrame(frame, elapsedTime);
3697+
}
3698+
36613699
foreach (var p in Gauges)
36623700
{
36633701
var gauge = p.Value.CVFR.Control;

0 commit comments

Comments
 (0)