Skip to content

Commit f5eef67

Browse files
committed
Make the 3d texture actually working. Usage in s file e.g.: image ( screens/etcs_dmi,maxspeed=280,maxvisiblespeed=280,units=kmph,displayunits=0 )
1 parent c27f32d commit f5eef67

File tree

5 files changed

+141
-76
lines changed

5 files changed

+141
-76
lines changed

Source/RunActivity/Viewer3D/Materials.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ public class SharedMaterialManager
247247
public readonly ShadowMapShader ShadowMapShader;
248248
public readonly SkyShader SkyShader;
249249
public readonly DebugShader DebugShader;
250+
public readonly CabShader CabShader;
250251

251252
public static Texture2D MissingTexture;
252253
public static Texture2D DefaultSnowTexture;
@@ -282,6 +283,7 @@ public SharedMaterialManager(Viewer viewer)
282283
ShadowMapShader = new ShadowMapShader(viewer.RenderProcess.GraphicsDevice);
283284
SkyShader = new SkyShader(viewer.RenderProcess.GraphicsDevice);
284285
DebugShader = new DebugShader(viewer.RenderProcess.GraphicsDevice);
286+
CabShader = new CabShader(viewer.RenderProcess.GraphicsDevice, Vector4.One, Vector4.One, Vector3.One, Vector3.One);
285287

