mirror of
https://github.com/osukey/osukey.git
synced 2025-07-02 08:49:59 +09:00
Compute lifetime from entry in scrolling container
This commit is contained in:
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
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.Primitives;
|
||||||
using osu.Framework.Layout;
|
using osu.Framework.Layout;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
@ -127,6 +127,16 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
|
|
||||||
private float scrollLength => scrollingAxis == Direction.Horizontal ? DrawWidth : DrawHeight;
|
private float scrollLength => scrollingAxis == Direction.Horizontal ? DrawWidth : DrawHeight;
|
||||||
|
|
||||||
|
public override void Add(HitObjectLifetimeEntry entry)
|
||||||
|
{
|
||||||
|
// Scroll info is not available until loaded.
|
||||||
|
// The lifetime of all entries will be updated in the first Update.
|
||||||
|
if (IsLoaded)
|
||||||
|
setComputedLifetimeStart(entry);
|
||||||
|
|
||||||
|
base.Add(entry);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void AddDrawable(HitObjectLifetimeEntry entry, DrawableHitObject drawable)
|
protected override void AddDrawable(HitObjectLifetimeEntry entry, DrawableHitObject drawable)
|
||||||
{
|
{
|
||||||
base.AddDrawable(entry, drawable);
|
base.AddDrawable(entry, drawable);
|
||||||
@ -145,7 +155,6 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
|
|
||||||
private void invalidateHitObject(DrawableHitObject hitObject)
|
private void invalidateHitObject(DrawableHitObject hitObject)
|
||||||
{
|
{
|
||||||
hitObject.LifetimeStart = computeOriginAdjustedLifetimeStart(hitObject);
|
|
||||||
layoutComputed.Remove(hitObject);
|
layoutComputed.Remove(hitObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,10 +166,8 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
|
|
||||||
layoutComputed.Clear();
|
layoutComputed.Clear();
|
||||||
|
|
||||||
// Reset lifetime to the conservative estimation.
|
|
||||||
// If a drawable becomes alive by this lifetime, its lifetime will be updated to a more precise lifetime in the next update.
|
|
||||||
foreach (var entry in Entries)
|
foreach (var entry in Entries)
|
||||||
entry.SetInitialLifetime();
|
setComputedLifetimeStart(entry);
|
||||||
|
|
||||||
scrollingInfo.Algorithm.Reset();
|
scrollingInfo.Algorithm.Reset();
|
||||||
|
|
||||||
@ -187,38 +194,46 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private double computeOriginAdjustedLifetimeStart(DrawableHitObject hitObject)
|
/// <summary>
|
||||||
|
/// Get a conservative maximum bounding box of a <see cref="DrawableHitObject"/> corresponding to <paramref name="entry"/>.
|
||||||
|
/// It is used to calculate when the hit object appears.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual RectangleF GetConservativeBoundingBox(HitObjectLifetimeEntry entry) => new RectangleF().Inflate(100);
|
||||||
|
|
||||||
|
private double computeDisplayStartTime(HitObjectLifetimeEntry entry)
|
||||||
{
|
{
|
||||||
// Origin position may be relative to the parent size
|
RectangleF boundingBox = GetConservativeBoundingBox(entry);
|
||||||
Debug.Assert(hitObject.Parent != null);
|
float startOffset = 0;
|
||||||
|
|
||||||
float originAdjustment = 0.0f;
|
|
||||||
|
|
||||||
// calculate the dimension of the part of the hitobject that should already be visible
|
|
||||||
// when the hitobject origin first appears inside the scrolling container
|
|
||||||
switch (direction.Value)
|
switch (direction.Value)
|
||||||
{
|
{
|
||||||
case ScrollingDirection.Up:
|
case ScrollingDirection.Right:
|
||||||
originAdjustment = hitObject.OriginPosition.Y;
|
startOffset = boundingBox.Right;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ScrollingDirection.Down:
|
case ScrollingDirection.Down:
|
||||||
originAdjustment = hitObject.DrawHeight - hitObject.OriginPosition.Y;
|
startOffset = boundingBox.Bottom;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ScrollingDirection.Left:
|
case ScrollingDirection.Left:
|
||||||
originAdjustment = hitObject.OriginPosition.X;
|
startOffset = -boundingBox.Left;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ScrollingDirection.Right:
|
case ScrollingDirection.Up:
|
||||||
originAdjustment = hitObject.DrawWidth - hitObject.OriginPosition.X;
|
startOffset = -boundingBox.Top;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
double computedStartTime = scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, originAdjustment, timeRange.Value, scrollLength);
|
return scrollingInfo.Algorithm.GetDisplayStartTime(entry.HitObject.StartTime, startOffset, timeRange.Value, scrollLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setComputedLifetimeStart(HitObjectLifetimeEntry entry)
|
||||||
|
{
|
||||||
|
double computedStartTime = computeDisplayStartTime(entry);
|
||||||
|
|
||||||
// always load the hitobject before its first judgement offset
|
// always load the hitobject before its first judgement offset
|
||||||
return Math.Min(hitObject.HitObject.StartTime - hitObject.MaximumJudgementOffset, computedStartTime);
|
double judgementOffset = entry.HitObject.HitWindows?.WindowFor(Scoring.HitResult.Miss) ?? 0;
|
||||||
|
entry.LifetimeStart = Math.Min(entry.HitObject.StartTime - judgementOffset, computedStartTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLayoutRecursive(DrawableHitObject hitObject)
|
private void updateLayoutRecursive(DrawableHitObject hitObject)
|
||||||
|
Reference in New Issue
Block a user