add image align options

This commit is contained in:
dfsek 2021-02-12 14:29:39 -07:00
parent 8a47a01dd8
commit 5e40fbbf07
4 changed files with 32 additions and 27 deletions

View File

@ -9,14 +9,16 @@ import java.awt.image.BufferedImage;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class ImageBiomeProvider implements BiomeProvider { public class ImageBiomeProvider implements BiomeProvider, BiomeProvider.BiomeProviderBuilder { // This provider does not need a seed, so it is its own builder.
private final Map<Color, TerraBiome> colorBiomeMap = new HashMap<>(); private final Map<Color, TerraBiome> colorBiomeMap = new HashMap<>();
private final BufferedImage image; private final BufferedImage image;
private final int resolution; private final int resolution;
private final Align align;
public ImageBiomeProvider(TerraRegistry<TerraBiome> registry, BufferedImage image, int resolution) { public ImageBiomeProvider(TerraRegistry<TerraBiome> registry, BufferedImage image, int resolution, Align align) {
this.image = image; this.image = image;
this.resolution = resolution; this.resolution = resolution;
this.align = align;
registry.forEach(biome -> colorBiomeMap.put(new Color(biome.getColor()), biome)); registry.forEach(biome -> colorBiomeMap.put(new Color(biome.getColor()), biome));
} }
@ -26,7 +28,9 @@ public class ImageBiomeProvider implements BiomeProvider {
@Override @Override
public TerraBiome getBiome(int x, int z) { public TerraBiome getBiome(int x, int z) {
Color color = new Color(image.getRGB(FastMath.floorMod(x / resolution, image.getWidth()), FastMath.floorMod(z / resolution, image.getHeight()))); x /= resolution;
z /= resolution;
Color color = align.getColor(image, x, z);
return colorBiomeMap.get(colorBiomeMap.keySet().stream().reduce(colorBiomeMap.keySet().stream().findAny().orElseThrow(IllegalStateException::new), (running, element) -> { return colorBiomeMap.get(colorBiomeMap.keySet().stream().reduce(colorBiomeMap.keySet().stream().findAny().orElseThrow(IllegalStateException::new), (running, element) -> {
int d1 = distance(color, running); int d1 = distance(color, running);
int d2 = distance(color, element); int d2 = distance(color, element);
@ -34,20 +38,24 @@ public class ImageBiomeProvider implements BiomeProvider {
})); }));
} }
public static class ImageBiomeProviderBuilder implements BiomeProviderBuilder { @Override
private final BufferedImage image; public BiomeProvider build(long seed) {
private final int resolution; return this;
private final TerraRegistry<TerraBiome> registry; }
public ImageBiomeProviderBuilder(BufferedImage image, int resolution, TerraRegistry<TerraBiome> registry) { public enum Align {
this.image = image; CENTER {
this.resolution = resolution; @Override
this.registry = registry; public Color getColor(BufferedImage image, int x, int z) {
} return new Color(image.getRGB(FastMath.floorMod(x - image.getWidth() / 2, image.getWidth()), FastMath.floorMod(z - image.getHeight() / 2, image.getHeight())));
}
}, NONE {
@Override
public Color getColor(BufferedImage image, int x, int z) {
return new Color(image.getRGB(FastMath.floorMod(x, image.getWidth()), FastMath.floorMod(z, image.getHeight())));
}
};
@Override public abstract Color getColor(BufferedImage image, int x, int z);
public BiomeProvider build(long seed) {
return new ImageBiomeProvider(registry, image, resolution);
}
} }
} }

View File

@ -2,7 +2,7 @@ package com.dfsek.terra.biome.provider;
import com.dfsek.terra.biome.TerraBiome; import com.dfsek.terra.biome.TerraBiome;
public class SingleBiomeProvider implements BiomeProvider { public class SingleBiomeProvider implements BiomeProvider, BiomeProvider.BiomeProviderBuilder {
private final TerraBiome biome; private final TerraBiome biome;
public SingleBiomeProvider(TerraBiome biome) { public SingleBiomeProvider(TerraBiome biome) {
@ -14,5 +14,8 @@ public class SingleBiomeProvider implements BiomeProvider {
return biome; return biome;
} }
@Override
public BiomeProvider build(long seed) {
return this;
}
} }

View File

@ -79,18 +79,12 @@ public class BiomeProviderBuilderLoader implements TypeLoader<BiomeProvider.Biom
try { try {
main.getLogger().info("Using image " + imageMap.get("name") + " for biome distribution."); main.getLogger().info("Using image " + imageMap.get("name") + " for biome distribution.");
BufferedImage image = ImageIO.read(fileLoader.get(imageMap.get("name").toString())); BufferedImage image = ImageIO.read(fileLoader.get(imageMap.get("name").toString()));
return new ImageBiomeProvider.ImageBiomeProviderBuilder(image, resolution, biomeRegistry); return new ImageBiomeProvider(biomeRegistry, image, resolution, ImageBiomeProvider.Align.valueOf((String) imageMap.getOrDefault("align", "CENTER")));
} catch(IOException e) { } catch(IOException e) {
throw new LoadException("Failed to load image", e); throw new LoadException("Failed to load image", e);
} }
} else if(map.get("type").equals("SINGLE")) { } else if(map.get("type").equals("SINGLE")) {
return seed -> { return new SingleBiomeProvider(loader.loadClass(TerraBiome.class, map.get("biome")));
try {
return new SingleBiomeProvider(loader.loadClass(TerraBiome.class, map.get("biome")));
} catch(LoadException e) {
throw new RuntimeException(e);
}
};
} }
throw new LoadException("No such biome provider type: " + map.get("type")); throw new LoadException("No such biome provider type: " + map.get("type"));

View File

@ -48,7 +48,7 @@ public class ImageTest {
}; };
folderLoader.open("biomes", ".yml").then(inputStreams -> ConfigPack.buildAll((template, main) -> template, biomeRegistry, loader.load(inputStreams, TestBiome::new), null)); folderLoader.open("biomes", ".yml").then(inputStreams -> ConfigPack.buildAll((template, main) -> template, biomeRegistry, loader.load(inputStreams, TestBiome::new), null));
return new ImageBiomeProvider(biomeRegistry, ImageIO.read(ImageTest.class.getResourceAsStream("/map.jpg")), 1); return new ImageBiomeProvider(biomeRegistry, ImageIO.read(ImageTest.class.getResourceAsStream("/map.jpg")), 1, ImageBiomeProvider.Align.CENTER);
} }
@Test @Test