286288
// TODO: This should happen on the loader thread.
287289
MissingTexture = SharedTextureManager.Get(viewer.RenderProcess.GraphicsDevice, Path.Combine(viewer.ContentPath, "blank.bmp"));
@@ -368,7 +370,7 @@ public Material Load(string materialName, string textureName = null, int options
368370
Materials[materialKey] = new WaterMaterial(Viewer, textureName);
369371
break;
370372
case "Screen":
371-
Materials[materialKey] = new ScreenMaterial(Viewer, textureName);
373+
Materials[materialKey] = new ScreenMaterial(Viewer, textureName, options);
372374
break;
373375
default:
374376
Trace.TraceInformation("Skipped unknown material type {0}", materialName);
@@ -562,7 +564,7 @@ internal void UpdateShaders()
562564
public abstract class Material
563565
{
564566
public readonly Viewer Viewer;
565-
readonly string Key;
567+
public readonly string Key;
566568

567569
protected Material(Viewer viewer, string key)
568570
{
@@ -1170,15 +1172,17 @@ public override bool GetBlending()
11701172
public class ScreenMaterial : SceneryMaterial
11711173
{
11721174
RollingStock.CabViewControlRenderer ScreenRenderer;
1175+
public readonly int HierarchyIndex;
11731176

1174-
public ScreenMaterial(Viewer viewer, string key)
1177+
public ScreenMaterial(Viewer viewer, string key, int hierarchyIndex)
11751178
: base(viewer, key, SceneryMaterialOptions.ShaderFullBright, 0)
11761179
{
1180+
HierarchyIndex = hierarchyIndex;
11771181
}
11781182

1179-
public void Set2DRenderer(RollingStock.CabViewControlRenderer circularSpeedGaugeRenderer)
1183+
public void Set2DRenderer(RollingStock.CabViewControlRenderer cabViewControlRenderer)
11801184
{
1181-
ScreenRenderer = circularSpeedGaugeRenderer;
1185+
ScreenRenderer = cabViewControlRenderer;
11821186
Texture = new RenderTarget2D(Viewer.GraphicsDevice,
11831187
(int)ScreenRenderer.Control.Width, (int)ScreenRenderer.Control.Height, false, SurfaceFormat.Color, DepthFormat.None);
11841188
}
@@ -1189,11 +1193,14 @@ public override void Render(GraphicsDevice graphicsDevice, IEnumerable<RenderIte
11891193
{
11901194
var originalRenderTargets = graphicsDevice.GetRenderTargets();
11911195
graphicsDevice.SetRenderTarget(Texture as RenderTarget2D);
1192-
ScreenRenderer.ControlView.SpriteBatch.Begin(); // Dummy Begin(), gets closed immediately
1196+
ScreenRenderer.ControlView.SpriteBatch.Begin();
11931197
ScreenRenderer.Draw(graphicsDevice);
11941198
ScreenRenderer.ControlView.SpriteBatch.End();
11951199
graphicsDevice.SetRenderTargets(originalRenderTargets);
11961200
}
1201+
1202+
Viewer.MaterialManager.SceneryShader.ImageTexture = Texture;
1203+
11971204
base.Render(graphicsDevice, renderItems, ref XNAViewMatrix, ref XNAProjectionMatrix);
11981205
}
11991206
}

Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3346,16 +3346,7 @@ public ThreeDimentionCabViewer(Viewer viewer, MSTSLocomotive car, MSTSLocomotive
33463346
break;
33473347
}
33483348

3349-
if (style is CircularSpeedGaugeRenderer || style is DriverMachineInterfaceRenderer)
3350-
{
3351-
// Attach the control renderer to the material
3352-
var material = Viewer.MaterialManager.Load("Screen", Helpers.GetTextureFile(Viewer.Simulator, Helpers.TextureFlags.None,
3353-
TrainCarShape.SharedShape.ReferencePath, matrixName)) as ScreenMaterial;
3354-
material?.Set2DRenderer(locoViewer.ThreeDimentionCabRenderer.ControlMap[key]);
3355-
3356-
ScreenDisplays3D.Add(key, new ThreeDimCabScreen(viewer, iMatrix, TrainCarShape, locoViewer.ThreeDimentionCabRenderer.ControlMap[key]));
3357-
}
3358-
else if (style != null && style is CabViewDigitalRenderer)//digits?
3349+
if (style != null && style is CabViewDigitalRenderer)//digits?
33593350
{
33603351
//DigitParts.Add(key, new DigitalDisplay(viewer, TrainCarShape, iMatrix, parameter, locoViewer.ThreeDimentionCabRenderer.ControlMap[key]));
33613352
DigitParts3D.Add(key, new ThreeDimCabDigit(viewer, iMatrix, parameter1, parameter2, this.TrainCarShape, locoViewer.ThreeDimentionCabRenderer.ControlMap[key], Locomotive));
@@ -3397,7 +3388,49 @@ public ThreeDimentionCabViewer(Viewer viewer, MSTSLocomotive car, MSTSLocomotive
33973388
}
33983389
}
33993390
}
3391+
3392+
var screens = TrainCarShape?.SharedShape?.LodControls?.FirstOrDefault()?.DistanceLevels?.FirstOrDefault()?
3393+
.SubObjects?.SelectMany(s => s.ShapePrimitives).Select(p => p.Material).Where(m => m is ScreenMaterial);
3394+
foreach (var screen in screens)
3395+
{
3396+
var material = screen as ScreenMaterial;
3397+
if (!int.TryParse(material.Key.Split(':').LastOrDefault(), out var id))
3398+
id = 0;
3399+
var des = material.Key.AsSpan();
3400+
var parameters = new Dictionary<string, string> { { "type", des.Slice(0, des.IndexOf(',')).ToString() } };
3401+
des = des.Slice(des.IndexOf(',') + 1);
3402+
while (des.IndexOf(',') is var c && c != -1)
3403+
{
3404+
if (des.IndexOf('=') is var e && e != -1)
3405+
{
3406+
var key = des.Slice(0, e).ToString();
3407+
if (!parameters.ContainsKey(key))
3408+
parameters.Add(key, des.Slice(e + 1, c - e - 1).ToString());
3409+
}
3410+
des = des.Slice(c + 1);
3411+
}
3412+
3413+
var control = new CVCScreen()
3414+
{
3415+
CustomParameters = { { "texture3d", "1" } },
3416+
Units = parameters.TryGetValue("units", out var units) && units == "mph" ? CABViewControlUnits.MILES_PER_HOUR : CABViewControlUnits.KM_PER_HOUR,
3417+
};
3418+
foreach (var p in parameters.Keys)
3419+
if (!control.CustomParameters.ContainsKey(p))
3420+
control.CustomParameters.Add(p, parameters[p]);
3421+
3422+
if (parameters.TryGetValue("type", out var type) && type == "screens/etcs_dmi")
3423+
{
3424+
// Usage: in s file e.g.: image ( screens/etcs_dmi,maxspeed=280,maxvisiblespeed=280,units=kmph,displayunits=0 )
3425+
3426+
var renderer = new DriverMachineInterfaceRenderer(Viewer, Locomotive, control, Viewer.MaterialManager.CabShader);
3427+
material.Set2DRenderer(renderer);
3428+
var sd3d = new ThreeDimCabScreen(Viewer, material.HierarchyIndex, TrainCarShape, renderer);
3429+
ScreenDisplays3D.Add((new CabViewControlType(CABViewControlTypes.ORTS_ETCS), id), sd3d);
3430+
}
3431+
}
34003432
}
3433+
34013434
public override void InitializeUserInputCommands() { }
34023435

34033436
/// <summary>
@@ -3536,6 +3569,24 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
35363569
p.Value.PrepareFrame(frame, elapsedTime);
35373570
}
35383571

