From 3f08f5270f537aea749403734b7983b8e071b4ff Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Thu, 13 Apr 2023 01:48:58 +0100 Subject: [PATCH] feat: add DebugUtility.DrawFunction --- CHANGELOG.md | 1 + .../Tests/DebugUtilityIntegrationTests.cs | 6 +- .../src/DebugUtility/DebugUtility.Function.cs | 69 +++++++++++++++++++ .../DebugUtility/DebugUtility.Polyhedron.cs | 45 +++++++++++- 4 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 X10D.Unity/src/DebugUtility/DebugUtility.Function.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ea3856..633397e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - X10D: Added `TextWriter.WriteLineNoAlloc(long[, ReadOnlySpan[, IFormatProvider]])`. - X10D: Added `TextWriter.WriteLineNoAlloc(ulong[, ReadOnlySpan[, IFormatProvider]])`. - X10D.Unity: Added `RaycastHit.GetComponent` and `RaycastHit.TryGetComponent`. +- X10D.Unity: Added `DebugUtility.DrawFunction`, and `DebugUtility.DrawUnjoinedPolyhedron` on which it relies. ### Changed diff --git a/X10D.Unity.Tests/Assets/Tests/DebugUtilityIntegrationTests.cs b/X10D.Unity.Tests/Assets/Tests/DebugUtilityIntegrationTests.cs index 1c625e5..157f6a9 100644 --- a/X10D.Unity.Tests/Assets/Tests/DebugUtilityIntegrationTests.cs +++ b/X10D.Unity.Tests/Assets/Tests/DebugUtilityIntegrationTests.cs @@ -1,4 +1,5 @@ -using UnityEngine; +using System; +using UnityEngine; using X10D.Drawing; using X10D.Unity.Drawing; using Color = UnityEngine.Color; @@ -34,6 +35,9 @@ namespace X10D.Unity.Tests var sphere = new Sphere(System.Numerics.Vector3.Zero, 0.5f); DebugUtility.DrawSphere(sphere, 25, new Vector2(0.0f, -1.5f), Color.white); + DebugUtility.DrawFunction(x => MathF.Sin(x + UnityEngine.Time.time % (2 * MathF.PI)), -10, 10, 0.1f, Vector3.up * 4, + Color.yellow, 0.0f, false); + DebugUtility.Assert(true); } } diff --git a/X10D.Unity/src/DebugUtility/DebugUtility.Function.cs b/X10D.Unity/src/DebugUtility/DebugUtility.Function.cs new file mode 100644 index 0000000..4b7f33c --- /dev/null +++ b/X10D.Unity/src/DebugUtility/DebugUtility.Function.cs @@ -0,0 +1,69 @@ +using UnityEngine; +using X10D.Drawing; +using X10D.Numerics; +using X10D.Unity.Numerics; +using Quaternion = System.Numerics.Quaternion; + +namespace X10D.Unity; + +public static partial class DebugUtility +{ + /// + /// Draws a function plot. + /// + /// The function to plot. + /// The minimum X value. + /// The maximum X value. + public static void DrawFunction(Func function, float xMin, float xMax) + { + DrawFunction(function, xMin, xMax, 0.1f, Vector3.zero, Color.white, 0.0f, false); + } + + /// + /// Draws a function plot. + /// + /// The function to plot. + /// The minimum X value. + /// The maximum X value. + /// The X increment. + /// The drawing offset of the circle. + /// The color of the circle. + /// + /// The duration of the circle's visibility, in seconds. If 0 is passed, the circle is visible for a single frame. + /// + /// + /// if depth test should be applied; otherwise, . Passing + /// will have the circle be obscured by objects closer to the camera. + /// + /// is . + public static void DrawFunction(Func function, float xMin, float xMax, float step, in Vector3 offset, + in Color color, float duration, + bool depthTest) + { + if (function is null) + { + throw new ArgumentNullException(nameof(function)); + } + + DrawUnjoinedPolyhedron(CreateFunction(function, xMin, xMax, step, Vector3.zero), offset, color, duration, depthTest); + } + + private static Polyhedron CreateFunction(Func function, float xMin, float xMax, float step, in Vector3 axis) + { + var points = new List(); + for (float x = xMin; x < xMax; x += step) + { + float y = function(x); + var vector = new System.Numerics.Vector3(x, y, 0); + + if (axis != Vector3.zero) + { + vector = Quaternion.CreateFromAxisAngle(axis.ToSystemVector(), MathF.PI / 2.0f).Multiply(vector); + } + + points.Add(vector); + } + + return new Polyhedron(points); + } +} diff --git a/X10D.Unity/src/DebugUtility/DebugUtility.Polyhedron.cs b/X10D.Unity/src/DebugUtility/DebugUtility.Polyhedron.cs index 7ab51a0..205dfff 100644 --- a/X10D.Unity/src/DebugUtility/DebugUtility.Polyhedron.cs +++ b/X10D.Unity/src/DebugUtility/DebugUtility.Polyhedron.cs @@ -1,4 +1,4 @@ -using UnityEngine; +using UnityEngine; using X10D.Drawing; using X10D.Unity.Numerics; @@ -126,4 +126,47 @@ public static partial class DebugUtility DrawLine(start, end, color, duration, depthTest); } } + + /// + /// Draws a polyhedron. + /// + /// The polyhedron to draw. + /// The drawing offset of the polyhedron. + /// The color to use for drawing. + /// + /// The duration of the polyhedron's visibility, in seconds. If 0 is passed, the polyhedron is visible for a single frame. + /// + /// + /// if depth test should be applied; otherwise, . Passing + /// will have the box be obscured by objects closer to the camera. + /// + /// is . + public static void DrawUnjoinedPolyhedron(Polyhedron polyhedron, in Vector3 offset, in Color color, float duration, + bool depthTest) + { + if (polyhedron is null) + { + throw new ArgumentNullException(nameof(polyhedron)); + } + + IReadOnlyList points = polyhedron.Vertices; + if (points.Count < 2) + { + return; + } + + for (var i = 0; i < points.Count; i++) + { + if (i >= points.Count - 2) + { + break; + } + + int j = i + 1; + Vector3 start = points[i].ToUnityVector() + offset; + Vector3 end = points[j].ToUnityVector() + offset; + + DrawLine(start, end, color, duration, depthTest); + } + } }