mirror of
https://github.com/ppy/osu.git
synced 2025-01-09 21:12:55 +08:00
Merge pull request #30214 from minetoblend/feat/optimize-polygon-tool
Fix slow performance of polygon generation tool
This commit is contained in:
commit
de250d5ac1
@ -50,9 +50,14 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private HitObjectComposer composer { get; set; } = null!;
|
private HitObjectComposer composer { get; set; } = null!;
|
||||||
|
|
||||||
|
private Bindable<TernaryState> newComboState = null!;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
var selectionHandler = (EditorSelectionHandler)composer.BlueprintContainer.SelectionHandler;
|
||||||
|
newComboState = selectionHandler.SelectionNewComboState.GetBoundCopy();
|
||||||
|
|
||||||
AllowableAnchors = new[] { Anchor.CentreLeft, Anchor.CentreRight };
|
AllowableAnchors = new[] { Anchor.CentreLeft, Anchor.CentreRight };
|
||||||
|
|
||||||
Child = new FillFlowContainer
|
Child = new FillFlowContainer
|
||||||
@ -120,10 +125,11 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
changeHandler?.BeginChange();
|
changeHandler?.BeginChange();
|
||||||
began = true;
|
began = true;
|
||||||
|
|
||||||
distanceSnapInput.Current.BindValueChanged(_ => tryCreatePolygon());
|
distanceSnapInput.Current.BindValueChanged(_ => Scheduler.AddOnce(tryCreatePolygon));
|
||||||
offsetAngleInput.Current.BindValueChanged(_ => tryCreatePolygon());
|
offsetAngleInput.Current.BindValueChanged(_ => Scheduler.AddOnce(tryCreatePolygon));
|
||||||
repeatCountInput.Current.BindValueChanged(_ => tryCreatePolygon());
|
repeatCountInput.Current.BindValueChanged(_ => Scheduler.AddOnce(tryCreatePolygon));
|
||||||
pointInput.Current.BindValueChanged(_ => tryCreatePolygon());
|
pointInput.Current.BindValueChanged(_ => Scheduler.AddOnce(tryCreatePolygon));
|
||||||
|
newComboState.BindValueChanged(_ => Scheduler.AddOnce(tryCreatePolygon));
|
||||||
tryCreatePolygon();
|
tryCreatePolygon();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,39 +144,69 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
double length = distanceSnapInput.Current.Value * velocity * timeSpacing;
|
double length = distanceSnapInput.Current.Value * velocity * timeSpacing;
|
||||||
float polygonRadius = (float)(length / (2 * Math.Sin(double.Pi / pointInput.Current.Value)));
|
float polygonRadius = (float)(length / (2 * Math.Sin(double.Pi / pointInput.Current.Value)));
|
||||||
|
|
||||||
editorBeatmap.RemoveRange(insertedCircles);
|
int totalPoints = pointInput.Current.Value * repeatCountInput.Current.Value;
|
||||||
insertedCircles.Clear();
|
|
||||||
|
|
||||||
var selectionHandler = (EditorSelectionHandler)composer.BlueprintContainer.SelectionHandler;
|
if (insertedCircles.Count > totalPoints)
|
||||||
bool first = true;
|
|
||||||
|
|
||||||
for (int i = 1; i <= pointInput.Current.Value * repeatCountInput.Current.Value; ++i)
|
|
||||||
{
|
{
|
||||||
float angle = float.DegreesToRadians(offsetAngleInput.Current.Value) + i * (2 * float.Pi / pointInput.Current.Value);
|
editorBeatmap.RemoveRange(insertedCircles.GetRange(totalPoints, insertedCircles.Count - totalPoints));
|
||||||
var position = OsuPlayfield.BASE_SIZE / 2 + new Vector2(polygonRadius * float.Cos(angle), polygonRadius * float.Sin(angle));
|
insertedCircles.RemoveRange(totalPoints, insertedCircles.Count - totalPoints);
|
||||||
|
}
|
||||||
|
|
||||||
var circle = new HitCircle
|
var newlyAdded = new List<HitCircle>();
|
||||||
|
|
||||||
|
for (int i = 0; i < totalPoints; ++i)
|
||||||
|
{
|
||||||
|
float angle = float.DegreesToRadians(offsetAngleInput.Current.Value) + (i + 1) * (2 * float.Pi / pointInput.Current.Value);
|
||||||
|
var position = OsuPlayfield.BASE_SIZE / 2 + new Vector2(polygonRadius * float.Cos(angle), polygonRadius * float.Sin(angle));
|
||||||
|
bool newCombo = i == 0 && newComboState.Value == TernaryState.True;
|
||||||
|
|
||||||
|
HitCircle circle;
|
||||||
|
|
||||||
|
if (i < insertedCircles.Count)
|
||||||
|
{
|
||||||
|
circle = insertedCircles[i];
|
||||||
|
|
||||||
|
circle.Position = position;
|
||||||
|
circle.StartTime = startTime;
|
||||||
|
circle.NewCombo = newCombo;
|
||||||
|
|
||||||
|
editorBeatmap.Update(circle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
circle = new HitCircle
|
||||||
{
|
{
|
||||||
Position = position,
|
Position = position,
|
||||||
StartTime = startTime,
|
StartTime = startTime,
|
||||||
NewCombo = first && selectionHandler.SelectionNewComboState.Value == TernaryState.True,
|
NewCombo = newCombo,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
newlyAdded.Add(circle);
|
||||||
|
|
||||||
// TODO: probably ensure samples also follow current ternary status (not trivial)
|
// TODO: probably ensure samples also follow current ternary status (not trivial)
|
||||||
circle.Samples.Add(circle.CreateHitSampleInfo());
|
circle.Samples.Add(circle.CreateHitSampleInfo());
|
||||||
|
}
|
||||||
|
|
||||||
if (position.X < 0 || position.Y < 0 || position.X > OsuPlayfield.BASE_SIZE.X || position.Y > OsuPlayfield.BASE_SIZE.Y)
|
if (position.X < 0 || position.Y < 0 || position.X > OsuPlayfield.BASE_SIZE.X || position.Y > OsuPlayfield.BASE_SIZE.Y)
|
||||||
{
|
{
|
||||||
commitButton.Enabled.Value = false;
|
commitButton.Enabled.Value = false;
|
||||||
|
editorBeatmap.RemoveRange(insertedCircles);
|
||||||
|
insertedCircles.Clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
insertedCircles.Add(circle);
|
|
||||||
startTime = beatSnapProvider.SnapTime(startTime + timeSpacing);
|
startTime = beatSnapProvider.SnapTime(startTime + timeSpacing);
|
||||||
|
|
||||||
first = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
editorBeatmap.AddRange(insertedCircles);
|
var previousNewComboState = newComboState.Value;
|
||||||
|
|
||||||
|
insertedCircles.AddRange(newlyAdded);
|
||||||
|
editorBeatmap.AddRange(newlyAdded);
|
||||||
|
|
||||||
|
// When adding new hitObjects, newCombo state will get reset to false when no objects are selected.
|
||||||
|
// Since this is the case when this popover is showing, we need to restore the previous newCombo state
|
||||||
|
newComboState.Value = previousNewComboState;
|
||||||
|
|
||||||
commitButton.Enabled.Value = true;
|
commitButton.Enabled.Value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,6 +258,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
|
|
||||||
private void resetTernaryStates()
|
private void resetTernaryStates()
|
||||||
{
|
{
|
||||||
|
if (SelectionNewComboState.Value == TernaryState.Indeterminate)
|
||||||
|
SelectionNewComboState.Value = TernaryState.False;
|
||||||
AutoSelectionBankEnabled.Value = true;
|
AutoSelectionBankEnabled.Value = true;
|
||||||
SelectionAdditionBanksEnabled.Value = true;
|
SelectionAdditionBanksEnabled.Value = true;
|
||||||
SelectionBankStates[HIT_BANK_AUTO].Value = TernaryState.True;
|
SelectionBankStates[HIT_BANK_AUTO].Value = TernaryState.True;
|
||||||
@ -269,6 +271,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void UpdateTernaryStates()
|
protected virtual void UpdateTernaryStates()
|
||||||
{
|
{
|
||||||
|
if (SelectedItems.Any())
|
||||||
SelectionNewComboState.Value = GetStateFromSelection(SelectedItems.OfType<IHasComboInformation>(), h => h.NewCombo);
|
SelectionNewComboState.Value = GetStateFromSelection(SelectedItems.OfType<IHasComboInformation>(), h => h.NewCombo);
|
||||||
AutoSelectionBankEnabled.Value = SelectedItems.Count == 0;
|
AutoSelectionBankEnabled.Value = SelectedItems.Count == 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user