Skip to content

Commit

Permalink
optimze Hold drawing and add VisibleLineVerticesQuery
Browse files Browse the repository at this point in the history
  • Loading branch information
MikiraSora committed Dec 28, 2023
1 parent d572473 commit 22a2f5b
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using OngekiFumenEditor.Base;
using OngekiFumenEditor.Base.OngekiObjects.ConnectableObject;
using OngekiFumenEditor.Kernel.Graphics;
using OngekiFumenEditor.Utils.ObjectPool;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
Expand All @@ -25,61 +26,11 @@ public CommonLinesDrawTargetBase()
public void FillLine(IFumenEditorDrawingContext target, T start)
{
var color = GetLanePointColor(start);
var resT = start.TGrid.ResT;
var resX = start.XGrid.ResX;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
void PostPoint2(double tGridUnit, double xGridUnit, bool isVailed)
{
var x = (float)XGridCalculator.ConvertXGridToX(xGridUnit, target.Editor);
var y = (float)target.ConvertToY(tGridUnit);

lineDrawing.PostPoint(new(x, y), color, isVailed ? VertexDash.Solider : invailedDash);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void PostPoint(TGrid tGrid, XGrid xGrid, bool isVailed) => PostPoint2(tGrid.TotalUnit, xGrid.TotalUnit, isVailed);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void PostObject(OngekiMovableObjectBase obj, bool isVailed) => PostPoint(obj.TGrid, obj.XGrid, isVailed);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
bool getNextIsVaild(ConnectableObjectBase o) => o.NextObject?.IsVaildPath ?? true;

var prevVisible = target.CheckVisible(start.TGrid);
var alwaysDrawing = target.CheckRangeVisible(start.MinTGrid, start.MaxTGrid);

PostObject(start, getNextIsVaild(start));
var prevInvaild = true;
var prevObj = start as ConnectableObjectBase;

foreach (var childObj in start.Children)
{
var visible = alwaysDrawing || target.CheckVisible(childObj.TGrid);
var curIsVaild = childObj.IsVaildPath;
if (prevInvaild != curIsVaild)
{
PostObject(prevObj, curIsVaild);
prevInvaild = curIsVaild;
}

if (prevVisible != visible && prevVisible == false)
PostObject(prevObj, prevInvaild);

if (visible || prevVisible)
{
if (childObj.IsCurvePath)
{
foreach (var item in childObj.GetConnectionPaths())
{
PostPoint2(item.pos.Y / resT, item.pos.X / resX, curIsVaild);
}
}
else
PostObject(childObj, curIsVaild);
}

prevObj = childObj;
prevVisible = visible;
}
using var d = ObjectPool<List<LineVertex>>.GetWithUsingDisposable(out var list, out _);
list.Clear();
VisibleLineVerticesQuery.QueryVisibleLineVertices(target, start, invailedDash, color, list);
lineDrawing.Draw(target, list, LineWidth);
}

public override void DrawBatch(IFumenEditorDrawingContext target, IEnumerable<T> starts)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ public override void Draw(IFumenEditorDrawingContext target, Hold hold)
var holdEnd = hold.HoldEnd;
var laneType = start?.LaneType;

var shareTGrid = new TGrid();
var shareXGrid = new XGrid();

var color = laneType switch
{
LaneType.Left => new Vector4(1, 0, 0, 0.75f),
Expand All @@ -47,81 +44,32 @@ public override void Draw(IFumenEditorDrawingContext target, Hold hold)
_ => new Vector4(1, 1, 1, 0.75f),
};

//draw line
using var d = ObjectPool<List<LineVertex>>.GetWithUsingDisposable(out var list, out _);
list.Clear();

void Upsert<T>(T obj) where T : IHorizonPositionObject, ITimelineObject
{
var y = (float)target.ConvertToY(obj.TGrid);
var x = (float)XGridCalculator.ConvertXGridToX(obj.XGrid, target.Editor);
list.Add(new(new(x, y), color, VertexDash.Solider));
}

void Upsert2((float, float) pos)
{
var y = (float)target.ConvertToY(pos.Item1);
var x = (float)XGridCalculator.ConvertXGridToX(pos.Item2, target.Editor);
list.Add(new(new(x, y), color, VertexDash.Solider));
}

if (holdEnd != null)
{
var resT = hold.TGrid.ResT;
var resX = hold.XGrid.ResX;

var endPos = ((float)holdEnd.TGrid.TotalUnit, (float)holdEnd.XGrid.TotalUnit);

Upsert(hold);
if (start != null)
Vector2 PostPoint2(double tGridUnit, double xGridUnit)
{
var nodes = start.Children
.SelectMany(x => x.GetConnectionPaths())
.Select(x => (x.pos.Y / resT, x.pos.X / resX))
.Prepend(((float)start.TGrid.TotalUnit, (float)start.XGrid.TotalUnit))
.DistinctContinuousBy(x => x)
.Where(pos => hold.TGrid.TotalUnit <= pos.Item1 && pos.Item1 <= holdEnd.TGrid.TotalUnit);
//var r = nodes.ToArray();
var itor = nodes.GetEnumerator();
var x = (float)XGridCalculator.ConvertXGridToX(xGridUnit, target.Editor);
var y = (float)target.ConvertToY(tGridUnit);

var hasValue = itor.MoveNext();
var cur = itor.Current;
var prev = (float.MinValue, 2857f);

bool checkDiscardByHorizon((float, float) prev, (float, float) cur)
{
//判断三个点是否都在一个水平上
if (prev.Item1 == cur.Item1 && endPos.Item1 == cur.Item1)
{
/*
good discard
o-----------x---------o----------x----------------
| | | |
prevX curX_1 endPosX curX_2
*/
var checkX = cur.Item2;
if (checkX < MathF.Min(prev.Item2, endPos.Item2) || checkX > MathF.Max(prev.Item2, endPos.Item2))
return true;
}
return false;
}
return new(x, y);
}

while (itor.MoveNext())
{
if (!checkDiscardByHorizon(prev, cur))
Upsert2(cur);
prev = cur;
cur = itor.Current;
}
var holdPoint = PostPoint2(hold.TGrid.TotalUnit, hold.XGrid.TotalUnit);
var holdEndPoint = PostPoint2(holdEnd.TGrid.TotalUnit, holdEnd.XGrid.TotalUnit);

if (hasValue)
{
if (!checkDiscardByHorizon(prev, cur))
Upsert2(cur);
}
using var d = ObjectPool<List<LineVertex>>.GetWithUsingDisposable(out var list, out _);
list.Clear();
VisibleLineVerticesQuery.QueryVisibleLineVertices(target, start, VertexDash.Solider, color, list);
if (list.Count > 0)
{
while (holdPoint.Y > list[0].Point.Y)
list.RemoveAt(0);
list.Insert(0, new LineVertex(holdPoint, color, VertexDash.Solider));
while (holdEndPoint.Y < list[list.Count - 1].Point.Y)
list.RemoveAt(list.Count - 1);
list.Add(new LineVertex(holdEndPoint, color, VertexDash.Solider));
}

Upsert2(endPos);
lineDrawing.Draw(target, list, 13);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using OngekiFumenEditor.Base;
using OngekiFumenEditor.Base.OngekiObjects.ConnectableObject;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using static OngekiFumenEditor.Kernel.Graphics.ILineDrawing;

namespace OngekiFumenEditor.Modules.FumenVisualEditor.Graphics.Drawing.TargetImpl
{
public static class VisibleLineVerticesQuery
{
public static void QueryVisibleLineVertices(IFumenEditorDrawingContext target, ConnectableStartObject start, VertexDash invailedDash, Vector4 color, IList<LineVertex> outVertices)
{
var resT = start.TGrid.ResT;
var resX = start.XGrid.ResX;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
void PostPoint2(double tGridUnit, double xGridUnit, bool isVailed)
{
var x = (float)XGridCalculator.ConvertXGridToX(xGridUnit, target.Editor);
var y = (float)target.ConvertToY(tGridUnit);

outVertices.Add(new(new(x, y), color, isVailed ? VertexDash.Solider : invailedDash));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void PostPoint(TGrid tGrid, XGrid xGrid, bool isVailed) => PostPoint2(tGrid.TotalUnit, xGrid.TotalUnit, isVailed);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void PostObject(OngekiMovableObjectBase obj, bool isVailed) => PostPoint(obj.TGrid, obj.XGrid, isVailed);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
bool getNextIsVaild(ConnectableObjectBase o) => o.NextObject?.IsVaildPath ?? true;

var prevVisible = target.CheckVisible(start.TGrid);
var alwaysDrawing = target.CheckRangeVisible(start.MinTGrid, start.MaxTGrid);

PostObject(start, getNextIsVaild(start));
var prevInvaild = true;
var prevObj = start as ConnectableObjectBase;

foreach (var childObj in start.Children)
{
var visible = alwaysDrawing || target.CheckVisible(childObj.TGrid);
var curIsVaild = childObj.IsVaildPath;
if (prevInvaild != curIsVaild)
{
PostObject(prevObj, curIsVaild);
prevInvaild = curIsVaild;
}

if (prevVisible != visible && prevVisible == false)
PostObject(prevObj, prevInvaild);

if (visible || prevVisible)
{
if (childObj.IsCurvePath)
{
foreach (var item in childObj.GetConnectionPaths())
PostPoint2(item.pos.Y / resT, item.pos.X / resX, curIsVaild);
}
else
PostObject(childObj, curIsVaild);
}

prevObj = childObj;
prevVisible = visible;
}
}
}
}

0 comments on commit 22a2f5b

Please sign in to comment.