Rewrite VisualiserLine + add VisualiserContainer.

This commit is contained in:
smoogipooo 2017-03-03 15:43:16 +09:00
parent a70b1ae108
commit 777996d884
4 changed files with 213 additions and 225 deletions

View File

@ -0,0 +1,208 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Batches;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.OpenGL;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Shaders;
using osu.Framework.Graphics.Transforms;
using osu.Framework.MathUtils;
using osu.Framework.Timing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace osu.Game.Screens.Tournament.Components
{
class VisualiserContainer : Container
{
/// <summary>
/// Number of lines in the visualiser.
/// </summary>
public int Lines
{
get { return allLines.Count; }
set
{
while (value > allLines.Count)
addLine();
while (value < allLines.Count)
removeLine();
}
}
private List<VisualiserLine> allLines = new List<VisualiserLine>();
private float offset;
private void addLine()
{
VisualiserLine newLine = new VisualiserLine()
{
RelativeSizeAxes = Axes.Both,
PeriodOffset = offset,
Period = 2 * (float)Math.PI,
CycleTime = RNG.Next(10000, 12000)
};
allLines.Add(newLine);
Add(newLine);
offset += (float)Math.PI / 6f;
}
private void removeLine()
{
if (allLines.Count == 0)
return;
Remove(allLines.First());
allLines.Remove(allLines.First());
}
class VisualiserLine : Drawable
{
/// <summary>
/// Width of the line strokes.
/// </summary>
public float StrokeWidth = 1f;
/// <summary>
/// Height of the line strokes.
/// </summary>
public float StrokeHeight = 1f;
/// <summary>
/// Separation between strokes in the line.
/// </summary>
public float Separation = 0;
/// <summary>
/// Period offset of the line.
/// </summary>
public float PeriodOffset;
/// <summary>
/// Period of the line.
/// </summary>
public float Period;
/// <summary>
/// The time to cycle one period of the line in milliseconds.
/// </summary>
public double CycleTime;
private Shader shader;
private VisualiserLineDrawNodeSharedData visualiserLineDrawNodeSharedData => new VisualiserLineDrawNodeSharedData();
private float runningPeriodOffset;
protected override void Update()
{
base.Update();
if (CycleTime != 0)
{
runningPeriodOffset += (float)(Time.Elapsed / CycleTime) * Period;
Invalidate(Invalidation.DrawNode, shallPropagate: false);
}
}
protected override DrawNode CreateDrawNode() => new VisualiserLineDrawNode();
[BackgroundDependencyLoader]
private void load(ShaderManager shaders)
{
shader = shaders?.Load(VertexShaderDescriptor.Colour, @"DottedLine");
}
protected override void ApplyDrawNode(DrawNode node)
{
base.ApplyDrawNode(node);
VisualiserLineDrawNode vNode = node as VisualiserLineDrawNode;
vNode.Shader = shader;
vNode.Shared = visualiserLineDrawNodeSharedData;
vNode.ScreenSpaceDrawQuad = ScreenSpaceDrawQuad;
vNode.Period = Period;
vNode.PeriodOffset = PeriodOffset + runningPeriodOffset;
vNode.StrokeWidth = StrokeWidth;
vNode.StrokeHeight = StrokeHeight;
vNode.Separation = Separation;
}
class VisualiserLineDrawNodeSharedData
{
public QuadBatch<Vertex2D> QuadBatch = new QuadBatch<Vertex2D>(1, 1);
}
class VisualiserLineDrawNode : DrawNode
{
public Shader Shader;
public VisualiserLineDrawNodeSharedData Shared;
public Quad ScreenSpaceDrawQuad;
public float Period;
public float PeriodOffset;
public float StrokeWidth;
public float StrokeHeight;
public float Separation;
public override void Draw(Action<TexturedVertex2D> vertexAction)
{
base.Draw(vertexAction);
Shader.Bind();
Shader.GetUniform<Vector2>(@"g_Position").Value = ScreenSpaceDrawQuad.TopLeft;
Shader.GetUniform<Vector2>(@"g_Size").Value = ScreenSpaceDrawQuad.Size;
Shader.GetUniform<float>(@"g_Period").Value = Period;
Shader.GetUniform<float>(@"g_PeriodOffset").Value = PeriodOffset;
Shader.GetUniform<float>(@"g_StrokeWidth").Value = StrokeWidth;
Shader.GetUniform<float>(@"g_StrokeHeight").Value = StrokeHeight;
Shader.GetUniform<float>(@"g_Separation").Value = Separation;
Shared.QuadBatch.Add(new Vertex2D()
{
Position = ScreenSpaceDrawQuad.BottomLeft,
Colour = DrawInfo.Colour.BottomLeft.Linear
});
Shared.QuadBatch.Add(new Vertex2D()
{
Position = ScreenSpaceDrawQuad.BottomRight,
Colour = DrawInfo.Colour.BottomRight.Linear
});
Shared.QuadBatch.Add(new Vertex2D()
{
Position = ScreenSpaceDrawQuad.TopRight,
Colour = DrawInfo.Colour.TopRight.Linear
});
Shared.QuadBatch.Add(new Vertex2D()
{
Position = ScreenSpaceDrawQuad.TopLeft,
Colour = DrawInfo.Colour.TopLeft.Linear
});
Shader.Unbind();
}
}
}
}
}

