132 lines
3.9 KiB
Java
132 lines
3.9 KiB
Java
package com.hypixel.hytale.procedurallib.condition;
|
|
|
|
import com.hypixel.hytale.procedurallib.property.NoiseProperty;
|
|
import java.util.Arrays;
|
|
import javax.annotation.Nonnull;
|
|
|
|
public class NoiseHeightThresholdInterpreter implements IHeightThresholdInterpreter {
|
|
protected final NoiseProperty noise;
|
|
@Nonnull
|
|
protected final float[] keys;
|
|
@Nonnull
|
|
protected final IHeightThresholdInterpreter[] values;
|
|
protected final int length;
|
|
protected final int lowestNonOne;
|
|
protected final int highestNonZero;
|
|
|
|
public NoiseHeightThresholdInterpreter(NoiseProperty noise, @Nonnull float[] keys, @Nonnull IHeightThresholdInterpreter[] values) {
|
|
if (keys.length != values.length) {
|
|
throw new IllegalStateException("Length of keys and values are different!");
|
|
} else {
|
|
checkInterpreterLength(values);
|
|
this.noise = noise;
|
|
this.keys = keys;
|
|
this.values = values;
|
|
this.length = values[0].getLength();
|
|
int lowestNonOne = 0;
|
|
|
|
for (IHeightThresholdInterpreter value : values) {
|
|
if (value.getLowestNonOne() < lowestNonOne) {
|
|
lowestNonOne = value.getLowestNonOne();
|
|
}
|
|
}
|
|
|
|
this.lowestNonOne = lowestNonOne;
|
|
int highestNonZero = this.length - 1;
|
|
|
|
for (IHeightThresholdInterpreter valuex : values) {
|
|
if (valuex.getHighestNonZero() > highestNonZero) {
|
|
highestNonZero = valuex.getHighestNonZero();
|
|
}
|
|
}
|
|
|
|
this.highestNonZero = highestNonZero;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int getLowestNonOne() {
|
|
return this.lowestNonOne;
|
|
}
|
|
|
|
@Override
|
|
public int getHighestNonZero() {
|
|
return this.highestNonZero;
|
|
}
|
|
|
|
protected double noise(int seed, double x, double y) {
|
|
return this.noise.get(seed, x, y);
|
|
}
|
|
|
|
@Override
|
|
public double getContext(int seed, double x, double y) {
|
|
return this.noise(seed, x, y);
|
|
}
|
|
|
|
@Override
|
|
public int getLength() {
|
|
return this.length;
|
|
}
|
|
|
|
@Override
|
|
public float getThreshold(int seed, double x, double z, int height) {
|
|
return this.getThreshold(seed, x, z, height, this.getContext(seed, x, z));
|
|
}
|
|
|
|
@Override
|
|
public float getThreshold(int seed, double x, double z, int height, double context) {
|
|
if (height > this.highestNonZero) {
|
|
return 0.0F;
|
|
} else {
|
|
int length = this.keys.length;
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
if (context <= this.keys[i]) {
|
|
if (i == 0) {
|
|
return this.values[0].getThreshold(seed, x, z, height);
|
|
}
|
|
|
|
float distance = ((float)context - this.keys[i - 1]) / (this.keys[i] - this.keys[i - 1]);
|
|
return IHeightThresholdInterpreter.lerp(
|
|
this.values[i - 1].getThreshold(seed, x, z, height), this.values[i].getThreshold(seed, x, z, height), distance
|
|
);
|
|
}
|
|
}
|
|
|
|
return this.values[length - 1].getThreshold(seed, x, z, height);
|
|
}
|
|
}
|
|
|
|
static float lerp(float from, float to, float t) {
|
|
return from + (to - from) * t;
|
|
}
|
|
|
|
private static void checkInterpreterLength(@Nonnull IHeightThresholdInterpreter[] values) {
|
|
int length = values[0].getLength();
|
|
|
|
for (int i = 1; i < values.length; i++) {
|
|
if (values[i].getLength() != length) {
|
|
throw new IllegalStateException("ThresholdKeyInterpreter have different size!");
|
|
}
|
|
}
|
|
}
|
|
|
|
@Nonnull
|
|
@Override
|
|
public String toString() {
|
|
return "NoiseHeightThresholdInterpreter{noise="
|
|
+ this.noise
|
|
+ ", keys="
|
|
+ Arrays.toString(this.keys)
|
|
+ ", values="
|
|
+ Arrays.toString((Object[])this.values)
|
|
+ ", length="
|
|
+ this.length
|
|
+ ", lowestNonOne="
|
|
+ this.lowestNonOne
|
|
+ ", highestNonZero="
|
|
+ this.highestNonZero
|
|
+ "}";
|
|
}
|
|
}
|