diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/LayeredChunkGeneratorAddon.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/LayeredChunkGeneratorAddon.java index 844594577..b2bf49e76 100644 --- a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/LayeredChunkGeneratorAddon.java +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/LayeredChunkGeneratorAddon.java @@ -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>> 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> 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>> 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>> 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> 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>> resolverTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_RESOLVER_TYPE_TOKEN); resolverTypeRegistry.register(addon.key("TEST"), PredicateLayerResolverTemplate::new); diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/DotProductLayerPaletteTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/DotProductLayerPaletteTemplate.java new file mode 100644 index 000000000..6d8fed140 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/DotProductLayerPaletteTemplate.java @@ -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 sampler; + + @Value("palettes") + private Map palettes; + + @Override + public LayerPalette get() { + Map 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); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/DotProductLayerPalette.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/DotProductLayerPalette.java new file mode 100644 index 000000000..8da5d5f7b --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/DotProductLayerPalette.java @@ -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 palettes; + private final Vector3Int[] samplePoints; + private final LayerSampler sampler; + private final Vector3 direction; + + public DotProductLayerPalette(Group group, boolean resetsGroup, + PointSet points, DoubleNavigableHolder 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())); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/DoubleNavigableHolder.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/DoubleNavigableHolder.java new file mode 100644 index 000000000..2f0a9f91b --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/DoubleNavigableHolder.java @@ -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 { + + private final NavigableMap map; + + public DoubleNavigableHolder(Map inputMap) { + NavigableMap 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 { + + public Single(Map inputMap) { + super(inputMap); + } + } +}