diff --git a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java index 9675cb306..4cd18aa6f 100644 --- a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java @@ -42,11 +42,11 @@ import com.seibel.lod.wrappers.Chunk.ChunkPosWrapper; import com.seibel.lod.wrappers.Chunk.ChunkWrapper; import com.seibel.lod.wrappers.MinecraftWrapper; +import com.seibel.lod.wrappers.World.BiomeColorWrapper; import com.seibel.lod.wrappers.World.BiomeWrapper; import com.seibel.lod.wrappers.World.WorldWrapper; -import net.minecraft.block.Blocks; import net.minecraft.world.DimensionType; import net.minecraft.world.IWorld; @@ -215,7 +215,6 @@ public class LodBuilder int size = 1 << detail.detailLevel; long[] dataToMerge = ThreadMapUtil.getBuilderVerticalArray(detail.detailLevel); - int verticalData = DataPointUtil.worldHeight / 2 + 1; ChunkPosWrapper chunkPos = chunk.getPos(); @@ -322,7 +321,6 @@ public class LodBuilder { for (int y = yAbs; y >= 0; y--) { - blockPos.set(xAbs, y, zAbs); blockPos.set(xAbs, y, zAbs); if (isLayerValidLodPoint(chunk, blockPos)) { @@ -368,9 +366,9 @@ public class LodBuilder aboveColorInt = getColorForBlock(chunk, blockPos); } - if (colorInt == 0 && yAbs > 0) + //if (colorInt == 0 && yAbs > 0) // if this block is invisible, check the block below it - colorInt = generateLodColor(chunk, config, xRel, yAbs - 1, zRel, blockPos); + // colorInt = generateLodColor(chunk, config, xRel, yAbs - 1, zRel, blockPos); // override this block's color if there was a block above this // and we were avoiding non-full/non-solid blocks @@ -472,48 +470,51 @@ public class LodBuilder int y = blockPos.getY(); int z = blockPos.getZ(); - //Biome biome = chunk.getBiomes().getNoiseBiome(xRel >> 2, y >> 2, zRel >> 2); BlockColorWrapper blockColorWrapper; - BlockShapeWrapper blockShapeWrapper; if (chunk.isWaterLogged(blockPos)) { - blockColorWrapper = BlockColorWrapper.WATER_COLOR; - blockShapeWrapper = BlockShapeWrapper.WATER_SHAPE; + BiomeWrapper biome = chunk.getBiome(xRel, y, zRel); + return biome.getWaterTint(); + //blockColorWrapper = BlockColorWrapper.WATER_COLOR; } else { blockColorWrapper = chunk.getBlockColorWrapper(blockPos); - blockShapeWrapper = chunk.getBlockShapeWrapper(blockPos); } - + /* if (blockShapeWrapper.isToAvoid()) { return 0; } - + */ colorOfBlock = blockColorWrapper.getColor(); if (blockColorWrapper.hasTint()) { - BiomeWrapper biome = chunk.getBiome(xRel, y, zRel); + + WorldWrapper world = MinecraftWrapper.INSTANCE.getWrappedServerWorld(); + + if (world.isEmpty()) + { + world = MinecraftWrapper.INSTANCE.getWrappedClientWorld(); + } int tintValue; if (blockColorWrapper.hasGrassTint()) { // grass and green plants - tintValue = biome.getGrassTint(x, z); + tintValue = BiomeColorWrapper.getGrassColor(world,blockPos); } else if (blockColorWrapper.hasFolliageTint()) { - tintValue = biome.getFolliageTint(); + tintValue = BiomeColorWrapper.getFoliageColor(world,blockPos); } else { //we can reintroduce this with the wrappers - //tintValue = BiomeColors.getAverageFoliageColor(serverWorld, blockPos); - tintValue = biome.getWaterTint(); + tintValue = BiomeColorWrapper.getWaterColor(world,blockPos); } colorInt = ColorUtil.multiplyRGBcolors(tintValue | 0xFF000000, colorOfBlock); } @@ -535,8 +536,7 @@ public class LodBuilder boolean noCollisionAvoidance = LodConfig.CLIENT.worldGenerator.blockToAvoid.get().noCollision; BlockShapeWrapper block = chunk.getBlockShapeWrapper(blockPos); - return block != null - && !block.isToAvoid() + return !block.isToAvoid() && !(nonFullAvoidance && block.isNonFull()) && !(noCollisionAvoidance && block.hasNoCollision()); diff --git a/src/main/java/com/seibel/lod/util/ThreadMapUtil.java b/src/main/java/com/seibel/lod/util/ThreadMapUtil.java index d70dbc0e8..c3eac5998 100644 --- a/src/main/java/com/seibel/lod/util/ThreadMapUtil.java +++ b/src/main/java/com/seibel/lod/util/ThreadMapUtil.java @@ -125,11 +125,11 @@ public class ThreadMapUtil if (!threadBuilderVerticalArrayMap.containsKey(Thread.currentThread().getName()) || (threadBuilderVerticalArrayMap.get(Thread.currentThread().getName()) == null)) { long[][] array = new long[5][]; - int size = 1; + int size; for (int i = 0; i < 5; i++) { + size = 1 << i; array[i] = new long[size * size * DataPointUtil.worldHeight / 2 + 1]; - size = size << 1; } threadBuilderVerticalArrayMap.put(Thread.currentThread().getName(), array); } diff --git a/src/main/java/com/seibel/lod/wrappers/Block/BlockColorWrapper.java b/src/main/java/com/seibel/lod/wrappers/Block/BlockColorWrapper.java index 1e03e912c..987204f72 100644 --- a/src/main/java/com/seibel/lod/wrappers/Block/BlockColorWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/Block/BlockColorWrapper.java @@ -1,16 +1,12 @@ package com.seibel.lod.wrappers.Block; import com.seibel.lod.util.ColorUtil; -import com.seibel.lod.wrappers.Chunk.ChunkWrapper; import com.seibel.lod.wrappers.MinecraftWrapper; import net.minecraft.block.*; import net.minecraft.client.renderer.model.BakedQuad; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.util.Direction; -import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.shapes.VoxelShape; -import net.minecraft.world.IBlockReader; import net.minecraftforge.client.model.data.ModelDataMap; import java.util.List; @@ -26,8 +22,10 @@ public class BlockColorWrapper //set of block which require tint public static final ConcurrentMap blockColorWrapperMap = new ConcurrentHashMap<>(); public static final ModelDataMap dataMap = new ModelDataMap.Builder().build(); + public static final BlockPos blockPos = new BlockPos(0,0,0); public static Random random = new Random(0); - public static BlockColorWrapper WATER_COLOR = getBlockColorWrapper(Blocks.WATER); + //public static BlockColourWrapper WATER_COLOR = getBlockColorWrapper(Blocks.WATER); + public static final Direction[] directions = new Direction[] { Direction.UP, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.NORTH, Direction.DOWN }; private Block block; private int color; @@ -39,29 +37,33 @@ public class BlockColorWrapper /**Constructor only require for the block instance we are wrapping**/ - public BlockColorWrapper(Block block) + public BlockColorWrapper(BlockState blockState, BlockPosWrapper blockPosWrapper) { + this.block = blockState.getBlock(); this.color = 0; this.isColored = true; this.toTint = false; - this.block = block; - setupColorAndTint(); + this.folliageTint = false; + this.grassTint = false; + this.waterTint = false; + setupColorAndTint(blockState,blockPosWrapper); + System.out.println(block + " color " + Integer.toHexString(color) + " to tint " + toTint + " folliageTint " + folliageTint + " grassTint " + grassTint + " waterTint " + waterTint); } /** * this return a wrapper of the block in input - * @param block Block object to wrap + * @param blockState of the block to wrap */ - static public BlockColorWrapper getBlockColorWrapper(Block block) + static public BlockColorWrapper getBlockColorWrapper(BlockState blockState, BlockPosWrapper blockPosWrapper) { //first we check if the block has already been wrapped - if (blockColorWrapperMap.containsKey(block) && blockColorWrapperMap.get(block) != null) - return blockColorWrapperMap.get(block); + if (blockColorWrapperMap.containsKey(blockState.getBlock()) && blockColorWrapperMap.get(blockState.getBlock()) != null) + return blockColorWrapperMap.get(blockState.getBlock()); //if it hasn't been created yet, we create it and save it in the map - BlockColorWrapper blockWrapper = new BlockColorWrapper(block); - blockColorWrapperMap.put(block, blockWrapper); + BlockColorWrapper blockWrapper = new BlockColorWrapper(blockState, blockPosWrapper); + blockColorWrapperMap.put(blockState.getBlock(), blockWrapper); //we return the newly created wrapper return blockWrapper; @@ -71,7 +73,7 @@ public class BlockColorWrapper * Generate the color of the given block from its texture * and store it for later use. */ - private void setupColorAndTint() + private void setupColorAndTint(BlockState blockState, BlockPosWrapper blockPosWrapper) { MinecraftWrapper mc = MinecraftWrapper.INSTANCE; TextureAtlasSprite texture; @@ -81,9 +83,9 @@ public class BlockColorWrapper int listSize = 0; // first step is to check if this block has a tinted face - for (Direction direction : Direction.values()) + for (Direction direction : directions) { - quads = mc.getModelManager().getBlockModelShaper().getBlockModel(block.defaultBlockState()).getQuads(block.defaultBlockState(), direction, random, dataMap); + quads = mc.getModelManager().getBlockModelShaper().getBlockModel(block.defaultBlockState()).getQuads(blockState, direction, random, dataMap); listSize = Math.max(listSize, quads.size()); for (BakedQuad bakedQuad : quads) { @@ -96,19 +98,24 @@ public class BlockColorWrapper this.toTint = true; //now we get the first non empty face - for (Direction direction : Direction.values()) + for (Direction direction : directions) { - quads = mc.getModelManager().getBlockModelShaper().getBlockModel(block.defaultBlockState()).getQuads(block.defaultBlockState(), direction, random, dataMap); + quads = mc.getModelManager().getBlockModelShaper().getBlockModel(block.defaultBlockState()).getQuads(blockState, direction, random, dataMap); if (!quads.isEmpty()) break; } //the quads list is not empty we extract the first one if (!quads.isEmpty()) + { + isColored = true; texture = quads.get(0).getSprite(); + } else { - return; + isColored = false; + texture = mc.getModelManager().getBlockModelShaper().getTexture(block.defaultBlockState(), mc.getClientWorld(), blockPosWrapper.getBlockPos()); + //return; } int count = 0; @@ -128,11 +135,12 @@ public class BlockColorWrapper { for (int v = 0; v < texture.getWidth(); v++) { - if (texture.isTransparent(frameIndex, u, v)) - continue; tempColor = texture.getPixelRGBA(frameIndex, u, v); + if (ColorUtil.getAlpha(texture.getPixelRGBA(frameIndex, u, v)) == 0) + continue; + // determine if this pixel is gray int colorMax = Math.max(Math.max(ColorUtil.getBlue(tempColor), ColorUtil.getGreen(tempColor)), ColorUtil.getRed(tempColor)); int colorMin = 4 + Math.min(Math.min(ColorUtil.getBlue(tempColor), ColorUtil.getGreen(tempColor)), ColorUtil.getRed(tempColor)); @@ -177,14 +185,11 @@ public class BlockColorWrapper this.toTint = true; // we check which kind of tint we need to apply - if (grassInstance()) - this.grassTint = true; + this.grassTint = grassInstance() && toTint; - if (leavesInstance()) - this.folliageTint = true; + this.folliageTint = leavesInstance() && toTint; - if (waterIstance()) - this.waterTint = true; + this.waterTint = waterIstance() && toTint; color = tempColor; } @@ -225,7 +230,7 @@ public class BlockColorWrapper public int getColor() { - if(hasColor()) + if (hasColor()) return color; else return block.defaultMaterialColor().col; diff --git a/src/main/java/com/seibel/lod/wrappers/Block/BlockShapeWrapper.java b/src/main/java/com/seibel/lod/wrappers/Block/BlockShapeWrapper.java index e5dd35448..37f1da2e9 100644 --- a/src/main/java/com/seibel/lod/wrappers/Block/BlockShapeWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/Block/BlockShapeWrapper.java @@ -37,8 +37,9 @@ public class BlockShapeWrapper this.block = block; this.nonFull = false; this.noCollision = false; - this.toAvoid = false; + this.toAvoid = ofBlockToAvoid(); setupShapes(chunkWrapper, blockPosWrapper); + System.out.println(block + " non full " + nonFull + " no collision " + noCollision + " to avoid " + toAvoid); } private BlockShapeWrapper() @@ -91,10 +92,7 @@ public class BlockShapeWrapper double xWidth = (bbox.maxX - bbox.minX); double yWidth = (bbox.maxY - bbox.minY); double zWidth = (bbox.maxZ - bbox.minZ); - if (xWidth < 1 && zWidth < 1 && yWidth < 1) - nonFull = true; - else - nonFull = false; + nonFull = xWidth < 1 && zWidth < 1 && yWidth < 1; } else { @@ -107,15 +105,13 @@ public class BlockShapeWrapper VoxelShape collisionShape = block.defaultBlockState().getCollisionShape(chunk, blockPos); noCollision = collisionShape.isEmpty(); } - - toAvoid = ofBlockToAvoid(block); } - private boolean ofBlockToAvoid(Block block) + public boolean ofBlockToAvoid() { - return block == Blocks.AIR - || block != Blocks.CAVE_AIR - || block != Blocks.BARRIER; + return block.equals(Blocks.AIR) + || block.equals(Blocks.CAVE_AIR) + || block.equals(Blocks.BARRIER); } //-----------------// //Avoidance getters// diff --git a/src/main/java/com/seibel/lod/wrappers/Chunk/ChunkWrapper.java b/src/main/java/com/seibel/lod/wrappers/Chunk/ChunkWrapper.java index ca4d89054..0a5fa6725 100644 --- a/src/main/java/com/seibel/lod/wrappers/Chunk/ChunkWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/Chunk/ChunkWrapper.java @@ -47,7 +47,7 @@ public class ChunkWrapper public BlockColorWrapper getBlockColorWrapper(BlockPosWrapper blockPos) { - return BlockColorWrapper.getBlockColorWrapper(chunk.getBlockState(blockPos.getBlockPos()).getBlock()); + return BlockColorWrapper.getBlockColorWrapper(chunk.getBlockState(blockPos.getBlockPos()),blockPos); } public BlockShapeWrapper getBlockShapeWrapper(BlockPosWrapper blockPos) diff --git a/src/main/java/com/seibel/lod/wrappers/World/BiomeColorWrapper.java b/src/main/java/com/seibel/lod/wrappers/World/BiomeColorWrapper.java new file mode 100644 index 000000000..9ec7b0072 --- /dev/null +++ b/src/main/java/com/seibel/lod/wrappers/World/BiomeColorWrapper.java @@ -0,0 +1,33 @@ +package com.seibel.lod.wrappers.World; + +import com.seibel.lod.util.LodUtil; +import com.seibel.lod.wrappers.Block.BlockPosWrapper; +import net.minecraft.block.Blocks; +import net.minecraft.block.material.MaterialColor; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.BiomeColors; + +import java.awt.*; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + + +public class BiomeColorWrapper +{ + + public static int getGrassColor(WorldWrapper worldWrapper, BlockPosWrapper blockPosWrapper) + { + return BiomeColors.getAverageGrassColor(worldWrapper.getWorld(), blockPosWrapper.getBlockPos()); + } + public static int getWaterColor(WorldWrapper worldWrapper, BlockPosWrapper blockPosWrapper) + { + + return BiomeColors.getAverageWaterColor(worldWrapper.getWorld(), blockPosWrapper.getBlockPos()); + } + public static int getFoliageColor(WorldWrapper worldWrapper, BlockPosWrapper blockPosWrapper) + { + + return BiomeColors.getAverageFoliageColor(worldWrapper.getWorld(), blockPosWrapper.getBlockPos()); + } +} diff --git a/src/main/java/com/seibel/lod/wrappers/World/BiomeWrapper.java b/src/main/java/com/seibel/lod/wrappers/World/BiomeWrapper.java index 362b609eb..317bc5710 100644 --- a/src/main/java/com/seibel/lod/wrappers/World/BiomeWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/World/BiomeWrapper.java @@ -1,10 +1,16 @@ package com.seibel.lod.wrappers.World; import com.seibel.lod.util.ColorUtil; +import com.seibel.lod.util.LodUtil; import com.seibel.lod.wrappers.Block.BlockColorWrapper; +import com.seibel.lod.wrappers.Block.BlockPosWrapper; import net.minecraft.block.Blocks; +import net.minecraft.block.material.MaterialColor; +import net.minecraft.world.World; import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.BiomeColors; +import java.awt.*; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -42,72 +48,55 @@ public class BiomeWrapper public int getColorForBiome(int x, int z) { int colorInt; - int color; - int tint; switch (biome.getBiomeCategory()) { case NETHER: - colorInt = BlockColorWrapper.getBlockColorWrapper(Blocks.NETHERRACK).getColor(); + colorInt = Blocks.NETHERRACK.defaultBlockState().materialColor.col; break; case THEEND: - colorInt = BlockColorWrapper.getBlockColorWrapper(Blocks.END_STONE).getColor(); + colorInt = Blocks.END_STONE.defaultBlockState().materialColor.col; break; case BEACH: case DESERT: - colorInt = BlockColorWrapper.getBlockColorWrapper(Blocks.SAND).getColor(); + colorInt = Blocks.SAND.defaultBlockState().materialColor.col; break; case EXTREME_HILLS: - colorInt = BlockColorWrapper.getBlockColorWrapper(Blocks.STONE).getColor(); + colorInt = Blocks.STONE.defaultMaterialColor().col; break; case MUSHROOM: - colorInt = BlockColorWrapper.getBlockColorWrapper(Blocks.MYCELIUM).getColor(); + colorInt = MaterialColor.COLOR_LIGHT_GRAY.col; break; case ICY: - colorInt = BlockColorWrapper.getBlockColorWrapper(Blocks.SNOW).getColor(); + colorInt = Blocks.SNOW.defaultMaterialColor().col; break; case MESA: - colorInt = BlockColorWrapper.getBlockColorWrapper(Blocks.RED_SAND).getColor(); + colorInt = Blocks.RED_SAND.defaultMaterialColor().col; break; case OCEAN: case RIVER: colorInt = biome.getWaterColor(); break; - - case SWAMP: - case FOREST: - color = BlockColorWrapper.getBlockColorWrapper(Blocks.OAK_LEAVES).getColor(); - tint = biome.getFoliageColor(); - colorInt = ColorUtil.multiplyRGBcolors(color, tint); - break; - - case TAIGA: - color = BlockColorWrapper.getBlockColorWrapper(Blocks.SPRUCE_LEAVES).getColor(); - tint = biome.getFoliageColor(); - colorInt = ColorUtil.multiplyRGBcolors(color, tint); - break; - - case JUNGLE: - color = BlockColorWrapper.getBlockColorWrapper(Blocks.JUNGLE_LEAVES).getColor(); - tint = biome.getFoliageColor(); - colorInt = ColorUtil.multiplyRGBcolors(color, tint); - break; - - default: + case NONE: + case FOREST: + case TAIGA: + case JUNGLE: case PLAINS: case SAVANNA: - color = BlockColorWrapper.getBlockColorWrapper(Blocks.GRASS_BLOCK).getColor(); - tint = biome.getGrassColor(x,z); - colorInt = ColorUtil.multiplyRGBcolors(color, tint); + case SWAMP: + default: + Color tmp = LodUtil.intToColor(biome.getGrassColor(x, z)); + tmp = tmp.darker(); + colorInt = LodUtil.colorToInt(tmp); break; } diff --git a/src/main/java/com/seibel/lod/wrappers/World/WorldWrapper.java b/src/main/java/com/seibel/lod/wrappers/World/WorldWrapper.java index 79dddee46..3eda1ed18 100644 --- a/src/main/java/com/seibel/lod/wrappers/World/WorldWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/World/WorldWrapper.java @@ -57,6 +57,11 @@ public class WorldWrapper return BiomeWrapper.getBiomeWrapper(world.getBiome(blockPos.getBlockPos())); } + public IWorld getWorld() + { + return world; + } + public boolean hasCeiling() { return world.dimensionType().hasCeiling();