269 lines
9.1 KiB
Java
269 lines
9.1 KiB
Java
package com.hypixel.hytale.procedurallib.logic;
|
|
|
|
import com.hypixel.hytale.math.util.HashUtil;
|
|
import com.hypixel.hytale.math.util.MathUtil;
|
|
import com.hypixel.hytale.math.util.TrigMathUtil;
|
|
import com.hypixel.hytale.procedurallib.NoiseFunction;
|
|
import com.hypixel.hytale.procedurallib.logic.cell.CellDistanceFunction;
|
|
import com.hypixel.hytale.procedurallib.logic.cell.evaluator.PointEvaluator;
|
|
import com.hypixel.hytale.procedurallib.property.NoiseProperty;
|
|
import javax.annotation.Nonnull;
|
|
import javax.annotation.Nullable;
|
|
|
|
public class CellNoise implements NoiseFunction {
|
|
protected final CellDistanceFunction distanceFunction;
|
|
protected final PointEvaluator pointEvaluator;
|
|
protected final CellNoise.CellFunction cellFunction;
|
|
@Nullable
|
|
protected final NoiseProperty noiseLookup;
|
|
|
|
public CellNoise(
|
|
CellDistanceFunction distanceFunction, PointEvaluator pointEvaluator, CellNoise.CellFunction cellFunction, @Nullable NoiseProperty noiseLookup
|
|
) {
|
|
this.distanceFunction = distanceFunction;
|
|
this.pointEvaluator = pointEvaluator;
|
|
this.cellFunction = cellFunction;
|
|
this.noiseLookup = noiseLookup;
|
|
}
|
|
|
|
public CellDistanceFunction getDistanceFunction() {
|
|
return this.distanceFunction;
|
|
}
|
|
|
|
public CellNoise.CellFunction getCellFunction() {
|
|
return this.cellFunction;
|
|
}
|
|
|
|
@Nullable
|
|
public NoiseProperty getNoiseLookup() {
|
|
return this.noiseLookup;
|
|
}
|
|
|
|
@Override
|
|
public double get(int seed, int offsetSeed, double x, double y) {
|
|
x = this.distanceFunction.scale(x);
|
|
y = this.distanceFunction.scale(y);
|
|
int xr = this.distanceFunction.getCellX(x, y);
|
|
int yr = this.distanceFunction.getCellY(x, y);
|
|
ResultBuffer.ResultBuffer2d buffer = this.localBuffer2d();
|
|
buffer.distance = Double.POSITIVE_INFINITY;
|
|
this.distanceFunction.nearest2D(offsetSeed, x, y, xr, yr, buffer, this.pointEvaluator);
|
|
return GeneralNoise.limit(this.cellFunction.eval(seed, offsetSeed, x, y, buffer, this.distanceFunction, this.noiseLookup)) * 2.0 - 1.0;
|
|
}
|
|
|
|
@Override
|
|
public double get(int seed, int offsetSeed, double x, double y, double z) {
|
|
int xr = this.distanceFunction.getCellX(x, y, z);
|
|
int yr = this.distanceFunction.getCellY(x, y, z);
|
|
int zr = this.distanceFunction.getCellZ(x, y, z);
|
|
ResultBuffer.ResultBuffer3d buffer = this.localBuffer3d();
|
|
buffer.distance = Double.POSITIVE_INFINITY;
|
|
this.distanceFunction.nearest3D(offsetSeed, x, y, z, xr, yr, zr, buffer, this.pointEvaluator);
|
|
return GeneralNoise.limit(this.cellFunction.eval(seed, offsetSeed, x, y, z, buffer, this.distanceFunction, this.noiseLookup)) * 2.0 - 1.0;
|
|
}
|
|
|
|
protected ResultBuffer.ResultBuffer2d localBuffer2d() {
|
|
return ResultBuffer.buffer2d;
|
|
}
|
|
|
|
protected ResultBuffer.ResultBuffer3d localBuffer3d() {
|
|
return ResultBuffer.buffer3d;
|
|
}
|
|
|
|
@Nonnull
|
|
@Override
|
|
public String toString() {
|
|
return "CellNoise{distanceFunction="
|
|
+ this.distanceFunction
|
|
+ ", pointEvaluator="
|
|
+ this.pointEvaluator
|
|
+ ", cellFunction="
|
|
+ this.cellFunction
|
|
+ ", noiseLookup="
|
|
+ this.noiseLookup
|
|
+ "}";
|
|
}
|
|
|
|
public interface CellFunction {
|
|
double eval(int var1, int var2, double var3, double var5, ResultBuffer.ResultBuffer2d var7, CellDistanceFunction var8, NoiseProperty var9);
|
|
|
|
double eval(int var1, int var2, double var3, double var5, double var7, ResultBuffer.ResultBuffer3d var9, CellDistanceFunction var10, NoiseProperty var11);
|
|
}
|
|
|
|
public static enum CellMode {
|
|
CELL_VALUE(
|
|
new CellNoise.CellFunction() {
|
|
@Override
|
|
public double eval(
|
|
int seed,
|
|
int offsetSeed,
|
|
double x,
|
|
double y,
|
|
@Nonnull ResultBuffer.ResultBuffer2d buffer,
|
|
CellDistanceFunction cellFunction,
|
|
NoiseProperty noiseLookup
|
|
) {
|
|
return HashUtil.random(offsetSeed, buffer.ix, buffer.iy);
|
|
}
|
|
|
|
@Override
|
|
public double eval(
|
|
int seed,
|
|
int offsetSeed,
|
|
double x,
|
|
double y,
|
|
double z,
|
|
@Nonnull ResultBuffer.ResultBuffer3d buffer,
|
|
CellDistanceFunction cellFunction,
|
|
NoiseProperty noiseLookup
|
|
) {
|
|
return HashUtil.random(offsetSeed, buffer.ix, buffer.iy, buffer.iz);
|
|
}
|
|
|
|
@Nonnull
|
|
@Override
|
|
public String toString() {
|
|
return "CellValueCellFunction{}";
|
|
}
|
|
}
|
|
),
|
|
NOISE_LOOKUP(
|
|
new CellNoise.CellFunction() {
|
|
@Override
|
|
public double eval(
|
|
int seed,
|
|
int offsetSeed,
|
|
double x,
|
|
double y,
|
|
@Nonnull ResultBuffer.ResultBuffer2d buffer,
|
|
@Nonnull CellDistanceFunction cellFunction,
|
|
@Nonnull NoiseProperty noiseLookup
|
|
) {
|
|
double px = cellFunction.invScale(buffer.x);
|
|
double py = cellFunction.invScale(buffer.y);
|
|
return noiseLookup.get(seed, px, py);
|
|
}
|
|
|
|
@Override
|
|
public double eval(
|
|
int seed,
|
|
int offsetSeed,
|
|
double x,
|
|
double y,
|
|
double z,
|
|
@Nonnull ResultBuffer.ResultBuffer3d buffer,
|
|
@Nonnull CellDistanceFunction cellFunction,
|
|
@Nonnull NoiseProperty noiseLookup
|
|
) {
|
|
double px = cellFunction.invScale(buffer.x);
|
|
double py = cellFunction.invScale(buffer.y);
|
|
double pz = cellFunction.invScale(buffer.z);
|
|
return noiseLookup.get(seed, px, py, pz);
|
|
}
|
|
|
|
@Nonnull
|
|
@Override
|
|
public String toString() {
|
|
return "NoiseLookupCellFunction{}";
|
|
}
|
|
}
|
|
),
|
|
DISTANCE(
|
|
new CellNoise.CellFunction() {
|
|
@Override
|
|
public double eval(
|
|
int seed,
|
|
int offsetSeed,
|
|
double x,
|
|
double y,
|
|
@Nonnull ResultBuffer.ResultBuffer2d buffer,
|
|
CellDistanceFunction cellFunction,
|
|
NoiseProperty noiseLookup
|
|
) {
|
|
return Math.sqrt(buffer.distance);
|
|
}
|
|
|
|
@Override
|
|
public double eval(
|
|
int seed,
|
|
int offsetSeed,
|
|
double x,
|
|
double y,
|
|
double z,
|
|
@Nonnull ResultBuffer.ResultBuffer3d buffer,
|
|
CellDistanceFunction cellFunction,
|
|
NoiseProperty noiseLookup
|
|
) {
|
|
return Math.sqrt(buffer.distance);
|
|
}
|
|
|
|
@Nonnull
|
|
@Override
|
|
public String toString() {
|
|
return "DistanceCellFunction{}";
|
|
}
|
|
}
|
|
),
|
|
DIRECTION(
|
|
new CellNoise.CellFunction() {
|
|
@Override
|
|
public double eval(
|
|
int seed,
|
|
int offsetSeed,
|
|
double x,
|
|
double y,
|
|
@Nonnull ResultBuffer.ResultBuffer2d buffer,
|
|
CellDistanceFunction cellFunction,
|
|
NoiseProperty noiseLookup
|
|
) {
|
|
float angle = (float)this.getAngleNoise(seed, offsetSeed, buffer, noiseLookup) * (float) (Math.PI * 2);
|
|
float dx = TrigMathUtil.sin(angle);
|
|
float dy = TrigMathUtil.cos(angle);
|
|
double ax = buffer.x;
|
|
double ay = buffer.y;
|
|
double bx = ax + dx;
|
|
double by = ay + dy;
|
|
double distance2 = MathUtil.distanceToInfLineSq(x, y, ax, ay, bx, by);
|
|
double distance = MathUtil.clamp(Math.sqrt(distance2), 0.0, 1.0);
|
|
int side = MathUtil.sideOfLine(x, y, ax, ay, bx, by);
|
|
return 0.5 + side * distance * 0.5;
|
|
}
|
|
|
|
@Override
|
|
public double eval(
|
|
int seed,
|
|
int offsetSeed,
|
|
double x,
|
|
double y,
|
|
double z,
|
|
ResultBuffer.ResultBuffer3d buffer,
|
|
CellDistanceFunction cellFunction,
|
|
NoiseProperty noiseLookup
|
|
) {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
|
|
@Nonnull
|
|
@Override
|
|
public String toString() {
|
|
return "DirectionCellFunction{}";
|
|
}
|
|
|
|
private double getAngleNoise(int seed, int offsetSeed, @Nonnull ResultBuffer.ResultBuffer2d buffer, @Nullable NoiseProperty noiseProperty) {
|
|
return noiseProperty != null ? noiseProperty.get(seed, buffer.x, buffer.y) : HashUtil.random(offsetSeed, buffer.ix, buffer.iy);
|
|
}
|
|
}
|
|
);
|
|
|
|
private final CellNoise.CellFunction function;
|
|
|
|
private CellMode(CellNoise.CellFunction function) {
|
|
this.function = function;
|
|
}
|
|
|
|
public CellNoise.CellFunction getFunction() {
|
|
return this.function;
|
|
}
|
|
}
|
|
}
|