Circular visualizer now has function organized circle vertice order; sorting comparator moved to local method;

This commit is contained in:
Harrison Deng 2018-04-15 02:59:35 -05:00
parent bfcad74529
commit 62dc7381c6
5 changed files with 123 additions and 83 deletions

View File

@ -1,23 +1,28 @@
package zero1hd.rhythmbullet.audio.visualizer;
import java.util.Comparator;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Disposable;
import zero1hd.rhythmbullet.RhythmBullet;
public class CircularVisualizer implements Disposable {
private int circlePointIndex;
private int centerX, centerY;
private int r;
private int componentCount = 2 + 1;
private float[][] circlePoints;
private Array<Vector2> circlePoints;
private float[] vertComponents;
private float color;
private Mesh mesh;
@ -43,16 +48,14 @@ public class CircularVisualizer implements Disposable {
* Only should be called when all changes have been done.
*/
public void applyPositionChanges() {
int vertsReq = calculateVerticeCount(centerX, centerY, r);
vertComponents = new float[vertsReq * componentCount];
circlePoints = new float[vertsReq][2];
Gdx.app.debug("Circular Visualizer", "Using " + circlePoints.length + " points to create a circle.");
circlePoints = new Array<>();
createCircleVertices(r);
vertComponents = new float[circlePoints.size * componentCount];
if (mesh != null) {
mesh.dispose();
}
createCircleVertices(centerX, centerY, r);
mesh = new Mesh(true, circlePoints.length, 0, new VertexAttribute(Usage.Position, 2, "a_position"), new VertexAttribute(Usage.ColorPacked, 4, "a_color"));
mesh = new Mesh(true, circlePoints.size, 0, new VertexAttribute(Usage.Position, 2, "a_position"), new VertexAttribute(Usage.ColorPacked, 4, "a_color"));
}
public void setCenter(int x, int y) {
@ -60,21 +63,15 @@ public class CircularVisualizer implements Disposable {
this.centerY = y;
}
private void addCircleVertex(int x, int y) {
circlePoints[circlePointIndex][0] = x;
circlePoints[circlePointIndex][1] = y;
circlePointIndex++;
}
public void drawVisualizer() {
for (int circlePointIndex = 0; circlePointIndex < circlePoints.length; circlePointIndex++) {
for (int componentIndex = 0; componentIndex < componentCount; componentIndex++) {
int index = circlePointIndex*componentCount + componentIndex;
if (componentIndex == 2) {
vertComponents[index] = color;
for (int circlePointIndex = 0; circlePointIndex < circlePoints.size; circlePointIndex++) {
for (int comp = 0; comp < componentCount; comp++) {
if (comp != 2) {
vertComponents[circlePointIndex*componentCount + comp] = circlePoints.get(circlePointIndex).x + centerX;
comp++;
vertComponents[circlePointIndex*componentCount + comp] = circlePoints.get(circlePointIndex).y + centerY;
} else {
vertComponents[index] = circlePoints[circlePointIndex][componentIndex];
vertComponents[circlePointIndex*componentCount + comp] = color;
}
}
}
@ -84,40 +81,39 @@ public class CircularVisualizer implements Disposable {
private void flush() {
mesh.setVertices(vertComponents);
Gdx.gl.glDepthMask(false);
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
int vertexCount = circlePoints.length;
int vertexCount = circlePoints.size;
((OrthographicCamera) camera).setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
shader.begin();
shader.setUniformMatrix("u_projTrans", camera.combined);
mesh.render(shader, GL20.GL_TRIANGLE_FAN, 0, vertexCount);
mesh.render(shader, GL20.GL_LINE_STRIP, 0, vertexCount);
shader.end();
Gdx.gl.glDepthMask(true);
}
private void createCircleVertices(int centerX, int centerY, int radius) {
private void createCircleVertices(int radius) {
int x = radius - 1;
int y = 0;
int dx = 1;
int dy = 1;
int err = dx - (radius << 1);
circlePointIndex = 0;
while (x >= y)
{
addCircleVertex(centerX + x, centerY + y);
addCircleVertex(centerX + y, centerY + x);
addCircleVertex(centerX - y, centerY + x);
addCircleVertex(centerX - x, centerY + y);
addCircleVertex(centerX - x, centerY - y);
addCircleVertex(centerX - y, centerY - x);
addCircleVertex(centerX + y, centerY - x);
addCircleVertex(centerX + x, centerY - y);
circlePoints.clear();
while (x >= y) {
circlePoints.add(new Vector2(+ x, + y));
circlePoints.add(new Vector2(+ y, + x));
circlePoints.add(new Vector2(- y, + x));
circlePoints.add(new Vector2(- x, + y));
circlePoints.add(new Vector2(- x, - y));
circlePoints.add(new Vector2(- y, - x));
circlePoints.add(new Vector2(+ y, - x));
circlePoints.add(new Vector2(+ x, - y));
if (err <= 0) {
y++;
err += dy;
@ -128,30 +124,83 @@ public class CircularVisualizer implements Disposable {
err += dx - (radius << 1);
}
}
}
private int calculateVerticeCount(int centerX, int centerY, int radius) {
int x = radius - 1;
int y = 0;
int dx = 1;
int dy = 1;
int err = dx - (radius << 1);
int vertCount = 0;
while (x >= y)
{
vertCount += 8;
if (err <= 0) {
y++;
err += dy;
dy += 2;
} else {
x--;
dx += 2;
err += dx - (radius << 1);
}
}
return vertCount;
circlePoints.sort(new Comparator<Vector2>() {
@Override
public int compare(Vector2 o1, Vector2 o2) {
double deg1;
if (o1.x != 0 || o1.y != 0) {
deg1 = Math.atan(Math.abs(o1.y)/Math.abs(o1.x));
if (o1.x < 0) {
if (o1.y < 0) {
deg1 += 180;
} else {
deg1 = 180 - deg1;
}
} else {
if (o1.y < 0) {
deg1 = 360 - deg1;
}
}
} else {
if (o1.x != 0) {
if (o1.x > 0) {
deg1 = 0;
} else {
deg1 = 180;
}
deg1 = 0;
} else {
if (o1.y > 0) {
deg1 = 90;
} else {
deg1 = 270;
}
}
}
double deg2;
if (o2.x != 0 || o2.y != 0) {
deg2 = Math.atan(Math.abs(o2.y)/Math.abs(o2.x));
if (o2.x < 0) {
if (o2.y < 0) {
deg2 += 180;
} else {
deg2 = 180 - deg2;
}
} else {
if (o2.y < 0) {
deg2 = 360 - deg2;
}
}
} else {
if (o2.x != 0) {
if (o2.x > 0) {
deg2 = 0;
} else {
deg2 = 180;
}
deg2 = 0;
} else {
if (o2.y > 0) {
deg2 = 90;
} else {
deg2 = 270;
}
}
}
if ((deg1 - deg2) > 0) {
return 1;
} else if (deg1 - deg2 == 0) {
return 0;
} else {
return -1;
}
}
});
}
public void setColor(float color) {

View File

@ -120,7 +120,7 @@ public class HorizontalVisualizer implements Disposable {
public void setMM(MusicManager mm) {
maxAvgHeight = 0;
currentAvg = 0;
float validBins = (1700/((mm.getSampleRate()/2)/((mm.getReadWindowSize()/2)+1)));
float validBins = (2200/((mm.getSampleRate()/2)/((mm.getReadWindowSize()/2)+1)));
Gdx.app.debug("Visualizer", "valid frequency bins " + validBins);
binsPerBar = MathUtils.round((validBins/barCount));
barHeights = new float[barCount];

View File

@ -1,13 +0,0 @@
package zero1hd.rhythmbullet.util;
import java.util.Comparator;
import com.badlogic.gdx.files.FileHandle;
public class FileHandleAlphabeticalComparator implements Comparator<FileHandle>{
@Override
public int compare(FileHandle o1, FileHandle o2) {
return o1.nameWithoutExtension().compareTo(o2.nameWithoutExtension());
}
}

View File

@ -1,5 +1,6 @@
package zero1hd.rhythmbullet.desktop.audio;
import java.util.Comparator;
import java.util.Observable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -10,18 +11,15 @@ import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Sort;
import zero1hd.rhythmbullet.audio.MusicManager;
import zero1hd.rhythmbullet.util.FileHandleAlphabeticalComparator;
public class MusicList extends Observable {
private Array<FileHandle> musicArray;
private String searchPath;
private boolean searched;
private FileHandleAlphabeticalComparator fhac;
private ExecutorService exec;
public MusicList() {
musicArray = new Array<>();
fhac = new FileHandleAlphabeticalComparator();
exec = Executors.newSingleThreadExecutor();
}
@ -56,7 +54,13 @@ public class MusicList extends Observable {
}
musicArray.add(Gdx.files.external("RhythmBullet/Alan Walker - Spectre.mp3"));
setChanged();
Sort.instance().sort(musicArray, fhac);
Sort.instance().sort(musicArray, new Comparator<FileHandle>() {
@Override
public int compare(FileHandle o1, FileHandle o2) {
return o1.nameWithoutExtension().compareTo(o2.nameWithoutExtension());
}
});
searched = true;
if (notifyOnCompletion) {

View File

@ -36,14 +36,14 @@ public class SplashScreen extends ScreenAdapter implements AdvancedResizeScreen
stage.act(delta);
if (!zero1HD.hasActions() && core.isInitComplete()) {
moveOn();
attemptMoveOn();
}
stage.draw();
super.render(delta);
}
private void moveOn() {
private void attemptMoveOn() {
if (!done) {
Gdx.app.debug("Loading Screen", "queue has all been loaded. Action is done playing.");
done = true;