diff --git a/src/main/java/com/seibel/lod/objects/LevelContainer.java b/src/main/java/com/seibel/lod/objects/LevelContainer.java index 841863ce8..c4f48eeb6 100644 --- a/src/main/java/com/seibel/lod/objects/LevelContainer.java +++ b/src/main/java/com/seibel/lod/objects/LevelContainer.java @@ -12,6 +12,7 @@ public interface LevelContainer public static final char DATA_DELIMITER = ','; public static final ConcurrentMap threadAddDataMap = new ConcurrentHashMap(); public static final ConcurrentMap threadGetDataMap = new ConcurrentHashMap(); + public static final ConcurrentMap threadSingleUpdateMap = new ConcurrentHashMap(); public static final ConcurrentMap threadVerticalUpdateMap = new ConcurrentHashMap(); public static final ConcurrentMap threadVerticalIndexesMap = new ConcurrentHashMap(); /**With this you can add data to the level container diff --git a/src/main/java/com/seibel/lod/objects/SingleLevelContainer.java b/src/main/java/com/seibel/lod/objects/SingleLevelContainer.java index fd1975794..a8c69cf32 100644 --- a/src/main/java/com/seibel/lod/objects/SingleLevelContainer.java +++ b/src/main/java/com/seibel/lod/objects/SingleLevelContainer.java @@ -3,6 +3,7 @@ package com.seibel.lod.objects; import com.seibel.lod.builders.LodBuilder; import com.seibel.lod.enums.DistanceGenerationMode; import com.seibel.lod.util.DataPointUtil; +import com.seibel.lod.util.DetailDistanceUtil; import com.seibel.lod.util.LevelPosUtil; import com.seibel.lod.util.LodUtil; @@ -88,22 +89,16 @@ public class SingleLevelContainer implements LevelContainer public void updateData(LevelContainer lowerLevelContainer, int posX, int posZ) { - int numberOfChildren = 0; - int numberOfVoidChildren = 0; + //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()); - int tempAlpha = 0; - int tempRed = 0; - int tempGreen = 0; - int tempBlue = 0; - int tempHeight = 0; - int tempDepth = 0; - int tempLight = 0; - byte tempGenMode = DistanceGenerationMode.SERVER.complexity; int childPosX; int childPosZ; - long childData; long data = 0; - byte childDetailLevel = (byte) (detailLevel - 1); posX = LevelPosUtil.getRegionModule(detailLevel, posX); posZ = LevelPosUtil.getRegionModule(detailLevel, posZ); for (int x = 0; x <= 1; x++) @@ -112,49 +107,11 @@ public class SingleLevelContainer implements LevelContainer { childPosX = 2 * posX + x; childPosZ = 2 * posZ + z; - childData = lowerLevelContainer.getData(childPosX, childPosZ)[0]; - - if (DataPointUtil.doesItExist(childData)) - { - if (!(DataPointUtil.isItVoid(childData))) - { - numberOfChildren++; - - tempAlpha += DataPointUtil.getAlpha(childData); - tempRed += DataPointUtil.getRed(childData); - tempGreen += DataPointUtil.getGreen(childData); - tempBlue += DataPointUtil.getBlue(childData); - tempHeight += DataPointUtil.getHeight(childData); - tempDepth += DataPointUtil.getDepth(childData); - } else - { - // void children have the default height (most likely -1) - // and represent a LOD with no blocks in it - numberOfVoidChildren++; - } - tempGenMode = (byte) Math.min(tempGenMode, DataPointUtil.getGenerationMode(childData)); - }else - { - tempGenMode = (byte) Math.min(tempGenMode, DistanceGenerationMode.NONE.complexity); - } + dataToMerge[2*z + x] = lowerLevelContainer.getData(childPosX, childPosZ)[0]; } } - if (numberOfChildren > 0) - { - tempAlpha = tempAlpha / numberOfChildren; - tempRed = tempRed / numberOfChildren; - tempGreen = tempGreen / numberOfChildren; - tempBlue = tempBlue / numberOfChildren; - tempHeight = tempHeight / numberOfChildren; - tempDepth = tempDepth / numberOfChildren; - tempLight = tempLight / numberOfChildren; - data = DataPointUtil.createDataPoint(tempAlpha, tempRed, tempGreen, tempBlue, tempHeight, tempDepth, tempLight, tempGenMode); - addSingleData(data, posX, posZ); - } else if (numberOfVoidChildren > 0) - { - data = DataPointUtil.createDataPoint(tempGenMode); - addSingleData(data, posX, posZ); - } + data = DataPointUtil.mergeSingleData(dataToMerge); + addSingleData(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 224281e07..fe0f340d2 100644 --- a/src/main/java/com/seibel/lod/util/DataPointUtil.java +++ b/src/main/java/com/seibel/lod/util/DataPointUtil.java @@ -1,11 +1,14 @@ package com.seibel.lod.util; +import com.seibel.lod.enums.DistanceGenerationMode; + public class DataPointUtil { //To be used in the future for negative value //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 ALPHA_SHIFT = 56; public final static int RED_SHIFT = 48; @@ -32,7 +35,7 @@ public class DataPointUtil public final static long EXISTENCE_MASK = 1; - public static long createDataPoint(int generationMode) + public static long createVoidDataPoint(int generationMode) { long dataPoint = 0; dataPoint += (generationMode & GEN_TYPE_MASK) << GEN_TYPE_SHIFT; @@ -141,6 +144,75 @@ public class DataPointUtil return s.toString(); } + public static long mergeSingleData(long[] dataToMerge) + { + int numberOfChildren = 0; + int numberOfVoidChildren = 0; + + int tempAlpha = 0; + int tempRed = 0; + int tempGreen = 0; + int tempBlue = 0; + int tempHeight = 0; + int tempDepth = 0; + int tempLight = 0; + byte tempGenMode = DistanceGenerationMode.SERVER.complexity; + long newData = 0; + for(long data : dataToMerge) + { + if (DataPointUtil.doesItExist(data)) + { + if (!(DataPointUtil.isItVoid(data))) + { + numberOfChildren++; + + tempAlpha += DataPointUtil.getAlpha(data); + tempRed += DataPointUtil.getRed(data); + tempGreen += DataPointUtil.getGreen(data); + tempBlue += DataPointUtil.getBlue(data); + tempHeight += DataPointUtil.getHeight(data); + tempDepth += DataPointUtil.getDepth(data); + } else + { + // void children have the default height (most likely -1) + // and represent a LOD with no blocks in it + numberOfVoidChildren++; + } + tempGenMode = (byte) Math.min(tempGenMode, DataPointUtil.getGenerationMode(data)); + } else + { + tempGenMode = (byte) Math.min(tempGenMode, DistanceGenerationMode.NONE.complexity); + } + } + if (numberOfChildren > 0) + { + //we have at least 1 child + tempAlpha = tempAlpha / numberOfChildren; + tempRed = tempRed / numberOfChildren; + tempGreen = tempGreen / numberOfChildren; + tempBlue = tempBlue / numberOfChildren; + tempHeight = tempHeight / numberOfChildren; + tempDepth = tempDepth / numberOfChildren; + tempLight = tempLight / numberOfChildren; + return DataPointUtil.createDataPoint(tempAlpha, tempRed, tempGreen, tempBlue, tempHeight, tempDepth, tempLight, tempGenMode); + } else if (numberOfVoidChildren > 0) + { + //all the children are void + return DataPointUtil.createVoidDataPoint(tempGenMode); + }else + { + //no child has been initialized + return DataPointUtil.EMPTY_DATA; + } + } +/* + public static int mergeVerticalData(long dataPoint) + { + int R = (getRed(dataPoint) << 16) & 0x00FF0000; + int G = (getGreen(dataPoint) << 8) & 0x0000FF00; + int B = getBlue(dataPoint) & 0x000000FF; + return 0xFF000000 | R | G | B; + }*/ public static long[] compress(long[] data, byte detailLevel) {