Skip to content

Commit de2793f

Browse files
committed
Implement Display settings, UnitConversion class, bump 3.2.5.
1 parent 06e3fce commit de2793f

16 files changed

Lines changed: 705 additions & 79 deletions

ETS2LA.Overlay/AR/AR.cs

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ public class ARRenderer
2222
private int thisFrameWidth = 0;
2323
private int thisFrameHeight = 0;
2424

25+
private OverlaySettings overlaySettings;
26+
2527
// These are all variables that are needed for
2628
// rendering ImGui windows in 3D space.
2729
private GL gl;
@@ -53,7 +55,16 @@ public ARRenderer(GL gl)
5355
cameraData = CameraProvider.Current.GetCurrentData();
5456
telemetryData = GameTelemetry.Current.GetCurrentData();
5557

58+
overlaySettings = OverlaySettingsHandler.Current.GetSettings();
59+
OverlaySettingsHandler.Current.OnSettingsUpdated += OnOverlaySettingsUpdated;
60+
5661
ImGui.SetCurrentContext(mainContext);
62+
63+
}
64+
65+
private void OnOverlaySettingsUpdated(OverlaySettings newSettings)
66+
{
67+
overlaySettings = newSettings;
5768
}
5869

5970
/// <summary>
@@ -65,6 +76,7 @@ public void Render()
6576
{
6677
thisFrameProjection = default;
6778
thisFrameView = default;
79+
GetViewMatrix();
6880

6981
thisFrameWidth = (int)OverlayHandler.Current.OverlayWidth;
7082
thisFrameHeight = (int)OverlayHandler.Current.OverlayHeight;
@@ -185,12 +197,11 @@ public Matrix4x4 GetProjectionMatrix()
185197
}
186198

187199
/// <summary>
188-
/// This function will return the world space coordinates of the provided ARCoordinate
189-
/// while also taking into account the coordinate center. Truck positions are interpolated
190-
/// to avoid jitter.
200+
/// This function will return the camera space coordinates of the provided ARCoordinate
201+
/// while also taking into account the coordinate center.
191202
/// </summary>
192203
/// <param name="coord">ARCoordinate to convert.</param>
193-
/// <returns>World space coordinates.</returns>
204+
/// <returns>camera space coordinates.</returns>
194205
/// <exception cref="ArgumentException"></exception>
195206
public Vector3 ARCoordinateToVector3(ARCoordinate coord)
196207
{
@@ -226,6 +237,22 @@ private uint ConvertColor(uint rgba)
226237
((rgba & 0x000000FF) << 24);
227238
}
228239

