mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 02:32:55 +08:00
Remove other grid types
This commit is contained in:
parent
39f4a1aa8e
commit
de14da95fa
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
@ -101,8 +100,6 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
|||||||
return grid switch
|
return grid switch
|
||||||
{
|
{
|
||||||
RectangularPositionSnapGrid rectangular => rectangular.StartPosition.Value + GeometryUtils.RotateVector(rectangular.Spacing.Value, -rectangular.GridLineRotation.Value),
|
RectangularPositionSnapGrid rectangular => rectangular.StartPosition.Value + GeometryUtils.RotateVector(rectangular.Spacing.Value, -rectangular.GridLineRotation.Value),
|
||||||
TriangularPositionSnapGrid triangular => triangular.StartPosition.Value + GeometryUtils.RotateVector(new Vector2(triangular.Spacing.Value / 2, triangular.Spacing.Value / 2 * MathF.Sqrt(3)), -triangular.GridLineRotation.Value),
|
|
||||||
CircularPositionSnapGrid circular => circular.StartPosition.Value + GeometryUtils.RotateVector(new Vector2(circular.Spacing.Value, 0), -45),
|
|
||||||
_ => Vector2.Zero
|
_ => Vector2.Zero
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
@ -16,9 +12,7 @@ using osu.Game.Input.Bindings;
|
|||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
using osu.Game.Screens.Edit.Components.RadioButtons;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Edit
|
namespace osu.Game.Rulesets.Osu.Edit
|
||||||
{
|
{
|
||||||
@ -82,13 +76,10 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Bindable<Vector2> SpacingVector { get; } = new Bindable<Vector2>();
|
public Bindable<Vector2> SpacingVector { get; } = new Bindable<Vector2>();
|
||||||
|
|
||||||
public Bindable<PositionSnapGridType> GridType { get; } = new Bindable<PositionSnapGridType>();
|
|
||||||
|
|
||||||
private ExpandableSlider<float> startPositionXSlider = null!;
|
private ExpandableSlider<float> startPositionXSlider = null!;
|
||||||
private ExpandableSlider<float> startPositionYSlider = null!;
|
private ExpandableSlider<float> startPositionYSlider = null!;
|
||||||
private ExpandableSlider<float> spacingSlider = null!;
|
private ExpandableSlider<float> spacingSlider = null!;
|
||||||
private ExpandableSlider<float> gridLinesRotationSlider = null!;
|
private ExpandableSlider<float> gridLinesRotationSlider = null!;
|
||||||
private EditorRadioButtonCollection gridTypeButtons = null!;
|
|
||||||
|
|
||||||
public OsuGridToolboxGroup()
|
public OsuGridToolboxGroup()
|
||||||
: base("grid")
|
: base("grid")
|
||||||
@ -122,31 +113,6 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
Current = GridLinesRotation,
|
Current = GridLinesRotation,
|
||||||
KeyboardStep = 1,
|
KeyboardStep = 1,
|
||||||
},
|
},
|
||||||
new FillFlowContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
Spacing = new Vector2(0f, 10f),
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
gridTypeButtons = new EditorRadioButtonCollection
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Items = new[]
|
|
||||||
{
|
|
||||||
new RadioButton("Square",
|
|
||||||
() => GridType.Value = PositionSnapGridType.Square,
|
|
||||||
() => new SpriteIcon { Icon = FontAwesome.Regular.Square }),
|
|
||||||
new RadioButton("Triangle",
|
|
||||||
() => GridType.Value = PositionSnapGridType.Triangle,
|
|
||||||
() => new OutlineTriangle(true, 20)),
|
|
||||||
new RadioButton("Circle",
|
|
||||||
() => GridType.Value = PositionSnapGridType.Circle,
|
|
||||||
() => new SpriteIcon { Icon = FontAwesome.Regular.Circle }),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Spacing.Value = editorBeatmap.BeatmapInfo.GridSize;
|
Spacing.Value = editorBeatmap.BeatmapInfo.GridSize;
|
||||||
@ -156,8 +122,6 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
gridTypeButtons.Items.First().Select();
|
|
||||||
|
|
||||||
StartPositionX.BindValueChanged(x =>
|
StartPositionX.BindValueChanged(x =>
|
||||||
{
|
{
|
||||||
startPositionXSlider.ContractedLabelText = $"X: {x.NewValue:N0}";
|
startPositionXSlider.ContractedLabelText = $"X: {x.NewValue:N0}";
|
||||||
@ -185,12 +149,6 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
gridLinesRotationSlider.ContractedLabelText = $"R: {rotation.NewValue:#,0.##}";
|
gridLinesRotationSlider.ContractedLabelText = $"R: {rotation.NewValue:#,0.##}";
|
||||||
gridLinesRotationSlider.ExpandedLabelText = $"Rotation: {rotation.NewValue:#,0.##}";
|
gridLinesRotationSlider.ExpandedLabelText = $"Rotation: {rotation.NewValue:#,0.##}";
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
expandingContainer?.Expanded.BindValueChanged(v =>
|
|
||||||
{
|
|
||||||
gridTypeButtons.FadeTo(v.NewValue ? 1f : 0f, 500, Easing.OutQuint);
|
|
||||||
gridTypeButtons.BypassAutoSizeAxes = !v.NewValue ? Axes.Y : Axes.None;
|
|
||||||
}, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void nextGridSize()
|
private void nextGridSize()
|
||||||
@ -213,42 +171,5 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
public void OnReleased(KeyBindingReleaseEvent<GlobalAction> e)
|
public void OnReleased(KeyBindingReleaseEvent<GlobalAction> e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class OutlineTriangle : BufferedContainer
|
|
||||||
{
|
|
||||||
public OutlineTriangle(bool outlineOnly, float size)
|
|
||||||
: base(cachedFrameBuffer: true)
|
|
||||||
{
|
|
||||||
Size = new Vector2(size);
|
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
|
||||||
{
|
|
||||||
new EquilateralTriangle { RelativeSizeAxes = Axes.Both },
|
|
||||||
};
|
|
||||||
|
|
||||||
if (outlineOnly)
|
|
||||||
{
|
|
||||||
AddInternal(new EquilateralTriangle
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
RelativePositionAxes = Axes.Y,
|
|
||||||
Y = 0.48f,
|
|
||||||
Colour = Color4.Black,
|
|
||||||
Size = new Vector2(size - 7),
|
|
||||||
Blending = BlendingParameters.None,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Blending = BlendingParameters.Additive;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum PositionSnapGridType
|
|
||||||
{
|
|
||||||
Square,
|
|
||||||
Triangle,
|
|
||||||
Circle,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
// we may be entering the screen with a selection already active
|
// we may be entering the screen with a selection already active
|
||||||
updateDistanceSnapGrid();
|
updateDistanceSnapGrid();
|
||||||
|
|
||||||
OsuGridToolboxGroup.GridType.BindValueChanged(updatePositionSnapGrid, true);
|
updatePositionSnapGrid();
|
||||||
|
|
||||||
RightToolbox.AddRange(new EditorToolboxGroup[]
|
RightToolbox.AddRange(new EditorToolboxGroup[]
|
||||||
{
|
{
|
||||||
@ -110,45 +110,18 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updatePositionSnapGrid(ValueChangedEvent<PositionSnapGridType> obj)
|
private void updatePositionSnapGrid()
|
||||||
{
|
{
|
||||||
if (positionSnapGrid != null)
|
if (positionSnapGrid != null)
|
||||||
LayerBelowRuleset.Remove(positionSnapGrid, true);
|
LayerBelowRuleset.Remove(positionSnapGrid, true);
|
||||||
|
|
||||||
switch (obj.NewValue)
|
|
||||||
{
|
|
||||||
case PositionSnapGridType.Square:
|
|
||||||
var rectangularPositionSnapGrid = new RectangularPositionSnapGrid();
|
var rectangularPositionSnapGrid = new RectangularPositionSnapGrid();
|
||||||
|
|
||||||
|
rectangularPositionSnapGrid.StartPosition.BindTo(OsuGridToolboxGroup.StartPosition);
|
||||||
rectangularPositionSnapGrid.Spacing.BindTo(OsuGridToolboxGroup.SpacingVector);
|
rectangularPositionSnapGrid.Spacing.BindTo(OsuGridToolboxGroup.SpacingVector);
|
||||||
rectangularPositionSnapGrid.GridLineRotation.BindTo(OsuGridToolboxGroup.GridLinesRotation);
|
rectangularPositionSnapGrid.GridLineRotation.BindTo(OsuGridToolboxGroup.GridLinesRotation);
|
||||||
|
|
||||||
positionSnapGrid = rectangularPositionSnapGrid;
|
positionSnapGrid = rectangularPositionSnapGrid;
|
||||||
break;
|
|
||||||
|
|
||||||
case PositionSnapGridType.Triangle:
|
|
||||||
var triangularPositionSnapGrid = new TriangularPositionSnapGrid();
|
|
||||||
|
|
||||||
triangularPositionSnapGrid.Spacing.BindTo(OsuGridToolboxGroup.Spacing);
|
|
||||||
triangularPositionSnapGrid.GridLineRotation.BindTo(OsuGridToolboxGroup.GridLinesRotation);
|
|
||||||
|
|
||||||
positionSnapGrid = triangularPositionSnapGrid;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PositionSnapGridType.Circle:
|
|
||||||
var circularPositionSnapGrid = new CircularPositionSnapGrid();
|
|
||||||
|
|
||||||
circularPositionSnapGrid.Spacing.BindTo(OsuGridToolboxGroup.Spacing);
|
|
||||||
|
|
||||||
positionSnapGrid = circularPositionSnapGrid;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{OsuGridToolboxGroup.GridType} has an incorrect value.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind the start position to the toolbox sliders.
|
|
||||||
positionSnapGrid.StartPosition.BindTo(OsuGridToolboxGroup.StartPosition);
|
|
||||||
|
|
||||||
positionSnapGrid.RelativeSizeAxes = Axes.Both;
|
positionSnapGrid.RelativeSizeAxes = Axes.Both;
|
||||||
LayerBelowRuleset.Add(positionSnapGrid);
|
LayerBelowRuleset.Add(positionSnapGrid);
|
||||||
|
@ -70,51 +70,6 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCaseSource(nameof(test_cases))]
|
|
||||||
public void TestTriangularGrid(Vector2 position, Vector2 spacing, float rotation)
|
|
||||||
{
|
|
||||||
TriangularPositionSnapGrid grid = null;
|
|
||||||
|
|
||||||
AddStep("create grid", () =>
|
|
||||||
{
|
|
||||||
Child = grid = new TriangularPositionSnapGrid
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
};
|
|
||||||
grid.StartPosition.Value = position;
|
|
||||||
grid.Spacing.Value = spacing.X;
|
|
||||||
grid.GridLineRotation.Value = rotation;
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep("add snapping cursor", () => Add(new SnappingCursorContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
GetSnapPosition = pos => grid.GetSnappedPosition(grid.ToLocalSpace(pos))
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCaseSource(nameof(test_cases))]
|
|
||||||
public void TestCircularGrid(Vector2 position, Vector2 spacing, float rotation)
|
|
||||||
{
|
|
||||||
CircularPositionSnapGrid grid = null;
|
|
||||||
|
|
||||||
AddStep("create grid", () =>
|
|
||||||
{
|
|
||||||
Child = grid = new CircularPositionSnapGrid
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
};
|
|
||||||
grid.StartPosition.Value = position;
|
|
||||||
grid.Spacing.Value = spacing.X;
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep("add snapping cursor", () => Add(new SnappingCursorContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
GetSnapPosition = pos => grid.GetSnappedPosition(grid.ToLocalSpace(pos))
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
private partial class SnappingCursorContainer : CompositeDrawable
|
private partial class SnappingCursorContainer : CompositeDrawable
|
||||||
{
|
{
|
||||||
public Func<Vector2, Vector2> GetSnapPosition;
|
public Func<Vector2, Vector2> GetSnapPosition;
|
||||||
|
@ -1,101 +0,0 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
|
||||||
using osu.Framework.Utils;
|
|
||||||
using osuTK;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Compose.Components
|
|
||||||
{
|
|
||||||
public partial class CircularPositionSnapGrid : PositionSnapGrid
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The spacing between grid lines of this <see cref="CircularPositionSnapGrid"/>.
|
|
||||||
/// </summary>
|
|
||||||
public BindableFloat Spacing { get; } = new BindableFloat(1f)
|
|
||||||
{
|
|
||||||
MinValue = 0f,
|
|
||||||
};
|
|
||||||
|
|
||||||
public CircularPositionSnapGrid()
|
|
||||||
{
|
|
||||||
Spacing.BindValueChanged(_ => GridCache.Invalidate());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void CreateContent()
|
|
||||||
{
|
|
||||||
var drawSize = DrawSize;
|
|
||||||
|
|
||||||
// Calculate the maximum distance from the origin to the edge of the grid.
|
|
||||||
float maxDist = MathF.Max(
|
|
||||||
MathF.Max(StartPosition.Value.Length, (StartPosition.Value - drawSize).Length),
|
|
||||||
MathF.Max((StartPosition.Value - new Vector2(drawSize.X, 0)).Length, (StartPosition.Value - new Vector2(0, drawSize.Y)).Length)
|
|
||||||
);
|
|
||||||
|
|
||||||
generateCircles((int)(maxDist / Spacing.Value) + 1);
|
|
||||||
|
|
||||||
GenerateOutline(drawSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateCircles(int count)
|
|
||||||
{
|
|
||||||
// Make lines the same width independent of display resolution.
|
|
||||||
float lineWidth = 2 * DrawWidth / ScreenSpaceDrawQuad.Width;
|
|
||||||
|
|
||||||
List<CircularContainer> generatedCircles = new List<CircularContainer>();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
// Add a minimum diameter so the center circle is clearly visible.
|
|
||||||
float diameter = MathF.Max(lineWidth * 1.5f, i * Spacing.Value * 2);
|
|
||||||
|
|
||||||
var gridCircle = new CircularContainer
|
|
||||||
{
|
|
||||||
BorderColour = Colour4.White,
|
|
||||||
BorderThickness = lineWidth,
|
|
||||||
Alpha = 0.2f,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
RelativeSizeAxes = Axes.None,
|
|
||||||
Width = diameter,
|
|
||||||
Height = diameter,
|
|
||||||
Position = StartPosition.Value,
|
|
||||||
Masking = true,
|
|
||||||
Child = new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
AlwaysPresent = true,
|
|
||||||
Alpha = 0f,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
generatedCircles.Add(gridCircle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (generatedCircles.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
generatedCircles.First().Alpha = 0.8f;
|
|
||||||
|
|
||||||
AddRangeInternal(generatedCircles);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Vector2 GetSnappedPosition(Vector2 original)
|
|
||||||
{
|
|
||||||
Vector2 relativeToStart = original - StartPosition.Value;
|
|
||||||
|
|
||||||
if (relativeToStart.LengthSquared < Precision.FLOAT_EPSILON)
|
|
||||||
return StartPosition.Value;
|
|
||||||
|
|
||||||
float length = relativeToStart.Length;
|
|
||||||
float wantedLength = MathF.Round(length / Spacing.Value) * Spacing.Value;
|
|
||||||
|
|
||||||
return StartPosition.Value + Vector2.Multiply(relativeToStart, wantedLength / length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Game.Utils;
|
|
||||||
using osuTK;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Compose.Components
|
|
||||||
{
|
|
||||||
public partial class TriangularPositionSnapGrid : LinedPositionSnapGrid
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The spacing between grid lines of this <see cref="TriangularPositionSnapGrid"/>.
|
|
||||||
/// </summary>
|
|
||||||
public BindableFloat Spacing { get; } = new BindableFloat(1f)
|
|
||||||
{
|
|
||||||
MinValue = 0f,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The rotation in degrees of the grid lines of this <see cref="TriangularPositionSnapGrid"/>.
|
|
||||||
/// </summary>
|
|
||||||
public BindableFloat GridLineRotation { get; } = new BindableFloat();
|
|
||||||
|
|
||||||
public TriangularPositionSnapGrid()
|
|
||||||
{
|
|
||||||
Spacing.BindValueChanged(_ => GridCache.Invalidate());
|
|
||||||
GridLineRotation.BindValueChanged(_ => GridCache.Invalidate());
|
|
||||||
}
|
|
||||||
|
|
||||||
private const float sqrt3 = 1.73205080757f;
|
|
||||||
private const float sqrt3_over2 = 0.86602540378f;
|
|
||||||
private const float one_over_sqrt3 = 0.57735026919f;
|
|
||||||
|
|
||||||
protected override void CreateContent()
|
|
||||||
{
|
|
||||||
var drawSize = DrawSize;
|
|
||||||
float stepSpacing = Spacing.Value * sqrt3_over2;
|
|
||||||
var step1 = GeometryUtils.RotateVector(new Vector2(stepSpacing, 0), -GridLineRotation.Value - 30);
|
|
||||||
var step2 = GeometryUtils.RotateVector(new Vector2(stepSpacing, 0), -GridLineRotation.Value - 90);
|
|
||||||
var step3 = GeometryUtils.RotateVector(new Vector2(stepSpacing, 0), -GridLineRotation.Value - 150);
|
|
||||||
|
|
||||||
GenerateGridLines(step1, drawSize);
|
|
||||||
GenerateGridLines(-step1, drawSize);
|
|
||||||
|
|
||||||
GenerateGridLines(step2, drawSize);
|
|
||||||
GenerateGridLines(-step2, drawSize);
|
|
||||||
|
|
||||||
GenerateGridLines(step3, drawSize);
|
|
||||||
GenerateGridLines(-step3, drawSize);
|
|
||||||
|
|
||||||
GenerateOutline(drawSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Vector2 GetSnappedPosition(Vector2 original)
|
|
||||||
{
|
|
||||||
Vector2 relativeToStart = GeometryUtils.RotateVector(original - StartPosition.Value, GridLineRotation.Value);
|
|
||||||
Vector2 hex = pixelToHex(relativeToStart);
|
|
||||||
|
|
||||||
return StartPosition.Value + GeometryUtils.RotateVector(hexToPixel(hex), -GridLineRotation.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Vector2 pixelToHex(Vector2 pixel)
|
|
||||||
{
|
|
||||||
float x = pixel.X / Spacing.Value;
|
|
||||||
float y = pixel.Y / Spacing.Value;
|
|
||||||
// Algorithm from Charles Chambers
|
|
||||||
// with modifications and comments by Chris Cox 2023
|
|
||||||
// <https://gitlab.com/chriscox/hex-coordinates>
|
|
||||||
float t = sqrt3 * y + 1; // scaled y, plus phase
|
|
||||||
float temp1 = MathF.Floor(t + x); // (y+x) diagonal, this calc needs floor
|
|
||||||
float temp2 = t - x; // (y-x) diagonal, no floor needed
|
|
||||||
float temp3 = 2 * x + 1; // scaled horizontal, no floor needed, needs +1 to get correct phase
|
|
||||||
float qf = (temp1 + temp3) / 3.0f; // pseudo x with fraction
|
|
||||||
float rf = (temp1 + temp2) / 3.0f; // pseudo y with fraction
|
|
||||||
float q = MathF.Floor(qf); // pseudo x, quantized and thus requires floor
|
|
||||||
float r = MathF.Floor(rf); // pseudo y, quantized and thus requires floor
|
|
||||||
return new Vector2(q, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Vector2 hexToPixel(Vector2 hex)
|
|
||||||
{
|
|
||||||
// Taken from <https://www.redblobgames.com/grids/hexagons/#hex-to-pixel>
|
|
||||||
// with modifications for the different definition of size.
|
|
||||||
return new Vector2(Spacing.Value * (hex.X - hex.Y / 2), Spacing.Value * one_over_sqrt3 * 1.5f * hex.Y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user