From 627327140e9c31326e5a68d1fa496569780111c4 Mon Sep 17 00:00:00 2001 From: cola98765 Date: Sat, 9 Oct 2021 17:07:38 +0200 Subject: [PATCH 1/2] reversed logic in mergeMultiData to improve performance of initial compression to maxVerticalData --- .../com/seibel/lod/util/DataPointUtil.java | 94 +++++++++---------- 1 file changed, 46 insertions(+), 48 deletions(-) diff --git a/src/main/java/com/seibel/lod/util/DataPointUtil.java b/src/main/java/com/seibel/lod/util/DataPointUtil.java index 9afddaa92..39c975d81 100644 --- a/src/main/java/com/seibel/lod/util/DataPointUtil.java +++ b/src/main/java/com/seibel/lod/util/DataPointUtil.java @@ -5,6 +5,7 @@ import com.seibel.lod.enums.DistanceGenerationMode; import net.minecraft.client.renderer.texture.NativeImage; import javax.xml.crypto.Data; +import java.util.Arrays; public class DataPointUtil { @@ -371,12 +372,12 @@ public class DataPointUtil boolean topExtend = false; for (i = 0; i < count; i++) { - if (depth >= heightAndDepth[i * 2] && depth <= heightAndDepth[i * 2 + 1]) + if (depth <= heightAndDepth[i * 2] && depth >= heightAndDepth[i * 2 + 1]) { botPos = i; break; } - else if (((i + 1 < count && depth < heightAndDepth[(i + 1) * 2]) || i + 1 == count) && depth > heightAndDepth[i * 2 + 1]) + else if (depth < heightAndDepth[i * 2 + 1] && ((i + 1 < count && depth > heightAndDepth[(i + 1) * 2]) || i + 1 == count)) { botPos = i; botExtend = true; @@ -385,75 +386,75 @@ public class DataPointUtil } for (i = 0; i < count; i++) { - if (height >= heightAndDepth[i * 2] && height <= heightAndDepth[i * 2 + 1]) + if (height <= heightAndDepth[i * 2] && height >= heightAndDepth[i * 2 + 1]) { topPos = i; break; } - else if (((i + 1 < count && height < heightAndDepth[(i + 1) * 2]) || i + 1 == count) && height > heightAndDepth[i * 2 + 1]) + else if (height < heightAndDepth[i * 2 + 1] && ((i + 1 < count && height > heightAndDepth[(i + 1) * 2]) || i + 1 == count)) { topPos = i; topExtend = true; break; } } - if (botPos == -1) + if (topPos == -1) { - if (topPos == -1) + if (botPos == -1) { - //whole block falls below + //whole block falls above extendArray(heightAndDepth, 2, 0, 1, count); - heightAndDepth[0] = depth; - heightAndDepth[1] = height; + heightAndDepth[0] = height; + heightAndDepth[1] = depth; count++; } - else if (!topExtend) + else if (!botExtend) { - //only bottom falls below extending it there, while top is inside existing - shrinkArray(heightAndDepth, 2, 0, topPos, count); - heightAndDepth[0] = depth; - count -= topPos; + //only top falls above extending it there, while bottom is inside existing + shrinkArray(heightAndDepth, 2, 0, botPos, count); + heightAndDepth[0] = height; + count -= botPos; } else { //top falls between some blocks, extending those as well - shrinkArray(heightAndDepth, 2, 0, topPos, count); - heightAndDepth[0] = depth; - heightAndDepth[1] = height; - count -= topPos; + shrinkArray(heightAndDepth, 2, 0, botPos, count); + heightAndDepth[0] = height; + heightAndDepth[1] = depth; + count -= botPos; } } - else if (!botExtend) + else if (!topExtend) { - if (!topExtend) + if (!botExtend) //both top and bottom are within some exiting blocks, possibly merging them - heightAndDepth[botPos * 2 + 1] = heightAndDepth[topPos * 2 + 1]; + heightAndDepth[topPos * 2 + 1] = heightAndDepth[botPos * 2 + 1]; else //top falls between some blocks, extending it there - heightAndDepth[botPos * 2 + 1] = height; - shrinkArray(heightAndDepth, 2, botPos + 1, topPos - botPos, count); - count -= topPos - botPos; + heightAndDepth[topPos * 2 + 1] = depth; + shrinkArray(heightAndDepth, 2, topPos + 1, botPos - topPos, count); + count -= botPos - topPos; } else { - if (!topExtend) + if (!botExtend) { //only top is within some exiting block, extending it - botPos++; //to make it easier - heightAndDepth[botPos * 2] = depth; - heightAndDepth[botPos * 2 + 1] = heightAndDepth[topPos * 2 + 1]; - shrinkArray(heightAndDepth, 2, botPos + 1, topPos - botPos, count); - count -= topPos - botPos; + topPos++; //to make it easier + heightAndDepth[topPos * 2] = height; + heightAndDepth[topPos * 2 + 1] = heightAndDepth[botPos * 2 + 1]; + shrinkArray(heightAndDepth, 2, topPos + 1, botPos - topPos, count); + count -= botPos - topPos; } else { //both top and bottom are outside existing blocks - shrinkArray(heightAndDepth, 2, botPos + 1, topPos - botPos, count); - count -= topPos - botPos; - extendArray(heightAndDepth, 2, botPos + 1, 1, count); + shrinkArray(heightAndDepth, 2, topPos + 1, botPos - topPos, count); + count -= botPos - topPos; + extendArray(heightAndDepth, 2, topPos + 1, 1, count); count++; - heightAndDepth[botPos * 2 + 2] = depth; - heightAndDepth[botPos * 2 + 3] = height; + heightAndDepth[topPos * 2 + 2] = height; + heightAndDepth[topPos * 2 + 3] = depth; } } } @@ -473,6 +474,7 @@ public class DataPointUtil dataPoint[0] = createVoidDataPoint(genMode); return dataPoint; } + //we limit the vertical portion to maxVerticalData int j = 0; while (count > maxVerticalData) @@ -480,9 +482,9 @@ public class DataPointUtil ii = worldHeight; for (i = 0; i < count - 1; i++) { - if (heightAndDepth[(i + 1) * 2] - heightAndDepth[i * 2 + 1] < ii) + if (heightAndDepth[i * 2 + 1] - heightAndDepth[(i + 1) * 2]< ii) { - ii = heightAndDepth[(i + 1) * 2] - heightAndDepth[i * 2 + 1]; + ii = heightAndDepth[i * 2 + 1] - heightAndDepth[(i + 1) * 2]; j = i; } } @@ -492,20 +494,18 @@ public class DataPointUtil heightAndDepth[i * 2] = heightAndDepth[(i + 1) * 2]; heightAndDepth[i * 2 + 1] = heightAndDepth[(i + 1) * 2 + 1]; } - //System.arraycopy(heightAndDepth,j + 1, heightAndDepth, j,count - j - 1); + //System.arraycopy(heightAndDepth, j + 1, heightAndDepth, j, count - j - 1); count--; } //As standard the vertical lods are ordered from top to bottom - for (j = 0; j < count; j++) + for (j = count - 1; j >= 0; j--) { - depth = heightAndDepth[j * 2]; - height = heightAndDepth[j * 2 + 1]; + height = heightAndDepth[j * 2]; + depth = heightAndDepth[j * 2 + 1]; + if ((depth == 0 && height == 0) || j >= heightAndDepth.length / 2) break; - for (int k = 0; k < size; k++) - { - singleDataToMerge[k] = 0; - } + Arrays.fill(singleDataToMerge, 0); for (int index = 0; index < size; index++) { for (dataIndex = 0; dataIndex < inputVerticalData; dataIndex++) @@ -518,9 +518,7 @@ public class DataPointUtil || (depth <= getHeight(singleData) && getHeight(singleData) <= height)) { if (getHeight(singleData) > getHeight(singleDataToMerge[index])) - { singleDataToMerge[index] = singleData; - } } } else @@ -533,7 +531,7 @@ public class DataPointUtil } long data = mergeSingleData(singleDataToMerge); - dataPoint[count - j - 1] = createDataPoint(height, depth, getColor(data), getLightSky(data), getLightBlock(data), getGenerationMode(data)); + dataPoint[j] = createDataPoint(height, depth, getColor(data), getLightSky(data), getLightBlock(data), getGenerationMode(data)); } return dataPoint; } From 3ec30d49be469462eb8a5c89a4f4bff5289950b2 Mon Sep 17 00:00:00 2001 From: cola98765 Date: Sat, 9 Oct 2021 17:47:58 +0200 Subject: [PATCH 2/2] put guts of mergeSingleData into mergeMultiData and make dataPoint smaller to make it faster --- .../com/seibel/lod/util/DataPointUtil.java | 63 ++++++++++++++++--- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/seibel/lod/util/DataPointUtil.java b/src/main/java/com/seibel/lod/util/DataPointUtil.java index 39c975d81..53c982794 100644 --- a/src/main/java/com/seibel/lod/util/DataPointUtil.java +++ b/src/main/java/com/seibel/lod/util/DataPointUtil.java @@ -333,8 +333,7 @@ public class DataPointUtil // We initialize the arrays that are going to be used short[] heightAndDepth = ThreadMapUtil.getHeightAndDepth((worldHeight + 1) * 2); - long[] singleDataToMerge = ThreadMapUtil.getSingleAddDataToMerge(size); - long[] dataPoint = ThreadMapUtil.getVerticalDataArray(worldHeight + 1); + long[] dataPoint = ThreadMapUtil.getVerticalDataArray(DetailDistanceUtil.getMaxVerticalData(0)); int genMode = DistanceGenerationMode.SERVER.complexity; @@ -505,7 +504,19 @@ public class DataPointUtil if ((depth == 0 && height == 0) || j >= heightAndDepth.length / 2) break; - Arrays.fill(singleDataToMerge, 0); + + int numberOfChildren = 0; + int tempAlpha = 0; + int tempRed = 0; + int tempGreen = 0; + int tempBlue = 0; + int tempLightBlock = 0; + int tempLightSky = 0; + byte tempGenMode = DistanceGenerationMode.SERVER.complexity; + allEmpty = true; + allVoid = true; + long data = 0; + for (int index = 0; index < size; index++) { for (dataIndex = 0; dataIndex < inputVerticalData; dataIndex++) @@ -517,21 +528,55 @@ public class DataPointUtil if ((depth <= getDepth(singleData) && getDepth(singleData) <= height) || (depth <= getHeight(singleData) && getHeight(singleData) <= height)) { - if (getHeight(singleData) > getHeight(singleDataToMerge[index])) - singleDataToMerge[index] = singleData; + if (getHeight(singleData) > getHeight(data)) + data = singleData; } } else break; } - if(!doesItExist(singleDataToMerge[index])){ + if(!doesItExist(data)){ singleData = dataToMerge[index * inputVerticalData]; - singleDataToMerge[index] = createVoidDataPoint(getGenerationMode(singleData)); + data = createVoidDataPoint(getGenerationMode(singleData)); } + + if (doesItExist(data)) + { + allEmpty = false; + if (!isVoid(data)) + { + numberOfChildren++; + allVoid = false; + tempAlpha += getAlpha(data); + tempRed += getRed(data); + tempGreen += getGreen(data); + tempBlue += getBlue(data); + tempLightBlock += getLightBlock(data); + tempLightSky += getLightSky(data); + } + tempGenMode = (byte) Math.min(tempGenMode, getGenerationMode(data)); + } + else + tempGenMode = (byte) Math.min(tempGenMode, DistanceGenerationMode.NONE.complexity); } - long data = mergeSingleData(singleDataToMerge); - dataPoint[j] = createDataPoint(height, depth, getColor(data), getLightSky(data), getLightBlock(data), getGenerationMode(data)); + if (allEmpty) + //no child has been initialized + dataPoint[j] = EMPTY_DATA; + else if (allVoid) + //all the children are void + dataPoint[j] = createVoidDataPoint(tempGenMode); + else + { + //we have at least 1 child + tempAlpha = tempAlpha / numberOfChildren; + tempRed = tempRed / numberOfChildren; + tempGreen = tempGreen / numberOfChildren; + tempBlue = tempBlue / numberOfChildren; + tempLightBlock = tempLightBlock / numberOfChildren; + tempLightSky = tempLightSky / numberOfChildren; + dataPoint[j] = createDataPoint(tempAlpha, tempRed, tempGreen, tempBlue, height, depth, tempLightSky, tempLightBlock, tempGenMode); + } } return dataPoint; }