attempt to fix merged sliders rendering wrong cones

This commit is contained in:
yugecin 2018-10-26 22:52:23 +02:00
parent 8d6e34faaf
commit a027330be3
No known key found for this signature in database
GPG Key ID: 2C5AC035A7068E44
8 changed files with 84 additions and 77 deletions

View File

@ -957,7 +957,7 @@ public class GameData {
private void drawHitAnimations(HitObjectResult hitResult, int trackPosition) {
// fade out slider curve
if (hitResult.result != HIT_SLIDER_REPEAT && hitResult.result != HIT_SLIDER_REPEAT_M && hitResult.curve != null) {
if (!OPTION_SHRINKING_SLIDERS.state) {
if (!OPTION_SHRINKING_SLIDERS.state && hitResult.curve.getCurvePoints().length > 0) {
float progress = AnimationEquation.OUT_CUBIC.calc(
(float) Utils.clamp(trackPosition - hitResult.time, 0, HITCIRCLE_FADE_TIME) / HITCIRCLE_FADE_TIME);
float alpha = 1f - progress;

View File

@ -124,7 +124,7 @@ public class Slider extends GameObject {
private int comboColorIndex;
public int baseSliderFrom;
public int curveStartIndex;
/**
* Initializes the Slider data type with images and dimensions.
@ -205,9 +205,9 @@ public class Slider extends GameObject {
final int fadeInTime = game.getFadeInTime();
float scale = timeDiff / (float) approachTime;
float approachScale = 1 + scale * 3;
double fadeinScale = (timeDiff - approachTime + fadeInTime) / (double) fadeInTime;
float alpha = Utils.clamp(1 - (float) fadeinScale, 0, 1);
float decorationsAlpha = Utils.clamp(-2.0f * (float) fadeinScale, 0, 1);
float fadeinScale = (timeDiff - approachTime + fadeInTime) / (float) fadeInTime;
float alpha = Utils.clamp(1f - fadeinScale, 0f, 1f);
float decorationsAlpha = Utils.clamp(-2.0f * fadeinScale, 0f, 1f);
boolean overlayAboveNumber = SkinService.skin.isHitCircleOverlayAboveNumber();
float oldAlpha = Colors.WHITE_FADE.a;
Colors.WHITE_FADE.a = color.a = alpha;
@ -222,7 +222,7 @@ public class Slider extends GameObject {
}
curveColor.a = sliderAlpha;
boolean isCurveCompletelyDrawn = drawSliderTrack(trackPosition, Utils.clamp(1d - fadeinScale, 0d, 1d));
boolean isCurveCompletelyDrawn = drawSliderTrack(trackPosition, Utils.clamp(1f - fadeinScale, 0f, 1f));
color.a = alpha;
// end circle (only draw if ball still has to go there)
@ -448,38 +448,46 @@ public class Slider extends GameObject {
}
}
private boolean drawSliderTrack(int trackPosition, double snakingSliderProgress) {
double curveIntervalTo = OPTION_SNAKING_SLIDERS.state ? snakingSliderProgress : 1d;
double curveIntervalFrom = 0d;
/**
* @return {@code true} if track is completely drawn (snaking, shrinking etc)
*/
private boolean drawSliderTrack(int trackPosition, float snakingSliderProgress)
{
int curvelen = curve.curve.length;
if (curvelen == 0) {
return true;
}
float curveIntervalTo = OPTION_SNAKING_SLIDERS.state ? snakingSliderProgress : 1f;
float curveIntervalFrom = 0f;
if (OPTION_SHRINKING_SLIDERS.state) {
double sliderprogress = (trackPosition - getTime() - ((double) sliderTime * (repeats - 1))) / (double) sliderTime;
float sliderprogress = (trackPosition - getTime() - sliderTime * (repeats - 1)) / sliderTime;
if (sliderprogress > 0) {
curveIntervalFrom = sliderprogress;
}
}
int curvelen = curve.getCurvePoints().length;
if (!OPTION_FALLBACK_SLIDERS.state && OPTION_MERGING_SLIDERS.state) {
if (OPTION_SHRINKING_SLIDERS.state && curveIntervalFrom > 0) {
if (OPTION_SHRINKING_SLIDERS.state && curveIntervalFrom > 0d) {
if (hitObject.getRepeatCount() % 2 == 0) {
game.addMergedSliderPointsToRender(baseSliderFrom, baseSliderFrom + (int) ((1d - curveIntervalFrom) * curvelen));
game.addMergedSliderPointsToRender(curveStartIndex, curveStartIndex + (int) ((1d - curveIntervalFrom) * curvelen));
} else {
game.addMergedSliderPointsToRender(baseSliderFrom + (int) (curveIntervalFrom * curvelen) + 1, baseSliderFrom + (int) (curveIntervalTo * curve.getCurvePoints().length));
game.addMergedSliderPointsToRender(curveStartIndex + (int) (curveIntervalFrom * curvelen) + 1, curveStartIndex + (int) (curveIntervalTo * (curvelen - 1)));
}
} else {
game.addMergedSliderPointsToRender(baseSliderFrom, baseSliderFrom + (int) (curveIntervalTo * curve.getCurvePoints().length));
int to = (int) (curveIntervalTo * (curvelen - 1));
game.addMergedSliderPointsToRender(curveStartIndex, curveStartIndex + to);
}
} else {
if (OPTION_SHRINKING_SLIDERS.state && curveIntervalFrom > 0 && repeats % 2 == 0) {
if (OPTION_FALLBACK_SLIDERS.state) {
curveIntervalTo = 1d - curveIntervalFrom;
curveIntervalTo = 1f - curveIntervalFrom;
} else {
curve.splice((int) ((1d - curveIntervalFrom) * curvelen), curvelen);
curve.splice((int) ((1f - curveIntervalFrom) * curvelen), curvelen);
}
curveIntervalFrom = 0d;
curveIntervalFrom = 0f;
}
curve.draw(curveColor, (int) (curveIntervalFrom * curvelen), (int) (curveIntervalTo * curvelen));
}
return curveIntervalTo == 1d;
return curveIntervalTo == 1f;
}
/**
@ -830,6 +838,16 @@ public class Slider extends GameObject {
return curve;
}
public Vec2f[] getCurvePoints()
{
return curve.curve;
}
public int getCurvePointsCount()
{
return curve.curve.length;
}
public int getRepeats() {
return repeats;
}

View File

@ -91,10 +91,8 @@ public abstract class Curve {
}
/**
* Set the width and height of the container that Curves get drawn into.
* Init curves for given circle diameter
* Should be called before any curves are drawn.
* @param width the container width
* @param height the container height
* @param circleDiameter the circle diameter
* @param borderColor the curve border color
*/

View File

@ -75,7 +75,7 @@ public class CurveRenderState {
private final int mirrors;
/**
* Set the width and height of the container that Curves get drawn into.
* Init curves for given circle diameter
* Should be called before any curves are drawn.
* @param circleDiameter the circle diameter
*/
@ -83,7 +83,6 @@ public class CurveRenderState {
// equivalent to what happens in Slider.init()
scale = (int) (circleDiameter * HitObject.getXMultiplier()); // convert from Osupixels (640x480)
//scale = scale * 118 / 128; //for curves exactly as big as the sliderball
FrameBufferCache.init(width, height);
NewCurveStyleState.initUnitCone();
}
@ -293,31 +292,20 @@ public class CurveRenderState {
*/
private void createVertexBuffer(int bufferID) {
int arrayBufferBinding = GL11.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING);
FloatBuffer buff = BufferUtils.createByteBuffer(4 * (4 + 2) * (2 * curve.length - 1) * mirrors * (NewCurveStyleState.DIVIDES + 2)).asFloatBuffer();
if (curve.length > 0) {
fillCone(buff, curve[0].x, curve[0].y, 0);
}
FloatBuffer buff = BufferUtils.createByteBuffer(4 * (4 + 2) * (curve.length) * mirrors * (NewCurveStyleState.DIVIDES + 2)).asFloatBuffer();
for (int mirror = 0; mirror < mirrors; mirror++) {
final float angle = 360f * mirror / mirrors;
float lastx = curve[0].x;
float lasty = curve[0].y;
fillCone(buff, lastx, lasty, angle);
for (int i = 1; i < curve.length; ++i) {
float x = curve[i].x;
float y = curve[i].y;
fillCone(buff, x, y, angle);
float last_x = curve[i - 1].x;
float last_y = curve[i - 1].y;
double diff_x = x - last_x;
double diff_y = y - last_y;
float dist = Utils.distance(x, y, last_x, last_y);
if (dist < gameObjectRenderer.circleDiameter / 8) {
x = (float) (x - diff_x / 2);
y = (float) (y - diff_y / 2);
} else {
// don't mind me
x = -100f;
y = -100f;
}
fillCone(buff, x, y, angle);
//fillCone(buff, (x + lastx) / 2f, (y + lasty) / 2f, angle);
//lastx = x;
//lasty = y;
}
}
buff.flip();
@ -349,16 +337,15 @@ public class CurveRenderState {
if (clearFirst) {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
}
int max = mirrors;
if (!OPTION_DANCE_MIRROR.state) {
max = 1;
}
for (int i = 0; i < max; i++) {
final int mirrors = OPTION_DANCE_MIRROR.state ? this.mirrors : 1;
for (int i = 0; i < mirrors; i++) {
if (pointsToRender == null) {
renderCurve(from, to, i);
} else {
renderCurve(i);
}
//from++;
//to++;
}
GL11.glFlush();
GL20.glDisableVertexAttribArray(staticState.texCoordLoc);
@ -367,15 +354,16 @@ public class CurveRenderState {
}
private void renderCurve(int from, int to, int mirror) {
// since there are len*2-1 points, subtract mirror index
if (from > 0) {
from -= mirror;
}
to -= mirror;
for (int i = from * 2; i < to * 2 - 1; ++i) {
for (int i = from; i < to - 1; ++i) {
if (spliceFrom <= i && i <= spliceTo) {
continue;
}
final int index = i + curve.length * 2 * mirror;
final int index = i + curve.length * mirror;
GL11.glDrawArrays(GL11.GL_TRIANGLE_FAN, index * (NewCurveStyleState.DIVIDES + 2), NewCurveStyleState.DIVIDES + 2);
}
}
@ -383,8 +371,8 @@ public class CurveRenderState {
private void renderCurve(int mirror) {
Iterator<Integer> iter = pointsToRender.iterator();
while (iter.hasNext()) {
for (int i = iter.next() * 2, end = iter.next() * 2 - 1; i < end; ++i) {
final int index = i + curve.length * 2 * mirror;
for (int i = iter.next(), end = iter.next(); i < end; ++i) {
final int index = i + curve.length * mirror;
GL11.glDrawArrays(GL11.GL_TRIANGLE_FAN, index * (NewCurveStyleState.DIVIDES + 2), NewCurveStyleState.DIVIDES + 2);
}
}

View File

@ -23,6 +23,8 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import static yugecin.opsudance.core.InstanceContainer.*;
/**
* This is cache for OpenGL FrameBufferObjects. This is currently only used
* to draw curve objects of the new slider style. Does currently not integrate
@ -40,20 +42,6 @@ public class FrameBufferCache {
/** */
private ArrayList<Rendertarget> cache;
/** Container dimensions. */
public static int width, height;
/**
* Set the width and height of the framebuffers in this cache.
* Should be called before anything is inserted into the map.
* @param width the container width
* @param height the container height
*/
public static void init(int width, int height) {
FrameBufferCache.width = width;
FrameBufferCache.height = height;
}
/**
* Constructor.
*/

View File

@ -68,6 +68,7 @@ import yugecin.opsudance.utils.GLHelper;
import static itdelatrisu.opsu.GameImage.*;
import static itdelatrisu.opsu.ui.Colors.*;
import static java.lang.System.arraycopy;
import static org.lwjgl.input.Keyboard.*;
import static yugecin.opsudance.options.Options.*;
import static yugecin.opsudance.core.InstanceContainer.*;
@ -1672,22 +1673,36 @@ public class Game extends ComplexOpsuState {
}
if (knorkesliders == null) {
// let's create knorkesliders
List<Vec2f> curvepoints = new ArrayList<>();
for (GameObject gameObject : gameObjects) {
if (gameObject.isSlider()) {
((Slider) gameObject).baseSliderFrom = curvepoints.size();
curvepoints.addAll(Arrays.asList(((Slider) gameObject).getCurve().getCurvePoints()));
int totalpoints = 0;
ArrayList<Slider> sliders = new ArrayList<>();
for (GameObject o : gameObjects) {
if (o.isSlider()) {
final Slider s = (Slider) o;
final int len = s.getCurvePointsCount();
if (len > 0) {
sliders.add(s);
s.curveStartIndex = totalpoints;
totalpoints += s.getCurvePointsCount();
}
}
}
if (curvepoints.size() > 0) {
knorkesliders = new FakeCombinedCurve(curvepoints.toArray(new Vec2f[curvepoints.size()]));
if (totalpoints > 0) {
Vec2f[] combinedcurve = new Vec2f[totalpoints];
int idx = 0;
for (Slider s : sliders) {
int len = s.getCurvePointsCount();
arraycopy(s.getCurvePoints(), 0, combinedcurve, idx, len);
idx += len;
}
knorkesliders = new FakeCombinedCurve(combinedcurve);
}
} else {
int base = 0;
int startIndex = 0;
for (GameObject gameObject : gameObjects) {
if (gameObject.isSlider()) {
((Slider) gameObject).baseSliderFrom = base;
base += ((Slider) gameObject).getCurve().getCurvePoints().length;
final Slider s = (Slider) gameObject;
s.curveStartIndex = startIndex;
startIndex += s.getCurvePointsCount();
}
}
}

View File

@ -50,7 +50,7 @@ public class OptionGroups {
OPTION_FALLBACK_SLIDERS,
OPTION_SHRINKING_SLIDERS,
OPTION_MERGING_SLIDERS,
//OPTION_MERGING_SLIDERS_MIRROR_POOL,
OPTION_MERGING_SLIDERS_MIRROR_POOL,
OPTION_DRAW_SLIDER_ENDCIRCLES,
}),
new OptionTab("DANCING HITCIRCLES", new Option[] {

View File

@ -496,7 +496,7 @@ public class Options {
}
};
public static final NumericOption OPTION_MERGING_SLIDERS_MIRROR_POOL = new NumericOption("Merging sliders mirror pool", "MergingSliderMirrorPool", "Amount of mirrors to calculate for merging sliders (impacts performance)", 2, 1, 5) {
public static final NumericOption OPTION_MERGING_SLIDERS_MIRROR_POOL = new NumericOption("Mirrors", "MergingSliderMirrorPool", "Amount of mirrors to calculate for merging sliders (impacts performance)", 2, 2, 6) {
@Override
public String getValueString () {
return String.valueOf(val);