diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java b/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java
index 7575be3fb..347e12b8b 100644
--- a/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java
+++ b/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
package com.seibel.lod.core.objects.opengl;
import java.nio.ByteBuffer;
@@ -36,18 +36,20 @@ import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import static com.seibel.lod.core.render.LodRenderer.EVENT_LOGGER;
-public class LodQuadBuilder {
+public class LodQuadBuilder
+{
static final int MAX_BUFFER_SIZE = (1024 * 1024);
static final int QUAD_BYTE_SIZE = (12 * 6);
static final int MAX_QUADS_PER_BUFFER = MAX_BUFFER_SIZE / QUAD_BYTE_SIZE;
//static final int MAX_MERGED_QUAD_SIZE = 64;
-
+
static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
-
+
public final boolean skipSkylight0Quads;
public final short skyLightCullingBelow;
-
- static class Quad {
+
+ static class Quad
+ {
final short x;
final short y;
final short z;
@@ -58,11 +60,14 @@ public class LodQuadBuilder {
final byte blocklight;
final LodDirection dir;
double distance = 0d;
-
+
Quad(short x, short y, short z, short w0, short w1, int color, byte skylight, byte blocklight,
- LodDirection dir) {
- if (w0 == 0 || w1 == 0) throw new IllegalArgumentException("Size 0 quad!");
- if (w0 < 0 || w1 < 0) throw new IllegalArgumentException("Negative sized quad!");
+ LodDirection dir)
+ {
+ if (w0 == 0 || w1 == 0)
+ throw new IllegalArgumentException("Size 0 quad!");
+ if (w0 < 0 || w1 < 0)
+ throw new IllegalArgumentException("Negative sized quad!");
this.x = x;
this.y = y;
this.z = z;
@@ -74,22 +79,30 @@ public class LodQuadBuilder {
this.dir = dir;
}
- private static double pow(double d) {return d*d;}
-
- // NOTE: This is only a rough but fast calculation!
- void calculateDistance(double relativeX, double relativeY, double relativeZ) {
- distance = pow(relativeX-x) + pow(relativeY-y) + pow(relativeZ-z);
+ private static double pow(double d)
+ {
+ return d * d;
}
- private static int _compondCompare(short a0, short a1, short a2, short b0, short b1, short b2) {
- long a = (long)a0<<48 | (long)a1<<32 | (long)a2 << 16;
- long b = (long)b0<<48 | (long)b1<<32 | (long)b2 << 16;
+ // NOTE: This is only a rough but fast calculation!
+ void calculateDistance(double relativeX, double relativeY, double relativeZ)
+ {
+ distance = pow(relativeX - x) + pow(relativeY - y) + pow(relativeZ - z);
+ }
+
+ private static int _compondCompare(short a0, short a1, short a2, short b0, short b1, short b2)
+ {
+ long a = (long) a0 << 48 | (long) a1 << 32 | (long) a2 << 16;
+ long b = (long) b0 << 48 | (long) b1 << 32 | (long) b2 << 16;
return Long.compare(a, b);
}
- public int compareTo1(Quad o) {
- if (dir != o.dir) throw new IllegalArgumentException("The other quad is not in the same direction: " + o.dir + " vs "+dir);
- switch (dir.getAxis()) {
+ public int compareTo1(Quad o)
+ {
+ if (dir != o.dir)
+ throw new IllegalArgumentException("The other quad is not in the same direction: " + o.dir + " vs " + dir);
+ switch (dir.getAxis())
+ {
case X:
return _compondCompare(x, y, z, o.x, o.y, o.z);
case Y:
@@ -100,9 +113,13 @@ public class LodQuadBuilder {
throw new IllegalArgumentException("Invalid Axis enum: " + dir.getAxis());
}
}
- public int compareTo2(Quad o) {
- if (dir != o.dir) throw new IllegalArgumentException("The other quad is not in the same direction: " + o.dir + " vs "+dir);
- switch (dir.getAxis()) {
+
+ public int compareTo2(Quad o)
+ {
+ if (dir != o.dir)
+ throw new IllegalArgumentException("The other quad is not in the same direction: " + o.dir + " vs " + dir);
+ switch (dir.getAxis())
+ {
case X:
return _compondCompare(x, z, y, o.x, o.z, o.y);
case Y:
@@ -182,7 +199,7 @@ public class LodQuadBuilder {
throw new IllegalArgumentException("Invalid Axis enum: " + dir.getAxis());
}
}
-
+
public boolean tryMergeWith2(Quad o)
{
if (dir != o.dir)
@@ -250,60 +267,77 @@ public class LodQuadBuilder {
}
}
-
- final ArrayList[] quads = (ArrayList[])new ArrayList[6];
-
- public LodQuadBuilder(int initialSize, boolean enableSkylightCulling, int skyLightCullingBelow) {
- for (int i=0; i<6; i++) quads[i] = new ArrayList();
+
+ final ArrayList[] quads = (ArrayList[]) new ArrayList[6];
+
+ public LodQuadBuilder(int initialSize, boolean enableSkylightCulling, int skyLightCullingBelow)
+ {
+ for (int i = 0; i < 6; i++)
+ quads[i] = new ArrayList();
this.skipSkylight0Quads = enableSkylightCulling;
this.skyLightCullingBelow = (short) (skyLightCullingBelow - LodBuilder.MIN_WORLD_HEIGHT);
}
-
+
public void addQuadAdj(LodDirection dir, short x, short y, short z, short w0, short wy, int color, byte skylight,
- byte blocklight) {
+ byte blocklight)
+ {
if (dir.ordinal() <= LodDirection.DOWN.ordinal())
throw new IllegalArgumentException("addQuadAdj() is only for adj direction! Not UP or Down!");
- if (skipSkylight0Quads && skylight==0 && y < skyLightCullingBelow) return;
+ if (skipSkylight0Quads && skylight == 0 && y < skyLightCullingBelow)
+ return;
quads[dir.ordinal()].add(new Quad(x, y, z, w0, wy, color, skylight, blocklight, dir));
}
-
+
// XZ
- public void addQuadUp(short x, short y, short z, short wx, short wz, int color, byte skylight, byte blocklight) {
- if (skipSkylight0Quads && skylight==0 && y < skyLightCullingBelow) return;
+ public void addQuadUp(short x, short y, short z, short wx, short wz, int color, byte skylight, byte blocklight)
+ {
+ if (skipSkylight0Quads && skylight == 0 && y < skyLightCullingBelow)
+ return;
quads[LodDirection.UP.ordinal()].add(new Quad(x, y, z, wx, wz, color, skylight, blocklight, LodDirection.UP));
}
-
- public void addQuadDown(short x, short y, short z, short wx, short wz, int color, byte skylight, byte blocklight) {
- if (skipSkylight0Quads && skylight==0 && y < skyLightCullingBelow) return;
+
+ public void addQuadDown(short x, short y, short z, short wx, short wz, int color, byte skylight, byte blocklight)
+ {
+ if (skipSkylight0Quads && skylight == 0 && y < skyLightCullingBelow)
+ return;
quads[LodDirection.DOWN.ordinal()].add(new Quad(x, y, z, wx, wz, color, skylight, blocklight, LodDirection.DOWN));
}
-
+
// XY
- public void addQuadN(short x, short y, short z, short wx, short wy, int color, byte skylight, byte blocklight) {
- if (skipSkylight0Quads && skylight==0 && y < skyLightCullingBelow) return;
+ public void addQuadN(short x, short y, short z, short wx, short wy, int color, byte skylight, byte blocklight)
+ {
+ if (skipSkylight0Quads && skylight == 0 && y < skyLightCullingBelow)
+ return;
quads[LodDirection.NORTH.ordinal()].add(new Quad(x, y, z, wx, wy, color, skylight, blocklight, LodDirection.NORTH));
}
-
- public void addQuadS(short x, short y, short z, short wx, short wy, int color, byte skylight, byte blocklight) {
- if (skipSkylight0Quads && skylight==0 && y < skyLightCullingBelow) return;
+
+ public void addQuadS(short x, short y, short z, short wx, short wy, int color, byte skylight, byte blocklight)
+ {
+ if (skipSkylight0Quads && skylight == 0 && y < skyLightCullingBelow)
+ return;
quads[LodDirection.SOUTH.ordinal()].add(new Quad(x, y, z, wx, wy, color, skylight, blocklight, LodDirection.SOUTH));
}
-
+
// ZY
- public void addQuadW(short x, short y, short z, short wz, short wy, int color, byte skylight, byte blocklight) {
- if (skipSkylight0Quads && skylight==0 && y < skyLightCullingBelow) return;
+ public void addQuadW(short x, short y, short z, short wz, short wy, int color, byte skylight, byte blocklight)
+ {
+ if (skipSkylight0Quads && skylight == 0 && y < skyLightCullingBelow)
+ return;
quads[LodDirection.WEST.ordinal()].add(new Quad(x, y, z, wz, wy, color, skylight, blocklight, LodDirection.WEST));
}
-
- public void addQuadE(short x, short y, short z, short wz, short wy, int color, byte skylight, byte blocklight) {
- if (skipSkylight0Quads && skylight==0 && y < skyLightCullingBelow) return;
+
+ public void addQuadE(short x, short y, short z, short wz, short wy, int color, byte skylight, byte blocklight)
+ {
+ if (skipSkylight0Quads && skylight == 0 && y < skyLightCullingBelow)
+ return;
quads[LodDirection.EAST.ordinal()].add(new Quad(x, y, z, wz, wy, color, skylight, blocklight, LodDirection.EAST));
}
-
- private static void putVertex(ByteBuffer bb, short x, short y, short z, int color, byte skylight, byte blocklight) {
+
+ private static void putVertex(ByteBuffer bb, short x, short y, short z, int color, byte skylight, byte blocklight)
+ {
skylight %= 16;
blocklight %= 16;
-
+
bb.putShort(x);
bb.putShort(y);
bb.putShort(z);
@@ -318,15 +352,18 @@ public class LodQuadBuilder {
bb.put(b);
bb.put(a);
}
-
- private static void putQuad(ByteBuffer bb, Quad quad) {
+
+ private static void putQuad(ByteBuffer bb, Quad quad)
+ {
int[][] quadBase = DIRECTION_VERTEX_QUAD[quad.dir.ordinal()];
short d0 = quad.w0;
short d1 = quad.w1;
Axis axis = quad.dir.getAxis();
- for (int i = 0; i < quadBase.length; i++) {
+ for (int i = 0; i < quadBase.length; i++)
+ {
short dx, dy, dz;
- switch (axis) {
+ switch (axis)
+ {
case X: // ZY
dx = 0;
dz = quadBase[i][0] == 1 ? d0 : 0;
@@ -350,251 +387,307 @@ public class LodQuadBuilder {
}
}
- public void sort(double dPlayerPosX, double dPlayerPosY, double dPlayerPosZ) {
+ public void sort(double dPlayerPosX, double dPlayerPosY, double dPlayerPosZ)
+ {
}
-
- private long mergeQuadsPass1(int dir) {
- if (quads[dir].size()<=1) return 0;
+
+ private long mergeQuadsPass1(int dir)
+ {
+ if (quads[dir].size() <= 1)
+ return 0;
quads[dir].sort(Quad::compareTo1);
ListIterator iter = quads[dir].listIterator();
long mergeCount = 0;
Quad currentQuad = iter.next();
- while (iter.hasNext()) {
+ while (iter.hasNext())
+ {
Quad nextQuad = iter.next();
- if (currentQuad.tryMergeWith1(nextQuad)) {
+ if (currentQuad.tryMergeWith1(nextQuad))
+ {
mergeCount++;
iter.set(null);
- } else {
+ }
+ else
+ {
currentQuad = nextQuad;
}
}
- quads[dir].removeIf(o -> o==null);
+ quads[dir].removeIf(o -> o == null);
return mergeCount;
}
-
- private long mergeQuadsPass2(int dir) {
- if (quads[dir].size()<=1) return 0;
+
+ private long mergeQuadsPass2(int dir)
+ {
+ if (quads[dir].size() <= 1)
+ return 0;
quads[dir].sort(Quad::compareTo2);
ListIterator iter = quads[dir].listIterator();
long mergeCount = 0;
Quad currentQuad = iter.next();
- while (iter.hasNext()) {
+ while (iter.hasNext())
+ {
Quad nextQuad = iter.next();
- if (currentQuad.tryMergeWith2(nextQuad)) {
+ if (currentQuad.tryMergeWith2(nextQuad))
+ {
mergeCount++;
iter.set(null);
- } else {
+ }
+ else
+ {
currentQuad = nextQuad;
}
}
- quads[dir].removeIf(o -> o==null);
+ quads[dir].removeIf(o -> o == null);
return mergeCount;
}
-
- public void mergeQuads() {
+
+ public void mergeQuads()
+ {
long mergeCount = 0;
long preQuadsCount = getCurrentQuadsCount();
- if (preQuadsCount<=1) return;
- for (int i=0; i<6; i++) {
+ if (preQuadsCount <= 1)
+ return;
+ for (int i = 0; i < 6; i++)
+ {
mergeCount += mergeQuadsPass1(i);
- if (i>=2) {
+ if (i >= 2)
+ {
continue;
//long pass2 = mergeQuadsPass2(i);
//mergeCount += pass2;
//skipperMerge += pass2;
- } else {
+ }
+ else
+ {
long pass2 = mergeQuadsPass2(i);
mergeCount += pass2;
}
}
long postQuadsCount = getCurrentQuadsCount();
//if (mergeCount != 0)
- EVENT_LOGGER.debug("Merged {}/{}({}) quads", mergeCount, preQuadsCount, mergeCount/(double)preQuadsCount);
+ EVENT_LOGGER.debug("Merged {}/{}({}) quads", mergeCount, preQuadsCount, mergeCount / (double) preQuadsCount);
}
- public Iterator makeVertexBuffers() {
- return new Iterator() {
+ public Iterator makeVertexBuffers()
+ {
+ return new Iterator()
+ {
final ByteBuffer bb = ByteBuffer.allocateDirect(MAX_QUADS_PER_BUFFER * QUAD_BYTE_SIZE)
.order(ByteOrder.nativeOrder());
int dir = skipEmpty(0);
int quad = 0;
- private int skipEmpty(int d) {
- while(d<6 && quads[d].isEmpty()) d++;
+ private int skipEmpty(int d)
+ {
+ while (d < 6 && quads[d].isEmpty())
+ d++;
return d;
}
@Override
- public boolean hasNext() {
+ public boolean hasNext()
+ {
return dir < 6;
}
-
+
@Override
- public ByteBuffer next() {
- if (dir >= 6) {
+ public ByteBuffer next()
+ {
+ if (dir >= 6)
+ {
return null;
}
bb.clear();
bb.limit(MAX_QUADS_PER_BUFFER * QUAD_BYTE_SIZE);
- while (bb.hasRemaining() && dir < 6) {
+ while (bb.hasRemaining() && dir < 6)
+ {
writeData();
}
bb.limit(bb.position());
bb.rewind();
return bb;
}
-
- private void writeData() {
+
+ private void writeData()
+ {
int startQ = quad;
int i = startQ;
- for (i = startQ; i= quads[dir].size()) {
+ if (i >= quads[dir].size())
+ {
quad = 0;
dir++;
dir = skipEmpty(dir);
- } else {
+ }
+ else
+ {
quad = i;
}
}
};
}
- public interface BufferFiller {
+ public interface BufferFiller
+ {
boolean fill(LodVertexBuffer vbo); // If true: means more data is needed to be filled
}
-
- public BufferFiller makeBufferFiller(GpuUploadMethod method) {
- return new BufferFiller() {
+
+ public BufferFiller makeBufferFiller(GpuUploadMethod method)
+ {
+ return new BufferFiller()
+ {
int dir = 0;
int quad = 0;
- public boolean fill(LodVertexBuffer vbo) {
- if (dir >= 6) {
+
+ public boolean fill(LodVertexBuffer vbo)
+ {
+ if (dir >= 6)
+ {
vbo.vertexCount = 0;
return false;
}
int numOfQuads = _countRemainingQuads();
- if (numOfQuads > MAX_QUADS_PER_BUFFER) numOfQuads = MAX_QUADS_PER_BUFFER;
- if (numOfQuads == 0) {
+ if (numOfQuads > MAX_QUADS_PER_BUFFER)
+ numOfQuads = MAX_QUADS_PER_BUFFER;
+ if (numOfQuads == 0)
+ {
vbo.vertexCount = 0;
return false;
}
- ByteBuffer bb = vbo.mapBuffer(numOfQuads*QUAD_BYTE_SIZE, method, MAX_QUADS_PER_BUFFER * QUAD_BYTE_SIZE);
- if (bb == null) throw new NullPointerException("mapBuffer returned null");
+ ByteBuffer bb = vbo.mapBuffer(numOfQuads * QUAD_BYTE_SIZE, method, MAX_QUADS_PER_BUFFER * QUAD_BYTE_SIZE);
+ if (bb == null)
+ throw new NullPointerException("mapBuffer returned null");
bb.clear();
bb.limit(numOfQuads * QUAD_BYTE_SIZE);
- while (bb.hasRemaining() && dir < 6) {
+ while (bb.hasRemaining() && dir < 6)
+ {
writeData(bb);
}
bb.rewind();
vbo.unmapBuffer(method);
- vbo.vertexCount = numOfQuads*6;
+ vbo.vertexCount = numOfQuads * 6;
return dir < 6;
}
- private int _countRemainingQuads() {
+
+ private int _countRemainingQuads()
+ {
int a = quads[dir].size() - quad;
- for (int i=dir+1; i= quads[dir].size()) {
+ if (i >= quads[dir].size())
+ {
quad = 0;
dir++;
- while (dir<6 && quads[dir].isEmpty()) dir++;
- } else {
+ while (dir < 6 && quads[dir].isEmpty())
+ dir++;
+ }
+ else
+ {
quad = i;
}
}
};
}
- public int getCurrentQuadsCount() {
+ public int getCurrentQuadsCount()
+ {
int i = 0;
- for (ArrayList qs : quads) i+=qs.size();
+ for (ArrayList qs : quads)
+ i += qs.size();
return i;
}
-
- public int getCurrentNeededVertexBuffers() {
+
+ public int getCurrentNeededVertexBuffers()
+ {
return LodUtil.ceilDiv(getCurrentQuadsCount(), MAX_QUADS_PER_BUFFER);
}
-
+
public static final int[][][] DIRECTION_VERTEX_QUAD = new int[][][] {
// X,Z
{ // UP
{ 1, 0 }, // 0
{ 1, 1 }, // 1
{ 0, 1 }, // 2
-
+
{ 1, 0 }, // 0
{ 0, 1 }, // 2
{ 0, 0 }, // 3
}, { // DOWN
- { 0, 0 }, // 0
- { 0, 1 }, // 1
- { 1, 1 }, // 2
-
- { 0, 0 }, // 0
- { 1, 1 }, // 2
- { 1, 0 }, // 3
- },
+ { 0, 0 }, // 0
+ { 0, 1 }, // 1
+ { 1, 1 }, // 2
+
+ { 0, 0 }, // 0
+ { 1, 1 }, // 2
+ { 1, 0 }, // 3
+ },
// X,Y
{ // NORTH
{ 0, 0 }, // 0
{ 0, 1 }, // 1
{ 1, 1 }, // 2
-
+
{ 0, 0 }, // 0
{ 1, 1 }, // 2
{ 1, 0 }, // 3
}, { // SOUTH
- { 1, 0 }, // 0
- { 1, 1 }, // 1
- { 0, 1 }, // 2
-
- { 1, 0 }, // 0
- { 0, 1 }, // 2
- { 0, 0 }, // 3
- },
+ { 1, 0 }, // 0
+ { 1, 1 }, // 1
+ { 0, 1 }, // 2
+
+ { 1, 0 }, // 0
+ { 0, 1 }, // 2
+ { 0, 0 }, // 3
+ },
// Z,Y
{ // WEST
{ 0, 0 }, // 0
{ 1, 0 }, // 1
{ 1, 1 }, // 2
-
+
{ 0, 0 }, // 0
{ 1, 1 }, // 2
{ 0, 1 }, // 3
}, { // EAST
- { 0, 1 }, // 0
- { 1, 1 }, // 1
- { 1, 0 }, // 2
-
- { 0, 1 }, // 0
- { 1, 0 }, // 2
- { 0, 0 }, // 3
- }, };
-
+ { 0, 1 }, // 0
+ { 1, 1 }, // 1
+ { 1, 0 }, // 2
+
+ { 0, 1 }, // 0
+ { 1, 0 }, // 2
+ { 0, 0 }, // 3
+ }, };
+
}