149 lines
5.4 KiB
Java
149 lines
5.4 KiB
Java
package com.hypixel.hytale.math.block;
|
|
|
|
import com.hypixel.hytale.function.predicate.TriIntObjPredicate;
|
|
import javax.annotation.Nonnull;
|
|
import javax.annotation.Nullable;
|
|
|
|
public class BlockInvertedDomeUtil {
|
|
public static <T> boolean forEachBlock(
|
|
int originX, int originY, int originZ, int radiusX, int radiusY, int radiusZ, @Nullable T t, @Nonnull TriIntObjPredicate<T> consumer
|
|
) {
|
|
if (radiusX <= 0) {
|
|
throw new IllegalArgumentException(String.valueOf(radiusX));
|
|
} else if (radiusY <= 0) {
|
|
throw new IllegalArgumentException(String.valueOf(radiusY));
|
|
} else if (radiusZ <= 0) {
|
|
throw new IllegalArgumentException(String.valueOf(radiusZ));
|
|
} else {
|
|
float radiusXAdjusted = radiusX + 0.41F;
|
|
float radiusYAdjusted = radiusY + 0.41F;
|
|
float radiusZAdjusted = radiusZ + 0.41F;
|
|
float invRadiusXSqr = 1.0F / (radiusXAdjusted * radiusXAdjusted);
|
|
float invRadiusYSqr = 1.0F / (radiusYAdjusted * radiusYAdjusted);
|
|
|
|
for (int x = 0; x <= radiusX; x++) {
|
|
float qx = 1.0F - x * x * invRadiusXSqr;
|
|
double dy = Math.sqrt(qx) * radiusYAdjusted;
|
|
int maxY = (int)dy;
|
|
|
|
for (int y = 0; y <= maxY; y++) {
|
|
double dz = Math.sqrt(qx - y * y * invRadiusYSqr) * radiusZAdjusted;
|
|
int maxZ = (int)dz;
|
|
|
|
for (int z = 0; z <= maxZ; z++) {
|
|
if (!test(originX, originY, originZ, x, -y, z, t, consumer)) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public static <T> boolean forEachBlock(
|
|
int originX,
|
|
int originY,
|
|
int originZ,
|
|
int radiusX,
|
|
int radiusY,
|
|
int radiusZ,
|
|
int thickness,
|
|
boolean capped,
|
|
@Nullable T t,
|
|
@Nonnull TriIntObjPredicate<T> consumer
|
|
) {
|
|
if (thickness < 1) {
|
|
return forEachBlock(originX, originY, originZ, radiusX, radiusY, radiusZ, t, consumer);
|
|
} else if (radiusX <= 0) {
|
|
throw new IllegalArgumentException(String.valueOf(radiusX));
|
|
} else if (radiusY <= 0) {
|
|
throw new IllegalArgumentException(String.valueOf(radiusY));
|
|
} else if (radiusZ <= 0) {
|
|
throw new IllegalArgumentException(String.valueOf(radiusZ));
|
|
} else {
|
|
float radiusXAdjusted = radiusX + 0.41F;
|
|
float radiusYAdjusted = radiusY + 0.41F;
|
|
float radiusZAdjusted = radiusZ + 0.41F;
|
|
float innerRadiusXAdjusted = radiusXAdjusted - thickness;
|
|
float innerRadiusYAdjusted = radiusYAdjusted - thickness;
|
|
float innerRadiusZAdjusted = radiusZAdjusted - thickness;
|
|
float invRadiusX2 = 1.0F / (radiusXAdjusted * radiusXAdjusted);
|
|
float invRadiusY2 = 1.0F / (radiusYAdjusted * radiusYAdjusted);
|
|
float invRadiusZ2 = 1.0F / (radiusZAdjusted * radiusZAdjusted);
|
|
float invInnerRadiusX2 = 1.0F / (innerRadiusXAdjusted * innerRadiusXAdjusted);
|
|
float invInnerRadiusY2 = 1.0F / (innerRadiusYAdjusted * innerRadiusYAdjusted);
|
|
float invInnerRadiusZ2 = 1.0F / (innerRadiusZAdjusted * innerRadiusZAdjusted);
|
|
int y = 0;
|
|
|
|
for (int y1 = 1; y <= radiusY; y1++) {
|
|
float qy = y * y * invRadiusY2;
|
|
double dx = Math.sqrt(1.0F - qy) * radiusXAdjusted;
|
|
int maxX = (int)dx;
|
|
float innerQy = y * y * invInnerRadiusY2;
|
|
float outerQy = y1 * y1 * invRadiusY2;
|
|
boolean isAtTop = y == 0 && capped;
|
|
int x = 0;
|
|
|
|
for (int x1 = 1; x <= maxX; x1++) {
|
|
float qx = x * x * invRadiusX2;
|
|
double dz = Math.sqrt(1.0F - qx - qy) * radiusZAdjusted;
|
|
int maxZ = (int)dz;
|
|
float innerQx = x * x * invInnerRadiusX2;
|
|
float outerQx = x1 * x1 * invRadiusX2;
|
|
int z = 0;
|
|
|
|
for (int z1 = 1; z <= maxZ; z1++) {
|
|
float innerQz = z * z * invInnerRadiusZ2;
|
|
if (isAtTop) {
|
|
if (!test(originX, originY, originZ, x, -y, z, t, consumer)) {
|
|
return false;
|
|
}
|
|
} else {
|
|
label60: {
|
|
if (innerQx + innerQy + innerQz < 1.0F) {
|
|
float outerQz = z1 * z1 * invRadiusZ2;
|
|
if (outerQx + outerQy + outerQz < 1.0F) {
|
|
break label60;
|
|
}
|
|
}
|
|
|
|
if (!test(originX, originY, originZ, x, -y, z, t, consumer)) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
z++;
|
|
}
|
|
|
|
x++;
|
|
}
|
|
|
|
y++;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private static <T> boolean test(int originX, int originY, int originZ, int x, int y, int z, T context, @Nonnull TriIntObjPredicate<T> consumer) {
|
|
if (!consumer.test(originX + x, originY + y, originZ + z, context)) {
|
|
return false;
|
|
} else {
|
|
if (x > 0) {
|
|
if (!consumer.test(originX - x, originY + y, originZ + z, context)) {
|
|
return false;
|
|
}
|
|
|
|
if (z > 0 && !consumer.test(originX - x, originY + y, originZ - z, context)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return z > 0 ? consumer.test(originX + x, originY + y, originZ - z, context) : true;
|
|
}
|
|
}
|
|
}
|