diff --git a/common/src/main/java/com/seibel/lod/common/wrappers/block/BlockDetailMap.java b/common/src/main/java/com/seibel/lod/common/wrappers/block/BlockDetailMap.java index 663df01a1..bc57b5f98 100644 --- a/common/src/main/java/com/seibel/lod/common/wrappers/block/BlockDetailMap.java +++ b/common/src/main/java/com/seibel/lod/common/wrappers/block/BlockDetailMap.java @@ -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 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(); } 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(); } 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); diff --git a/core b/core index d39912e23..e995834a9 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit d39912e235d920eaecfe1e95d50f3956bf4a9ec8 +Subproject commit e995834a98227f3110a20a07e27cd37cde0f5643