Implement dot product layer palette

This commit is contained in:
Astrash
2022-07-30 12:00:54 +10:00
parent 596c84ab10
commit 9a171b0cdb
4 changed files with 135 additions and 18 deletions

View File

@@ -15,6 +15,7 @@ import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerPredicatePackConfi
import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerResolverPackConfigTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerSamplerPackConfigTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.palette.BiomeDefinedLayerPaletteTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.palette.DotProductLayerPaletteTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.palette.PlatformAirLayerPaletteTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.palette.SimpleLayerPaletteTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.AdjacentPointSetTemplate;
@@ -36,8 +37,6 @@ import com.dfsek.terra.addons.chunkgenerator.config.sampler.BiomeDefinedLayerSam
import com.dfsek.terra.addons.chunkgenerator.config.sampler.SimpleLayerSamplerTemplate;
import com.dfsek.terra.addons.chunkgenerator.generation.LayeredChunkGenerator;
import com.dfsek.terra.addons.chunkgenerator.layer.palette.BiomeDefinedLayerPalette;
import com.dfsek.terra.addons.chunkgenerator.layer.predicate.SamplerLayerPredicate;
import com.dfsek.terra.addons.chunkgenerator.layer.predicate.SamplerListLayerPredicate.CoordinateTest;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.BiomeDefinedLayerSampler;
import com.dfsek.terra.addons.chunkgenerator.math.BooleanOperator;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
@@ -124,11 +123,24 @@ public class LayeredChunkGeneratorAddon implements AddonInitializer {
samplerRegistry.register(addon.key(key), new InstanceWrapper<>(sampler));
});
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<LayerPredicate>>> predicateTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_PREDICATE_TYPE_TOKEN);
predicateTypeRegistry.register(addon.key("BELOW"), BelowLayerPredicateTemplate::new);
predicateTypeRegistry.register(addon.key("RANGE"), RangeLayerPredicateTemplate::new);
predicateTypeRegistry.register(addon.key("SAMPLER"), SamplerLayerPredicateTemplate::new);
predicateTypeRegistry.register(addon.key("SAMPLER_POINTS"), SamplerListLayerPredicateTemplate::new);
CheckedRegistry<InstanceWrapper<LayerPredicate>> predicateRegistry = event.getPack().getOrCreateRegistry(LAYER_PREDICATE_TOKEN);
event.loadTemplate(new LayerPredicatePackConfigTemplate()).getPredicates().forEach((key, predicate) -> {
predicateRegistry.register(addon.key(key), new InstanceWrapper<>(predicate));
});
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<LayerPalette>>> paletteTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_PALETTE_TYPE_TOKEN);
paletteTypeRegistry.register(addon.key("PALETTE"), SimpleLayerPaletteTemplate::new);
paletteTypeRegistry.register(addon.key("BIOME_DEFINED"), BiomeDefinedLayerPaletteTemplate::new);
paletteTypeRegistry.register(addon.key("AIR"), () -> new PlatformAirLayerPaletteTemplate(platform));
paletteTypeRegistry.register(addon.key("SURFACE_NORMAL"), DotProductLayerPaletteTemplate::new);
event.getPack().applyLoader(LayerPalette.Group.class, new LayerPalette.Group.Loader(event.getPack()));
@@ -137,22 +149,6 @@ public class LayeredChunkGeneratorAddon implements AddonInitializer {
paletteRegistry.register(addon.key(key), new InstanceWrapper<>(palette));
});
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<LayerPredicate>>> predicateTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_PREDICATE_TYPE_TOKEN);
predicateTypeRegistry.register(addon.key("BELOW"), BelowLayerPredicateTemplate::new);
predicateTypeRegistry.register(addon.key("RANGE"), RangeLayerPredicateTemplate::new);
predicateTypeRegistry.register(addon.key("SAMPLER"), SamplerLayerPredicateTemplate::new);
predicateTypeRegistry.register(addon.key("SAMPLER_LIST"), SamplerListLayerPredicateTemplate::new);
event.getPack().applyLoader(CoordinateTest.class, CoordinateTest.Template::new)
.applyLoader(SamplerLayerPredicate.Operator.class,
(type, o, loader, depthTracker) -> SamplerLayerPredicate.Operator.valueOf((String) o));
CheckedRegistry<InstanceWrapper<LayerPredicate>> predicateRegistry = event.getPack().getOrCreateRegistry(LAYER_PREDICATE_TOKEN);
event.loadTemplate(new LayerPredicatePackConfigTemplate()).getPredicates().forEach((key, predicate) -> {
predicateRegistry.register(addon.key(key), new InstanceWrapper<>(predicate));
});
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<LayerResolver>>> resolverTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_RESOLVER_TYPE_TOKEN);
resolverTypeRegistry.register(addon.key("TEST"), PredicateLayerResolverTemplate::new);

