From 476ba4ab418648ed6d5f3a91bba6f9c78d5dede2 Mon Sep 17 00:00:00 2001 From: Jordan Date: Tue, 27 Jun 2023 17:36:54 +0100 Subject: [PATCH] refactor: efficiency improvements to some editsession methods (#2304) --- .../java/com/sk89q/worldedit/EditSession.java | 273 +++++++++++------- 1 file changed, 172 insertions(+), 101 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index 1b405fe75..f8a08148b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -2161,10 +2161,12 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { final int ceilRadiusX = (int) Math.ceil(radiusX); final int ceilRadiusZ = (int) Math.ceil(radiusZ); - double xSqr; - double zSqr; - double distanceSq; + double xSqr, zSqr, distanceSq; + double xn, zn; + double dx2, dz2; double nextXn = 0; + double nextZn, nextMinZn; + int xx, x_x, zz, z_z, yy; if (thickness != 0) { double nextMinXn = 0; @@ -2172,19 +2174,18 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { final double minInvRadiusZ = 1 / (radiusZ - thickness); forX: for (int x = 0; x <= ceilRadiusX; ++x) { - final double xn = nextXn; - double dx2 = nextMinXn * nextMinXn; + xn = nextXn; + dx2 = nextMinXn * nextMinXn; nextXn = (x + 1) * invRadiusX; nextMinXn = (x + 1) * minInvRadiusX; - double nextZn = 0; - double nextMinZn = 0; + nextZn = 0; + nextMinZn = 0; xSqr = xn * xn; + xx = px + x; + x_x = px - x; forZ: for (int z = 0; z <= ceilRadiusZ; ++z) { - final double zn = nextZn; - double dz2 = nextMinZn * nextMinZn; - nextZn = (z + 1) * invRadiusZ; - nextMinZn = (z + 1) * minInvRadiusZ; + zn = nextZn; zSqr = zn * zn; distanceSq = xSqr + zSqr; if (distanceSq > 1) { @@ -2193,16 +2194,23 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { } break forZ; } + dz2 = nextMinZn * nextMinZn; + nextZn = (z + 1) * invRadiusZ; + nextMinZn = (z + 1) * minInvRadiusZ; if ((dz2 + nextMinXn * nextMinXn <= 1) && (nextMinZn * nextMinZn + dx2 <= 1)) { continue; } + zz = pz + z; + z_z = pz - z; + for (int y = 0; y < height; ++y) { - this.setBlock(mutableBlockVector3.setComponents(px + x, py + y, pz + z), block); - this.setBlock(mutableBlockVector3.setComponents(px - x, py + y, pz + z), block); - this.setBlock(mutableBlockVector3.setComponents(px + x, py + y, pz - z), block); - this.setBlock(mutableBlockVector3.setComponents(px - x, py + y, pz - z), block); + yy = py + y; + this.setBlock(xx, yy, zz, block); + this.setBlock(x_x, yy, zz, block); + this.setBlock(xx, yy, z_z, block); + this.setBlock(x_x, yy, z_z, block); } } } @@ -2210,14 +2218,17 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { //FAWE end forX: for (int x = 0; x <= ceilRadiusX; ++x) { - final double xn = nextXn; + xn = nextXn; nextXn = (x + 1) * invRadiusX; - double nextZn = 0; + nextZn = 0; xSqr = xn * xn; + // FAWE start + xx = px + x; + x_x = px - x; + //FAWE end forZ: for (int z = 0; z <= ceilRadiusZ; ++z) { - final double zn = nextZn; - nextZn = (z + 1) * invRadiusZ; + zn = nextZn; zSqr = zn * zn; distanceSq = xSqr + zSqr; if (distanceSq > 1) { @@ -2227,18 +2238,27 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { break forZ; } + // FAWE start + nextZn = (z + 1) * invRadiusZ; + //FAWE end if (!filled) { if ((zSqr + nextXn * nextXn <= 1) && (nextZn * nextZn + xSqr <= 1)) { continue; } } + //FAWE start + zz = pz + z; + z_z = pz - z; + //FAWE end + for (int y = 0; y < height; ++y) { - //FAWE start - mutable - this.setBlock(mutableBlockVector3.setComponents(px + x, py + y, pz + z), block); - this.setBlock(mutableBlockVector3.setComponents(px - x, py + y, pz + z), block); - this.setBlock(mutableBlockVector3.setComponents(px + x, py + y, pz - z), block); - this.setBlock(mutableBlockVector3.setComponents(px - x, py + y, pz - z), block); + //FAWE start + yy = py + y; + this.setBlock(xx, yy, zz, block); + this.setBlock(x_x, yy, zz, block); + this.setBlock(xx, yy, z_z, block); + this.setBlock(x_x, yy, z_z, block); //FAWE end } } @@ -2293,7 +2313,6 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { int px = pos.getBlockX(); int py = pos.getBlockY(); int pz = pos.getBlockZ(); - MutableBlockVector3 mutable = new MutableBlockVector3(); final int ceilRadiusX = (int) Math.ceil(radiusX); final int ceilRadiusY = (int) Math.ceil(radiusY); @@ -2301,31 +2320,43 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { double threshold = 0.5; + double dx, dy, dz, dxy, dxz, dyz, dxyz; + int xx, x_x, yy, y_y, zz, z_z; + double xnx, yny, znz; double nextXn = 0; - double dx; - double dy; - double dz; - double dxy; - double dxyz; + double nextYn, nextZn; + double nextXnSq, nextYnSq, nextZnSq; + double xn, yn, zn; forX: for (int x = 0; x <= ceilRadiusX; ++x) { - final double xn = nextXn; + xn = nextXn; dx = xn * xn; nextXn = (x + 1) * invRadiusX; - double nextYn = 0; + nextXnSq = nextXn * nextXn; + nextYn = 0; + xx = px + x; + x_x = px - x; + xnx = x * nx; forY: for (int y = 0; y <= ceilRadiusY; ++y) { - final double yn = nextYn; + yn = nextYn; dy = yn * yn; dxy = dx + dy; nextYn = (y + 1) * invRadiusY; - double nextZn = 0; + nextYnSq = nextYn * nextYn; + nextZn = 0; + yy = py + y; + y_y = py - y; + yny = y * ny; forZ: for (int z = 0; z <= ceilRadiusZ; ++z) { - final double zn = nextZn; + zn = nextZn; dz = zn * zn; dxyz = dxy + dz; + dxz = dx + dz; + dyz = dy + dz; nextZn = (z + 1) * invRadiusZ; + nextZnSq = nextZn * nextZn; if (dxyz > 1) { if (z == 0) { if (y == 0) { @@ -2336,34 +2367,37 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { break forZ; } if (!filled) { - if (nextXn * nextXn + dy + dz <= 1 && nextYn * nextYn + dx + dz <= 1 && nextZn * nextZn + dx + dy <= 1) { + if (nextXnSq + dyz <= 1 && nextYnSq + dxz <= 1 && nextZnSq + dxy <= 1) { continue; } } + zz = pz + z; + z_z = pz - z; + znz = z * nz; - if (Math.abs((x) * nx + (y) * ny + (z) * nz) < threshold) { - setBlock(mutable.setComponents(px + x, py + y, pz + z), block); + if (Math.abs(xnx + yny + znz) < threshold) { + setBlock(xx, yy, zz, block); } - if (Math.abs((-x) * nx + (y) * ny + (z) * nz) < threshold) { - setBlock(mutable.setComponents(px - x, py + y, pz + z), block); + if (Math.abs(-xnx + yny + znz) < threshold) { + setBlock(x_x, yy, zz, block); } - if (Math.abs((x) * nx + (-y) * ny + (z) * nz) < threshold) { - setBlock(mutable.setComponents(px + x, py - y, pz + z), block); + if (Math.abs(xnx - yny + znz) < threshold) { + setBlock(xx, y_y, zz, block); } - if (Math.abs((x) * nx + (y) * ny + (-z) * nz) < threshold) { - setBlock(mutable.setComponents(px + x, py + y, pz - z), block); + if (Math.abs(xnx + yny - znz) < threshold) { + setBlock(xx, yy, z_z, block); } - if (Math.abs((-x) * nx + (-y) * ny + (z) * nz) < threshold) { - setBlock(mutable.setComponents(px - x, py - y, pz + z), block); + if (Math.abs(-xnx - yny + znz) < threshold) { + setBlock(x_x, y_y, zz, block); } - if (Math.abs((x) * nx + (-y) * ny + (-z) * nz) < threshold) { - setBlock(mutable.setComponents(px + x, py - y, pz - z), block); + if (Math.abs(xnx - yny - znz) < threshold) { + setBlock(xx, y_y, z_z, block); } - if (Math.abs((-x) * nx + (y) * ny + (-z) * nz) < threshold) { - setBlock(mutable.setComponents(px - x, py + y, pz - z), block); + if (Math.abs(-xnx + yny - znz) < threshold) { + setBlock(x_x, yy, z_z, block); } - if (Math.abs((-x) * nx + (-y) * ny + (-z) * nz) < threshold) { - setBlock(mutable.setComponents(px - x, py - y, pz - z), block); + if (Math.abs(-xnx - yny - znz) < threshold) { + setBlock(x_x, y_y, z_z, block); } } } @@ -2418,29 +2452,38 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { final int ceilRadiusZ = (int) Math.ceil(radiusZ); //FAWE start - int yy; - //FAWE end - double nextXn = 0; + double nextYn, nextZn; + double nextXnSq, nextYnSq, nextZnSq; + double xn, yn, zn, dx, dy, dz; + double dxy, dxz, dyz, dxyz; + int xx, x_x, yy, zz, z_z; + forX: for (int x = 0; x <= ceilRadiusX; ++x) { - final double xn = nextXn; - double dx = xn * xn; + xn = nextXn; + dx = xn * xn; nextXn = (x + 1) * invRadiusX; - double nextZn = 0; + nextXnSq = nextXn * nextXn; + xx = px + x; + x_x = px - x; + nextZn = 0; forZ: for (int z = 0; z <= ceilRadiusZ; ++z) { - final double zn = nextZn; - double dz = zn * zn; - double dxz = dx + dz; + zn = nextZn; + dz = zn * zn; + dxz = dx + dz; nextZn = (z + 1) * invRadiusZ; - double nextYn = 0; + nextZnSq = nextZn * nextZn; + zz = pz + z; + z_z = pz - z; + nextYn = 0; forY: for (int y = 0; y <= ceilRadiusY; ++y) { - final double yn = nextYn; - double dy = yn * yn; - double dxyz = dxz + dy; + yn = nextYn; + dy = yn * yn; + dxyz = dxz + dy; nextYn = (y + 1) * invRadiusY; if (dxyz > 1) { @@ -2453,40 +2496,45 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { break forY; } + nextYnSq = nextYn * nextYn; + dxy = dx + dy; + dyz = dy + dz; + if (!filled) { - if (nextXn * nextXn + dy + dz <= 1 && nextYn * nextYn + dx + dz <= 1 && nextZn * nextZn + dx + dy <= 1) { + if (nextXnSq + dyz <= 1 && nextYnSq + dxz <= 1 && nextZnSq + dxy <= 1) { continue; } } //FAWE start yy = py + y; if (yy <= maxY) { - this.setBlock(px + x, py + y, pz + z, block); + this.setBlock(xx, yy, zz, block); if (x != 0) { - this.setBlock(px - x, py + y, pz + z, block); + this.setBlock(x_x, yy, zz, block); } if (z != 0) { - this.setBlock(px + x, py + y, pz - z, block); + this.setBlock(xx, yy, z_z, block); if (x != 0) { - this.setBlock(px - x, py + y, pz - z, block); + this.setBlock(x_x, yy, z_z, block); } } } if (y != 0 && (yy = py - y) >= minY) { - this.setBlock(px + x, yy, pz + z, block); + this.setBlock(xx, yy, zz, block); if (x != 0) { - this.setBlock(px - x, yy, pz + z, block); + this.setBlock(x_x, yy, zz, block); } if (z != 0) { - this.setBlock(px + x, yy, pz - z, block); + this.setBlock(xx, yy, z_z, block); if (x != 0) { - this.setBlock(px - x, yy, pz - z, block); + this.setBlock(x_x, yy, z_z, block); } } } } } } + //FAWE end return changes; //FAWE end @@ -2509,17 +2557,22 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { int bz = position.getZ(); int height = size; + int yy, xx, x_x, zz, z_z; for (int y = 0; y <= height; ++y) { size--; + yy = y + by; for (int x = 0; x <= size; ++x) { + xx = bx + x; + x_x = bx - x; for (int z = 0; z <= size; ++z) { - + zz = bz + z; + z_z = bz - z; if ((filled && z <= size && x <= size) || z == size || x == size) { - setBlock(x + bx, y + by, z + bz, block); - setBlock(-x + bx, y + by, z + bz, block); - setBlock(x + bx, y + by, -z + bz, block); - setBlock(-x + bx, y + by, -z + bz, block); + setBlock(xx, yy, zz, block); + setBlock(x_x, yy, zz, block); + setBlock(xx, yy, z_z, block); + setBlock(x_x, yy, z_z, block); } } } @@ -3774,19 +3827,28 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { int radiusSqr = (int) (size * size); int sizeInt = (int) size * 2; + int xx, yy, zz; + double distance; + double noise; + if (sphericity == 1) { + double nx, ny, nz; + double d1, d2; for (int x = -sizeInt; x <= sizeInt; x++) { - double nx = seedX + x * distort; - double d1 = x * x * modX; + nx = seedX + x * distort; + d1 = x * x * modX; + xx = px + x; for (int y = -sizeInt; y <= sizeInt; y++) { - double d2 = d1 + y * y * modY; - double ny = seedY + y * distort; + d2 = d1 + y * y * modY; + ny = seedY + y * distort; + yy = py + y; for (int z = -sizeInt; z <= sizeInt; z++) { - double nz = seedZ + z * distort; - double distance = d2 + z * z * modZ; - double noise = amplitude * SimplexNoise.noise(nx, ny, nz); + nz = seedZ + z * distort; + distance = d2 + z * z * modZ; + zz = pz + z; + noise = amplitude * SimplexNoise.noise(nx, ny, nz); if (distance + distance * noise < radiusSqr) { - setBlock(px + x, py + y, pz + z, pattern); + setBlock(xx, yy, zz, pattern); } } } @@ -3803,39 +3865,48 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { MutableVector3 mutable = new MutableVector3(); double roughness = 1 - sphericity; + int x; + int y; + int z; + double xScaled; + double yScaled; + double zScaled; + double manDist; + double distSqr; for (int xr = -sizeInt; xr <= sizeInt; xr++) { + xx = px + xr; for (int yr = -sizeInt; yr <= sizeInt; yr++) { + yy = py + yr; for (int zr = -sizeInt; zr <= sizeInt; zr++) { + zz = pz + zr; // pt == mutable as it's a MutableVector3 // so it must be set each time - mutable.mutX(xr); - mutable.mutY(yr); - mutable.mutZ(zr); + mutable.setComponents(xr, yr, zr); Vector3 pt = transform.apply(mutable); - int x = MathMan.roundInt(pt.getX()); - int y = MathMan.roundInt(pt.getY()); - int z = MathMan.roundInt(pt.getZ()); + x = MathMan.roundInt(pt.getX()); + y = MathMan.roundInt(pt.getY()); + z = MathMan.roundInt(pt.getZ()); - double xScaled = Math.abs(x) * modX; - double yScaled = Math.abs(y) * modY; - double zScaled = Math.abs(z) * modZ; - double manDist = xScaled + yScaled + zScaled; - double distSqr = x * x * modX + z * z * modZ + y * y * modY; + xScaled = Math.abs(x) * modX; + yScaled = Math.abs(y) * modY; + zScaled = Math.abs(z) * modZ; + manDist = xScaled + yScaled + zScaled; + distSqr = x * x * modX + z * z * modZ + y * y * modY; - double distance = Math.sqrt(distSqr) * sphericity + MathMan.max( + distance = Math.sqrt(distSqr) * sphericity + MathMan.max( manDist, xScaled * manScaleX, yScaled * manScaleY, zScaled * manScaleZ ) * roughness; - double noise = amplitude * SimplexNoise.noise( + noise = amplitude * SimplexNoise.noise( seedX + x * distort, seedZ + z * distort, seedZ + z * distort ); if (distance + distance * noise < r) { - setBlock(px + xr, py + yr, pz + zr, pattern); + setBlock(xx, yy, zz, pattern); } } }