using System.Collections.Generic; using System.Numerics; using Dalamud.Bindings.ImGui; using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game.Control; using FFXIVClientStructs.FFXIV.Client.Graphics.Render; namespace Auspex.Rendering.ImGuiFallback; internal sealed class ImGuiFallbackRenderer { private readonly ImDrawListPtr drawList; private readonly Matrix4x4 viewProj; private readonly Vector4 nearPlane; public unsafe ImGuiFallbackRenderer(ImDrawListPtr drawList) { this.drawList = drawList; viewProj = Control.Instance()->ViewProjectionMatrix; FFXIVClientStructs.FFXIV.Client.Game.Camera* activeCamera = Control.Instance()->CameraManager.GetActiveCamera(); FFXIVClientStructs.FFXIV.Client.Graphics.Render.Camera* ptr = ((activeCamera != null) ? activeCamera->SceneCamera.RenderCamera : null); if (ptr == null) { nearPlane = new Vector4(viewProj.M13, viewProj.M23, viewProj.M33, viewProj.M43); return; } if (!Matrix4x4.Invert(ptr->ProjectionMatrix, out var result)) { nearPlane = new Vector4(viewProj.M13, viewProj.M23, viewProj.M33, viewProj.M43); return; } Matrix4x4 matrix4x = viewProj * result; nearPlane = new Vector4(matrix4x.M13, matrix4x.M23, matrix4x.M33, matrix4x.M43 + ptr->NearPlane); } public void DrawStroke(List world, float thickness, uint color, bool closed = false, float dashLength = 0f, float gapLength = 0f, float dashOffset = 0f, uint? colorEnd = null, AxLineCap cap = AxLineCap.Butt, AxLineJoin join = AxLineJoin.None) { if (world.Count != 0) { for (int i = 1; i < world.Count; i++) { DrawStroke(world[i - 1], world[i], thickness, color); } if (closed) { DrawStroke(world[world.Count - 1], world[0], thickness, color); } } } public void DrawStroke(Vector3 start, Vector3 stop, float thickness, uint color) { if (FallbackClipMath.ClipLineToPlane(nearPlane, ref start, ref stop, out var _) != FallbackClipMath.LineClipStatus.NotVisible) { drawList.PathClear(); drawList.PathLineTo(FallbackClipMath.WorldToScreenOld(in viewProj, in start)); drawList.PathLineTo(FallbackClipMath.WorldToScreenOld(in viewProj, in stop)); drawList.PathStroke(color, ImDrawFlags.None, thickness); } } }