public tpHitObject(HitObjectBase BaseHitObject, float CircleRadius)
{
this.BaseHitObject = BaseHitObject;
// We will scale everything by this factor, so we can assume a uniform CircleSize among beatmaps.
float ScalingFactor = (52.0f / CircleRadius);
NormalizedStartPosition = BaseHitObject.Position * ScalingFactor;
// Calculate approximation of lazy movement on the slider
if ((BaseHitObject.Type & HitObjectType.Slider) > 0)
{
float SliderFollowCircleRadius = CircleRadius * 3; // Not sure if this is correct, but here we do not need 100% exact values. This comes pretty darn close in my tests.
int SegmentLength = BaseHitObject.Length / BaseHitObject.SegmentCount;
int SegmentEndTime = BaseHitObject.StartTime + SegmentLength;
// For simplifying this step we use actual osu! coordinates and simply scale the length, that we obtain by the ScalingFactor later
Vector2 CursorPos = BaseHitObject.Position; //
// Actual computation of the first lazy curve
for (int Time = BaseHitObject.StartTime + LAZY_SLIDER_STEP_LENGTH; Time < SegmentEndTime; Time += LAZY_SLIDER_STEP_LENGTH)
{
Vector2 Difference = BaseHitObject.PositionAtTime(Time) - CursorPos;
float Distance = Difference.Length();
// Did we move away too far?
if (Distance > SliderFollowCircleRadius)
{
// Yep, we need to move the cursor
Difference.Normalize(); // Obtain the direction of difference. We do no longer need the actual difference
Distance -= SliderFollowCircleRadius;
CursorPos += Difference * Distance; // We move the cursor just as far as needed to stay in the follow circle
LazySliderLengthFirst += Distance;
}
}
LazySliderLengthFirst *= ScalingFactor;
// If we have an odd amount of repetitions the current position will be the end of the slider. Note that this will -always- be triggered if
// BaseHitObject.SegmentCount <= 1, because BaseHitObject.SegmentCount can not be smaller than 1. Therefore NormalizedEndPosition will always be initialized
if (BaseHitObject.SegmentCount % 2 == 1)
{
NormalizedEndPosition = CursorPos * ScalingFactor;
}
// If we have more than one segment, then we also need to compute the length ob subsequent lazy curves. They are different from the first one, since the first
// one starts right at the beginning of the slider.
if(BaseHitObject.SegmentCount > 1)
{
// Use the next segment
SegmentEndTime += SegmentLength;
for (int Time = SegmentEndTime - SegmentLength + LAZY_SLIDER_STEP_LENGTH; Time < SegmentEndTime; Time += LAZY_SLIDER_STEP_LENGTH)
{
Vector2 Difference = BaseHitObject.PositionAtTime(Time) - CursorPos;
float Distance = Difference.Length();
// Did we move away too far?
if (Distance > SliderFollowCircleRadius)
{
// Yep, we need to move the cursor
Difference.Normalize(); // Obtain the direction of difference. We do no longer need the actual difference
Distance -= SliderFollowCircleRadius;
CursorPos += Difference * Distance; // We move the cursor just as far as needed to stay in the follow circle
LazySliderLengthSubsequent += Distance;
}
}
LazySliderLengthSubsequent *= ScalingFactor;
// If we have an even amount of repetitions the current position will be the end of the slider
if (BaseHitObject.SegmentCount % 2 == 1)
{
NormalizedEndPosition = CursorPos * ScalingFactor;
}
}
}
// We have a normal HitCircle or a spinner
else
{
NormalizedEndPosition = BaseHitObject.EndPosition * ScalingFactor;
}
}