protected override void BuildVertices() { var startTiming = StartNote.Temporary.HitTiming.TotalSeconds; var endTiming = EndNote.Temporary.HitTiming.TotalSeconds; var finishPosition = EndNote.Basic.FinishPosition; var now = Now; var context = RenderContext; var xs = new float[JointCount]; var ys = new float[JointCount]; var rs = new float[JointCount]; for (var i = 0; i < JointCount; ++i) { var timing = (endTiming - startTiming) / (JointCount - 1) * i + startTiming; var startPosition = EndNote.Basic.StartPosition; xs[i] = NotesLayerUtils.GetNoteXPosition(context, now, timing, startPosition, finishPosition, true, true); ys[i] = NotesLayerUtils.GetNoteYPosition(context, now, timing, true, true); rs[i] = NotesLayerUtils.GetNoteRadius(now, timing); } for (var i = 0; i < JointCount; ++i) { var x = xs[i]; var y = ys[i]; var r = rs[i]; var vertex1 = new Vector2(x - r, y); var vertex2 = new Vector2(x + r, y); Vertices[i * 2] = vertex1; Vertices[i * 2 + 1] = vertex2; } }
private void DrawSlideNote(Graphics context, double now, Note note) { float x, y, r; if (NotesLayerUtils.IsNoteOnStage(note, now)) { if (note.Helper.IsSlideEnd && NotesLayerUtils.IsNotePassed(note, now)) { return; } x = NotesLayerUtils.GetNoteXPosition(context, now, note); y = NotesLayerUtils.GetNoteYPosition(context, now, note); r = NotesLayerUtils.GetNoteRadius(now, note); } else if (NotesLayerUtils.IsNotePassed(note, now)) { if (!note.Helper.HasNextSlide || NotesLayerUtils.IsNotePassed(note.Editor.NextSlide, now)) { return; } var nextSlideNote = note.Editor.NextSlide; if (nextSlideNote == null) { // Actually, here is an example of invalid format. :) DrawTapNote(context, now, note); return; } else { var startX = NotesLayerUtils.GetEndXByNotePosition(context.Bounds, note.Basic.FinishPosition); var endX = NotesLayerUtils.GetEndXByNotePosition(context.Bounds, nextSlideNote.Basic.FinishPosition); y = NotesLayerUtils.GetAvatarYPosition(context.Bounds); x = (float)((now - note.Temporary.HitTiming.TotalSeconds) / (nextSlideNote.Temporary.HitTiming.TotalSeconds - note.Temporary.HitTiming.TotalSeconds)) * (endX - startX) + startX; r = Definitions.AvatarCircleRadius; } } else { return; } DrawCommonNoteOutline(context, note, x, y, r); var isMidway = note.Helper.IsSlideMidway; var fillColors = isMidway ? SlideNoteShapeFillOuterTranslucentColors : SlideNoteShapeFillOuterColors; var r1 = r * Definitions.ScaleFactor1; using (var fill = GetFillBrush(x, y, r, fillColors)) { context.FillEllipse(fill, x - r1, y - r1, r1 * 2, r1 * 2); } var r2 = r * Definitions.ScaleFactor3; context.FillEllipse(_slideNoteShapeFillInner, x - r2, y - r2, r2 * 2, r2 * 2); var l = r * Definitions.SlideNoteStrikeHeightFactor; context.FillRectangle(_slideNoteShapeFillInner, x - r1 - 1, y - l, r1 * 2 + 2, l * 2); }
private void DrawFlickNote(Graphics context, double now, Note note) { if (!NotesLayerUtils.IsNoteOnStage(note, now)) { return; } if (note.Basic.FlickType == NoteFlickType.None) { Debug.Print("WARNING: Tap/hold/slide note requested in DrawFlickNote."); return; } float x = NotesLayerUtils.GetNoteXPosition(context, now, note), y = NotesLayerUtils.GetNoteYPosition(context, now, note), r = NotesLayerUtils.GetNoteRadius(now, note); DrawCommonNoteOutline(context, note, x, y, r); var flickType = note.Basic.FlickType; switch (flickType) { case NoteFlickType.Left: case NoteFlickType.Right: break; default: throw new ArgumentOutOfRangeException(nameof(flickType), "Unknown flick type for flick note rendering."); } var r1 = r * Definitions.ScaleFactor1; using (var fill = GetFillBrush(x, y, r1, FlickNoteShapeFillOuterColors)) { context.FillCircle(fill, x, y, r1); } context.DrawCircle(_flickNoteShapeStroke, x, y, r1); var r3 = r * Definitions.ScaleFactor2; // Triangle var polygon = new Vector2[3]; switch (flickType) { case NoteFlickType.Left: polygon[0] = new Vector2(x - r3, y); polygon[1] = new Vector2(x + r3 / 2, y + r3 / 2 * Definitions.Sqrt3); polygon[2] = new Vector2(x + r3 / 2, y - r3 / 2 * Definitions.Sqrt3); break; case NoteFlickType.Right: polygon[0] = new Vector2(x + r3, y); polygon[1] = new Vector2(x - r3 / 2, y - r3 / 2 * Definitions.Sqrt3); polygon[2] = new Vector2(x - r3 / 2, y + r3 / 2 * Definitions.Sqrt3); break; } context.FillPolygon(_flickNoteShapeFillInner, polygon); }
protected override void BuildVertices() { var now = Now; var context = RenderContext; var xs = new float[JointCount]; var ys = new float[JointCount]; var rs = new float[JointCount]; var x1 = NotesLayerUtils.GetNoteXPosition(context, now, StartNote, true, true); var x2 = NotesLayerUtils.GetNoteXPosition(context, now, EndNote, true, true); var y1 = NotesLayerUtils.GetNoteYPosition(context, now, StartNote, true, true); var y2 = NotesLayerUtils.GetNoteYPosition(context, now, EndNote, true, true); var r1 = NotesLayerUtils.GetNoteRadius(now, StartNote); var r2 = NotesLayerUtils.GetNoteRadius(now, EndNote); for (var i = 0; i < JointCount; ++i) { var t = (float)i / (JointCount - 1); xs[i] = MathHelper.Lerp(x1, x2, t); ys[i] = MathHelper.Lerp(y1, y2, t); rs[i] = MathHelper.Lerp(r1, r2, t); } for (var i = 0; i < JointCount; ++i) { var x = xs[i]; var y = ys[i]; var r = rs[i]; float ydif, xdif; if (i == JointCount - 1) { ydif = y - ys[i - 1]; xdif = x - xs[i - 1]; } else { ydif = ys[i + 1] - y; xdif = xs[i + 1] - x; } var rad = (float)Math.Atan2(ydif, xdif); var cos = (float)Math.Cos(rad); var sin = (float)Math.Sin(rad); var vertex1 = new Vector2(x - r * sin, y - r * cos); var vertex2 = new Vector2(x + r * sin, y + r * cos); Vertices[i * 2] = vertex1; Vertices[i * 2 + 1] = vertex2; } }
private void DrawSyncLine(Graphics context, double now, Note note1, Note note2) { if (!NotesLayerUtils.IsNoteOnStage(note1, now) || !NotesLayerUtils.IsNoteOnStage(note2, now)) { return; } float x1 = NotesLayerUtils.GetNoteXPosition(context, now, note1), y = NotesLayerUtils.GetNoteYPosition(context, now, note2), x2 = NotesLayerUtils.GetNoteXPosition(context, now, note2); var r = NotesLayerUtils.GetNoteRadius(now, note2); float xLeft = Math.Min(x1, x2), xRight = Math.Max(x1, x2); context.DrawLine(_syncLineStroke, xLeft + r, y, xRight - r, y); }
private void DrawHoldRibbon(Graphics context, double now, Note startNote, Note endNote) { OnStageStatus s1 = NotesLayerUtils.GetNoteOnStageStatus(startNote, now), s2 = NotesLayerUtils.GetNoteOnStageStatus(endNote, now); if (s1 == s2 && s1 != OnStageStatus.OnStage) { return; } var mesh = new HoldRibbonMesh(context, startNote, endNote, now); mesh.Initialize(); mesh.Fill(_ribbonBrush); }
private void DrawSlideRibbon(Graphics context, double now, Note startNote, Note endNote) { if (endNote.Helper.IsFlick) { DrawFlickRibbon(context, now, startNote, endNote); return; } if (!NotesLayerUtils.IsNoteComing(startNote, now) && !NotesLayerUtils.IsNotePassed(endNote, now)) { var mesh = new SlideRibbonMesh(context, startNote, endNote, now); mesh.Initialize(); mesh.Fill(_ribbonBrush); } }
private void DrawTapNote(Graphics context, double now, Note note) { if (!NotesLayerUtils.IsNoteOnStage(note, now)) { return; } float x = NotesLayerUtils.GetNoteXPosition(context, now, note), y = NotesLayerUtils.GetNoteYPosition(context, now, note), r = NotesLayerUtils.GetNoteRadius(now, note); DrawCommonNoteOutline(context, note, x, y, r); var r1 = r * Definitions.ScaleFactor1; using (var fill = GetFillBrush(x, y, r, TapNoteShapeFillColors)) { context.FillEllipse(fill, x - r1, y - r1, r1 * 2, r1 * 2); } context.DrawEllipse(_tapNoteShapeStroke, x - r1, y - r1, r1 * 2, r1 * 2); }
private void RenderAvatars(Graphics context) { var clientSize = context.Bounds; var yCenter = clientSize.Height * Definitions.BaseLineYPosition; var diameter = Definitions.AvatarCircleDiameter; var radius = Definitions.AvatarCircleRadius; var fill = _avatarFill; var stroke = _avatarBorderStroke; var xStart = NotesLayerUtils.GetAvatarXPosition(clientSize, NotePosition.Min) - diameter; var xEnd = NotesLayerUtils.GetAvatarXPosition(clientSize, NotePosition.Max) + diameter; context.DrawLine(stroke, xStart, yCenter, xEnd, yCenter); foreach (var position in Definitions.AvatarCenterXEndPositions) { var xCenter = clientSize.Width * position; context.FillCircle(fill, xCenter, yCenter, radius); context.DrawCircle(stroke, xCenter, yCenter, radius); } }
private void DrawNotes(Graphics context, double now, IEnumerable <Note> notes, int startIndex, int endIndex) { if (startIndex < 0) { return; } IEnumerable <Note> selectedNotes; if (endIndex >= 0) { selectedNotes = notes.Skip(startIndex).Take(endIndex - startIndex + 1); } else { selectedNotes = notes; } foreach (var note in selectedNotes) { switch (note.Basic.Type) { case NoteType.TapOrFlick: case NoteType.Hold: case NoteType.Slide: if (note.Helper.HasNextSync) { DrawSyncLine(context, now, note, note.Editor.NextSync); } break; } switch (note.Basic.Type) { case NoteType.TapOrFlick: if (note.Helper.IsFlick) { if (note.Helper.HasNextFlick) { DrawFlickRibbon(context, now, note, note.Editor.NextFlick); } } break; case NoteType.Hold: if (note.Helper.IsHoldStart) { DrawHoldRibbon(context, now, note, note.Editor.HoldPair); } if (note.Helper.IsHoldEnd) { if (!NotesLayerUtils.IsNoteOnStage(note.Editor.HoldPair, now)) { DrawHoldRibbon(context, now, note.Editor.HoldPair, note); } } break; case NoteType.Slide: if (note.Helper.HasNextSlide) { DrawSlideRibbon(context, now, note, note.Editor.NextSlide); } else if (note.Helper.HasNextFlick) { DrawSlideRibbon(context, now, note, note.Editor.NextFlick); } if (note.Helper.HasPrevSlide) { if (!NotesLayerUtils.IsNoteOnStage(note.Editor.PrevSlide, now)) { DrawSlideRibbon(context, now, note.Editor.PrevSlide, note); } } break; } switch (note.Basic.Type) { case NoteType.TapOrFlick: if (note.Basic.FlickType == NoteFlickType.None) { if (note.Helper.IsHoldEnd) { DrawHoldNote(context, now, note); } else { DrawTapNote(context, now, note); } } else { DrawFlickNote(context, now, note); } break; case NoteType.Hold: DrawHoldNote(context, now, note); break; case NoteType.Slide: if (note.Helper.HasNextFlick || (note.Helper.IsSlideEnd && note.Basic.FlickType != NoteFlickType.None)) { DrawFlickNote(context, now, note); } else if (note.Basic.FlickType != NoteFlickType.None) { DrawFlickNote(context, now, note); } else { DrawSlideNote(context, now, note); } break; } } }
private void Initialize() { var startTiming = StartNote.HitTiming; var endTiming = EndNote.HitTiming; var finishPosition = EndNote.FinishPosition; var now = Now; var context = RenderContext; var xs = new float[JointCount]; var ys = new float[JointCount]; var rs = new float[JointCount]; var rawConnection = ConnectionType & ConnectionType.RawMask; switch (rawConnection) { case ConnectionType.Hold: for (var i = 0; i < JointCount; ++i) { var timing = (endTiming - startTiming) / (JointCount - 1) * i + startTiming; xs[i] = NotesLayerUtils.GetNoteXPosition(context, now, timing, finishPosition, true, true); ys[i] = NotesLayerUtils.GetNoteYPosition(context, now, timing, true, true); rs[i] = NotesLayerUtils.GetNoteRadius(now, timing); } break; case ConnectionType.Flick: var x1 = NotesLayerUtils.GetNoteXPosition(context, now, StartNote, true, true); var x2 = NotesLayerUtils.GetNoteXPosition(context, now, EndNote, true, true); var y1 = NotesLayerUtils.GetNoteYPosition(context, now, StartNote, true, true); var y2 = NotesLayerUtils.GetNoteYPosition(context, now, EndNote, true, true); var r1 = NotesLayerUtils.GetNoteRadius(now, StartNote); var r2 = NotesLayerUtils.GetNoteRadius(now, EndNote); for (var i = 0; i < JointCount; ++i) { var t = (float)i / (JointCount - 1); xs[i] = D2DHelper.Lerp(x1, x2, t); ys[i] = D2DHelper.Lerp(y1, y2, t); rs[i] = D2DHelper.Lerp(r1, r2, t); } break; default: throw new ArgumentOutOfRangeException(nameof(rawConnection)); } for (var i = 0; i < JointCount; ++i) { var x = xs[i]; var y = ys[i]; var r = rs[i]; RawVector2 vertex1, vertex2; switch (rawConnection) { case ConnectionType.Hold: vertex1 = new RawVector2(x - r, y); vertex2 = new RawVector2(x + r, y); break; case ConnectionType.Flick: float ydif, xdif; if (i == JointCount - 1) { ydif = y - ys[i - 1]; xdif = x - xs[i - 1]; } else { ydif = ys[i + 1] - y; xdif = xs[i + 1] - x; } var rad = (float)Math.Atan2(ydif, xdif); var cos = (float)Math.Cos(rad); var sin = (float)Math.Sin(rad); vertex1 = new RawVector2(x - r * sin, y - r * cos); vertex2 = new RawVector2(x + r * sin, y + r * cos); break; default: throw new ArgumentOutOfRangeException(nameof(rawConnection)); } Vertices[i * 2] = vertex1; Vertices[i * 2 + 1] = vertex2; } }
protected override void BuildVertices() { var startTiming = StartNote.Temporary.HitTiming.TotalSeconds; var now = Now; var context = RenderContext; var xs = new float[JointCount]; var ys = new float[JointCount]; var rs = new float[JointCount]; var x2 = NotesLayerUtils.GetNoteXPosition(context, now, EndNote, true, true); var y2 = NotesLayerUtils.GetNoteYPosition(context, now, EndNote, true, true); var r2 = NotesLayerUtils.GetNoteRadius(now, EndNote); float x1, y1, r1; if (now <= startTiming) { x1 = NotesLayerUtils.GetNoteXPosition(context, now, StartNote, true, true); y1 = NotesLayerUtils.GetNoteYPosition(context, now, StartNote, true, true); r1 = NotesLayerUtils.GetNoteRadius(now, StartNote); } else { var startPosition = StartNote.Basic.FinishPosition; var endPosition = EndNote.Basic.FinishPosition; var tx1 = NotesLayerUtils.GetAvatarXPosition(context.Bounds, startPosition); var tx2 = NotesLayerUtils.GetAvatarXPosition(context.Bounds, endPosition); var endTiming = EndNote.Temporary.HitTiming.TotalSeconds; var tr = (float)(now - startTiming) / (float)(endTiming - startTiming); x1 = tx1 * (1 - tr) + tx2 * tr; y1 = NotesLayerUtils.GetAvatarYPosition(context.Bounds); r1 = Definitions.AvatarCircleRadius; } for (var i = 0; i < JointCount; ++i) { var t = (float)i / (JointCount - 1); xs[i] = MathHelper.Lerp(x1, x2, t); ys[i] = MathHelper.Lerp(y1, y2, t); rs[i] = MathHelper.Lerp(r1, r2, t); } var vertices = Vertices; for (var i = 0; i < JointCount; ++i) { var x = xs[i]; var y = ys[i]; var r = rs[i]; float ydif, xdif; if (i == JointCount - 1) { ydif = y - ys[i - 1]; xdif = x - xs[i - 1]; } else { ydif = ys[i + 1] - y; xdif = xs[i + 1] - x; } var rad = (float)Math.Atan2(ydif, xdif); var cos = (float)Math.Cos(rad); var sin = (float)Math.Sin(rad); var vertex1 = new Vector2(x - r * sin, y - r * cos); var vertex2 = new Vector2(x + r * sin, y + r * cos); vertices[i * 2] = vertex1; vertices[i * 2 + 1] = vertex2; } }