Skip to content

Commit

Permalink
Improve cache locality of voxel accesses in GreedyMeshing
Browse files Browse the repository at this point in the history
and specialize determineHeight() methods for X, Y and Z
  • Loading branch information
httpdigest committed Nov 19, 2021
1 parent 6413a2f commit 986d9da
Showing 1 changed file with 37 additions and 19 deletions.
56 changes: 37 additions & 19 deletions src/org/lwjgl/demo/game/VoxelGameGL.java
Original file line number Diff line number Diff line change
Expand Up @@ -268,14 +268,14 @@ else if (a != 0) {

private int neighborsX(int x, int y, int z) {
/* UV = YZ */
int n0 = at(x, y, z - 1) != 0 ? 1 : 0;
int n1 = at(x, y - 1, z - 1) != 0 ? 2 : 0;
int n2 = at(x, y - 1, z) != 0 ? 4 : 0;
int n3 = at(x, y - 1, z + 1) != 0 ? 8 : 0;
int n0 = at(x, y, z - 1) != 0 ? 1 : 0;
int n4 = at(x, y, z + 1) != 0 ? 16 : 0;
int n5 = at(x, y + 1, z + 1) != 0 ? 32 : 0;
int n6 = at(x, y + 1, z) != 0 ? 64 : 0;
int n7 = at(x, y + 1, z - 1) != 0 ? 128 : 0;
int n6 = at(x, y + 1, z) != 0 ? 64 : 0;
int n5 = at(x, y + 1, z + 1) != 0 ? 32 : 0;
return NEIGHBOR_CONFIGS[n0 | n1 | n2 | n3 | n4 | n5 | n6 | n7];
}

Expand All @@ -291,14 +291,14 @@ else if (a != 0) {

private int neighborsY(int x, int y, int z) {
/* UV = ZX */
int n0 = at(x - 1, y, z) != 0 ? 1 : 0;
int n1 = at(x - 1, y, z - 1) != 0 ? 2 : 0;
int n2 = at(x, y, z - 1) != 0 ? 4 : 0;
int n3 = at(x + 1, y, z - 1) != 0 ? 8 : 0;
int n4 = at(x + 1, y, z) != 0 ? 16 : 0;
int n5 = at(x + 1, y, z + 1) != 0 ? 32 : 0;
int n0 = at(x - 1, y, z) != 0 ? 1 : 0;
int n6 = at(x, y, z + 1) != 0 ? 64 : 0;
int n4 = at(x + 1, y, z) != 0 ? 16 : 0;
int n7 = at(x - 1, y, z + 1) != 0 ? 128 : 0;
int n5 = at(x + 1, y, z + 1) != 0 ? 32 : 0;
return NEIGHBOR_CONFIGS[n0 | n1 | n2 | n3 | n4 | n5 | n6 | n7];
}

Expand All @@ -314,14 +314,14 @@ else if (a != 0)

private int neighborsZ(int x, int y, int z) {
/* UV = XY */
int n0 = at(x, y - 1, z) != 0 ? 1 : 0;
int n1 = at(x - 1, y - 1, z) != 0 ? 2 : 0;
int n0 = at(x, y - 1, z) != 0 ? 1 : 0;
int n7 = at(x + 1, y - 1, z) != 0 ? 128 : 0;
int n2 = at(x - 1, y, z) != 0 ? 4 : 0;
int n6 = at(x + 1, y, z) != 0 ? 64 : 0;
int n3 = at(x - 1, y + 1, z) != 0 ? 8 : 0;
int n4 = at(x, y + 1, z) != 0 ? 16 : 0;
int n5 = at(x + 1, y + 1, z) != 0 ? 32 : 0;
int n6 = at(x + 1, y, z) != 0 ? 64 : 0;
int n7 = at(x + 1, y - 1, z) != 0 ? 128 : 0;
return NEIGHBOR_CONFIGS[n0 | n1 | n2 | n3 | n4 | n5 | n6 | n7];
}

Expand Down Expand Up @@ -351,7 +351,7 @@ private int mergeAndGenerateFaceX(FaceConsumer faces, int x, int n, int i, int j
if (mn == 0)
return 1;
int w = determineWidthX(mn, n, i);
int h = determineHeight(mn, n, j, w, dy, dz);
int h = determineHeightX(mn, n, j, w);
faces.consume(i, j, i + w, j + h, x, mn > 0 ? 1 : 0, mn);
count++;
eraseMask(n, w, h, dy);
Expand All @@ -363,7 +363,7 @@ private int mergeAndGenerateFaceY(FaceConsumer faces, int y, int n, int i, int j
if (mn == 0)
return 1;
int w = determineWidthY(mn, n, i);
int h = determineHeight(mn, n, j, w, dz, dx);
int h = determineHeightY(mn, n, j, w);
faces.consume(i, j, i + w, j + h, y, 2 + (mn > 0 ? 1 : 0), mn);
count++;
eraseMask(n, w, h, dz);
Expand All @@ -375,17 +375,17 @@ private int mergeAndGenerateFaceZ(FaceConsumer faces, int z, int n, int i, int j
if (mn == 0)
return 1;
int w = determineWidthZ(mn, n, i);
int h = determineHeight(mn, n, j, w, dx, py);
int h = determineHeightZ(mn, n, j, w);
faces.consume(i, j, i + w, j + h, z, 4 + (mn > 0 ? 1 : 0), mn);
count++;
eraseMask(n, w, h, dx);
return w;
}

private void eraseMask(int n, int w, int h, int d) {
for (int l = 0; l < h; l++)
for (int l = 0, ls = 0; l < h; l++, ls += d)
for (int k = 0; k < w; k++)
m[n + k + l * d] = 0;
m[n + k + ls] = 0;
}

private int determineWidthX(int c, int n, int i) {
Expand All @@ -397,23 +397,41 @@ private int determineWidthX(int c, int n, int i) {

private int determineWidthY(int c, int n, int i) {
int w = 1;
for (; w < MAX_MERGE_LENGTH && i + w < dz && c == m[n + w]; w++)
for (; i + w < dz && c == m[n + w]; w++)
;
return w;
}

private int determineWidthZ(int c, int n, int i) {
int w = 1;
for (; w < MAX_MERGE_LENGTH && i + w < dx && c == m[n + w]; w++)
for (; i + w < dx && c == m[n + w]; w++)
;
return w;
}

private int determineHeight(int c, int n, int j, int w, int du, int maxV) {
private int determineHeightX(int c, int n, int j, int w) {
int h = 1;
for (int hs = dy; j + h < dz; h++, hs += dy)
for (int k = 0; k < w; k++)
if (c != m[n + k + hs])
return h;
return h;
}

private int determineHeightY(int c, int n, int j, int w) {
int h = 1;
for (int hs = dz; j + h < dx; h++, hs += dz)
for (int k = 0; k < w; k++)
if (c != m[n + k + hs])
return h;
return h;
}

private int determineHeightZ(int c, int n, int j, int w) {
int h = 1;
for (; h < MAX_MERGE_LENGTH && j + h < maxV; h++)
for (int hs = dx; h < MAX_MERGE_LENGTH && j + h < py; h++, hs += dx)
for (int k = 0; k < w; k++)
if (c != m[n + k + h * du])
if (c != m[n + k + hs])
return h;
return h;
}
Expand Down

0 comments on commit 986d9da

Please sign in to comment.