From 12a32b9fb4addbcb737c191fd7938edc6b9edece Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 26 Oct 2021 11:58:33 +0200 Subject: [PATCH 01/10] Implemented the wrappers in the lodBuilder --- .../lod/builders/lodBuilding/LodBuilder.java | 569 +++--------------- .../worldGeneration/LodGenWorker.java | 11 +- .../com/seibel/lod/proxy/ClientProxy.java | 5 +- .../lod/wrappers/Block/BlockPosWrapper.java | 2 +- .../lod/wrappers/Block/BlockWrapper.java | 143 ++++- .../lod/wrappers/Chunk/ChunkPosWrapper.java | 20 + .../lod/wrappers/Chunk/ChunkWrapper.java | 74 ++- .../seibel/lod/wrappers/MinecraftWrapper.java | 32 + .../lod/wrappers/World/BiomeWrapper.java | 16 + .../lod/wrappers/World/WorldWrapper.java | 8 +- 10 files changed, 362 insertions(+), 518 deletions(-) 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 152f58efa..ff1d8444a 100644 --- a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java @@ -19,9 +19,6 @@ package com.seibel.lod.builders.lodBuilding; -import java.awt.Color; -import java.util.List; -import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutorService; @@ -30,11 +27,9 @@ import java.util.concurrent.Executors; import com.seibel.lod.config.LodConfig; import com.seibel.lod.enums.DistanceGenerationMode; import com.seibel.lod.enums.HorizontalResolution; -import com.seibel.lod.enums.VerticalQuality; import com.seibel.lod.objects.LodDimension; import com.seibel.lod.objects.LodRegion; import com.seibel.lod.objects.LodWorld; -import com.seibel.lod.proxy.ClientProxy; import com.seibel.lod.util.ColorUtil; import com.seibel.lod.util.DataPointUtil; import com.seibel.lod.util.DetailDistanceUtil; @@ -42,47 +37,23 @@ import com.seibel.lod.util.LevelPosUtil; import com.seibel.lod.util.LodThreadFactory; import com.seibel.lod.util.LodUtil; import com.seibel.lod.util.ThreadMapUtil; +import com.seibel.lod.wrappers.Block.BlockPosWrapper; +import com.seibel.lod.wrappers.Block.BlockWrapper; +import com.seibel.lod.wrappers.Chunk.ChunkPosWrapper; +import com.seibel.lod.wrappers.Chunk.ChunkWrapper; import com.seibel.lod.wrappers.MinecraftWrapper; -import net.minecraft.block.AbstractPlantBlock; -import net.minecraft.block.AbstractTopPlantBlock; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; +import com.seibel.lod.wrappers.World.BiomeWrapper; +import com.seibel.lod.wrappers.World.WorldWrapper; + + import net.minecraft.block.Blocks; -import net.minecraft.block.BushBlock; -import net.minecraft.block.FlowerBlock; -import net.minecraft.block.GrassBlock; -import net.minecraft.block.IGrowable; -import net.minecraft.block.ILiquidContainer; -import net.minecraft.block.IWaterLoggable; -import net.minecraft.block.LeavesBlock; -import net.minecraft.block.SixWayBlock; -import net.minecraft.block.TallGrassBlock; -import net.minecraft.block.material.MaterialColor; -import net.minecraft.client.renderer.model.BakedQuad; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.data.BlockModelProvider; -import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.util.Direction; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.ChunkPos; -import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.DimensionType; import net.minecraft.world.IWorld; -import net.minecraft.world.LightType; -import net.minecraft.world.World; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.BiomeColors; -import net.minecraft.world.chunk.ChunkSection; -import net.minecraft.world.chunk.IChunk; -import net.minecraft.world.server.ServerWorld; -import net.minecraftforge.client.model.data.ModelDataMap; /** * This object is in charge of creating Lod related objects. - * + * * @author Cola * @author Leonardo Amato * @author James Seibel @@ -94,18 +65,6 @@ public class LodBuilder private final ExecutorService lodGenThreadPool = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName())); - public static final Direction[] directions = new Direction[] { Direction.UP, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.NORTH, Direction.DOWN }; - public static final int CHUNK_DATA_WIDTH = LodUtil.CHUNK_WIDTH; - public static final int CHUNK_SECTION_HEIGHT = CHUNK_DATA_WIDTH; - public static final ConcurrentMap colorMap = new ConcurrentHashMap<>(); - public static final ConcurrentMap tintColor = new ConcurrentHashMap<>(); - public static final ConcurrentMap toTint = new ConcurrentHashMap<>(); - - public static final ConcurrentMap notFullBlock = new ConcurrentHashMap<>(); - public static final ConcurrentMap smallBlock = new ConcurrentHashMap<>(); - - - public static final ModelDataMap dataMap = new ModelDataMap.Builder().build(); /** If no blocks are found in the area in determineBottomPointForArea return this */ public static final short DEFAULT_DEPTH = 0; @@ -131,12 +90,12 @@ public class LodBuilder } - public void generateLodNodeAsync(IChunk chunk, LodWorld lodWorld, IWorld world) + public void generateLodNodeAsync(ChunkWrapper chunk, LodWorld lodWorld, IWorld world) { generateLodNodeAsync(chunk, lodWorld, world, DistanceGenerationMode.SERVER); } - public void generateLodNodeAsync(IChunk chunk, LodWorld lodWorld, IWorld world, DistanceGenerationMode generationMode) + public void generateLodNodeAsync(ChunkWrapper chunk, LodWorld lodWorld, IWorld world, DistanceGenerationMode generationMode) { if (lodWorld == null || lodWorld.getIsWorldNotLoaded()) return; @@ -191,7 +150,7 @@ public class LodBuilder * Creates a LodNode for a chunk in the given world. * @throws IllegalArgumentException thrown if either the chunk or world is null. */ - public void generateLodNodeFromChunk(LodDimension lodDim, IChunk chunk) throws IllegalArgumentException + public void generateLodNodeFromChunk(LodDimension lodDim, ChunkWrapper chunk) throws IllegalArgumentException { generateLodNodeFromChunk(lodDim, chunk, new LodBuilderConfig()); } @@ -200,7 +159,7 @@ public class LodBuilder * Creates a LodNode for a chunk in the given world. * @throws IllegalArgumentException thrown if either the chunk or world is null. */ - public void generateLodNodeFromChunk(LodDimension lodDim, IChunk chunk, LodBuilderConfig config) + public void generateLodNodeFromChunk(LodDimension lodDim, ChunkWrapper chunk, LodBuilderConfig config) throws IllegalArgumentException { if (chunk == null) @@ -237,23 +196,23 @@ public class LodBuilder endZ = detail.endZ[i]; long[] data; - long[] dataToMergeVertical = createVerticalDataToMerge(detail, chunk, config, startX, startZ, endX, endZ); + long[] dataToMergeVertical = createVerticalDataToMerge(detail, chunk, config, startX, startZ); data = DataPointUtil.mergeMultiData(dataToMergeVertical, DataPointUtil.worldHeight / 2 + 1, DetailDistanceUtil.getMaxVerticalData(detailLevel)); //lodDim.clear(detailLevel, posX, posZ); if (data != null && data.length != 0) { - posX = LevelPosUtil.convert((byte) 0, chunk.getPos().x * 16 + startX, detail.detailLevel); - posZ = LevelPosUtil.convert((byte) 0, chunk.getPos().z * 16 + startZ, detail.detailLevel); + posX = LevelPosUtil.convert((byte) 0, chunk.getPos().getX() * 16 + startX, detail.detailLevel); + posZ = LevelPosUtil.convert((byte) 0, chunk.getPos().getZ() * 16 + startZ, detail.detailLevel); lodDim.addVerticalData(detailLevel, posX, posZ, data, false); } } - lodDim.updateData(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z); + lodDim.updateData(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().getX(), chunk.getPos().getZ()); } /** creates a vertical DataPoint */ - private long[] createVerticalDataToMerge(HorizontalResolution detail, IChunk chunk, LodBuilderConfig config, int startX, int startZ, int endX, int endZ) + private long[] createVerticalDataToMerge(HorizontalResolution detail, ChunkWrapper chunk, LodBuilderConfig config, int startX, int startZ) { // equivalent to 2^detailLevel int size = 1 << detail.detailLevel; @@ -262,7 +221,7 @@ public class LodBuilder int verticalData = DataPointUtil.worldHeight / 2 + 1; - ChunkPos chunkPos = chunk.getPos(); + ChunkPosWrapper chunkPos = chunk.getPos(); int height; int depth; int color; @@ -279,7 +238,7 @@ public class LodBuilder boolean hasCeiling = mc.getClientWorld().dimensionType().hasCeiling(); boolean hasSkyLight = mc.getClientWorld().dimensionType().hasSkyLight(); boolean isDefault; - BlockPos.Mutable blockPos = new BlockPos.Mutable(0, 0, 0); + BlockPosWrapper blockPos = new BlockPosWrapper(); int index; for (index = 0; index < size * size; index++) @@ -295,7 +254,7 @@ public class LodBuilder boolean topBlock = true; while (yAbs > 0) { - height = determineHeightPointFrom(chunk, config, xRel, zRel, yAbs, blockPos); + height = determineHeightPointFrom(chunk, config, xRel, yAbs, zRel, blockPos); // If the lod is at the default height, it must be void data if (height == DEFAULT_HEIGHT) @@ -307,13 +266,13 @@ public class LodBuilder yAbs = height - 1; // We search light on above air block - depth = determineBottomPointFrom(chunk, config, xRel, zRel, yAbs, blockPos); + depth = determineBottomPointFrom(chunk, config, xRel, yAbs, zRel, blockPos); if (hasCeiling && topBlock) { yAbs = depth; blockPos.set(xAbs, yAbs, zAbs); light = getLightValue(chunk, blockPos, hasCeiling, hasSkyLight, topBlock); - color = generateLodColor(chunk, config, xRel, yAbs, zRel, blockPos); + color = generateLodColor(chunk, config, xAbs, yAbs, zAbs, blockPos); blockPos.set(xAbs, yAbs - 1, zAbs); } else @@ -340,67 +299,39 @@ public class LodBuilder * Find the lowest valid point from the bottom. * Used when creating a vertical LOD. */ - private short determineBottomPointFrom(IChunk chunk, LodBuilderConfig config, int xRel, int zRel, int yAbs, BlockPos.Mutable blockPos) + private short determineBottomPointFrom(ChunkWrapper chunk, LodBuilderConfig config, int xAbs, int yAbs, int zAbs, BlockPosWrapper blockPos) { short depth = DEFAULT_DEPTH; - /*if (config.useHeightmap) + + for (int y = yAbs; y >= 0; y--) { - // when using the generated heightmap there is no data about the lowest point - depth = 0; //DEFAULT_DEPTH == 0 - } - else - {*/ - boolean voidData = true; - ChunkSection[] chunkSections = chunk.getSections(); - for (int sectionIndex = chunkSections.length - 1; sectionIndex >= 0; sectionIndex--) - { - for (int yRel = CHUNK_DATA_WIDTH - 1; yRel >= 0; yRel--) + blockPos.set(xAbs, y, zAbs); + if (!isLayerValidLodPoint(chunk, blockPos)) { - if (sectionIndex * CHUNK_DATA_WIDTH + yRel > yAbs) - continue; - - blockPos.set(chunk.getPos().getMinBlockX() + xRel, sectionIndex * CHUNK_DATA_WIDTH + yRel, chunk.getPos().getMinBlockZ() + zRel); - if (!isLayerValidLodPoint(chunk, blockPos)) - { - depth = (short) (sectionIndex * CHUNK_DATA_WIDTH + yRel + 1); - voidData = false; - break; - } - } - - if (!voidData) + depth = (short) (y + 1); break; + } } - //} return depth; } /** Find the highest valid point from the Top */ - private short determineHeightPointFrom(IChunk chunk, LodBuilderConfig config, int xRel, int zRel, int yAbs, BlockPos.Mutable blockPos) + private short determineHeightPointFrom(ChunkWrapper chunk, LodBuilderConfig config, int xAbs, int yAbs, int zAbs, BlockPosWrapper blockPos) { short height = DEFAULT_HEIGHT; if (config.useHeightmap) - height = (short) chunk.getOrCreateHeightmapUnprimed(LodUtil.DEFAULT_HEIGHTMAP).getFirstAvailable(xRel, zRel); + height = (short) chunk.getHeightMapValue(xAbs, zAbs); else { - boolean voidData = true; - ChunkSection[] chunkSections = chunk.getSections(); - for (int sectionIndex = chunkSections.length - 1; sectionIndex >= 0; sectionIndex--) + for (int y = yAbs; y >= 0; y--) { - for (int yRel = CHUNK_DATA_WIDTH - 1; yRel >= 0; yRel--) + blockPos.set(xAbs, y, zAbs); + blockPos.set(xAbs, y, zAbs); + if (isLayerValidLodPoint(chunk, blockPos)) { - if (sectionIndex * CHUNK_DATA_WIDTH + yRel > yAbs) - continue; - blockPos.set(chunk.getPos().getMinBlockX() + xRel, sectionIndex * CHUNK_DATA_WIDTH + yRel, chunk.getPos().getMinBlockZ() + zRel); - if (isLayerValidLodPoint(chunk, blockPos)) - { - height = (short) (sectionIndex * CHUNK_DATA_WIDTH + yRel + 1); - voidData = false; - break; - } - } - if (!voidData) + height = (short) (y + 1); break; + } } } return height; @@ -416,26 +347,19 @@ public class LodBuilder * Generate the color for the given chunk using biome water color, foliage * color, and grass color. */ - private int generateLodColor(IChunk chunk, LodBuilderConfig config, int xRel, int yAbs, int zRel, BlockPos.Mutable blockPos) + private int generateLodColor(ChunkWrapper chunk, LodBuilderConfig config, int xRel, int yAbs, int zRel, BlockPosWrapper blockPos) { - ChunkSection[] chunkSections = chunk.getSections(); int colorInt = 0; if (config.useBiomeColors) { // I have no idea why I need to bit shift to the right, but // if I don't the biomes don't show up correctly. - Biome biome = chunk.getBiomes().getNoiseBiome(xRel >> 2, yAbs >> 2, zRel >> 2); - colorInt = getColorForBiome(xRel, zRel, biome); + colorInt = chunk.getBiome(xRel, yAbs, zRel).getColorForBiome(xRel, zRel); } else { - int sectionIndex = Math.floorDiv(yAbs, CHUNK_SECTION_HEIGHT); - int yRel = Math.floorMod(yAbs, CHUNK_SECTION_HEIGHT); - if (chunkSections[sectionIndex] != null) - { - blockPos.set(chunk.getPos().getMinBlockX() + xRel, sectionIndex * CHUNK_DATA_WIDTH + yRel, chunk.getPos().getMinBlockZ() + zRel); - colorInt = getColorForBlock(chunk, blockPos); - } + blockPos.set(chunk.getPos().getMinBlockX() + xRel, yAbs, chunk.getPos().getMinBlockZ() + zRel); + colorInt = getColorForBlock(chunk, blockPos); // if we are skipping non-full and non-solid blocks that means we ignore // snow, flowers, etc. Get the above block so we can still get the color @@ -443,7 +367,7 @@ public class LodBuilder int aboveColorInt = 0; if (LodConfig.CLIENT.worldGenerator.blockToAvoid.get().nonFull || LodConfig.CLIENT.worldGenerator.blockToAvoid.get().noCollision) { - blockPos.set(chunk.getPos().getMinBlockX() + xRel, sectionIndex * CHUNK_DATA_WIDTH + yRel + 1, chunk.getPos().getMinBlockZ() + zRel); + blockPos.set(chunk.getPos().getMinBlockX() + xRel, yAbs + 1, chunk.getPos().getMinBlockZ() + zRel); aboveColorInt = getColorForBlock(chunk, blockPos); } @@ -461,21 +385,16 @@ public class LodBuilder } /** Gets the light value for the given block position */ - private int getLightValue(IChunk chunk, BlockPos.Mutable blockPos, boolean hasCeiling, boolean hasSkyLight, boolean topBlock) + private int getLightValue(ChunkWrapper chunk, BlockPosWrapper blockPos, boolean hasCeiling, boolean hasSkyLight, boolean topBlock) { int skyLight = 0; int blockLight; // 1 means the lighting is a guess int isDefault = 0; + WorldWrapper world = MinecraftWrapper.INSTANCE.getWrappedServerWorld(); - ClientWorld clientWorld = mc.getClientWorld(); - if (clientWorld == null) - return 0; - ServerWorld serverWorld = LodUtil.getServerWorldFromDimension(clientWorld.dimensionType()); - - - int blockBrightness = chunk.getLightEmission(blockPos); + int blockBrightness = chunk.getEmittedBrightness(blockPos); // get the air block above or below this block if (hasCeiling && topBlock) blockPos.set(blockPos.getX(), blockPos.getY() - 1, blockPos.getZ()); @@ -484,14 +403,14 @@ public class LodBuilder - if (serverWorld != null) + if (world.isEmpty()) { // server world sky light (always accurate) - blockLight = serverWorld.getBrightness(LightType.BLOCK, blockPos); - if(topBlock && !hasCeiling && hasSkyLight) + blockLight = world.getBlockLight(blockPos); + if (topBlock && !hasCeiling && hasSkyLight) skyLight = DEFAULT_MAX_LIGHT; else - skyLight = serverWorld.getBrightness(LightType.SKY, blockPos); + skyLight = world.getSkyLight(blockPos); if (!topBlock && skyLight == 15) { @@ -508,8 +427,11 @@ public class LodBuilder } else { + world = MinecraftWrapper.INSTANCE.getWrappedClientWorld(); + if(world.isEmpty()) + return 0; // client world sky light (almost never accurate) - blockLight = clientWorld.getBrightness(LightType.BLOCK, blockPos); + blockLight = world.getBlockLight(blockPos); // estimate what the lighting should be if (hasSkyLight || !hasCeiling) { @@ -517,7 +439,7 @@ public class LodBuilder skyLight = DEFAULT_MAX_LIGHT; else { - skyLight = clientWorld.getBrightness(LightType.SKY, blockPos); + skyLight = world.getSkyLight(blockPos); if (!chunk.isLightCorrect() && (skyLight == 0 || skyLight == 15)) { // we don't know what the light here is, @@ -539,147 +461,8 @@ public class LodBuilder return blockLight + (skyLight << 4) + (isDefault << 8); } - - /** - * Generate the color of the given block from its texture - * and store it for later use. - */ - private int getColorTextureForBlock(BlockState blockState, BlockPos blockPos, boolean useTopTexture) - { - // use the pre-generated color if we can - Block block = blockState.getBlock(); - if (colorMap.containsKey(block) && toTint.containsKey(block)) - return colorMap.get(block); - - World world = mc.getClientWorld(); - TextureAtlasSprite texture; - List quads = null; - int tintIndex = Integer.MIN_VALUE; - boolean isTinted = false; - int listSize = 0; - // get the first quad we can for this block - for (Direction direction : directions) - { - quads = mc.getModelManager().getBlockModelShaper().getBlockModel(blockState).getQuads(blockState, direction, new Random(0), dataMap); - listSize = Math.max(listSize, quads.size()); - for (BakedQuad bakedQuad : quads) - { - isTinted |= bakedQuad.isTinted(); - tintIndex = Math.max(tintIndex, bakedQuad.getTintIndex()); - } - } - toTint.put(block, isTinted); - tintColor.put(block, tintIndex); - for (Direction direction : directions) - { - quads = mc.getModelManager().getBlockModelShaper().getBlockModel(blockState).getQuads(blockState, direction, new Random(0), dataMap); - if (!quads.isEmpty()) - break; - } - - if (useTopTexture && !quads.isEmpty()) - texture = quads.get(0).getSprite(); - else - texture = mc.getModelManager().getBlockModelShaper().getTexture(blockState, world, blockPos); - - - int count = 0; - int alpha = 0; - int red = 0; - int green = 0; - int blue = 0; - int numberOfGreyPixel = 0; - int color; - int colorMultiplier; - - // generate the block's color - for (int frameIndex = 0; frameIndex < texture.getFrameCount(); frameIndex++) - { - // textures normally use u and v instead of x and y - for (int u = 0; u < texture.getHeight(); u++) - { - for (int v = 0; v < texture.getWidth(); v++) - { - if (texture.isTransparent(frameIndex, u, v)) - continue; - - color = texture.getPixelRGBA(frameIndex, u, v); - - // determine if this pixel is gray - int colorMax = Math.max(Math.max(ColorUtil.getBlue(color), ColorUtil.getGreen(color)), ColorUtil.getRed(color)); - int colorMin = 4 + Math.min(Math.min(ColorUtil.getBlue(color), ColorUtil.getGreen(color)), ColorUtil.getRed(color)); - boolean isGray = colorMax < colorMin; - if (isGray) - numberOfGreyPixel++; - - - // for flowers, weight their non-green color higher - if (block instanceof FlowerBlock && (!(ColorUtil.getGreen(color) > (ColorUtil.getBlue(color) + 30)) || !(ColorUtil.getGreen(color) > (ColorUtil.getRed(color) + 30)))) - colorMultiplier = 5; - else - colorMultiplier = 1; - - - // add to the running averages - count += colorMultiplier; - alpha += ColorUtil.getAlpha(color) * colorMultiplier; - red += ColorUtil.getBlue(color) * colorMultiplier; - green += ColorUtil.getGreen(color) * colorMultiplier; - blue += ColorUtil.getRed(color) * colorMultiplier; - } - } - } - - - if (count == 0) - // this block is entirely transparent - color = 0; - else - { - // determine the average color - alpha /= count; - red /= count; - green /= count; - blue /= count; - color = ColorUtil.rgbToInt(alpha, red, green, blue); - } - - // determine if this block should use the biome color tint - if ((useGrassTint(block) || useLeafTint(block) || useWaterTint(block)) && (float) numberOfGreyPixel / count > 0.75f) - toTint.replace(block, true); - - // add the newly generated block color to the map for later use - colorMap.put(block, color); - return color; - } - - /** determine if the given block should use the biome's grass color */ - private boolean useGrassTint(Block block) - { - return block instanceof GrassBlock - || block instanceof BushBlock - || block instanceof IGrowable - || block instanceof AbstractPlantBlock - || block instanceof AbstractTopPlantBlock - || block instanceof TallGrassBlock; - } - - /** determine if the given block should use the biome's foliage color */ - private boolean useLeafTint(Block block) - { - return block instanceof LeavesBlock - || block == Blocks.VINE - || block == Blocks.SUGAR_CANE; - } - - /** determine if the given block should use the biome's water color */ - private boolean useWaterTint(Block block) - { - return block == Blocks.WATER; - } - /** Returns a color int for the given block. */ - private int getColorForBlock(IChunk chunk, BlockPos blockPos) + private int getColorForBlock(ChunkWrapper chunk, BlockPosWrapper blockPos) { @@ -693,84 +476,39 @@ public class LodBuilder int z = blockPos.getZ(); //Biome biome = chunk.getBiomes().getNoiseBiome(xRel >> 2, y >> 2, zRel >> 2); - BlockState blockState = chunk.getBlockState(blockPos); + BlockWrapper block; + if (chunk.isWaterLogged(blockPos)) + block = BlockWrapper.getBlockWrapper(Blocks.WATER); + else + block = chunk.getBlock(blockPos); - if(isInWater(blockState)) - blockState = Blocks.WATER.defaultBlockState(); - - // block special cases - // TODO: this needs to be replaced by a config file of some sort - if (blockState == Blocks.AIR.defaultBlockState() - || blockState == Blocks.CAVE_AIR.defaultBlockState() - || blockState == Blocks.BARRIER.defaultBlockState()) + if (block.isToAvoid()) { return 0; } - blockColor = getColorTextureForBlock(blockState, blockPos, true); + blockColor = block.getColor(); - //if the blockColor is 0 we reset it and don't use the faceColor - if (blockColor == 0) - { - tintColor.remove(blockState.getBlock()); - toTint.remove(blockState.getBlock()); - colorMap.remove(blockState.getBlock()); - blockColor = getColorTextureForBlock(blockState, blockPos, false); - } - //if the blockColor is still 0 we use the default material color - if (blockColor == 0) + if (block.hasTint()) { - tintColor.replace(blockState.getBlock(), 0); - toTint.replace(blockState.getBlock(), false); - colorMap.replace(blockState.getBlock(), blockState.getBlock().defaultMaterialColor().col); - } - - if (toTint.get(blockState.getBlock())) - { - Biome biome = chunk.getBiomes().getNoiseBiome(xRel >> 2, y >> 2, zRel >> 2); - - ClientWorld clientWorld = mc.getClientWorld(); - if (clientWorld == null) - return 0; - ServerWorld serverWorld = LodUtil.getServerWorldFromDimension(clientWorld.dimensionType()); + BiomeWrapper biome = chunk.getBiome(xRel, y, zRel); int tintValue; - if (useGrassTint(blockState.getBlock())) + if (block.hasGrassTint()) { // grass and green plants - try - { - tintValue = BiomeColors.getAverageGrassColor(serverWorld, blockPos); - } - catch(NullPointerException e) - { - tintValue = biome.getGrassColor(x, z); - } + tintValue = biome.getGrassTint(x, z); } - else if (useWaterTint(blockState.getBlock())) + else if (block.hasFolliageTint()) { - // water - try - { - tintValue = BiomeColors.getAverageWaterColor(serverWorld, blockPos); - } - catch(NullPointerException e) - { - tintValue = biome.getWaterColor(); - } + tintValue = biome.getFolliageTint(); } else { - // leaves - try - { - tintValue = BiomeColors.getAverageFoliageColor(serverWorld, blockPos); - } - catch(NullPointerException e) - { - tintValue = biome.getFoliageColor(); - } + //we can reintroduce this with the wrappers + //tintValue = BiomeColors.getAverageFoliageColor(serverWorld, blockPos); + tintValue = biome.getWaterTint(); } colorInt = ColorUtil.multiplyRGBcolors(tintValue | 0xFF000000, blockColor); } @@ -779,164 +517,23 @@ public class LodBuilder return colorInt; } - /** Returns a color int for the given biome. */ - private int getColorForBiome(int x, int z, Biome biome) - { - int colorInt; - - switch (biome.getBiomeCategory()) - { - - case NETHER: - colorInt = Blocks.NETHERRACK.defaultBlockState().materialColor.col; - break; - - case THEEND: - colorInt = Blocks.END_STONE.defaultBlockState().materialColor.col; - break; - - case BEACH: - case DESERT: - colorInt = Blocks.SAND.defaultBlockState().materialColor.col; - break; - - case EXTREME_HILLS: - colorInt = Blocks.STONE.defaultMaterialColor().col; - break; - - case MUSHROOM: - colorInt = MaterialColor.COLOR_LIGHT_GRAY.col; - break; - - case ICY: - colorInt = Blocks.SNOW.defaultMaterialColor().col; - break; - - case MESA: - colorInt = Blocks.RED_SAND.defaultMaterialColor().col; - break; - - case OCEAN: - case RIVER: - colorInt = biome.getWaterColor(); - break; - - case NONE: - case FOREST: - case TAIGA: - case JUNGLE: - case PLAINS: - case SAVANNA: - case SWAMP: - default: - Color tmp = LodUtil.intToColor(biome.getGrassColor(x, z)); - tmp = tmp.darker(); - colorInt = LodUtil.colorToInt(tmp); - break; - - } - - return colorInt; - } - - private boolean isInWater(BlockState blockState) - { - //This type of block is always in water - if((blockState.getBlock() instanceof ILiquidContainer) && !(blockState.getBlock() instanceof IWaterLoggable)) - return true; - - //This type of block could be in water - if(blockState.getOptionalValue(BlockStateProperties.WATERLOGGED).isPresent() && blockState.getOptionalValue(BlockStateProperties.WATERLOGGED).get()) - return true; - - return false; - } - /** Is the block at the given blockPos a valid LOD point? */ - private boolean isLayerValidLodPoint(IChunk chunk, BlockPos.Mutable blockPos) + private boolean isLayerValidLodPoint(ChunkWrapper chunk, BlockPosWrapper blockPos) { - BlockState blockState = chunk.getBlockState(blockPos); - if (isInWater(blockState)) + if (chunk.isWaterLogged(blockPos)) return true; - - boolean nonFullAvoidance = LodConfig.CLIENT.worldGenerator.blockToAvoid.get().nonFull; - boolean noCollisionAvoidance = LodConfig.CLIENT.worldGenerator.blockToAvoid.get().noCollision; - if (blockState != null) - { - if (nonFullAvoidance) - { - if(!blockState.getFluidState().isEmpty() || blockState.getBlock() instanceof SixWayBlock) - { - notFullBlock.put(blockState.getBlock(), false); - } - if (!notFullBlock.containsKey(blockState.getBlock()) || notFullBlock.get(blockState.getBlock()) == null) - { - VoxelShape voxelShape = blockState.getBlock().defaultBlockState().getShape(chunk, blockPos); - - if (!voxelShape.isEmpty()) - { - AxisAlignedBB bbox = voxelShape.bounds(); - 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) - notFullBlock.put(blockState.getBlock(), true); - else - notFullBlock.put(blockState.getBlock(), false); - } - else - { - notFullBlock.put(blockState.getBlock(), false); - } - } - - if (notFullBlock.get(blockState.getBlock())) - { - return false; - } - } - - if (noCollisionAvoidance) - { - if(!blockState.getFluidState().isEmpty() || blockState.getBlock() instanceof SixWayBlock) - smallBlock.put(blockState.getBlock(), false); - - if (!smallBlock.containsKey(blockState.getBlock()) || smallBlock.get(blockState.getBlock()) == null) - { - VoxelShape voxelShape = blockState.getCollisionShape(chunk, blockPos); - if (!blockState.getFluidState().isEmpty()) - { - smallBlock.put(blockState.getBlock(), false); - } - else - { - - if (voxelShape.isEmpty()) - { - smallBlock.put(blockState.getBlock(), true); - } - else - { - smallBlock.put(blockState.getBlock(), false); - } - } - } - - if (smallBlock.get(blockState.getBlock())) - { - return false; - } - } - - - return blockState.getBlock() != Blocks.AIR - && blockState.getBlock() != Blocks.CAVE_AIR - && blockState.getBlock() != Blocks.BARRIER; - } - return false; + boolean nonFullAvoidance = LodConfig.CLIENT.worldGenerator.blockToAvoid.get().nonFull; + boolean noCollisionAvoidance = LodConfig.CLIENT.worldGenerator.blockToAvoid.get().noCollision; + + BlockWrapper block = chunk.getBlock(blockPos); + return block != null + && !block.isToAvoid() + && !(nonFullAvoidance && block.isNonFull()) + && !(noCollisionAvoidance && block.hasNoCollision()); + } } diff --git a/src/main/java/com/seibel/lod/builders/worldGeneration/LodGenWorker.java b/src/main/java/com/seibel/lod/builders/worldGeneration/LodGenWorker.java index 75b5ef576..7787664e7 100644 --- a/src/main/java/com/seibel/lod/builders/worldGeneration/LodGenWorker.java +++ b/src/main/java/com/seibel/lod/builders/worldGeneration/LodGenWorker.java @@ -37,6 +37,7 @@ import com.seibel.lod.objects.LodDimension; import com.seibel.lod.proxy.ClientProxy; import com.seibel.lod.util.LodUtil; +import com.seibel.lod.wrappers.Chunk.ChunkWrapper; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.util.math.ChunkPos; @@ -384,7 +385,7 @@ public class LodGenWorker implements IWorker if (!inTheEnd) { - lodBuilder.generateLodNodeFromChunk(lodDim, chunk, new LodBuilderConfig(true, true, false)); + lodBuilder.generateLodNodeFromChunk(lodDim, new ChunkWrapper(chunk), new LodBuilderConfig(true, true, false)); } else { @@ -392,7 +393,7 @@ public class LodGenWorker implements IWorker // Since we don't know where the islands are, everything // generates the same, and it looks awful. //TODO it appears that 'if' can be collapsed, but comment says that it should not be a case - lodBuilder.generateLodNodeFromChunk(lodDim, chunk, new LodBuilderConfig(true, true, false)); + lodBuilder.generateLodNodeFromChunk(lodDim, new ChunkWrapper(chunk), new LodBuilderConfig(true, true, false)); } @@ -432,7 +433,7 @@ public class LodGenWorker implements IWorker snowFeature.place(lodServerWorld, chunkGen, serverWorld.random, chunk.getPos().getWorldPosition(), null); - lodBuilder.generateLodNodeFromChunk(lodDim, chunk, new LodBuilderConfig(DistanceGenerationMode.SURFACE)); + lodBuilder.generateLodNodeFromChunk(lodDim, new ChunkWrapper(chunk), new LodBuilderConfig(DistanceGenerationMode.SURFACE)); /*TODO if we want to use Biome utils and terrain utils for overworld * lodBuilder.generateLodNodeFromChunk(lodDim, pos ,detailLevel, serverWorld.getSeed());*/ @@ -558,7 +559,7 @@ public class LodGenWorker implements IWorker } // generate a Lod like normal - lodBuilder.generateLodNodeFromChunk(lodDim, chunk, new LodBuilderConfig(DistanceGenerationMode.FEATURES)); + lodBuilder.generateLodNodeFromChunk(lodDim, new ChunkWrapper(chunk), new LodBuilderConfig(DistanceGenerationMode.FEATURES)); } @@ -573,7 +574,7 @@ public class LodGenWorker implements IWorker */ private void generateWithServer() { - lodBuilder.generateLodNodeFromChunk(lodDim, serverWorld.getChunk(pos.x, pos.z, ChunkStatus.FEATURES), new LodBuilderConfig(DistanceGenerationMode.SERVER)); + lodBuilder.generateLodNodeFromChunk(lodDim, new ChunkWrapper(serverWorld.getChunk(pos.x, pos.z, ChunkStatus.FEATURES)), new LodBuilderConfig(DistanceGenerationMode.SERVER)); } diff --git a/src/main/java/com/seibel/lod/proxy/ClientProxy.java b/src/main/java/com/seibel/lod/proxy/ClientProxy.java index 644531783..139f3ef8c 100644 --- a/src/main/java/com/seibel/lod/proxy/ClientProxy.java +++ b/src/main/java/com/seibel/lod/proxy/ClientProxy.java @@ -19,6 +19,7 @@ package com.seibel.lod.proxy; +import com.seibel.lod.wrappers.Chunk.ChunkWrapper; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.lwjgl.glfw.GLFW; @@ -213,7 +214,7 @@ public class ClientProxy @SubscribeEvent public void chunkLoadEvent(ChunkEvent.Load event) { - lodBuilder.generateLodNodeAsync(event.getChunk(), lodWorld, event.getWorld(), DistanceGenerationMode.SERVER); + lodBuilder.generateLodNodeAsync(new ChunkWrapper(event.getChunk()), lodWorld, event.getWorld(), DistanceGenerationMode.SERVER); } @SubscribeEvent @@ -283,7 +284,7 @@ public class ClientProxy event.getClass() == BlockEvent.PortalSpawnEvent.class) { // recreate the LOD where the blocks were changed - lodBuilder.generateLodNodeAsync(event.getWorld().getChunk(event.getPos()), lodWorld, event.getWorld()); + lodBuilder.generateLodNodeAsync(new ChunkWrapper(event.getWorld().getChunk(event.getPos())), lodWorld, event.getWorld()); } } diff --git a/src/main/java/com/seibel/lod/wrappers/Block/BlockPosWrapper.java b/src/main/java/com/seibel/lod/wrappers/Block/BlockPosWrapper.java index 270b8b25a..6dd9d0f20 100644 --- a/src/main/java/com/seibel/lod/wrappers/Block/BlockPosWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/Block/BlockPosWrapper.java @@ -23,7 +23,7 @@ public class BlockPosWrapper public BlockPosWrapper() { - this.blockPos = new BlockPos.Mutable(); + this.blockPos = new BlockPos.Mutable(0,0,0); } public void set(int x, int y, int z) diff --git a/src/main/java/com/seibel/lod/wrappers/Block/BlockWrapper.java b/src/main/java/com/seibel/lod/wrappers/Block/BlockWrapper.java index 0f5bb38aa..767607096 100644 --- a/src/main/java/com/seibel/lod/wrappers/Block/BlockWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/Block/BlockWrapper.java @@ -1,11 +1,16 @@ 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.*; @@ -23,19 +28,31 @@ public class BlockWrapper private Block block; + private boolean toAvoid; private boolean nonFull; private boolean noCollision; private int color; private boolean isColored; private boolean toTint; - private boolean leavesTint; + private boolean folliageTint; private boolean grassTint; private boolean waterTint; - /**Constructor only require for the block instance we are wrapping**/ public BlockWrapper(Block block) + { + this.nonFull = false; + this.noCollision = false; + this.color = 0; + this.isColored = true; + this.toTint = false; + this.block = block; + setupColorAndTint(); + } + + /**Constructor only require for the block instance we are wrapping**/ + public BlockWrapper(Block block, ChunkWrapper chunkWrapper, BlockPosWrapper blockPosWrapper) { this.nonFull = true; this.noCollision = true; @@ -44,7 +61,7 @@ public class BlockWrapper this.toTint = false; this.block = block; setupColorAndTint(); - setupShapes(); + setupShapes(chunkWrapper, blockPosWrapper); } /** @@ -54,7 +71,7 @@ public class BlockWrapper static public BlockWrapper getBlockWrapper(Block block) { //first we check if the block has already been wrapped - if(blockWrapperMap.containsKey(block) && blockWrapperMap.get(block) != null) + if (blockWrapperMap.containsKey(block) && blockWrapperMap.get(block) != null) return blockWrapperMap.get(block); @@ -66,6 +83,25 @@ public class BlockWrapper return blockWrapper; } + /** + * this return a wrapper of the block in input + * @param block Block object to wrap + */ + static public BlockWrapper getBlockWrapper(Block block, ChunkWrapper chunkWrapper, BlockPosWrapper blockPosWrapper) + { + //first we check if the block has already been wrapped + if (blockWrapperMap.containsKey(block) && blockWrapperMap.get(block) != null) + return blockWrapperMap.get(block); + + + //if it hasn't been created yet, we create it and save it in the map + BlockWrapper blockWrapper = new BlockWrapper(block, chunkWrapper, blockPosWrapper); + blockWrapperMap.put(block, blockWrapper); + + //we return the newly created wrapper + return blockWrapper; + } + /** * Generate the color of the given block from its texture @@ -92,7 +128,7 @@ public class BlockWrapper } //if it contains a tinted face then we store this block in the toTint set - if(isTinted) + if (isTinted) this.toTint = true; //now we get the first non empty face @@ -181,7 +217,7 @@ public class BlockWrapper this.grassTint = true; if (leavesInstance() && this.toTint) - this.leavesTint = true; + this.folliageTint = true; if (waterIstance() && this.toTint) this.waterTint = true; @@ -214,13 +250,58 @@ public class BlockWrapper return block == Blocks.WATER; } - private void setupShapes(){ - + private void setupShapes(ChunkWrapper chunkWrapper, BlockPosWrapper blockPosWrapper) + { + IBlockReader chunk = chunkWrapper.getChunk(); + BlockPos blockPos = blockPosWrapper.getBlockPos(); + boolean noCollisionSetted = false; + boolean nonFullSetted = false; + if (!block.defaultBlockState().getFluidState().isEmpty() || block instanceof SixWayBlock) + { + noCollisionSetted = true; + nonFullSetted = true; + noCollision = false; + nonFull = false; + } + if (!nonFullSetted) + { + VoxelShape voxelShape = block.defaultBlockState().getShape(chunk, blockPos); + + if (!voxelShape.isEmpty()) + { + AxisAlignedBB bbox = voxelShape.bounds(); + 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; + } + else + { + nonFull = false; + } + } + + if (!noCollisionSetted) + { + VoxelShape collisionShape = block.defaultBlockState().getCollisionShape(chunk, blockPos); + noCollision = collisionShape.isEmpty(); + } + + toAvoid = ofBlockToAvoid(block); } - //--------------// - //Colors getters// - //--------------// + private boolean ofBlockToAvoid(Block block) + { + return block == Blocks.AIR + || block != Blocks.CAVE_AIR + || block != Blocks.BARRIER; + } +//--------------// +//Colors getters// +//--------------// public boolean hasColor() { @@ -229,12 +310,15 @@ public class BlockWrapper public int getColor() { - return color; + if(hasColor()) + return color; + else + return block.defaultMaterialColor().col; } - - //------------// - //Tint getters// - //------------// + +//------------// +//Tint getters// +//------------// public boolean hasTint() @@ -247,9 +331,9 @@ public class BlockWrapper return grassTint; } - public boolean hasLeavesTint() + public boolean hasFolliageTint() { - return leavesTint; + return folliageTint; } public boolean hasWaterTint() @@ -258,6 +342,29 @@ public class BlockWrapper } +//-----------------// +//Avoidance getters// +//-----------------// + + + public boolean isNonFull() + { + return nonFull; + } + + public boolean hasNoCollision() + { + return noCollision; + } + + public boolean isToAvoid() + { + return folliageTint; + } + + + + @Override public boolean equals(Object o) { if (this == o) diff --git a/src/main/java/com/seibel/lod/wrappers/Chunk/ChunkPosWrapper.java b/src/main/java/com/seibel/lod/wrappers/Chunk/ChunkPosWrapper.java index 5fc84f5eb..88ae081ac 100644 --- a/src/main/java/com/seibel/lod/wrappers/Chunk/ChunkPosWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/Chunk/ChunkPosWrapper.java @@ -26,6 +26,26 @@ public class ChunkPosWrapper return chunkPos.z; } + public int getMinBlockX() + { + return chunkPos.getMinBlockX(); + } + + public int getMinBlockZ() + { + return chunkPos.getMinBlockZ(); + } + + public int getRegionX() + { + return chunkPos.getRegionX(); + } + + public int getRegionZ() + { + return chunkPos.getRegionZ(); + } + public ChunkPos getChunkPos() { return chunkPos; 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 084db34e1..b8eac2382 100644 --- a/src/main/java/com/seibel/lod/wrappers/Chunk/ChunkWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/Chunk/ChunkWrapper.java @@ -1,29 +1,93 @@ package com.seibel.lod.wrappers.Chunk; +import com.seibel.lod.util.LodUtil; import com.seibel.lod.wrappers.Block.BlockWrapper; import com.seibel.lod.wrappers.Block.BlockPosWrapper; +import com.seibel.lod.wrappers.World.BiomeWrapper; +import com.sun.javafx.scene.control.behavior.OptionalBoolean; +import net.minecraft.block.BlockState; +import net.minecraft.block.ILiquidContainer; +import net.minecraft.block.IWaterLoggable; +import net.minecraft.loot.conditions.BlockStateProperty; +import net.minecraft.state.Property; +import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.world.chunk.IChunk; +import java.util.Optional; + public class ChunkWrapper { private IChunk chunk; private ChunkPosWrapper chunkPos; + public int getHeight(){ + return chunk.getMaxBuildHeight(); + } + + public boolean isPositionInWater(BlockPosWrapper blockPos) + { + BlockState blockState = chunk.getBlockState(blockPos.getBlockPos()); + + //This type of block is always in water + if((blockState.getBlock() instanceof ILiquidContainer) && !(blockState.getBlock() instanceof IWaterLoggable)) + return true; + + //This type of block could be in water + if(blockState.getOptionalValue(BlockStateProperties.WATERLOGGED).isPresent() && blockState.getOptionalValue(BlockStateProperties.WATERLOGGED).get()) + return true; + + return false; + } + + public int getHeightMapValue(int xRel, int zRel){ + return chunk.getOrCreateHeightmapUnprimed(LodUtil.DEFAULT_HEIGHTMAP).getFirstAvailable(xRel, zRel); + } + + public BiomeWrapper getBiome(int xRel, int yAbs, int zRel) + { + return BiomeWrapper.getBiomeWrapper(chunk.getBiomes().getNoiseBiome(xRel >> 2, yAbs >> 2, zRel >> 2)); + } + + public BlockWrapper getBlock(BlockPosWrapper blockPos) + { + return BlockWrapper.getBlockWrapper(chunk.getBlockState(blockPos.getBlockPos()).getBlock(), this, blockPos); + } + + public ChunkWrapper(IChunk chunk) { this.chunk = chunk; this.chunkPos = new ChunkPosWrapper(chunk.getPos()); } - public BlockWrapper getBlock(BlockPosWrapper blockPos) - { - return BlockWrapper.getBlockWrapper(chunk.getBlockState(blockPos.getBlockPos()).getBlock()); + public IChunk getChunk(){ + return chunk; } - - public ChunkPosWrapper getChunkPos(){ + public ChunkPosWrapper getPos(){ return chunkPos; } + + public boolean isLightCorrect(){ + return chunk.isLightCorrect(); + } + + public boolean + isWaterLogged(BlockPosWrapper blockPos) + { + BlockState blockState = chunk.getBlockState(blockPos.getBlockPos()); + + //This type of block is always in water + if((blockState.getBlock() instanceof ILiquidContainer) && !(blockState.getBlock() instanceof IWaterLoggable)) + return true; + + //This type of block could be in water + if(blockState.getOptionalValue(BlockStateProperties.WATERLOGGED).isPresent() && blockState.getOptionalValue(BlockStateProperties.WATERLOGGED).get()) + return true; + + return false; + } + public int getEmittedBrightness(BlockPosWrapper blockPos) { return chunk.getLightEmission(blockPos.getBlockPos()); diff --git a/src/main/java/com/seibel/lod/wrappers/MinecraftWrapper.java b/src/main/java/com/seibel/lod/wrappers/MinecraftWrapper.java index 67f2297fe..8c7c2fcd6 100644 --- a/src/main/java/com/seibel/lod/wrappers/MinecraftWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/MinecraftWrapper.java @@ -26,6 +26,7 @@ import com.seibel.lod.ModInfo; import com.seibel.lod.proxy.ClientProxy; import com.seibel.lod.util.LodUtil; +import com.seibel.lod.wrappers.World.WorldWrapper; import net.minecraft.client.GameSettings; import net.minecraft.client.MainWindow; import net.minecraft.client.Minecraft; @@ -44,6 +45,7 @@ import net.minecraft.profiler.IProfiler; import net.minecraft.server.integrated.IntegratedServer; import net.minecraft.util.Direction; import net.minecraft.world.DimensionType; +import net.minecraft.world.server.ServerWorld; /** * A singleton that wraps the Minecraft class @@ -183,6 +185,36 @@ public class MinecraftWrapper return mc.level; } + public WorldWrapper getWrappedClientWorld() + { + return WorldWrapper.getWorldWrapper(mc.level); + } + + public WorldWrapper getWrappedServerWorld() + { + + if (mc.level == null) + return null; + DimensionType dimension = mc.level.dimensionType(); + IntegratedServer server = mc.getSingleplayerServer(); + if (server == null) + return null; + + Iterable worlds = server.getAllLevels(); + ServerWorld returnWorld = null; + + for (ServerWorld world : worlds) + { + if (world.dimensionType() == dimension) + { + returnWorld = world; + break; + } + } + + return WorldWrapper.getWorldWrapper(returnWorld); + } + /** Measured in chunks */ public int getRenderDistance() { 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 f14485f8c..42c1a4c59 100644 --- a/src/main/java/com/seibel/lod/wrappers/World/BiomeWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/World/BiomeWrapper.java @@ -115,6 +115,22 @@ public class BiomeWrapper return colorInt; } + public int getGrassTint(int x, int z) + { + return biome.getGrassColor(x, z); + } + + public int getFolliageTint() + { + return biome.getFoliageColor(); + } + + public int getWaterTint() + { + return biome.getWaterColor(); + } + + @Override public boolean equals(Object o) { if (this == o) 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 4589c225a..79dddee46 100644 --- a/src/main/java/com/seibel/lod/wrappers/World/WorldWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/World/WorldWrapper.java @@ -16,7 +16,8 @@ public class WorldWrapper this.world = world; } - public WorldWrapper getWorldWrapper(IWorld world) + + public static WorldWrapper getWorldWrapper(IWorld world) { //first we check if the biome has already been wrapped if(worldWrapperMap.containsKey(world) && worldWrapperMap.get(world) != null) @@ -65,4 +66,9 @@ public class WorldWrapper { return world.dimensionType().hasSkyLight(); } + + public boolean isEmpty() + { + return world == null; + } } From bde14012d9a61e68823b1fe5015f7f71600cc234 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 26 Oct 2021 12:31:06 +0200 Subject: [PATCH 02/10] Divided the Block Wrapper in two different class --- .../lod/builders/lodBuilding/LodBuilder.java | 43 ++--- ...ockWrapper.java => BlockColorWrapper.java} | 143 +++------------- .../lod/wrappers/Block/BlockShapeWrapper.java | 157 ++++++++++++++++++ .../lod/wrappers/Chunk/ChunkWrapper.java | 16 +- .../lod/wrappers/World/BiomeWrapper.java | 24 +-- 5 files changed, 220 insertions(+), 163 deletions(-) rename src/main/java/com/seibel/lod/wrappers/Block/{BlockWrapper.java => BlockColorWrapper.java} (66%) create mode 100644 src/main/java/com/seibel/lod/wrappers/Block/BlockShapeWrapper.java 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 ff1d8444a..9675cb306 100644 --- a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java @@ -19,8 +19,6 @@ package com.seibel.lod.builders.lodBuilding; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -38,7 +36,8 @@ import com.seibel.lod.util.LodThreadFactory; import com.seibel.lod.util.LodUtil; import com.seibel.lod.util.ThreadMapUtil; import com.seibel.lod.wrappers.Block.BlockPosWrapper; -import com.seibel.lod.wrappers.Block.BlockWrapper; +import com.seibel.lod.wrappers.Block.BlockColorWrapper; +import com.seibel.lod.wrappers.Block.BlockShapeWrapper; import com.seibel.lod.wrappers.Chunk.ChunkPosWrapper; import com.seibel.lod.wrappers.Chunk.ChunkWrapper; import com.seibel.lod.wrappers.MinecraftWrapper; @@ -192,8 +191,6 @@ public class LodBuilder { startX = detail.startX[i]; startZ = detail.startZ[i]; - endX = detail.endX[i]; - endZ = detail.endZ[i]; long[] data; long[] dataToMergeVertical = createVerticalDataToMerge(detail, chunk, config, startX, startZ); @@ -466,7 +463,7 @@ public class LodBuilder { - int blockColor; + int colorOfBlock; int colorInt; int xRel = blockPos.getX() - chunk.getPos().getMinBlockX(); @@ -476,31 +473,39 @@ public class LodBuilder int z = blockPos.getZ(); //Biome biome = chunk.getBiomes().getNoiseBiome(xRel >> 2, y >> 2, zRel >> 2); - BlockWrapper block; - if (chunk.isWaterLogged(blockPos)) - block = BlockWrapper.getBlockWrapper(Blocks.WATER); - else - block = chunk.getBlock(blockPos); + BlockColorWrapper blockColorWrapper; + BlockShapeWrapper blockShapeWrapper; - if (block.isToAvoid()) + if (chunk.isWaterLogged(blockPos)) + { + blockColorWrapper = BlockColorWrapper.WATER_COLOR; + blockShapeWrapper = BlockShapeWrapper.WATER_SHAPE; + } + else + { + blockColorWrapper = chunk.getBlockColorWrapper(blockPos); + blockShapeWrapper = chunk.getBlockShapeWrapper(blockPos); + } + + if (blockShapeWrapper.isToAvoid()) { return 0; } - blockColor = block.getColor(); + colorOfBlock = blockColorWrapper.getColor(); - if (block.hasTint()) + if (blockColorWrapper.hasTint()) { BiomeWrapper biome = chunk.getBiome(xRel, y, zRel); int tintValue; - if (block.hasGrassTint()) + if (blockColorWrapper.hasGrassTint()) { // grass and green plants tintValue = biome.getGrassTint(x, z); } - else if (block.hasFolliageTint()) + else if (blockColorWrapper.hasFolliageTint()) { tintValue = biome.getFolliageTint(); } @@ -510,10 +515,10 @@ public class LodBuilder //tintValue = BiomeColors.getAverageFoliageColor(serverWorld, blockPos); tintValue = biome.getWaterTint(); } - colorInt = ColorUtil.multiplyRGBcolors(tintValue | 0xFF000000, blockColor); + colorInt = ColorUtil.multiplyRGBcolors(tintValue | 0xFF000000, colorOfBlock); } else - colorInt = blockColor; + colorInt = colorOfBlock; return colorInt; } @@ -529,7 +534,7 @@ public class LodBuilder boolean nonFullAvoidance = LodConfig.CLIENT.worldGenerator.blockToAvoid.get().nonFull; boolean noCollisionAvoidance = LodConfig.CLIENT.worldGenerator.blockToAvoid.get().noCollision; - BlockWrapper block = chunk.getBlock(blockPos); + BlockShapeWrapper block = chunk.getBlockShapeWrapper(blockPos); return block != null && !block.isToAvoid() && !(nonFullAvoidance && block.isNonFull()) diff --git a/src/main/java/com/seibel/lod/wrappers/Block/BlockWrapper.java b/src/main/java/com/seibel/lod/wrappers/Block/BlockColorWrapper.java similarity index 66% rename from src/main/java/com/seibel/lod/wrappers/Block/BlockWrapper.java rename to src/main/java/com/seibel/lod/wrappers/Block/BlockColorWrapper.java index 767607096..1e03e912c 100644 --- a/src/main/java/com/seibel/lod/wrappers/Block/BlockWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/Block/BlockColorWrapper.java @@ -13,24 +13,23 @@ import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; import net.minecraftforge.client.model.data.ModelDataMap; -import java.util.*; +import java.util.List; +import java.util.Objects; +import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; //This class wraps the minecraft Block class -public class BlockWrapper +public class BlockColorWrapper { //set of block which require tint - public static final ConcurrentMap blockWrapperMap = new ConcurrentHashMap<>(); + public static final ConcurrentMap blockColorWrapperMap = new ConcurrentHashMap<>(); public static final ModelDataMap dataMap = new ModelDataMap.Builder().build(); public static Random random = new Random(0); - + public static BlockColorWrapper WATER_COLOR = getBlockColorWrapper(Blocks.WATER); private Block block; - private boolean toAvoid; - private boolean nonFull; - private boolean noCollision; private int color; private boolean isColored; private boolean toTint; @@ -40,10 +39,8 @@ public class BlockWrapper /**Constructor only require for the block instance we are wrapping**/ - public BlockWrapper(Block block) + public BlockColorWrapper(Block block) { - this.nonFull = false; - this.noCollision = false; this.color = 0; this.isColored = true; this.toTint = false; @@ -51,58 +48,25 @@ public class BlockWrapper setupColorAndTint(); } - /**Constructor only require for the block instance we are wrapping**/ - public BlockWrapper(Block block, ChunkWrapper chunkWrapper, BlockPosWrapper blockPosWrapper) - { - this.nonFull = true; - this.noCollision = true; - this.color = 0; - this.isColored = true; - this.toTint = false; - this.block = block; - setupColorAndTint(); - setupShapes(chunkWrapper, blockPosWrapper); - } - /** * this return a wrapper of the block in input * @param block Block object to wrap */ - static public BlockWrapper getBlockWrapper(Block block) + static public BlockColorWrapper getBlockColorWrapper(Block block) { //first we check if the block has already been wrapped - if (blockWrapperMap.containsKey(block) && blockWrapperMap.get(block) != null) - return blockWrapperMap.get(block); + if (blockColorWrapperMap.containsKey(block) && blockColorWrapperMap.get(block) != null) + return blockColorWrapperMap.get(block); //if it hasn't been created yet, we create it and save it in the map - BlockWrapper blockWrapper = new BlockWrapper(block); - blockWrapperMap.put(block, blockWrapper); + BlockColorWrapper blockWrapper = new BlockColorWrapper(block); + blockColorWrapperMap.put(block, blockWrapper); //we return the newly created wrapper return blockWrapper; } - /** - * this return a wrapper of the block in input - * @param block Block object to wrap - */ - static public BlockWrapper getBlockWrapper(Block block, ChunkWrapper chunkWrapper, BlockPosWrapper blockPosWrapper) - { - //first we check if the block has already been wrapped - if (blockWrapperMap.containsKey(block) && blockWrapperMap.get(block) != null) - return blockWrapperMap.get(block); - - - //if it hasn't been created yet, we create it and save it in the map - BlockWrapper blockWrapper = new BlockWrapper(block, chunkWrapper, blockPosWrapper); - blockWrapperMap.put(block, blockWrapper); - - //we return the newly created wrapper - return blockWrapper; - } - - /** * Generate the color of the given block from its texture * and store it for later use. @@ -213,13 +177,13 @@ public class BlockWrapper this.toTint = true; // we check which kind of tint we need to apply - if (grassInstance() && this.toTint) + if (grassInstance()) this.grassTint = true; - if (leavesInstance() && this.toTint) + if (leavesInstance()) this.folliageTint = true; - if (waterIstance() && this.toTint) + if (waterIstance()) this.waterTint = true; color = tempColor; @@ -249,56 +213,7 @@ public class BlockWrapper { return block == Blocks.WATER; } - - private void setupShapes(ChunkWrapper chunkWrapper, BlockPosWrapper blockPosWrapper) - { - IBlockReader chunk = chunkWrapper.getChunk(); - BlockPos blockPos = blockPosWrapper.getBlockPos(); - boolean noCollisionSetted = false; - boolean nonFullSetted = false; - if (!block.defaultBlockState().getFluidState().isEmpty() || block instanceof SixWayBlock) - { - noCollisionSetted = true; - nonFullSetted = true; - noCollision = false; - nonFull = false; - } - if (!nonFullSetted) - { - VoxelShape voxelShape = block.defaultBlockState().getShape(chunk, blockPos); - - if (!voxelShape.isEmpty()) - { - AxisAlignedBB bbox = voxelShape.bounds(); - 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; - } - else - { - nonFull = false; - } - } - - if (!noCollisionSetted) - { - VoxelShape collisionShape = block.defaultBlockState().getCollisionShape(chunk, blockPos); - noCollision = collisionShape.isEmpty(); - } - - toAvoid = ofBlockToAvoid(block); - } - - private boolean ofBlockToAvoid(Block block) - { - return block == Blocks.AIR - || block != Blocks.CAVE_AIR - || block != Blocks.BARRIER; - } + //--------------// //Colors getters// //--------------// @@ -342,36 +257,15 @@ public class BlockWrapper } -//-----------------// -//Avoidance getters// -//-----------------// - - - public boolean isNonFull() - { - return nonFull; - } - - public boolean hasNoCollision() - { - return noCollision; - } - - public boolean isToAvoid() - { - return folliageTint; - } - - @Override public boolean equals(Object o) { if (this == o) return true; - if (!(o instanceof BlockWrapper)) + if (!(o instanceof BlockColorWrapper)) return false; - BlockWrapper that = (BlockWrapper) o; + BlockColorWrapper that = (BlockColorWrapper) o; return Objects.equals(block, that.block); } @@ -381,3 +275,4 @@ public class BlockWrapper } } + diff --git a/src/main/java/com/seibel/lod/wrappers/Block/BlockShapeWrapper.java b/src/main/java/com/seibel/lod/wrappers/Block/BlockShapeWrapper.java new file mode 100644 index 000000000..e5dd35448 --- /dev/null +++ b/src/main/java/com/seibel/lod/wrappers/Block/BlockShapeWrapper.java @@ -0,0 +1,157 @@ + +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.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + + +//This class wraps the minecraft Block class +public class BlockShapeWrapper +{ + //set of block which require tint + public static final ConcurrentMap blockShapeWrapperMap = new ConcurrentHashMap<>(); + public static BlockShapeWrapper WATER_SHAPE = new BlockShapeWrapper(); + + private Block block; + private boolean toAvoid; + private boolean nonFull; + private boolean noCollision; + + /**Constructor only require for the block instance we are wrapping**/ + public BlockShapeWrapper(Block block, ChunkWrapper chunkWrapper, BlockPosWrapper blockPosWrapper) + { + this.block = block; + this.nonFull = false; + this.noCollision = false; + this.toAvoid = false; + setupShapes(chunkWrapper, blockPosWrapper); + } + + private BlockShapeWrapper() + { + this.block = Blocks.WATER; + this.nonFull = false; + this.noCollision = false; + this.toAvoid = false; + } + + /** + * this return a wrapper of the block in input + * @param block Block object to wrap + */ + static public BlockShapeWrapper getBlockShapeWrapper(Block block, ChunkWrapper chunkWrapper, BlockPosWrapper blockPosWrapper) + { + //first we check if the block has already been wrapped + if (blockShapeWrapperMap.containsKey(block) && blockShapeWrapperMap.get(block) != null) + return blockShapeWrapperMap.get(block); + + + //if it hasn't been created yet, we create it and save it in the map + BlockShapeWrapper blockWrapper = new BlockShapeWrapper(block, chunkWrapper, blockPosWrapper); + blockShapeWrapperMap.put(block, blockWrapper); + + //we return the newly created wrapper + return blockWrapper; + } + + private void setupShapes(ChunkWrapper chunkWrapper, BlockPosWrapper blockPosWrapper) + { + IBlockReader chunk = chunkWrapper.getChunk(); + BlockPos blockPos = blockPosWrapper.getBlockPos(); + boolean noCollisionSetted = false; + boolean nonFullSetted = false; + if (!block.defaultBlockState().getFluidState().isEmpty() || block instanceof SixWayBlock) + { + noCollisionSetted = true; + nonFullSetted = true; + noCollision = false; + nonFull = false; + } + if (!nonFullSetted) + { + VoxelShape voxelShape = block.defaultBlockState().getShape(chunk, blockPos); + + if (!voxelShape.isEmpty()) + { + AxisAlignedBB bbox = voxelShape.bounds(); + 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; + } + else + { + nonFull = false; + } + } + + if (!noCollisionSetted) + { + VoxelShape collisionShape = block.defaultBlockState().getCollisionShape(chunk, blockPos); + noCollision = collisionShape.isEmpty(); + } + + toAvoid = ofBlockToAvoid(block); + } + + private boolean ofBlockToAvoid(Block block) + { + return block == Blocks.AIR + || block != Blocks.CAVE_AIR + || block != Blocks.BARRIER; + } +//-----------------// +//Avoidance getters// +//-----------------// + + + public boolean isNonFull() + { + return nonFull; + } + + public boolean hasNoCollision() + { + return noCollision; + } + + public boolean isToAvoid() + { + return toAvoid; + } + + + + + @Override public boolean equals(Object o) + { + if (this == o) + return true; + if (!(o instanceof BlockShapeWrapper)) + return false; + BlockShapeWrapper that = (BlockShapeWrapper) o; + return Objects.equals(block, that.block); + } + + @Override public int hashCode() + { + return Objects.hash(block); + } +} \ No newline at end of file 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 b8eac2382..ca4d89054 100644 --- a/src/main/java/com/seibel/lod/wrappers/Chunk/ChunkWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/Chunk/ChunkWrapper.java @@ -1,20 +1,16 @@ package com.seibel.lod.wrappers.Chunk; import com.seibel.lod.util.LodUtil; -import com.seibel.lod.wrappers.Block.BlockWrapper; +import com.seibel.lod.wrappers.Block.BlockColorWrapper; import com.seibel.lod.wrappers.Block.BlockPosWrapper; +import com.seibel.lod.wrappers.Block.BlockShapeWrapper; import com.seibel.lod.wrappers.World.BiomeWrapper; -import com.sun.javafx.scene.control.behavior.OptionalBoolean; import net.minecraft.block.BlockState; import net.minecraft.block.ILiquidContainer; import net.minecraft.block.IWaterLoggable; -import net.minecraft.loot.conditions.BlockStateProperty; -import net.minecraft.state.Property; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.world.chunk.IChunk; -import java.util.Optional; - public class ChunkWrapper { @@ -49,11 +45,15 @@ public class ChunkWrapper return BiomeWrapper.getBiomeWrapper(chunk.getBiomes().getNoiseBiome(xRel >> 2, yAbs >> 2, zRel >> 2)); } - public BlockWrapper getBlock(BlockPosWrapper blockPos) + public BlockColorWrapper getBlockColorWrapper(BlockPosWrapper blockPos) { - return BlockWrapper.getBlockWrapper(chunk.getBlockState(blockPos.getBlockPos()).getBlock(), this, blockPos); + return BlockColorWrapper.getBlockColorWrapper(chunk.getBlockState(blockPos.getBlockPos()).getBlock()); } + public BlockShapeWrapper getBlockShapeWrapper(BlockPosWrapper blockPos) + { + return BlockShapeWrapper.getBlockShapeWrapper(chunk.getBlockState(blockPos.getBlockPos()).getBlock(), this, blockPos); + } public ChunkWrapper(IChunk chunk) { 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 42c1a4c59..362b609eb 100644 --- a/src/main/java/com/seibel/lod/wrappers/World/BiomeWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/World/BiomeWrapper.java @@ -1,7 +1,7 @@ package com.seibel.lod.wrappers.World; import com.seibel.lod.util.ColorUtil; -import com.seibel.lod.wrappers.Block.BlockWrapper; +import com.seibel.lod.wrappers.Block.BlockColorWrapper; import net.minecraft.block.Blocks; import net.minecraft.world.biome.Biome; @@ -49,32 +49,32 @@ public class BiomeWrapper { case NETHER: - colorInt = BlockWrapper.getBlockWrapper(Blocks.NETHERRACK).getColor(); + colorInt = BlockColorWrapper.getBlockColorWrapper(Blocks.NETHERRACK).getColor(); break; case THEEND: - colorInt = BlockWrapper.getBlockWrapper(Blocks.END_STONE).getColor(); + colorInt = BlockColorWrapper.getBlockColorWrapper(Blocks.END_STONE).getColor(); break; case BEACH: case DESERT: - colorInt = BlockWrapper.getBlockWrapper(Blocks.SAND).getColor(); + colorInt = BlockColorWrapper.getBlockColorWrapper(Blocks.SAND).getColor(); break; case EXTREME_HILLS: - colorInt = BlockWrapper.getBlockWrapper(Blocks.STONE).getColor(); + colorInt = BlockColorWrapper.getBlockColorWrapper(Blocks.STONE).getColor(); break; case MUSHROOM: - colorInt = BlockWrapper.getBlockWrapper(Blocks.MYCELIUM).getColor(); + colorInt = BlockColorWrapper.getBlockColorWrapper(Blocks.MYCELIUM).getColor(); break; case ICY: - colorInt = BlockWrapper.getBlockWrapper(Blocks.SNOW).getColor(); + colorInt = BlockColorWrapper.getBlockColorWrapper(Blocks.SNOW).getColor(); break; case MESA: - colorInt = BlockWrapper.getBlockWrapper(Blocks.RED_SAND).getColor(); + colorInt = BlockColorWrapper.getBlockColorWrapper(Blocks.RED_SAND).getColor(); break; case OCEAN: @@ -84,19 +84,19 @@ public class BiomeWrapper case SWAMP: case FOREST: - color = BlockWrapper.getBlockWrapper(Blocks.OAK_LEAVES).getColor(); + color = BlockColorWrapper.getBlockColorWrapper(Blocks.OAK_LEAVES).getColor(); tint = biome.getFoliageColor(); colorInt = ColorUtil.multiplyRGBcolors(color, tint); break; case TAIGA: - color = BlockWrapper.getBlockWrapper(Blocks.SPRUCE_LEAVES).getColor(); + color = BlockColorWrapper.getBlockColorWrapper(Blocks.SPRUCE_LEAVES).getColor(); tint = biome.getFoliageColor(); colorInt = ColorUtil.multiplyRGBcolors(color, tint); break; case JUNGLE: - color = BlockWrapper.getBlockWrapper(Blocks.JUNGLE_LEAVES).getColor(); + color = BlockColorWrapper.getBlockColorWrapper(Blocks.JUNGLE_LEAVES).getColor(); tint = biome.getFoliageColor(); colorInt = ColorUtil.multiplyRGBcolors(color, tint); break; @@ -105,7 +105,7 @@ public class BiomeWrapper case NONE: case PLAINS: case SAVANNA: - color = BlockWrapper.getBlockWrapper(Blocks.GRASS_BLOCK).getColor(); + color = BlockColorWrapper.getBlockColorWrapper(Blocks.GRASS_BLOCK).getColor(); tint = biome.getGrassColor(x,z); colorInt = ColorUtil.multiplyRGBcolors(color, tint); break; From 27f9a527bc7987dcabe4d84982d77a2b8bc0ea0a Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 26 Oct 2021 21:19:09 +0200 Subject: [PATCH 03/10] Fixed part of the colors problems --- .../lod/builders/lodBuilding/LodBuilder.java | 38 +++++------ .../com/seibel/lod/util/ThreadMapUtil.java | 4 +- .../lod/wrappers/Block/BlockColorWrapper.java | 63 ++++++++++--------- .../lod/wrappers/Block/BlockShapeWrapper.java | 18 +++--- .../lod/wrappers/Chunk/ChunkWrapper.java | 2 +- .../lod/wrappers/World/BiomeColorWrapper.java | 33 ++++++++++ .../lod/wrappers/World/BiomeWrapper.java | 55 +++++++--------- .../lod/wrappers/World/WorldWrapper.java | 5 ++ 8 files changed, 123 insertions(+), 95 deletions(-) create mode 100644 src/main/java/com/seibel/lod/wrappers/World/BiomeColorWrapper.java 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(); From bf712e893e78c3713f84292cc0ec9770404dbcf4 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 26 Oct 2021 21:28:18 +0200 Subject: [PATCH 04/10] removed default color use from the BlockColorWrapper --- .../com/seibel/lod/wrappers/Block/BlockColorWrapper.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) 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 987204f72..c73e8d022 100644 --- a/src/main/java/com/seibel/lod/wrappers/Block/BlockColorWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/Block/BlockColorWrapper.java @@ -113,9 +113,8 @@ public class BlockColorWrapper } else { - isColored = false; + isColored = true; texture = mc.getModelManager().getBlockModelShaper().getTexture(block.defaultBlockState(), mc.getClientWorld(), blockPosWrapper.getBlockPos()); - //return; } int count = 0; @@ -230,10 +229,7 @@ public class BlockColorWrapper public int getColor() { - if (hasColor()) return color; - else - return block.defaultMaterialColor().col; } //------------// From 447325e5a147ccfbc86570008db17e88f7b48654 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 26 Oct 2021 21:43:11 +0200 Subject: [PATCH 05/10] Fixed the colors for now --- .../com/seibel/lod/builders/lodBuilding/LodBuilder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 4cd18aa6f..a3ff88585 100644 --- a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java @@ -471,23 +471,23 @@ public class LodBuilder int z = blockPos.getZ(); BlockColorWrapper blockColorWrapper; + BlockShapeWrapper blockShapeWrapper = chunk.getBlockShapeWrapper(blockPos); if (chunk.isWaterLogged(blockPos)) { BiomeWrapper biome = chunk.getBiome(xRel, y, zRel); return biome.getWaterTint(); - //blockColorWrapper = BlockColorWrapper.WATER_COLOR; } else { blockColorWrapper = chunk.getBlockColorWrapper(blockPos); } - /* + if (blockShapeWrapper.isToAvoid()) { return 0; } - */ + colorOfBlock = blockColorWrapper.getColor(); @@ -520,7 +520,7 @@ public class LodBuilder } else colorInt = colorOfBlock; - return colorInt; + return colorOfBlock; } From 923d57b377bec4aaeae7046f2205d7f66eb9fec2 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 26 Oct 2021 21:46:06 +0200 Subject: [PATCH 06/10] Fixed the colors in the lodBuilder --- .../java/com/seibel/lod/builders/lodBuilding/LodBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a3ff88585..3a097cea5 100644 --- a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java @@ -520,7 +520,7 @@ public class LodBuilder } else colorInt = colorOfBlock; - return colorOfBlock; + return colorInt; } From f2face9782a5cbc80af77477f42efde8360c03a1 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 26 Oct 2021 21:59:35 +0200 Subject: [PATCH 07/10] small change to light value getters in lod builde. Added WorldLightWrapper for future implementation --- .../com/seibel/lod/builders/lodBuilding/LodBuilder.java | 2 +- src/main/java/com/seibel/lod/wrappers/LigthMapWrapper.java | 2 +- .../com/seibel/lod/wrappers/World/WorldLightWrapper.java | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/seibel/lod/wrappers/World/WorldLightWrapper.java 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 3a097cea5..0e52d5c2e 100644 --- a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java @@ -398,7 +398,7 @@ public class LodBuilder - if (world.isEmpty()) + if (!world.isEmpty()) { // server world sky light (always accurate) blockLight = world.getBlockLight(blockPos); diff --git a/src/main/java/com/seibel/lod/wrappers/LigthMapWrapper.java b/src/main/java/com/seibel/lod/wrappers/LigthMapWrapper.java index bb5eabf19..4647e3752 100644 --- a/src/main/java/com/seibel/lod/wrappers/LigthMapWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/LigthMapWrapper.java @@ -9,7 +9,7 @@ public class LigthMapWrapper public static void setLightMap(NativeImage lightMap) { - lightMap = null; + lightMap = lightMap; } public static int getLightValue(int skyLight, int blockLight) diff --git a/src/main/java/com/seibel/lod/wrappers/World/WorldLightWrapper.java b/src/main/java/com/seibel/lod/wrappers/World/WorldLightWrapper.java new file mode 100644 index 000000000..e3a4483f6 --- /dev/null +++ b/src/main/java/com/seibel/lod/wrappers/World/WorldLightWrapper.java @@ -0,0 +1,7 @@ +package com.seibel.lod.wrappers.World; + + +//We will use this class to get all the light information from the game like skylight, blocklight and light emission; +public class WorldLightWrapper +{ +} From 00ac368bba103cfce1ce54e7d965bc8bff4a3128 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 26 Oct 2021 22:38:14 +0200 Subject: [PATCH 08/10] fixed light being wrong --- .../seibel/lod/builders/lodBuilding/LodBuilder.java | 10 ++++++++-- .../com/seibel/lod/wrappers/World/WorldWrapper.java | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) 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 0e52d5c2e..e395a8655 100644 --- a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java @@ -267,14 +267,20 @@ public class LodBuilder { yAbs = depth; blockPos.set(xAbs, yAbs, zAbs); - light = getLightValue(chunk, blockPos, hasCeiling, hasSkyLight, topBlock); + if(hasSkyLight) + light = getLightValue(chunk, blockPos, hasCeiling, hasSkyLight, topBlock); + else + light = 0; color = generateLodColor(chunk, config, xAbs, yAbs, zAbs, blockPos); blockPos.set(xAbs, yAbs - 1, zAbs); } else { blockPos.set(xAbs, yAbs, zAbs); - light = getLightValue(chunk, blockPos, hasCeiling, hasSkyLight, topBlock); + if(hasSkyLight) + light = getLightValue(chunk, blockPos, hasCeiling, hasSkyLight, topBlock); + else + light = 0; color = generateLodColor(chunk, config, xRel, yAbs, zRel, blockPos); blockPos.set(xAbs, yAbs + 1, zAbs); } 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 3eda1ed18..99a57359a 100644 --- a/src/main/java/com/seibel/lod/wrappers/World/WorldWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/World/WorldWrapper.java @@ -44,12 +44,12 @@ public class WorldWrapper public int getBlockLight(BlockPosWrapper blockPos) { - return world.getLightEngine().skyEngine.getLightValue(blockPos.getBlockPos()); + return world.getLightEngine().blockEngine.getLightValue(blockPos.getBlockPos()); } public int getSkyLight(BlockPosWrapper blockPos) { - return world.getLightEngine().blockEngine.getLightValue(blockPos.getBlockPos()); + return world.getLightEngine().skyEngine.getLightValue(blockPos.getBlockPos()); } public BiomeWrapper getBiome(BlockPosWrapper blockPos) From db15e8684cd5b57642e352b1e3d7bed0360e5166 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 26 Oct 2021 22:44:21 +0200 Subject: [PATCH 09/10] Another small fix to light --- .../lod/builders/lodBuilding/LodBuilder.java | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) 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 e395a8655..972696ebb 100644 --- a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java @@ -267,20 +267,14 @@ public class LodBuilder { yAbs = depth; blockPos.set(xAbs, yAbs, zAbs); - if(hasSkyLight) - light = getLightValue(chunk, blockPos, hasCeiling, hasSkyLight, topBlock); - else - light = 0; + light = getLightValue(chunk, blockPos, hasCeiling, hasSkyLight, topBlock); color = generateLodColor(chunk, config, xAbs, yAbs, zAbs, blockPos); blockPos.set(xAbs, yAbs - 1, zAbs); } else { blockPos.set(xAbs, yAbs, zAbs); - if(hasSkyLight) - light = getLightValue(chunk, blockPos, hasCeiling, hasSkyLight, topBlock); - else - light = 0; + light = getLightValue(chunk, blockPos, hasCeiling, hasSkyLight, topBlock); color = generateLodColor(chunk, config, xRel, yAbs, zRel, blockPos); blockPos.set(xAbs, yAbs + 1, zAbs); } @@ -373,7 +367,7 @@ public class LodBuilder } //if (colorInt == 0 && yAbs > 0) - // if this block is invisible, check the block below it + // if this block is invisible, check the block below it // colorInt = generateLodColor(chunk, config, xRel, yAbs - 1, zRel, blockPos); // override this block's color if there was a block above this @@ -411,8 +405,12 @@ public class LodBuilder if (topBlock && !hasCeiling && hasSkyLight) skyLight = DEFAULT_MAX_LIGHT; else - skyLight = world.getSkyLight(blockPos); - + { + if (hasSkyLight) + skyLight = world.getSkyLight(blockPos); + else + skyLight = 0; + } if (!topBlock && skyLight == 15) { // we are on predicted terrain, and we don't know what the light here is, @@ -429,7 +427,7 @@ public class LodBuilder else { world = MinecraftWrapper.INSTANCE.getWrappedClientWorld(); - if(world.isEmpty()) + if (world.isEmpty()) return 0; // client world sky light (almost never accurate) blockLight = world.getBlockLight(blockPos); @@ -440,7 +438,12 @@ public class LodBuilder skyLight = DEFAULT_MAX_LIGHT; else { - skyLight = world.getSkyLight(blockPos); + + if (hasSkyLight) + skyLight = world.getSkyLight(blockPos); + else + skyLight = 0; + if (!chunk.isLightCorrect() && (skyLight == 0 || skyLight == 15)) { // we don't know what the light here is, @@ -454,6 +457,8 @@ public class LodBuilder skyLight = 0; } } + if (hasSkyLight) + skyLight = 0; } } @@ -482,7 +487,7 @@ public class LodBuilder if (chunk.isWaterLogged(blockPos)) { BiomeWrapper biome = chunk.getBiome(xRel, y, zRel); - return biome.getWaterTint(); + return biome.getWaterTint(); } else { @@ -511,16 +516,16 @@ public class LodBuilder if (blockColorWrapper.hasGrassTint()) { // grass and green plants - tintValue = BiomeColorWrapper.getGrassColor(world,blockPos); + tintValue = BiomeColorWrapper.getGrassColor(world, blockPos); } else if (blockColorWrapper.hasFolliageTint()) { - tintValue = BiomeColorWrapper.getFoliageColor(world,blockPos); + tintValue = BiomeColorWrapper.getFoliageColor(world, blockPos); } else { //we can reintroduce this with the wrappers - tintValue = BiomeColorWrapper.getWaterColor(world,blockPos); + tintValue = BiomeColorWrapper.getWaterColor(world, blockPos); } colorInt = ColorUtil.multiplyRGBcolors(tintValue | 0xFF000000, colorOfBlock); } From a3db8e50f53f3fc5acfd1ba447c17f2797d95433 Mon Sep 17 00:00:00 2001 From: cola98765 Date: Tue, 26 Oct 2021 23:09:31 +0200 Subject: [PATCH 10/10] removed NativeImage dependency outside of wrappers. Now LodRenderer only triggers regen without storing lightmap --- .../lod/builders/bufferBuilding/LodBufferBuilder.java | 2 +- .../bufferBuilding/lodTemplates/AbstractLodTemplate.java | 3 +-- .../bufferBuilding/lodTemplates/CubicLodTemplate.java | 6 ++---- .../bufferBuilding/lodTemplates/DynamicLodTemplate.java | 3 +-- .../bufferBuilding/lodTemplates/TriangularLodTemplate.java | 3 +-- src/main/java/com/seibel/lod/render/LodRenderer.java | 7 +------ src/main/java/com/seibel/lod/util/ColorUtil.java | 6 +++--- 7 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java index 915d375ab..de5238018 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java @@ -415,7 +415,7 @@ public class LodBufferBuilder //We send the call to create the vertices LodConfig.CLIENT.graphics.advancedGraphicsOption.lodTemplate.get().template.addLodToBuffer(currentBuffers[bufferIndex], playerBlockPosRounded, data, adjData, - detailLevel, posX, posZ, box, renderer.previousDebugMode, renderer.lightMap, adjShadeDisabled); + detailLevel, posX, posZ, box, renderer.previousDebugMode, adjShadeDisabled); } diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/AbstractLodTemplate.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/AbstractLodTemplate.java index 118e571a2..daff1fa0f 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/AbstractLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/AbstractLodTemplate.java @@ -25,7 +25,6 @@ import com.seibel.lod.enums.DebugMode; import com.seibel.lod.util.ColorUtil; import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.texture.NativeImage; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; @@ -40,7 +39,7 @@ public abstract class AbstractLodTemplate /** Uploads the given LOD to the buffer. */ public abstract void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map adjData, - byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap, boolean[] adjShadeDisabled); + byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, boolean[] adjShadeDisabled); /** add the given position and color to the buffer */ protected void addPosAndColor(BufferBuilder buffer, diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/CubicLodTemplate.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/CubicLodTemplate.java index a46c6af46..677dc7c7d 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/CubicLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/CubicLodTemplate.java @@ -25,10 +25,8 @@ import com.seibel.lod.enums.DebugMode; import com.seibel.lod.util.ColorUtil; import com.seibel.lod.util.DataPointUtil; import com.seibel.lod.util.LodUtil; -import com.seibel.lod.wrappers.MinecraftWrapper; import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.texture.NativeImage; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; @@ -47,7 +45,7 @@ public class CubicLodTemplate extends AbstractLodTemplate @Override public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map adjData, - byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap, boolean[] adjShadeDisabled) + byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, boolean[] adjShadeDisabled) { if (box == null) return; @@ -128,7 +126,7 @@ public class CubicLodTemplate extends AbstractLodTemplate color = box.getColor(direction); skyLight = box.getSkyLight(direction, verticalFaceIndex); blockLight = box.getBlockLight(); - color = ColorUtil.applyLightValue(color, skyLight, blockLight, MinecraftWrapper.INSTANCE.getCurrentLightMap()); + color = ColorUtil.applyLightValue(color, skyLight, blockLight); addPosAndColor(buffer, box.getX(direction, vertexIndex), box.getY(direction, vertexIndex, verticalFaceIndex), diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/DynamicLodTemplate.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/DynamicLodTemplate.java index a7ec3c87b..dd88744ab 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/DynamicLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/DynamicLodTemplate.java @@ -25,7 +25,6 @@ import com.seibel.lod.enums.DebugMode; import com.seibel.lod.proxy.ClientProxy; import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.texture.NativeImage; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; @@ -41,7 +40,7 @@ public class DynamicLodTemplate extends AbstractLodTemplate { @Override public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map adjData, - byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap, boolean[] adjShadeDisabled) + byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, boolean[] adjShadeDisabled) { ClientProxy.LOGGER.error(DynamicLodTemplate.class.getSimpleName() + " is not implemented!"); } diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/TriangularLodTemplate.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/TriangularLodTemplate.java index 9ad30e317..765399455 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/TriangularLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/TriangularLodTemplate.java @@ -25,7 +25,6 @@ import com.seibel.lod.enums.DebugMode; import com.seibel.lod.proxy.ClientProxy; import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.texture.NativeImage; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; @@ -39,7 +38,7 @@ public class TriangularLodTemplate extends AbstractLodTemplate { @Override public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map adjData, - byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap, boolean[] adjShadeDisabled) + byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, boolean[] adjShadeDisabled) { ClientProxy.LOGGER.error(DynamicLodTemplate.class.getSimpleName() + " is not implemented!"); } diff --git a/src/main/java/com/seibel/lod/render/LodRenderer.java b/src/main/java/com/seibel/lod/render/LodRenderer.java index c9aa5fa6a..1753b90f6 100644 --- a/src/main/java/com/seibel/lod/render/LodRenderer.java +++ b/src/main/java/com/seibel/lod/render/LodRenderer.java @@ -49,7 +49,6 @@ import com.seibel.lod.wrappers.MinecraftWrapper; import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.client.renderer.texture.NativeImage; import net.minecraft.client.renderer.vertex.VertexBuffer; import net.minecraft.potion.Effects; import net.minecraft.profiler.IProfiler; @@ -104,9 +103,6 @@ public class LodRenderer /** This is used to determine if the LODs should be regenerated */ private int[] previousPos = new int[] { 0, 0, 0 }; - public NativeImage lightMap = null; - public NativeImage lastLightMap = null; - // these variables are used to determine if the buffers should be rebuilt private float prevSkyBrightness = 0; private double prevBrightness = 0; @@ -866,10 +862,9 @@ public class LodRenderer // (just in case the minLightingDifference is too large to notice the change) || (skyBrightness == 1.0f && prevSkyBrightness != 1.0f) // noon || (skyBrightness == 0.2f && prevSkyBrightness != 0.2f) // midnight - || mc.getOptions().gamma != prevBrightness || lightMap == null) + || mc.getOptions().gamma != prevBrightness) { fullRegen = true; - lightMap = mc.getCurrentLightMap(); prevBrightness = mc.getOptions().gamma; prevSkyBrightness = skyBrightness; } diff --git a/src/main/java/com/seibel/lod/util/ColorUtil.java b/src/main/java/com/seibel/lod/util/ColorUtil.java index 7a814dd08..d8456b9aa 100644 --- a/src/main/java/com/seibel/lod/util/ColorUtil.java +++ b/src/main/java/com/seibel/lod/util/ColorUtil.java @@ -21,7 +21,7 @@ package com.seibel.lod.util; import java.awt.Color; -import net.minecraft.client.renderer.texture.NativeImage; +import com.seibel.lod.wrappers.MinecraftWrapper; /** * @@ -78,9 +78,9 @@ public class ColorUtil } /** This method apply the lightmap to the color to use */ - public static int applyLightValue(int color, int skyLight, int blockLight, NativeImage lightMap) + public static int applyLightValue(int color, int skyLight, int blockLight) { - int lightColor = lightMap.getPixelRGBA(blockLight, skyLight); + int lightColor = MinecraftWrapper.INSTANCE.getColorIntFromLightMap(blockLight, skyLight); int red = ColorUtil.getBlue(lightColor); int green = ColorUtil.getGreen(lightColor); int blue = ColorUtil.getRed(lightColor);