diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java index ce393d0ea..bd2cd397d 100644 --- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java @@ -116,11 +116,12 @@ public class LodBufferBuilder private volatile PosToRenderContainer[][] setsToRender; private volatile RegionPos center; - /** This is the ChunkPos the player was at the last time the buffers were built. - * IE the center of the buffers last time they were built */ - private volatile ChunkPos drawableCenterChunkPos = new ChunkPos(0,0); - private volatile ChunkPos buildableCenterChunkPos = new ChunkPos(0,0); - + /** + * This is the ChunkPos the player was at the last time the buffers were built. + * IE the center of the buffers last time they were built + */ + private volatile ChunkPos drawableCenterChunkPos = new ChunkPos(0, 0); + private volatile ChunkPos buildableCenterChunkPos = new ChunkPos(0, 0); public LodBufferBuilder() @@ -250,8 +251,9 @@ public class LodBufferBuilder int chunkXdist; int chunkZdist; short gameChunkRenderDistance = (short) (renderer.vanillaRenderedChunks.length / 2 - 1); - long dataPoint; + //long dataPoint; long[] adjData = new long[NUMBER_OF_DIRECTION]; + for (int index = 0; index < posToRender.getNumberOfPos(); index++) { detailLevel = posToRender.getNthDetailLevel(index); @@ -270,39 +272,44 @@ public class LodBufferBuilder // skip any chunks that Minecraft is going to render try { - if (lodDim.doesDataExist(detailLevel, posX, posZ)) + //dataPoint = lodDim.getData(detailLevel, posX, posZ)[0]; + for(long dataPoint : lodDim.getData(detailLevel, posX, posZ)) { - dataPoint = lodDim.getData(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 (!DataPointUtil.isItVoid(dataPoint) && DataPointUtil.doesItExist(dataPoint)) + { + /* + for (int direction = 0; direction < NUMBER_OF_DIRECTION; direction++) { - if (!renderer.vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance + 1][chunkZdist + gameChunkRenderDistance + 1] - && posToRender.contains(detailLevel, xAdj, zAdj)) + 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)) { - adjData[direction]= lodDim.getData(detailLevel, xAdj, zAdj); - }else{ - adjData[direction]= 0; - } - } else - { - if (posToRender.contains(detailLevel, xAdj, zAdj)) + if (!renderer.vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance + 1][chunkZdist + gameChunkRenderDistance + 1] + && posToRender.contains(detailLevel, xAdj, zAdj)) + { + adjData[direction] = lodDim.getData(detailLevel, xAdj, zAdj)[0]; + } else + { + adjData[direction] = 0; + } + } else { - adjData[direction] = lodDim.getData(detailLevel, xAdj, zAdj); - }else{ - adjData[direction]= 0; + if (posToRender.contains(detailLevel, xAdj, zAdj)) + { + adjData[direction] = lodDim.getData(detailLevel, xAdj, zAdj)[0]; + } else + { + adjData[direction] = 0; + } } - } + }*/ + LodConfig.CLIENT.graphics.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPosRounded, dataPoint, adjData, + detailLevel, posX, posZ, boxCache[xR][zR], renderer.previousDebugMode); } - LodConfig.CLIENT.graphics.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPosRounded, dataPoint, adjData, - detailLevel, posX, posZ, boxCache[xR][zR],renderer.previousDebugMode); } } catch (ArrayIndexOutOfBoundsException e) { @@ -477,7 +484,6 @@ public class LodBufferBuilder } - /** * Get the newly created VBOs */ @@ -500,6 +506,7 @@ public class LodBufferBuilder return new VertexBuffersAndOffset(drawableVbos, drawableCenterChunkPos); } + /** * A simple container to pass multiple objects back in the getVertexBuffers method. */ diff --git a/src/main/java/com/seibel/lod/builders/LodBuilder.java b/src/main/java/com/seibel/lod/builders/LodBuilder.java index 8af31d10b..5d1326735 100644 --- a/src/main/java/com/seibel/lod/builders/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBuilder.java @@ -167,7 +167,6 @@ public class LodBuilder byte light; short height; short depth; - long data; try { LodDetail detail; @@ -187,41 +186,100 @@ public class LodBuilder endX = detail.endX[i]; endZ = detail.endZ[i]; - /* - color = generateLodColorForArea(chunk, config, startX, startZ, endX, endZ); - light = generateLodLightForArea(chunk, config, startX, startZ, endX, endZ); - - if (!config.useHeightmap) - { - height = determineHeightPointForArea(chunk.getSections(), startX, startZ, endX, endZ); - depth = determineBottomPointForArea(chunk.getSections(), startX, startZ, endX, endZ); - } else - { - height = determineHeightPoint(chunk.getOrCreateHeightmapUnprimed(LodUtil.DEFAULT_HEIGHTMAP), startX, - startZ, endX, endZ); - depth = 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); - long[] dataToMerge = createSingleDataToMerge(detail, chunk, config, startX, startZ, endX, endZ); - boolean isServer = config.distanceGenerationMode == DistanceGenerationMode.SERVER; - data = DataPointUtil.mergeSingleData(dataToMerge); - lodDim.addData(detailLevel, - posX, - posZ, - data, - false, - isServer); + long[] data; + long[] dataToMerge; + //data = ThreadMapUtil.getSingleAddDataArray(); + dataToMerge = createSingleDataToMerge(detail, chunk, config, startX, startZ, endX, endZ); + + try + { + long[][] dataToMerge2 = new long[dataToMerge.length][]; + for (int index = 0; index < dataToMerge.length; index++) + { + dataToMerge2[index] = new long[]{dataToMerge[index]}; + } + //data[0] = DataPointUtil.mergeSingleData(dataToMerge); + + //dataToMerge = createVerticalDataToMerge(detail, chunk, config, startX, startZ, endX, endZ); + data = DataPointUtil.mergeVerticalData(dataToMerge2); + + boolean isServer = config.distanceGenerationMode == DistanceGenerationMode.SERVER; + lodDim.addData(detailLevel, + posX, + posZ, + data, + false, + isServer); + }catch (Exception e) + { + e.printStackTrace(); + throw e; + } } lodDim.updateData(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z); } catch (Exception e) { e.printStackTrace(); - throw e; } } + /*private long[][] createVerticalDataToMerge(LodDetail detail, IChunk chunk, LodBuilderConfig config, int startX, int startZ, int endX, int endZ) + { + long[][] dataToMerge = ThreadMapUtil.getBuilderVerticalArray()[detail.detailLevel]; + ChunkPos chunkPos = chunk.getPos(); + + int size = 1 << detail.detailLevel; + int height = 0; + int depth = 0; + int color = 0; + int light = 0; + int generation = config.distanceGenerationMode.complexity; + + int xRel; + int zRel; + int xAbs; + int yAbs; + int zAbs; + + BlockPos.Mutable blockPos = new BlockPos.Mutable(0, 0, 0); + int index = 0; + if (dataToMerge == null) + { + dataToMerge = new long[size * size][256]; + } + for (index = 0; index < size * size; index++) + { + xRel = Math.floorMod(index, size) + startX; + zRel = Math.floorDiv(index, size) + startZ; + xAbs = chunkPos.getMinBlockX() + xRel; + zAbs = chunkPos.getMinBlockZ() + zRel; + + //Calculate the height of the lod + height = determineHeightPoint(chunk, config, xRel, zRel); + + //If the lod is at default, then we set this as void data + if (height == DEFAULT_HEIGHT) + { + dataToMerge[index] = DataPointUtil.createVoidDataPoint(generation); + continue; + } + + yAbs = height - 1; + // We search light on above air block + blockPos.set(xAbs, yAbs + 1, zAbs); + + color = generateLodColor(chunk, config, xRel, yAbs, zRel); + light = getLightBlockValue(chunk, blockPos); + depth = determineBottomPoint(chunk, config, xRel, zRel); + + dataToMerge[index] = DataPointUtil.createDataPoint(height, depth, color, light, generation); + } + return dataToMerge; + }*/ + private long[] createSingleDataToMerge(LodDetail detail, IChunk chunk, LodBuilderConfig config, int startX, int startZ, int endX, int endZ) { long[] dataToMerge = ThreadMapUtil.getBuilderArray()[detail.detailLevel]; diff --git a/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java b/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java index 2a6385a41..0df076916 100644 --- a/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java +++ b/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java @@ -28,10 +28,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import com.seibel.lod.enums.DistanceGenerationMode; -import com.seibel.lod.objects.SingleLevelContainer; -import com.seibel.lod.objects.LodDimension; -import com.seibel.lod.objects.LodRegion; -import com.seibel.lod.objects.RegionPos; +import com.seibel.lod.objects.*; import com.seibel.lod.proxy.ClientProxy; import com.seibel.lod.util.LodThreadFactory; import com.seibel.lod.util.LodUtil; @@ -195,7 +192,8 @@ public class LodDimensionFileHandler data = bufferedReader.readLine(); bufferedReader.close(); - region.addLevel(new SingleLevelContainer(data)); + //region.addLevel(new SingleLevelContainer(data)); + region.addLevel(new VerticalLevelContainer(data)); } catch (Exception e) { // the buffered reader encountered a diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index 4b1db5d6f..127d541f7 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -433,7 +433,7 @@ public class LodDimension * stored in the LOD. If an LOD already exists at the given * coordinates it will be overwritten. */ - public Boolean addData(byte detailLevel, int posX, int posZ, long lodDataPoint, boolean dontSave, boolean serverQuality) + public Boolean addData(byte detailLevel, int posX, int posZ, long[] dataPoint, boolean dontSave, boolean serverQuality) { // don't continue if the region can't be saved @@ -443,9 +443,7 @@ public class LodDimension LodRegion region = getRegion(regionPosX, regionPosZ); if (region == null) return false; - long[] dataArray = ThreadMapUtil.getSingleAddDataArray(); - dataArray[0] = lodDataPoint; - boolean nodeAdded = region.addData(detailLevel, posX, posZ, dataArray, serverQuality); + boolean nodeAdded = region.addData(detailLevel, posX, posZ, dataPoint, serverQuality); // only save valid LODs to disk if (!dontSave && fileHandler != null) { @@ -520,7 +518,7 @@ public class LodDimension * Returns null if the LodChunk doesn't exist or * is outside the loaded area. */ - public long getData(byte detailLevel, int posX, int posZ) + public long[] getData(byte detailLevel, int posX, int posZ) { if (detailLevel > LodUtil.REGION_DETAIL_LEVEL) throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max."); @@ -529,10 +527,10 @@ public class LodDimension if (region == null) { - return 0; + return new long[]{DataPointUtil.EMPTY_DATA}; } - return region.getData(detailLevel, posX, posZ)[0]; + return region.getData(detailLevel, posX, posZ); } diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java index 29f5ed7a9..b21efdd06 100644 --- a/src/main/java/com/seibel/lod/objects/LodRegion.java +++ b/src/main/java/com/seibel/lod/objects/LodRegion.java @@ -55,7 +55,8 @@ public class LodRegion //Initialize all the different matrices for (byte lod = minDetailLevel; lod <= LodUtil.REGION_DETAIL_LEVEL; lod++) { - dataContainer[lod] = new SingleLevelContainer(lod); + //dataContainer[lod] = new SingleLevelContainer(lod); + dataContainer[lod] = new VerticalLevelContainer(lod); /*if(twoDimension){ dataContainer[lod] = new SingleLevelContainer(lod); }else{ diff --git a/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java b/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java index 1c26730d6..f8a96d9a2 100644 --- a/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java +++ b/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java @@ -1,8 +1,11 @@ package com.seibel.lod.objects; -/* + import com.seibel.lod.util.DataPointUtil; import com.seibel.lod.util.LevelPosUtil; import com.seibel.lod.util.LodUtil; +import com.seibel.lod.util.ThreadMapUtil; + +import java.security.InvalidParameterException; public class VerticalLevelContainer implements LevelContainer { @@ -15,13 +18,7 @@ public class VerticalLevelContainer implements LevelContainer { this.detailLevel = detailLevel; int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel); - dataContainer = new long[size][size][]; - } - - public VerticalLevelContainer(byte detailLevel, long[][][] data) - { - this.detailLevel = detailLevel; - this.dataContainer = data; + dataContainer = new long[size][size][1]; } @Override @@ -45,12 +42,15 @@ public class VerticalLevelContainer implements LevelContainer public boolean doesItExist(int posX, int posZ){ long[] data = getData(posX,posZ); - return (data != null && DataPointUtil.doesItExist(data[0])); + return DataPointUtil.doesItExist(data[0]); } public VerticalLevelContainer(String inputString) { + throw new InvalidParameterException("loading not yet implemented"); + +/* int index = 0; int lastIndex = 0; @@ -68,25 +68,21 @@ public class VerticalLevelContainer implements LevelContainer index = inputString.indexOf(DATA_DELIMITER, lastIndex + 1); dataContainer[x][z][0] = Long.parseLong(inputString.substring(lastIndex + 1, index), 16); } - } + }*/ } public LevelContainer expand(){ - return new SingleLevelContainer((byte) (getDetailLevel() - 1)); + return new VerticalLevelContainer((byte) (getDetailLevel() - 1)); } public void updateData(LevelContainer lowerLevelContainer, int posX, int posZ) { //We reset the array - if(!LevelContainer.threadGetDataMap.containsKey(Thread.currentThread().getName()) || (LevelContainer.threadGetDataMap.get(Thread.currentThread().getName()) == null)) - { - LevelContainer.threadGetDataMap.put(Thread.currentThread().getName(), new long[4]); - } - long[] dataToMerge = LevelContainer.threadGetDataMap.get(Thread.currentThread().getName()); + long[][] dataToMerge = ThreadMapUtil.getVerticalUpdateArray(); int childPosX; int childPosZ; - long data = 0; + long[] data; posX = LevelPosUtil.getRegionModule(detailLevel, posX); posZ = LevelPosUtil.getRegionModule(detailLevel, posZ); for (int x = 0; x <= 1; x++) @@ -95,99 +91,13 @@ public class VerticalLevelContainer implements LevelContainer { childPosX = 2 * posX + x; childPosZ = 2 * posZ + z; - dataToMerge[2*z + x] = lowerLevelContainer.getData(childPosX, childPosZ)[0]; + dataToMerge[2*z + x] = lowerLevelContainer.getData(childPosX, childPosZ); } } - data = DataPointUtil.mergeSingleData(dataToMerge); + data = DataPointUtil.mergeVerticalData(dataToMerge); addData(data,posX,posZ); } - public void updateData(LevelContainer lowerLevelContainer, int posX, int posZ) - { - long[][][] updateTemps; - int[] indexes; - if(!LevelContainer.threadVerticalUpdateMap.containsKey(Thread.currentThread().getName()) || (LevelContainer.threadVerticalUpdateMap.get(Thread.currentThread().getName()) == null)) - { - //To avoid the creation of multiple - updateTemps = new long[4][][]; - updateTemps[0] = new long[4][16]; - updateTemps[1] = new long[1][32]; - updateTemps[2] = new long[1][4]; - updateTemps[3] = new long[1][4]; - LevelContainer.threadVerticalUpdateMap.put(Thread.currentThread().getName(), updateTemps); - } - if(!LevelContainer.threadVerticalIndexesMap.containsKey(Thread.currentThread().getName()) || (LevelContainer.threadVerticalIndexesMap.get(Thread.currentThread().getName()) == null)) - { - //To avoid the creation of multiple - indexes = new int[4]; - LevelContainer.threadVerticalIndexesMap.put(Thread.currentThread().getName(), updateTemps); - } - - updateTemps = LevelContainer.threadVerticalIndexesMap.get(Thread.currentThread().getName()); - - long[][] dataArray = updateTemps[0]; - long[] newDataPoint = updateTemps[1][1]; - long[] indexes = updateTemps[2][1]; - long[] dataToCombine = updateTemps[3][1]; - //int maxSize = Math.max(Math.max(Math.max(dataArray[0].length, dataArray[1].length), dataArray[2].length), dataArray[3].length); - //DetailDistanceUtil.getMaxVerticalData(detailLevel); - //we are re-using these arrays so we must reset them to 0 - int dataIndex = 0; - int i; - for (i = 0; i < newDataPoint.length; i++) - newDataPoint[i] = 0; - for (i = 0; i < 4; i++) - indexes[i] = 0; - //We continue until all the data has been read - int minDepth; - int maxHeight; - int selectedDepth; - int selectedHeight; - int startingArray; - while (indexes[0] < dataArray[0].length - && indexes[1] < dataArray[1].length - && indexes[2] < dataArray[2].length - && indexes[3] < dataArray[3].length) - { - //We select the data that at the lowest point - minDepth = Integer.MAX_VALUE; - maxHeight = Integer.MIN_VALUE; - startingArray = 0; - for (int arrayIndex = 0; arrayIndex < 4; arrayIndex++) - { - if (indexes[arrayIndex] < dataArray[arrayIndex].length) - { - if (minDepth < DataPointUtil.getDepth(dataArray[arrayIndex][indexes[arrayIndex]])) - { - minDepth = DataPointUtil.getDepth(dataArray[arrayIndex][indexes[arrayIndex]]); - startingArray = arrayIndex; - } - } - } - selectedDepth = minDepth; - //now we have selected the dataPoint that has yet to be analyzed with min depth - dataToCombine[startingArray] = dataArray[startingArray][indexes[startingArray]]; - indexes[startingArray]++; - newDataPoint[dataIndex] = minDepth; - - //now we must check if the other data can be combined with this lod - maxHeight = DataPointUtil.getHeight(dataArray[startingArray][indexes[startingArray]]); - - for (int arrayIndex = 0; arrayIndex < 4; arrayIndex++) - { - while (maxHeight >= getDepth(dataArray[arrayIndex][indexes[arrayIndex]])) - { - maxHeight = getHeight(dataArray[arrayIndex][indexes[arrayIndex]]); - dataToCombine[arrayIndex] = dataArray[arrayIndex][indexes[arrayIndex]]; - indexes[arrayIndex]++; - } - } - dataIndex++; - - } - return null; - } - public String toDataString() { return toString(); @@ -196,6 +106,7 @@ public class VerticalLevelContainer implements LevelContainer @Override public String toString() { + /* StringBuilder stringBuilder = new StringBuilder(); int size = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel); stringBuilder.append(detailLevel); @@ -210,5 +121,7 @@ public class VerticalLevelContainer implements LevelContainer } } return stringBuilder.toString(); + */ + return " "; } -}*/ +} diff --git a/src/main/java/com/seibel/lod/util/DataPointUtil.java b/src/main/java/com/seibel/lod/util/DataPointUtil.java index e59e761b0..d946ffe00 100644 --- a/src/main/java/com/seibel/lod/util/DataPointUtil.java +++ b/src/main/java/com/seibel/lod/util/DataPointUtil.java @@ -13,6 +13,7 @@ public class DataPointUtil //public final static int MIN_DEPTH = -64; //public final static int MIN_HEIGHT = -64; public final static int EMPTY_DATA = 0; + public final static int WORLD_HEIGHT = 256; public final static int ALPHA_SHIFT = 56; public final static int RED_SHIFT = 48; @@ -216,6 +217,104 @@ public class DataPointUtil } } + public static long[] mergeVerticalData(long[][] dataToMerge) + { + boolean[] projection = new boolean[WORLD_HEIGHT + 1]; + int size = 0; + + int genMode = DistanceGenerationMode.SERVER.complexity; + boolean allEmpty = true; + boolean allVoid = true; + long singleData; + + int depth = 0; + int height = 0; + //We collect the indexes of the data, ordered by the depth + for (int index = 0; index < dataToMerge.length; index++) + { + for (int dataIndex = 0; dataIndex < dataToMerge[index].length; dataIndex++) + { + singleData = dataToMerge[index][dataIndex]; + if (doesItExist(singleData)) + { + genMode = Math.min(genMode, getGenerationMode(singleData)); + allEmpty = false; + if (!isItVoid(singleData)) + { + allVoid = false; + depth = getDepth(singleData); + height = getHeight(singleData); + for (int y = depth; y <= height; y++) + { + projection[y] = true; + } + } + } + } + } + + + //We check if there is any data that's not empty or void + if (allEmpty) + { + return new long[]{EMPTY_DATA}; + } + if (allVoid) + { + return new long[]{createVoidDataPoint(genMode)}; + } + + int count = 0; + int i = 0; + int[][] heightAndDepth = new int[projection.length][2]; + while (i < projection.length) + { + while (i < projection.length && !projection[i]) + { + i++; + } + depth = i; + while (i < projection.length && projection[i]) + { + height = i; + i++; + } + if(!(i < projection.length)) + break; + heightAndDepth[count][0] = depth; + heightAndDepth[count][1] = height; + count++; + } + //As standard the vertical lods are ordered from top to bottom + long[] dataPoint = new long[count]; + for (int j = count - 1; j >= 0; j--) + { + depth = heightAndDepth[j][0]; + height = heightAndDepth[j][1]; + long[] singleDataToMerge = new long[dataToMerge.length]; + for (int index = 0; index < dataToMerge.length; index++) + { + for (int dataIndex = 0; dataIndex < dataToMerge[index].length; dataIndex++) + { + singleData = dataToMerge[index][dataIndex]; + if (doesItExist(singleData) && !isItVoid(singleData)) + { + if ((depth <= getDepth(singleData) && getDepth(singleData) <= height) + || (depth <= getHeight(singleData) && getHeight(singleData) <= height)) + { + singleDataToMerge[dataIndex] = singleData; + break; + } + } + } + } + long data = mergeSingleData(singleDataToMerge); + dataPoint[j] = createDataPoint(height, depth, getColor(data), getLightValue(data), getGenerationMode(data)); + } + + return dataPoint; + } + /* public static long[] mergeVerticalData(long[][] dataToMerge) { int[][] dataCollector = new int[256][2]; @@ -230,7 +329,7 @@ public class DataPointUtil //We collect the indexes of the data, ordered by the depth for (int index = 0; index < dataToMerge.length; index++) { - for (int dataIndex = 0; dataIndex < dataToMerge.length; dataIndex++) + for (int dataIndex = 0; dataIndex < dataToMerge[index].length; dataIndex++) { singleData = dataToMerge[index][dataIndex]; if (doesItExist(singleData)) @@ -246,11 +345,12 @@ public class DataPointUtil dataCollector[j] = dataCollector[j - 1]; j = j - 1; } - dataCollector[j][0] = dataIndex; - dataCollector[j][1] = index; + dataCollector[j][0] = index; + dataCollector[j][1] = dataIndex; size++; } } + } } @@ -273,7 +373,7 @@ public class DataPointUtil int index = 0; int dataCount = 0; long[] singleDataToMerge = new long[dataToMerge.length]; - long[] newData = new long[dataToMerge.length]; + long[] newData = new long[256]; while (index < size) { dataCount++; @@ -281,17 +381,21 @@ public class DataPointUtil minDepth = getDepth(singleData); maxHeight = getHeight(singleData); index++; - while(index < size) + while (index < size) { - singleData = dataToMerge[dataCollector[index][0]][dataCollector[index][1]]; + if(dataCollector[index][1] >= dataToMerge[dataCollector[index][0]].length) + singleData = EMPTY_DATA; + else + singleData = dataToMerge[dataCollector[index][0]][dataCollector[index][1]]; tempDepth = getDepth(singleData); tempHeight = getHeight(singleData); - if(maxHeight >= tempDepth) + if (maxHeight >= tempDepth) { singleDataToMerge[dataCollector[index][0]] = singleData; maxHeight = tempHeight; index++; - }else{ + } else + { break; } } @@ -299,7 +403,7 @@ public class DataPointUtil newData[dataCount] = createDataPoint(maxHeight, minDepth, getColor(singleData), getLightValue(singleData), getGenerationMode(singleData)); } return Arrays.copyOf(newData, dataCount); - } + }*/ public static long[] compress(long[] data, byte detailLevel) { diff --git a/src/main/java/com/seibel/lod/util/LodUtil.java b/src/main/java/com/seibel/lod/util/LodUtil.java index fc6f02ea1..b6b881c3f 100644 --- a/src/main/java/com/seibel/lod/util/LodUtil.java +++ b/src/main/java/com/seibel/lod/util/LodUtil.java @@ -337,7 +337,8 @@ public class LodUtil if (!lodDim.doesDataExist(LodUtil.CHUNK_DETAIL_LEVEL, x, z)) continue; - long data = lodDim.getData(LodUtil.CHUNK_DETAIL_LEVEL, x, z); + long[] dataVertical = lodDim.getData(LodUtil.CHUNK_DETAIL_LEVEL, x, z); + long data = dataVertical[dataVertical.length - 1]; short lodAverageHeight = DataPointUtil.getHeight(data); diff --git a/src/main/java/com/seibel/lod/util/ThreadMapUtil.java b/src/main/java/com/seibel/lod/util/ThreadMapUtil.java index 4bf2613e7..6b9588bae 100644 --- a/src/main/java/com/seibel/lod/util/ThreadMapUtil.java +++ b/src/main/java/com/seibel/lod/util/ThreadMapUtil.java @@ -11,9 +11,10 @@ public class ThreadMapUtil public static final ConcurrentMap threadSingleGetDataMap = new ConcurrentHashMap(); public static final ConcurrentMap threadSingleUpdateMap = new ConcurrentHashMap(); public static final ConcurrentMap threadBuilderArrayMap = new ConcurrentHashMap(); + public static final ConcurrentMap threadBuilderVerticalArrayMap = new ConcurrentHashMap(); public static final ConcurrentMap threadVerticalAddDataMap = new ConcurrentHashMap(); public static final ConcurrentMap threadVerticalGetDataMap = new ConcurrentHashMap(); - public static final ConcurrentMap threadVerticalUpdateMap = new ConcurrentHashMap(); + public static final ConcurrentMap threadVerticalUpdateMap = new ConcurrentHashMap(); public static final ConcurrentMap threadVerticalIndexesMap = new ConcurrentHashMap(); @@ -50,6 +51,14 @@ public class ThreadMapUtil return threadBuilderArrayMap.get(Thread.currentThread().getName()); } + public static long[][][] getBuilderVerticalArray(){ + if(!threadBuilderVerticalArrayMap.containsKey(Thread.currentThread().getName()) || (threadBuilderVerticalArrayMap.get(Thread.currentThread().getName()) == null)) + { + long[][][] array = new long[5][][]; + threadBuilderVerticalArrayMap.put(Thread.currentThread().getName(), array); + } + return threadBuilderVerticalArrayMap.get(Thread.currentThread().getName()); + } public static long[] addVerticalDataArray(){ if(!threadVerticalAddDataMap.containsKey(Thread.currentThread().getName()) || (threadVerticalAddDataMap.get(Thread.currentThread().getName()) == null)) @@ -67,10 +76,10 @@ public class ThreadMapUtil return threadVerticalGetDataMap.get(Thread.currentThread().getName()); } - public static long[][][] getVerticalUpdateArray(){ + public static long[][] getVerticalUpdateArray(){ if(!threadVerticalUpdateMap.containsKey(Thread.currentThread().getName()) || (threadVerticalUpdateMap.get(Thread.currentThread().getName()) == null)) { - threadVerticalUpdateMap.put(Thread.currentThread().getName(), new long[4][4][16]); + threadVerticalUpdateMap.put(Thread.currentThread().getName(), new long[4][]); } return threadVerticalUpdateMap.get(Thread.currentThread().getName()); }