mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-05-20 08:40:26 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a028b193a | |||
| d31679e6be | |||
| 43d52e4bc1 | |||
| accc07fa07 | |||
| 1ae0d1f867 | |||
| 370b2e0122 | |||
| 331075e54d | |||
| 973590f5fd | |||
| 1a5ab6b505 | |||
| 14732328cd | |||
| 6c7974c302 | |||
| 1204b7a8c1 | |||
| fbe1c76e26 | |||
| add7803e65 | |||
| 4393a16b2f | |||
| b4fa635455 | |||
| 9f425c6159 | |||
| 158ffba2a5 | |||
| b7326c0ff6 |
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
preRelease(true)
|
preRelease(true)
|
||||||
|
|
||||||
versionProjects(":common:api", version("6.5.0"))
|
versionProjects(":common:api", version("6.6.0"))
|
||||||
versionProjects(":common:implementation", version("6.5.0"))
|
versionProjects(":common:implementation", version("6.6.0"))
|
||||||
versionProjects(":platforms", version("6.5.0"))
|
versionProjects(":platforms", version("6.6.0"))
|
||||||
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
|
|||||||
@@ -74,5 +74,6 @@ object Versions {
|
|||||||
object CLI {
|
object CLI {
|
||||||
const val nbt = "6.1"
|
const val nbt = "6.1"
|
||||||
const val logback = "1.5.8"
|
const val logback = "1.5.8"
|
||||||
|
const val picocli = "4.7.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+5
@@ -17,6 +17,7 @@ import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
|||||||
import com.dfsek.terra.addons.noise.config.CubicSplinePointTemplate;
|
import com.dfsek.terra.addons.noise.config.CubicSplinePointTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
|
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.BinaryArithmeticTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.BinaryArithmeticTemplate;
|
||||||
|
import com.dfsek.terra.addons.noise.config.templates.CacheSamplerTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.DerivativeNoiseSamplerTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.DerivativeNoiseSamplerTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.DomainWarpTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.DomainWarpTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
|
||||||
@@ -37,6 +38,7 @@ import com.dfsek.terra.addons.noise.config.templates.noise.fractal.RidgedFractal
|
|||||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.ClampNormalizerTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.normalizer.ClampNormalizerTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.CubicSplineNormalizerTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.normalizer.CubicSplineNormalizerTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.ExpressionNormalizerTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.normalizer.ExpressionNormalizerTemplate;
|
||||||
|
import com.dfsek.terra.addons.noise.config.templates.normalizer.LinearMapNormalizerTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.LinearNormalizerTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.normalizer.LinearNormalizerTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.NormalNormalizerTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.normalizer.NormalNormalizerTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.PosterizationNormalizerTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.normalizer.PosterizationNormalizerTemplate;
|
||||||
@@ -101,6 +103,7 @@ public class NoiseAddon implements AddonInitializer {
|
|||||||
.applyLoader(DerivativeNoiseSampler.class, DerivativeNoiseSamplerTemplate::new);
|
.applyLoader(DerivativeNoiseSampler.class, DerivativeNoiseSamplerTemplate::new);
|
||||||
|
|
||||||
noiseRegistry.register(addon.key("LINEAR"), LinearNormalizerTemplate::new);
|
noiseRegistry.register(addon.key("LINEAR"), LinearNormalizerTemplate::new);
|
||||||
|
noiseRegistry.register(addon.key("LINEAR_MAP"), LinearMapNormalizerTemplate::new);
|
||||||
noiseRegistry.register(addon.key("NORMAL"), NormalNormalizerTemplate::new);
|
noiseRegistry.register(addon.key("NORMAL"), NormalNormalizerTemplate::new);
|
||||||
noiseRegistry.register(addon.key("CLAMP"), ClampNormalizerTemplate::new);
|
noiseRegistry.register(addon.key("CLAMP"), ClampNormalizerTemplate::new);
|
||||||
noiseRegistry.register(addon.key("PROBABILITY"), ProbabilityNormalizerTemplate::new);
|
noiseRegistry.register(addon.key("PROBABILITY"), ProbabilityNormalizerTemplate::new);
|
||||||
@@ -148,6 +151,8 @@ public class NoiseAddon implements AddonInitializer {
|
|||||||
noiseRegistry.register(addon.key("MAX"), () -> new BinaryArithmeticTemplate<>(MaxSampler::new));
|
noiseRegistry.register(addon.key("MAX"), () -> new BinaryArithmeticTemplate<>(MaxSampler::new));
|
||||||
noiseRegistry.register(addon.key("MIN"), () -> new BinaryArithmeticTemplate<>(MinSampler::new));
|
noiseRegistry.register(addon.key("MIN"), () -> new BinaryArithmeticTemplate<>(MinSampler::new));
|
||||||
|
|
||||||
|
noiseRegistry.register(addon.key("CACHE"), () -> new CacheSamplerTemplate(plugin.getGenerationThreads()));
|
||||||
|
|
||||||
|
|
||||||
Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>();
|
Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>();
|
||||||
Map<String, FunctionTemplate> packFunctions = new LinkedHashMap<>();
|
Map<String, FunctionTemplate> packFunctions = new LinkedHashMap<>();
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
package com.dfsek.terra.addons.noise.config.templates;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.noise.samplers.CacheSampler;
|
||||||
|
import com.dfsek.terra.addons.noise.samplers.LinearHeightmapSampler;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
|
||||||
|
|
||||||
|
public class CacheSamplerTemplate extends SamplerTemplate<LinearHeightmapSampler> {
|
||||||
|
@Value("sampler")
|
||||||
|
@Default
|
||||||
|
private NoiseSampler sampler;
|
||||||
|
|
||||||
|
private final int generationThreads;
|
||||||
|
|
||||||
|
public CacheSamplerTemplate(int generationThreads) {
|
||||||
|
this.generationThreads = generationThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NoiseSampler get() {
|
||||||
|
return new CacheSampler(sampler, getDimensions(), generationThreads);
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-1
@@ -34,7 +34,11 @@ public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
|
|||||||
@Value("lookup")
|
@Value("lookup")
|
||||||
@Default
|
@Default
|
||||||
private @Meta NoiseSampler lookup = new OpenSimplex2Sampler();
|
private @Meta NoiseSampler lookup = new OpenSimplex2Sampler();
|
||||||
|
|
||||||
|
@Value("salt-lookup")
|
||||||
|
@Default
|
||||||
|
private @Meta boolean saltLookup = true;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NoiseSampler get() {
|
public NoiseSampler get() {
|
||||||
CellularSampler sampler = new CellularSampler();
|
CellularSampler sampler = new CellularSampler();
|
||||||
@@ -44,6 +48,7 @@ public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
|
|||||||
sampler.setReturnType(cellularReturnType);
|
sampler.setReturnType(cellularReturnType);
|
||||||
sampler.setDistanceFunction(cellularDistanceFunction);
|
sampler.setDistanceFunction(cellularDistanceFunction);
|
||||||
sampler.setSalt(salt);
|
sampler.setSalt(salt);
|
||||||
|
sampler.setSaltLookup(saltLookup);
|
||||||
return sampler;
|
return sampler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
package com.dfsek.terra.addons.noise.config.templates.normalizer;
|
||||||
|
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.noise.normalizer.LinearMapNormalizer;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
|
||||||
|
|
||||||
|
public class LinearMapNormalizerTemplate extends NormalizerTemplate<LinearMapNormalizer> {
|
||||||
|
|
||||||
|
@Value("from.a")
|
||||||
|
@Default
|
||||||
|
private @Meta double aFrom = -1;
|
||||||
|
|
||||||
|
@Value("from.b")
|
||||||
|
@Default
|
||||||
|
private @Meta double bFrom = 1;
|
||||||
|
|
||||||
|
@Value("to.a")
|
||||||
|
private @Meta double aTo;
|
||||||
|
|
||||||
|
@Value("to.b")
|
||||||
|
private @Meta double bTo;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NoiseSampler get() {
|
||||||
|
return new LinearMapNormalizer(function, aFrom, aTo, bFrom, bTo);
|
||||||
|
}
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
package com.dfsek.terra.addons.noise.normalizer;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
|
||||||
|
|
||||||
|
public class LinearMapNormalizer extends Normalizer {
|
||||||
|
|
||||||
|
private final double aFrom;
|
||||||
|
|
||||||
|
private final double aTo;
|
||||||
|
|
||||||
|
private final double bFrom;
|
||||||
|
|
||||||
|
private final double bTo;
|
||||||
|
|
||||||
|
public LinearMapNormalizer(NoiseSampler sampler, double aFrom, double aTo, double bFrom, double bTo) {
|
||||||
|
super(sampler);
|
||||||
|
this.aFrom = aFrom;
|
||||||
|
this.aTo = aTo;
|
||||||
|
this.bFrom = bFrom;
|
||||||
|
this.bTo = bTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double normalize(double in) {
|
||||||
|
return (in - aFrom) * (aTo - bTo) / (aFrom - bFrom) + aTo;
|
||||||
|
}
|
||||||
|
}
|
||||||
+125
@@ -0,0 +1,125 @@
|
|||||||
|
package com.dfsek.terra.addons.noise.samplers;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
|
||||||
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
|
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||||
|
|
||||||
|
|
||||||
|
public class CacheSampler implements DerivativeNoiseSampler {
|
||||||
|
|
||||||
|
private final NoiseSampler sampler;
|
||||||
|
private final LoadingCache<DoubleSeededVector2, Double> cache2D;
|
||||||
|
private final LoadingCache<DoubleSeededVector3, Double> cache3D;
|
||||||
|
private final LoadingCache<DoubleSeededVector2, double[]> cache2DDirv;
|
||||||
|
private final LoadingCache<DoubleSeededVector3, double[]> cache3DDirv;
|
||||||
|
|
||||||
|
public CacheSampler(NoiseSampler sampler, int dimensions, int generationThreads) {
|
||||||
|
this.sampler = sampler;
|
||||||
|
if (dimensions == 2) {
|
||||||
|
this.cache2D = Caffeine
|
||||||
|
.newBuilder()
|
||||||
|
.initialCapacity(0)
|
||||||
|
.maximumSize(256L * generationThreads) // 1 full chunk (high res)
|
||||||
|
.build(vec -> sampler.noise(vec.seed, vec.x, vec.z));
|
||||||
|
cache3D = null;
|
||||||
|
cache3DDirv = null;
|
||||||
|
if (DerivativeNoiseSampler.isDifferentiable(sampler)) {
|
||||||
|
this.cache2DDirv = Caffeine
|
||||||
|
.newBuilder()
|
||||||
|
.initialCapacity(0)
|
||||||
|
.maximumSize(256L * generationThreads) // 1 full chunk (high res)
|
||||||
|
.build(vec -> ((DerivativeNoiseSampler) sampler).noised(vec.seed, vec.x, vec.z));
|
||||||
|
} else {
|
||||||
|
cache2DDirv = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.cache3D = Caffeine
|
||||||
|
.newBuilder()
|
||||||
|
.initialCapacity(0)
|
||||||
|
.maximumSize(256L * generationThreads) // 1 full chunk (high res)
|
||||||
|
.build(vec -> sampler.noise(vec.seed, vec.x, vec.y, vec.z));
|
||||||
|
cache2D = null;
|
||||||
|
cache2DDirv = null;
|
||||||
|
if (DerivativeNoiseSampler.isDifferentiable(sampler)) {
|
||||||
|
this.cache3DDirv = Caffeine
|
||||||
|
.newBuilder()
|
||||||
|
.initialCapacity(0)
|
||||||
|
.maximumSize(256L * generationThreads) // 1 full chunk (high res)
|
||||||
|
.build(vec -> ((DerivativeNoiseSampler) sampler).noised(vec.seed, vec.x, vec.y, vec.z));
|
||||||
|
} else {
|
||||||
|
cache3DDirv = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDifferentiable() {
|
||||||
|
return DerivativeNoiseSampler.isDifferentiable(sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] noised(long seed, double x, double y) {
|
||||||
|
return cache2DDirv.get(new DoubleSeededVector2(x, y, seed));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] noised(long seed, double x, double y, double z) {
|
||||||
|
return cache3DDirv.get(new DoubleSeededVector3(x, y, z, seed));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double noise(long seed, double x, double y) {
|
||||||
|
DoubleSeededVector2 vec = new DoubleSeededVector2(x, y, seed);
|
||||||
|
if (cache2DDirv != null && cache2DDirv.estimatedSize() != 0) {
|
||||||
|
return cache2DDirv.get(vec)[0];
|
||||||
|
}
|
||||||
|
return cache2D.get(vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double noise(long seed, double x, double y, double z) {
|
||||||
|
DoubleSeededVector3 vec = new DoubleSeededVector3(x, y, z, seed);
|
||||||
|
if (cache3DDirv != null && cache3DDirv.estimatedSize() != 0) {
|
||||||
|
return cache3DDirv.get(vec)[0];
|
||||||
|
}
|
||||||
|
return cache3D.get(vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
private record DoubleSeededVector3(double x, double y, double z, long seed) {
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if(obj instanceof DoubleSeededVector3 that) {
|
||||||
|
return this.y == that.y && this.z == that.z && this.x == that.x && this.seed == that.seed;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int code = (int) Double.doubleToLongBits(x);
|
||||||
|
code = 31 * code + (int) Double.doubleToLongBits(y);
|
||||||
|
code = 31 * code + (int) Double.doubleToLongBits(z);
|
||||||
|
return 31 * code + (Long.hashCode(seed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private record DoubleSeededVector2(double x, double z, long seed) {
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if(obj instanceof DoubleSeededVector2 that) {
|
||||||
|
return this.z == that.z && this.x == that.x && this.seed == that.seed;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int code = (int) Double.doubleToLongBits(x);
|
||||||
|
code = 31 * code + (int) Double.doubleToLongBits(z);
|
||||||
|
return 31 * code + (Long.hashCode(seed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -12,4 +12,14 @@ public class AdditionSampler extends BinaryArithmeticSampler {
|
|||||||
public double operate(double left, double right) {
|
public double operate(double left, double right) {
|
||||||
return left + right;
|
return left + right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] operateDerivative(double[] left, double[] right) {
|
||||||
|
int dimensions = left.length;
|
||||||
|
double[] out = new double[dimensions];
|
||||||
|
for(int i = 0; i < dimensions; i++) {
|
||||||
|
out[i] = left[i] + right[i];
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-1
@@ -1,9 +1,10 @@
|
|||||||
package com.dfsek.terra.addons.noise.samplers.arithmetic;
|
package com.dfsek.terra.addons.noise.samplers.arithmetic;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
|
||||||
|
|
||||||
public abstract class BinaryArithmeticSampler implements NoiseSampler {
|
public abstract class BinaryArithmeticSampler implements DerivativeNoiseSampler {
|
||||||
private final NoiseSampler left;
|
private final NoiseSampler left;
|
||||||
private final NoiseSampler right;
|
private final NoiseSampler right;
|
||||||
|
|
||||||
@@ -12,6 +13,11 @@ public abstract class BinaryArithmeticSampler implements NoiseSampler {
|
|||||||
this.right = right;
|
this.right = right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDifferentiable() {
|
||||||
|
return DerivativeNoiseSampler.isDifferentiable(left) && DerivativeNoiseSampler.isDifferentiable(right);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double noise(long seed, double x, double y) {
|
public double noise(long seed, double x, double y) {
|
||||||
return operate(left.noise(seed, x, y), right.noise(seed, x, y));
|
return operate(left.noise(seed, x, y), right.noise(seed, x, y));
|
||||||
@@ -22,5 +28,17 @@ public abstract class BinaryArithmeticSampler implements NoiseSampler {
|
|||||||
return operate(left.noise(seed, x, y, z), right.noise(seed, x, y, z));
|
return operate(left.noise(seed, x, y, z), right.noise(seed, x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] noised(long seed, double x, double y) {
|
||||||
|
return operateDerivative(((DerivativeNoiseSampler)left).noised(seed, x, y), ((DerivativeNoiseSampler)right).noised(seed, x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] noised(long seed, double x, double y, double z) {
|
||||||
|
return operateDerivative(((DerivativeNoiseSampler)left).noised(seed, x, y, z), ((DerivativeNoiseSampler)right).noised(seed, x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
public abstract double operate(double left, double right);
|
public abstract double operate(double left, double right);
|
||||||
|
|
||||||
|
public abstract double[] operateDerivative(double[] left, double[] right);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -12,4 +12,15 @@ public class DivisionSampler extends BinaryArithmeticSampler {
|
|||||||
public double operate(double left, double right) {
|
public double operate(double left, double right) {
|
||||||
return left / right;
|
return left / right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] operateDerivative(double[] left, double[] right) {
|
||||||
|
int dimensions = left.length;
|
||||||
|
double[] out = new double[dimensions];
|
||||||
|
out[0] = left[0] / right[0];
|
||||||
|
for(int i = 1; i < dimensions; i++) {
|
||||||
|
out[i] = (left[i] * right[0] - left[0] * right[i]) / (right[0] * right[0]);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -12,4 +12,11 @@ public class MaxSampler extends BinaryArithmeticSampler {
|
|||||||
public double operate(double left, double right) {
|
public double operate(double left, double right) {
|
||||||
return Math.max(left, right);
|
return Math.max(left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] operateDerivative(double[] left, double[] right) {
|
||||||
|
double leftValue = left[0];
|
||||||
|
double rightValue = right[0];
|
||||||
|
return leftValue > rightValue ? left : right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -12,4 +12,11 @@ public class MinSampler extends BinaryArithmeticSampler {
|
|||||||
public double operate(double left, double right) {
|
public double operate(double left, double right) {
|
||||||
return Math.min(left, right);
|
return Math.min(left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] operateDerivative(double[] left, double[] right) {
|
||||||
|
double leftValue = left[0];
|
||||||
|
double rightValue = right[0];
|
||||||
|
return leftValue < rightValue ? left : right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -12,4 +12,15 @@ public class MultiplicationSampler extends BinaryArithmeticSampler {
|
|||||||
public double operate(double left, double right) {
|
public double operate(double left, double right) {
|
||||||
return left * right;
|
return left * right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] operateDerivative(double[] left, double[] right) {
|
||||||
|
int dimensions = left.length;
|
||||||
|
double[] out = new double[dimensions];
|
||||||
|
out[0] = left[0] * right[0];
|
||||||
|
for(int i = 1; i < dimensions; i++) {
|
||||||
|
out[i] = left[i] * right[0] + left[0] * right[i];
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -12,4 +12,14 @@ public class SubtractionSampler extends BinaryArithmeticSampler {
|
|||||||
public double operate(double left, double right) {
|
public double operate(double left, double right) {
|
||||||
return left - right;
|
return left - right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] operateDerivative(double[] left, double[] right) {
|
||||||
|
int dimensions = left.length;
|
||||||
|
double[] out = new double[dimensions];
|
||||||
|
for(int i = 0; i < dimensions; i++) {
|
||||||
|
out[i] = left[i] - right[i];
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-6
@@ -197,7 +197,9 @@ public class CellularSampler extends NoiseFunction {
|
|||||||
private double jitterModifier = 1.0;
|
private double jitterModifier = 1.0;
|
||||||
|
|
||||||
private NoiseSampler noiseLookup;
|
private NoiseSampler noiseLookup;
|
||||||
|
|
||||||
|
private boolean saltLookup;
|
||||||
|
|
||||||
public CellularSampler() {
|
public CellularSampler() {
|
||||||
noiseLookup = new OpenSimplex2Sampler();
|
noiseLookup = new OpenSimplex2Sampler();
|
||||||
}
|
}
|
||||||
@@ -217,7 +219,11 @@ public class CellularSampler extends NoiseFunction {
|
|||||||
public void setReturnType(ReturnType returnType) {
|
public void setReturnType(ReturnType returnType) {
|
||||||
this.returnType = returnType;
|
this.returnType = returnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSaltLookup(boolean saltLookup) {
|
||||||
|
this.saltLookup = saltLookup;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getNoiseRaw(long sl, double x, double y) {
|
public double getNoiseRaw(long sl, double x, double y) {
|
||||||
int seed = (int) sl;
|
int seed = (int) sl;
|
||||||
@@ -286,8 +292,8 @@ public class CellularSampler extends NoiseFunction {
|
|||||||
case Distance2Sub -> distance1 - distance0 - 1;
|
case Distance2Sub -> distance1 - distance0 - 1;
|
||||||
case Distance2Mul -> distance1 * distance0 * 0.5 - 1;
|
case Distance2Mul -> distance1 * distance0 * 0.5 - 1;
|
||||||
case Distance2Div -> distance0 / distance1 - 1;
|
case Distance2Div -> distance0 / distance1 - 1;
|
||||||
case NoiseLookup -> noiseLookup.noise(sl, centerX, centerY);
|
case NoiseLookup -> noiseLookup.noise(sl - (saltLookup ? 0 : salt), centerX, centerY);
|
||||||
case LocalNoiseLookup -> noiseLookup.noise(sl, x / frequency - centerX, y / frequency - centerY);
|
case LocalNoiseLookup -> noiseLookup.noise(sl - (saltLookup ? 0 : salt), x / frequency - centerX, y / frequency - centerY);
|
||||||
case Distance3 -> distance2 - 1;
|
case Distance3 -> distance2 - 1;
|
||||||
case Distance3Add -> (distance2 + distance0) * 0.5 - 1;
|
case Distance3Add -> (distance2 + distance0) * 0.5 - 1;
|
||||||
case Distance3Sub -> distance2 - distance0 - 1;
|
case Distance3Sub -> distance2 - distance0 - 1;
|
||||||
@@ -377,8 +383,8 @@ public class CellularSampler extends NoiseFunction {
|
|||||||
case Distance2Sub -> distance1 - distance0 - 1;
|
case Distance2Sub -> distance1 - distance0 - 1;
|
||||||
case Distance2Mul -> distance1 * distance0 * 0.5 - 1;
|
case Distance2Mul -> distance1 * distance0 * 0.5 - 1;
|
||||||
case Distance2Div -> distance0 / distance1 - 1;
|
case Distance2Div -> distance0 / distance1 - 1;
|
||||||
case NoiseLookup -> noiseLookup.noise(sl, centerX, centerY, centerZ);
|
case NoiseLookup -> noiseLookup.noise(sl - (saltLookup ? 0 : salt), centerX, centerY, centerZ);
|
||||||
case LocalNoiseLookup -> noiseLookup.noise(sl, x / frequency - centerX, y / frequency - centerY, z / frequency - centerZ);
|
case LocalNoiseLookup -> noiseLookup.noise(sl - (saltLookup ? 0 : salt), x / frequency - centerX, y / frequency - centerY, z / frequency - centerZ);
|
||||||
case Distance3 -> distance2 - 1;
|
case Distance3 -> distance2 - 1;
|
||||||
case Distance3Add -> (distance2 + distance0) * 0.5 - 1;
|
case Distance3Add -> (distance2 + distance0) * 0.5 - 1;
|
||||||
case Distance3Sub -> distance2 - distance0 - 1;
|
case Distance3Sub -> distance2 - distance0 - 1;
|
||||||
|
|||||||
+57
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
package com.dfsek.terra.addons.noise.samplers.noise.fractal;
|
package com.dfsek.terra.addons.noise.samplers.noise.fractal;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.util.MathUtil;
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
|
|
||||||
@@ -52,4 +53,60 @@ public class BrownianMotionSampler extends FractalNoiseFunction {
|
|||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDifferentiable() {
|
||||||
|
return DerivativeNoiseSampler.isDifferentiable(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] getNoiseDerivativeRaw(long seed, double x, double y) {
|
||||||
|
double[] sum = {0, 0, 0};
|
||||||
|
double amp = fractalBounding;
|
||||||
|
|
||||||
|
for(int i = 0; i < octaves; i++) {
|
||||||
|
// This should only be called after `input` is verified as a `DerivativeNoiseSampler`
|
||||||
|
// so this should be a safe cast
|
||||||
|
double[] noise = ((DerivativeNoiseSampler) input).noised(seed++, x, y);
|
||||||
|
sum[0] += noise[0] * amp;
|
||||||
|
|
||||||
|
// Directional derivative of each octave can be subject to the same addition and product
|
||||||
|
// as per derivative sum and product rules in order to produce the correct final derivative
|
||||||
|
sum[1] += noise[1] * amp;
|
||||||
|
sum[2] += noise[2] * amp;
|
||||||
|
|
||||||
|
amp *= MathUtil.lerp(weightedStrength, 1.0, Math.min(noise[0] + 1, 2) * 0.5);
|
||||||
|
|
||||||
|
x *= lacunarity;
|
||||||
|
y *= lacunarity;
|
||||||
|
amp *= gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] getNoiseDerivativeRaw(long seed, double x, double y, double z) {
|
||||||
|
double[] sum = {0, 0, 0, 0};
|
||||||
|
double amp = fractalBounding;
|
||||||
|
|
||||||
|
for(int i = 0; i < octaves; i++) {
|
||||||
|
double[] noise = ((DerivativeNoiseSampler) input).noised(seed++, x, y, z);
|
||||||
|
sum[0] += noise[0] * amp;
|
||||||
|
|
||||||
|
// See comment in 2D version
|
||||||
|
sum[1] += noise[1] * amp;
|
||||||
|
sum[2] += noise[2] * amp;
|
||||||
|
sum[3] += noise[3] * amp;
|
||||||
|
|
||||||
|
amp *= MathUtil.lerp(weightedStrength, 1.0, (noise[0] + 1) * 0.5);
|
||||||
|
|
||||||
|
x *= lacunarity;
|
||||||
|
y *= lacunarity;
|
||||||
|
z *= lacunarity;
|
||||||
|
amp *= gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-2
@@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
package com.dfsek.terra.addons.noise.samplers.noise.fractal;
|
package com.dfsek.terra.addons.noise.samplers.noise.fractal;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
|
import com.dfsek.terra.addons.noise.samplers.noise.DerivativeNoiseFunction;
|
||||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
|
||||||
|
|
||||||
public abstract class FractalNoiseFunction extends NoiseFunction {
|
public abstract class FractalNoiseFunction extends DerivativeNoiseFunction {
|
||||||
protected final NoiseSampler input;
|
protected final NoiseSampler input;
|
||||||
protected double fractalBounding = 1 / 1.75;
|
protected double fractalBounding = 1 / 1.75;
|
||||||
protected int octaves = 3;
|
protected int octaves = 3;
|
||||||
@@ -52,4 +52,19 @@ public abstract class FractalNoiseFunction extends NoiseFunction {
|
|||||||
public void setWeightedStrength(double weightedStrength) {
|
public void setWeightedStrength(double weightedStrength) {
|
||||||
this.weightedStrength = weightedStrength;
|
this.weightedStrength = weightedStrength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDifferentiable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] getNoiseDerivativeRaw(long seed, double x, double y) {
|
||||||
|
throw new UnsupportedOperationException("Implementation failed to check or set isDifferentiable correctly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] getNoiseDerivativeRaw(long seed, double x, double y, double z) {
|
||||||
|
throw new UnsupportedOperationException("Implementation failed to check or set isDifferentiable correctly");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -116,12 +116,12 @@ public abstract class SimplexStyleSampler extends DerivativeNoiseFunction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double[] getNoiseDerivativeRaw(long seed, double x, double y) {
|
public double[] getNoiseDerivativeRaw(long seed, double x, double y) {
|
||||||
return new double[]{ 0, 0, 0 };
|
throw new UnsupportedOperationException("Implementation failed to check or set isDifferentiable correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double[] getNoiseDerivativeRaw(long seed, double x, double y, double z) {
|
public double[] getNoiseDerivativeRaw(long seed, double x, double y, double z) {
|
||||||
return new double[]{ 0, 0, 0, 0 };
|
throw new UnsupportedOperationException("Implementation failed to check or set isDifferentiable correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -81,4 +81,7 @@ public interface Platform extends LoaderRegistrar {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Contract(pure = true)
|
@Contract(pure = true)
|
||||||
Profiler getProfiler();
|
Profiler getProfiler();
|
||||||
|
|
||||||
|
@Contract(pure = true)
|
||||||
|
int getGenerationThreads();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,7 @@ package com.dfsek.terra.api.noise;
|
|||||||
public interface DerivativeNoiseSampler extends NoiseSampler {
|
public interface DerivativeNoiseSampler extends NoiseSampler {
|
||||||
|
|
||||||
static boolean isDifferentiable(NoiseSampler sampler) {
|
static boolean isDifferentiable(NoiseSampler sampler) {
|
||||||
if(sampler instanceof DerivativeNoiseSampler dSampler) {
|
return sampler instanceof DerivativeNoiseSampler dSampler && dSampler.isDifferentiable();
|
||||||
return dSampler.isDifferentiable();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+4
-2
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
package com.dfsek.terra.api.world.biome.generation;
|
package com.dfsek.terra.api.world.biome.generation;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.Platform;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -91,11 +93,11 @@ public interface BiomeProvider {
|
|||||||
return StreamSupport.stream(getBiomes().spliterator(), false);
|
return StreamSupport.stream(getBiomes().spliterator(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
default CachingBiomeProvider caching() {
|
default CachingBiomeProvider caching(Platform platform) {
|
||||||
if(this instanceof CachingBiomeProvider cachingBiomeProvider) {
|
if(this instanceof CachingBiomeProvider cachingBiomeProvider) {
|
||||||
return cachingBiomeProvider;
|
return cachingBiomeProvider;
|
||||||
}
|
}
|
||||||
return new CachingBiomeProvider(this);
|
return new CachingBiomeProvider(this, platform.getGenerationThreads());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+7
-6
@@ -21,19 +21,20 @@ public class CachingBiomeProvider implements BiomeProvider, Handle {
|
|||||||
private final LoadingCache<SeededVector3, Biome> cache;
|
private final LoadingCache<SeededVector3, Biome> cache;
|
||||||
private final LoadingCache<SeededVector2, Optional<Biome>> baseCache;
|
private final LoadingCache<SeededVector2, Optional<Biome>> baseCache;
|
||||||
|
|
||||||
protected CachingBiomeProvider(BiomeProvider delegate) {
|
protected CachingBiomeProvider(BiomeProvider delegate, int generationThreads) {
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
this.res = delegate.resolution();
|
this.res = delegate.resolution();
|
||||||
|
int size = generationThreads * 98304;
|
||||||
this.cache = Caffeine
|
this.cache = Caffeine
|
||||||
.newBuilder()
|
.newBuilder()
|
||||||
.scheduler(Scheduler.disabledScheduler())
|
.scheduler(Scheduler.disabledScheduler())
|
||||||
.initialCapacity(98304)
|
.initialCapacity(size)
|
||||||
.maximumSize(98304) // 1 full chunk (high res)
|
.maximumSize(size) // 1 full chunk (high res)
|
||||||
.build(vec -> delegate.getBiome(vec.x * res, vec.y * res, vec.z * res, vec.seed));
|
.build(vec -> delegate.getBiome(vec.x * res, vec.y * res, vec.z * res, vec.seed));
|
||||||
|
|
||||||
this.baseCache = Caffeine
|
this.baseCache = Caffeine
|
||||||
.newBuilder()
|
.newBuilder()
|
||||||
.maximumSize(256) // 1 full chunk (high res)
|
.maximumSize(256L * generationThreads) // 1 full chunk (high res)
|
||||||
.build(vec -> delegate.getBaseBiome(vec.x * res, vec.z * res, vec.seed));
|
.build(vec -> delegate.getBaseBiome(vec.x * res, vec.z * res, vec.seed));
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -77,7 +78,7 @@ public class CachingBiomeProvider implements BiomeProvider, Handle {
|
|||||||
int code = x;
|
int code = x;
|
||||||
code = 31 * code + y;
|
code = 31 * code + y;
|
||||||
code = 31 * code + z;
|
code = 31 * code + z;
|
||||||
return 31 * code + ((int) (seed ^ (seed >>> 32)));
|
return 31 * code + (Long.hashCode(seed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +96,7 @@ public class CachingBiomeProvider implements BiomeProvider, Handle {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int code = x;
|
int code = x;
|
||||||
code = 31 * code + z;
|
code = 31 * code + z;
|
||||||
return 31 * code + ((int) (seed ^ (seed >>> 32)));
|
return 31 * code + (Long.hashCode(seed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -310,6 +310,24 @@ public abstract class AbstractPlatform implements Platform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getGenerationThreadsWithReflection(String className, String fieldName, String project) {
|
||||||
|
try {
|
||||||
|
Class aClass = Class.forName(className);
|
||||||
|
int threads = aClass.getField(fieldName).getInt(null);
|
||||||
|
logger.info("{} found, setting {} generation threads.", project, threads);
|
||||||
|
return threads;
|
||||||
|
} catch(ClassNotFoundException e) {
|
||||||
|
logger.info("{} not found.", project);
|
||||||
|
} catch(NoSuchFieldException e) {
|
||||||
|
logger.warn("{} found, but {} field not found this probably means {0} has changed its code and " +
|
||||||
|
"Terra has not updated to reflect that.", project, fieldName);
|
||||||
|
} catch(IllegalAccessException e) {
|
||||||
|
logger.error("Failed to access {} field in {}, assuming 1 generation thread.", fieldName, project, e);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void register(TypeRegistry registry) {
|
public void register(TypeRegistry registry) {
|
||||||
loaders.register(registry);
|
loaders.register(registry);
|
||||||
@@ -339,4 +357,9 @@ public abstract class AbstractPlatform implements Platform {
|
|||||||
public @NotNull Profiler getProfiler() {
|
public @NotNull Profiler getProfiler() {
|
||||||
return profiler;
|
return profiler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getGenerationThreads() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -232,7 +232,7 @@ public class ConfigPackImpl implements ConfigPack {
|
|||||||
ConfigPackPostTemplate packPostTemplate = new ConfigPackPostTemplate();
|
ConfigPackPostTemplate packPostTemplate = new ConfigPackPostTemplate();
|
||||||
selfLoader.load(packPostTemplate, packManifest);
|
selfLoader.load(packPostTemplate, packManifest);
|
||||||
seededBiomeProvider =
|
seededBiomeProvider =
|
||||||
template.getBiomeCache() ? packPostTemplate.getProviderBuilder().caching() : packPostTemplate.getProviderBuilder();
|
template.getBiomeCache() ? packPostTemplate.getProviderBuilder().caching(platform) : packPostTemplate.getProviderBuilder();
|
||||||
checkDeadEntries();
|
checkDeadEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,13 @@ public class PlatformImpl extends AbstractPlatform {
|
|||||||
|
|
||||||
private final TerraBukkitPlugin plugin;
|
private final TerraBukkitPlugin plugin;
|
||||||
|
|
||||||
|
private int generationThreads;
|
||||||
|
|
||||||
public PlatformImpl(TerraBukkitPlugin plugin) {
|
public PlatformImpl(TerraBukkitPlugin plugin) {
|
||||||
|
generationThreads = getGenerationThreadsWithReflection("ca.spottedleaf.moonrise.common.util.MoonriseCommon", "WORKER_THREADS", "Moonrise");
|
||||||
|
if (generationThreads == 0) {
|
||||||
|
generationThreads = 1;
|
||||||
|
}
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
@@ -108,6 +114,11 @@ public class PlatformImpl extends AbstractPlatform {
|
|||||||
return itemHandle;
|
return itemHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getGenerationThreads() {
|
||||||
|
return generationThreads;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void register(TypeRegistry registry) {
|
public void register(TypeRegistry registry) {
|
||||||
super.register(registry);
|
super.register(registry);
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ dependencies {
|
|||||||
shadedApi("commons-io", "commons-io", Versions.Libraries.Internal.apacheIO)
|
shadedApi("commons-io", "commons-io", Versions.Libraries.Internal.apacheIO)
|
||||||
shadedApi("com.github.Querz", "NBT", Versions.CLI.nbt)
|
shadedApi("com.github.Querz", "NBT", Versions.CLI.nbt)
|
||||||
|
|
||||||
|
shadedImplementation("info.picocli", "picocli", Versions.CLI.picocli)
|
||||||
|
annotationProcessor("info.picocli", "picocli-codegen", Versions.CLI.picocli)
|
||||||
|
|
||||||
shadedImplementation("com.google.guava", "guava", Versions.Libraries.Internal.guava)
|
shadedImplementation("com.google.guava", "guava", Versions.Libraries.Internal.guava)
|
||||||
|
|
||||||
shadedImplementation("ch.qos.logback", "logback-classic", Versions.CLI.logback)
|
shadedImplementation("ch.qos.logback", "logback-classic", Versions.CLI.logback)
|
||||||
@@ -26,6 +29,12 @@ tasks.withType<Jar> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType<JavaCompile> {
|
||||||
|
doFirst {
|
||||||
|
options.compilerArgs.add("-Aproject=${project.group}/${project.name}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
application {
|
application {
|
||||||
mainClass.set(javaMainClass)
|
mainClass.set(javaMainClass)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ public class CLIPlatform extends AbstractPlatform {
|
|||||||
private final CLIWorldHandle worldHandle = new CLIWorldHandle();
|
private final CLIWorldHandle worldHandle = new CLIWorldHandle();
|
||||||
private final CLIItemHandle itemHandle = new CLIItemHandle();
|
private final CLIItemHandle itemHandle = new CLIItemHandle();
|
||||||
|
|
||||||
|
private final int generationThreads = Runtime.getRuntime().availableProcessors() - 1;
|
||||||
|
|
||||||
public CLIPlatform() {
|
public CLIPlatform() {
|
||||||
LOGGER.info("Root directory: {}", getDataFolder().getAbsoluteFile());
|
LOGGER.info("Root directory: {}", getDataFolder().getAbsoluteFile());
|
||||||
load();
|
load();
|
||||||
@@ -58,4 +60,9 @@ public class CLIPlatform extends AbstractPlatform {
|
|||||||
super.register(registry);
|
super.register(registry);
|
||||||
registry.registerLoader(PlatformBiome.class, (TypeLoader<PlatformBiome>) (annotatedType, o, configLoader, depthTracker) -> () -> o);
|
registry.registerLoader(PlatformBiome.class, (TypeLoader<PlatformBiome>) (annotatedType, o, configLoader, depthTracker) -> () -> o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getGenerationThreads() {
|
||||||
|
return generationThreads;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,41 +5,74 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import com.dfsek.terra.api.config.ConfigPack;
|
import com.dfsek.terra.api.config.ConfigPack;
|
||||||
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
|
import com.dfsek.terra.api.event.events.platform.PlatformInitializationEvent;
|
||||||
import com.dfsek.terra.api.util.vector.Vector2Int;
|
import com.dfsek.terra.api.util.vector.Vector2Int;
|
||||||
import com.dfsek.terra.cli.world.CLIWorld;
|
import com.dfsek.terra.cli.world.CLIWorld;
|
||||||
|
|
||||||
|
import picocli.CommandLine;
|
||||||
|
import picocli.CommandLine.Command;
|
||||||
|
import picocli.CommandLine.Option;
|
||||||
|
|
||||||
public final class TerraCLI {
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(TerraCLI.class);
|
|
||||||
|
|
||||||
public static void main(String... args) {
|
//TODO auto pull in version
|
||||||
|
@Command(name = "TerraCLI", mixinStandardHelpOptions = true, version = "6.6.0",
|
||||||
|
description = "Generates a Terra World and saves it in minecraft region format.")
|
||||||
|
public final class TerraCLI implements Callable<Integer> {
|
||||||
|
@Option(names = { "-s", "--size"}, description = "Number of regions to generate.")
|
||||||
|
private int size = 2;
|
||||||
|
|
||||||
|
@Option(names = { "-p", "--pack"}, description = "Config pack to use.")
|
||||||
|
private String pack = "OVERWORLD";
|
||||||
|
|
||||||
|
@Option(names = { "--seed"}, description = "Seed for world generation.")
|
||||||
|
private long seed = 0;
|
||||||
|
|
||||||
|
@Option(names = { "--max-height"}, description = "Maximum height of the world.")
|
||||||
|
private int maxHeight = 384;
|
||||||
|
|
||||||
|
@Option(names = { "--min-height"}, description = "Minimum height of the world.")
|
||||||
|
private int minHeight = -64;
|
||||||
|
|
||||||
|
@Option(names = { "--no-save"}, description = "Don't save the world to disk.")
|
||||||
|
private boolean noSave = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer call() {
|
||||||
|
Logger LOGGER = LoggerFactory.getLogger(TerraCLI.class);
|
||||||
LOGGER.info("Starting Terra CLI...");
|
LOGGER.info("Starting Terra CLI...");
|
||||||
|
|
||||||
CLIPlatform platform = new CLIPlatform();
|
CLIPlatform platform = new CLIPlatform();
|
||||||
platform.getEventManager().callEvent(new PlatformInitializationEvent());
|
platform.getEventManager().callEvent(new PlatformInitializationEvent());
|
||||||
|
|
||||||
ConfigPack generate = platform.getConfigRegistry().getByID("OVERWORLD").orElseThrow(); // TODO: make this a cli argument
|
ConfigPack generate = platform.getConfigRegistry().getByID(pack).orElseThrow();
|
||||||
|
|
||||||
CLIWorld world = new CLIWorld(2, 2, 384, -64, generate);
|
CLIWorld world = new CLIWorld(size, seed, maxHeight, minHeight, generate, noSave);
|
||||||
|
|
||||||
world.generate();
|
world.generate();
|
||||||
|
|
||||||
world.serialize().parallel().forEach(mcaFile -> {
|
if(!noSave) {
|
||||||
Vector2Int pos = mcaFile.getLeft();
|
world.serialize().parallel().forEach(mcaFile -> {
|
||||||
String name = MCAUtil.createNameFromRegionLocation(pos.getX(), pos.getZ());
|
Vector2Int pos = mcaFile.getLeft();
|
||||||
LOGGER.info("Writing region ({}, {}) to {}", pos.getX(), pos.getZ(), name);
|
String name = MCAUtil.createNameFromRegionLocation(pos.getX(), pos.getZ());
|
||||||
|
LOGGER.info("Writing region ({}, {}) to {}", pos.getX(), pos.getZ(), name);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
MCAUtil.write(mcaFile.getRight(), name);
|
MCAUtil.write(mcaFile.getRight(), name);
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
LOGGER.info("Wrote region to file.");
|
LOGGER.info("Wrote region to file.");
|
||||||
});
|
});
|
||||||
|
}
|
||||||
LOGGER.info("Done.");
|
LOGGER.info("Done.");
|
||||||
System.exit(0);
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
int exitCode = new CommandLine(new TerraCLI()).execute(args);
|
||||||
|
System.exit(exitCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ public class CLIWorld implements ServerWorld, NBTSerializable<Stream<Pair<Vector
|
|||||||
private final ChunkGenerator chunkGenerator;
|
private final ChunkGenerator chunkGenerator;
|
||||||
private final BiomeProvider biomeProvider;
|
private final BiomeProvider biomeProvider;
|
||||||
private final ConfigPack pack;
|
private final ConfigPack pack;
|
||||||
|
private final boolean noSave;
|
||||||
private final AtomicInteger amount = new AtomicInteger(0);
|
private final AtomicInteger amount = new AtomicInteger(0);
|
||||||
|
|
||||||
private final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() - 1);
|
private final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() - 1);
|
||||||
@@ -51,7 +52,7 @@ public class CLIWorld implements ServerWorld, NBTSerializable<Stream<Pair<Vector
|
|||||||
long seed,
|
long seed,
|
||||||
int maxHeight,
|
int maxHeight,
|
||||||
int minHeight,
|
int minHeight,
|
||||||
ConfigPack pack) {
|
ConfigPack pack, boolean noSave) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.maxHeight = maxHeight;
|
this.maxHeight = maxHeight;
|
||||||
this.minHeight = minHeight;
|
this.minHeight = minHeight;
|
||||||
@@ -59,6 +60,7 @@ public class CLIWorld implements ServerWorld, NBTSerializable<Stream<Pair<Vector
|
|||||||
this.chunkGenerator = pack.getGeneratorProvider().newInstance(pack);
|
this.chunkGenerator = pack.getGeneratorProvider().newInstance(pack);
|
||||||
this.biomeProvider = pack.getBiomeProvider();
|
this.biomeProvider = pack.getBiomeProvider();
|
||||||
this.pack = pack;
|
this.pack = pack;
|
||||||
|
this.noSave = noSave;
|
||||||
|
|
||||||
|
|
||||||
size += 1;
|
size += 1;
|
||||||
@@ -73,6 +75,7 @@ public class CLIWorld implements ServerWorld, NBTSerializable<Stream<Pair<Vector
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void generate() {
|
public void generate() {
|
||||||
|
ArrayList<Double> CPSHistory = new ArrayList<>();
|
||||||
int sizeChunks = size * 32;
|
int sizeChunks = size * 32;
|
||||||
List<Future<?>> futures = new ArrayList<>();
|
List<Future<?>> futures = new ArrayList<>();
|
||||||
final AtomicLong start = new AtomicLong(System.nanoTime());
|
final AtomicLong start = new AtomicLong(System.nanoTime());
|
||||||
@@ -83,7 +86,13 @@ public class CLIWorld implements ServerWorld, NBTSerializable<Stream<Pair<Vector
|
|||||||
futures.add(executor.submit(() -> {
|
futures.add(executor.submit(() -> {
|
||||||
try {
|
try {
|
||||||
int num = amount.getAndIncrement();
|
int num = amount.getAndIncrement();
|
||||||
CLIChunk chunk = getChunkAt(finalX, finalZ);
|
CLIChunk chunk;
|
||||||
|
if (!noSave) {
|
||||||
|
chunk = getChunkAt(finalX, finalZ);
|
||||||
|
} else {
|
||||||
|
chunk = new CLIChunk(Math.floorMod(finalX, 32), Math.floorMod(finalZ, 32), this);
|
||||||
|
}
|
||||||
|
|
||||||
BiomeProvider cachingBiomeProvider = pack.getBiomeProvider();
|
BiomeProvider cachingBiomeProvider = pack.getBiomeProvider();
|
||||||
chunkGenerator.generateChunkData(chunk, this, cachingBiomeProvider, finalX, finalZ);
|
chunkGenerator.generateChunkData(chunk, this, cachingBiomeProvider, finalX, finalZ);
|
||||||
CLIProtoWorld protoWorld = new CLIProtoWorld(this, cachingBiomeProvider, finalX, finalZ);
|
CLIProtoWorld protoWorld = new CLIProtoWorld(this, cachingBiomeProvider, finalX, finalZ);
|
||||||
@@ -91,6 +100,7 @@ public class CLIWorld implements ServerWorld, NBTSerializable<Stream<Pair<Vector
|
|||||||
if(num % 240 == 239) {
|
if(num % 240 == 239) {
|
||||||
long time = System.nanoTime();
|
long time = System.nanoTime();
|
||||||
double cps = num / ((double) (time - start.get()) / 1000000000);
|
double cps = num / ((double) (time - start.get()) / 1000000000);
|
||||||
|
CPSHistory.add(cps);
|
||||||
LOGGER.info("Generating chunk at ({}, {}), generated {} chunks at {}cps", finalX, finalZ, num, cps);
|
LOGGER.info("Generating chunk at ({}, {}), generated {} chunks at {}cps", finalX, finalZ, num, cps);
|
||||||
amount.set(0);
|
amount.set(0);
|
||||||
start.set(System.nanoTime());
|
start.set(System.nanoTime());
|
||||||
@@ -109,6 +119,8 @@ public class CLIWorld implements ServerWorld, NBTSerializable<Stream<Pair<Vector
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGGER.info("Average CPS: {}", CPSHistory.stream().mapToDouble(d -> d).average().orElse(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+12
@@ -3,6 +3,9 @@ package com.dfsek.terra.lifecycle;
|
|||||||
import ca.solostudios.strata.Versions;
|
import ca.solostudios.strata.Versions;
|
||||||
import ca.solostudios.strata.parser.tokenizer.ParseException;
|
import ca.solostudios.strata.parser.tokenizer.ParseException;
|
||||||
import ca.solostudios.strata.version.Version;
|
import ca.solostudios.strata.version.Version;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.reflection.ReflectionUtil;
|
||||||
|
|
||||||
import net.minecraft.MinecraftVersion;
|
import net.minecraft.MinecraftVersion;
|
||||||
import net.minecraft.enchantment.Enchantment;
|
import net.minecraft.enchantment.Enchantment;
|
||||||
import net.minecraft.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
@@ -37,8 +40,15 @@ public abstract class LifecyclePlatform extends ModPlatform {
|
|||||||
private static final AtomicReference<Registry<MultiNoiseBiomeSourceParameterList>> NOISE = new AtomicReference<>();
|
private static final AtomicReference<Registry<MultiNoiseBiomeSourceParameterList>> NOISE = new AtomicReference<>();
|
||||||
private static final AtomicReference<Registry<Enchantment>> ENCHANTMENT = new AtomicReference<>();
|
private static final AtomicReference<Registry<Enchantment>> ENCHANTMENT = new AtomicReference<>();
|
||||||
private static MinecraftServer server;
|
private static MinecraftServer server;
|
||||||
|
private int generationThreads;
|
||||||
|
|
||||||
public LifecyclePlatform() {
|
public LifecyclePlatform() {
|
||||||
|
generationThreads = getGenerationThreadsWithReflection("com.ishland.c2me.base.common.GlobalExecutors", "GLOBAL_EXECUTOR_PARALLELISM", "C2ME");
|
||||||
|
if (generationThreads == 0) {
|
||||||
|
generationThreads = getGenerationThreadsWithReflection("ca.spottedleaf.moonrise.common.util.MoonriseCommon", "WORKER_THREADS", "Moonrise");
|
||||||
|
} if (generationThreads == 0) {
|
||||||
|
generationThreads = 1;
|
||||||
|
}
|
||||||
CommonPlatform.initialize(this);
|
CommonPlatform.initialize(this);
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
@@ -55,6 +65,8 @@ public abstract class LifecyclePlatform extends ModPlatform {
|
|||||||
ENCHANTMENT.set(enchantmentRegistry);
|
ENCHANTMENT.set(enchantmentRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MinecraftServer getServer() {
|
public MinecraftServer getServer() {
|
||||||
return server;
|
return server;
|
||||||
|
|||||||
Reference in New Issue
Block a user