mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 02:20:57 +00:00
Implement distance sampler
This commit is contained in:
@@ -24,6 +24,7 @@ import com.dfsek.terra.addons.noise.config.templates.LinearHeightmapSamplerTempl
|
||||
import com.dfsek.terra.addons.noise.config.templates.TranslateSamplerTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.noise.CellularNoiseTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.noise.ConstantNoiseTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.noise.DistanceSamplerTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.noise.ExpressionFunctionTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.noise.GaborNoiseTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.noise.SimpleNoiseTemplate;
|
||||
@@ -44,6 +45,7 @@ import com.dfsek.terra.addons.noise.samplers.arithmetic.MinSampler;
|
||||
import com.dfsek.terra.addons.noise.samplers.arithmetic.MultiplicationSampler;
|
||||
import com.dfsek.terra.addons.noise.samplers.arithmetic.SubtractionSampler;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.CellularSampler;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.DistanceSampler;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.random.GaussianNoiseSampler;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.random.PositiveWhiteNoiseSampler;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.random.WhiteNoiseSampler;
|
||||
@@ -85,6 +87,8 @@ public class NoiseAddon implements AddonInitializer {
|
||||
(type, o, loader, depthTracker) -> CellularSampler.DistanceFunction.valueOf((String) o))
|
||||
.applyLoader(CellularSampler.ReturnType.class,
|
||||
(type, o, loader, depthTracker) -> CellularSampler.ReturnType.valueOf((String) o))
|
||||
.applyLoader(DistanceSampler.DistanceFunction.class,
|
||||
(type, o, loader, depthTracker) -> DistanceSampler.DistanceFunction.valueOf((String) o))
|
||||
.applyLoader(DimensionApplicableNoiseSampler.class, DimensionApplicableNoiseSampler::new)
|
||||
.applyLoader(FunctionTemplate.class, FunctionTemplate::new);
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.dfsek.terra.addons.noise.config.templates.noise;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
|
||||
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.DistanceSampler;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.DistanceSampler.DistanceFunction;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
|
||||
|
||||
public class DistanceSamplerTemplate extends SamplerTemplate<DistanceSampler> {
|
||||
|
||||
@Value("distance-function")
|
||||
@Default
|
||||
private DistanceSampler.@Meta DistanceFunction distanceFunction = DistanceFunction.Euclidean;
|
||||
|
||||
@Value("point.x")
|
||||
@Default
|
||||
private @Meta double x = 0;
|
||||
|
||||
@Value("point.y")
|
||||
@Default
|
||||
private @Meta double y = 0;
|
||||
|
||||
@Value("point.z")
|
||||
@Default
|
||||
private @Meta double z = 0;
|
||||
|
||||
@Value("normalize")
|
||||
@Default
|
||||
private @Meta boolean normalize = false;
|
||||
|
||||
@Value("radius")
|
||||
@Default
|
||||
private @Meta double normalizeRadius = 100;
|
||||
|
||||
@Override
|
||||
public DistanceSampler get() {
|
||||
return new DistanceSampler(distanceFunction, x, y, z, normalize, normalizeRadius);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.dfsek.terra.addons.noise.samplers.noise;
|
||||
|
||||
|
||||
public class DistanceSampler extends NoiseFunction {
|
||||
|
||||
private final DistanceFunction distanceFunction;
|
||||
private final double ox, oy, oz;
|
||||
private final boolean normalize;
|
||||
private final double radius;
|
||||
|
||||
private final double distanceAtRadius;
|
||||
|
||||
public DistanceSampler(DistanceFunction distanceFunction, double ox, double oy, double oz, boolean normalize, double radius) {
|
||||
frequency = 1;
|
||||
this.distanceFunction = distanceFunction;
|
||||
this.ox = ox;
|
||||
this.oy = oy;
|
||||
this.oz = oz;
|
||||
this.normalize = normalize;
|
||||
this.radius = radius;
|
||||
this.distanceAtRadius = distance2d(distanceFunction, radius, 0); // distance2d and distance3d should return the same value
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(long seed, double x, double y) {
|
||||
double dx = x - ox;
|
||||
double dy = y - oz;
|
||||
if (normalize && (fastAbs(dx) > radius || fastAbs(dy) > radius)) return 1;
|
||||
double dist = distance2d(distanceFunction, dx, dy);
|
||||
if (normalize) return fastMin(((2*dist)/distanceAtRadius)-1, 1);
|
||||
return dist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(long seed, double x, double y, double z) {
|
||||
double dx = x - ox;
|
||||
double dy = y - oy;
|
||||
double dz = z - oz;
|
||||
if(normalize && (fastAbs(dx) > radius || fastAbs(dy) > radius || fastAbs(dz) > radius)) return 1;
|
||||
double dist = distance3d(distanceFunction, dx, dy, dz);
|
||||
if (normalize) return fastMin(((2*dist)/distanceAtRadius)-1, 1);
|
||||
return dist;
|
||||
}
|
||||
|
||||
private static double distance2d(DistanceFunction distanceFunction, double x, double z) {
|
||||
return switch(distanceFunction) {
|
||||
case Euclidean -> fastSqrt(x*x + z*z);
|
||||
case EuclideanSq -> x*x + z*z;
|
||||
case Manhattan -> fastAbs(x) + fastAbs(z);
|
||||
};
|
||||
}
|
||||
|
||||
private static double distance3d(DistanceFunction distanceFunction, double x, double y, double z) {
|
||||
return switch(distanceFunction) {
|
||||
case Euclidean -> fastSqrt(x*x + y*y + z*z);
|
||||
case EuclideanSq -> x*x + y*y + z*z;
|
||||
case Manhattan -> fastAbs(x) + fastAbs(y) + fastAbs(z);
|
||||
};
|
||||
}
|
||||
|
||||
public enum DistanceFunction {
|
||||
Euclidean,
|
||||
EuclideanSq,
|
||||
Manhattan
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user