View File

@ -1,209 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shaders;
using System;
using osu.Framework.Graphics.OpenGL;
using osu.Framework.Graphics.Batches;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Timing;
using osu.Framework.Graphics.Transforms;
namespace osu.Game.Screens.Tournament.Components
{
class VisualiserLine : Drawable
{
private float strokeWidth = 1;
public float StrokeWidth
{
get { return strokeWidth; }
set
{
if (strokeWidth == value)
return;
strokeWidth = value;
Invalidate(Invalidation.DrawNode, shallPropagate: false);
}
}
private float strokeHeight = 1;
public float StrokeHeight
{
get { return strokeHeight; }
set
{
if (strokeHeight == value)
return;
strokeHeight = value;
Invalidate(Invalidation.DrawNode, shallPropagate: false);
}
}
private float separation = 0;
public float Separation
{
get { return separation; }
set
{
if (separation == value)
return;
separation = value;
Invalidate(Invalidation.DrawNode, shallPropagate: false);
}
}
private Shader shader;
private VisualiserLineDrawNodeSharedData visualiserLineDrawNodeSharedData => new VisualiserLineDrawNodeSharedData();
/// <summary>
/// The period of this visualiser line, in radians.
/// </summary>
private float period;
/// <summary>
/// The period offset this line was constructed with, in radians.
/// </summary>
private readonly float initialPeriodOffset;
/// <summary>
/// The rolling period offset (by transformation), in radians.
/// </summary>
private float _periodOffset;
/// <summary>
/// The final period offset, in radians.
/// </summary>
private float periodOffset
{
get { return initialPeriodOffset + _periodOffset; }
set
{
if (_periodOffset == value)
return;
_periodOffset = value;
Invalidate(Invalidation.DrawNode, shallPropagate: false);
}
}
/// <summary>
/// Constructs a new Visualiser Line.
/// </summary>
/// <param name="period">The period of the line, in radians.</param>
/// <param name="periodOffset">The offset to the period of the line, in radians.</param>
/// <param name="cycleTime">The time to cycle the line.</param>
public VisualiserLine(float period, float periodOffset = 0, int cycleTime = 0)
{
this.period = period;
this.initialPeriodOffset = periodOffset;
Clock = new FramedClock();
if (cycleTime > 0)
TransformFloatTo(0, period, cycleTime, EasingTypes.None, new TransformVisualiserOffset());
Loop();
}
protected override DrawNode CreateDrawNode() => new VisualiserLineDrawNode();
[BackgroundDependencyLoader]
private void load(ShaderManager shaders)
{
shader = shaders?.Load(VertexShaderDescriptor.Colour, @"DottedLine");
}
protected override void ApplyDrawNode(DrawNode node)
{
base.ApplyDrawNode(node);
VisualiserLineDrawNode vNode = node as VisualiserLineDrawNode;
vNode.Shader = shader;
vNode.Shared = visualiserLineDrawNodeSharedData;
vNode.ScreenSpaceDrawQuad = ScreenSpaceDrawQuad;
vNode.Period = period;
vNode.PeriodOffset = periodOffset;
vNode.StrokeWidth = StrokeWidth;
vNode.StrokeHeight = StrokeHeight;
vNode.Separation = Separation;
}
class VisualiserLineDrawNodeSharedData
{
public QuadBatch<Vertex2D> QuadBatch = new QuadBatch<Vertex2D>(1, 1);
}
class VisualiserLineDrawNode : DrawNode
{
public Shader Shader;
public VisualiserLineDrawNodeSharedData Shared;
public Quad ScreenSpaceDrawQuad;
public float Period;
public float PeriodOffset;
public float StrokeWidth;
public float StrokeHeight;
public float Separation;
public override void Draw(Action<TexturedVertex2D> vertexAction)
{
base.Draw(vertexAction);
Shader.Bind();
Shader.GetUniform<Vector2>(@"g_Position").Value = ScreenSpaceDrawQuad.TopLeft;
Shader.GetUniform<Vector2>(@"g_Size").Value = ScreenSpaceDrawQuad.Size;
Shader.GetUniform<float>(@"g_Period").Value = Period;
Shader.GetUniform<float>(@"g_PeriodOffset").Value = PeriodOffset;
Shader.GetUniform<float>(@"g_StrokeWidth").Value = StrokeWidth;
Shader.GetUniform<float>(@"g_StrokeHeight").Value = StrokeHeight;
Shader.GetUniform<float>(@"g_Separation").Value = Separation;
Shared.QuadBatch.Add(new Vertex2D()
{
Position = ScreenSpaceDrawQuad.BottomLeft,
Colour = DrawInfo.Colour.BottomLeft.Linear
});
Shared.QuadBatch.Add(new Vertex2D()
{
Position = ScreenSpaceDrawQuad.BottomRight,
Colour = DrawInfo.Colour.BottomRight.Linear
});
Shared.QuadBatch.Add(new Vertex2D()
{
Position = ScreenSpaceDrawQuad.TopRight,
Colour = DrawInfo.Colour.TopRight.Linear
});
Shared.QuadBatch.Add(new Vertex2D()
{
Position = ScreenSpaceDrawQuad.TopLeft,
Colour = DrawInfo.Colour.TopLeft.Linear
});
Shader.Unbind();
}
}
class TransformVisualiserOffset : TransformFloat
{
public override void Apply(Drawable d)
{
base.Apply(d);
(d as VisualiserLine).periodOffset = CurrentValue;
}
}
}
}