240+
private bool AllPointsOutsideRenderDistance(ARCoordinate[] points)
241+
{
242+
float maxDistance = overlaySettings.MaxARDistance;
243+
Vector3 cameraPos = cameraData.position;
244+
245+
foreach (var point in points)
246+
{
247+
Vector3 worldPos = ARCoordinateToVector3(point);
248+
float distance = Vector3.Distance(worldPos, cameraPos);
249+
if (distance <= maxDistance)
250+
return false;
251+
}
252+
253+
return true;
254+
}
255+
229256
/// <summary>
230257
/// Draw a line in 3D space. The line will be transformed and projected
231258
/// onto the AR overlay.
@@ -236,6 +263,9 @@ private uint ConvertColor(uint rgba)
236263
/// <param name="thickness">Thickness of the line in pixels.</param>
237264
public void Draw3DLine(ARCoordinate start, ARCoordinate end, UInt32 color, float thickness = 1.0f)
238265
{
266+
if (AllPointsOutsideRenderDistance(new ARCoordinate[] { start, end }))
267+
return;
268+
239269
Vector2? p1 = WorldToScreen(ARCoordinateToVector3(start), thisFrameWidth, thisFrameHeight);
240270
Vector2? p2 = WorldToScreen(ARCoordinateToVector3(end), thisFrameWidth, thisFrameHeight);
241271

@@ -257,6 +287,9 @@ public void Draw3DLine(ARCoordinate start, ARCoordinate end, UInt32 color, float
257287
/// <param name="thickness">The thickness of the circle outline.</param>
258288
public void Draw3DCircle(ARCoordinate center, float radius, UInt32 color, bool filled = false, float thickness = 1)
259289
{
290+
if (AllPointsOutsideRenderDistance(new ARCoordinate[] { center }))
291+
return;
292+
260293
Vector2? centerScreen = WorldToScreen(ARCoordinateToVector3(center), thisFrameWidth, thisFrameHeight);
261294
if (!centerScreen.HasValue)
262295
return;
@@ -282,6 +315,9 @@ public void Draw3DCircle(ARCoordinate center, float radius, UInt32 color, bool f
282315
/// <param name="thickness">The thickness of the polygon outline.</param>
283316
public void Draw3DPolygon(ARCoordinate[] points, UInt32 color, bool filled = false, float thickness = 1)
284317
{
318+
if (AllPointsOutsideRenderDistance(points))
319+
return;
320+
285321
if (points == null || points.Length < 3)
286322
return;
287323

@@ -328,6 +364,9 @@ public void Draw3DPolygon(ARCoordinate[] points, UInt32 color, bool filled = fal
328364
/// <param name="thickness">The thickness of a non filled quad.</param>
329365
public void Draw3DQuad(ARCoordinate p1, ARCoordinate p2, ARCoordinate p3, ARCoordinate p4, UInt32 color, bool filled = false, float thickness = 1)
330366
{
367+
if (AllPointsOutsideRenderDistance(new ARCoordinate[] { p1, p2, p3, p4 }))
368+
return;
369+
331370
Vector2? p1s = WorldToScreen(ARCoordinateToVector3(p1), thisFrameWidth, thisFrameHeight);
332371
Vector2? p2s = WorldToScreen(ARCoordinateToVector3(p2), thisFrameWidth, thisFrameHeight);
333372
Vector2? p3s = WorldToScreen(ARCoordinateToVector3(p3), thisFrameWidth, thisFrameHeight);
@@ -363,6 +402,9 @@ public void Draw3DQuad(ARCoordinate p1, ARCoordinate p2, ARCoordinate p3, ARCoor
363402
/// <param name="thickness">The thickness of a non filled triangle.</param>
364403
public void Draw3DTriangle(ARCoordinate p1, ARCoordinate p2, ARCoordinate p3, UInt32 color, bool filled = false, float thickness = 1)
365404
{
405+
if (AllPointsOutsideRenderDistance(new ARCoordinate[] { p1, p2, p3 }))
406+
return;
407+
366408
Vector2? p1s = WorldToScreen(ARCoordinateToVector3(p1), thisFrameWidth, thisFrameHeight);
367409
Vector2? p2s = WorldToScreen(ARCoordinateToVector3(p2), thisFrameWidth, thisFrameHeight);
368410
Vector2? p3s = WorldToScreen(ARCoordinateToVector3(p3), thisFrameWidth, thisFrameHeight);
@@ -396,6 +438,9 @@ public void Draw3DTriangle(ARCoordinate p1, ARCoordinate p2, ARCoordinate p3, UI
396438
/// <param name="color"></param>
397439
public void Draw3DText(ARCoordinate position, string text, UInt32 color)
398440
{
441+
if (AllPointsOutsideRenderDistance(new ARCoordinate[] { position }))
442+
return;
443+
399444
Vector2? screenPos = WorldToScreen(ARCoordinateToVector3(position), thisFrameWidth, thisFrameHeight);
400445
if (!screenPos.HasValue) return;
401446

@@ -471,6 +516,12 @@ public void EndWindow(ARCoordinate center, Quaternion rotation, float width, boo
471516
// onto the main overlay background.
472517
ImGui.SetCurrentContext(oldContext);
473518

519+
if (AllPointsOutsideRenderDistance(new ARCoordinate[] { center }))
520+
{
521+
isWindowContextInitialized = false;
522+
return;
523+
}
524+
474525
float windowAspectRatio = windowSize.Y / windowSize.X;
475526
float height = width * windowAspectRatio;
476527

ETS2LA.Overlay/Overlay.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class OverlayHandler
3636
};
3737

3838
public ARRenderer AR;
39+
private OverlaySettings overlaySettings;
3940

4041
private bool isInteracting = false;
4142
private float bgOpacityTarget = 0.0f;
@@ -60,6 +61,8 @@ public OverlayHandler()
6061
{
6162
ControlsBackend.Current.RegisterControl(Interact);
6263
ControlsBackend.Current.On(Interact.Id, HandleInput);
64+
overlaySettings = OverlaySettingsHandler.Current.GetSettings();
65+
OverlaySettingsHandler.Current.OnSettingsUpdated += OnOverlaySettingsUpdated;
6366

6467
Task.Run(() => RenderLoop());
6568

@@ -69,6 +72,11 @@ public OverlayHandler()
6972
windows.Add(new StateWindow());
7073
}
7174

75+
private void OnOverlaySettingsUpdated(OverlaySettings newSettings)
76+
{
77+
overlaySettings = newSettings;
78+
}
79+
7280
private void HandleInput(object sender, ControlChangeEventArgs e)
7381
{
7482
bool b = (bool)e.NewValue;
@@ -100,6 +108,11 @@ private void RenderLoop()
100108

101109
while (GLFW.WindowShouldClose(glfwWindow) == 0 && !shutdown)
102110
{
111+
if (overlaySettings.LimitFramerate)
112+
interval = 1000.0 / overlaySettings.MaxFramerate;
113+
else
114+
interval = 1000.0 / targetFramerate;
115+
103116
start = fs.Elapsed.TotalMilliseconds;
104117
next += interval;
105118

@@ -150,8 +163,8 @@ private void RenderLoop()
150163
// all other calls are just setup.
151164
Stopwatch ARStopwatch = Stopwatch.StartNew();
152165
try {
153-
if (AR == null) { AR = new ARRenderer(gl); }
154-
AR.Render();
166+
if (AR == null) AR = new ARRenderer(gl);
167+
if (overlaySettings.RenderAR) AR.Render();
155168
}
156169
catch (Exception ex) {
157170
Logger.Error($"Error in AR rendering: {ex}");

ETS2LA.Overlay/Settings.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using ETS2LA.Settings;
2+
3+
namespace ETS2LA.Overlay;
4+
5+
[Serializable]
6+
public class OverlaySettings
7+
{
8+
public bool LimitFramerate = true;
9+
public int MaxFramerate = 30;
10+
11+
// AR
12+
public bool RenderAR = true;
13+
public float MaxARDistance = 150.0f;
14+
}
15+
16+
public class OverlaySettingsHandler
17+
{
18+
private static readonly Lazy<OverlaySettingsHandler> _instance = new(() => new OverlaySettingsHandler());
19+
public static OverlaySettingsHandler Current => _instance.Value;
20+
21+
private SettingsHandler _settingsHandler;
22+
private OverlaySettings _settings;
23+
24+
public event Action<OverlaySettings>? OnSettingsUpdated;
25+
26+
public OverlaySettingsHandler()
27+
{
28+
_settingsHandler = new SettingsHandler();
29+
_settings = _settingsHandler.Load<OverlaySettings>("OverlaySettings.json");
30+
_settingsHandler.RegisterListener<OverlaySettings>("OverlaySettings.json", OnSettingsChanged);
31+
}
32+
33+
public void Save()
34+
{
35+
_settingsHandler.Save<OverlaySettings>("OverlaySettings.json", _settings);
36+
}
37+
38+
public OverlaySettings GetSettings()
39+
{
40+
return _settings;
41+
}
42+
43+
private void OnSettingsChanged(OverlaySettings overlaySettings)
44+
{
45+
_settings = overlaySettings;
46+
OnSettingsUpdated?.Invoke(_settings);
47+
}
48+
}

ETS2LA.Overlay/Window/StateWindow.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,11 @@ public StateWindow()
4343

4444
DescriptionText("Pause Longitudinal Assist: "); ImGui.SameLine(); ColoredBoolean(ApplicationState.Current.PauseLongitudinalAssist, invert: true);
4545

46-
float speedInUnits = ApplicationState.Current.FromScientificUnits(ApplicationState.Current.DesiredSpeed);
47-
DescriptionText("Desired Speed: "); ImGui.SameLine(); Text($"{ApplicationState.Current.DesiredSpeed:F1} m/s ({speedInUnits:F1} in {ApplicationState.Current.DisplayUnits})");
46+
float speed = ApplicationState.Current.DesiredSpeed;
47+
Units displayUnits = ApplicationState.Current.DisplayUnits;
48+
float speedInUnits = UnitConversions.FromScientificUnits(UnitType.Speed, speed, displayUnits);
49+
string unitAbbreviation = UnitConversions.GetUnitAbbreviation(UnitType.Speed, displayUnits);
50+
DescriptionText("Desired Speed: "); ImGui.SameLine(); Text($"{speed:F1} m/s ({speedInUnits:F1} in {unitAbbreviation})");
4851

4952
DescriptionText("Display Units: "); ImGui.SameLine(); Text(ApplicationState.Current.DisplayUnits.ToString());
5053
};

ETS2LA.State/Program.cs

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,6 @@ public enum LongitudinalAssists
2222
AdaptiveCruiseControl
2323
}
2424

25-
public enum Units
26-
{
27-
Metric,
28-
Imperial,
29-
Scientific
30-
}
31-
3225
/// <summary>
3326
/// This state contains the most important ETS2LA variables. Most plugins
3427
/// will use it to follow the user's preferences and read the game data.
@@ -50,6 +43,15 @@ public ApplicationState()
5043
ControlsBackend.Current.On(DefaultControls.Assist.Id, HandleAssist);
5144

5245
assistanceSettings = AssistanceSettings.Current;
46+
47+
StateSettingsHandler.Current.OnSettingsChanged += HandleSettingsChanged;
48+
HandleSettingsChanged(StateSettingsHandler.Current.GetSettings());
49+
}
50+
51+
private void HandleSettingsChanged(StateSettings newStateSettings)
52+
{
53+
stateSettings = newStateSettings;
54+
DisplayUnits = newStateSettings.DisplayUnits;
5355
}
5456

5557
private void HandleTelemetryUpdate(GameTelemetryData data)
@@ -76,6 +78,7 @@ public void Shutdown()
7678
}
7779

7880

81+
7982
// MARK: Self-Driving Related
8083
// NOTE: This class is organized by *category* and not variable/function type.
8184
// This makes the most sense to avoid having lots of variables back to back
@@ -121,37 +124,14 @@ public void Shutdown()
121124
/// is automatically changed by ETS2LA, either when the user sets it in the settings, or when we
122125
/// detect a change in the game's units. This unit should determine the units used everywhere, e.g.
123126
/// the units used when increasing and decreasing the target speed. (+-1 mph/kph/ms) <br/><br/>
124-
/// **Use FromScientificUnits and ToScientificUnits to convert values to and from the current display units.**
127+
/// **Use UnitConversions.FromScientificUnits and UnitConversions.ToScientificUnits to convert values to and from the current display units.**
125128
/// </summary>
126129
public Units DisplayUnits { get; set; } = Units.Metric;
127130

128131
// Internal value to keep track of the latest telemetry we received.
129132
private GameTelemetryData latestTelemetryData = new();
130133
private AssistanceSettings assistanceSettings;
131-
132-
public float FromScientificUnits(float speedInMps, Units? overrideDisplayUnits = null)
133-
{
134-
var units = overrideDisplayUnits ?? DisplayUnits;
135-
return units switch
136-
{
137-
Units.Metric => speedInMps * 3.6f, // m/s to km/h
138-
Units.Imperial => speedInMps * 2.23693f, // m/s to mph
139-
Units.Scientific => speedInMps, // m/s
140-
_ => speedInMps
141-
};
142-
}
143-
144-
public float ToScientificUnits(float speedInDisplayUnits, Units? overrideDisplayUnits = null)
145-
{
146-
var units = overrideDisplayUnits ?? DisplayUnits;
147-
return units switch
148-
{
149-
Units.Metric => speedInDisplayUnits / 3.6f, // km/h to m/s
150-
Units.Imperial => speedInDisplayUnits / 2.23693f, // mph to m/s
151-
Units.Scientific => speedInDisplayUnits, // m/s
152-
_ => speedInDisplayUnits
153-
};
154-
}
134+
private StateSettings stateSettings;
155135

156136
// The functions below are for handling control events.
157137
// If determining what they do is hard via code, then take a look at the
@@ -193,10 +173,10 @@ private void HandleIncrease(object sender, ControlChangeEventArgs e)
193173
switch (DisplayUnits)
194174
{
195175
case Units.Metric:
196-
DesiredSpeed += ToScientificUnits(1.0f, Units.Metric); // 1 km/h in m/s
176+
DesiredSpeed += UnitConversions.ToScientificUnits(UnitType.Speed, 1.0f, Units.Metric); // 1 km/h in m/s
197177
break;
198178
case Units.Imperial:
199-
DesiredSpeed += ToScientificUnits(1.0f, Units.Imperial); // 1 mph in m/s
179+
DesiredSpeed += UnitConversions.ToScientificUnits(UnitType.Speed, 1.0f, Units.Imperial); // 1 mph in m/s
200180
break;
201181
case Units.Scientific:
202182
DesiredSpeed += 1f; // 1 m/s
@@ -219,10 +199,10 @@ private void HandleDecrease(object sender, ControlChangeEventArgs e)
219199
switch (DisplayUnits)
220200
{
221201
case Units.Metric:
222-
DesiredSpeed -= ToScientificUnits(1.0f, Units.Metric); // 1 km/h in m/s
202+
DesiredSpeed -= UnitConversions.ToScientificUnits(UnitType.Speed, 1.0f, Units.Metric); // 1 km/h in m/s
223203
break;
224204
case Units.Imperial:
225-
DesiredSpeed -= ToScientificUnits(1.0f, Units.Imperial); // 1 mph in m/s
205+
DesiredSpeed -= UnitConversions.ToScientificUnits(UnitType.Speed, 1.0f, Units.Imperial); // 1 mph in m/s
226206
break;
227207
case Units.Scientific:
228208
DesiredSpeed -= 1f; // 1 m/s

0 commit comments

Comments
 (0)