From e2a02357e807ad490d9690236743f4cea340e43f Mon Sep 17 00:00:00 2001 From: httpdigest Date: Thu, 18 Nov 2021 19:22:57 +0100 Subject: [PATCH] Improve cache locality of voxel accesses in GreedyMeshing and specialize determineHeight() methods for X, Y and Z --- src/org/lwjgl/demo/game/VoxelGameGL.java | 54 ++++++++++++++++-------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/src/org/lwjgl/demo/game/VoxelGameGL.java b/src/org/lwjgl/demo/game/VoxelGameGL.java index e5de673b..d6a8da30 100644 --- a/src/org/lwjgl/demo/game/VoxelGameGL.java +++ b/src/org/lwjgl/demo/game/VoxelGameGL.java @@ -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]; } @@ -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]; } @@ -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]; } @@ -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); @@ -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); @@ -375,7 +375,7 @@ 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); @@ -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) { - int h = 1; - for (; h < MAX_MERGE_LENGTH && j + h < maxV; h++) + private int determineHeightX(int c, int n, int j, int w) { + int h = 1, hs = dy; + for (; 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, hs = dz; + for (; 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, hs = dx; + for (; 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; }