Update core + fix colors. See commit in core
This commit is contained in:
@@ -5,7 +5,6 @@ import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.seibel.lod.core.api.ApiShared;
|
||||
import com.seibel.lod.core.api.ClientApi;
|
||||
import com.seibel.lod.core.util.ColorUtil;
|
||||
import com.seibel.lod.core.wrapperInterfaces.block.BlockDetail;
|
||||
|
||||
@@ -15,10 +14,12 @@ import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.FlowerBlock;
|
||||
import net.minecraft.world.level.block.LeavesBlock;
|
||||
import net.minecraft.world.level.block.LiquidBlock;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.RotatedPillarBlock;
|
||||
@@ -35,15 +36,14 @@ public class BlockDetailMap
|
||||
|
||||
//TODO: Perhaps make this not just use the first frame?
|
||||
//FIXME: Stuff is wrong.
|
||||
private static int calculateColorFromTexture(TextureAtlasSprite texture, boolean useFlowerScaling) {
|
||||
private static int calculateColorFromTexture(TextureAtlasSprite texture, boolean useFlowerScaling, boolean useFastLeaf) {
|
||||
|
||||
int count = 0;
|
||||
int alpha = 0;
|
||||
int red = 0;
|
||||
int green = 0;
|
||||
int blue = 0;
|
||||
double alpha = 0;
|
||||
double red = 0;
|
||||
double green = 0;
|
||||
double blue = 0;
|
||||
int tempColor;
|
||||
int colorMultiplier;
|
||||
|
||||
{
|
||||
// textures normally use u and v instead of x and y
|
||||
@@ -51,42 +51,59 @@ public class BlockDetailMap
|
||||
{
|
||||
for (int v = 0; v < texture.getHeight(); v++)
|
||||
{
|
||||
//note: Minecraft color format is: 0xAA BB GG RR
|
||||
//________ DH mod color format is: 0xAA RR GG BB
|
||||
//OpenGL RGBA format native order: 0xRR GG BB AA
|
||||
//_ OpenGL RGBA format Java Order: 0xAA BB GG RR
|
||||
tempColor = TextureAtlasSpriteWrapper.getPixelRGBA(texture, 0, u, v);
|
||||
|
||||
if (ColorUtil.getAlpha(TextureAtlasSpriteWrapper.getPixelRGBA(texture, 0, u, v)) == 0)
|
||||
continue;
|
||||
double r = ((tempColor & 0x000000FF) )/255.;
|
||||
double g = ((tempColor & 0x0000FF00) >>> 8)/255.;
|
||||
double b = ((tempColor & 0x00FF0000) >>> 16)/255.;
|
||||
double a = ((tempColor & 0xFF000000) >>> 24)/255.;
|
||||
int scale = 1;
|
||||
|
||||
// for flowers, weight their non-green color higher
|
||||
if (useFlowerScaling && (
|
||||
!(ColorUtil.getGreen(tempColor) > (ColorUtil.getBlue(tempColor) + 30)) ||
|
||||
!(ColorUtil.getGreen(tempColor) > (ColorUtil.getRed(tempColor) + 30))
|
||||
))
|
||||
colorMultiplier = FLOWER_COLOR_SCALE;
|
||||
else
|
||||
colorMultiplier = 1;
|
||||
if (useFastLeaf) {
|
||||
r *= a;
|
||||
g *= a;
|
||||
b *= a;
|
||||
a = 1.;
|
||||
} else if (a==0.) {
|
||||
continue;
|
||||
} else if (useFlowerScaling && (g+0.1<b || g+0.1<r)) {
|
||||
scale = FLOWER_COLOR_SCALE;
|
||||
}
|
||||
|
||||
// add to the running averages
|
||||
count += colorMultiplier;
|
||||
alpha += ColorUtil.getAlpha(tempColor) * ColorUtil.getAlpha(tempColor) * colorMultiplier;
|
||||
red += ColorUtil.getBlue(tempColor) * ColorUtil.getBlue(tempColor) * colorMultiplier;
|
||||
green += ColorUtil.getGreen(tempColor) * ColorUtil.getGreen(tempColor) * colorMultiplier;
|
||||
blue += ColorUtil.getRed(tempColor) * ColorUtil.getRed(tempColor) * colorMultiplier;
|
||||
count += scale;
|
||||
alpha += a*a*scale;
|
||||
red += r*r*scale;
|
||||
green += g*g*scale;
|
||||
blue += b*b*scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
// this block is entirely transparent
|
||||
tempColor = 0;
|
||||
tempColor = ColorUtil.rgbToInt(255,255,0,255);
|
||||
else
|
||||
{
|
||||
// determine the average color
|
||||
tempColor = ColorUtil.rgbToInt(
|
||||
(int) Math.sqrt(alpha / count),
|
||||
(int) Math.sqrt(red / count),
|
||||
(int) Math.sqrt(green / count),
|
||||
(int) Math.sqrt(blue / count));
|
||||
(int) (Math.sqrt(alpha/count)*255.),
|
||||
(int) (Math.sqrt(red / count)*255.),
|
||||
(int) (Math.sqrt(green / count)*255.),
|
||||
(int) (Math.sqrt(blue / count)*255.));
|
||||
}
|
||||
// TODO: Remove this when transparency is added!
|
||||
double colorAlpha = ColorUtil.getAlpha(tempColor)/255.;
|
||||
tempColor = ColorUtil.rgbToInt(
|
||||
ColorUtil.getAlpha(tempColor),
|
||||
(int)(ColorUtil.getRed(tempColor) * colorAlpha),
|
||||
(int)(ColorUtil.getGreen(tempColor) * colorAlpha),
|
||||
(int)(ColorUtil.getBlue(tempColor) * colorAlpha)
|
||||
);
|
||||
|
||||
return tempColor;
|
||||
}
|
||||
|
||||
@@ -98,8 +115,9 @@ public class BlockDetailMap
|
||||
|
||||
private static final Direction[] DIRECTION_ORDER = {Direction.UP, Direction.NORTH, Direction.EAST, Direction.WEST, Direction.SOUTH, Direction.DOWN};
|
||||
|
||||
|
||||
ConcurrentHashMap<Biome, BlockDetail> biomeDetailMap = null;
|
||||
BlockDetail blockDetail;
|
||||
BlockDetail defaultTintedDetail = null;
|
||||
boolean requireResolving;
|
||||
@SuppressWarnings("unused")
|
||||
boolean requireShade; //TODO: Add back using this in renderer
|
||||
@@ -113,14 +131,14 @@ public class BlockDetailMap
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean hasNoCollision(BlockState bs, BlockPos pos, BlockAndTintGetter getter) {
|
||||
static boolean hasNoCollision(BlockState bs, BlockPos pos, LevelReader getter) {
|
||||
if (!bs.getFluidState().isEmpty() || bs.getBlock() instanceof LiquidBlock) // Is blockState a fluid?
|
||||
return false;
|
||||
if (bs.getCollisionShape(getter, pos).isEmpty())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
static boolean hasOnlyNonFullFace(BlockState bs, BlockPos pos, BlockAndTintGetter getter) {
|
||||
static boolean hasOnlyNonFullFace(BlockState bs, BlockPos pos, LevelReader getter) {
|
||||
if (!bs.getFluidState().isEmpty() || bs.getBlock() instanceof LiquidBlock) // Is blockState a fluid?
|
||||
return false;
|
||||
VoxelShape voxelShape = bs.getShape(getter, pos);
|
||||
@@ -132,7 +150,7 @@ public class BlockDetailMap
|
||||
return xWidth < 1 && zWidth < 1 && yWidth < 1;
|
||||
}
|
||||
|
||||
static BlockDetailCache make(BlockState bs, BlockPos pos, BlockAndTintGetter getter) {
|
||||
static BlockDetailCache make(BlockState bs, BlockPos pos, LevelReader getter) {
|
||||
boolean noCol, nonFull, canOcclude;
|
||||
if(!bs.getFluidState().isEmpty()) {
|
||||
bs = bs.getFluidState().createLegacyBlock();
|
||||
@@ -142,7 +160,7 @@ public class BlockDetailMap
|
||||
nonFull = false;
|
||||
canOcclude = false;
|
||||
BlockDetailCache result = new BlockDetailCache(fs);
|
||||
ApiShared.LOGGER.info(fs.toString()+" = ["+result+"]");
|
||||
//ApiShared.LOGGER.info(fs.toString()+" = ["+result+"]");
|
||||
return result;
|
||||
} else {
|
||||
if (bs.getRenderShape() != RenderShape.MODEL) return NULL_BLOCK_DETAIL;
|
||||
@@ -159,18 +177,20 @@ public class BlockDetailMap
|
||||
break;
|
||||
};
|
||||
if (quads == null || quads.isEmpty()) return NULL_BLOCK_DETAIL;
|
||||
BlockDetailCache result = new BlockDetailCache(canOcclude, noCol, nonFull, quads.get(0), bs.getBlock() instanceof FlowerBlock);
|
||||
ApiShared.LOGGER.info(bs.toString()+" = ["+result+"]");
|
||||
BlockDetailCache result = new BlockDetailCache(canOcclude, noCol, nonFull, quads.get(0),
|
||||
bs.getBlock() instanceof FlowerBlock, bs.getBlock() instanceof LeavesBlock);
|
||||
// ApiShared.LOGGER.info(bs.toString()+" = ["+result+"]");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
BlockDetailCache(boolean isFullBlock, boolean noCol, boolean nonFull, BakedQuad quad, boolean useFlowerScaling) {
|
||||
BlockDetailCache(boolean isFullBlock, boolean noCol, boolean nonFull, BakedQuad quad, boolean useFlowerScaling, boolean useFastLeaf) {
|
||||
requireResolving = quad.isTinted();
|
||||
requireShade = quad.isShade();
|
||||
tintIndex = quad.getTintIndex();
|
||||
scaleFlowerColor = useFlowerScaling;
|
||||
blockDetail = new BlockDetail(calculateColorFromTexture(quad.getSprite(), useFlowerScaling), isFullBlock, noCol, nonFull);
|
||||
blockDetail = new BlockDetail(calculateColorFromTexture(quad.getSprite(), useFlowerScaling, useFastLeaf), isFullBlock, noCol, nonFull);
|
||||
if (quad.isTinted()) biomeDetailMap = new ConcurrentHashMap<Biome, BlockDetail>();
|
||||
}
|
||||
|
||||
BlockDetailCache(FluidState fluid) {
|
||||
@@ -179,7 +199,8 @@ public class BlockDetailMap
|
||||
tintIndex = 0; // Vanilla doesn't use this index currently. (Checked at 1.18.X, See BlockColors.class)
|
||||
scaleFlowerColor = false;
|
||||
TextureAtlasSprite text = Minecraft.getInstance().getModelManager().getBlockModelShaper().getBlockModel(fluid.createLegacyBlock()).getParticleIcon();
|
||||
blockDetail = new BlockDetail(calculateColorFromTexture(text, false), true, false, false);
|
||||
blockDetail = new BlockDetail(calculateColorFromTexture(text, false, false), true, false, false);
|
||||
biomeDetailMap = new ConcurrentHashMap<Biome, BlockDetail>();
|
||||
}
|
||||
|
||||
private BlockDetailCache()
|
||||
@@ -187,25 +208,40 @@ public class BlockDetailMap
|
||||
//DUMMY CREATOR
|
||||
}
|
||||
|
||||
BlockDetail getResolvedBlockDetail(BlockState bs, int x, int y, int z, BlockAndTintGetter getter) {
|
||||
BlockDetail getResolvedBlockDetail(BlockState bs, int x, int y, int z, LevelReader getter) {
|
||||
if (!requireResolving) return blockDetail;
|
||||
BlockColors bc = Minecraft.getInstance().getBlockColors();
|
||||
if (!bs.getFluidState().isEmpty()) bs = bs.getFluidState().createLegacyBlock();
|
||||
int tintColor = bc.getColor(bs, getter, new BlockPos(x, y, z), tintIndex);
|
||||
if (tintColor == -1) return blockDetail;
|
||||
return new BlockDetail(ColorUtil.multiplyRGBcolors(blockDetail.color, tintColor),
|
||||
blockDetail.isFullBlock, blockDetail.hasNoCollision, blockDetail.hasOnlyNonFullFace);
|
||||
BlockPos pos = new BlockPos(x,y,z);
|
||||
Biome biome = getter.getBiome(pos);
|
||||
BlockDetail tintDetail = biomeDetailMap.get(biome);
|
||||
if (tintDetail == null) {
|
||||
if (!bs.getFluidState().isEmpty()) bs = bs.getFluidState().createLegacyBlock();
|
||||
BlockColors bc = Minecraft.getInstance().getBlockColors();
|
||||
int tintColor = bc.getColor(bs, getter, pos, tintIndex);
|
||||
tintColor = ColorUtil.multiplyARGBwithRGB(blockDetail.color, tintColor);
|
||||
tintDetail = new BlockDetail(tintColor, blockDetail.isFullBlock,
|
||||
blockDetail.hasNoCollision, blockDetail.hasOnlyNonFullFace);
|
||||
BlockDetail tintDetailCAS = biomeDetailMap.putIfAbsent(biome, tintDetail);
|
||||
if (tintDetailCAS != null) tintDetail = tintDetailCAS;
|
||||
}
|
||||
return tintDetail;
|
||||
}
|
||||
|
||||
// Note: this one won't resolve biome based or pos based colors. (Kinda like GUI block icons)
|
||||
BlockDetail getResolvedBlockDetail(BlockState bs) {
|
||||
if (!requireResolving) return blockDetail;
|
||||
if (defaultTintedDetail != null) return defaultTintedDetail;
|
||||
|
||||
BlockColors bc = Minecraft.getInstance().getBlockColors();
|
||||
if (!bs.getFluidState().isEmpty()) bs = bs.getFluidState().createLegacyBlock();
|
||||
int tintColor = bc.getColor(bs, null, null, tintIndex);
|
||||
if (tintColor == -1) return blockDetail;
|
||||
return new BlockDetail(ColorUtil.multiplyRGBcolors(blockDetail.color, tintColor),
|
||||
if (tintColor == -1) {
|
||||
defaultTintedDetail = blockDetail;
|
||||
}
|
||||
else {
|
||||
defaultTintedDetail = new BlockDetail(ColorUtil.multiplyARGBwithRGB(blockDetail.color, tintColor),
|
||||
blockDetail.isFullBlock, blockDetail.hasNoCollision, blockDetail.hasOnlyNonFullFace);
|
||||
}
|
||||
return defaultTintedDetail;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -221,7 +257,7 @@ public class BlockDetailMap
|
||||
|
||||
private BlockDetailMap() {}
|
||||
|
||||
private static BlockDetailCache getOrMakeBlockDetailCache(BlockState bs, BlockPos pos, BlockAndTintGetter getter) {
|
||||
private static BlockDetailCache getOrMakeBlockDetailCache(BlockState bs, BlockPos pos, LevelReader getter) {
|
||||
BlockDetailCache cache = map.get(bs);
|
||||
if (cache != null) return cache;
|
||||
if (bs.getFluidState().isEmpty()) {
|
||||
@@ -242,7 +278,7 @@ public class BlockDetailMap
|
||||
}
|
||||
|
||||
// Return null means skip the block
|
||||
public static BlockDetail getBlockDetailWithCompleteTint(BlockState bs, int x, int y, int z, BlockAndTintGetter tintGetter) {
|
||||
public static BlockDetail getBlockDetailWithCompleteTint(BlockState bs, int x, int y, int z, LevelReader tintGetter) {
|
||||
BlockDetailCache cache = getOrMakeBlockDetailCache(bs, new BlockPos(x,y,z), tintGetter);
|
||||
if (cache == BlockDetailCache.NULL_BLOCK_DETAIL) return null;
|
||||
return cache.getResolvedBlockDetail(bs, x, y, z, tintGetter);
|
||||
|
||||
+1
-1
Submodule core updated: d39912e235...e995834a98
Reference in New Issue
Block a user