diff --git a/src/main/java/com/seibel/lod/Main.java b/src/main/java/com/seibel/lod/Main.java index 05c00a423..0db2495c1 100644 --- a/src/main/java/com/seibel/lod/Main.java +++ b/src/main/java/com/seibel/lod/Main.java @@ -1,11 +1,11 @@ package com.seibel.lod; -import com.google.common.primitives.UnsignedLong; -import com.seibel.lod.objects.PosToGenerateContainer; +import com.seibel.lod.builders.lodTemplates.Box; import com.seibel.lod.util.DataPointUtil; +import net.minecraft.util.Direction; -import javax.xml.crypto.Data; -import java.math.BigInteger; +import java.util.HashMap; +import java.util.Map; public class Main { @@ -13,18 +13,37 @@ public class Main { try { - long[][] dataToMerge = new long[][]{ - {DataPointUtil.createDataPoint(10, 5, 0, 0, 0, 0)}, - {DataPointUtil.createDataPoint(15, 5, 0, 0, 0, 0)}, - {DataPointUtil.createDataPoint(40, 20, 0, 0, 0, 0)}, - {DataPointUtil.createDataPoint(1, 0, 0, 0, 0, 0)}}; - long[] data = DataPointUtil.mergeVerticalData(dataToMerge); - for (long dataPoint : data) + Map adjData = new HashMap() + {{ + put(Direction.EAST, new long[]{DataPointUtil.createDataPoint(70, 50, 0, 0, 0, 0), DataPointUtil.createDataPoint(45, 30, 0, 0, 0, 0), DataPointUtil.createDataPoint(28, 25, 0, 0, 0, 0)}); + put(Direction.WEST, new long[]{DataPointUtil.createDataPoint(70, 10, 0, 0, 0, 0)}); + put(Direction.NORTH, new long[]{DataPointUtil.createDataPoint(50, 0, 0, 0, 0, 0)}); + put(Direction.SOUTH, new long[]{DataPointUtil.createDataPoint(50, 30, 0, 0, 0, 0)}); + }}; + + Box box = new Box(); + int height = 60; + int depth = 20; + + box.set(10, height - depth, 10); + box.move(0, depth, 0); + box.setAdjData(adjData); + + for(Direction direction : Box.ADJ_DIRECTIONS) { - System.out.println("depth " + DataPointUtil.getDepth(dataPoint)); - System.out.println("height " + DataPointUtil.getHeight(dataPoint)); + int adjIndex = 0; + while (box.shouldContinue(direction, adjIndex)) + { + for (int i = 0; i < 4; i++) + { + System.out.println(box.getX(direction, i) + " " + box.getY(direction, i, adjIndex) + " " + box.getZ(direction, i)); + } + adjIndex++; + } } - }catch (Exception e){ + + } catch (Exception e) + { e.printStackTrace(); } } diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java index 7ab1a5cab..1294fd307 100644 --- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java @@ -19,13 +19,16 @@ package com.seibel.lod.builders; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.locks.ReentrantLock; +import net.minecraft.util.Direction; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL15C; @@ -112,7 +115,7 @@ public class LodBufferBuilder private static final int NUMBER_OF_DIRECTION = 4; //in order -x, +x, -z, +z - private static final int[][] ADJ_DIRECTION = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; + private static final int[][] ADJ_VECTOR = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; private volatile Box[][] boxCache; private volatile PosToRenderContainer[][] setsToRender; @@ -249,7 +252,7 @@ public class LodBufferBuilder int chunkZdist; short gameChunkRenderDistance = (short) (renderer.vanillaRenderedChunks.length / 2 - 1); //long dataPoint; - long[] adjData = new long[NUMBER_OF_DIRECTION]; + Map adjData = new HashMap<>(); for (int index = 0; index < posToRender.getNumberOfPos(); index++) { @@ -270,49 +273,46 @@ public class LodBufferBuilder try { + for (int direction = 0; direction < NUMBER_OF_DIRECTION; direction++) + { + + xAdj = posX + ADJ_VECTOR[direction][0]; + zAdj = posZ + ADJ_VECTOR[direction][1]; + chunkXdist = LevelPosUtil.getChunkPos(detailLevel,xAdj) - playerChunkPos.x; + chunkZdist = LevelPosUtil.getChunkPos(detailLevel,zAdj) - playerChunkPos.z; + + if (gameChunkRenderDistance >= Math.abs(chunkXdist) && gameChunkRenderDistance >= Math.abs(chunkZdist)) + { + if (!renderer.vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance + 1][chunkZdist + gameChunkRenderDistance + 1] + && posToRender.contains(detailLevel, xAdj, zAdj)) + { + adjData.put(Box.ADJ_DIRECTIONS[direction], lodDim.getData(detailLevel, xAdj, zAdj)); + }else{ + adjData.put(Box.ADJ_DIRECTIONS[direction], null); + } + } else + { + if (posToRender.contains(detailLevel, xAdj, zAdj)) + { + adjData.put(Box.ADJ_DIRECTIONS[direction], lodDim.getData(detailLevel, xAdj, zAdj)); + }else{ + adjData.put(Box.ADJ_DIRECTIONS[direction], null); + } + } + } + if (region.getLodQualityMode() == LodQualityMode.HEIGHTMAP) { //dataPoint = lodDim.getData(detailLevel, posX, posZ)[0]; long dataPoint = lodDim.getSingleData(detailLevel, posX, posZ); if (!DataPointUtil.isItVoid(dataPoint) && DataPointUtil.doesItExist(dataPoint)) { - dataPoint = lodDim.getSingleData(detailLevel, posX, posZ); - if(DataPointUtil.getHeight(dataPoint) == LodBuilder.DEFAULT_HEIGHT && DataPointUtil.getDepth(dataPoint) == LodBuilder.DEFAULT_DEPTH) - continue; - for (int direction = 0; direction < NUMBER_OF_DIRECTION; direction++) - { - - xAdj = posX + ADJ_DIRECTION[direction][0]; - zAdj = posZ + ADJ_DIRECTION[direction][1]; - chunkXdist = LevelPosUtil.getChunkPos(detailLevel,xAdj) - playerChunkPos.x; - chunkZdist = LevelPosUtil.getChunkPos(detailLevel,zAdj) - playerChunkPos.z; - - if (gameChunkRenderDistance >= Math.abs(chunkXdist) && gameChunkRenderDistance >= Math.abs(chunkZdist)) - { - if (!renderer.vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance + 1][chunkZdist + gameChunkRenderDistance + 1] - && posToRender.contains(detailLevel, xAdj, zAdj)) - { - adjData[direction]= lodDim.getSingleData(detailLevel, xAdj, zAdj); - }else{ - adjData[direction]= 0; - } - } else - { - if (posToRender.contains(detailLevel, xAdj, zAdj)) - { - adjData[direction] = lodDim.getSingleData(detailLevel, xAdj, zAdj); - }else{ - adjData[direction]= 0; - } - } - } LodConfig.CLIENT.graphics.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPosRounded, dataPoint, adjData, detailLevel, posX, posZ, boxCache[xR][zR],renderer.previousDebugMode, renderer.lightMap); } } else if (region.getLodQualityMode() == LodQualityMode.MULTI_LOD) { - //dataPoint = lodDim.getData(detailLevel, posX, posZ)[0]; for (long dataPoint : lodDim.getData(detailLevel, posX, posZ)) { if (!DataPointUtil.isItVoid(dataPoint) && DataPointUtil.doesItExist(dataPoint)) @@ -385,7 +385,7 @@ public class LodBufferBuilder // upload the new buffers uploadBuffers(fullRegen, lodDim); bufferLock.unlock(); - + // make sure the context is disabled GlProxy.getInstance().setGlContext(GlProxyContext.NONE); } @@ -491,8 +491,8 @@ public class LodBufferBuilder glProxy.setGlContext(GlProxyContext.LOD_BUILDER); // only print console debugging for vboUpload once per upload cycle boolean bufferMapFail = false; - - + + for (int x = 0; x < buildableVbos.length; x++) { for (int z = 0; z < buildableVbos.length; z++) @@ -505,8 +505,8 @@ public class LodBufferBuilder } } } - - + + // make sure all the buffers have been uploaded. // this probably is necessary, but it makes me feel good :) GL11.glFlush(); @@ -529,25 +529,25 @@ public class LodBufferBuilder { // this is how many points will be rendered vbo.vertexCount = (uploadBuffer.remaining() / vbo.format.getVertexSize()); - - + + GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.id); - - + + // subData only works if the memory is allocated beforehand. GL15C.glBufferData(GL15.GL_ARRAY_BUFFER, uploadBuffer.remaining(), GL15C.GL_DYNAMIC_DRAW); - + // interestingly bufferSubData renders faster than glMapBuffer // even though OpenGLInsights-AsynchronousBufferTransfers says glMapBuffer // is faster for transferring data. They must put the data in different memory // or something. GL15C.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, uploadBuffer); - - + + GL15C.glUnmapBuffer(GL15.GL_ARRAY_BUFFER); GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); } - + // just used to improve debug printing return bufferMapFail; } diff --git a/src/main/java/com/seibel/lod/builders/LodBuilder.java b/src/main/java/com/seibel/lod/builders/LodBuilder.java index 6abaa8b8c..f1f1f3f34 100644 --- a/src/main/java/com/seibel/lod/builders/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBuilder.java @@ -49,15 +49,12 @@ 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.gen.Heightmap; import net.minecraftforge.client.extensions.IForgeBakedModel; import net.minecraftforge.client.model.data.ModelDataMap; -import javax.swing.*; - /** * This object is in charge of creating Lod related objects. (specifically: Lod * World, Dimension, and Region objects) @@ -228,7 +225,7 @@ public class LodBuilder case MULTI_LOD: long[][] dataToMergeVertical; dataToMergeVertical = createVerticalDataToMerge(detail, chunk, config, startX, startZ, endX, endZ); - data = DataPointUtil.mergeVerticalData(dataToMergeVertical); + data = DataPointUtil.mergeMultiData(dataToMergeVertical); if (data.length == 0 || data == null) data = new long[]{DataPointUtil.EMPTY_DATA}; lodDim.addData(detailLevel, diff --git a/src/main/java/com/seibel/lod/builders/lodTemplates/AbstractLodTemplate.java b/src/main/java/com/seibel/lod/builders/lodTemplates/AbstractLodTemplate.java index 7384e8695..ce82f3824 100644 --- a/src/main/java/com/seibel/lod/builders/lodTemplates/AbstractLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/lodTemplates/AbstractLodTemplate.java @@ -19,12 +19,16 @@ package com.seibel.lod.builders.lodTemplates; 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; import net.minecraft.world.DimensionType; +import java.awt.*; +import java.util.Map; + /** * This is the abstract class used to create different * BufferBuilders. @@ -36,7 +40,7 @@ public abstract class AbstractLodTemplate { - public abstract void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, long[] adjData, + public abstract void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map adjData, byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap); /** @@ -44,10 +48,10 @@ public abstract class AbstractLodTemplate */ protected void addPosAndColor(BufferBuilder buffer, double x, double y, double z, - int red, int green, int blue, int alpha) + int color) { - buffer.vertex(x, y, z).color(red, green, blue, alpha).endVertex(); + buffer.vertex(x, y, z).color(ColorUtil.getRed(color), ColorUtil.getGreen(color), ColorUtil.getBlue(color), ColorUtil.getAlpha(color)).endVertex(); } /** diff --git a/src/main/java/com/seibel/lod/builders/lodTemplates/Box.java b/src/main/java/com/seibel/lod/builders/lodTemplates/Box.java index 500e6bd16..054203779 100644 --- a/src/main/java/com/seibel/lod/builders/lodTemplates/Box.java +++ b/src/main/java/com/seibel/lod/builders/lodTemplates/Box.java @@ -1,13 +1,17 @@ package com.seibel.lod.builders.lodTemplates; +import com.seibel.lod.config.LodConfig; +import com.seibel.lod.enums.ShadingMode; +import com.seibel.lod.util.ColorUtil; +import com.seibel.lod.util.DataPointUtil; +import com.seibel.lod.wrappers.MinecraftWrapper; +import net.minecraft.util.Direction; + +import java.util.HashMap; +import java.util.Map; + public class Box { - public static final int DOWN = 0; - public static final int UP = 1; - public static final int EAST = 2; - public static final int WEST = 3; - public static final int SOUTH = 4; - public static final int NORTH = 5; public static final int OFFSET = 0; public static final int WIDTH = 1; @@ -16,49 +20,304 @@ public class Box public static final int Y = 1; public static final int Z = 2; + + public static final int VOID_FACE = 0; + + public static final Direction[] DIRECTIONS = new Direction[]{ + Direction.UP, + Direction.DOWN}; + + public static final Direction[] ADJ_DIRECTIONS = new Direction[]{ + Direction.WEST, + Direction.EAST, + Direction.NORTH, + Direction.SOUTH}; + + public static final Map DIRECTION_VERTEX_MAP = new HashMap() + {{ + put(Direction.UP, new int[][]{ + {0, 1, 0}, + {0, 1, 1}, + {1, 1, 0}, + {1, 1, 1}}); + put(Direction.DOWN, new int[][]{ + {0, 0, 0}, + {0, 0, 1}, + {1, 0, 0}, + {1, 0, 1}}); + put(Direction.EAST, new int[][]{ + {1, 0, 0}, + {1, 0, 1}, + {1, 1, 0}, + {1, 1, 1}}); + put(Direction.WEST, new int[][]{ + {0, 0, 0}, + {0, 0, 1}, + {0, 1, 0}, + {0, 1, 1}}); + put(Direction.SOUTH, new int[][]{ + {0, 0, 1}, + {1, 0, 1}, + {0, 1, 1}, + {1, 1, 1}}); + put(Direction.NORTH, new int[][]{ + {0, 0, 0}, + {1, 0, 0}, + {0, 1, 0}, + {1, 1, 0}}); + }}; + + public static final Map DIRECTION_NORMAL_MAP = new HashMap() + {{ + put(Direction.UP, new int[]{0, 1, 0}); + put(Direction.DOWN, new int[]{0, -1, 0}); + put(Direction.EAST, new int[]{1, 0, 0}); + put(Direction.WEST, new int[]{-1, 0, 0}); + put(Direction.SOUTH, new int[]{0, 0, 1}); + put(Direction.NORTH, new int[]{0, 0, -1}); + }}; + public int[][] box; + public Map colorMap; + public Map adjData; + public int color; + public Map adjHeightAndDepth = new HashMap() + {{ + put(Direction.EAST, new int[256][2]); + put(Direction.WEST, new int[256][2]); + put(Direction.SOUTH, new int[256][2]); + put(Direction.NORTH, new int[256][2]); + }}; - public Box(){ + public Box() + { box = new int[2][3]; + colorMap = new HashMap() + {{ + put(Direction.UP, new int[1]); + put(Direction.DOWN, new int[1]); + put(Direction.EAST, new int[1]); + put(Direction.WEST, new int[1]); + put(Direction.SOUTH, new int[1]); + put(Direction.NORTH, new int[1]); + }}; } - public void set(int xWidth, int yWidth, int zWidth){ - box[OFFSET][X] = 0; - box[OFFSET][Y] = 0; - box[OFFSET][Z] = 0; - - box[WIDTH][X] = xWidth; - box[WIDTH][Y] = yWidth; - box[WIDTH][Z] = zWidth; + public void setColor(int color) + { + this.color = color; + for (Direction direction : DIRECTIONS) + { + colorMap.get(direction)[0] = ColorUtil.applyShade(color, MinecraftWrapper.INSTANCE.getWorld().getShade(direction, true)); + } } - public void move(int xOffset, int yOffset, int zOffset){ + public int getColor(Direction direction) + { + if (LodConfig.CLIENT.graphics.shadingMode.get() == ShadingMode.DARKEN_SIDES) + { + return colorMap.get(direction)[0]; + } else + { + return color; + } + } + + public void setAdjData(Map adjData) + { + int height; + int depth; + this.adjData = adjData; + + for (Direction direction : ADJ_DIRECTIONS) + { + boolean noMatch = true; + long[] dataPoint = adjData.get(direction); + if (dataPoint == null) + { + adjHeightAndDepth.get(direction)[0][0] = getMaxY(); + adjHeightAndDepth.get(direction)[0][1] = getMinY(); + adjHeightAndDepth.get(direction)[1][0] = VOID_FACE; + adjHeightAndDepth.get(direction)[1][1] = VOID_FACE; + continue; + } + int i; + int faceToDraw = 0; + boolean firstFace = true; + boolean toFinish = false; + for (i = 0; i < dataPoint.length; i++) + { + height = DataPointUtil.getHeight(dataPoint[i]); + depth = DataPointUtil.getDepth(dataPoint[i]); + + if (depth > getMaxY()) + {//the adj data is higher than the current data + //we continue since there could be some other data that intersect the current + System.out.println("case 1 " + height + " " + depth); + continue; + } else if (height < getMinY()) + {//the adj data is lower than the current data + //we break since all the other data will be lower + + if (firstFace) + { + System.out.println("case 2-1 " + height + " " + depth); + adjHeightAndDepth.get(direction)[0][0] = getMaxY(); + adjHeightAndDepth.get(direction)[0][1] = getMinY(); + } else + { + System.out.println("case 2-2 " + height + " " + depth); + adjHeightAndDepth.get(direction)[faceToDraw][1] = getMinY(); + } + faceToDraw++; + toFinish = false; + break; + } else if (depth <= getMinY() && height >= getMaxY()) + {//the adj data contains the current + //we do not draw the face + System.out.println("case 3"); + adjHeightAndDepth.get(direction)[0][0] = VOID_FACE; + adjHeightAndDepth.get(direction)[0][1] = VOID_FACE; + break; + } else if (depth <= getMinY() && height < getMaxY()) + {//the adj data intersect the lower part of the current data + //if this is the only face we use the maxY and break + //if there was other face we finish the last one and break + if (firstFace) + { + System.out.println("case 4-1 " + height + " " + depth); + adjHeightAndDepth.get(direction)[0][0] = getMaxY(); + adjHeightAndDepth.get(direction)[0][1] = height; + } else + { + System.out.println("case 4-2 " + height + " " + depth); + adjHeightAndDepth.get(direction)[faceToDraw][1] = height; + } + firstFace = false; + toFinish = false; + faceToDraw++; + break; + } else if (depth > getMinY() && height >= getMaxY()) + {//the adj data intersect the higher part of the current data + //we start the creation of a new face + System.out.println("case 5 " + height + " " + depth); + adjHeightAndDepth.get(direction)[faceToDraw][0] = depth; + firstFace = false; + toFinish = true; + continue; + } else if (depth > getMinY() && height < getMaxY()) + {//the adj data is contained in the current data + if (firstFace) + { + System.out.println("case 6-1 " + height + " " + depth);; + adjHeightAndDepth.get(direction)[0][0] = getMaxY(); + } else + { + System.out.println("case 6-2 " + height + " " + depth); + } + adjHeightAndDepth.get(direction)[faceToDraw][1] = height; + faceToDraw++; + adjHeightAndDepth.get(direction)[faceToDraw][0] = depth; + firstFace = false; + toFinish = true; + continue; + } + } + if(toFinish) + { + adjHeightAndDepth.get(direction)[faceToDraw][1] = getMinY(); + faceToDraw++; + } + adjHeightAndDepth.get(direction)[faceToDraw][0] = VOID_FACE; + adjHeightAndDepth.get(direction)[faceToDraw][1] = VOID_FACE; + } + } + + public void set(int xWidth, int yWidth, int zWidth) + { + box[OFFSET][X] = 0; + box[OFFSET][Y] = 0; + box[OFFSET][Z] = 0; + + box[WIDTH][X] = xWidth; + box[WIDTH][Y] = yWidth; + box[WIDTH][Z] = zWidth; + } + + public void move(int xOffset, int yOffset, int zOffset) + { box[OFFSET][X] = xOffset; box[OFFSET][Y] = yOffset; box[OFFSET][Z] = zOffset; } - public int getMinX(){ + public int getCoord(Direction direction, int axis, int vertexIndex) + { + return box[OFFSET][axis] + box[WIDTH][axis] * DIRECTION_VERTEX_MAP.get(direction)[vertexIndex][axis]; + } + + public int getX(Direction direction, int vertexIndex) + { + return box[OFFSET][X] + box[WIDTH][X] * DIRECTION_VERTEX_MAP.get(direction)[vertexIndex][X]; + } + + public int getY(Direction direction, int vertexIndex, int adjIndex) + { + if (direction == Direction.DOWN || direction == Direction.UP) + { + return box[OFFSET][Y] + box[WIDTH][Y] * DIRECTION_VERTEX_MAP.get(direction)[vertexIndex][Y]; + } else + { + return adjHeightAndDepth.get(direction)[adjIndex][1 - DIRECTION_VERTEX_MAP.get(direction)[vertexIndex][Y]]; + } + } + + public int getZ(Direction direction, int vertexIndex) + { + return box[OFFSET][Z] + box[WIDTH][Z] * DIRECTION_VERTEX_MAP.get(direction)[vertexIndex][Z]; + } + + public boolean shouldContinue(Direction direction, int adjIndex) + { + if (direction == Direction.UP || direction == Direction.DOWN) + { + if (adjIndex == 0) + return true; + else + return false; + } + return !(adjHeightAndDepth.get(direction)[adjIndex][0] == VOID_FACE && adjHeightAndDepth.get(direction)[adjIndex][1] == VOID_FACE); + + } + + public int getMinX() + { return box[OFFSET][X]; } - public int getMaxX(){ + public int getMaxX() + { return box[OFFSET][X] + box[WIDTH][X]; } - public int getMinY(){ + public int getMinY() + { return box[OFFSET][Y]; } - public int getMaxY(){ + public int getMaxY() + { return box[OFFSET][Y] + box[WIDTH][Y]; } - public int getMinZ(){ + public int getMinZ() + { return box[OFFSET][Z]; } - public int getMaxZ(){ + public int getMaxZ() + { return box[OFFSET][Z] + box[WIDTH][Z]; } + } diff --git a/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java b/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java index 3dcc85828..ac634821d 100644 --- a/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java @@ -17,24 +17,16 @@ */ package com.seibel.lod.builders.lodTemplates; -import com.seibel.lod.config.LodConfig; import com.seibel.lod.enums.DebugMode; -import com.seibel.lod.enums.ShadingMode; -import com.seibel.lod.objects.LodDimension; import com.seibel.lod.util.DataPointUtil; -import com.seibel.lod.util.ColorUtil; import com.seibel.lod.util.LodUtil; -import com.seibel.lod.wrappers.MinecraftWrapper; -import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.texture.NativeImage; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.DimensionType; -import java.lang.annotation.Native; +import java.util.Map; /** * Builds LODs as rectangular prisms. @@ -52,7 +44,7 @@ public class CubicLodTemplate extends AbstractLodTemplate } @Override - public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, long[] adjData, + public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map adjData, byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap) { int width = 1 << detailLevel; @@ -66,7 +58,8 @@ public class CubicLodTemplate extends AbstractLodTemplate posX * width, 0, posZ * width, - bufferCenterBlockPos); + bufferCenterBlockPos, + adjData); int color; color = DataPointUtil.getLightColor(data,lightMap); @@ -82,12 +75,12 @@ public class CubicLodTemplate extends AbstractLodTemplate if (box != null) { - addBoundingBoxToBuffer(buffer, box, color, bufferCenterBlockPos, adjData); + addBoundingBoxToBuffer(buffer, box); } } - private void generateBoundingBox(Box box, int height, int depth, int width, double xOffset, double yOffset, double zOffset, BlockPos bufferCenterBlockPos) + private void generateBoundingBox(Box box, int height, int depth, int width, double xOffset, double yOffset, double zOffset, BlockPos bufferCenterBlockPos, Map adjData) { // don't add an LOD if it is empty if (height == -1 && depth == -1) @@ -105,285 +98,30 @@ public class CubicLodTemplate extends AbstractLodTemplate // which only uses floats double x = -bufferCenterBlockPos.getX(); double z = -bufferCenterBlockPos.getZ(); + box.setAdjData(adjData); box.set(width, height - depth, width); box.move((int) (xOffset + x), (int) (yOffset + depth), (int) (zOffset + z)); } - private void addBoundingBoxToBuffer(BufferBuilder buffer, Box box, int c, BlockPos playerBlockPos, long[] adjData) + private void addBoundingBoxToBuffer(BufferBuilder buffer, Box box) { - int topColor = c; - int bottomColor = c; - int northColor = c; - int southColor = c; - int westColor = c; - int eastColor = c; - // darken the bottom and side colors if requested - if (LodConfig.CLIENT.graphics.shadingMode.get() == ShadingMode.DARKEN_SIDES) + for(Direction direction : Box.DIRECTIONS) { - // the side colors are different because - // when using fast lighting in Minecraft the north/south - // and east/west sides are different in a similar way - /**TODO OPTIMIZE THIS STEP*/ - Minecraft mc = Minecraft.getInstance(); - topColor = ColorUtil.applyShade(c, mc.level.getShade(Direction.UP, true)); - bottomColor = ColorUtil.applyShade(c, mc.level.getShade(Direction.DOWN, true)); - northColor = ColorUtil.applyShade(c, mc.level.getShade(Direction.NORTH, true)); - southColor = ColorUtil.applyShade(c, mc.level.getShade(Direction.SOUTH, true)); - westColor = ColorUtil.applyShade(c, mc.level.getShade(Direction.WEST, true)); - eastColor = ColorUtil.applyShade(c, mc.level.getShade(Direction.EAST, true)); - } - - // apply the user specified saturation and brightness - float saturationMultiplier = LodConfig.CLIENT.graphics.saturationMultiplier.get().floatValue(); - float brightnessMultiplier = LodConfig.CLIENT.graphics.brightnessMultiplier.get().floatValue(); - - if (saturationMultiplier != 1 || brightnessMultiplier != 1) - { - topColor = ColorUtil.applySaturationAndBrightnessMultipliers(topColor, saturationMultiplier, brightnessMultiplier); - bottomColor = ColorUtil.applySaturationAndBrightnessMultipliers(bottomColor, saturationMultiplier, brightnessMultiplier); - northColor = ColorUtil.applySaturationAndBrightnessMultipliers(northColor, saturationMultiplier, brightnessMultiplier); - southColor = ColorUtil.applySaturationAndBrightnessMultipliers(southColor, saturationMultiplier, brightnessMultiplier); - westColor = ColorUtil.applySaturationAndBrightnessMultipliers(westColor, saturationMultiplier, brightnessMultiplier); - eastColor = ColorUtil.applySaturationAndBrightnessMultipliers(eastColor, saturationMultiplier, brightnessMultiplier); - } - int minX; - int maxX; - int minY; - int maxY; - int minZ; - int maxZ; - long data; - int tempMinY; - int tempMaxY; - - int red; - int green; - int blue; - int alpha; - boolean disableCulling = true; - /**TODO make all of this more automatic if possible*/ - if (playerBlockPos.getY() > box.getMaxY() - CULL_OFFSET || disableCulling) - { - red = ColorUtil.getRed(topColor); - green = ColorUtil.getGreen(topColor); - blue = ColorUtil.getBlue(topColor); - alpha = ColorUtil.getAlpha(topColor); - // top (facing up) - minX = box.getMinX(); - maxX = box.getMaxX(); - minY = box.getMinY(); - maxY = box.getMaxY(); - minZ = box.getMinZ(); - maxZ = box.getMaxZ(); - addPosAndColor(buffer, minX, maxY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, maxY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, maxY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, maxY, minZ, red, green, blue, alpha); - } - if (playerBlockPos.getY() < box.getMinY() + CULL_OFFSET || disableCulling) - { - red = ColorUtil.getRed(bottomColor); - green = ColorUtil.getGreen(bottomColor); - blue = ColorUtil.getBlue(bottomColor); - alpha = ColorUtil.getAlpha(bottomColor); - // bottom (facing down) - minX = box.getMinX(); - maxX = box.getMaxX(); - minY = box.getMinY(); - maxY = box.getMaxY(); - minZ = box.getMinZ(); - maxZ = box.getMaxZ(); - addPosAndColor(buffer, maxX, minY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, minY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, minY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, minY, minZ, red, green, blue, alpha); - } - - if (playerBlockPos.getX() < box.getMaxX() + CULL_OFFSET || disableCulling) - { - red = ColorUtil.getRed(westColor); - green = ColorUtil.getGreen(westColor); - blue = ColorUtil.getBlue(westColor); - alpha = ColorUtil.getAlpha(westColor); - // west (facing -X) - data = adjData[0]; - - minX = box.getMinX(); - maxX = box.getMaxX(); - minY = box.getMinY(); - maxY = box.getMaxY(); - minZ = box.getMinZ(); - maxZ = box.getMaxZ(); - if (data == 0) + int adjIndex = 0; + while(box.shouldContinue(direction, adjIndex)) { - addPosAndColor(buffer, minX, minY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, minY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, maxY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, maxY, minZ, red, green, blue, alpha); - }else - { - maxY = box.getMaxY(); - tempMaxY = DataPointUtil.getHeight(data); - if (tempMaxY < maxY) + for (int vertexIndex = 0; vertexIndex < 4; vertexIndex++) { - minY = Math.max(tempMaxY, minY); - addPosAndColor(buffer, minX, minY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, minY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, maxY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, maxY, minZ, red, green, blue, alpha); - } - tempMinY = DataPointUtil.getDepth(data); - minY = box.getMinY(); - if (tempMinY > minY) - { - maxY = Math.min(tempMinY, maxY); - addPosAndColor(buffer, minX, minY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, minY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, maxY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, maxY, minZ, red, green, blue, alpha); + addPosAndColor(buffer, + box.getX(direction, vertexIndex), + box.getY(direction, vertexIndex, adjIndex), + box.getX(direction, vertexIndex), + box.getColor(direction)); } + adjIndex++; } } - - if (playerBlockPos.getX() > box.getMinX() - CULL_OFFSET || disableCulling) - { - red = ColorUtil.getRed(eastColor); - green = ColorUtil.getGreen(eastColor); - blue = ColorUtil.getBlue(eastColor); - alpha = ColorUtil.getAlpha(eastColor); - // east (facing +X) - data = adjData[1]; - minX = box.getMinX(); - maxX = box.getMaxX(); - minY = box.getMinY(); - maxY = box.getMaxY(); - minZ = box.getMinZ(); - maxZ = box.getMaxZ(); - if (data == 0) - { - addPosAndColor(buffer, maxX, maxY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, maxY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, minY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, minY, minZ, red, green, blue, alpha); - } - else - { - maxY = box.getMaxY(); - tempMaxY = DataPointUtil.getHeight(data); - if (tempMaxY < maxY) - { - minY = Math.max(tempMaxY, minY); - addPosAndColor(buffer, maxX, maxY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, maxY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, minY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, minY, minZ, red, green, blue, alpha); - } - tempMinY = DataPointUtil.getDepth(data); - minY = box.getMinY(); - if (tempMinY > minY) - { - maxY = Math.min(tempMinY, maxY); - addPosAndColor(buffer, maxX, maxY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, maxY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, minY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, minY, minZ, red, green, blue, alpha); - } - } - } - - if (playerBlockPos.getZ() > box.getMinZ() - CULL_OFFSET || disableCulling) - { - red = ColorUtil.getRed(northColor); - green = ColorUtil.getGreen(northColor); - blue = ColorUtil.getBlue(northColor); - alpha = ColorUtil.getAlpha(northColor); - data = adjData[3]; - minX = box.getMinX(); - maxX = box.getMaxX(); - minY = box.getMinY(); - maxY = box.getMaxY(); - minZ = box.getMinZ(); - maxZ = box.getMaxZ(); - // north (facing +Z) - if (data == 0) - { - addPosAndColor(buffer, maxX, minY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, maxY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, maxY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, minY, maxZ, red, green, blue, alpha); - } - else - { - maxY = box.getMaxY(); - tempMaxY = DataPointUtil.getHeight(data); - if (tempMaxY < maxY) - { - minY = Math.max(tempMaxY, minY); - addPosAndColor(buffer, maxX, minY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, maxY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, maxY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, minY, maxZ, red, green, blue, alpha); - } - tempMinY = DataPointUtil.getDepth(data); - minY = box.getMinY(); - if (tempMinY > minY) - { - maxY = Math.min(tempMinY, maxY); - addPosAndColor(buffer, maxX, minY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, maxY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, maxY, maxZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, minY, maxZ, red, green, blue, alpha); - } - } - } - - if (playerBlockPos.getZ() < box.getMaxZ() + CULL_OFFSET || disableCulling) - { - red = ColorUtil.getRed(southColor); - green = ColorUtil.getGreen(southColor); - blue = ColorUtil.getBlue(southColor); - alpha = ColorUtil.getAlpha(southColor); - data = adjData[2]; - minX = box.getMinX(); - maxX = box.getMaxX(); - minY = box.getMinY(); - maxY = box.getMaxY(); - minZ = box.getMinZ(); - maxZ = box.getMaxZ(); - // south (facing -Z) - if (data == 0) - { - addPosAndColor(buffer, minX, minY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, maxY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, maxY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, minY, minZ, red, green, blue, alpha); - } - else - { - maxY = box.getMaxY(); - tempMaxY = DataPointUtil.getHeight(data); - if (tempMaxY < maxY) - { - minY = Math.max(tempMaxY, minY); - addPosAndColor(buffer, minX, minY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, maxY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, maxY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, minY, minZ, red, green, blue, alpha); - } - tempMinY = DataPointUtil.getDepth(data); - minY = box.getMinY(); - if (tempMinY > minY) - { - maxY = Math.min(tempMinY, maxY); - addPosAndColor(buffer, minX, minY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, minX, maxY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, maxY, minZ, red, green, blue, alpha); - addPosAndColor(buffer, maxX, minY, minZ, red, green, blue, alpha); - } - } - } - } @Override diff --git a/src/main/java/com/seibel/lod/builders/lodTemplates/DynamicLodTemplate.java b/src/main/java/com/seibel/lod/builders/lodTemplates/DynamicLodTemplate.java index a0d6460b8..da3740cea 100644 --- a/src/main/java/com/seibel/lod/builders/lodTemplates/DynamicLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/lodTemplates/DynamicLodTemplate.java @@ -21,9 +21,12 @@ import com.seibel.lod.enums.DebugMode; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.texture.NativeImage; +import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.DimensionType; +import java.util.Map; + /** * TODO DynamicLodTemplate * Chunks smoothly transition between @@ -36,7 +39,7 @@ import net.minecraft.world.DimensionType; public class DynamicLodTemplate extends AbstractLodTemplate { @Override - public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, long[] adjData, + public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map adjData, byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap) { System.err.println("DynamicLodTemplate not implemented!"); diff --git a/src/main/java/com/seibel/lod/builders/lodTemplates/TriangularLodTemplate.java b/src/main/java/com/seibel/lod/builders/lodTemplates/TriangularLodTemplate.java index 2adebf3d7..ba2f1e947 100644 --- a/src/main/java/com/seibel/lod/builders/lodTemplates/TriangularLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/lodTemplates/TriangularLodTemplate.java @@ -21,9 +21,12 @@ import com.seibel.lod.enums.DebugMode; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.texture.NativeImage; +import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.DimensionType; +import java.util.Map; + /** * TODO #21 TriangularLodTemplate * Builds each LOD chunk as a singular rectangular prism. @@ -34,7 +37,7 @@ import net.minecraft.world.DimensionType; public class TriangularLodTemplate extends AbstractLodTemplate { @Override - public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, long[] adjData, + public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map adjData, byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap) { System.err.println("DynamicLodTemplate not implemented!"); diff --git a/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java b/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java index 6c91f1dcc..6e88cd484 100644 --- a/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java +++ b/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java @@ -110,7 +110,7 @@ public class VerticalLevelContainer implements LevelContainer dataToMerge[2*z + x] = lowerLevelContainer.getData(childPosX, childPosZ); } } - data = DataPointUtil.mergeVerticalData(dataToMerge); + data = DataPointUtil.mergeMultiData(dataToMerge); addData(data,posX,posZ); } diff --git a/src/main/java/com/seibel/lod/util/DataPointUtil.java b/src/main/java/com/seibel/lod/util/DataPointUtil.java index be7ed8f59..e42aba465 100644 --- a/src/main/java/com/seibel/lod/util/DataPointUtil.java +++ b/src/main/java/com/seibel/lod/util/DataPointUtil.java @@ -281,7 +281,7 @@ public class DataPointUtil } } - public static long[] mergeVerticalData(long[][] dataToMerge) + public static long[] mergeMultiData(long[][] dataToMerge) { boolean[] projection = ThreadMapUtil.getProjection(WORLD_HEIGHT + 1); int[][] heightAndDepth = ThreadMapUtil.getHeightAndDepth(WORLD_HEIGHT + 1);