Check for parallel vectors before constructing a CircumscribedCircle.
If the check fails, use a LinearBezier instead. (e.g. in map 45471). Moved slider time and curve calculations into HitObject so that they can be reused. Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
d360b73bf5
commit
c516d93d1e
|
@ -19,6 +19,11 @@
|
|||
package itdelatrisu.opsu.beatmap;
|
||||
|
||||
import itdelatrisu.opsu.GameMod;
|
||||
import itdelatrisu.opsu.objects.curves.CatmullCurve;
|
||||
import itdelatrisu.opsu.objects.curves.CircumscribedCircle;
|
||||
import itdelatrisu.opsu.objects.curves.Curve;
|
||||
import itdelatrisu.opsu.objects.curves.LinearBezier;
|
||||
import itdelatrisu.opsu.objects.curves.Vec2f;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
|
@ -403,6 +408,35 @@ public class HitObject {
|
|||
*/
|
||||
public float getPixelLength() { return pixelLength; }
|
||||
|
||||
/**
|
||||
* Returns the time duration of the slider (excluding repeats), in milliseconds.
|
||||
* @param sliderMultiplier the beatmap's slider movement speed multiplier
|
||||
* @param beatLength the beat length
|
||||
* @return the slider segment length
|
||||
*/
|
||||
public float getSliderTime(float sliderMultiplier, float beatLength) {
|
||||
return beatLength * (pixelLength / sliderMultiplier) / 100f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the slider curve.
|
||||
* @param scaled whether to use scaled coordinates
|
||||
* @return a new Curve instance
|
||||
*/
|
||||
public Curve getSliderCurve(boolean scaled) {
|
||||
if (sliderType == SLIDER_PASSTHROUGH && sliderX.length == 2) {
|
||||
Vec2f nora = new Vec2f(sliderX[0] - x, sliderY[0] - y).nor();
|
||||
Vec2f norb = new Vec2f(sliderX[0] - sliderX[1], sliderY[0] - sliderY[1]).nor();
|
||||
if (Math.abs(norb.x * nora.y - norb.y * nora.x) < 0.00001f)
|
||||
return new LinearBezier(this, false, scaled); // vectors parallel, use linear bezier instead
|
||||
else
|
||||
return new CircumscribedCircle(this, scaled);
|
||||
} else if (sliderType == SLIDER_CATMULL)
|
||||
return new CatmullCurve(this, scaled);
|
||||
else
|
||||
return new LinearBezier(this, sliderType == SLIDER_LINEAR, scaled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the spinner end time.
|
||||
* @return the end time (in ms)
|
||||
|
|
|
@ -26,10 +26,7 @@ import itdelatrisu.opsu.Options;
|
|||
import itdelatrisu.opsu.Utils;
|
||||
import itdelatrisu.opsu.beatmap.Beatmap;
|
||||
import itdelatrisu.opsu.beatmap.HitObject;
|
||||
import itdelatrisu.opsu.objects.curves.CatmullCurve;
|
||||
import itdelatrisu.opsu.objects.curves.CircumscribedCircle;
|
||||
import itdelatrisu.opsu.objects.curves.Curve;
|
||||
import itdelatrisu.opsu.objects.curves.LinearBezier;
|
||||
import itdelatrisu.opsu.states.Game;
|
||||
import itdelatrisu.opsu.ui.Colors;
|
||||
|
||||
|
@ -157,7 +154,7 @@ public class Slider implements GameObject {
|
|||
updatePosition();
|
||||
|
||||
// slider time calculations
|
||||
this.sliderTime = game.getBeatLength() * (hitObject.getPixelLength() / sliderMultiplier) / 100f;
|
||||
this.sliderTime = hitObject.getSliderTime(sliderMultiplier, game.getBeatLength());
|
||||
this.sliderTimeTotal = sliderTime * hitObject.getRepeatCount();
|
||||
|
||||
// ticks
|
||||
|
@ -525,13 +522,7 @@ public class Slider implements GameObject {
|
|||
public void updatePosition() {
|
||||
this.x = hitObject.getScaledX();
|
||||
this.y = hitObject.getScaledY();
|
||||
|
||||
if (hitObject.getSliderType() == HitObject.SLIDER_PASSTHROUGH && hitObject.getSliderX().length == 2)
|
||||
this.curve = new CircumscribedCircle(hitObject);
|
||||
else if (hitObject.getSliderType() == HitObject.SLIDER_CATMULL)
|
||||
this.curve = new CatmullCurve(hitObject);
|
||||
else
|
||||
this.curve = new LinearBezier(hitObject, hitObject.getSliderType() == HitObject.SLIDER_LINEAR);
|
||||
this.curve = hitObject.getSliderCurve(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue
Block a user