diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java index bfa68103d..4dae5a94d 100644 --- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java @@ -374,7 +374,7 @@ public class LodBufferBuilder for (int verticalIndex = 0; verticalIndex < lodDim.getMaxVerticalData(detailLevel, posX, posZ); verticalIndex++) { data = lodDim.getData(detailLevel, posX, posZ, verticalIndex); - if (DataPointUtil.isItVoid(data) || DataPointUtil.doesItExist(data)) + if (DataPointUtil.isItVoid(data) || !DataPointUtil.doesItExist(data)) break; LodConfig.CLIENT.graphics.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPosRounded, data, adjData, detailLevel, posX, posZ, boxCache[xR][zR], renderer.previousDebugMode, renderer.lightMap); diff --git a/src/main/java/com/seibel/lod/builders/LodBuilder.java b/src/main/java/com/seibel/lod/builders/LodBuilder.java index 112d0dc25..6d6b9682d 100644 --- a/src/main/java/com/seibel/lod/builders/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBuilder.java @@ -241,13 +241,13 @@ public class LodBuilder case MULTI_LOD: long[] dataToMergeVertical; dataToMergeVertical = createVerticalDataToMerge(detail, chunk, config, startX, startZ, endX, endZ); - data = DataPointUtil.mergeMultiData(dataToMergeVertical, detailLevel); + data = DataPointUtil.mergeMultiData(dataToMergeVertical, DataPointUtil.WORLD_HEIGHT, DetailDistanceUtil.getMaxVerticalData(detailLevel)); if (data.length == 0 || data == null) data = new long[]{DataPointUtil.EMPTY_DATA}; //lodDim.clear(detailLevel, posX, posZ); for (int verticalIndex = 0; (verticalIndex < data.length) && (verticalIndex < lodDim.getMaxVerticalData(detailLevel, posX, posZ)); verticalIndex++) { - lodDim.addData(detailLevel, + boolean test = lodDim.addData(detailLevel, posX, posZ, verticalIndex, @@ -258,7 +258,6 @@ public class LodBuilder posX, posZ, verticalIndex); - System.out.println(DataPointUtil.toString(dataTest)); } break; @@ -267,6 +266,10 @@ public class LodBuilder } lodDim.updateData(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z); + long dataTest = lodDim.getData(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z, 0); + long dataTest2 = lodDim.getData(LodUtil.REGION_DETAIL_LEVEL, chunk.getPos().getRegionX(), chunk.getPos().getRegionZ(), 0); + /*System.out.println(LodUtil.CHUNK_DETAIL_LEVEL + " " + chunk.getPos().x + " " + chunk.getPos().z + " " + 0 + " " +DataPointUtil.toString(dataTest)); + System.out.println(LodUtil.REGION_DETAIL_LEVEL + " " + chunk.getPos().getRegionX() + " " + chunk.getPos().getRegionZ() + " " + 0 + " " +DataPointUtil.toString(dataTest2));*/ } catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java b/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java index 3fc830779..b89f51aa4 100644 --- a/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java +++ b/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java @@ -3,6 +3,7 @@ package com.seibel.lod.objects; import com.seibel.lod.util.*; import java.security.InvalidParameterException; +import java.util.Arrays; public class VerticalLevelContainer implements LevelContainer { @@ -31,10 +32,8 @@ public class VerticalLevelContainer implements LevelContainer posX = LevelPosUtil.getRegionModule(detailLevel, posX); posZ = LevelPosUtil.getRegionModule(detailLevel, posZ); - int index = 0; - for(int i = 0; i < maxVerticalData; i++){ - index = posX*size*maxVerticalData + posZ*maxVerticalData + i; - dataContainer[index] = DataPointUtil.EMPTY_DATA; + for(int verticalIndex = 0; verticalIndex < maxVerticalData; verticalIndex++){ + dataContainer[posX*size*maxVerticalData + posZ*maxVerticalData + verticalIndex] = DataPointUtil.EMPTY_DATA; } } @@ -74,30 +73,37 @@ public class VerticalLevelContainer implements LevelContainer return DataPointUtil.doesItExist(getSingleData(posX,posZ)); } - public VerticalLevelContainer(String inputString) + public VerticalLevelContainer(byte inputData[]) { - - throw new InvalidParameterException("loading not yet implemented"); - -/* + int tempIndex; int index = 0; - int lastIndex = 0; - - - index = inputString.indexOf(DATA_DELIMITER, 0); - this.detailLevel = (byte) Integer.parseInt(inputString.substring(0, index)); - int size = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel); - - this.dataContainer = new long[size][size][1]; - for (int x = 0; x < size; x++) + long newData; + detailLevel = inputData[index]; + index++; + maxVerticalData = inputData[index]; + index++; + size = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel); + this.dataContainer = new long[size * size * maxVerticalData]; + int x, y, z = 0; + for (x = 0; x < size; x++) { - for (int z = 0; z < size; z++) + for (z = 0; z < size; z++) { - lastIndex = index; - index = inputString.indexOf(DATA_DELIMITER, lastIndex + 1); - dataContainer[x][z][0] = Long.parseLong(inputString.substring(lastIndex + 1, index), 16); + for (y = 0; y < maxVerticalData; y++) { + newData = 0; + if (inputData[index] == 0) + index++; + else if (index + 7 >= inputData.length) + break; + else { + for (tempIndex = 0; tempIndex < 8; tempIndex++) + newData += (((long) inputData[index + tempIndex]) & 0xff) << (8 * tempIndex); + index = index + 8; + } + dataContainer[(x * size + z) * maxVerticalData + y] = newData; + } } - }*/ + } } public LevelContainer expand(){ @@ -125,7 +131,7 @@ public class VerticalLevelContainer implements LevelContainer dataToMerge[(z*2+x)*maxVerticalData + verticalIndex] = lowerLevelContainer.getData(childPosX, childPosZ, verticalIndex); } } - data = DataPointUtil.mergeMultiData(dataToMerge, lowerLevelContainer.getDetailLevel()); + data = DataPointUtil.mergeMultiData(dataToMerge, lowerLevelContainer.getMaxVerticalData(), getMaxVerticalData()); for(int verticalIndex = 0; (verticalIndex < data.length) && (verticalIndex < maxVerticalData); verticalIndex++) { @@ -138,8 +144,37 @@ public class VerticalLevelContainer implements LevelContainer public byte[] toDataString() { - byte[] temp = {}; - return temp; + int index = 0; + int tempIndex; + byte[] tempData = new byte[2 + (size * size * maxVerticalData * 8)]; + tempData[index] = detailLevel; + index++; + tempData[index] = (byte) maxVerticalData; + index++; + int x, y, z = 0; + for (x = 0; x < size; x++) + { + for (z = 0; z < size; z++) + { + for (y = 0; y < maxVerticalData; y++) + { + if (dataContainer[(x * size + z) * maxVerticalData + y] == 0) + { + tempData[index] = 0; + index++; + } else if (dataContainer[(x * size + z) * maxVerticalData + y] == 3) + { + tempData[index] = 3; + index++; + } else { + for (tempIndex = 0; tempIndex < 8; tempIndex++) + tempData[index + tempIndex] = (byte) (dataContainer[(x * size + z) * maxVerticalData + y] >>> (8 * tempIndex)); + index += 8; + } + } + } + } + return Arrays.copyOfRange(tempData, 0, index); } @Override diff --git a/src/main/java/com/seibel/lod/util/DataPointUtil.java b/src/main/java/com/seibel/lod/util/DataPointUtil.java index 3b27ddbf1..f5fbf7842 100644 --- a/src/main/java/com/seibel/lod/util/DataPointUtil.java +++ b/src/main/java/com/seibel/lod/util/DataPointUtil.java @@ -279,29 +279,29 @@ public class DataPointUtil } } - public static long[] mergeMultiData(long[] dataToMerge, byte detailLevel) + public static long[] mergeMultiData(long[] dataToMerge, int inputVerticalData,int maxVerticalData) { - int verticalData = DetailDistanceUtil.getMaxVerticalData(detailLevel); - int size = dataToMerge.length/verticalData; + int size = dataToMerge.length / inputVerticalData; short[] projection = ThreadMapUtil.getProjectionShort((WORLD_HEIGHT + 1) / 16); - short[][] heightAndDepth = ThreadMapUtil.getHeightAndDepth((WORLD_HEIGHT / 2) + 1); + short[][] heightAndDepth = ThreadMapUtil.getHeightAndDepth(inputVerticalData); long[] singleDataToMerge = ThreadMapUtil.getSingleAddDataToMerge(size); int genMode = DistanceGenerationMode.SERVER.complexity; boolean allEmpty = true; boolean allVoid = true; long singleData; - int test = 0; - for(int k=0; k < projection.length; k++) + + for(int k=0; k < projection.length; k++) //probably can remove projection[k] = 0; short depth = 0; short height = 0; + //We collect the indexes of the data, ordered by the depth for (int index = 0; index < size; index++) { - for (int verticalIndex = 0; verticalIndex < verticalData; verticalIndex++) + for (int dataIndex = 0; dataIndex < inputVerticalData; dataIndex++) { - singleData = dataToMerge[index * verticalData + verticalIndex]; + singleData = dataToMerge[index * inputVerticalData + dataIndex]; if (doesItExist(singleData)) { genMode = Math.min(genMode, getGenerationMode(singleData)); @@ -324,6 +324,7 @@ public class DataPointUtil if (allVoid) return new long[]{createVoidDataPoint(genMode)}; + //We extract the merged data int count = 0; int i = 0; int ii = 0; @@ -357,13 +358,31 @@ public class DataPointUtil } height = (short)(i * 16 + ii - 1); heightAndDepth[count][0] = depth; - heightAndDepth[count][1] = height; + heightAndDepth[count][1] = height; count++; } + //we limit the vertical portion to maxVerticalData + int j = 0; + while (count > maxVerticalData) + { + ii = WORLD_HEIGHT; + for (i = 0; i < count - 1; i++) + { + if (heightAndDepth[i][1] - heightAndDepth[i + 1][0] < ii) + { + ii = heightAndDepth[i][1] - heightAndDepth[i + 1][0]; + j = i; + } + } + heightAndDepth[j][1] = heightAndDepth[j + 1][1]; + System.arraycopy(heightAndDepth,j + 1, heightAndDepth, j,count - j - 1); + 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--) + for (j = count - 1; j >= 0; j--) { depth = heightAndDepth[j][0]; height = heightAndDepth[j][1]; @@ -372,9 +391,9 @@ public class DataPointUtil } for (int index = 0; index < size; index++) { - for (int verticalIndex = 0; verticalIndex < verticalData; verticalIndex++) + for (int dataIndex = 0; dataIndex < inputVerticalData; dataIndex++) { - singleData = dataToMerge[index * verticalData + verticalIndex]; + singleData = dataToMerge[index * inputVerticalData + dataIndex]; if (doesItExist(singleData) && !isItVoid(singleData)) { if ((depth <= getDepth(singleData) && getDepth(singleData) <= height) @@ -391,8 +410,7 @@ public class DataPointUtil long data = mergeSingleData(singleDataToMerge); dataPoint[j] = createDataPoint(height, depth, getColor(data), getLightSky(data), getLightBlock(data), getGenerationMode(data)); } - verticalData = DetailDistanceUtil.getMaxVerticalData(detailLevel+1); - return Arrays.copyOf(dataPoint, verticalData); + return dataPoint; } public static long[] compress(long[] data, byte detailLevel) diff --git a/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java b/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java index 552538694..a9a321c0b 100644 --- a/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java +++ b/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java @@ -32,6 +32,19 @@ public class DetailDistanceUtil 1, 1,}; + /*private static int[] maxVerticalData = { + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8};*/ + private static LodDetail[] lodGenDetails = { LodDetail.FULL, LodDetail.HALF,