View File

@@ -0,0 +1,44 @@
package com.dfsek.terra.addons.chunkgenerator.config.palette;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.HashMap;
import java.util.Map;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.palette.DotProductLayerPalette;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.AdjacentPointSet;
import com.dfsek.terra.addons.chunkgenerator.palette.DoubleNavigableHolder;
import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.api.util.vector.Vector3;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
public class DotProductLayerPaletteTemplate extends LayerPaletteTemplate {
@Value("normal.approximation-points")
@Default
private PointSet normalApproximationPoints = new AdjacentPointSet();
@Value("normal.direction")
@Default
private Vector3 direction = Vector3.of(0, 1, 0);
@Value("normal.sampler")
private InstanceWrapper<LayerSampler> sampler;
@Value("palettes")
private Map<String, Palette> palettes;
@Override
public LayerPalette get() {
Map<Double, Palette> paletteMap = new HashMap<>();
palettes.forEach((s, p) -> {
paletteMap.put(Double.parseDouble(s), p);
});
return new DotProductLayerPalette(group, resetsGroup, normalApproximationPoints, new DoubleNavigableHolder<>(paletteMap), sampler.get(), direction);
}
}

View File

@@ -0,0 +1,43 @@
package com.dfsek.terra.addons.chunkgenerator.layer.palette;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.addons.chunkgenerator.palette.DoubleNavigableHolder;
import com.dfsek.terra.api.util.vector.Vector3;
import com.dfsek.terra.api.util.vector.Vector3Int;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
import com.dfsek.terra.api.world.info.WorldProperties;
public class DotProductLayerPalette extends LayerPalette {
private static final Logger logger = LoggerFactory.getLogger(DotProductLayerPalette.class);
private final DoubleNavigableHolder<Palette> palettes;
private final Vector3Int[] samplePoints;
private final LayerSampler sampler;
private final Vector3 direction;
public DotProductLayerPalette(Group group, boolean resetsGroup,
PointSet points, DoubleNavigableHolder<Palette> palettes, LayerSampler sampler, Vector3 direction) {
super(group, resetsGroup);
this.palettes = palettes;
this.sampler = sampler;
this.direction = direction;
this.samplePoints = points.toArray();
}
@Override
public Palette get(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) {
Vector3.Mutable surfaceNormalApproximation = Vector3.Mutable.of(0, 0, 0);
for(Vector3Int point : samplePoints) {
double scalar = -sampler.sample(x+point.getX(), y+point.getY(), z+point.getZ(), world, biomeProvider);
surfaceNormalApproximation.add(point.toVector3Mutable().multiply(scalar));
}
return palettes.get(direction.dot(surfaceNormalApproximation.normalize()));
}
}

View File

@@ -0,0 +1,34 @@
package com.dfsek.terra.addons.chunkgenerator.palette;
import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
public class DoubleNavigableHolder<T> {
private final NavigableMap<Double, T> map;
public DoubleNavigableHolder(Map<Double, T> inputMap) {
NavigableMap<Double, T> map = new TreeMap<>(inputMap);
map.put(Double.MAX_VALUE, map.lastEntry().getValue());
this.map = map;
}
public T get(double threshold) {
return map.ceilingEntry(threshold).getValue();
}
enum Method {
CEILING,
FLOOR,
CLOSEST
}
public class Single extends DoubleNavigableHolder<T> {
public Single(Map<Double, T> inputMap) {
super(inputMap);
}
}
}