Started convertion for vertical data

This commit is contained in:
Leonardo
2021-09-10 01:05:12 +02:00
parent 878714dae3
commit 21140593e2
19 changed files with 503 additions and 202 deletions
@@ -1,97 +0,0 @@
package com.seibel.lod.objects;
public class DataPoint
{
public final static int HEIGHT_SHIFT = 54;
public final static int DEPTH_SHIFT = 44;
public final static int RED_SHIFT = 36;
public final static int GREEN_SHIFT = 28;
public final static int BLUE_SHIFT = 20;
public final static int GEN_TYPE_SHIFT = 17;
public final static int LIGHT_SHIFT = 13;
public final static int EXISTENCE_SHIFT = 0;
public final static long HEIGHT_MASK = Long.parseUnsignedLong("1111111111", 2);
public final static long DEPTH_MASK = Long.parseUnsignedLong("1111111111", 2);
public final static long RED_MASK = Long.parseUnsignedLong("11111111", 2);
public final static long GREEN_MASK = Long.parseUnsignedLong("11111111", 2);
public final static long BLUE_MASK = Long.parseUnsignedLong("11111111", 2);
public final static long GEN_TYPE_MASK = Long.parseUnsignedLong("111", 2);
public final static long LIGHT_MASK = Long.parseUnsignedLong("1111", 2);
public final static long EXISTENCE_MASK = 1;
public static long createDataPoint(int height, int depth, int color)
{
int red = (getRed(color) << 16) & 0x00FF0000;
int green = (getGreen(color) << 8) & 0x0000FF00;
int blue = getBlue(color)& 0x000000FF;
return createDataPoint(height, depth, red, green, blue);
}
public static long createDataPoint(int height, int depth, int red, int green, int blue)
{
long dataPoint = 0;
dataPoint += (height & HEIGHT_MASK) << HEIGHT_SHIFT;
dataPoint += (depth & DEPTH_MASK) << DEPTH_SHIFT;
dataPoint += (red & RED_MASK) << RED_SHIFT;
dataPoint += (green & GREEN_MASK) << GREEN_SHIFT;
dataPoint += (blue & BLUE_MASK) << BLUE_SHIFT;
dataPoint += 1;
return dataPoint;
}
public static short getHeight(long dataPoint)
{
return (short) ((dataPoint >> HEIGHT_SHIFT) & HEIGHT_MASK);
}
public static short getDepth(long dataPoint)
{
return (short) ((dataPoint >> DEPTH_SHIFT) & DEPTH_MASK);
}
public static short getRed(long dataPoint)
{
return (short) ((dataPoint >> RED_SHIFT) & RED_MASK);
}
public static short getGreen(long dataPoint)
{
return (short) ((dataPoint >> GREEN_SHIFT) & GREEN_MASK);
}
public static short getBlue(long dataPoint)
{
return (short) ((dataPoint >> BLUE_SHIFT) & BLUE_MASK);
}
public static boolean doesItExist(long dataPoint)
{
return ((dataPoint & EXISTENCE_MASK) == 1);
}
public static int getColor(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 String toString(long dataPoint)
{
StringBuilder s = new StringBuilder();
s.append(getHeight(dataPoint));
s.append(" ");
s.append(getDepth(dataPoint));
s.append(" ");
s.append(getRed(dataPoint));
s.append(" ");
s.append(getBlue(dataPoint));
s.append(" ");
s.append(getGreen(dataPoint));
s.append('\n');
return s.toString();
}
}
@@ -1,67 +1,16 @@
package com.seibel.lod.objects;
import java.io.Serializable;
import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodUtil;
public class LevelContainer implements Serializable
public interface LevelContainer
{
/** This is here so that Eclipse doesn't complain */
private static final long serialVersionUID = -4930855068717998385L;
public static final char VERTICAL_DATA_DELIMITER = ',';
public static final char DATA_DELIMITER = ',';
public final byte detailLevel;
public final long[][] data;
public LevelContainer(byte detailLevel, long[][] data)
{
this.detailLevel = detailLevel;
this.data = data;
}
public LevelContainer(String inputString)
{
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.data = new long[size][size];
for (int x = 0; x < size; x++)
{
for (int z = 0; z < size; z++)
{
lastIndex = index;
index = inputString.indexOf(DATA_DELIMITER, lastIndex + 1);
data[x][z] = Long.parseLong(inputString.substring(lastIndex + 1, index), 16);
}
}
}
@Override
public String toString()
{
StringBuilder stringBuilder = new StringBuilder();
int size = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel);
stringBuilder.append(detailLevel);
stringBuilder.append(DATA_DELIMITER);
for (int x = 0; x < size; x++)
{
for (int z = 0; z < size; z++)
{
//Converting the dataToHex
stringBuilder.append(Long.toHexString(data[x][z]));
stringBuilder.append(DATA_DELIMITER);
}
}
return stringBuilder.toString();
}
public boolean putData(long[] data, int posX, int posZ);
public long[] getData(int posX, int posZ);
/**TODO could i use a static map from thread name to arrays to store these values?*/
public long[] mergeData(long[][] dataArray, long[] newDataPoint, int[] indexes, long[] dataToCombine);
public String toDataString();
}
@@ -1,253 +0,0 @@
package com.seibel.lod.objects;
import com.seibel.lod.util.LodUtil;
public class LevelPosUtil
{
public static int[] convert(int[] levelPos, byte newDetailLevel)
{
return convert(getDetailLevel(levelPos), getPosX(levelPos), getPosZ(levelPos), newDetailLevel);
}
public static int[] convert(byte detailLevel, int posX, int posZ, byte newDetailLevel)
{
int width;
if (newDetailLevel >= detailLevel)
{
width = 1 << (newDetailLevel - detailLevel);
return createLevelPos(
newDetailLevel,
Math.floorDiv(posX, width),
Math.floorDiv(posZ, width));
} else
{
width = 1 << (detailLevel - newDetailLevel);
return createLevelPos(
newDetailLevel,
posX * width,
posZ * width);
}
}
public static int[] createLevelPos(byte detailLevel, int posX, int posZ)
{
return new int[]{detailLevel, posX, posZ};
}
public static int convert(byte detailLevel, int pos, byte newDetailLevel)
{
int width;
if (newDetailLevel >= detailLevel)
{
width = 1 << (newDetailLevel - detailLevel);
return Math.floorDiv(pos, width);
} else
{
width = 1 << (detailLevel - newDetailLevel);
return pos * width;
}
}
public static int getRegion(byte detailLevel, int pos)
{
return Math.floorDiv(pos, 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel));
}
public static int getRegionModule(byte detailLevel, int pos)
{
return Math.floorMod(pos, 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel));
}
public static byte getDetailLevel(int[] levelPos)
{
return (byte) levelPos[0];
}
public static int getPosX(int[] levelPos)
{
return levelPos[1];
}
public static int getPosZ(int[] levelPos)
{
return levelPos[2];
}
public static int getDistance(int[] levelPos)
{
return levelPos[3];
}
public static int[] getRegionModule(int[] levelPos)
{
return getRegionModule(getDetailLevel(levelPos), getPosX(levelPos), getPosZ(levelPos));
}
public static int[] getRegionModule(byte detailLevel, int posX, int posZ)
{
int width = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel);
return createLevelPos(
detailLevel,
Math.floorMod(posX, width),
Math.floorMod(posZ, width));
}
public static int[] applyOffset(int[] levelPos, int xOffset, int zOffset)
{
return createLevelPos(
getDetailLevel(levelPos),
getPosX(levelPos) + xOffset,
getPosZ(levelPos) + zOffset);
}
public static int[] applyLevelOffset(int[] levelPos, byte detailOffset, int xOffset, int zOffset)
{
return createLevelPos(
getDetailLevel(levelPos),
getPosX(levelPos) + xOffset * (1 << detailOffset),
getPosZ(levelPos) + zOffset * (1 << detailOffset));
}
public static int getRegionPosX(int[] levelPos)
{
int width = 1 << (LodUtil.REGION_DETAIL_LEVEL - getDetailLevel(levelPos));
return Math.floorDiv(getPosX(levelPos), width);
}
public static int getRegionPosZ(int[] levelPos)
{
int width = 1 << (LodUtil.REGION_DETAIL_LEVEL - getDetailLevel(levelPos));
return Math.floorDiv(getPosZ(levelPos), width);
}
public static int getChunkPos(byte detailLevel, int pos)
{
return convert(detailLevel,pos, LodUtil.CHUNK_DETAIL_LEVEL);
}
public static int getChunkPosX(int[] levelPos)
{
levelPos = convert(levelPos, LodUtil.CHUNK_DETAIL_LEVEL);
return getPosX(levelPos);
}
public static int getChunkPosZ(int[] levelPos)
{
levelPos = convert(levelPos, LodUtil.CHUNK_DETAIL_LEVEL);
return getPosZ(levelPos);
}
public static int maxDistance(int[] levelPos, int playerPosX, int playerPosZ)
{
return maxDistance(getDetailLevel(levelPos), getPosX(levelPos), getPosZ(levelPos), playerPosX, playerPosZ);
}
public static int maxDistance(byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ)
{
int width = 1 << detailLevel;
int startPosX = posX * width;
int startPosZ = posZ * width;
int endPosX = startPosX + width;
int endPosZ = startPosZ + width;
int maxDistance = (int) Math.sqrt(Math.pow(playerPosX - startPosX, 2) + Math.pow(playerPosZ - startPosZ, 2));
maxDistance = Math.max(maxDistance, (int) Math.sqrt(Math.pow(playerPosX - startPosX, 2) + Math.pow(playerPosZ - endPosZ, 2)));
maxDistance = Math.max(maxDistance, (int) Math.sqrt(Math.pow(playerPosX - endPosX, 2) + Math.pow(playerPosZ - startPosZ, 2)));
maxDistance = Math.max(maxDistance, (int) Math.sqrt(Math.pow(playerPosX - endPosX, 2) + Math.pow(playerPosZ - endPosZ, 2)));
return maxDistance;
}
public static int maxDistance(byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ, int xRegion, int zRegion)
{
int width = 1 << detailLevel;
int startPosX = xRegion * 512 + posX * width;
int startPosZ = zRegion * 512 + posZ * width;
int endPosX = startPosX + width;
int endPosZ = startPosZ + width;
int maxDistance = (int) Math.sqrt(Math.pow(playerPosX - startPosX, 2) + Math.pow(playerPosZ - startPosZ, 2));
maxDistance = Math.max(maxDistance, (int) Math.sqrt(Math.pow(playerPosX - startPosX, 2) + Math.pow(playerPosZ - endPosZ, 2)));
maxDistance = Math.max(maxDistance, (int) Math.sqrt(Math.pow(playerPosX - endPosX, 2) + Math.pow(playerPosZ - startPosZ, 2)));
maxDistance = Math.max(maxDistance, (int) Math.sqrt(Math.pow(playerPosX - endPosX, 2) + Math.pow(playerPosZ - endPosZ, 2)));
return maxDistance;
}
public static int minDistance(int[] levelPos, int playerPosX, int playerPosZ)
{
return minDistance(getDetailLevel(levelPos), getPosX(levelPos), getPosZ(levelPos), playerPosX, playerPosZ);
}
public static int minDistance(byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ)
{
int width = 1 << detailLevel;
int startPosX = posX * width;
int startPosZ = posZ * width;
int endPosX = startPosX + width;
int endPosZ = startPosZ + width;
boolean inXArea = playerPosX >= startPosX && playerPosX <= endPosX;
boolean inZArea = playerPosZ >= startPosZ && playerPosZ <= endPosZ;
if (inXArea && inZArea)
{
return 0;
} else if (inXArea)
{
return Math.min(
Math.abs(playerPosZ - startPosZ),
Math.abs(playerPosZ - endPosZ)
);
} else if (inZArea)
{
return Math.min(
Math.abs(playerPosX - startPosX),
Math.abs(playerPosX - endPosX)
);
} else
{
int minDistance = (int) Math.sqrt(Math.pow(playerPosX - startPosX, 2) + Math.pow(playerPosZ - startPosZ, 2));
minDistance = Math.min(minDistance, (int) Math.sqrt(Math.pow(playerPosX - startPosX, 2) + Math.pow(playerPosZ - endPosZ, 2)));
minDistance = Math.min(minDistance, (int) Math.sqrt(Math.pow(playerPosX - endPosX, 2) + Math.pow(playerPosZ - startPosZ, 2)));
minDistance = Math.min(minDistance, (int) Math.sqrt(Math.pow(playerPosX - endPosX, 2) + Math.pow(playerPosZ - endPosZ, 2)));
return minDistance;
}
}
public static int compareDistance(int firstDistance, int secondDistance)
{
return Integer.compare(
firstDistance,
secondDistance);
}
public static int compareLevelAndDistance(byte firstDetail, int firstDistance, byte secondDetail, int secondDistance)
{
int compareResult = Integer.compare(
secondDetail,
firstDetail);
// System.out.println("comparing level "+ firstDetail + " " + secondDetail + " " + compareResult);
if (compareResult == 0)
{
compareResult = compareDistance(
firstDistance,
secondDistance);
// System.out.println("Equal level "+ firstDistance + " " + secondDistance + " " + compareResult);
}
return compareResult;
}
public static String toString(int[] levelPos)
{
return (getDetailLevel(levelPos) + " " + getPosX(levelPos) + " " + getPosZ(levelPos));
}
public static String toString(byte detailLevel, int posX, int posZ)
{
return (detailLevel + " " + posX + " " + posZ);
}
}
@@ -26,6 +26,7 @@ import com.seibel.lod.config.LodConfig;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.handlers.LodDimensionFileHandler;
import com.seibel.lod.util.DetailDistanceUtil;
import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodThreadFactory;
import com.seibel.lod.util.LodUtil;
import com.seibel.lod.wrappers.MinecraftWrapper;
@@ -435,7 +436,7 @@ public class LodDimension
* stored in the LOD. If an LOD already exists at the given
* coordinates it will be overwritten.
*/
public synchronized Boolean addData(byte detailLevel, int posX, int posZ, long lodDataPoint, boolean dontSave, boolean serverQuality)
public Boolean addData(byte detailLevel, int posX, int posZ, long lodDataPoint, boolean dontSave, boolean serverQuality)
{
// don't continue if the region can't be saved
@@ -3,7 +3,9 @@ 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;
/**
@@ -32,17 +34,17 @@ public class LodRegion
public final int regionPosX;
public final int regionPosZ;
public LodRegion(LevelContainer levelContainer, RegionPos regionPos, DistanceGenerationMode generationMode)
public LodRegion(VerticalLevelContainer verticalLevelContainer, RegionPos regionPos, DistanceGenerationMode generationMode)
{
this.generationMode = generationMode;
this.regionPosX = regionPos.x;
this.regionPosZ = regionPos.z;
this.minDetailLevel = levelContainer.detailLevel;
this.minDetailLevel = verticalLevelContainer.detailLevel;
//Arrays of matrices
data = new long[POSSIBLE_LOD][][];
data[minDetailLevel] = levelContainer.data;
data[minDetailLevel] = verticalLevelContainer.data;
//Initialize all the different matrices
for (byte lod = (byte) (minDetailLevel + 1); lod <= LodUtil.REGION_DETAIL_LEVEL; lod++)
@@ -308,16 +310,16 @@ public class LodRegion
childDetailLevel = (byte) (detailLevel - 1);
if (doesDataExist(childDetailLevel, childPosX, childPosZ))
{
if (!(DataPoint.getHeight(data[childDetailLevel][childPosX][childPosZ]) == LodBuilder.DEFAULT_HEIGHT
&& DataPoint.getDepth(data[childDetailLevel][childPosX][childPosZ]) == LodBuilder.DEFAULT_DEPTH))
if (!(DataPointUtil.getHeight(data[childDetailLevel][childPosX][childPosZ]) == LodBuilder.DEFAULT_HEIGHT
&& DataPointUtil.getDepth(data[childDetailLevel][childPosX][childPosZ]) == LodBuilder.DEFAULT_DEPTH))
{
numberOfChildren++;
tempRed += DataPoint.getRed(data[childDetailLevel][childPosX][childPosZ]);
tempGreen += DataPoint.getGreen(data[childDetailLevel][childPosX][childPosZ]);
tempBlue += DataPoint.getBlue(data[childDetailLevel][childPosX][childPosZ]);
tempHeight += DataPoint.getHeight(data[childDetailLevel][childPosX][childPosZ]);
tempDepth += DataPoint.getDepth(data[childDetailLevel][childPosX][childPosZ]);
tempRed += DataPointUtil.getRed(data[childDetailLevel][childPosX][childPosZ]);
tempGreen += DataPointUtil.getGreen(data[childDetailLevel][childPosX][childPosZ]);
tempBlue += DataPointUtil.getBlue(data[childDetailLevel][childPosX][childPosZ]);
tempHeight += DataPointUtil.getHeight(data[childDetailLevel][childPosX][childPosZ]);
tempDepth += DataPointUtil.getDepth(data[childDetailLevel][childPosX][childPosZ]);
} else
{
// void children have the default height (most likely -1)
@@ -342,7 +344,7 @@ public class LodRegion
tempHeight = LodBuilder.DEFAULT_HEIGHT;
tempDepth = LodBuilder.DEFAULT_DEPTH;
}
data[detailLevel][posX][posZ] = DataPoint.createDataPoint(tempHeight, tempDepth, tempRed, tempGreen, tempBlue);
data[detailLevel][posX][posZ] = DataPointUtil.createDataPoint(tempHeight, tempDepth, tempRed, tempGreen, tempBlue);
}
@@ -354,7 +356,7 @@ public class LodRegion
if(detailLevel < minDetailLevel) return false;
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
return DataPoint.doesItExist(data[detailLevel][posX][posZ]);
return DataPointUtil.doesItExist(data[detailLevel][posX][posZ]);
}
/**
@@ -376,26 +378,26 @@ public class LodRegion
* @param detailLevel
* @return
*/
public LevelContainer getLevel(byte detailLevel)
public VerticalLevelContainer getLevel(byte detailLevel)
{
if (detailLevel < minDetailLevel)
{
throw new IllegalArgumentException("getLevel asked for a level that does not exist: minimum " + minDetailLevel + " level requested " + detailLevel);
}
return new LevelContainer(detailLevel, data[detailLevel]);
return new VerticalLevelContainer(detailLevel, data[detailLevel]);
}
/**
* @param levelContainer
* @param verticalLevelContainer
*/
public void addLevel(LevelContainer levelContainer)
public void addLevel(VerticalLevelContainer verticalLevelContainer)
{
if (levelContainer.detailLevel < minDetailLevel - 1)
if (verticalLevelContainer.detailLevel < minDetailLevel - 1)
{
throw new IllegalArgumentException("addLevel requires a level that is at least the minimum level of the region -1 ");
}
if (levelContainer.detailLevel == minDetailLevel - 1) minDetailLevel = levelContainer.detailLevel;
data[levelContainer.detailLevel] = levelContainer.data;
if (verticalLevelContainer.detailLevel == minDetailLevel - 1) minDetailLevel = verticalLevelContainer.detailLevel;
data[verticalLevelContainer.detailLevel] = verticalLevelContainer.data;
}
@@ -1,5 +1,7 @@
package com.seibel.lod.objects;
import com.seibel.lod.util.LevelPosUtil;
public class PosToGenerateContainer
{
private int playerPosX;
@@ -1,5 +1,6 @@
package com.seibel.lod.objects;
import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodUtil;
public class PosToRenderContainer
@@ -0,0 +1,134 @@
package com.seibel.lod.objects;
import com.seibel.lod.builders.LodBuilder;
import com.seibel.lod.util.DataPointUtil;
import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodUtil;
public class SingleLevelContainer implements LevelContainer
{
public final byte detailLevel;
public final long[][] data;
public SingleLevelContainer(byte detailLevel, long[][] data)
{
this.detailLevel = detailLevel;
this.data = data;
}
public boolean putData(long[] data, int posX, int posZ){
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
data[posX][posZ] = data[0];
return true;
}
public long[] getData(int posX, int posZ){
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
return data[posX][posZ];
}
public SingleLevelContainer(String inputString)
{
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.data = new long[size][size][1];
for (int x = 0; x < size; x++)
{
for (int z = 0; z < size; z++)
{
lastIndex = index;
index = inputString.indexOf(DATA_DELIMITER, lastIndex + 1);
data[x][z][0] = Long.parseLong(inputString.substring(lastIndex + 1, index), 16);
}
}
}
public long[] mergeData(long[][] dataArray, long[] newDataPoint, int[] indexes, long[] dataToCombine)
{
int numberOfChildren = 0;
int numberOfVoidChildren = 0;
int tempRed = 0;
int tempGreen = 0;
int tempBlue = 0;
int tempHeight = 0;
int tempDepth = 0;
int childPosX;
int childPosZ;
byte childDetailLevel;
for (int index = 0; x <= 4; x++)
{
childDetailLevel = (byte) (detailLevel - 1);
if (doesDataExist(childDetailLevel, childPosX, childPosZ))
{
if (!(DataPointUtil.getHeight(data[childDetailLevel][childPosX][childPosZ]) == LodBuilder.DEFAULT_HEIGHT
&& DataPointUtil.getDepth(data[childDetailLevel][childPosX][childPosZ]) == LodBuilder.DEFAULT_DEPTH))
{
numberOfChildren++;
tempRed += DataPointUtil.getRed(data[childDetailLevel][childPosX][childPosZ]);
tempGreen += DataPointUtil.getGreen(data[childDetailLevel][childPosX][childPosZ]);
tempBlue += DataPointUtil.getBlue(data[childDetailLevel][childPosX][childPosZ]);
tempHeight += DataPointUtil.getHeight(data[childDetailLevel][childPosX][childPosZ]);
tempDepth += DataPointUtil.getDepth(data[childDetailLevel][childPosX][childPosZ]);
} else
{
// void children have the default height (most likely -1)
// and represent a LOD with no blocks in it
numberOfVoidChildren++;
}
}
}
}
if (numberOfChildren > 0)
{
tempRed = tempRed / numberOfChildren;
tempGreen = tempGreen / numberOfChildren;
tempBlue = tempBlue / numberOfChildren;
tempHeight = tempHeight / numberOfChildren;
tempDepth = tempDepth / numberOfChildren;
} else if (numberOfVoidChildren > 0)
{
tempRed = (byte) 0;
tempGreen = (byte) 0;
tempBlue = (byte) 0;
tempHeight = LodBuilder.DEFAULT_HEIGHT;
tempDepth = LodBuilder.DEFAULT_DEPTH;
}
data[detailLevel][posX][posZ] = DataPointUtil.createDataPoint(tempHeight, tempDepth, tempRed, tempGreen, tempBlue);
}
public String toDataString()
{
return toString();
}
@Override
public String toString()
{
StringBuilder stringBuilder = new StringBuilder();
int size = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel);
stringBuilder.append(detailLevel);
stringBuilder.append(DATA_DELIMITER);
for (int x = 0; x < size; x++)
{
for (int z = 0; z < size; z++)
{
//Converting the dataToHex
stringBuilder.append(Long.toHexString(data[x][z][0]));
stringBuilder.append(DATA_DELIMITER);
}
}
return stringBuilder.toString();
}
}
@@ -0,0 +1,143 @@
package com.seibel.lod.objects;
import java.io.Serializable;
import com.seibel.lod.util.DataPointUtil;
import com.seibel.lod.util.DetailDistanceUtil;
import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodUtil;
public class VerticalLevelContainer implements LevelContainer
{
public final byte detailLevel;
public final long[][][] data;
public VerticalLevelContainer(byte detailLevel, long[][][] data)
{
this.detailLevel = detailLevel;
this.data = data;
}
public boolean putData(long[] data, int posX, int posZ){
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
data[posX][posZ] = data
return true;
}
public long[] getData(int posX, int posZ){
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
return data[posX][posZ];
}
public VerticalLevelContainer(String inputString)
{
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.data = new long[size][size][1];
for (int x = 0; x < size; x++)
{
for (int z = 0; z < size; z++)
{
lastIndex = index;
index = inputString.indexOf(DATA_DELIMITER, lastIndex + 1);
data[x][z][0] = Long.parseLong(inputString.substring(lastIndex + 1, index), 16);
}
}
}
public long[] mergeData(long[][] dataArray, long[] newDataPoint, int[] indexes, long[] dataToCombine)
{
//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 < getDepth(dataArray[arrayIndex][indexes[arrayIndex]]))
{
minDepth = 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();
}
@Override
public String toString()
{
StringBuilder stringBuilder = new StringBuilder();
int size = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel);
stringBuilder.append(detailLevel);
stringBuilder.append(DATA_DELIMITER);
for (int x = 0; x < size; x++)
{
for (int z = 0; z < size; z++)
{
//Converting the dataToHex
stringBuilder.append(Long.toHexString(data[x][z][0]));
stringBuilder.append(DATA_DELIMITER);
}
}
return stringBuilder.toString();
}
}