From 638a0ddae10cef09cd6596f958e6154de461f1b1 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Mon, 25 Oct 2021 20:20:40 +0200 Subject: [PATCH] BlockPosWrapper and BlockWrapper almost completed --- .../lod/builders/lodBuilding/LodBuilder.java | 4 +- .../seibel/lod/wrappers/BlockPosWrapper.java | 64 +++++ .../com/seibel/lod/wrappers/BlockWrapper.java | 271 ++++++++++++++++++ .../seibel/lod/wrappers/TextureWrapper.java | 5 - 4 files changed, 336 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/seibel/lod/wrappers/BlockPosWrapper.java delete mode 100644 src/main/java/com/seibel/lod/wrappers/TextureWrapper.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 dcd301c81..152f58efa 100644 --- a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java @@ -62,6 +62,7 @@ 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; @@ -99,7 +100,6 @@ public class LodBuilder 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 shapeMap = new ConcurrentHashMap<>(); public static final ConcurrentMap notFullBlock = new ConcurrentHashMap<>(); public static final ConcurrentMap smallBlock = new ConcurrentHashMap<>(); @@ -551,8 +551,6 @@ public class LodBuilder if (colorMap.containsKey(block) && toTint.containsKey(block)) return colorMap.get(block); - - World world = mc.getClientWorld(); TextureAtlasSprite texture; List quads = null; diff --git a/src/main/java/com/seibel/lod/wrappers/BlockPosWrapper.java b/src/main/java/com/seibel/lod/wrappers/BlockPosWrapper.java new file mode 100644 index 000000000..eb389320f --- /dev/null +++ b/src/main/java/com/seibel/lod/wrappers/BlockPosWrapper.java @@ -0,0 +1,64 @@ +package com.seibel.lod.wrappers; + +import com.seibel.lod.util.ColorUtil; +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.BlockPos; +import net.minecraftforge.client.model.data.ModelDataMap; + +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 BlockPos.Mutable (and BlockPos) class +public class BlockPosWrapper +{ + private BlockPos.Mutable blockPos; + + + public BlockPosWrapper() + { + this.blockPos = new BlockPos.Mutable(); + } + + public void set(int x, int y, int z) + { + blockPos.set(x, y, z); + } + + public int getX() + { + return blockPos.getX(); + } + + public int getY() + { + return blockPos.getY(); + } + + public int getZ() + { + return blockPos.getZ(); + } + + private BlockPos.Mutable getBlockPos() + { + return blockPos; + } + + @Override public boolean equals(Object o) + { + return blockPos.equals(o); + } + + @Override public int hashCode() + { + return Objects.hash(blockPos); + } + +} diff --git a/src/main/java/com/seibel/lod/wrappers/BlockWrapper.java b/src/main/java/com/seibel/lod/wrappers/BlockWrapper.java index 138db7bc9..e55f92bb3 100644 --- a/src/main/java/com/seibel/lod/wrappers/BlockWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/BlockWrapper.java @@ -1,5 +1,276 @@ package com.seibel.lod.wrappers; +import com.seibel.lod.util.ColorUtil; +import net.minecraft.block.*; +import net.minecraft.client.renderer.model.BakedQuad; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.util.Direction; +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 BlockWrapper { + //set of block which require tint + public static final ConcurrentMap blockWrapperMap = new ConcurrentHashMap<>(); + public static final ModelDataMap dataMap = new ModelDataMap.Builder().build(); + public static Random random = new Random(0); + + + private Block block; + private boolean nonFull; + private boolean noCollision; + private int color; + private boolean isColored; + private boolean toTint; + private boolean leavesTint; + private boolean grassTint; + private boolean waterTint; + + + + /**Constructor only require for the block instance we are wrapping**/ + public BlockWrapper(Block block) + { + this.nonFull = true; + this.noCollision = true; + this.color = 0; + this.isColored = true; + this.toTint = false; + this.block = block; + setupColorAndTint(); + setupShapes(); + } + + /** + * this return a wrapper of the block in input + * @param block Block object to wrap + */ + static public BlockWrapper getBlockWrapper(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 it hasn't been created yet, we create it and save it in the map + BlockWrapper blockWrapper = new BlockWrapper(block); + 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. + */ + private void setupColorAndTint() + { + MinecraftWrapper mc = MinecraftWrapper.INSTANCE; + TextureAtlasSprite texture; + List quads = null; + + boolean isTinted = false; + int listSize = 0; + + // first step is to check if this block has a tinted face + for (Direction direction : Direction.values()) + { + quads = mc.getModelManager().getBlockModelShaper().getBlockModel(block.defaultBlockState()).getQuads(block.defaultBlockState(), direction, random, dataMap); + listSize = Math.max(listSize, quads.size()); + for (BakedQuad bakedQuad : quads) + { + isTinted |= bakedQuad.isTinted(); + } + } + + //if it contains a tinted face then we store this block in the toTint set + if(isTinted) + this.toTint = true; + + //now we get the first non empty face + for (Direction direction : Direction.values()) + { + quads = mc.getModelManager().getBlockModelShaper().getBlockModel(block.defaultBlockState()).getQuads(block.defaultBlockState(), direction, random, dataMap); + if (!quads.isEmpty()) + break; + } + + //the quads list is not empty we extract the first one + if (!quads.isEmpty()) + texture = quads.get(0).getSprite(); + else + { + return; + } + + int count = 0; + int alpha = 0; + int red = 0; + int green = 0; + int blue = 0; + int numberOfGreyPixel = 0; + int tempColor; + 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; + + tempColor = texture.getPixelRGBA(frameIndex, u, v); + + // 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)); + boolean isGray = colorMax < colorMin; + if (isGray) + numberOfGreyPixel++; + + + // for flowers, weight their non-green color higher + if (block instanceof FlowerBlock && (!(ColorUtil.getGreen(tempColor) > (ColorUtil.getBlue(tempColor) + 30)) || !(ColorUtil.getGreen(tempColor) > (ColorUtil.getRed(tempColor) + 30)))) + colorMultiplier = 5; + else + colorMultiplier = 1; + + + // add to the running averages + count += colorMultiplier; + alpha += ColorUtil.getAlpha(tempColor) * colorMultiplier; + red += ColorUtil.getBlue(tempColor) * colorMultiplier; + green += ColorUtil.getGreen(tempColor) * colorMultiplier; + blue += ColorUtil.getRed(tempColor) * colorMultiplier; + } + } + } + + + if (count == 0) + // this block is entirely transparent + tempColor = 0; + else + { + // determine the average color + alpha /= count; + red /= count; + green /= count; + blue /= count; + tempColor = ColorUtil.rgbToInt(alpha, red, green, blue); + } + + // determine if this block should use the biome color tint + if ((grassInstance() || leavesInstance() || waterIstance()) && (float) numberOfGreyPixel / count > 0.75f) + this.toTint = true; + + // we check which kind of tint we need to apply + if (grassInstance() && this.toTint) + this.grassTint = true; + + if (leavesInstance() && this.toTint) + this.leavesTint = true; + + if (waterIstance() && this.toTint) + this.waterTint = true; + + color = tempColor; + } + + /** determine if the given block should use the biome's grass color */ + private boolean grassInstance() + { + 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 leavesInstance() + { + return block instanceof LeavesBlock + || block == Blocks.VINE + || block == Blocks.SUGAR_CANE; + } + + /** determine if the given block should use the biome's foliage color */ + private boolean waterIstance() + { + return block == Blocks.WATER; + } + + private void setupShapes(){ + + } + + //--------------// + //Colors getters// + //--------------// + + public boolean hasColor() + { + return isColored; + } + + public int getColor() + { + return color; + } + + //------------// + //Tint getters// + //------------// + + + public boolean hasTint() + { + return toTint; + } + + public boolean hasGrassTint() + { + return grassTint; + } + + public boolean hasLeavesTint() + { + return leavesTint; + } + + public boolean hasWaterTint() + { + return waterTint; + } + + + @Override public boolean equals(Object o) + { + if (this == o) + return true; + if (!(o instanceof BlockWrapper)) + return false; + BlockWrapper that = (BlockWrapper) o; + return Objects.equals(block, that.block); + } + + @Override public int hashCode() + { + return Objects.hash(block); + } + } diff --git a/src/main/java/com/seibel/lod/wrappers/TextureWrapper.java b/src/main/java/com/seibel/lod/wrappers/TextureWrapper.java deleted file mode 100644 index 9ae9a8d9e..000000000 --- a/src/main/java/com/seibel/lod/wrappers/TextureWrapper.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.seibel.lod.wrappers; - -public class TextureWrapper -{ -}