Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

debug overlay #1698

Merged
merged 9 commits into from
Dec 25, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions TLM/TLM/Patch/_DefaultTool/RenderOverlayPatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ namespace TrafficManager.Patch._DefaultTool {
using JetBrains.Annotations;
using TrafficManager.UI;
using TrafficManager.Lifecycle;
using TrafficManager.UI.Helpers;

[HarmonyPatch(typeof(DefaultTool), "RenderOverlay")]
[UsedImplicitly]
Expand All @@ -13,6 +14,7 @@ public static class RenderOverlayPatch {
[HarmonyPostfix]
[UsedImplicitly]
public static void Postfix(RenderManager.CameraInfo cameraInfo) {
DebugOverlay.RenderOverlay(cameraInfo);
if (TMPELifecycle.PlayMode && !TrafficManagerTool.IsCurrentTool) {
if (UI.SubTools.PrioritySigns.MassEditOverlay.IsActive) {
ModUI.GetTrafficManagerTool()?.RenderOverlayImpl(cameraInfo);
Expand Down
30 changes: 20 additions & 10 deletions TLM/TLM/Patch/_VehicleAI/UpdatePathTargetPositionsPatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace TrafficManager.Patch._VehicleAI {
using Manager.Impl;
using State;
using State.ConfigData;
using TrafficManager.UI.Helpers;
using TrafficManager.Util.Extensions;
using UnityEngine;
using Util;
Expand Down Expand Up @@ -69,9 +70,17 @@ public static bool Prefix(VehicleAI __instance,
&& (GlobalConfig.Instance.Debug.ApiExtVehicleType == API.Traffic.Enums.ExtVehicleType.None
|| GlobalConfig.Instance.Debug.ApiExtVehicleType == API.Traffic.Enums.ExtVehicleType.RoadVehicle)
&& (DebugSettings.VehicleId == 0 || DebugSettings.VehicleId == vehicleID);
bool debugOverlay = logLogic && DebugSettings.VehicleId != 0;
#else
var logLogic = false;
const bool logLogic = false;
const bool debugOverlay = false;
#endif
if (debugOverlay) {
DebugOverlay.Actions.Remove(0);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to remove these because the overlay needs to clear if vehicle exits node.

DebugOverlay.Actions.Remove(1);
DebugOverlay.Actions.Remove(2);
}

if (logLogic) {
Log._Debug(
$"CustomVehicle.CustomUpdatePathTargetPositions({vehicleID}) called.\n" +
Expand Down Expand Up @@ -745,7 +754,7 @@ public static bool Prefix(VehicleAI __instance,
logLogic,
() => $"CustomVehicle.CustomUpdatePathTargetPositions({vehicleID}): " +
"Calculated current segment position for regular vehicle. " +
$"nextSegOffset={nextSegOffset}, bezier.len={bezier.a}, " +
$"nextSegOffset={nextSegOffset}, bezier.a={bezier.a}, " +
$"curSegDir={curSegDir}, maxSpeed={maxSpeed}, pathOffset={pathOffset}, " +
$"calculateNextNextPos={calculateNextNextPos}");

Expand Down Expand Up @@ -887,14 +896,15 @@ public static bool Prefix(VehicleAI __instance,
}
// STOCK CODE END

Log._DebugIf(
logLogic,
() => $"CustomVehicle.CustomUpdatePathTargetPositions({vehicleID}): " +
$"Direction vectors normalized. curSegDir={curSegDir}, nextSegDir={nextSegDir}\n" +
$"CustomVehicle.CustomUpdatePathTargetPositions({vehicleID}): " +
$"Calculated bezier middle points. IN: bezier.len={bezier.a}, " +
$"curSegDir={curSegDir}, bezier.d={bezier.d}, nextSegDir={nextSegDir}, " +
$"true, true, OUT: bezier.b={bezier.b}, bezier.c={bezier.c}, dist={dist}");
if (debugOverlay) {
Segment3 arrow1 = new(bezier.a, bezier.a + curSegDir);
Segment3 arrow2 = new(bezier.d, bezier.d + nextSegDir);
DebugOverlay.Actions[0] = () => bezier.RenderDebugOverlay(Color.yellow);
Color color = Color.cyan;
Color color2 = Color.Lerp(color, Color.black, 0.2f);
DebugOverlay.Actions[1] = () => arrow1.RenderDebugArrowOverlay(color);
DebugOverlay.Actions[2] = () => arrow2.RenderDebugArrowOverlay(color2);
}

if (dist > 1f) {
ushort nextNodeId;
Expand Down
1 change: 1 addition & 0 deletions TLM/TLM/TLM.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@
<Compile Include="TrafficLight\Impl\ITrafficLightContainer.cs" />
<Compile Include="TrafficLight\Impl\TrafficLightSimulation.cs" />
<Compile Include="UI\AllowDespawn\AllowDespawnPanel.cs" />
<Compile Include="UI\Helpers\DebugOverlay.cs" />
<Compile Include="UI\DebugSwitches\DebugSwitchPanel.cs" />
<Compile Include="UI\DebugSwitches\DebugSwitchCheckboxOption.cs" />
<Compile Include="UI\Helpers\IValuePropagator.cs" />
Expand Down
147 changes: 147 additions & 0 deletions TLM/TLM/UI/Helpers/DebugOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
namespace TrafficManager.UI.Helpers;
using ColossalFramework.Math;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Diagnostics;
using TrafficManager.Util;
using System.Linq;

internal static class DebugOverlay {
public class ActionDict {
private static Dictionary<int, Action> dict_ = new();

public Action this[int key] {
get {
lock (dict_) {
return dict_[key];
}
}
set {
lock (dict_) {
dict_[key] = value;
}
}
}

public Action[] Values {
get {
lock (dict_) {
return dict_.Values.ToArray();
}
}
}

public bool Remove(int key) {
lock (dict_) {
return dict_.Remove(key);
}
}

public void Clear() {
lock (dict_) {
dict_.Clear();
}
}
}

private static RenderManager.CameraInfo cameraInfo_;

/// <summary>
/// key : id
/// value : render action
/// </summary>
public static ActionDict Actions;

#if DEBUG
static DebugOverlay() => Actions = new();
#endif

public static void RenderDebugOverlay(this Bezier3 bezier, Color color) {
float y = bezier.a.y;
RenderManager.instance.OverlayEffect.DrawBezier(
cameraInfo: cameraInfo_,
color: color,
bezier: bezier,
size: 1,
cutStart: 0,
cutEnd: 0,
minY: y - 5,
maxY: y + 5,
renderLimits: true,
alphaBlend: true);
}

public static void RenderDebugOverlay(this Bezier3 bezier, Color color, float makredOffset) {
float y = bezier.a.y;
RenderManager.instance.OverlayEffect.DrawBezier(
cameraInfo: cameraInfo_,
color: color,
bezier: bezier,
size: 1,
cutStart: 0,
cutEnd: 0,
minY: y - 5,
maxY: y + 5,
renderLimits: true,
alphaBlend: true);
Vector3 pos = bezier.Position(makredOffset);
pos.RenderDebugOverlay(color);
}

public static void RenderDebugOverlay(this Vector3 pos, Color color) {
RenderManager.instance.OverlayEffect.DrawCircle(
cameraInfo: cameraInfo_,
color: color,
center: pos,
size: 2,
minY: pos.y - 5,
maxY: pos.y + 5,
renderLimits: true,
alphaBlend: true);
}

public static void RenderDebugArrowOverlay(this Segment3 segment, Color color) {
// draw line
float y = segment.a.y;
RenderManager.instance.OverlayEffect.DrawSegment(
cameraInfo: cameraInfo_,
color: color,
segment: segment,
dashLen: 0,
size: 1,
minY: y - 5,
maxY: y + 5,
renderLimits: true,
alphaBlend: true);

// draw arrow head:
Vector3 dir = (segment.b - segment.a).normalized;
Vector3 dir90 = dir.RotateXZ90CW();
Vector3 center = segment.b;

Quad3 quad = new Quad3 {
a = center + dir90,
b = center - dir90,
c = center + 2 * dir,
d = center + 2 * dir,
};

RenderManager.instance.OverlayEffect.DrawQuad(
cameraInfo_,
color,
quad,
y - 5,
y + 5,
renderLimits: true,
alphaBlend: true);
}

[Conditional("DEBUG")]
public static void RenderOverlay(RenderManager.CameraInfo cameraInfo) {
cameraInfo_ = cameraInfo;
foreach (var action in Actions.Values) {
krzychu124 marked this conversation as resolved.
Show resolved Hide resolved
action();
}
}
}