3572+
foreach (var p in ScreenDisplays3D)
3573+
{
3574+
var screen = p.Value.CVFR.Control;
3575+
if (screen.Screens != null && screen.Screens[0] != "all")
3576+
{
3577+
foreach (var scr in screen.Screens)
3578+
{
3579+
if (LocoViewer.ThreeDimentionCabRenderer.ActiveScreen[screen.Display] == scr)
3580+
{
3581+
p.Value.PrepareFrame(frame, elapsedTime);
3582+
break;
3583+
}
3584+
}
3585+
continue;
3586+
}
3587+
p.Value.PrepareFrame(frame, elapsedTime);
3588+
}
3589+
35393590
foreach (var p in Gauges)
35403591
{
35413592
var gauge = p.Value.CVFR.Control;

Source/RunActivity/Viewer3D/RollingStock/SubSystems/ETCS/DriverMachineInterface.cs

Lines changed: 60 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -95,50 +95,47 @@ public enum DMIMode
9595
public bool IsSoftLayout;
9696
public DMIWindow ActiveWindow;
9797
DMIButton ActiveButton;
98-
public DriverMachineInterface(float height, float width, MSTSLocomotive locomotive, Viewer viewer, CabViewControl control)
98+
public readonly bool IsTexture3D;
99+
100+
public static readonly Dictionary<DMIMode, (int Width, int Height)> ScreenSizes = new Dictionary<DMIMode, (int, int)>
101+
{
102+
{ DMIMode.FullSize, (640, 480) },
103+
{ DMIMode.SpeedArea, (334, 480) },
104+
{ DMIMode.PlanningArea, (334, 480) },
105+
{ DMIMode.GaugeOnly, (280, 300) },
106+
};
107+
108+
public DriverMachineInterface(MSTSLocomotive locomotive, Viewer viewer, CabViewControl control)
99109
{
100-
if (control is CVCScreen)
110+
if (!(control is CVCScreen cvcScreen))
101111
{
102-
CurrentDMIMode = DMIMode.FullSize;
103-
if ((control as CVCScreen).CustomParameters.TryGetValue("mode", out string mode))
104-
{
105-
if (mode == "planningarea") CurrentDMIMode = DMIMode.PlanningArea;
106-
else if (mode == "speedarea") CurrentDMIMode = DMIMode.SpeedArea;
107-
}
112+
CurrentDMIMode = DMIMode.GaugeOnly;
108113
}
109114
else
110115
{
111-
CurrentDMIMode = DMIMode.GaugeOnly;
116+
if (!(cvcScreen.CustomParameters.TryGetValue("mode", out var mode) && Enum.TryParse(mode, ignoreCase: true, out CurrentDMIMode)))
117+
CurrentDMIMode = DMIMode.FullSize;
118+
IsTexture3D = cvcScreen.CustomParameters.TryGetValue("texture3d", out var texture3d) && texture3d == "1";
112119
}
113-
switch(CurrentDMIMode)
114-
{
115-
case DMIMode.GaugeOnly:
116-
Width = 280;
117-
Height = 300;
118-
break;
119-
case DMIMode.FullSize:
120-
Width = 640;
121-
Height = 480;
122-
break;
123-
case DMIMode.PlanningArea:
124-
case DMIMode.SpeedArea:
125-
Width = 334;
126-
Height = 480;
127-
break;
120+
121+
Width = ScreenSizes[CurrentDMIMode].Width;
122+
Height = ScreenSizes[CurrentDMIMode].Height;
123+
124+
if (IsTexture3D)
125+
{
126+
control.Width = Width;
127+
control.Height = Height;
128128
}
129+
SizeTo((float)control.Width, (float)control.Height);
130+
129131
Viewer = viewer;
130132
Locomotive = locomotive;
131-
Scale = Math.Min(width / Width, height / Height);
132-
if (Scale < 0.5) MipMapScale = 2;
133-
else MipMapScale = 1;
134-
135133
Shader = new DriverMachineInterfaceShader(Viewer.GraphicsDevice);
136-
ETCSDefaultWindow = new ETCSDefaultWindow(this, control);
137-
ETCSDefaultWindow.Visible = true;
138134

135+
ActiveWindow = ETCSDefaultWindow = new ETCSDefaultWindow(this, control) { Visible = true };
139136
AddToLayout(ETCSDefaultWindow, Point.Zero);
140-
ActiveWindow = ETCSDefaultWindow;
141137
}
138+
142139
public void ShowSubwindow(DMISubwindow window)
143140
{
144141
AddToLayout(window, new Point(window.FullScreen ? 0 : 334, 15));
@@ -761,7 +758,7 @@ public CircularSpeedGaugeRenderer(Viewer viewer, MSTSLocomotive locomotive, CVCD
761758
: base(viewer, locomotive, control, shader)
762759
{
763760
// Height is adjusted to keep compatibility
764-
DMI = new DriverMachineInterface((int)Control.Width, (int)Control.Height, locomotive, viewer, control);
761+
DMI = new DriverMachineInterface(locomotive, viewer, control);
765762
}
766763
public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
767764
{
@@ -794,34 +791,37 @@ public DriverMachineInterfaceRenderer(Viewer viewer, MSTSLocomotive locomotive,
794791
Control.Height *= 0.75f;
795792
Control.Width *= 0.75f;
796793
}
797-
DMI = new DriverMachineInterface((int)Control.Height, (int)Control.Width, locomotive, viewer, control);
794+
DMI = new DriverMachineInterface(locomotive, viewer, control);
798795
}
799796

800797
public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
801798
{
802799
if (!IsPowered && Control.HideIfDisabled)
803800
return;
804801

805-
base.PrepareFrame(frame, elapsedTime);
806-
var xScale = (float)Viewer.CabWidthPixels / 640;
807-
var yScale = (float)Viewer.CabHeightPixels / 480;
808-
DrawPosition.X = (int)(Position.X * xScale) - Viewer.CabXOffsetPixels + Viewer.CabXLetterboxPixels;
809-
DrawPosition.Y = (int)(Position.Y * yScale) + Viewer.CabYOffsetPixels + Viewer.CabYLetterboxPixels;
810-
DrawPosition.Width = (int)(Control.Width * xScale);
811-
DrawPosition.Height = (int)(Control.Height * yScale);
812-
if (Zoomed)
813-
{
814-
DrawPosition.Width = DMI.Width;
815-
DrawPosition.Height = DMI.Height;
816-
DMI.SizeTo(DrawPosition.Width, DrawPosition.Height);
817-
DrawPosition.X -= DMI.Width/2;
818-
DrawPosition.Y -= DMI.Height/2;
819-
DMI.ETCSDefaultWindow.BackgroundColor = ColorBackground;
820-
}
821-
else
802+
if (!DMI.IsTexture3D)
822803
{
823-
DMI.SizeTo(DrawPosition.Width, DrawPosition.Height);
824-
DMI.ETCSDefaultWindow.BackgroundColor = Color.Transparent;
804+
base.PrepareFrame(frame, elapsedTime);
805+
var xScale = (float)Viewer.CabWidthPixels / 640;
806+
var yScale = (float)Viewer.CabHeightPixels / 480;
807+
DrawPosition.X = (int)(Position.X * xScale) - Viewer.CabXOffsetPixels + Viewer.CabXLetterboxPixels;
808+
DrawPosition.Y = (int)(Position.Y * yScale) + Viewer.CabYOffsetPixels + Viewer.CabYLetterboxPixels;
809+
DrawPosition.Width = (int)(Control.Width * xScale);
810+
DrawPosition.Height = (int)(Control.Height * yScale);
811+
if (Zoomed)
812+
{
813+
DrawPosition.Width = DMI.Width;
814+
DrawPosition.Height = DMI.Height;
815+
DMI.SizeTo(DrawPosition.Width, DrawPosition.Height);
816+
DrawPosition.X -= DMI.Width / 2;
817+
DrawPosition.Y -= DMI.Height / 2;
818+
DMI.ETCSDefaultWindow.BackgroundColor = ColorBackground;
819+
}
820+
else
821+
{
822+
DMI.SizeTo(DrawPosition.Width, DrawPosition.Height);
823+
DMI.ETCSDefaultWindow.BackgroundColor = Color.Transparent;
824+
}
825825
}
826826
DMI.PrepareFrame(elapsedTime.ClockSeconds);
827827
}
@@ -879,5 +879,13 @@ public ThreeDimCabScreen(Viewer viewer, int iMatrix, PoseableShape trainCarShape
879879
TrainCarShape = trainCarShape;
880880
XNAMatrix = TrainCarShape.SharedShape.Matrices[iMatrix];
881881
}
882+
883+
public void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
884+
{
885+
if (!CVFR.IsPowered && CVFR.Control.HideIfDisabled)
886+
return;
887+
888+
CVFR.PrepareFrame(frame, elapsedTime);
889+
}
882890
}
883891
}

Source/RunActivity/Viewer3D/RollingStock/SubSystems/ETCS/SpeedDistanceMonitoring.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -301,12 +301,15 @@ private void SetData(ETCSStatus status)
301301
int permittedSpeed = (int)SpeedFromMpS(status.AllowedSpeedMpS);
302302
int targetSpeed = status.TargetSpeedMpS < status.AllowedSpeedMpS ? (int)SpeedFromMpS(status.TargetSpeedMpS.Value) : permittedSpeed;
303303
int releaseSpeed = (int)SpeedFromMpS(status.ReleaseSpeedMpS ?? 0);
304-
float interventionSpeed = SpeedFromMpS(status.InterventionSpeedMpS);
304+
int interventionSpeed = (int)SpeedFromMpS(status.InterventionSpeedMpS);
305+
306+
SpeedText = (int)(currentSpeed + (currentSpeed < 1f || currentSpeed < (float)SpeedText ? 0.99999f : 0.49999f));
307+
CurrentSpeedAngle = Speed2Angle(SpeedText);
305308

306309
if (interventionSpeed < permittedSpeed && interventionSpeed < releaseSpeed)
307310
interventionSpeed = Math.Max(permittedSpeed, releaseSpeed);
308311
if (currentSpeed > permittedSpeed && currentSpeed > interventionSpeed)
309-
interventionSpeed = Math.Max(currentSpeed - 1, releaseSpeed);
312+
interventionSpeed = Math.Max(SpeedText, releaseSpeed);
310313

311314
switch (status.CurrentMode)
312315
{
@@ -376,10 +379,6 @@ private void SetData(ETCSStatus status)
376379
DMI.Shader.SetData(shaderAngles, GaugeColor, NeedleColor, GaugeColor);
377380
}
378381

379-
CurrentSpeedAngle = Speed2Angle(currentSpeed);
380-
381-
SpeedText = (int)(currentSpeed + (currentSpeed < 1f || currentSpeed < (float)SpeedText ? 0.99999f : 0.49999f));
382-
383382
for (int i = 0, d = 1; i < CurrentSpeed.Length; i++, d *= 10)
384383
{
385384
CurrentSpeed[i].Color = SpeedColor;

Source/RunActivity/Viewer3D/Shapes.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2284,8 +2284,8 @@ public SubObject(sub_object sub_object, ref int totalPrimitiveIndex, int[] hiera
22842284
material = sharedShape.Viewer.MaterialManager.Load("Scenery", Helpers.GetRouteTextureFile(sharedShape.Viewer.Simulator, textureFlags, imageName), (int)options, texture.MipMapLODBias);
22852285
else
22862286
{
2287-
if (imageName.ToUpper().Contains(nameof(CABViewControlTypes.ORTS_ETCS)))
2288-
material = sharedShape.Viewer.MaterialManager.Load("Screen", Helpers.GetTextureFile(sharedShape.Viewer.Simulator, Helpers.TextureFlags.None, sharedShape.ReferencePath, imageName));
2287+
if (imageName.ToLower().StartsWith("screens/"))
2288+
material = sharedShape.Viewer.MaterialManager.Load("Screen", imageName + "," + Guid.NewGuid(), vertexState.imatrix);
22892289
else
22902290
material = sharedShape.Viewer.MaterialManager.Load("Scenery", Helpers.GetTextureFile(sharedShape.Viewer.Simulator, textureFlags, sharedShape.ReferencePath, imageName), (int)options, texture.MipMapLODBias);
22912291
}

0 commit comments

Comments
 (0)