hytale-server/com/hypixel/hytale/server/worldgen/cave/shape/EllipsoidCaveNodeShape.java

189 lines
5.1 KiB
Java

package com.hypixel.hytale.server.worldgen.cave.shape;
import com.hypixel.hytale.math.util.MathUtil;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.procedurallib.supplier.IDoubleRange;
import com.hypixel.hytale.server.worldgen.cave.CaveNodeType;
import com.hypixel.hytale.server.worldgen.cave.CaveType;
import com.hypixel.hytale.server.worldgen.cave.element.CaveNode;
import com.hypixel.hytale.server.worldgen.util.bounds.IWorldBounds;
import java.util.Random;
import javax.annotation.Nonnull;
public class EllipsoidCaveNodeShape extends AbstractCaveNodeShape implements IWorldBounds {
private final CaveType caveType;
@Nonnull
private final Vector3d o;
private final double rx;
private final double ry;
private final double rz;
private final int lowBoundX;
private final int lowBoundY;
private final int lowBoundZ;
private final int highBoundX;
private final int highBoundY;
private final int highBoundZ;
public EllipsoidCaveNodeShape(CaveType caveType, @Nonnull Vector3d o, double rx, double ry, double rz) {
this.caveType = caveType;
this.o = o;
this.rx = rx;
this.ry = ry;
this.rz = rz;
this.lowBoundX = MathUtil.floor(Math.min(o.x - rx, o.x + rx));
this.lowBoundY = MathUtil.floor(Math.min(o.y - ry, o.y + ry));
this.lowBoundZ = MathUtil.floor(Math.min(o.z - rz, o.z + rz));
this.highBoundX = MathUtil.ceil(Math.max(o.x - rx, o.x + rx));
this.highBoundY = MathUtil.ceil(Math.max(o.y - ry, o.y + ry));
this.highBoundZ = MathUtil.ceil(Math.max(o.z - rz, o.z + rz));
}
@Nonnull
@Override
public Vector3d getStart() {
return this.o.clone();
}
@Nonnull
@Override
public Vector3d getEnd() {
return new Vector3d(this.o.x, this.lowBoundY, this.o.z);
}
@Nonnull
@Override
public Vector3d getAnchor(@Nonnull Vector3d vector, double tx, double ty, double tz) {
return CaveNodeShapeUtils.getSphereAnchor(vector, this.o, this.rx, this.ry, this.rz, tx, ty, tz);
}
@Nonnull
@Override
public IWorldBounds getBounds() {
return this;
}
@Override
public int getLowBoundX() {
return this.lowBoundX;
}
@Override
public int getLowBoundZ() {
return this.lowBoundZ;
}
@Override
public int getHighBoundX() {
return this.highBoundX;
}
@Override
public int getHighBoundZ() {
return this.highBoundZ;
}
@Override
public int getLowBoundY() {
return this.lowBoundY;
}
@Override
public int getHighBoundY() {
return this.highBoundY;
}
@Override
public boolean shouldReplace(int seed, double x, double z, int y) {
double fy = y;
double fx = x - this.o.x;
fy -= this.o.y;
double fz = z - this.o.z;
fx /= this.rx;
fy /= this.ry;
fz /= this.rz;
double t = this.caveType.getHeightRadiusFactor(seed, x, z, y);
return fx * fx + fy * fy + fz * fz <= t * t;
}
@Override
public double getFloorPosition(int seed, double x, double z) {
for (int y = this.getLowBoundY(); y < this.o.y; y++) {
if (this.shouldReplace(seed, x, z, y)) {
return y - 1;
}
}
return -1.0;
}
@Override
public double getCeilingPosition(int seed, double x, double z) {
for (int y = this.getHighBoundY(); y > this.o.y; y--) {
if (this.shouldReplace(seed, x, z, y)) {
return y + 1;
}
}
return -1.0;
}
@Nonnull
@Override
public String toString() {
return "EllipsoidCaveNodeShape{caveType="
+ this.caveType
+ ", o="
+ this.o
+ ", rx="
+ this.rx
+ ", ry="
+ this.ry
+ ", rz="
+ this.rz
+ ", lowBoundX="
+ this.lowBoundX
+ ", lowBoundY="
+ this.lowBoundY
+ ", lowBoundZ="
+ this.lowBoundZ
+ ", highBoundX="
+ this.highBoundX
+ ", highBoundY="
+ this.highBoundY
+ ", highBoundZ="
+ this.highBoundZ
+ "}";
}
public static class EllipsoidCaveNodeShapeGenerator implements CaveNodeShapeEnum.CaveNodeShapeGenerator {
private final IDoubleRange radiusX;
private final IDoubleRange radiusY;
private final IDoubleRange radiusZ;
public EllipsoidCaveNodeShapeGenerator(IDoubleRange radiusX, IDoubleRange radiusY, IDoubleRange radiusZ) {
this.radiusX = radiusX;
this.radiusY = radiusY;
this.radiusZ = radiusZ;
}
@Nonnull
@Override
public CaveNodeShape generateCaveNodeShape(
Random random,
CaveType caveType,
CaveNode parentNode,
@Nonnull CaveNodeType.CaveNodeChildEntry childEntry,
@Nonnull Vector3d origin,
float yaw,
float pitch
) {
double rx = this.radiusX.getValue(random);
double ry = this.radiusY.getValue(random);
double rz = this.radiusZ.getValue(random);
Vector3d offset = CaveNodeShapeUtils.getOffset(parentNode, childEntry);
origin.add(offset);
return new EllipsoidCaveNodeShape(caveType, origin, rx, ry, rz);
}
}
}