1
0
Fork 0
forked from aly/qstbak
qstbak/Auspex/Auspex/AxDrawList.cs
2026-08-17 20:25:32 +10:00

1611 lines
71 KiB
C#

using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using Auspex.Rendering.Direct3D;
using Auspex.Rendering.ImGuiFallback;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Interface.Utility;
namespace Auspex;
public sealed class AxDrawList : IDisposable
{
private static string? _cachedWindowName;
internal readonly ImDrawListPtr _drawList;
internal readonly ImDrawListPtr _textDrawList;
internal readonly List<Vector3> _path;
internal readonly Direct3DRenderer _renderer;
internal readonly ImGuiFallbackRenderer _fallbackRenderer;
internal readonly bool isMyWindow;
private readonly bool _separateTextDrawList;
private AxTexture? _texture;
private readonly Stack<Vector4> _clipStack = new Stack<Vector4>();
internal AxDxParams DefaultDxParams { get; init; }
internal bool Finalized => _texture.HasValue;
public Vector3 CameraRight => _renderer.CameraRight;
public Vector3 CameraUp => _renderer.CameraUp;
public Matrix4x4 ViewProj => _renderer.ViewProj;
public bool FanDegraded => _renderer.FanDegraded;
public bool StrokeDegraded => _renderer.StrokeDegraded;
public bool FullScreenPassDegraded => _renderer.FSPDegraded;
public bool TexturedQuadDegraded => _renderer.TexturedQuadDegraded;
public Vector2? WorldToScreen(Vector3 worldPos)
{
Matrix4x4 viewProj = _renderer.ViewProj;
float num = worldPos.X * viewProj.M14 + worldPos.Y * viewProj.M24 + worldPos.Z * viewProj.M34 + viewProj.M44;
if (num <= 0f)
{
return null;
}
float num2 = 1f / num;
float num3 = (worldPos.X * viewProj.M11 + worldPos.Y * viewProj.M21 + worldPos.Z * viewProj.M31 + viewProj.M41) * num2;
float num4 = (worldPos.X * viewProj.M12 + worldPos.Y * viewProj.M22 + worldPos.Z * viewProj.M32 + viewProj.M42) * num2;
ImGuiViewportPtr mainViewport = ImGuiHelpers.MainViewport;
return new Vector2(0.5f * mainViewport.Size.X * (1f + num3) + mainViewport.Pos.X, 0.5f * mainViewport.Size.Y * (1f - num4) + mainViewport.Pos.Y);
}
public (Vector3 Origin, Vector3 Direction)? ScreenToWorldRay(Vector2 screenPos)
{
if (!Matrix4x4.Invert(_renderer.ViewProj, out var result))
{
return null;
}
ImGuiViewportPtr mainViewport = ImGuiHelpers.MainViewport;
float nx = 2f * (screenPos.X - mainViewport.Pos.X) / mainViewport.Size.X - 1f;
float ny = 1f - 2f * (screenPos.Y - mainViewport.Pos.Y) / mainViewport.Size.Y;
Vector3 vector = Unproject(in result, nx, ny, 0f);
Vector3 item = Vector3.Normalize(Unproject(in result, nx, ny, 1f) - vector);
return (vector, item);
}
private static Vector3 Unproject(in Matrix4x4 invViewProj, float nx, float ny, float nz)
{
float num = nx * invViewProj.M11 + ny * invViewProj.M21 + nz * invViewProj.M31 + invViewProj.M41;
float num2 = nx * invViewProj.M12 + ny * invViewProj.M22 + nz * invViewProj.M32 + invViewProj.M42;
float num3 = nx * invViewProj.M13 + ny * invViewProj.M23 + nz * invViewProj.M33 + invViewProj.M43;
float num4 = nx * invViewProj.M14 + ny * invViewProj.M24 + nz * invViewProj.M34 + invViewProj.M44;
float num5 = 1f / num4;
return new Vector3(num * num5, num2 * num5, num3 * num5);
}
internal AxDrawList(ImDrawListPtr? drawlist, Direct3DRenderer renderer)
{
if (drawlist.HasValue)
{
_drawList = (_textDrawList = drawlist.Value);
}
else
{
_drawList = ImGui.GetBackgroundDrawList();
ImGuiHelpers.ForceNextWindowMainViewport();
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero);
ImGuiHelpers.SetNextWindowPosRelativeMainViewport(Vector2.Zero);
ImGui.SetNextWindowSize(ImGuiHelpers.MainViewport.Size);
if (_cachedWindowName == null)
{
_cachedWindowName = "AxWindow#" + AuspexService.PluginInterface.InternalName;
}
if (ImGui.Begin(_cachedWindowName, ImGuiWindowFlags.NoInputs | ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoBackground | ImGuiWindowFlags.NoSavedSettings | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.AlwaysUseWindowPadding))
{
CImGui.igBringWindowToDisplayBack(CImGui.igGetCurrentWindow());
_textDrawList = ImGui.GetWindowDrawList();
isMyWindow = true;
}
else
{
_textDrawList = ImGui.GetBackgroundDrawList();
}
ImGui.PopStyleVar();
}
_path = renderer.SharedPath;
_path.Clear();
_renderer = renderer;
DefaultDxParams = AuspexService.Hints.DefaultDxParams;
_texture = null;
_separateTextDrawList = isMyWindow;
_renderer.BeginFrame();
_fallbackRenderer = new ImGuiFallbackRenderer(_drawList);
}
public AxTexture DrawToTexture()
{
if (!_texture.HasValue)
{
FrameRenderTarget frameRenderTarget = _renderer.EndFrame();
_texture = frameRenderTarget.Texture;
}
return _texture.Value;
}
public void Dispose()
{
if (AuspexService.DrawList == this)
{
AuspexService.DrawList = null;
}
if (AuspexService.Hints.AutoDraw)
{
AxTexture axTexture = DrawToTexture();
_drawList.AddImage(axTexture.TextureId, ImGuiHelpers.MainViewport.Pos, ImGuiHelpers.MainViewport.Pos + axTexture.Size);
}
else
{
DrawToTexture();
}
if (isMyWindow)
{
ImGui.End();
}
GC.SuppressFinalize(this);
}
public void PushClipRect(Vector2 min, Vector2 max)
{
_clipStack.Push(new Vector4(min.X, min.Y, max.X, max.Y));
_renderer.SetScissorRect(min, max);
_drawList.PushClipRect(min, max, intersectWithCurrentClipRect: false);
if (_separateTextDrawList)
{
_textDrawList.PushClipRect(min, max, intersectWithCurrentClipRect: false);
}
}
public void PopClipRect()
{
if (_clipStack.Count != 0)
{
_clipStack.Pop();
_drawList.PopClipRect();
if (_separateTextDrawList)
{
_textDrawList.PopClipRect();
}
if (_clipStack.Count > 0)
{
Vector4 vector = _clipStack.Peek();
_renderer.SetScissorRect(new Vector2(vector.X, vector.Y), new Vector2(vector.Z, vector.W));
}
else
{
_renderer.ClearScissorRect();
}
}
}
public void AddText(Vector3 position, uint color, string text, float scale = 1f, uint? outlineColor = null, float outlineThickness = 1f, uint? shadowColor = null, Vector2? shadowOffset = null)
{
ArgumentNullException.ThrowIfNull((object)text, "text");
if (AuspexService.GameGui.WorldToScreen(position, out var screenPos))
{
ImGui.SetWindowFontScale(scale);
Vector2 vector = screenPos - ImGui.CalcTextSize(text) / 2f;
DrawTextEffects(_textDrawList, vector, text, outlineColor, outlineThickness, shadowColor, shadowOffset);
_textDrawList.AddText(vector, color, text);
ImGui.SetWindowFontScale(1f);
}
}
public void AddWorldText(Vector3 position, uint color, string text, float scale = 1f, uint? outlineColor = null, float outlineThickness = 1f, uint? shadowColor = null, Vector2? shadowOffset = null)
{
ArgumentNullException.ThrowIfNull((object)text, "text");
if (text.Length == 0)
{
return;
}
if (_renderer.TexturedQuadDegraded)
{
AddWorldTextImGui(position, color, text, scale, outlineColor, outlineThickness, shadowColor, shadowOffset);
}
else
{
if (!WorldToScreen(position).HasValue)
{
return;
}
HighResFontAtlas worldFont = _renderer.WorldFont;
ImFontPtr font = worldFont?.Font ?? ImGui.GetFont();
IntPtr textureSRV = worldFont?.TextureSRV ?? ((IntPtr)0);
float fontSize = font.FontSize;
float num = scale / fontSize;
float num2 = 0f;
foreach (Rune item in text.EnumerateRunes())
{
ushort c = ((item.Value <= 65535) ? ((ushort)item.Value) : font.FallbackChar);
num2 += font.GetCharAdvance(c) * num;
}
Vector3 cameraRight = _renderer.CameraRight;
Vector3 cameraUp = _renderer.CameraUp;
if (shadowColor.HasValue)
{
Vector2 vector = shadowOffset ?? new Vector2(1f, 1f);
Vector3 vector2 = cameraRight * (vector.X * num) - cameraUp * (vector.Y * num);
RenderWorldGlyphs(position + vector2, cameraRight, cameraUp, font, textureSRV, text, fontSize, num, num2, shadowColor.Value);
}
if (outlineColor.HasValue)
{
float num3 = outlineThickness * num;
RenderWorldGlyphs(position + cameraRight * num3, cameraRight, cameraUp, font, textureSRV, text, fontSize, num, num2, outlineColor.Value);
RenderWorldGlyphs(position - cameraRight * num3, cameraRight, cameraUp, font, textureSRV, text, fontSize, num, num2, outlineColor.Value);
RenderWorldGlyphs(position + cameraUp * num3, cameraRight, cameraUp, font, textureSRV, text, fontSize, num, num2, outlineColor.Value);
RenderWorldGlyphs(position - cameraUp * num3, cameraRight, cameraUp, font, textureSRV, text, fontSize, num, num2, outlineColor.Value);
}
RenderWorldGlyphs(position, cameraRight, cameraUp, font, textureSRV, text, fontSize, num, num2, color);
}
}
private unsafe void RenderWorldGlyphs(Vector3 origin, Vector3 right, Vector3 up, ImFontPtr font, IntPtr textureSRV, string text, float fontSize, float pixelToWorld, float totalWidthWorld, uint color)
{
float num = fontSize * 0.5f;
float num2 = (0f - totalWidthWorld) * 0.5f;
foreach (Rune item in text.EnumerateRunes())
{
ushort c = ((item.Value <= 65535) ? ((ushort)item.Value) : font.FallbackChar);
ImFontGlyph imFontGlyph = *font.FindGlyph(c);
if (imFontGlyph.Visible != 0)
{
float num3 = num2 + imFontGlyph.X0 * pixelToWorld;
float num4 = num2 + imFontGlyph.X1 * pixelToWorld;
float num5 = (0f - (imFontGlyph.Y0 - num)) * pixelToWorld;
float num6 = (0f - (imFontGlyph.Y1 - num)) * pixelToWorld;
Vector3 a = origin + right * num3 + up * num5;
Vector3 b = origin + right * num4 + up * num5;
Vector3 c2 = origin + right * num4 + up * num6;
Vector3 d = origin + right * num3 + up * num6;
IntPtr intPtr = textureSRV;
if (intPtr == (IntPtr)0)
{
ImFontAtlasPtr containerAtlas = font.ContainerAtlas;
ImTextureID texID = containerAtlas.Textures[(int)imFontGlyph.TextureIndex].TexID;
intPtr = Unsafe.As<ImTextureID, IntPtr>(ref texID);
}
_renderer.DrawTexturedQuad(intPtr, a, b, c2, d, color, new Vector2(imFontGlyph.U0, imFontGlyph.V0), new Vector2(imFontGlyph.U1, imFontGlyph.V1));
}
num2 += imFontGlyph.AdvanceX * pixelToWorld;
}
}
private void AddWorldTextImGui(Vector3 position, uint color, string text, float scale, uint? outlineColor, float outlineThickness, uint? shadowColor, Vector2? shadowOffset)
{
if (!AuspexService.GameGui.WorldToScreen(position, out var screenPos))
{
return;
}
Vector3 worldPos = position + _renderer.CameraUp * scale;
if (AuspexService.GameGui.WorldToScreen(worldPos, out var screenPos2))
{
float num = Vector2.Distance(screenPos, screenPos2) / ImGui.GetFontSize();
if (!(num < 0.01f))
{
ImGui.SetWindowFontScale(num);
Vector2 vector = screenPos - ImGui.CalcTextSize(text) / 2f;
DrawTextEffects(_textDrawList, vector, text, outlineColor, outlineThickness, shadowColor, shadowOffset);
_textDrawList.AddText(vector, color, text);
ImGui.SetWindowFontScale(1f);
}
}
}
private static void DrawTextEffects(ImDrawListPtr drawList, Vector2 textPosition, string text, uint? outlineColor, float outlineThickness, uint? shadowColor, Vector2? shadowOffset)
{
if (shadowColor.HasValue)
{
Vector2 vector = shadowOffset ?? new Vector2(1f, 1f);
drawList.AddText(textPosition + vector, shadowColor.Value, text);
}
if (outlineColor.HasValue)
{
uint value = outlineColor.Value;
drawList.AddText(textPosition + new Vector2(outlineThickness, 0f), value, text);
drawList.AddText(textPosition + new Vector2(0f - outlineThickness, 0f), value, text);
drawList.AddText(textPosition + new Vector2(0f, outlineThickness), value, text);
drawList.AddText(textPosition + new Vector2(0f, 0f - outlineThickness), value, text);
}
}
public void AddDot(Vector3 position, float radiusPixels, uint color, uint numSegments = 0u)
{
if (AuspexService.GameGui.WorldToScreen(position, out var screenPos))
{
_drawList.AddCircleFilled(screenPos, radiusPixels, color, (int)numSegments);
}
}
public void AddTexture(Vector3 position, IDalamudTextureWrap texture, float scale = 1f, uint color = uint.MaxValue)
{
ArgumentNullException.ThrowIfNull((object)texture, "texture");
if (AuspexService.GameGui.WorldToScreen(position, out var screenPos))
{
Vector2 vector = new Vector2(texture.Width, texture.Height) * scale;
Vector2 vector2 = screenPos - vector / 2f;
Vector2 pMax = vector2 + vector;
_textDrawList.AddImage(texture.Handle, vector2, pMax, Vector2.Zero, Vector2.One, color);
}
}
public void AddBillboard(Vector3 position, IDalamudTextureWrap texture, float width, float height, uint color = uint.MaxValue, float rotation = 0f, Vector2 uvMin = default(Vector2), Vector2 uvMax = default(Vector2))
{
ArgumentNullException.ThrowIfNull((object)texture, "texture");
if (uvMax == default(Vector2))
{
uvMax = Vector2.One;
}
if (_renderer.TexturedQuadDegraded)
{
AddTexture(position, texture, 1f, color);
return;
}
Vector3 vector = _renderer.CameraRight;
Vector3 vector2 = _renderer.CameraUp;
if (rotation != 0f)
{
float num = MathF.Cos(rotation);
float num2 = MathF.Sin(rotation);
Vector3 vector3 = vector * num + vector2 * num2;
Vector3 vector4 = vector2 * num - vector * num2;
vector = vector3;
vector2 = vector4;
}
float num3 = width * 0.5f;
float num4 = height * 0.5f;
Vector3 a = position - vector * num3 + vector2 * num4;
Vector3 b = position + vector * num3 + vector2 * num4;
Vector3 c = position + vector * num3 - vector2 * num4;
Vector3 d = position - vector * num3 - vector2 * num4;
ImTextureID handle = texture.Handle;
_renderer.DrawTexturedQuad(Unsafe.As<ImTextureID, IntPtr>(ref handle), a, b, c, d, color, uvMin, uvMax);
}
public void AddBillboard(Vector3 position, IDalamudTextureWrap texture, float scale = 1f, uint color = uint.MaxValue, float rotation = 0f, Vector2 uvMin = default(Vector2), Vector2 uvMax = default(Vector2))
{
ArgumentNullException.ThrowIfNull((object)texture, "texture");
float num = (float)texture.Width / (float)texture.Height;
AddBillboard(position, texture, scale * num, scale, color, rotation, uvMin, uvMax);
}
public void AddTexturedQuad(Vector3 a, Vector3 b, Vector3 c, Vector3 d, IDalamudTextureWrap texture, uint color = uint.MaxValue, Vector2 uvMin = default(Vector2), Vector2 uvMax = default(Vector2))
{
ArgumentNullException.ThrowIfNull((object)texture, "texture");
if (uvMax == default(Vector2))
{
uvMax = Vector2.One;
}
if (!_renderer.TexturedQuadDegraded)
{
ImTextureID handle = texture.Handle;
_renderer.DrawTexturedQuad(Unsafe.As<ImTextureID, IntPtr>(ref handle), a, b, c, d, color, uvMin, uvMax);
}
}
public void AddTexturedQuad(Vector3 center, Vector3 right, Vector3 up, float width, float height, IDalamudTextureWrap texture, uint color = uint.MaxValue, Vector2 uvMin = default(Vector2), Vector2 uvMax = default(Vector2))
{
float num = width * 0.5f;
float num2 = height * 0.5f;
Vector3 a = center - right * num + up * num2;
Vector3 b = center + right * num + up * num2;
Vector3 c = center + right * num - up * num2;
Vector3 d = center - right * num - up * num2;
AddTexturedQuad(a, b, c, d, texture, color, uvMin, uvMax);
}
public void PathLineTo(Vector3 point)
{
_path.Add(point);
}
public void PathArcTo(Vector3 point, float radius, float startAngle, float stopAngle, uint numSegments = 0u)
{
float num = stopAngle - startAngle;
if (num != 0f)
{
if (numSegments == 0)
{
numSegments = (uint)(MathF.Abs(num) * 16f);
}
float num2 = num / (float)numSegments;
for (int i = 0; i <= numSegments; i++)
{
float num3 = (float)Math.PI / 2f + startAngle + (float)i * num2;
Vector3 vector = new Vector3(MathF.Cos(num3), 0f, MathF.Sin(num3));
_path.Add(point + radius * vector);
}
}
}
public void PathBezierCubicTo(Vector3 p2, Vector3 p3, Vector3 p4, uint numSegments = 0u)
{
if (_path.Count != 0)
{
List<Vector3> path = _path;
Vector3 vector = path[path.Count - 1];
if (numSegments == 0)
{
float num = Vector3.Distance(vector, p2) + Vector3.Distance(p2, p3) + Vector3.Distance(p3, p4);
numSegments = (uint)MathF.Max(4f, MathF.Ceiling(num * 8f));
}
for (int i = 1; i <= numSegments; i++)
{
float num2 = (float)i / (float)numSegments;
float num3 = 1f - num2;
_path.Add(num3 * num3 * num3 * vector + 3f * num3 * num3 * num2 * p2 + 3f * num3 * num2 * num2 * p3 + num2 * num2 * num2 * p4);
}
}
}
public void PathBezierQuadraticTo(Vector3 p2, Vector3 p3, uint numSegments = 0u)
{
if (_path.Count != 0)
{
List<Vector3> path = _path;
Vector3 vector = path[path.Count - 1];
if (numSegments == 0)
{
float num = Vector3.Distance(vector, p2) + Vector3.Distance(p2, p3);
numSegments = (uint)MathF.Max(4f, MathF.Ceiling(num * 8f));
}
for (int i = 1; i <= numSegments; i++)
{
float num2 = (float)i / (float)numSegments;
float num3 = 1f - num2;
_path.Add(num3 * num3 * vector + 2f * num3 * num2 * p2 + num2 * num2 * p3);
}
}
}
public void PathCatmullRomTo(ReadOnlySpan<Vector3> points, uint numSegmentsPerSpan = 0u, float tension = 0f, bool closed = false)
{
if (points.Length < 2)
{
return;
}
float num = 1f - tension;
bool flag = _path.Count > 0;
int length = points.Length;
for (int i = 0; i < (closed ? length : (length - 1)); i++)
{
Vector3 vector = points[i];
Vector3 vector2 = points[(i + 1) % length];
Vector3 vector4;
if (i == 0 && !closed)
{
Vector3 vector3;
if (!flag)
{
vector3 = vector + (vector - vector2);
}
else
{
List<Vector3> path = _path;
vector3 = path[path.Count - 1];
}
vector4 = vector3;
}
else
{
vector4 = points[(i - 1 + length) % length];
}
Vector3 vector5 = ((i != length - 2 || closed) ? points[(i + 2) % length] : (vector2 + (vector2 - vector)));
uint num2 = numSegmentsPerSpan;
if (num2 == 0)
{
num2 = (uint)MathF.Max(4f, MathF.Ceiling(Vector3.Distance(vector, vector2) * 8f));
}
for (int j = ((i != 0 || flag) ? 1 : 0); j <= num2; j++)
{
float num3 = (float)j / (float)num2;
float num4 = num3 * num3;
float num5 = num4 * num3;
float num6 = (0f - num) * num5 + 2f * num * num4 - num * num3;
float num7 = (2f - num) * num5 + (num - 3f) * num4 + 1f;
float num8 = (num - 2f) * num5 + (3f - 2f * num) * num4 + num * num3;
float num9 = num * num5 - num * num4;
_path.Add(num6 * vector4 + num7 * vector + num8 * vector2 + num9 * vector5);
}
}
}
public void PathStroke(uint color, AxStrokeFlags flags = AxStrokeFlags.None, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxLineCap cap = AxLineCap.Butt, AxLineJoin join = AxLineJoin.None, AxDxParams? dxParams = null)
{
AxDxParams p = dxParams ?? DefaultDxParams;
if (_renderer.StrokeDegraded)
{
_fallbackRenderer.DrawStroke(_path, thickness, color, (flags & AxStrokeFlags.Closed) > AxStrokeFlags.None, dashLength, gapLength, dashOffset, colorEnd, cap, join);
}
else
{
_renderer.DrawStroke(_path, thickness, color, (flags & AxStrokeFlags.Closed) > AxStrokeFlags.None, dashLength, gapLength, dashOffset, colorEnd, cap, join, p);
}
_path.Clear();
}
public void PathStroke(uint color, float thicknessStart, float thicknessEnd, AxStrokeFlags flags = AxStrokeFlags.None, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxLineCap cap = AxLineCap.Butt, AxLineJoin join = AxLineJoin.None, AxDxParams? dxParams = null)
{
if (_path.Count < 2)
{
_path.Clear();
return;
}
Span<float> span = ((_path.Count > 1024) ? ((Span<float>)new float[_path.Count]) : stackalloc float[_path.Count]);
Span<float> span2 = span;
for (int i = 0; i < _path.Count; i++)
{
span2[i] = thicknessStart + (thicknessEnd - thicknessStart) * ((float)i / (float)(_path.Count - 1));
}
PathStroke(color, span2, flags, dashLength, gapLength, dashOffset, colorEnd, cap, join, dxParams);
}
public void PathStroke(uint color, ReadOnlySpan<float> thicknesses, AxStrokeFlags flags = AxStrokeFlags.None, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxLineCap cap = AxLineCap.Butt, AxLineJoin join = AxLineJoin.None, AxDxParams? dxParams = null)
{
if (_path.Count < 2 || thicknesses.Length < _path.Count)
{
_path.Clear();
return;
}
AxDxParams p = dxParams ?? DefaultDxParams;
bool closed = (flags & AxStrokeFlags.Closed) > AxStrokeFlags.None;
if (_renderer.StrokeDegraded)
{
float num = 0f;
for (int i = 0; i < thicknesses.Length; i++)
{
num += thicknesses[i];
}
num /= (float)thicknesses.Length;
_fallbackRenderer.DrawStroke(_path, num, color, closed, dashLength, gapLength, dashOffset, colorEnd, cap, join);
}
else
{
_renderer.DrawStroke(_path, thicknesses, color, closed, dashLength, gapLength, dashOffset, colorEnd, cap, join, p);
}
_path.Clear();
}
public void PathFill(uint color, AxDxParams? dxParams = null)
{
if (_path.Count < 3)
{
_path.Clear();
return;
}
for (int i = 1; i < _path.Count - 1; i++)
{
AddTriangleFilled(_path[0], _path[i], _path[i + 1], color, dxParams);
}
_path.Clear();
}
public void PathFill<T>(T gradient, AxDxParams? dxParams = null) where T : IPctGradient
{
if (_path.Count < 3)
{
_path.Clear();
return;
}
for (int i = 1; i < _path.Count - 1; i++)
{
AddTriangleFilled(_path[0], _path[i], _path[i + 1], gradient, dxParams);
}
_path.Clear();
}
public void AddPolyline(ReadOnlySpan<Vector3> vertices, uint color, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxLineCap cap = AxLineCap.Butt, AxLineJoin join = AxLineJoin.None, AxDxParams? dxParams = null)
{
if (vertices.Length >= 2)
{
for (int i = 0; i < vertices.Length; i++)
{
PathLineTo(vertices[i]);
}
PathStroke(color, AxStrokeFlags.None, thickness, dashLength, gapLength, dashOffset, colorEnd, cap, join);
}
}
public void AddPolygon(ReadOnlySpan<Vector3> vertices, uint color, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
if (vertices.Length >= 3)
{
for (int i = 0; i < vertices.Length; i++)
{
PathLineTo(vertices[i]);
}
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
}
public void AddPolygonFilled(ReadOnlySpan<Vector3> vertices, uint color, AxDxParams? dxParams = null)
{
if (vertices.Length >= 3)
{
for (int i = 1; i < vertices.Length - 1; i++)
{
AddTriangleFilled(vertices[0], vertices[i], vertices[i + 1], color, dxParams);
}
}
}
public void AddPolygonFilled<T>(ReadOnlySpan<Vector3> vertices, T gradient, AxDxParams? dxParams = null) where T : IPctGradient
{
if (vertices.Length >= 3)
{
for (int i = 1; i < vertices.Length - 1; i++)
{
AddTriangleFilled(vertices[0], vertices[i], vertices[i + 1], gradient, dxParams);
}
}
}
public void AddTriangle(Vector3 a, Vector3 b, Vector3 c, uint color, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
PathLineTo(a);
PathLineTo(b);
PathLineTo(c);
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
public void AddTriangleFilled(Vector3 a, Vector3 b, Vector3 c, uint color, AxDxParams? dxParams = null)
{
AddTriangleFilled(a, b, c, color, color, color, dxParams);
}
public void AddTriangleFilled(Vector3 a, Vector3 b, Vector3 c, uint colorA, uint colorB, uint colorC, AxDxParams? dxParams = null)
{
AxDxParams p = dxParams ?? DefaultDxParams;
_renderer.DrawTriangle(a, b, c, colorA, colorB, colorC, p);
}
public void AddTriangleFilled<T>(Vector3 a, Vector3 b, Vector3 c, T gradient, AxDxParams? dxParams = null) where T : IPctGradient
{
AddTriangleFilled(a, b, c, gradient.ColorAt(a), gradient.ColorAt(b), gradient.ColorAt(c), dxParams);
}
public void AddLine(Vector3 start, Vector3 stop, float halfWidth, uint color, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
Vector3 vector = stop - start;
Vector3 vector2 = halfWidth * Vector3.Normalize(Vector3.Cross(vector, Vector3.UnitY));
AddQuad(start - vector2, stop - vector2, stop + vector2, start + vector2, color, thickness, dashLength, gapLength, dashOffset, colorEnd, dxParams);
}
public void AddLineFilled(Vector3 start, Vector3 stop, float halfWidth, uint color, uint? colorEnd = null, AxDxParams? dxParams = null)
{
Vector3 vector = stop - start;
Vector3 vector2 = halfWidth * Vector3.Normalize(Vector3.Cross(vector, Vector3.UnitY));
AddQuadFilled(start - vector2, stop - vector2, stop + vector2, start + vector2, color, colorEnd ?? color, colorEnd ?? color, color, dxParams);
}
public void AddLineFilled<T>(Vector3 start, Vector3 stop, float halfWidth, T gradient, AxDxParams? dxParams = null) where T : IPctGradient
{
Vector3 vector = stop - start;
Vector3 vector2 = halfWidth * Vector3.Normalize(Vector3.Cross(vector, Vector3.UnitY));
AddQuadFilled(start - vector2, stop - vector2, stop + vector2, start + vector2, gradient, dxParams);
}
public void AddArrowFilled(Vector3 start, Vector3 stop, float halfWidth, uint color, float headLength = 0f, float headHalfWidth = 0f, AxDxParams? dxParams = null)
{
Vector3 vector = stop - start;
float num = vector.Length();
if (!(num < 1E-06f))
{
if (headLength == 0f)
{
headLength = halfWidth * 3f;
}
if (headHalfWidth == 0f)
{
headHalfWidth = halfWidth * 2f;
}
Vector3 vector2 = vector / num;
Vector3 vector3 = Vector3.Normalize(Vector3.Cross(vector2, Vector3.UnitY));
if (num > headLength)
{
Vector3 vector4 = stop - vector2 * headLength;
AddQuadFilled(start - vector3 * halfWidth, vector4 - vector3 * halfWidth, vector4 + vector3 * halfWidth, start + vector3 * halfWidth, color, dxParams);
AddTriangleFilled(vector4 - vector3 * headHalfWidth, stop, vector4 + vector3 * headHalfWidth, color, dxParams);
}
else
{
AddTriangleFilled(start - vector3 * headHalfWidth, stop, start + vector3 * headHalfWidth, color, dxParams);
}
}
}
public void AddArrowFilled<T>(Vector3 start, Vector3 stop, float halfWidth, T gradient, float headLength = 0f, float headHalfWidth = 0f, AxDxParams? dxParams = null) where T : IPctGradient
{
Vector3 vector = stop - start;
float num = vector.Length();
if (!(num < 1E-06f))
{
if (headLength == 0f)
{
headLength = halfWidth * 3f;
}
if (headHalfWidth == 0f)
{
headHalfWidth = halfWidth * 2f;
}
Vector3 vector2 = vector / num;
Vector3 vector3 = Vector3.Normalize(Vector3.Cross(vector2, Vector3.UnitY));
if (num > headLength)
{
Vector3 vector4 = stop - vector2 * headLength;
AddQuadFilled(start - vector3 * halfWidth, vector4 - vector3 * halfWidth, vector4 + vector3 * halfWidth, start + vector3 * halfWidth, gradient, dxParams);
AddTriangleFilled(vector4 - vector3 * headHalfWidth, stop, vector4 + vector3 * headHalfWidth, gradient, dxParams);
}
else
{
AddTriangleFilled(start - vector3 * headHalfWidth, stop, start + vector3 * headHalfWidth, gradient, dxParams);
}
}
}
public void AddArrow(Vector3 start, Vector3 stop, float halfWidth, uint color, float headLength = 0f, float headHalfWidth = 0f, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
Vector3 vector = stop - start;
float num = vector.Length();
if (!(num < 1E-06f))
{
if (headLength == 0f)
{
headLength = halfWidth * 3f;
}
if (headHalfWidth == 0f)
{
headHalfWidth = halfWidth * 2f;
}
Vector3 vector2 = vector / num;
Vector3 vector3 = Vector3.Normalize(Vector3.Cross(vector2, Vector3.UnitY));
if (num > headLength)
{
Vector3 vector4 = stop - vector2 * headLength;
PathLineTo(start + vector3 * halfWidth);
PathLineTo(vector4 + vector3 * halfWidth);
PathLineTo(vector4 + vector3 * headHalfWidth);
PathLineTo(stop);
PathLineTo(vector4 - vector3 * headHalfWidth);
PathLineTo(vector4 - vector3 * halfWidth);
PathLineTo(start - vector3 * halfWidth);
}
else
{
PathLineTo(start + vector3 * headHalfWidth);
PathLineTo(stop);
PathLineTo(start - vector3 * headHalfWidth);
}
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
}
public void AddQuad(Vector3 a, Vector3 b, Vector3 c, Vector3 d, uint color, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
PathLineTo(a);
PathLineTo(b);
PathLineTo(c);
PathLineTo(d);
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
public void AddQuadFilled(Vector3 a, Vector3 b, Vector3 c, Vector3 d, uint color, AxDxParams? dxParams = null)
{
AddQuadFilled(a, b, c, d, color, color, color, color, dxParams);
}
public void AddQuadFilled(Vector3 a, Vector3 b, Vector3 c, Vector3 d, uint colorA, uint colorB, uint colorC, uint colorD, AxDxParams? dxParams = null)
{
AddTriangleFilled(a, b, c, colorA, colorB, colorC, dxParams);
AddTriangleFilled(a, c, d, colorA, colorC, colorD, dxParams);
}
public void AddQuadFilled<T>(Vector3 a, Vector3 b, Vector3 c, Vector3 d, T gradient, AxDxParams? dxParams = null) where T : IPctGradient
{
AddTriangleFilled(a, b, c, gradient.ColorAt(a), gradient.ColorAt(b), gradient.ColorAt(c), dxParams);
AddTriangleFilled(a, c, d, gradient.ColorAt(a), gradient.ColorAt(c), gradient.ColorAt(d), dxParams);
}
public void AddRoundedRect(Vector3 origin, float halfWidth, float halfHeight, float cornerRadius, uint color, uint numSegments = 0u, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, float rotation = 0f, AxDxParams? dxParams = null)
{
float num = MathF.Min(cornerRadius, MathF.Min(halfWidth, halfHeight));
float cos = MathF.Cos(rotation);
float sin = MathF.Sin(rotation);
if (num <= 0f)
{
AddQuad(RotateXZ(origin, 0f - halfWidth, 0f - halfHeight, cos, sin), RotateXZ(origin, halfWidth, 0f - halfHeight, cos, sin), RotateXZ(origin, halfWidth, halfHeight, cos, sin), RotateXZ(origin, 0f - halfWidth, halfHeight, cos, sin), color, thickness, dashLength, gapLength, dashOffset, colorEnd, dxParams);
return;
}
Vector3 point = RotateXZ(origin, halfWidth - num, 0f - halfHeight + num, cos, sin);
Vector3 point2 = RotateXZ(origin, halfWidth - num, halfHeight - num, cos, sin);
Vector3 point3 = RotateXZ(origin, 0f - halfWidth + num, halfHeight - num, cos, sin);
Vector3 point4 = RotateXZ(origin, 0f - halfWidth + num, 0f - halfHeight + num, cos, sin);
PathArcTo(point, num, (float)Math.PI + rotation, 4.712389f + rotation, numSegments);
PathArcTo(point2, num, 4.712389f + rotation, (float)Math.PI * 2f + rotation, numSegments);
PathArcTo(point3, num, rotation, (float)Math.PI / 2f + rotation, numSegments);
PathArcTo(point4, num, (float)Math.PI / 2f + rotation, (float)Math.PI + rotation, numSegments);
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
public void AddRoundedRectFilled(Vector3 origin, float halfWidth, float halfHeight, float cornerRadius, uint color, uint numSegments = 0u, float rotation = 0f, AxDxParams? dxParams = null)
{
float num = MathF.Min(cornerRadius, MathF.Min(halfWidth, halfHeight));
float cos = MathF.Cos(rotation);
float sin = MathF.Sin(rotation);
if (num <= 0f)
{
AddQuadFilled(RotateXZ(origin, 0f - halfWidth, 0f - halfHeight, cos, sin), RotateXZ(origin, halfWidth, 0f - halfHeight, cos, sin), RotateXZ(origin, halfWidth, halfHeight, cos, sin), RotateXZ(origin, 0f - halfWidth, halfHeight, cos, sin), color, dxParams);
return;
}
if (num < halfWidth)
{
AddQuadFilled(RotateXZ(origin, 0f - halfWidth + num, 0f - halfHeight, cos, sin), RotateXZ(origin, halfWidth - num, 0f - halfHeight, cos, sin), RotateXZ(origin, halfWidth - num, halfHeight, cos, sin), RotateXZ(origin, 0f - halfWidth + num, halfHeight, cos, sin), color, dxParams);
}
if (num < halfHeight)
{
AddQuadFilled(RotateXZ(origin, 0f - halfWidth, 0f - halfHeight + num, cos, sin), RotateXZ(origin, 0f - halfWidth + num, 0f - halfHeight + num, cos, sin), RotateXZ(origin, 0f - halfWidth + num, halfHeight - num, cos, sin), RotateXZ(origin, 0f - halfWidth, halfHeight - num, cos, sin), color, dxParams);
AddQuadFilled(RotateXZ(origin, halfWidth - num, 0f - halfHeight + num, cos, sin), RotateXZ(origin, halfWidth, 0f - halfHeight + num, cos, sin), RotateXZ(origin, halfWidth, halfHeight - num, cos, sin), RotateXZ(origin, halfWidth - num, halfHeight - num, cos, sin), color, dxParams);
}
Vector3 origin2 = RotateXZ(origin, halfWidth - num, 0f - halfHeight + num, cos, sin);
Vector3 origin3 = RotateXZ(origin, halfWidth - num, halfHeight - num, cos, sin);
Vector3 origin4 = RotateXZ(origin, 0f - halfWidth + num, halfHeight - num, cos, sin);
Vector3 origin5 = RotateXZ(origin, 0f - halfWidth + num, 0f - halfHeight + num, cos, sin);
AddArcFilled(origin2, num, (float)Math.PI + rotation, 4.712389f + rotation, color, null, numSegments, dxParams);
AddArcFilled(origin3, num, 4.712389f + rotation, (float)Math.PI * 2f + rotation, color, null, numSegments, dxParams);
AddArcFilled(origin4, num, rotation, (float)Math.PI / 2f + rotation, color, null, numSegments, dxParams);
AddArcFilled(origin5, num, (float)Math.PI / 2f + rotation, (float)Math.PI + rotation, color, null, numSegments, dxParams);
}
public void AddRoundedRectFilled<T>(Vector3 origin, float halfWidth, float halfHeight, float cornerRadius, T gradient, uint numSegments = 0u, float rotation = 0f, AxDxParams? dxParams = null) where T : IPctGradient
{
float num = MathF.Min(cornerRadius, MathF.Min(halfWidth, halfHeight));
float cos = MathF.Cos(rotation);
float sin = MathF.Sin(rotation);
if (num <= 0f)
{
AddQuadFilled(RotateXZ(origin, 0f - halfWidth, 0f - halfHeight, cos, sin), RotateXZ(origin, halfWidth, 0f - halfHeight, cos, sin), RotateXZ(origin, halfWidth, halfHeight, cos, sin), RotateXZ(origin, 0f - halfWidth, halfHeight, cos, sin), gradient, dxParams);
return;
}
if (num < halfWidth)
{
AddQuadFilled(RotateXZ(origin, 0f - halfWidth + num, 0f - halfHeight, cos, sin), RotateXZ(origin, halfWidth - num, 0f - halfHeight, cos, sin), RotateXZ(origin, halfWidth - num, halfHeight, cos, sin), RotateXZ(origin, 0f - halfWidth + num, halfHeight, cos, sin), gradient, dxParams);
}
if (num < halfHeight)
{
AddQuadFilled(RotateXZ(origin, 0f - halfWidth, 0f - halfHeight + num, cos, sin), RotateXZ(origin, 0f - halfWidth + num, 0f - halfHeight + num, cos, sin), RotateXZ(origin, 0f - halfWidth + num, halfHeight - num, cos, sin), RotateXZ(origin, 0f - halfWidth, halfHeight - num, cos, sin), gradient, dxParams);
AddQuadFilled(RotateXZ(origin, halfWidth - num, 0f - halfHeight + num, cos, sin), RotateXZ(origin, halfWidth, 0f - halfHeight + num, cos, sin), RotateXZ(origin, halfWidth, halfHeight - num, cos, sin), RotateXZ(origin, halfWidth - num, halfHeight - num, cos, sin), gradient, dxParams);
}
Vector3 origin2 = RotateXZ(origin, halfWidth - num, 0f - halfHeight + num, cos, sin);
Vector3 origin3 = RotateXZ(origin, halfWidth - num, halfHeight - num, cos, sin);
Vector3 origin4 = RotateXZ(origin, 0f - halfWidth + num, halfHeight - num, cos, sin);
Vector3 origin5 = RotateXZ(origin, 0f - halfWidth + num, 0f - halfHeight + num, cos, sin);
AddFanFilled(origin2, 0f, num, (float)Math.PI + rotation, 4.712389f + rotation, gradient, numSegments, dxParams);
AddFanFilled(origin3, 0f, num, 4.712389f + rotation, (float)Math.PI * 2f + rotation, gradient, numSegments, dxParams);
AddFanFilled(origin4, 0f, num, rotation, (float)Math.PI / 2f + rotation, gradient, numSegments, dxParams);
AddFanFilled(origin5, 0f, num, (float)Math.PI / 2f + rotation, (float)Math.PI + rotation, gradient, numSegments, dxParams);
}
public void AddPill(Vector3 start, Vector3 stop, float halfWidth, uint color, uint numSegments = 0u, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
Vector3 vector = stop - start;
float num = vector.Length();
if (num < 1E-06f)
{
AddCircle(start, halfWidth, color, numSegments * 2, thickness, dashLength, gapLength, dashOffset, colorEnd, dxParams);
return;
}
Vector3 vector2 = vector / num;
Vector3 vector3 = Vector3.Normalize(Vector3.Cross(vector2, Vector3.UnitY));
int num2 = (int)((numSegments != 0) ? numSegments : 50);
PathLineTo(start + vector3 * halfWidth);
PathLineTo(stop + vector3 * halfWidth);
for (int i = 1; i <= num2; i++)
{
float num3 = (float)i * (float)Math.PI / (float)num2;
PathLineTo(stop + halfWidth * (MathF.Cos(num3) * vector3 + MathF.Sin(num3) * vector2));
}
PathLineTo(start - vector3 * halfWidth);
for (int j = 1; j < num2; j++)
{
float num4 = (float)Math.PI + (float)j * (float)Math.PI / (float)num2;
PathLineTo(start + halfWidth * (MathF.Cos(num4) * vector3 + MathF.Sin(num4) * vector2));
}
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
public void AddPillFilled(Vector3 start, Vector3 stop, float halfWidth, uint color, uint numSegments = 0u, AxDxParams? dxParams = null)
{
Vector3 vector = stop - start;
float num = vector.Length();
if (num < 1E-06f)
{
AddCircleFilled(start, halfWidth, color, null, numSegments * 2, dxParams);
return;
}
Vector3 vector2 = vector / num;
Vector3 vector3 = Vector3.Normalize(Vector3.Cross(vector2, Vector3.UnitY));
AddQuadFilled(start + vector3 * halfWidth, stop + vector3 * halfWidth, stop - vector3 * halfWidth, start - vector3 * halfWidth, color, dxParams);
int num2 = (int)((numSegments != 0) ? numSegments : 25);
Vector3 b = stop + vector3 * halfWidth;
for (int i = 1; i <= num2; i++)
{
float num3 = (float)i * (float)Math.PI / (float)num2;
Vector3 vector4 = stop + halfWidth * (MathF.Cos(num3) * vector3 + MathF.Sin(num3) * vector2);
AddTriangleFilled(stop, b, vector4, color, dxParams);
b = vector4;
}
b = start - vector3 * halfWidth;
for (int j = 1; j <= num2; j++)
{
float num4 = (float)Math.PI + (float)j * (float)Math.PI / (float)num2;
Vector3 vector5 = start + halfWidth * (MathF.Cos(num4) * vector3 + MathF.Sin(num4) * vector2);
AddTriangleFilled(start, b, vector5, color, dxParams);
b = vector5;
}
}
public void AddPillFilled<T>(Vector3 start, Vector3 stop, float halfWidth, T gradient, uint numSegments = 0u, AxDxParams? dxParams = null) where T : IPctGradient
{
Vector3 vector = stop - start;
float num = vector.Length();
if (num < 1E-06f)
{
AddCircleFilled(start, halfWidth, gradient, numSegments * 2, dxParams);
return;
}
Vector3 vector2 = vector / num;
Vector3 vector3 = Vector3.Normalize(Vector3.Cross(vector2, Vector3.UnitY));
AddQuadFilled(start + vector3 * halfWidth, stop + vector3 * halfWidth, stop - vector3 * halfWidth, start - vector3 * halfWidth, gradient, dxParams);
int num2 = (int)((numSegments != 0) ? numSegments : 25);
Vector3 b = stop + vector3 * halfWidth;
for (int i = 1; i <= num2; i++)
{
float num3 = (float)i * (float)Math.PI / (float)num2;
Vector3 vector4 = stop + halfWidth * (MathF.Cos(num3) * vector3 + MathF.Sin(num3) * vector2);
AddTriangleFilled(stop, b, vector4, gradient, dxParams);
b = vector4;
}
b = start - vector3 * halfWidth;
for (int j = 1; j <= num2; j++)
{
float num4 = (float)Math.PI + (float)j * (float)Math.PI / (float)num2;
Vector3 vector5 = start + halfWidth * (MathF.Cos(num4) * vector3 + MathF.Sin(num4) * vector2);
AddTriangleFilled(start, b, vector5, gradient, dxParams);
b = vector5;
}
}
public void AddCircle(Vector3 origin, float radius, uint color, uint numSegments = 0u, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
PathArcTo(origin, radius, 0f, (float)Math.PI * 2f, numSegments);
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
public void AddCircleFilled(Vector3 origin, float radius, uint color, uint? colorEnd = null, uint numSegments = 0u, AxDxParams? dxParams = null)
{
AddFanFilled(origin, 0f, radius, 0f, (float)Math.PI * 2f, color, colorEnd, numSegments, dxParams);
}
public void AddCircleFilled<T>(Vector3 origin, float radius, T gradient, uint numSegments = 0u, AxDxParams? dxParams = null) where T : IPctGradient
{
AddFanFilled(origin, 0f, radius, 0f, (float)Math.PI * 2f, gradient, numSegments, dxParams);
}
public void AddArc(Vector3 origin, float radius, float minAngle, float maxAngle, uint color, uint numSegments = 0u, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
PathArcTo(origin, radius, minAngle, maxAngle, numSegments);
PathStroke(color, AxStrokeFlags.None, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
public void AddArcFilled(Vector3 origin, float radius, float minAngle, float maxAngle, uint color, uint? colorEnd = null, uint numSegments = 0u, AxDxParams? dxParams = null)
{
AddFanFilled(origin, 0f, radius, minAngle, maxAngle, color, colorEnd, numSegments, dxParams);
}
public void AddArcFilled<T>(Vector3 origin, float radius, float minAngle, float maxAngle, T gradient, uint numSegments = 0u, AxDxParams? dxParams = null) where T : IPctGradient
{
AddFanFilled(origin, 0f, radius, minAngle, maxAngle, gradient, numSegments, dxParams);
}
public void AddCone(Vector3 origin, float radius, float rotation, float angle, uint color, uint numSegments = 0u, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
float num = angle / 2f;
AddFan(origin, 0f, radius, rotation - num, rotation + num, color, numSegments, thickness, dashLength, gapLength, dashOffset, colorEnd, dxParams);
}
public void AddConeFilled(Vector3 origin, float radius, float rotation, float angle, uint color, uint? colorEnd = null, uint numSegments = 0u, AxDxParams? dxParams = null)
{
float num = angle / 2f;
AddFanFilled(origin, 0f, radius, rotation - num, rotation + num, color, colorEnd, numSegments, dxParams);
}
public void AddConeFilled<T>(Vector3 origin, float radius, float rotation, float angle, T gradient, uint numSegments = 0u, AxDxParams? dxParams = null) where T : IPctGradient
{
float num = angle / 2f;
AddFanFilled(origin, 0f, radius, rotation - num, rotation + num, gradient, numSegments, dxParams);
}
public void AddFan(Vector3 origin, float innerRadius, float outerRadius, float minAngle, float maxAngle, uint color, uint numSegments = 0u, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
bool flag = (double)(maxAngle - minAngle) >= 6.283184482025146;
PathArcTo(origin, outerRadius, minAngle, maxAngle, numSegments);
if (innerRadius > 0f)
{
if (flag)
{
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
PathArcTo(origin, innerRadius, maxAngle, minAngle, numSegments);
}
else if (!flag)
{
PathLineTo(origin);
}
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
public void AddFanFilled(Vector3 origin, float innerRadius, float outerRadius, float minAngle, float maxAngle, uint color, uint? colorEnd = null, uint numSegments = 0u, AxDxParams? dxParams = null)
{
AxDxParams p = dxParams ?? DefaultDxParams;
_renderer.DrawFan(origin, innerRadius, outerRadius, minAngle, maxAngle, color, colorEnd ?? color, numSegments, p);
}
public void AddFanFilled<T>(Vector3 origin, float innerRadius, float outerRadius, float minAngle, float maxAngle, T gradient, uint numSegments = 0u, AxDxParams? dxParams = null) where T : IPctGradient
{
AxDxParams p = dxParams ?? DefaultDxParams;
_renderer.DrawTriangleFanGradient(origin, innerRadius, outerRadius, minAngle, maxAngle, gradient, numSegments, p);
}
public void AddRegularPolygon(Vector3 origin, float radius, uint numSides, uint color, float rotation = 0f, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
if (numSides >= 3)
{
float num = (float)Math.PI * 2f / (float)numSides;
float num2 = (float)Math.PI / 2f + rotation;
for (uint num3 = 0u; num3 < numSides; num3++)
{
float num4 = num2 + (float)num3 * num;
PathLineTo(origin + radius * new Vector3(MathF.Cos(num4), 0f, MathF.Sin(num4)));
}
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
}
public void AddRegularPolygonFilled(Vector3 origin, float radius, uint numSides, uint color, float rotation = 0f, AxDxParams? dxParams = null)
{
if (numSides >= 3)
{
float num = (float)Math.PI * 2f / (float)numSides;
float num2 = (float)Math.PI / 2f + rotation;
Vector3 vector = origin + radius * new Vector3(MathF.Cos(num2), 0f, MathF.Sin(num2));
Vector3 b = vector;
for (uint num3 = 1u; num3 < numSides; num3++)
{
float num4 = num2 + (float)num3 * num;
Vector3 vector2 = origin + radius * new Vector3(MathF.Cos(num4), 0f, MathF.Sin(num4));
AddTriangleFilled(origin, b, vector2, color, dxParams);
b = vector2;
}
AddTriangleFilled(origin, b, vector, color, dxParams);
}
}
public void AddRegularPolygonFilled<T>(Vector3 origin, float radius, uint numSides, T gradient, float rotation = 0f, AxDxParams? dxParams = null) where T : IPctGradient
{
if (numSides >= 3)
{
float num = (float)Math.PI * 2f / (float)numSides;
float num2 = (float)Math.PI / 2f + rotation;
Vector3 vector = origin + radius * new Vector3(MathF.Cos(num2), 0f, MathF.Sin(num2));
Vector3 b = vector;
for (uint num3 = 1u; num3 < numSides; num3++)
{
float num4 = num2 + (float)num3 * num;
Vector3 vector2 = origin + radius * new Vector3(MathF.Cos(num4), 0f, MathF.Sin(num4));
AddTriangleFilled(origin, b, vector2, gradient, dxParams);
b = vector2;
}
AddTriangleFilled(origin, b, vector, gradient, dxParams);
}
}
public void AddStar(Vector3 origin, float outerRadius, float innerRadius, uint numPoints, uint color, float rotation = 0f, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
if (numPoints >= 2)
{
float num = (float)Math.PI / (float)numPoints;
float num2 = (float)Math.PI / 2f + rotation;
for (uint num3 = 0u; num3 < numPoints * 2; num3++)
{
float num4 = num2 + (float)num3 * num;
float num5 = ((num3 % 2 == 0) ? outerRadius : innerRadius);
PathLineTo(origin + num5 * new Vector3(MathF.Cos(num4), 0f, MathF.Sin(num4)));
}
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
}
public void AddStarFilled(Vector3 origin, float outerRadius, float innerRadius, uint numPoints, uint color, float rotation = 0f, AxDxParams? dxParams = null)
{
if (numPoints >= 2)
{
float num = (float)Math.PI / (float)numPoints;
float num2 = (float)Math.PI / 2f + rotation;
uint num3 = numPoints * 2;
Vector3 vector = origin + outerRadius * new Vector3(MathF.Cos(num2), 0f, MathF.Sin(num2));
Vector3 b = vector;
for (uint num4 = 1u; num4 < num3; num4++)
{
float num5 = num2 + (float)num4 * num;
float num6 = ((num4 % 2 == 0) ? outerRadius : innerRadius);
Vector3 vector2 = origin + num6 * new Vector3(MathF.Cos(num5), 0f, MathF.Sin(num5));
AddTriangleFilled(origin, b, vector2, color, dxParams);
b = vector2;
}
AddTriangleFilled(origin, b, vector, color, dxParams);
}
}
public void AddStarFilled<T>(Vector3 origin, float outerRadius, float innerRadius, uint numPoints, T gradient, float rotation = 0f, AxDxParams? dxParams = null) where T : IPctGradient
{
if (numPoints >= 2)
{
float num = (float)Math.PI / (float)numPoints;
float num2 = (float)Math.PI / 2f + rotation;
uint num3 = numPoints * 2;
Vector3 vector = origin + outerRadius * new Vector3(MathF.Cos(num2), 0f, MathF.Sin(num2));
Vector3 b = vector;
for (uint num4 = 1u; num4 < num3; num4++)
{
float num5 = num2 + (float)num4 * num;
float num6 = ((num4 % 2 == 0) ? outerRadius : innerRadius);
Vector3 vector2 = origin + num6 * new Vector3(MathF.Cos(num5), 0f, MathF.Sin(num5));
AddTriangleFilled(origin, b, vector2, gradient, dxParams);
b = vector2;
}
AddTriangleFilled(origin, b, vector, gradient, dxParams);
}
}
public void AddWireframeBox(Vector3 center, Vector3 halfExtent, uint color, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
float x = halfExtent.X;
float y = halfExtent.Y;
float z = halfExtent.Z;
Vector3 point = center + new Vector3(0f - x, 0f - y, 0f - z);
Vector3 point2 = center + new Vector3(x, 0f - y, 0f - z);
Vector3 point3 = center + new Vector3(x, 0f - y, z);
Vector3 point4 = center + new Vector3(0f - x, 0f - y, z);
Vector3 point5 = center + new Vector3(0f - x, y, 0f - z);
Vector3 point6 = center + new Vector3(x, y, 0f - z);
Vector3 point7 = center + new Vector3(x, y, z);
Vector3 point8 = center + new Vector3(0f - x, y, z);
PathLineTo(point);
PathLineTo(point2);
PathLineTo(point3);
PathLineTo(point4);
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
PathLineTo(point5);
PathLineTo(point6);
PathLineTo(point7);
PathLineTo(point8);
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
PathLineTo(point);
PathLineTo(point5);
PathStroke(color, AxStrokeFlags.None, thickness, dashLength, gapLength, dashOffset, colorEnd);
PathLineTo(point2);
PathLineTo(point6);
PathStroke(color, AxStrokeFlags.None, thickness, dashLength, gapLength, dashOffset, colorEnd);
PathLineTo(point3);
PathLineTo(point7);
PathStroke(color, AxStrokeFlags.None, thickness, dashLength, gapLength, dashOffset, colorEnd);
PathLineTo(point4);
PathLineTo(point8);
PathStroke(color, AxStrokeFlags.None, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
public void AddWireframeSphere(Vector3 center, float radius, uint color, uint numSegments = 0u, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
if (numSegments == 0)
{
numSegments = (uint)MathF.Max(12f, MathF.Ceiling(radius * 8f));
}
float num = (float)Math.PI * 2f / (float)numSegments;
for (uint num2 = 0u; num2 < numSegments; num2++)
{
float num3 = (float)num2 * num;
PathLineTo(center + new Vector3(MathF.Cos(num3) * radius, 0f, MathF.Sin(num3) * radius));
}
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
for (uint num4 = 0u; num4 < numSegments; num4++)
{
float num5 = (float)num4 * num;
PathLineTo(center + new Vector3(MathF.Cos(num5) * radius, MathF.Sin(num5) * radius, 0f));
}
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
for (uint num6 = 0u; num6 < numSegments; num6++)
{
float num7 = (float)num6 * num;
PathLineTo(center + new Vector3(0f, MathF.Cos(num7) * radius, MathF.Sin(num7) * radius));
}
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
public void AddWireframeCylinder(Vector3 center, float radius, float halfHeight, uint color, uint numVerticals = 4u, uint numSegments = 0u, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxDxParams? dxParams = null)
{
if (numSegments == 0)
{
numSegments = (uint)MathF.Max(12f, MathF.Ceiling(radius * 8f));
}
float num = (float)Math.PI * 2f / (float)numSegments;
float y = center.Y + halfHeight;
float y2 = center.Y - halfHeight;
for (uint num2 = 0u; num2 < numSegments; num2++)
{
float num3 = (float)num2 * num;
PathLineTo(new Vector3(center.X + MathF.Cos(num3) * radius, y2, center.Z + MathF.Sin(num3) * radius));
}
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
for (uint num4 = 0u; num4 < numSegments; num4++)
{
float num5 = (float)num4 * num;
PathLineTo(new Vector3(center.X + MathF.Cos(num5) * radius, y, center.Z + MathF.Sin(num5) * radius));
}
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd);
if (numVerticals != 0)
{
float num6 = (float)Math.PI * 2f / (float)numVerticals;
for (uint num7 = 0u; num7 < numVerticals; num7++)
{
float num8 = (float)num7 * num6;
float x = center.X + MathF.Cos(num8) * radius;
float z = center.Z + MathF.Sin(num8) * radius;
PathLineTo(new Vector3(x, y2, z));
PathLineTo(new Vector3(x, y, z));
PathStroke(color, AxStrokeFlags.None, thickness, dashLength, gapLength, dashOffset, colorEnd);
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector3 RotateXZ(Vector3 origin, float dx, float dz, float cos, float sin)
{
return new Vector3(origin.X + dx * cos - dz * sin, origin.Y, origin.Z + dx * sin + dz * cos);
}
public void AddClipZone(Vector2 min, Vector2 max)
{
_renderer.AddClipZone(min, max);
}
public void AddCircleFilledOnTerrain(Vector3 origin, float radius, uint color, uint? colorEnd = null, uint numSegments = 0u, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
AxDxParams p = dxParams ?? DefaultDxParams;
_renderer.DrawTerrainFan(origin, 0f, radius, 0f, (float)Math.PI * 2f, color, colorEnd ?? color, resolution, yOffset, numSegments, p);
}
public void AddCircleFilledOnTerrain<T>(Vector3 origin, float radius, T gradient, uint numSegments = 0u, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null) where T : IPctGradient
{
AxDxParams p = dxParams ?? DefaultDxParams;
_renderer.DrawTerrainFanGradient(origin, 0f, radius, 0f, (float)Math.PI * 2f, gradient, resolution, yOffset, numSegments, p);
}
public void AddFanFilledOnTerrain(Vector3 origin, float innerRadius, float outerRadius, float minAngle, float maxAngle, uint color, uint? colorEnd = null, uint numSegments = 0u, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
AxDxParams p = dxParams ?? DefaultDxParams;
_renderer.DrawTerrainFan(origin, innerRadius, outerRadius, minAngle, maxAngle, color, colorEnd ?? color, resolution, yOffset, numSegments, p);
}
public void AddFanFilledOnTerrain<T>(Vector3 origin, float innerRadius, float outerRadius, float minAngle, float maxAngle, T gradient, uint numSegments = 0u, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null) where T : IPctGradient
{
AxDxParams p = dxParams ?? DefaultDxParams;
_renderer.DrawTerrainFanGradient(origin, innerRadius, outerRadius, minAngle, maxAngle, gradient, resolution, yOffset, numSegments, p);
}
public void AddQuadFilledOnTerrain(Vector3 a, Vector3 b, Vector3 c, Vector3 d, uint color, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
AxDxParams p = dxParams ?? DefaultDxParams;
_renderer.DrawTerrainQuad(a, b, c, d, color, color, color, color, resolution, yOffset, p);
}
public void AddQuadFilledOnTerrain(Vector3 a, Vector3 b, Vector3 c, Vector3 d, uint colorA, uint colorB, uint colorC, uint colorD, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
AxDxParams p = dxParams ?? DefaultDxParams;
_renderer.DrawTerrainQuad(a, b, c, d, colorA, colorB, colorC, colorD, resolution, yOffset, p);
}
public void AddQuadFilledOnTerrain<T>(Vector3 a, Vector3 b, Vector3 c, Vector3 d, T gradient, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null) where T : IPctGradient
{
AxDxParams p = dxParams ?? DefaultDxParams;
_renderer.DrawTerrainQuadGradient(a, b, c, d, gradient, resolution, yOffset, p);
}
public void AddCircleOnTerrain(Vector3 origin, float radius, uint color, uint numSegments = 0u, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
PathArcToOnTerrain(origin, radius, 0f, (float)Math.PI * 2f, yOffset, numSegments, resolution);
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd, AxLineCap.Butt, AxLineJoin.None, dxParams);
}
public void AddFanOnTerrain(Vector3 origin, float innerRadius, float outerRadius, float minAngle, float maxAngle, uint color, uint numSegments = 0u, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
bool flag = (double)(maxAngle - minAngle) >= 6.283184482025146;
PathArcToOnTerrain(origin, outerRadius, minAngle, maxAngle, yOffset, numSegments, resolution);
if (innerRadius > 0f)
{
if (flag)
{
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd, AxLineCap.Butt, AxLineJoin.None, dxParams);
}
PathArcToOnTerrain(origin, innerRadius, maxAngle, minAngle, yOffset, numSegments, resolution);
}
else if (!flag)
{
float terrainYRaw = AxTerrainQuery.GetTerrainYRaw(origin.X, origin.Z);
float y = (float.IsNaN(terrainYRaw) ? origin.Y : terrainYRaw) + yOffset;
PathLineTo(new Vector3(origin.X, y, origin.Z));
}
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd, AxLineCap.Butt, AxLineJoin.None, dxParams);
}
public void AddQuadOnTerrain(Vector3 a, Vector3 b, Vector3 c, Vector3 d, uint color, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
PathLineToOnTerrain(a, b, yOffset, resolution);
PathLineToOnTerrain(b, c, yOffset, resolution);
PathLineToOnTerrain(c, d, yOffset, resolution);
PathLineToOnTerrain(d, a, yOffset, resolution);
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd, AxLineCap.Butt, AxLineJoin.None, dxParams);
}
public void AddConeFilledOnTerrain(Vector3 origin, float radius, float rotation, float angle, uint color, uint? colorEnd = null, uint numSegments = 0u, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
float num = angle / 2f;
AddFanFilledOnTerrain(origin, 0f, radius, rotation - num, rotation + num, color, colorEnd, numSegments, resolution, yOffset, dxParams);
}
public void AddConeFilledOnTerrain<T>(Vector3 origin, float radius, float rotation, float angle, T gradient, uint numSegments = 0u, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null) where T : IPctGradient
{
float num = angle / 2f;
AddFanFilledOnTerrain(origin, 0f, radius, rotation - num, rotation + num, gradient, numSegments, resolution, yOffset, dxParams);
}
public void AddConeOnTerrain(Vector3 origin, float radius, float rotation, float angle, uint color, uint numSegments = 0u, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
float num = angle / 2f;
AddFanOnTerrain(origin, 0f, radius, rotation - num, rotation + num, color, numSegments, thickness, dashLength, gapLength, dashOffset, colorEnd, resolution, yOffset, dxParams);
}
public void AddArcFilledOnTerrain(Vector3 origin, float radius, float minAngle, float maxAngle, uint color, uint? colorEnd = null, uint numSegments = 0u, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
AddFanFilledOnTerrain(origin, 0f, radius, minAngle, maxAngle, color, colorEnd, numSegments, resolution, yOffset, dxParams);
}
public void AddArcFilledOnTerrain<T>(Vector3 origin, float radius, float minAngle, float maxAngle, T gradient, uint numSegments = 0u, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null) where T : IPctGradient
{
AddFanFilledOnTerrain(origin, 0f, radius, minAngle, maxAngle, gradient, numSegments, resolution, yOffset, dxParams);
}
public void AddArcOnTerrain(Vector3 origin, float radius, float minAngle, float maxAngle, uint color, uint numSegments = 0u, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
PathArcToOnTerrain(origin, radius, minAngle, maxAngle, yOffset, numSegments, resolution);
PathStroke(color, AxStrokeFlags.None, thickness, dashLength, gapLength, dashOffset, colorEnd, AxLineCap.Butt, AxLineJoin.None, dxParams);
}
public void AddLineFilledOnTerrain(Vector3 start, Vector3 stop, float halfWidth, uint color, uint? colorEnd = null, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
Vector3 vector = stop - start;
Vector3 vector2 = halfWidth * Vector3.Normalize(Vector3.Cross(vector, Vector3.UnitY));
AddQuadFilledOnTerrain(start - vector2, stop - vector2, stop + vector2, start + vector2, color, colorEnd ?? color, colorEnd ?? color, color, resolution, yOffset, dxParams);
}
public void AddLineFilledOnTerrain<T>(Vector3 start, Vector3 stop, float halfWidth, T gradient, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null) where T : IPctGradient
{
Vector3 vector = stop - start;
Vector3 vector2 = halfWidth * Vector3.Normalize(Vector3.Cross(vector, Vector3.UnitY));
AddQuadFilledOnTerrain(start - vector2, stop - vector2, stop + vector2, start + vector2, gradient, resolution, yOffset, dxParams);
}
public void AddLineOnTerrain(Vector3 start, Vector3 stop, float halfWidth, uint color, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
Vector3 vector = stop - start;
Vector3 vector2 = halfWidth * Vector3.Normalize(Vector3.Cross(vector, Vector3.UnitY));
AddQuadOnTerrain(start - vector2, stop - vector2, stop + vector2, start + vector2, color, thickness, dashLength, gapLength, dashOffset, colorEnd, resolution, yOffset, dxParams);
}
public void AddPillFilledOnTerrain(Vector3 start, Vector3 stop, float halfWidth, uint color, uint numSegments = 0u, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
Vector3 vector = stop - start;
float num = vector.Length();
if (num < 1E-06f)
{
AddCircleFilledOnTerrain(start, halfWidth, color, null, numSegments * 2, resolution, yOffset, dxParams);
return;
}
Vector3 vector2 = vector / num;
Vector3 vector3 = Vector3.Normalize(Vector3.Cross(vector2, Vector3.UnitY));
float num2 = MathF.Atan2(0f - vector2.X, vector2.Z);
AddQuadFilledOnTerrain(start + vector3 * halfWidth, stop + vector3 * halfWidth, stop - vector3 * halfWidth, start - vector3 * halfWidth, color, resolution, yOffset, dxParams);
AddFanFilledOnTerrain(stop, 0f, halfWidth, num2 - (float)Math.PI / 2f, num2 + (float)Math.PI / 2f, color, null, numSegments, resolution, yOffset, dxParams);
AddFanFilledOnTerrain(start, 0f, halfWidth, num2 + (float)Math.PI / 2f, num2 + 4.712389f, color, null, numSegments, resolution, yOffset, dxParams);
}
public void AddPillFilledOnTerrain<T>(Vector3 start, Vector3 stop, float halfWidth, T gradient, uint numSegments = 0u, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null) where T : IPctGradient
{
Vector3 vector = stop - start;
float num = vector.Length();
if (num < 1E-06f)
{
AddCircleFilledOnTerrain(start, halfWidth, gradient, numSegments * 2, resolution, yOffset, dxParams);
return;
}
Vector3 vector2 = vector / num;
Vector3 vector3 = Vector3.Normalize(Vector3.Cross(vector2, Vector3.UnitY));
float num2 = MathF.Atan2(0f - vector2.X, vector2.Z);
AddQuadFilledOnTerrain(start + vector3 * halfWidth, stop + vector3 * halfWidth, stop - vector3 * halfWidth, start - vector3 * halfWidth, gradient, resolution, yOffset, dxParams);
AddFanFilledOnTerrain(stop, 0f, halfWidth, num2 - (float)Math.PI / 2f, num2 + (float)Math.PI / 2f, gradient, numSegments, resolution, yOffset, dxParams);
AddFanFilledOnTerrain(start, 0f, halfWidth, num2 + (float)Math.PI / 2f, num2 + 4.712389f, gradient, numSegments, resolution, yOffset, dxParams);
}
public void AddPillOnTerrain(Vector3 start, Vector3 stop, float halfWidth, uint color, uint numSegments = 0u, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
Vector3 vector = stop - start;
float num = vector.Length();
if (num < 1E-06f)
{
AddCircleOnTerrain(start, halfWidth, color, numSegments * 2, thickness, dashLength, gapLength, dashOffset, colorEnd, resolution, yOffset, dxParams);
return;
}
Vector3 vector2 = Vector3.Normalize(Vector3.Cross(vector / num, Vector3.UnitY));
float num2 = MathF.Atan2(0f - vector2.X, vector2.Z);
PathLineToOnTerrain(start + vector2 * halfWidth, stop + vector2 * halfWidth, yOffset, resolution);
PathArcToOnTerrain(stop, halfWidth, num2, num2 - (float)Math.PI, yOffset, numSegments, resolution);
PathLineToOnTerrain(stop - vector2 * halfWidth, start - vector2 * halfWidth, yOffset, resolution);
PathArcToOnTerrain(start, halfWidth, num2 - (float)Math.PI, num2 - (float)Math.PI * 2f, yOffset, numSegments, resolution);
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd, AxLineCap.Butt, AxLineJoin.None, dxParams);
}
public void AddArrowFilledOnTerrain(Vector3 start, Vector3 stop, float halfWidth, uint color, float headLength = 0f, float headHalfWidth = 0f, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
Vector3 vector = stop - start;
float num = vector.Length();
if (!(num < 1E-06f))
{
if (headLength == 0f)
{
headLength = halfWidth * 3f;
}
if (headHalfWidth == 0f)
{
headHalfWidth = halfWidth * 2f;
}
Vector3 vector2 = vector / num;
Vector3 vector3 = Vector3.Normalize(Vector3.Cross(vector2, Vector3.UnitY));
if (num > headLength)
{
Vector3 vector4 = stop - vector2 * headLength;
AddQuadFilledOnTerrain(start - vector3 * halfWidth, vector4 - vector3 * halfWidth, vector4 + vector3 * halfWidth, start + vector3 * halfWidth, color, resolution, yOffset, dxParams);
AddQuadFilledOnTerrain(vector4 - vector3 * headHalfWidth, stop, stop, vector4 + vector3 * headHalfWidth, color, resolution, yOffset, dxParams);
}
else
{
AddQuadFilledOnTerrain(start - vector3 * headHalfWidth, stop, stop, start + vector3 * headHalfWidth, color, resolution, yOffset, dxParams);
}
}
}
public void AddArrowFilledOnTerrain<T>(Vector3 start, Vector3 stop, float halfWidth, T gradient, float headLength = 0f, float headHalfWidth = 0f, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null) where T : IPctGradient
{
Vector3 vector = stop - start;
float num = vector.Length();
if (!(num < 1E-06f))
{
if (headLength == 0f)
{
headLength = halfWidth * 3f;
}
if (headHalfWidth == 0f)
{
headHalfWidth = halfWidth * 2f;
}
Vector3 vector2 = vector / num;
Vector3 vector3 = Vector3.Normalize(Vector3.Cross(vector2, Vector3.UnitY));
if (num > headLength)
{
Vector3 vector4 = stop - vector2 * headLength;
AddQuadFilledOnTerrain(start - vector3 * halfWidth, vector4 - vector3 * halfWidth, vector4 + vector3 * halfWidth, start + vector3 * halfWidth, gradient, resolution, yOffset, dxParams);
AddQuadFilledOnTerrain(vector4 - vector3 * headHalfWidth, stop, stop, vector4 + vector3 * headHalfWidth, gradient, resolution, yOffset, dxParams);
}
else
{
AddQuadFilledOnTerrain(start - vector3 * headHalfWidth, stop, stop, start + vector3 * headHalfWidth, gradient, resolution, yOffset, dxParams);
}
}
}
public void AddArrowOnTerrain(Vector3 start, Vector3 stop, float halfWidth, uint color, float headLength = 0f, float headHalfWidth = 0f, float thickness = 2f, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, float resolution = 0.5f, float yOffset = 0.02f, AxDxParams? dxParams = null)
{
Vector3 vector = stop - start;
float num = vector.Length();
if (!(num < 1E-06f))
{
if (headLength == 0f)
{
headLength = halfWidth * 3f;
}
if (headHalfWidth == 0f)
{
headHalfWidth = halfWidth * 2f;
}
Vector3 vector2 = vector / num;
Vector3 vector3 = Vector3.Normalize(Vector3.Cross(vector2, Vector3.UnitY));
if (num > headLength)
{
Vector3 vector4 = stop - vector2 * headLength;
PathLineToOnTerrain(start + vector3 * halfWidth, vector4 + vector3 * halfWidth, yOffset, resolution);
PathLineToOnTerrain(vector4 + vector3 * halfWidth, vector4 + vector3 * headHalfWidth, yOffset, resolution);
PathLineToOnTerrain(vector4 + vector3 * headHalfWidth, stop, yOffset, resolution);
PathLineToOnTerrain(stop, vector4 - vector3 * headHalfWidth, yOffset, resolution);
PathLineToOnTerrain(vector4 - vector3 * headHalfWidth, vector4 - vector3 * halfWidth, yOffset, resolution);
PathLineToOnTerrain(vector4 - vector3 * halfWidth, start - vector3 * halfWidth, yOffset, resolution);
}
else
{
PathLineToOnTerrain(start + vector3 * headHalfWidth, stop, yOffset, resolution);
PathLineToOnTerrain(stop, start - vector3 * headHalfWidth, yOffset, resolution);
}
PathStroke(color, AxStrokeFlags.Closed, thickness, dashLength, gapLength, dashOffset, colorEnd, AxLineCap.Butt, AxLineJoin.None, dxParams);
}
}
private void PathArcToOnTerrain(Vector3 origin, float radius, float startAngle, float stopAngle, float yOffset, uint numSegments, float resolution)
{
float num = stopAngle - startAngle;
if (num != 0f)
{
if (numSegments == 0)
{
numSegments = (uint)MathF.Max(1f, MathF.Ceiling(MathF.Abs(num) * radius / resolution));
}
float num2 = num / (float)numSegments;
for (int i = 0; i <= numSegments; i++)
{
float num3 = (float)Math.PI / 2f + startAngle + (float)i * num2;
float x = origin.X + MathF.Cos(num3) * radius;
float z = origin.Z + MathF.Sin(num3) * radius;
float terrainYRaw = AxTerrainQuery.GetTerrainYRaw(x, z);
float y = (float.IsNaN(terrainYRaw) ? origin.Y : terrainYRaw) + yOffset;
_path.Add(new Vector3(x, y, z));
}
}
}
private void PathLineToOnTerrain(Vector3 start, Vector3 end, float yOffset, float resolution)
{
float num = Vector3.Distance(start, end);
int num2 = Math.Max(1, (int)MathF.Ceiling(num / resolution));
for (int i = 0; i < num2; i++)
{
float num3 = (float)i / (float)num2;
float x = start.X + (end.X - start.X) * num3;
float z = start.Z + (end.Z - start.Z) * num3;
float terrainYRaw = AxTerrainQuery.GetTerrainYRaw(x, z);
float num4 = start.Y + (end.Y - start.Y) * num3;
float y = (float.IsNaN(terrainYRaw) ? num4 : terrainYRaw) + yOffset;
_path.Add(new Vector3(x, y, z));
}
}
}