View File

@ -60,8 +60,6 @@ namespace osu.Game.Screens.Tournament
drawingsConfig = new DrawingsConfigManager(storage);
Container visualiserContainer;
Children = new Drawable[]
{
new Box()
@ -90,7 +88,7 @@ namespace osu.Game.Screens.Tournament
Children = new Drawable[]
{
// Visualiser
visualiserContainer = new Container()
new VisualiserContainer()
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@ -98,7 +96,9 @@ namespace osu.Game.Screens.Tournament
RelativeSizeAxes = Axes.X,
Size = new Vector2(1, 10),
Colour = new Color4(255, 204, 34, 255)
Colour = new Color4(255, 204, 34, 255),
Lines = 6
},
// Groups
groupsContainer = new GroupsContainer(drawingsConfig.Get<int>(DrawingsConfig.Groups), drawingsConfig.Get<int>(DrawingsConfig.TeamsPerGroup))
@ -230,17 +230,6 @@ namespace osu.Game.Screens.Tournament
}
};
float offset = 0;
for (int i = 0; i < 6; i++)
{
visualiserContainer.Add(new VisualiserLine(2 * (float)Math.PI, offset, RNG.Next(10000, 12000))
{
RelativeSizeAxes = Axes.Both,
});
offset += (float)Math.PI / 6f;
}
teamsContainer.OnSelected += onTeamSelected;
teamsContainer.OnScrollStarted += () => fullTeamNameText.FadeOut(200);

View File

@ -212,7 +212,7 @@
<Compile Include="Screens\Select\BeatmapInfoWedge.cs" />
<Compile Include="Screens\Select\WedgeBackground.cs" />
<Compile Include="Screens\Tournament\Components\DrawingsConfigManager.cs" />
<Compile Include="Screens\Tournament\Components\VisualiserLine.cs" />
<Compile Include="Screens\Tournament\Components\VisualiserContainer.cs" />
<Compile Include="Screens\Tournament\Drawings.cs" />
<Compile Include="Screens\Tournament\Group.cs" />
<Compile Include="Screens\Tournament\GroupsContainer.cs" />