Biome mixing tweaks to texture util
This commit is contained in:
parent
d14b267cfd
commit
0dbb3b2844
@ -468,20 +468,18 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
int widthIndex = img.getWidth() - 1;
|
||||
int heightIndex = img.getHeight() - 1;
|
||||
int maxIndex = biomes.length - 1;
|
||||
|
||||
int[] buffer = new int[2];
|
||||
for (int y = 0; y < img.getHeight(); y++) {
|
||||
boolean yBiome = y > 0 && y < heightIndex;
|
||||
for (int x = 0; x < img.getWidth(); x++) {
|
||||
for (int x = 0; x < img.getWidth(); x++, index++) {
|
||||
int color = img.getRGB(x, y);
|
||||
BaseBlock block = textureUtil.getNearestBlock(color);
|
||||
TextureUtil.BiomeColor biome = textureUtil.getNearestBiome(color);
|
||||
int blockColor = textureUtil.getColor(block);
|
||||
biomes[index] = (byte) biome.id;
|
||||
if (textureUtil.colorDistance(biome.grass, color) - biomePriority > textureUtil.colorDistance(blockColor, color)) {
|
||||
char combined = (char) block.getCombined();
|
||||
if (textureUtil.getIsBlockCloserThanBiome(buffer, color, biomePriority)) {
|
||||
char combined = (char) buffer[0];
|
||||
main[index] = combined;
|
||||
floor[index] = combined;
|
||||
}
|
||||
index++;
|
||||
biomes[index] = (byte) buffer[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,4 +118,4 @@ public class CopyPastaBrush implements Brush, ResettableTool {
|
||||
editSession.flushQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -49,6 +49,16 @@ public class DelegateTextureUtil extends TextureUtil {
|
||||
return parent.getColor(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getIsBlockCloserThanBiome(int[] blockAndBiomeIdOutput, int color, int biomePriority) {
|
||||
return parent.getIsBlockCloserThanBiome(blockAndBiomeIdOutput, color, biomePriority);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiomeMix(int[] biomeIdsOutput, int color) {
|
||||
return parent.getBiomeMix(biomeIdsOutput, color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeColor getBiome(int biome) {
|
||||
return parent.getBiome(biome);
|
||||
|
@ -16,8 +16,10 @@ public class RandomTextureUtil extends CachedTextureUtil {
|
||||
this.grassColor = parent.getColor(FaweCache.getBlock(BlockID.GRASS, 0));
|
||||
}
|
||||
|
||||
private int index;
|
||||
private int[] biomeMixBuffer = new int[3];
|
||||
private Int2ObjectOpenHashMap<Integer> offsets = new Int2ObjectOpenHashMap<>();
|
||||
private Int2ObjectOpenHashMap<Integer> biomeOffsets = new Int2ObjectOpenHashMap<>();
|
||||
private Int2ObjectOpenHashMap<int[]> biomeMixes = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
protected int addRandomColor(int c1, int c2) {
|
||||
int red1 = (c1 >> 16) & 0xFF;
|
||||
@ -38,26 +40,45 @@ public class RandomTextureUtil extends CachedTextureUtil {
|
||||
} else {
|
||||
return PseudoRandom.random.nextInt(i);
|
||||
}
|
||||
// return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getIsBlockCloserThanBiome(int[] blockAndBiomeIdOutput, int color, int biomePriority) {
|
||||
BaseBlock block = getNearestBlock(color);
|
||||
int[] mix = biomeMixes.getOrDefault(color, null);
|
||||
if (mix == null) {
|
||||
int average = getBiomeMix(biomeMixBuffer, color);
|
||||
mix = new int[4];
|
||||
System.arraycopy(biomeMixBuffer, 0, mix, 0, 3);
|
||||
mix[3] = average;
|
||||
biomeMixes.put(color, mix);
|
||||
}
|
||||
if (++index > 2) index = 0;
|
||||
int biomeId = mix[index];
|
||||
int biomeAvColor = mix[3];
|
||||
int blockColor = getColor(block);
|
||||
blockAndBiomeIdOutput[0] = block.getCombined();
|
||||
blockAndBiomeIdOutput[1] = biomeId;
|
||||
if (colorDistance(biomeAvColor, color) - biomePriority > colorDistance(blockColor, color)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BiomeColor getNearestBiome(int color) {
|
||||
int offsetColor = biomeOffsets.getOrDefault(color, 0);
|
||||
if (offsetColor != 0) {
|
||||
offsetColor = addRandomColor(color, offsetColor);
|
||||
} else {
|
||||
offsetColor = color;
|
||||
int[] mix = biomeMixes.getOrDefault(color, null);
|
||||
if (mix == null) {
|
||||
int average = getBiomeMix(biomeMixBuffer, color);
|
||||
mix = new int[4];
|
||||
System.arraycopy(biomeMixBuffer, 0, mix, 0, 3);
|
||||
mix[3] = average;
|
||||
biomeMixes.put(color, mix);
|
||||
}
|
||||
BiomeColor res = super.getNearestBiome(offsetColor);
|
||||
int newColor = res.grass;
|
||||
{
|
||||
byte dr = (byte) (((color >> 16) & 0xFF) - ((newColor >> 16) & 0xFF));
|
||||
byte dg = (byte) (((color >> 8) & 0xFF) - ((newColor >> 8) & 0xFF));
|
||||
byte db = (byte) (((color >> 0) & 0xFF) - ((newColor >> 0) & 0xFF));
|
||||
biomeOffsets.put(color, (Integer) ((dr << 16) + (dg << 8) + (db << 0)));
|
||||
}
|
||||
return res;
|
||||
if (++index > 2) index = 0;
|
||||
int biomeId = mix[index];
|
||||
return getBiome(biomeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -11,6 +11,8 @@ import com.sk89q.worldedit.blocks.BlockID;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArraySet;
|
||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
@ -50,9 +52,13 @@ public class TextureUtil {
|
||||
protected long[] distances;
|
||||
protected int[] validColors;
|
||||
protected char[] validBlockIds;
|
||||
|
||||
protected int[] validLayerColors;
|
||||
protected char[][] validLayerBlocks;
|
||||
|
||||
protected int[] validMixBiomeColors;
|
||||
protected long[] validMixBiomeIds;
|
||||
|
||||
|
||||
/**
|
||||
* https://github.com/erich666/Mineways/blob/master/Win/biomes.cpp
|
||||
@ -420,6 +426,43 @@ public class TextureUtil {
|
||||
return biomes[biome];
|
||||
}
|
||||
|
||||
public boolean getIsBlockCloserThanBiome(int[] blockAndBiomeIdOutput, int color, int biomePriority) {
|
||||
BaseBlock block = getNearestBlock(color);
|
||||
TextureUtil.BiomeColor biome = getNearestBiome(color);
|
||||
int blockColor = getColor(block);
|
||||
blockAndBiomeIdOutput[0] = block.getCombined();
|
||||
blockAndBiomeIdOutput[1] = biome.id;
|
||||
if (colorDistance(biome.grass, color) - biomePriority > colorDistance(blockColor, color)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getBiomeMix(int[] biomeIdsOutput, int color) {
|
||||
long closest = Long.MAX_VALUE;
|
||||
int closestAverage = Integer.MAX_VALUE;
|
||||
long min = Long.MAX_VALUE;
|
||||
int red1 = (color >> 16) & 0xFF;
|
||||
int green1 = (color >> 8) & 0xFF;
|
||||
int blue1 = (color >> 0) & 0xFF;
|
||||
int alpha = (color >> 24) & 0xFF;
|
||||
for (int i = 0; i < validMixBiomeColors.length; i++) {
|
||||
int other = validMixBiomeColors[i];
|
||||
if (((other >> 24) & 0xFF) == alpha) {
|
||||
long distance = colorDistance(red1, green1, blue1, other);
|
||||
if (distance < min) {
|
||||
min = distance;
|
||||
closest = validMixBiomeIds[i];
|
||||
closestAverage = other;
|
||||
}
|
||||
}
|
||||
}
|
||||
biomeIdsOutput[0] = (int) ((closest >> 0) & 0xFF);
|
||||
biomeIdsOutput[1] = (int) ((closest >> 8) & 0xFF);
|
||||
biomeIdsOutput[2] = (int) ((closest >> 16) & 0xFF);
|
||||
return closestAverage;
|
||||
}
|
||||
|
||||
public BiomeColor getNearestBiome(int color) {
|
||||
int grass = blockColors[2 << 4];
|
||||
if (grass == 0) {
|
||||
@ -633,12 +676,47 @@ public class TextureUtil {
|
||||
List<BiomeColor> valid = new ArrayList<>();
|
||||
for (int i = 0; i < biomes.length; i++) {
|
||||
BiomeColor biome = biomes[i];
|
||||
biome.grass = multiplyColor(biome.grass, grass);
|
||||
// biome.grass = multiplyColor(biome.grass, grass);
|
||||
if (biome.grass != 0 && !biome.name.equalsIgnoreCase("Unknown Biome")) {
|
||||
valid.add(biome);
|
||||
}
|
||||
}
|
||||
this.validBiomes = valid.toArray(new BiomeColor[valid.size()]);
|
||||
|
||||
{
|
||||
ArrayList<BiomeColor> uniqueColors = new ArrayList<>();
|
||||
Set<Integer> uniqueBiomesColors = new IntArraySet();
|
||||
for (BiomeColor color : validBiomes) {
|
||||
if (uniqueBiomesColors.add(color.grass)) {
|
||||
uniqueColors.add(color);
|
||||
}
|
||||
}
|
||||
int count = 0;
|
||||
int count2 = 0;
|
||||
uniqueBiomesColors.clear();
|
||||
|
||||
LongArrayList layerIds = new LongArrayList();
|
||||
LongArrayList layerColors = new LongArrayList();
|
||||
for (int i = 0; i < uniqueColors.size(); i++) {
|
||||
for (int j = i; j < uniqueColors.size(); j++) {
|
||||
for (int k = j; k < uniqueColors.size(); k++) {
|
||||
BiomeColor c1 = uniqueColors.get(i);
|
||||
BiomeColor c2 = uniqueColors.get(j);
|
||||
BiomeColor c3 = uniqueColors.get(k);
|
||||
int average = averageColor(c1.grass, c2.grass, c3.grass);
|
||||
if (uniqueBiomesColors.add(average)) {
|
||||
count++;
|
||||
layerColors.add((long) average);
|
||||
layerIds.add((long) ((c1.id) + (c2.id << 8) + (c3.id << 16)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
validMixBiomeColors = new int[layerColors.size()];
|
||||
for (int i = 0; i < layerColors.size(); i++) validMixBiomeColors[i] = (int) layerColors.getLong(i);
|
||||
validMixBiomeIds = layerIds.toLongArray();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -703,6 +781,25 @@ public class TextureUtil {
|
||||
return (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
|
||||
}
|
||||
|
||||
public int averageColor(int... colors) {
|
||||
int alpha = 0;
|
||||
int red = 0;
|
||||
int green = 0;
|
||||
int blue = 0;
|
||||
for (int c : colors) {
|
||||
alpha += (c >> 24) & 0xFF;
|
||||
red += (c >> 16) & 0xFF;
|
||||
green += (c >> 8) & 0xFF;
|
||||
blue += (c >> 0) & 0xFF;
|
||||
}
|
||||
int num = colors.length;
|
||||
alpha /= num;
|
||||
red /= num;
|
||||
green /= num;
|
||||
blue /= num;
|
||||
return (alpha << 24) + (red << 16) + (green << 8) + (blue << 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assumes the top layer is a transparent color and the bottom is opaque
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user