Make ore algorithm readable

This commit is contained in:
Astrash 2023-10-20 10:55:23 +11:00
parent 4e5b02ef42
commit 805f99f57a

View File

@ -58,53 +58,56 @@ public class VanillaOre implements Structure {
@Override @Override
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) { public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) {
float f = random.nextFloat() * (float) Math.PI; float randomRadian = random.nextFloat() * (float) Math.PI;
double g = size / 8.0F; double eigthSize = size / 8.0F;
int i = (int) FastMath.ceil((size / 16.0F * 2.0F + 1.0F) / 2.0F);
double startX = (double) location.getX() + FastMath.sin(f) * g; // Place points to form a line segment
double endX = (double) location.getX() - FastMath.sin(f) * g; double startX = (double) location.getX() + FastMath.sin(randomRadian) * eigthSize;
double startZ = (double) location.getZ() + FastMath.cos(f) * g; double endX = (double) location.getX() - FastMath.sin(randomRadian) * eigthSize;
double endZ = (double) location.getZ() - FastMath.cos(f) * g;
double startZ = (double) location.getZ() + FastMath.cos(randomRadian) * eigthSize;
double endZ = (double) location.getZ() - FastMath.cos(randomRadian) * eigthSize;
double startY = location.getY() + random.nextInt(3) - 2; double startY = location.getY() + random.nextInt(3) - 2;
double endY = location.getY() + random.nextInt(3) - 2; double endY = location.getY() + random.nextInt(3) - 2;
int x = (int) (location.getX() - FastMath.ceil(g) - i);
int y = location.getY() - 2 - i;
int z = (int) (location.getZ() - FastMath.ceil(g) - i);
int horizontalSize = (int) (2 * (FastMath.ceil(g) + i));
int verticalSize = 2 * (2 + i);
int i1 = 0; int sizeInt = (int) size;
BitSet bitSet = new BitSet(horizontalSize * verticalSize * horizontalSize); double[] points = new double[sizeInt * 4];
int j1 = (int) size; // Compute initial point positions and radius
double[] ds = new double[j1 * 4]; for(int i = 0; i < sizeInt; ++i) {
float t = (float) i / (float) sizeInt;
for(int k1 = 0; k1 < j1; ++k1) { double xt = lerp(t, startX, endX);
float f1 = (float) k1 / (float) j1; double yt = lerp(t, startY, endY);
double d1 = lerp(f1, startX, endX); double zt = lerp(t, startZ, endZ);
double e1 = lerp(f1, startY, endY); double roll = random.nextDouble() * size / 16.0;
double g1 = lerp(f1, startZ, endZ); // Taper radius closer to line ends
double h1 = random.nextDouble() * (double) j1 / 16.0; double radius = ((FastMath.sin((float) Math.PI * t) + 1.0F) * roll + 1.0) / 2.0;
double l1 = ((FastMath.sin((float) Math.PI * f1) + 1.0F) * h1 + 1.0) / 2.0; points[i * 4] = xt;
ds[k1 * 4] = d1; points[i * 4 + 1] = yt;
ds[k1 * 4 + 1] = e1; points[i * 4 + 2] = zt;
ds[k1 * 4 + 2] = g1; points[i * 4 + 3] = radius;
ds[k1 * 4 + 3] = l1;
} }
for(int k1 = 0; k1 < j1 - 1; ++k1) { // Compare every point to every other point
if(!(ds[k1 * 4 + 3] <= 0.0)) { for(int a = 0; a < sizeInt - 1; ++a) {
for(int m1 = k1 + 1; m1 < j1; ++m1) { double radiusA = points[a * 4 + 3];
if(!(ds[m1 * 4 + 3] <= 0.0)) { if(radiusA > 0.0) {
double d1 = ds[k1 * 4] - ds[m1 * 4]; for(int b = a + 1; b < sizeInt; ++b) {
double e1 = ds[k1 * 4 + 1] - ds[m1 * 4 + 1]; double radiusB = points[b * 4 + 3];
double g1 = ds[k1 * 4 + 2] - ds[m1 * 4 + 2]; if(radiusB > 0.0) {
double h1 = ds[k1 * 4 + 3] - ds[m1 * 4 + 3]; double dxt = points[a * 4] - points[b * 4];
if(h1 * h1 > d1 * d1 + e1 * e1 + g1 * g1) { double dyt = points[a * 4 + 1] - points[b * 4 + 1];
if(h1 > 0.0) { double dzt = points[a * 4 + 2] - points[b * 4 + 2];
ds[m1 * 4 + 3] = -1.0; double dRadius = radiusA - radiusB;
// If the radius difference is greater than the distance between the two points
if(dRadius * dRadius > dxt * dxt + dyt * dyt + dzt * dzt) {
// Set smaller of two radii to -1
if(dRadius > 0.0) {
points[b * 4 + 3] = -1.0;
} else { } else {
ds[k1 * 4 + 3] = -1.0; points[a * 4 + 3] = -1.0;
} }
} }
} }
@ -112,37 +115,54 @@ public class VanillaOre implements Structure {
} }
} }
for(int m1 = 0; m1 < j1; ++m1) { int outset = (int) FastMath.ceil((size / 16.0F * 2.0F + 1.0F) / 2.0F);
double d1 = ds[m1 * 4 + 3]; int x = (int) (location.getX() - FastMath.ceil(eigthSize) - outset);
if(!(d1 < 0.0)) { int y = location.getY() - 2 - outset;
double e1 = ds[m1 * 4]; int z = (int) (location.getZ() - FastMath.ceil(eigthSize) - outset);
double g1 = ds[m1 * 4 + 1];
double h1 = ds[m1 * 4 + 2];
int n1 = (int) FastMath.max(FastMath.floor(e1 - d1), x);
int o1 = (int) FastMath.max(FastMath.floor(g1 - d1), y);
int p1 = (int) FastMath.max(FastMath.floor(h1 - d1), z);
int q1 = (int) FastMath.max(FastMath.floor(e1 + d1), n1);
int r1 = (int) FastMath.max(FastMath.floor(g1 + d1), o1);
int s1 = (int) FastMath.max(FastMath.floor(h1 + d1), p1);
for(int t1 = n1; t1 <= q1; ++t1) { int horizontalSize = (int) (2 * (FastMath.ceil(eigthSize) + outset));
double u1 = ((double) t1 + 0.5 - e1) / d1; int verticalSize = 2 * (2 + outset);
if(u1 * u1 < 1.0) {
for(int v1 = o1; v1 <= r1; ++v1) {
double w1 = ((double) v1 + 0.5 - g1) / d1;
if(u1 * u1 + w1 * w1 < 1.0) {
for(int aa = p1; aa <= s1; ++aa) {
double ab = ((double) aa + 0.5 - h1) / d1;
if(u1 * u1 + w1 * w1 + ab * ab < 1.0 && !(v1 < world.getMinHeight() || v1 >= world.getMaxHeight())) {
int ac = t1 - x + (v1 - y) * horizontalSize + (aa - z) * horizontalSize * verticalSize;
if(!bitSet.get(ac)) {
bitSet.set(ac);
BlockType block = world.getBlockState(t1, v1, aa).getBlockType(); int sphereCount = 0;
BitSet visited = new BitSet(horizontalSize * verticalSize * horizontalSize);
if(shouldPlace(block, random, world, t1, v1, aa)) { // Generate a sphere at each point
world.setBlockState(t1, v1, aa, getMaterial(block), isApplyGravity()); for(int i = 0; i < sizeInt; ++i) {
++i1; double radius = points[i * 4 + 3];
if(radius > 0.0) {
double xt = points[i * 4];
double yt = points[i * 4 + 1];
double zt = points[i * 4 + 2];
int xLowerBound = (int) FastMath.max(FastMath.floor(xt - radius), x);
int xUpperBound = (int) FastMath.max(FastMath.floor(xt + radius), xLowerBound);
int yLowerBound = (int) FastMath.max(FastMath.floor(yt - radius), y);
int yUpperBound = (int) FastMath.max(FastMath.floor(yt + radius), yLowerBound);
int zLowerBound = (int) FastMath.max(FastMath.floor(zt - radius), z);
int zUpperBound = (int) FastMath.max(FastMath.floor(zt + radius), zLowerBound);
// Iterate over coordinates within bounds
for(int xi = xLowerBound; xi <= xUpperBound; ++xi) {
double dx = ((double) xi + 0.5 - xt) / radius;
if(dx * dx < 1.0) {
for(int yi = yLowerBound; yi <= yUpperBound; ++yi) {
double dy = ((double) yi + 0.5 - yt) / radius;
if(dx * dx + dy * dy < 1.0) {
for(int zi = zLowerBound; zi <= zUpperBound; ++zi) {
double dz = ((double) zi + 0.5 - zt) / radius;
// If position is inside the sphere
if(dx * dx + dy * dy + dz * dz < 1.0 && !(yi < world.getMinHeight() || yi >= world.getMaxHeight())) {
int index = xi - x + (yi - y) * horizontalSize + (zi - z) * horizontalSize * verticalSize;
if(!visited.get(index)) { // Skip blocks that have already been visited
visited.set(index);
BlockType block = world.getBlockState(xi, yi, zi).getBlockType();
if(shouldPlace(block, random, world, xi, yi, zi)) {
world.setBlockState(xi, yi, zi, getMaterial(block), isApplyGravity());
++sphereCount;
break; break;
} }
} }
@ -155,8 +175,7 @@ public class VanillaOre implements Structure {
} }
} }
return sphereCount > 0;
return i1 > 0;
} }
public boolean shouldPlace(BlockType type, Random random, WritableWorld world, int x, int y, int z) { public boolean shouldPlace(BlockType type, Random random, WritableWorld world, int x, int y, int z) {