public override (Vector2 position, double time) GetSnappedPosition(Vector2 position)
        {
            if (MaxIntervals == 0)
            {
                return(StartPosition, StartTime);
            }

            // This grid implementation factors in the user's distance spacing specification,
            // which is usually not considered by an `IDistanceSnapProvider`.
            float distanceSpacingMultiplier = (float)DistanceSpacingMultiplier.Value;

            Vector2 travelVector = (position - StartPosition);

            // We need a non-zero travel vector in order to find a valid direction.
            if (travelVector == Vector2.Zero)
            {
                travelVector = new Vector2(0, -1);
            }

            float travelLength = travelVector.Length;

            // FindSnappedDistance will always round down, but we want to potentially round upwards.
            travelLength += DistanceBetweenTicks / 2;

            // We never want to snap towards zero.
            if (travelLength < DistanceBetweenTicks)
            {
                travelLength = DistanceBetweenTicks;
            }

            // When interacting with the resolved snap provider, the distance spacing multiplier should first be removed
            // to allow for snapping at a non-multiplied ratio.
            float  snappedDistance = SnapProvider.FindSnappedDistance(ReferenceObject, travelLength / distanceSpacingMultiplier);
            double snappedTime     = StartTime + SnapProvider.DistanceToDuration(ReferenceObject, snappedDistance);

            if (snappedTime > LatestEndTime)
            {
                double tickLength = Beatmap.GetBeatLengthAtTime(StartTime);

                snappedDistance = SnapProvider.DurationToDistance(ReferenceObject, MaxIntervals * tickLength);
                snappedTime     = StartTime + SnapProvider.DistanceToDuration(ReferenceObject, snappedDistance);
            }

            // The multiplier can then be reapplied to the final position.
            Vector2 snappedPosition = StartPosition + travelVector.Normalized() * snappedDistance * distanceSpacingMultiplier;

            return(snappedPosition, snappedTime);
        }
示例#2
0
        private void updateSpacing()
        {
            DistanceSpacing = SnapProvider.GetBeatSnapDistanceAt(StartTime);

            if (endTime == null)
            {
                MaxIntervals = int.MaxValue;
            }
            else
            {
                // +1 is added since a snapped hitobject may have its start time slightly less than the snapped time due to floating point errors
                double maxDuration = endTime.Value - StartTime + 1;
                MaxIntervals = (int)(maxDuration / SnapProvider.DistanceToDuration(StartTime, DistanceSpacing));
            }

            gridCache.Invalidate();
        }
示例#3
0
        private void updateSpacing()
        {
            float distanceSpacingMultiplier = (float)DistanceSpacingMultiplier.Value;
            float beatSnapDistance          = SnapProvider.GetBeatSnapDistanceAt(ReferenceObject);

            DistanceBetweenTicks = beatSnapDistance * distanceSpacingMultiplier;

            if (LatestEndTime == null)
            {
                MaxIntervals = int.MaxValue;
            }
            else
            {
                MaxIntervals = (int)((LatestEndTime.Value - StartTime) / SnapProvider.DistanceToDuration(ReferenceObject, beatSnapDistance));
            }

            gridCache.Invalidate();
        }
        public override (Vector2 position, double time) GetSnappedPosition(Vector2 position)
        {
            Vector2 direction = position - CentrePosition;

            if (direction == Vector2.Zero)
            {
                direction = new Vector2(0.001f, 0.001f);
            }

            float distance = direction.Length;

            float radius      = DistanceSpacing;
            int   radialCount = Math.Max(1, (int)Math.Round(distance / radius));

            Vector2 normalisedDirection = direction * new Vector2(1f / distance);
            Vector2 snappedPosition     = CentrePosition + normalisedDirection * radialCount * radius;

            return(snappedPosition, StartTime + SnapProvider.GetSnappedDurationFromDistance(StartTime, (snappedPosition - CentrePosition).Length));
        }
示例#5
0
        public override (Vector2 position, double time) GetSnappedPosition(Vector2 position)
        {
            if (MaxIntervals == 0)
            {
                return(StartPosition, StartTime);
            }

            Vector2 direction = position - StartPosition;

            if (direction == Vector2.Zero)
            {
                direction = new Vector2(0.001f, 0.001f);
            }

            float distance = direction.Length;

            float radius      = DistanceSpacing;
            int   radialCount = Math.Clamp((int)MathF.Round(distance / radius), 1, MaxIntervals);

            Vector2 normalisedDirection = direction * new Vector2(1f / distance);
            Vector2 snappedPosition     = StartPosition + normalisedDirection * radialCount * radius;

            return(snappedPosition, StartTime + SnapProvider.GetSnappedDurationFromDistance(ReferenceObject, (snappedPosition - StartPosition).Length));
        }
示例#6
0
 private void updateSpacing()
 {
     DistanceSpacing = SnapProvider.GetBeatSnapDistanceAt(StartTime);
     gridCache.Invalidate();
 }