Slight optimizations to the mesher

This commit is contained in:
mcrcortex
2024-02-20 12:32:56 +10:00
parent e778fce6d6
commit 81e2acb995

View File

@@ -8,14 +8,19 @@ public class Mesher2D {
private final int size; private final int size;
private final int maxSize; private final int maxSize;
private final long[] data; private final long[] data;
private final BitSet setset; private final long[] setset;
private int[] quadCache; private int[] quadCache;
private boolean isEmpty = true; private boolean isEmpty = true;
private int setsMsk = 0;
public Mesher2D(int sizeBits, int maxSize) { public Mesher2D(int sizeBits, int maxSize) {
if (sizeBits > 5) {
throw new IllegalStateException("Due to the addition of the setsMsk, size greter than 32 is not supported atm");
}
this.size = sizeBits; this.size = sizeBits;
this.maxSize = maxSize; this.maxSize = maxSize;
this.data = new long[1<<(sizeBits<<1)]; this.data = new long[1<<(sizeBits<<1)];
this.setset = new BitSet(1<<(sizeBits<<1)); this.setset = new long[(1<<(sizeBits<<1))>>6];
this.quadCache = new int[128]; this.quadCache = new int[128];
} }
@@ -31,7 +36,8 @@ public class Mesher2D {
this.isEmpty = false; this.isEmpty = false;
int idx = this.getIdx(x, z); int idx = this.getIdx(x, z);
this.data[idx] = data; this.data[idx] = data;
this.setset.set(idx); this.setset[idx>>6] |= 1L<<(idx&0b111111);
this.setsMsk |= 1<<(idx>>6);
return this; return this;
} }
@@ -58,7 +64,18 @@ public class Mesher2D {
private boolean canMerge(int x, int z, long match) { private boolean canMerge(int x, int z, long match) {
int id = this.getIdx(x, z); int id = this.getIdx(x, z);
return this.setset.get(id) && this.data[id] == match; return (this.setset[id>>6]&(1L<<(id&0b111111))) != 0 && this.data[id] == match;
}
private int nextSetBit(int base) {
int wPos = Integer.numberOfTrailingZeros(this.setsMsk>>>(base>>6))+(base>>6);
while (wPos != 16) {
long word = this.setset[wPos++];
if (word != 0) {
return Long.numberOfTrailingZeros(word) + ((wPos-1)<<6);
}
}
return -1;
} }
//Returns the number of compacted quads //Returns the number of compacted quads
@@ -71,7 +88,7 @@ public class Mesher2D {
int idxCount = 0; int idxCount = 0;
//TODO: add different strategies/ways to mesh //TODO: add different strategies/ways to mesh
int posId = this.data[0] == 0?this.setset.nextSetBit(0):0; int posId = this.data[0] == 0?this.nextSetBit(0):0;
while (posId < this.data.length && posId != -1) { while (posId < this.data.length && posId != -1) {
int idx = posId; int idx = posId;
long data = this.data[idx]; long data = this.data[idx];
@@ -95,6 +112,7 @@ public class Mesher2D {
for (int tz = z; tz < endZ+1; tz++) { for (int tz = z; tz < endZ+1; tz++) {
if (!this.canMerge(endX + 1, tz, data)) { if (!this.canMerge(endX + 1, tz, data)) {
ex = false; ex = false;
break;
} }
} }
} }
@@ -110,6 +128,7 @@ public class Mesher2D {
for (int tx = x; tx < endX+1; tx++) { for (int tx = x; tx < endX+1; tx++) {
if (!this.canMerge(tx, endZ + 1, data)) { if (!this.canMerge(tx, endZ + 1, data)) {
ez = false; ez = false;
break;
} }
} }
} }
@@ -121,7 +140,8 @@ public class Mesher2D {
//Mark the sections as meshed //Mark the sections as meshed
for (int mx = x; mx <= endX; mx++) { for (int mx = x; mx <= endX; mx++) {
for (int mz = z; mz <= endZ; mz++) { for (int mz = z; mz <= endZ; mz++) {
this.setset.clear(this.getIdx(mx, mz)); int cid = this.getIdx(mx, mz);
this.setset[cid>>6] &= ~(1L<<(cid&0b111111));
} }
} }
@@ -136,9 +156,7 @@ public class Mesher2D {
} }
quads[pIdx] = encodedQuad; quads[pIdx] = encodedQuad;
} }
posId = this.nextSetBit(posId);
posId = this.setset.nextSetBit(posId);
} }
this.quadCache = quads; this.quadCache = quads;
@@ -152,7 +170,8 @@ public class Mesher2D {
public void reset() { public void reset() {
if (!this.isEmpty) { if (!this.isEmpty) {
this.isEmpty = true; this.isEmpty = true;
this.setset.clear(); this.setsMsk = 0;
Arrays.fill(this.setset, 0);
Arrays.fill(this.data, 0); Arrays.fill(this.data, 0);
} }
} }
@@ -165,7 +184,7 @@ public class Mesher2D {
return this.data[this.getIdx(x, z)]; return this.data[this.getIdx(x, z)];
} }
public static void main(String[] args) { public static void main3(String[] args) {
var mesh = new Mesher2D(5,15); var mesh = new Mesher2D(5,15);
mesh.put(30,30, 123); mesh.put(30,30, 123);
mesh.put(31,30, 123); mesh.put(31,30, 123);
@@ -176,6 +195,43 @@ public class Mesher2D {
System.err.println(count); System.err.println(count);
} }
public static void main(String[] args) {
var r = new Random(123451);
var mesh = new Mesher2D(5,15);
/*
for (int j = 0; j < 512; j++) {
mesh.put(r.nextInt(32), r.nextInt(32), r.nextInt(10));
}
*/
int cnt = 0;
for (int i = 0; i < 12000; i++) {
for (int j = 0; j < 512; j++) {
mesh.put(r.nextInt(32), r.nextInt(32), r.nextInt(32));
}
cnt += mesh.process();
mesh.reset();
}
cnt = 0;
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 15; z++) {
mesh.put(x, z, 134);
}
}
mesh.put(31, 31, 134);
cnt += mesh.process();
mesh.reset();
}
System.err.println(cnt);
System.err.println(System.currentTimeMillis()-start);
var dat = mesh.getArray();
//for (int i = 0; i < cnt; i++) {
// var q = dat[i];
// System.err.println("X: " + getX(q) + " Z: " + getZ(q) + " W: " + getW(q) + " H: " + getH(q));
//}
}
public static void main2(String[] args) { public static void main2(String[] args) {
var r = new Random(123451); var r = new Random(123451);
int a = 0; int a = 0;