reworked it back to primitive arrays

This commit is contained in:
cola98765
2021-12-04 14:03:01 +01:00
parent aa79d5b5d4
commit 30cc294a04
14 changed files with 683 additions and 416 deletions
@@ -30,7 +30,6 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.ReentrantLock;
import com.seibel.lod.core.objects.lod.DataPoint;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL30;
@@ -288,7 +287,9 @@ public class LodBufferBuilderFactory
int maxVerticalData = DetailDistanceUtil.getMaxVerticalData((byte) 0);
//we get or create the map that will contain the adj data
Map<LodDirection, DataPoint[]> adjData = ThreadMapUtil.getAdjDataArray(maxVerticalData);
Map<LodDirection, int[]> adjData = ThreadMapUtil.getAdjDataArray(maxVerticalData);
Map<LodDirection, byte[]> adjFlags = ThreadMapUtil.getAdjFlagsArray(maxVerticalData);
//previous setToRender cache
if (setsToRender[xR][zR] == null)
@@ -348,7 +349,9 @@ public class LodBufferBuilderFactory
xAdj = posX + Box.DIRECTION_NORMAL_MAP.get(lodDirection).x;
zAdj = posZ + Box.DIRECTION_NORMAL_MAP.get(lodDirection).z;
DataPoint data;
int color;
int data;
byte flags;
chunkXdist = LevelPosUtil.getChunkPos(detailLevel, xAdj) - playerChunkPos.getX();
chunkZdist = LevelPosUtil.getChunkPos(detailLevel, zAdj) - playerChunkPos.getZ();
adjPosInPlayerChunk = (chunkXdist == 0 && chunkZdist == 0);
@@ -364,20 +367,26 @@ public class LodBufferBuilderFactory
{
for (int verticalIndex = 0; verticalIndex < lodDim.getMaxVerticalData(detailLevel, xAdj, zAdj); verticalIndex++)
{
data = lodDim.getData(detailLevel, xAdj, zAdj, verticalIndex);
lodDim.getDataPoint(detailLevel, xAdj, zAdj, verticalIndex);
data = ThreadMapUtil.dataPointData;
flags = ThreadMapUtil.dataPointFlags;
adjShadeDisabled[Box.DIRECTION_INDEX.get(lodDirection)] = false;
adjData.get(lodDirection)[verticalIndex] = data;
adjFlags.get(lodDirection)[verticalIndex] = flags;
}
}
else
{
//Otherwise, we check if this position is
data = lodDim.getSingleData(detailLevel, xAdj, zAdj);
lodDim.getSingleDataPoint(detailLevel, xAdj, zAdj);
data = ThreadMapUtil.dataPointData;
flags = ThreadMapUtil.dataPointFlags;
adjData.get(lodDirection)[0] = DataPointUtil.EMPTY_DATA;
adjData.get(lodDirection)[0] = 0;
adjFlags.get(lodDirection)[0] = 0;
if ((isThisPositionGoingToBeRendered(detailLevel, xAdj, zAdj, playerChunkPos, vanillaRenderedChunks, gameChunkRenderDistance) || (posNotInPlayerChunk && adjPosInPlayerChunk))
&& DataPointUtil.doesItExist(data) && !DataPointUtil.isVoid(data))
&& DataPointUtil.doesItExist(flags) && !DataPointUtil.isVoid(flags))
{
adjShadeDisabled[Box.DIRECTION_INDEX.get(lodDirection)] = DataPointUtil.getAlpha(data) < 255;
}
@@ -387,32 +396,50 @@ public class LodBufferBuilderFactory
// We render every vertical lod present in this position
// We only stop when we find a block that is void or non-existing block
DataPoint data;
int color;
int data;
byte flags;
for (int verticalIndex = 0; verticalIndex < lodDim.getMaxVerticalData(detailLevel, posX, posZ); verticalIndex++)
{
//we get the above block as adj UP
if (verticalIndex > 0)
adjData.get(LodDirection.UP)[0] = lodDim.getData(detailLevel, posX, posZ, verticalIndex - 1);
{
lodDim.getDataPoint(detailLevel, posX, posZ, verticalIndex - 1);
adjData.get(LodDirection.UP)[0] = ThreadMapUtil.dataPointData;
adjFlags.get(LodDirection.UP)[0] = ThreadMapUtil.dataPointFlags;
}
else
adjData.get(LodDirection.UP)[0] = DataPointUtil.EMPTY_DATA;
{
adjData.get(LodDirection.UP)[0] = 0;
adjFlags.get(LodDirection.UP)[0] = 0;
}
//we get the below block as adj DOWN
if (verticalIndex < lodDim.getMaxVerticalData(detailLevel, posX, posZ) - 1)
adjData.get(LodDirection.DOWN)[0] = lodDim.getData(detailLevel, posX, posZ, verticalIndex + 1);
{
lodDim.getDataPoint(detailLevel, posX, posZ, verticalIndex + 1);
adjData.get(LodDirection.DOWN)[0] = ThreadMapUtil.dataPointData;
adjFlags.get(LodDirection.DOWN)[0] = ThreadMapUtil.dataPointFlags;
}
else
adjData.get(LodDirection.DOWN)[0] = DataPointUtil.EMPTY_DATA;
{
adjData.get(LodDirection.DOWN)[0] = 0;
adjFlags.get(LodDirection.DOWN)[0] = 0;
}
//We extract the data to render
data = lodDim.getData(detailLevel, posX, posZ, verticalIndex);
lodDim.getDataPoint(detailLevel, posX, posZ, verticalIndex);
color = ThreadMapUtil.dataPointColor;
data = ThreadMapUtil.dataPointData;
flags = ThreadMapUtil.dataPointFlags;
//If the data is not renderable (Void or non-existing) we stop since there is no data left in this position
if (!DataPointUtil.doesItExist(data) || DataPointUtil.isVoid(data))
if (!DataPointUtil.doesItExist(flags) || DataPointUtil.isVoid(flags))
break;
//We send the call to create the vertices
CONFIG.client().graphics().advancedGraphics().getLodTemplate().template.addLodToBuffer(currentBuffers[bufferIndex], playerBlockPosRounded, data, adjData,
CONFIG.client().graphics().advancedGraphics().getLodTemplate().template.addLodToBuffer(currentBuffers[bufferIndex], playerBlockPosRounded, color, data, flags, adjData, adjFlags,
detailLevel, posX, posZ, box, renderer.previousDebugMode, adjShadeDisabled);
}
@@ -420,9 +447,7 @@ public class LodBufferBuilderFactory
// the thread executed successfully
return true;
};
nodeToRenderThreads.add(dataToRenderThread);
}
} // region z
} // region z
@@ -24,7 +24,6 @@ import java.util.Map;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.enums.rendering.DebugMode;
import com.seibel.lod.core.objects.Box;
import com.seibel.lod.core.objects.lod.DataPoint;
import com.seibel.lod.core.objects.opengl.LodBufferBuilder;
import com.seibel.lod.core.util.ColorUtil;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
@@ -38,7 +37,8 @@ import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
public abstract class AbstractLodTemplate
{
/** Uploads the given LOD to the buffer. */
public abstract void addLodToBuffer(LodBufferBuilder buffer, AbstractBlockPosWrapper bufferCenterBlockPos, DataPoint data, Map<LodDirection, DataPoint[]> adjData,
public abstract void addLodToBuffer(LodBufferBuilder buffer, AbstractBlockPosWrapper bufferCenterBlockPos, int color, int data, byte flags,
Map<LodDirection, int[]> adjData, Map<LodDirection, byte[]> adjFlags,
byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, boolean[] adjShadeDisabled);
/** add the given position and color to the buffer */
@@ -24,7 +24,6 @@ import java.util.Map;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.enums.rendering.DebugMode;
import com.seibel.lod.core.objects.Box;
import com.seibel.lod.core.objects.lod.DataPoint;
import com.seibel.lod.core.objects.opengl.LodBufferBuilder;
import com.seibel.lod.core.util.ColorUtil;
import com.seibel.lod.core.util.DataPointUtil;
@@ -45,7 +44,9 @@ public class CubicLodTemplate extends AbstractLodTemplate
}
@Override
public void addLodToBuffer(LodBufferBuilder buffer, AbstractBlockPosWrapper bufferCenterBlockPos, DataPoint data, Map<LodDirection, DataPoint[]> adjData,
public void addLodToBuffer(LodBufferBuilder buffer, AbstractBlockPosWrapper bufferCenterBlockPos,
int color, int data, byte flags,
Map<LodDirection, int[]> adjData, Map<LodDirection, byte[]> adjFlags,
byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, boolean[] adjShadeDisabled)
{
if (box == null)
@@ -54,12 +55,8 @@ public class CubicLodTemplate extends AbstractLodTemplate
// equivalent to 2^detailLevel
int blockWidth = 1 << detailLevel;
int color;
if (debugging != DebugMode.OFF)
color = LodUtil.DEBUG_DETAIL_LEVEL_COLORS[detailLevel].getRGB();
else
color = DataPointUtil.getColor(data);
generateBoundingBox(
box,
@@ -69,8 +66,9 @@ public class CubicLodTemplate extends AbstractLodTemplate
posX * blockWidth, 0, posZ * blockWidth, // x, y, z offset
bufferCenterBlockPos,
adjData,
adjFlags,
color,
DataPointUtil.getLightSkyAlt(data),
DataPointUtil.getLightSkyAlt(data, flags),
DataPointUtil.getLightBlock(data),
adjShadeDisabled);
@@ -81,7 +79,8 @@ public class CubicLodTemplate extends AbstractLodTemplate
int height, int depth, int width,
double xOffset, double yOffset, double zOffset,
AbstractBlockPosWrapper bufferCenterBlockPos,
Map<LodDirection, DataPoint[]> adjData,
Map<LodDirection, int[]> adjData,
Map<LodDirection, byte[]> adjFlags,
int color,
int skyLight,
int blockLight,
@@ -107,7 +106,7 @@ public class CubicLodTemplate extends AbstractLodTemplate
box.setWidth(width, height - depth, width);
box.setOffset((int) (xOffset + x), (int) (depth + yOffset), (int) (zOffset + z));
box.setUpCulling(32, bufferCenterBlockPos);
box.setAdjData(adjData);
box.setAdjData(adjData, adjFlags);
}
private void addBoundingBoxToBuffer(LodBufferBuilder buffer, Box box)
@@ -25,7 +25,6 @@ import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.enums.rendering.DebugMode;
import com.seibel.lod.core.objects.Box;
import com.seibel.lod.core.objects.lod.DataPoint;
import com.seibel.lod.core.objects.opengl.LodBufferBuilder;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
@@ -40,7 +39,8 @@ import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
public class DynamicLodTemplate extends AbstractLodTemplate
{
@Override
public void addLodToBuffer(LodBufferBuilder buffer, AbstractBlockPosWrapper bufferCenterBlockPos, DataPoint data, Map<LodDirection, DataPoint[]> adjData,
public void addLodToBuffer(LodBufferBuilder buffer, AbstractBlockPosWrapper bufferCenterBlockPos, int color, int data, byte flags,
Map<LodDirection, int[]> adjData, Map<LodDirection, byte[]> adjFlags,
byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, boolean[] adjShadeDisabled)
{
ClientApi.LOGGER.error(DynamicLodTemplate.class.getSimpleName() + " is not implemented!");
@@ -25,7 +25,6 @@ import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.enums.rendering.DebugMode;
import com.seibel.lod.core.objects.Box;
import com.seibel.lod.core.objects.lod.DataPoint;
import com.seibel.lod.core.objects.opengl.LodBufferBuilder;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
@@ -38,7 +37,8 @@ import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
public class TriangularLodTemplate extends AbstractLodTemplate
{
@Override
public void addLodToBuffer(LodBufferBuilder buffer, AbstractBlockPosWrapper bufferCenterBlockPos, DataPoint data, Map<LodDirection, DataPoint[]> adjData,
public void addLodToBuffer(LodBufferBuilder buffer, AbstractBlockPosWrapper bufferCenterBlockPos, int color, int data, byte flags,
Map<LodDirection, int[]> adjData, Map<LodDirection, byte[]> adjFlags,
byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, boolean[] adjShadeDisabled)
{
ClientApi.LOGGER.error(DynamicLodTemplate.class.getSimpleName() + " is not implemented!");
@@ -24,7 +24,6 @@ import java.util.concurrent.Executors;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.enums.config.HorizontalResolution;
import com.seibel.lod.core.objects.lod.DataPoint;
import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.objects.lod.LodRegion;
import com.seibel.lod.core.objects.lod.LodWorld;
@@ -196,105 +195,107 @@ import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
startX = detail.startX[i];
startZ = detail.startZ[i];
DataPoint[] data;
DataPoint[] dataToMergeVertical = createVerticalDataToMerge(detail, chunk, config, startX, startZ);
data = DataPointUtil.mergeMultiData(dataToMergeVertical, DataPointUtil.WORLD_HEIGHT / 2 + 1, DetailDistanceUtil.getMaxVerticalData(detailLevel));
// creates a vertical DataPoint
// equivalent to 2^detailLevel
int size = 1 << detail.detailLevel;
int[] dataToMergeColor = ThreadMapUtil.getBuilderVerticalArrayColor(detail.detailLevel);
int[] dataToMergeData = ThreadMapUtil.getBuilderVerticalArrayData(detail.detailLevel);
byte[] dataToMergeFlags = ThreadMapUtil.getBuilderVerticalArrayFlags(detail.detailLevel);
int verticalData = DataPointUtil.WORLD_HEIGHT / 2 + 1;
AbstractChunkPosWrapper chunkPos = chunk.getPos();
int height;
int depth;
int color;
int light;
int lightSky;
int lightBlock;
byte generation = config.distanceGenerationMode.complexity;
int xRel;
int zRel;
int xAbs;
int yAbs;
int zAbs;
boolean hasCeiling = MC.getWrappedClientWorld().getDimensionType().hasCeiling();
boolean hasSkyLight = MC.getWrappedClientWorld().getDimensionType().hasSkyLight();
boolean isDefault;
AbstractBlockPosWrapper blockPos = FACTORY.createBlockPos();
int index;
for (index = 0; index < size * size; index++)
{
xRel = startX + index % size;
zRel = startZ + index / size;
xAbs = chunkPos.getMinBlockX() + xRel;
zAbs = chunkPos.getMinBlockZ() + zRel;
//Calculate the height of the lod
yAbs = DataPointUtil.WORLD_HEIGHT - DataPointUtil.VERTICAL_OFFSET + 1;
int count = 0;
boolean topBlock = true;
while (yAbs > 0)
{
height = determineHeightPointFrom(chunk, config, xRel, yAbs, zRel, blockPos);
// If the lod is at the default height, it must be void data
if (height == DEFAULT_HEIGHT)
{
if (topBlock)
dataToMergeFlags[index * verticalData] = DataPointUtil.createVoidDataPoint(generation);
break;
}
yAbs = height - 1;
// We search light on above air block
depth = determineBottomPointFrom(chunk, config, xRel, yAbs, zRel, blockPos);
if (hasCeiling && topBlock)
{
yAbs = depth;
blockPos.set(xAbs, yAbs, zAbs);
light = getLightValue(chunk, blockPos, true, hasSkyLight, true);
color = generateLodColor(chunk, config, xAbs, yAbs, zAbs, blockPos);
blockPos.set(xAbs, yAbs - 1, zAbs);
}
else
{
blockPos.set(xAbs, yAbs, zAbs);
light = getLightValue(chunk, blockPos, hasCeiling, hasSkyLight, topBlock);
color = generateLodColor(chunk, config, xRel, yAbs, zRel, blockPos);
blockPos.set(xAbs, yAbs + 1, zAbs);
}
lightBlock = light & 0b1111;
lightSky = (light >> 4) & 0b1111;
isDefault = ((light >> 8)) == 1;
DataPointUtil.createDataPoint(height - DataPointUtil.VERTICAL_OFFSET, depth - DataPointUtil.VERTICAL_OFFSET, color, lightSky, lightBlock, generation, isDefault);
dataToMergeColor[index * verticalData + count] = ThreadMapUtil.dataPointColor;
dataToMergeData[index * verticalData + count] = ThreadMapUtil.dataPointData;
dataToMergeFlags[index * verticalData + count] = ThreadMapUtil.dataPointFlags;
topBlock = false;
yAbs = depth - 1;
count++;
}
}
DataPointUtil.mergeMultiData(dataToMergeColor, dataToMergeData, dataToMergeFlags, DataPointUtil.WORLD_HEIGHT / 2 + 1, DetailDistanceUtil.getMaxVerticalData(detailLevel));
int[] mergedColor = ThreadMapUtil.getRawVerticalDataArrayColor();
int[] mergedData = ThreadMapUtil.getRawVerticalDataArrayData();
byte[] mergedFlags = ThreadMapUtil.getRawVerticalDataArrayFlags();
//lodDim.clear(detailLevel, posX, posZ);
if (data != null && data.length != 0)
if (mergedFlags.length != 0)
{
posX = LevelPosUtil.convert((byte) 0, chunk.getPos().getX() * 16 + startX, detail.detailLevel);
posZ = LevelPosUtil.convert((byte) 0, chunk.getPos().getZ() * 16 + startZ, detail.detailLevel);
lodDim.addVerticalData(detailLevel, posX, posZ, data, false);
lodDim.addVerticalData(detailLevel, posX, posZ, mergedColor, mergedData, mergedFlags, false);
}
}
lodDim.updateData(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().getX(), chunk.getPos().getZ());
}
/** creates a vertical DataPoint */
private DataPoint[] createVerticalDataToMerge(HorizontalResolution detail, IChunkWrapper chunk, LodBuilderConfig config, int startX, int startZ)
{
// equivalent to 2^detailLevel
int size = 1 << detail.detailLevel;
DataPoint[] dataToMerge = ThreadMapUtil.getBuilderVerticalArray(detail.detailLevel);
int verticalData = DataPointUtil.WORLD_HEIGHT / 2 + 1;
AbstractChunkPosWrapper chunkPos = chunk.getPos();
int height;
int depth;
int color;
int light;
int lightSky;
int lightBlock;
int generation = config.distanceGenerationMode.complexity;
int xRel;
int zRel;
int xAbs;
int yAbs;
int zAbs;
boolean hasCeiling = MC.getWrappedClientWorld().getDimensionType().hasCeiling();
boolean hasSkyLight = MC.getWrappedClientWorld().getDimensionType().hasSkyLight();
boolean isDefault;
AbstractBlockPosWrapper blockPos = FACTORY.createBlockPos();
int index;
for (index = 0; index < size * size; index++)
{
xRel = startX + index % size;
zRel = startZ + index / size;
xAbs = chunkPos.getMinBlockX() + xRel;
zAbs = chunkPos.getMinBlockZ() + zRel;
//Calculate the height of the lod
yAbs = DataPointUtil.WORLD_HEIGHT - DataPointUtil.VERTICAL_OFFSET + 1;
int count = 0;
boolean topBlock = true;
while (yAbs > 0)
{
height = determineHeightPointFrom(chunk, config, xRel, yAbs, zRel, blockPos);
// If the lod is at the default height, it must be void data
if (height == DEFAULT_HEIGHT)
{
if (topBlock)
dataToMerge[index * verticalData] = DataPointUtil.createVoidDataPoint(generation);
break;
}
yAbs = height - 1;
// We search light on above air block
depth = determineBottomPointFrom(chunk, config, xRel, yAbs, zRel, blockPos);
if (hasCeiling && topBlock)
{
yAbs = depth;
blockPos.set(xAbs, yAbs, zAbs);
light = getLightValue(chunk, blockPos, true, hasSkyLight, true);
color = generateLodColor(chunk, config, xAbs, yAbs, zAbs, blockPos);
blockPos.set(xAbs, yAbs - 1, zAbs);
}
else
{
blockPos.set(xAbs, yAbs, zAbs);
light = getLightValue(chunk, blockPos, hasCeiling, hasSkyLight, topBlock);
color = generateLodColor(chunk, config, xRel, yAbs, zRel, blockPos);
blockPos.set(xAbs, yAbs + 1, zAbs);
}
lightBlock = light & 0b1111;
lightSky = (light >> 4) & 0b1111;
isDefault = ((light >> 8)) == 1;
dataToMerge[index * verticalData + count] = DataPointUtil.createDataPoint(height - DataPointUtil.VERTICAL_OFFSET, depth - DataPointUtil.VERTICAL_OFFSET, color, lightSky, lightBlock, generation, isDefault);
topBlock = false;
yAbs = depth - 1;
count++;
}
}
return dataToMerge;
}
/**
* Find the lowest valid point from the bottom.
* Used when creating a vertical LOD.
@@ -25,7 +25,6 @@ import java.util.Map;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.enums.rendering.DebugMode;
import com.seibel.lod.core.objects.lod.DataPoint;
import com.seibel.lod.core.objects.math.Vec3i;
import com.seibel.lod.core.util.ColorUtil;
import com.seibel.lod.core.util.DataPointUtil;
@@ -340,25 +339,27 @@ public class Box
* This method create all the shared face culling based on the adjacent data
* @param adjData data adjacent to the column we are going to render
*/
public void setAdjData(Map<LodDirection, DataPoint[]> adjData)
public void setAdjData(Map<LodDirection, int[]> adjData, Map<LodDirection, byte[]> adjFlags)
{
int height;
int depth;
int minY = getMinY();
int maxY = getMaxY();
DataPoint singleAdjDataPoint;
int singleAdjData;
byte singleAdjFlags;
/* TODO implement attached vertical face culling
//Up direction case
if(DataPointUtil.doesItExist(adjData.get(Direction.UP)))
{
height = DataPointUtil.getHeight(singleAdjDataPoint);
depth = DataPointUtil.getDepth(singleAdjDataPoint);
height = DataPointUtil.getHeight(singleAdjData);
depth = DataPointUtil.getDepth(singleAdjData);
}*/
//Down direction case
singleAdjDataPoint = adjData.get(LodDirection.DOWN)[0];
if(DataPointUtil.doesItExist(singleAdjDataPoint))
skyLights.get(LodDirection.DOWN)[0] = DataPointUtil.getLightSkyAlt(singleAdjDataPoint);
singleAdjData = adjData.get(LodDirection.DOWN)[0];
singleAdjFlags = adjFlags.get(LodDirection.DOWN)[0];
if(DataPointUtil.doesItExist(singleAdjFlags))
skyLights.get(LodDirection.DOWN)[0] = DataPointUtil.getLightSkyAlt(singleAdjData, singleAdjFlags);
else
skyLights.get(LodDirection.DOWN)[0] = skyLights.get(LodDirection.UP)[0];
//other sided
@@ -368,8 +369,9 @@ public class Box
if (isCulled(lodDirection))
continue;
DataPoint[] dataPoint = adjData.get(lodDirection);
if (DataPointUtil.isVoid(dataPoint[0]))
int[] data = adjData.get(lodDirection);
byte[] flags = adjFlags.get(lodDirection);
if (DataPointUtil.isVoid(flags[0]))
{
adjHeight.get(lodDirection)[0] = maxY;
adjDepth.get(lodDirection)[0] = minY;
@@ -385,15 +387,16 @@ public class Box
boolean toFinish = false;
int toFinishIndex = 0;
boolean allAbove = true;
for (i = 0; i < dataPoint.length; i++)
for (i = 0; i < flags.length; i++)
{
singleAdjDataPoint = dataPoint[i];
singleAdjData = data[i];
singleAdjFlags = flags[i];
if (DataPointUtil.isVoid(singleAdjDataPoint) || !DataPointUtil.doesItExist(singleAdjDataPoint))
if (DataPointUtil.isVoid(singleAdjFlags) || !DataPointUtil.doesItExist(singleAdjFlags))
break;
height = DataPointUtil.getHeight(singleAdjDataPoint);
depth = DataPointUtil.getDepth(singleAdjDataPoint);
height = DataPointUtil.getHeight(singleAdjData);
depth = DataPointUtil.getDepth(singleAdjData);
if (depth <= maxY)
{
@@ -406,12 +409,12 @@ public class Box
{
adjHeight.get(lodDirection)[0] = getMaxY();
adjDepth.get(lodDirection)[0] = getMinY();
skyLights.get(lodDirection)[0] = DataPointUtil.getLightSkyAlt(singleAdjDataPoint); //skyLights.get(Direction.UP)[0];
skyLights.get(lodDirection)[0] = DataPointUtil.getLightSkyAlt(singleAdjData, singleAdjFlags); //skyLights.get(Direction.UP)[0];
}
else
{
adjDepth.get(lodDirection)[faceToDraw] = getMinY();
skyLights.get(lodDirection)[faceToDraw] = DataPointUtil.getLightSkyAlt(singleAdjDataPoint);
skyLights.get(lodDirection)[faceToDraw] = DataPointUtil.getLightSkyAlt(singleAdjData, singleAdjFlags);
}
faceToDraw++;
toFinish = false;
@@ -437,12 +440,12 @@ public class Box
{
adjHeight.get(lodDirection)[0] = getMaxY();
adjDepth.get(lodDirection)[0] = height;
skyLights.get(lodDirection)[0] = DataPointUtil.getLightSkyAlt(singleAdjDataPoint); //skyLights.get(Direction.UP)[0];
skyLights.get(lodDirection)[0] = DataPointUtil.getLightSkyAlt(singleAdjData, singleAdjFlags); //skyLights.get(Direction.UP)[0];
}
else
{
adjDepth.get(lodDirection)[faceToDraw] = height;
skyLights.get(lodDirection)[faceToDraw] = DataPointUtil.getLightSkyAlt(singleAdjDataPoint);
skyLights.get(lodDirection)[faceToDraw] = DataPointUtil.getLightSkyAlt(singleAdjData, singleAdjFlags);
}
toFinish = false;
faceToDraw++;
@@ -454,7 +457,7 @@ public class Box
// the adj data intersects the higher part of the current data
// we start the creation of a new face
adjHeight.get(lodDirection)[faceToDraw] = depth;
//skyLights.get(direction)[faceToDraw] = (byte) DataPointUtil.getLightSkyAlt(singleAdjDataPoint);
//skyLights.get(direction)[faceToDraw] = (byte) DataPointUtil.getLightSkyAlt(singleAdjData);
firstFace = false;
toFinish = true;
toFinishIndex = i + 1;
@@ -470,7 +473,7 @@ public class Box
}
adjDepth.get(lodDirection)[faceToDraw] = height;
skyLights.get(lodDirection)[faceToDraw] = DataPointUtil.getLightSkyAlt(singleAdjDataPoint);
skyLights.get(lodDirection)[faceToDraw] = DataPointUtil.getLightSkyAlt(singleAdjData, singleAdjFlags);
faceToDraw++;
adjHeight.get(lodDirection)[faceToDraw] = depth;
firstFace = false;
@@ -490,11 +493,12 @@ public class Box
else if (toFinish)
{
adjDepth.get(lodDirection)[faceToDraw] = minY;
if(toFinishIndex < dataPoint.length)
if(toFinishIndex < flags.length)
{
singleAdjDataPoint = dataPoint[toFinishIndex];
if (DataPointUtil.doesItExist(singleAdjDataPoint))
skyLights.get(lodDirection)[faceToDraw] = DataPointUtil.getLightSkyAlt(singleAdjDataPoint);
singleAdjData = data[toFinishIndex];
singleAdjFlags = flags[toFinishIndex];
if (DataPointUtil.doesItExist(singleAdjFlags))
skyLights.get(lodDirection)[faceToDraw] = DataPointUtil.getLightSkyAlt(singleAdjData, singleAdjFlags);
else
skyLights.get(lodDirection)[faceToDraw] = skyLights.get(LodDirection.UP)[0];
}
@@ -1,39 +0,0 @@
package com.seibel.lod.core.objects.lod;
public class DataPoint
{
public int color;
// |a |a |a |a |a |a |a |a |
// |r |r |r |r |r |r |r |r |
// |g |g |g |g |g |g |g |g |
// |b |b |b |b |b |b |b |b |
public int data;
// |h |h |h |h |h |h |h |h |
// |h |h |h |h |d |d |d |d |
// |d |d |d |d |d |d |d |d |
// |bl |bl |bl |bl |sl |sl |sl |sl |
public byte flags;
// |l |l |f |g |g |g |v |e |
public DataPoint()
{
color = 0;
data = 0;
flags = 0;
}
public DataPoint(int newColor, int newData, byte newFlags)
{
color = newColor;
data = newData;
flags = newFlags;
}
public void clear()
{
color = 0;
data = 0;
flags = 0;
}
}
@@ -32,7 +32,7 @@ public interface LevelContainer
* @param index z position in the detail level
* @return true if correctly added, false otherwise
*/
boolean addData(DataPoint data, int posX, int posZ, int index);
boolean addData(int color, int data, byte flags, int posX, int posZ, int index);
/**
* With this you can add data to the level container
@@ -41,7 +41,7 @@ public interface LevelContainer
* @param posZ z position in the detail level
* @return true if correctly added, false otherwise
*/
boolean addVerticalData(DataPoint[] data, int posX, int posZ);
boolean addVerticalData(int[] color, int[] data, byte[] flags, int posX, int posZ);
/**
* With this you can add data to the level container
@@ -50,25 +50,32 @@ public interface LevelContainer
* @param posZ z position in the detail level
* @return true if correctly added, false otherwise
*/
boolean addSingleData(DataPoint data, int posX, int posZ);
boolean addSingleData(int color, int data, byte flags, int posX, int posZ);
/**
* With this you can get data from the level container
* data is returned to ThreadMapUtil variables
* @param posX x position in the detail level
* @param posZ z position in the detail level
* @return the data in long array format
*/
DataPoint getData(int posX, int posZ, int index);
void getDataPoint(int posX, int posZ, int index);
/**
* With this you can get data from the level container
* data is returned to ThreadMapUtil variables
* @param posX x position in the detail level
* @param posZ z position in the detail level
* @return the data in long array format
*/
DataPoint getSingleData(int posX, int posZ);
void getSingleDataPoint(int posX, int posZ);
int getData(int posX, int posZ, int index);
byte getFlags(int posX, int posZ, int index);
byte getSingleFlags(int posX, int posZ);
/**
* data is returned to ThreadMapUtil variables
* @param posX x position in the detail level
* @param posZ z position in the detail level
* @return true only if the data exist
@@ -30,12 +30,7 @@ import com.seibel.lod.core.enums.config.VerticalQuality;
import com.seibel.lod.core.handlers.LodDimensionFileHandler;
import com.seibel.lod.core.objects.PosToGenerateContainer;
import com.seibel.lod.core.objects.PosToRenderContainer;
import com.seibel.lod.core.util.DataPointUtil;
import com.seibel.lod.core.util.DetailDistanceUtil;
import com.seibel.lod.core.util.LevelPosUtil;
import com.seibel.lod.core.util.LodThreadFactory;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.util.SingletonHandler;
import com.seibel.lod.core.util.*;
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
@@ -445,7 +440,7 @@ public class LodDimension
* stored in the LOD. If an LOD already exists at the given
* coordinate it will be overwritten.
*/
public Boolean addData(byte detailLevel, int posX, int posZ, int verticalIndex, DataPoint data, boolean dontSave)
public Boolean addData(byte detailLevel, int posX, int posZ, int verticalIndex, int color, int data, byte flags, boolean dontSave)
{
int regionPosX = LevelPosUtil.getRegion(detailLevel, posX);
int regionPosZ = LevelPosUtil.getRegion(detailLevel, posZ);
@@ -455,7 +450,7 @@ public class LodDimension
if (region == null)
return false;
boolean nodeAdded = region.addData(detailLevel, posX, posZ, verticalIndex, data);
boolean nodeAdded = region.addData(detailLevel, posX, posZ, verticalIndex, color, data, flags);
// only save valid LODs to disk
if (!dontSave && fileHandler != null)
@@ -487,7 +482,7 @@ public class LodDimension
* stored in the LOD. If an LOD already exists at the given
* coordinate it will be overwritten.
*/
public Boolean addVerticalData(byte detailLevel, int posX, int posZ, DataPoint[] data, boolean dontSave)
public Boolean addVerticalData(byte detailLevel, int posX, int posZ, int[] color, int[] data, byte[] flags, boolean dontSave)
{
int regionPosX = LevelPosUtil.getRegion(detailLevel, posX);
int regionPosZ = LevelPosUtil.getRegion(detailLevel, posZ);
@@ -497,7 +492,7 @@ public class LodDimension
if (region == null)
return false;
boolean nodeAdded = region.addVerticalData(detailLevel, posX, posZ, data);
boolean nodeAdded = region.addVerticalData(detailLevel, posX, posZ, color, data, flags);
// only save valid LODs to disk
if (!dontSave && fileHandler != null)
@@ -566,7 +561,9 @@ public class LodDimension
byte detailLevel;
int posX;
int posZ;
DataPoint data;
int color;
int data;
byte flags;
int numbChunksWide = (width) * 32;
int circleLimit = Integer.MAX_VALUE;
@@ -614,11 +611,12 @@ public class LodDimension
posX = LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, xChunkToCheck, detailLevel);
posZ = LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, zChunkToCheck, detailLevel);
data = getSingleData(detailLevel, posX, posZ);
getSingleDataPoint(detailLevel, posX, posZ);
flags = ThreadMapUtil.dataPointFlags;
//we will generate the position only if the current generation complexity is lower than the target one.
//an un-generated area will always have 0 generation
if (data != null && DataPointUtil.getGenerationMode(data) < complexity)
if (DataPointUtil.getGenerationMode(flags) < complexity)
{
posToGenerate.addPosToGenerate(detailLevel, posX, posZ);
if (maxDataToGenerate >= 0)
@@ -712,18 +710,41 @@ public class LodDimension
* Returns null if the LodChunk doesn't exist or
* is outside the loaded area.
*/
public DataPoint getData(byte detailLevel, int posX, int posZ, int verticalIndex)
public void getDataPoint(byte detailLevel, int posX, int posZ, int verticalIndex)
{
if (detailLevel > LodUtil.REGION_DETAIL_LEVEL)
throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
LodRegion region = getRegion(detailLevel, posX, posZ);
if (region == null)
return DataPointUtil.EMPTY_DATA;
return region.getData(detailLevel, posX, posZ, verticalIndex);
ThreadMapUtil.saveDataPoint(0,0, (byte) 0);
else
region.getDataPoint(detailLevel, posX, posZ, verticalIndex);
}
public int getData(byte detailLevel, int posX, int posZ, int verticalIndex)
{
if (detailLevel > LodUtil.REGION_DETAIL_LEVEL)
throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
LodRegion region = getRegion(detailLevel, posX, posZ);
if (region == null)
return 0;
else
return region.getData(detailLevel, posX, posZ, verticalIndex);
}
public byte getFlags(byte detailLevel, int posX, int posZ, int verticalIndex)
{
if (detailLevel > LodUtil.REGION_DETAIL_LEVEL)
throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
LodRegion region = getRegion(detailLevel, posX, posZ);
if (region == null)
return 0;
else
return region.getFlags(detailLevel, posX, posZ, verticalIndex);
}
/**
* Get the data point at the given X and Z coordinates
@@ -732,16 +753,28 @@ public class LodDimension
* Returns null if the LodChunk doesn't exist or
* is outside the loaded area.
*/
public DataPoint getSingleData(byte detailLevel, int posX, int posZ)
public void getSingleDataPoint(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.");
LodRegion region = getRegion(detailLevel, posX, posZ);
if (region == null)
return DataPointUtil.EMPTY_DATA;
return region.getSingleData(detailLevel, posX, posZ);
ThreadMapUtil.saveDataPoint(0, 0, (byte) 0);
else
region.getSingleDataPoint(detailLevel, posX, posZ);
}
public byte getSingleFlags(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.");
LodRegion region = getRegion(detailLevel, posX, posZ);
if (region == null)
return (byte) 0;
else
return region.getSingleFlags(detailLevel, posX, posZ);
}
/** Clears the given region */
@@ -154,7 +154,7 @@ public class LodRegion
* TODO this will always return true unless it has
* @return true if the data was added successfully
*/
public boolean addData(byte detailLevel, int posX, int posZ, int verticalIndex, DataPoint data)
public boolean addData(byte detailLevel, int posX, int posZ, int verticalIndex, int color, int data, byte flags)
{
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
@@ -166,7 +166,7 @@ public class LodRegion
this.dataContainer[detailLevel] = new VerticalLevelContainer(detailLevel);
}
this.dataContainer[detailLevel].addData(data, posX, posZ, verticalIndex);
this.dataContainer[detailLevel].addData(color, data, flags, posX, posZ, verticalIndex);
return true;
}
@@ -177,7 +177,7 @@ public class LodRegion
* TODO this will always return true unless it has
* @return true if the data was added successfully
*/
public boolean addVerticalData(byte detailLevel, int posX, int posZ, DataPoint[] data)
public boolean addVerticalData(byte detailLevel, int posX, int posZ, int[] color, int[] data, byte[] flags)
{
//position is already relative
//posX = LevelPosUtil.getRegionModule(detailLevel, posX);
@@ -188,7 +188,7 @@ public class LodRegion
if (this.dataContainer[detailLevel] == null)
this.dataContainer[detailLevel] = new VerticalLevelContainer(detailLevel);
return this.dataContainer[detailLevel].addVerticalData(data, posX, posZ);
return this.dataContainer[detailLevel].addVerticalData(color, data, flags, posX, posZ);
}
/**
@@ -196,21 +196,42 @@ public class LodRegion
* @return the data at the relative pos and detail level,
* 0 if the data doesn't exist.
*/
public DataPoint getData(byte detailLevel, int posX, int posZ, int verticalIndex)
public void getDataPoint(byte detailLevel, int posX, int posZ, int verticalIndex)
{
dataContainer[detailLevel].getDataPoint(posX, posZ, verticalIndex);
}
public int getData(byte detailLevel, int posX, int posZ, int verticalIndex)
{
return dataContainer[detailLevel].getData(posX, posZ, verticalIndex);
}
public byte getFlags(byte detailLevel, int posX, int posZ, int verticalIndex)
{
return dataContainer[detailLevel].getFlags(posX, posZ, verticalIndex);
}
/**
* Get the dataPoint at the given relative position.
* @return the data at the relative pos and detail level,
* 0 if the data doesn't exist.
*/
public DataPoint getSingleData(byte detailLevel, int posX, int posZ)
public void getSingleDataPoint(byte detailLevel, int posX, int posZ)
{
return dataContainer[detailLevel].getSingleData(posX, posZ);
dataContainer[detailLevel].getSingleDataPoint(posX, posZ);
}
/**
* Get the flags at the given relative position.
* @return the data at the relative pos and detail level,
* 0 if the data doesn't exist.
*/
public byte getSingleFlags(byte detailLevel, int posX, int posZ)
{
return dataContainer[detailLevel].getSingleFlags(posX, posZ);
}
/**
* Clears the datapoint at the given relative position
*/
@@ -358,6 +379,7 @@ public class LodRegion
posZ + regionPosZ * size);
}
else
{
//if (desiredLevel > detailLevel)
//{
// we have gone beyond the target Detail level
@@ -408,6 +430,7 @@ public class LodRegion
}
}
}
}
}
@@ -479,7 +502,7 @@ public class LodRegion
if (dataContainer[detailLevel].doesItExist(posX, posZ))
// We take the bottom information always
// TODO what does that mean? bottom of what?
return DataPointUtil.getGenerationMode(dataContainer[detailLevel].getSingleData(posX, posZ));
return DataPointUtil.getGenerationMode(dataContainer[detailLevel].getSingleFlags(posX, posZ));
else
return DistanceGenerationMode.NONE.complexity;
}
@@ -37,14 +37,19 @@ public class VerticalLevelContainer implements LevelContainer
public final int size;
public final int maxVerticalData;
public final DataPoint[] dataContainer;
public final int[] dataContainerColor;
public final int[] dataContainerData;
public final byte[] dataContainerFlags;
public VerticalLevelContainer(byte detailLevel)
{
this.detailLevel = detailLevel;
size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel);
maxVerticalData = DetailDistanceUtil.getMaxVerticalData(detailLevel);
dataContainer = new DataPoint[size * size * DetailDistanceUtil.getMaxVerticalData(detailLevel)];
final int i = size * size * maxVerticalData;
dataContainerColor = new int[i];
dataContainerData = new int[i];
dataContainerFlags = new byte[i];
}
@Override
@@ -60,47 +65,79 @@ public class VerticalLevelContainer implements LevelContainer
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
for (int verticalIndex = 0; verticalIndex < maxVerticalData; verticalIndex++)
{
dataContainer[posX * size * maxVerticalData + posZ * maxVerticalData + verticalIndex] = DataPointUtil.EMPTY_DATA;
final int i = (posX * size + posZ) * maxVerticalData + verticalIndex;
dataContainerColor[i] = 0;
dataContainerData[i] = 0;
dataContainerFlags[i] = 0;
}
}
@Override
public boolean addData(DataPoint data, int posX, int posZ, int verticalIndex)
public boolean addData(int color, int data, byte flags, int posX, int posZ, int verticalIndex)
{
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
dataContainer[posX * size * maxVerticalData + posZ * maxVerticalData + verticalIndex] = data;
final int i = (posX * size + posZ) * maxVerticalData + verticalIndex;
dataContainerColor[i] = color;
dataContainerData[i] = data;
dataContainerFlags[i] = flags;
return true;
}
@Override
public boolean addVerticalData(DataPoint[] data, int posX, int posZ)
public boolean addVerticalData(int[] color, int[] data, byte[] flags, int posX, int posZ)
{
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
for (int verticalIndex = 0; verticalIndex < maxVerticalData; verticalIndex++)
dataContainer[posX * size * maxVerticalData + posZ * maxVerticalData + verticalIndex] = data[verticalIndex];
{
final int i = (posX * size + posZ) * maxVerticalData + verticalIndex;
dataContainerColor[i] = color[verticalIndex];
dataContainerData[i] = data[verticalIndex];
dataContainerFlags[i] = flags[verticalIndex];
}
return true;
}
@Override
public boolean addSingleData(DataPoint data, int posX, int posZ)
public boolean addSingleData(int color, int data, byte flags, int posX, int posZ)
{
return addData(data, posX, posZ, 0);
return addData(color, data, flags, posX, posZ, 0);
}
@Override
public DataPoint getData(int posX, int posZ, int verticalIndex)
public void getDataPoint(int posX, int posZ, int verticalIndex)
{
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
return dataContainer[posX * size * maxVerticalData + posZ * maxVerticalData + verticalIndex];
final int i = (posX * size + posZ) * maxVerticalData + verticalIndex;
ThreadMapUtil.saveDataPoint(dataContainerColor[i], dataContainerData[i], dataContainerFlags[i]);
}
@Override
public DataPoint getSingleData(int posX, int posZ)
public void getSingleDataPoint(int posX, int posZ)
{
return getData(posX, posZ, 0);
getDataPoint(posX, posZ, 0);
}
@Override
public int getData(int posX, int posZ, int verticalIndex)
{
return dataContainerData[(posX * size + posZ) * maxVerticalData + verticalIndex];
}
@Override
public byte getFlags(int posX, int posZ, int verticalIndex)
{
return dataContainerFlags[(posX * size + posZ) * maxVerticalData + verticalIndex];
}
@Override
public byte getSingleFlags(int posX, int posZ)
{
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
return dataContainerFlags[(posX * size + posZ) * maxVerticalData];
}
@Override
@@ -119,7 +156,7 @@ public class VerticalLevelContainer implements LevelContainer
{
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
return DataPointUtil.doesItExist(getSingleData(posX, posZ));
return DataPointUtil.doesItExist(dataContainerFlags[(posX * size + posZ) * maxVerticalData]);
}
public VerticalLevelContainer(byte[] inputData, int version)
@@ -133,7 +170,9 @@ public class VerticalLevelContainer implements LevelContainer
index++;
size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel);
int x = size * size * tempMaxVerticalData;
DataPoint[] tempDataContainer = new DataPoint[x];
int[] tempDataContainerColor = new int[x];
int[] tempDataContainerData = new int[x];
byte[] tempDataContainerFlags = new byte[x];
if (version == 6)
{
@@ -154,7 +193,7 @@ public class VerticalLevelContainer implements LevelContainer
|bl |bl |bl |bl |sl |sl |sl |sl |
|l |l |f |g |g |g |v |e |
*/
DataPoint newData = DataPointUtil.createDataPoint(
DataPointUtil.createDataPoint(
(int)((oldData >> 60) << 4) + 15,
(int)(oldData >> 52) & 0xFF,
(int)(oldData >> 44) & 0xFF,
@@ -166,7 +205,9 @@ public class VerticalLevelContainer implements LevelContainer
(int)(oldData >> 5) & 0x1,
((oldData >> 5) & 0x1) == 1
);
tempDataContainer[i] = newData;
tempDataContainerColor[i] = ThreadMapUtil.dataPointColor;
tempDataContainerData[i] = ThreadMapUtil.dataPointData;
tempDataContainerFlags[i] = ThreadMapUtil.dataPointFlags;
}
}
else if (version == 7)
@@ -178,7 +219,7 @@ public class VerticalLevelContainer implements LevelContainer
for (tempIndex = 0; tempIndex < 8; tempIndex++)
oldData += (((long) inputData[index + tempIndex]) & 0xff) << (8 * tempIndex);
index += 8;
DataPoint newData = DataPointUtil.createDataPoint(
DataPointUtil.createDataPoint(
(int)((oldData >> 60) << 4) + 15,
(int)(oldData >> 52) & 0xFF,
(int)(oldData >> 44) & 0xFF,
@@ -190,7 +231,9 @@ public class VerticalLevelContainer implements LevelContainer
(int)(oldData >> 5) & 0x1,
((oldData >> 5) & 0x1) == 1
);
tempDataContainer[i] = newData;
tempDataContainerColor[i] = ThreadMapUtil.dataPointColor;
tempDataContainerData[i] = ThreadMapUtil.dataPointData;
tempDataContainerFlags[i] = ThreadMapUtil.dataPointFlags;
}
}
else //if (version == 8)
@@ -210,28 +253,42 @@ public class VerticalLevelContainer implements LevelContainer
}
index += 8;
tempDataContainer[i] = new DataPoint(color, data, flags);
tempDataContainerColor[i] = color;
tempDataContainerData[i] = data;
tempDataContainerFlags[i] = flags;
}
}
if (tempMaxVerticalData > DetailDistanceUtil.getMaxVerticalData(detailLevel))
{
int tempMaxVerticalData2 = DetailDistanceUtil.getMaxVerticalData(detailLevel);
DataPoint[] dataToMerge = new DataPoint[tempMaxVerticalData];
DataPoint[] tempDataContainer2 = new DataPoint[size * size * tempMaxVerticalData2];
int[] dataToMergeColor = new int[tempMaxVerticalData];
int[] dataToMergeData = new int[tempMaxVerticalData];
byte[] dataToMergeFlags = new byte[tempMaxVerticalData];
int[] tempDataContainer2Color = new int[size * size * tempMaxVerticalData2];
int[] tempDataContainer2Data = new int[size * size * tempMaxVerticalData2];
byte[] tempDataContainer2Flags = new byte[size * size * tempMaxVerticalData2];
for (int i = 0; i < size * size; i++)
{
System.arraycopy(tempDataContainer, i * tempMaxVerticalData, dataToMerge, 0, tempMaxVerticalData);
dataToMerge = DataPointUtil.mergeMultiData(dataToMerge, tempMaxVerticalData, tempMaxVerticalData2);
System.arraycopy(dataToMerge, 0, tempDataContainer2, i * tempMaxVerticalData2, tempMaxVerticalData2);
System.arraycopy(tempDataContainerColor, i * tempMaxVerticalData, dataToMergeColor, 0, tempMaxVerticalData);
System.arraycopy(tempDataContainerData, i * tempMaxVerticalData, dataToMergeData, 0, tempMaxVerticalData);
System.arraycopy(tempDataContainerFlags, i * tempMaxVerticalData, dataToMergeFlags, 0, tempMaxVerticalData);
DataPointUtil.mergeMultiData(dataToMergeColor, dataToMergeData, dataToMergeFlags, tempMaxVerticalData, tempMaxVerticalData2);
System.arraycopy(ThreadMapUtil.getRawVerticalDataArrayColor(), 0, tempDataContainer2Color, i * tempMaxVerticalData2, tempMaxVerticalData2);
System.arraycopy(ThreadMapUtil.getRawVerticalDataArrayData(), 0, tempDataContainer2Data, i * tempMaxVerticalData2, tempMaxVerticalData2);
System.arraycopy(ThreadMapUtil.getRawVerticalDataArrayFlags(), 0, tempDataContainer2Flags, i * tempMaxVerticalData2, tempMaxVerticalData2);
}
maxVerticalData = tempMaxVerticalData2;
this.dataContainer = tempDataContainer2;
this.dataContainerColor = tempDataContainer2Color;
this.dataContainerData = tempDataContainer2Data;
this.dataContainerFlags = tempDataContainer2Flags;
}
else
{
maxVerticalData = tempMaxVerticalData;
this.dataContainer = tempDataContainer;
this.dataContainerColor = tempDataContainerColor;
this.dataContainerData = tempDataContainerData;
this.dataContainerFlags = tempDataContainerFlags;
}
}
@@ -245,12 +302,13 @@ public class VerticalLevelContainer implements LevelContainer
public void updateData(LevelContainer lowerLevelContainer, int posX, int posZ)
{
//We reset the array
DataPoint[] dataToMerge = ThreadMapUtil.getVerticalUpdateArray(detailLevel);
int[] dataToMergeColor = ThreadMapUtil.getVerticalUpdateArrayColor(detailLevel);
int[] dataToMergeData = ThreadMapUtil.getVerticalUpdateArrayData(detailLevel);
byte[] dataToMergeFlags = ThreadMapUtil.getVerticalUpdateArrayFlags(detailLevel);
int lowerMaxVertical = dataToMerge.length / 4;
int lowerMaxVertical = dataToMergeFlags.length / 4;
int childPosX;
int childPosZ;
DataPoint[] data;
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
for (int x = 0; x <= 1; x++)
@@ -260,12 +318,17 @@ public class VerticalLevelContainer implements LevelContainer
childPosX = 2 * posX + x;
childPosZ = 2 * posZ + z;
for (int verticalIndex = 0; verticalIndex < lowerMaxVertical; verticalIndex++)
dataToMerge[(z * 2 + x) * lowerMaxVertical + verticalIndex] = lowerLevelContainer.getData(childPosX, childPosZ, verticalIndex);
{
lowerLevelContainer.getDataPoint(childPosX, childPosZ, verticalIndex);
final int i = (z * 2 + x) * lowerMaxVertical + verticalIndex;
dataToMergeColor[i] = ThreadMapUtil.dataPointColor;
dataToMergeData[i] = ThreadMapUtil.dataPointData;
dataToMergeFlags[i] = ThreadMapUtil.dataPointFlags;
}
}
}
data = DataPointUtil.mergeMultiData(dataToMerge, lowerMaxVertical, getMaxVerticalData());
addVerticalData(data, posX, posZ);
DataPointUtil.mergeMultiData(dataToMergeColor, dataToMergeData, dataToMergeFlags, lowerMaxVertical, getMaxVerticalData());
addVerticalData(ThreadMapUtil.getRawVerticalDataArrayColor(), ThreadMapUtil.getRawVerticalDataArrayData(), ThreadMapUtil.getRawVerticalDataArrayFlags(), posX, posZ);
}
@Override
@@ -274,7 +337,8 @@ public class VerticalLevelContainer implements LevelContainer
int index = 0;
int x = size * size;
int tempIndex;
DataPoint current;
int currentColor;
int currentData;
boolean allGenerated = true;
byte[] tempData = ThreadMapUtil.getSaveContainer(detailLevel);
@@ -287,20 +351,18 @@ public class VerticalLevelContainer implements LevelContainer
{
for (j = 0; j < maxVerticalData; j++)
{
current = dataContainer[i * maxVerticalData + j];
if (current != null)
currentColor = dataContainerColor[i * maxVerticalData + j];
currentData = dataContainerData[i * maxVerticalData + j];
tempData[index] = dataContainerFlags[i * maxVerticalData + j];
index++;
for (tempIndex = 0; tempIndex < 4; tempIndex++)
{
tempData[index] = current.flags;
index++;
for (tempIndex = 0; tempIndex < 4; tempIndex++)
{
tempData[index + tempIndex] = (byte) (current.data >>> (8 * tempIndex));
tempData[index + tempIndex + 4] = (byte) (current.color >>> (8 * tempIndex));
}
tempData[index + tempIndex] = (byte) (currentData >>> (8 * tempIndex));
tempData[index + tempIndex + 4] = (byte) (currentColor >>> (8 * tempIndex));
}
index += 8;
}
if(dataContainer[i] == null || !DataPointUtil.doesItExist(dataContainer[i]))
if(!DataPointUtil.doesItExist(dataContainerFlags[i]))
allGenerated = false;
}
if (allGenerated)
@@ -22,7 +22,6 @@ package com.seibel.lod.core.util;
import static com.seibel.lod.core.builders.bufferBuilding.LodBufferBuilderFactory.skyLightPlayer;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.objects.lod.DataPoint;
/**
*
@@ -58,7 +57,7 @@ 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 DataPoint EMPTY_DATA = new DataPoint();
public final static byte EMPTY_DATA = 0;
public static final short VERTICAL_OFFSET = -2048;
public static int WORLD_HEIGHT = 4096;
@@ -103,16 +102,17 @@ public class DataPointUtil
public final static byte VOID_MASK = 1;
public final static byte EXISTENCE_MASK = 1;
public static DataPoint createVoidDataPoint(int generationMode)
/** Returns the Flags byte */
public static byte createVoidDataPoint(byte generationMode)
{
byte flags = (byte) ((generationMode & GEN_TYPE_MASK) << GEN_TYPE_SHIFT);
flags += VOID_MASK << VOID_SHIFT;
flags += EXISTENCE_MASK << EXISTENCE_SHIFT;
return new DataPoint(0, 0, flags);
generationMode = (byte) ((generationMode & GEN_TYPE_MASK) << GEN_TYPE_SHIFT);
generationMode |= VOID_MASK << VOID_SHIFT;
generationMode |= EXISTENCE_MASK << EXISTENCE_SHIFT;
return generationMode;
}
public static DataPoint createDataPoint(int height, int depth, int color, int lightSky, int lightBlock, int generationMode, boolean flag)
/** Returned datapoint is in ThreadMapUtil */
public static void createDataPoint(int height, int depth, int color, int lightSky, int lightBlock, int generationMode, boolean flag)
{
int data = (height & HEIGHT_MASK) << HEIGHT_SHIFT;
data += (depth & DEPTH_MASK) << DEPTH_SHIFT;
@@ -121,105 +121,106 @@ public class DataPointUtil
byte flags = (byte) ((generationMode & GEN_TYPE_MASK) << GEN_TYPE_SHIFT);
if (flag) flags += FLAG_MASK << FLAG_SHIFT;
flags += EXISTENCE_MASK << EXISTENCE_SHIFT;
return new DataPoint(color, data, flags);
ThreadMapUtil.saveDataPoint(color, data, flags);
}
public static DataPoint createDataPoint(int alpha, int red, int green, int blue, int height, int depth, int lightSky, int lightBlock, int generationMode, boolean flag)
public static void createDataPoint(int alpha, int red, int green, int blue, int height, int depth, int lightSky, int lightBlock, int generationMode, boolean flag)
{
return createDataPoint(
createDataPoint(
height, depth,
(alpha << ALPHA_SHIFT) | (red << RED_SHIFT) | (green << GREEN_SHIFT) | blue,
lightSky, lightBlock, generationMode, flag);
}
public static short getHeight(DataPoint dataPoint)
public static short getHeight(int data)
{
return (short) ((dataPoint.data >>> HEIGHT_SHIFT) & HEIGHT_MASK);
return (short) ((data >>> HEIGHT_SHIFT) & HEIGHT_MASK);
}
public static short getDepth(DataPoint dataPoint)
public static short getDepth(int data)
{
return (short) ((dataPoint.data >>> DEPTH_SHIFT) & DEPTH_MASK);
return (short) ((data >>> DEPTH_SHIFT) & DEPTH_MASK);
}
public static short getAlpha(DataPoint dataPoint)
public static short getAlpha(int color)
{
return (short) ((dataPoint.color >>> ALPHA_SHIFT) & ALPHA_MASK);
return (short) ((color >>> ALPHA_SHIFT) & ALPHA_MASK);
}
public static short getRed(DataPoint dataPoint)
public static short getRed(int color)
{
return (short) ((dataPoint.color >>> RED_SHIFT) & RED_MASK);
return (short) ((color >>> RED_SHIFT) & RED_MASK);
}
public static short getGreen(DataPoint dataPoint)
public static short getGreen(int color)
{
return (short) ((dataPoint.color >>> GREEN_SHIFT) & GREEN_MASK);
return (short) ((color >>> GREEN_SHIFT) & GREEN_MASK);
}
public static short getBlue(DataPoint dataPoint)
public static short getBlue(int color)
{
return (short) ((dataPoint.color >>> BLUE_SHIFT) & BLUE_MASK);
return (short) ((color >>> BLUE_SHIFT) & BLUE_MASK);
}
public static byte getLightSky(DataPoint dataPoint)
public static byte getLightSky(int data)
{
return (byte) ((dataPoint.data >>> SKY_LIGHT_SHIFT) & SKY_LIGHT_MASK);
return (byte) ((data >>> SKY_LIGHT_SHIFT) & SKY_LIGHT_MASK);
}
public static byte getLightSkyAlt(DataPoint dataPoint)
public static byte getLightSkyAlt(int data, byte flags)
{
if (skyLightPlayer == 0 && ((dataPoint.flags >>> FLAG_SHIFT) & FLAG_MASK) == 1)
if (skyLightPlayer == 0 && ((flags >>> FLAG_SHIFT) & FLAG_MASK) == 1)
return 0;
else
return (byte) ((dataPoint.data >>> SKY_LIGHT_SHIFT) & SKY_LIGHT_MASK);
return (byte) ((data >>> SKY_LIGHT_SHIFT) & SKY_LIGHT_MASK);
}
public static byte getLightBlock(DataPoint dataPoint)
public static byte getLightBlock(int data)
{
return (byte) ((dataPoint.data >>> BLOCK_LIGHT_SHIFT) & BLOCK_LIGHT_MASK);
return (byte) ((data >>> BLOCK_LIGHT_SHIFT) & BLOCK_LIGHT_MASK);
}
public static boolean getFlag(DataPoint dataPoint)
public static boolean getFlag(byte flags)
{
return ((dataPoint.flags >>> FLAG_SHIFT) & FLAG_MASK) == 1;
return ((flags >>> FLAG_SHIFT) & FLAG_MASK) == 1;
}
public static byte getGenerationMode(DataPoint dataPoint)
public static byte getGenerationMode(byte flags)
{
return (byte) ((dataPoint.flags >>> GEN_TYPE_SHIFT) & GEN_TYPE_MASK);
return (byte) ((flags >>> GEN_TYPE_SHIFT) & GEN_TYPE_MASK);
}
public static boolean isVoid(DataPoint dataPoint)
public static boolean isVoid(byte flags)
{
return (((dataPoint.flags >>> VOID_SHIFT) & VOID_MASK) == 1);
return (((flags >>> VOID_SHIFT) & VOID_MASK) == 1);
}
public static boolean doesItExist(DataPoint dataPoint)
public static boolean doesItExist(byte flags)
{
return (dataPoint != null) && (((dataPoint.flags >>> EXISTENCE_SHIFT) & EXISTENCE_MASK) == 1);
return ((flags >>> EXISTENCE_SHIFT) & EXISTENCE_MASK) == 1;
}
public static int getColor(DataPoint dataPoint)
@Deprecated
public static int getColor(int color)
{
return dataPoint.color;
return color;
}
/** This is used to convert a dataPoint to string (useful for the print function) */
@SuppressWarnings("unused")
public static String toString(DataPoint dataPoint)
public static String toString(int color, int data, byte flags)
{
return getHeight(dataPoint) + " " +
getDepth(dataPoint) + " " +
getAlpha(dataPoint) + " " +
getRed(dataPoint) + " " +
getBlue(dataPoint) + " " +
getGreen(dataPoint) + " " +
getLightBlock(dataPoint) + " " +
getLightSky(dataPoint) + " " +
getGenerationMode(dataPoint) + " " +
isVoid(dataPoint) + " " +
doesItExist(dataPoint) + '\n';
return getHeight(data) + " " +
getDepth(data) + " " +
getAlpha(color) + " " +
getRed(color) + " " +
getBlue(color) + " " +
getGreen(color) + " " +
getLightBlock(data) + " " +
getLightSky(data) + " " +
getGenerationMode(flags) + " " +
isVoid(flags) + " " +
doesItExist(flags) + '\n';
}
public static void shrinkArray(short[] array, int packetSize, int start, int length, int arraySize)
@@ -249,25 +250,30 @@ public class DataPointUtil
/**
* This method merge column of multiple data together
* @param dataToMerge one or more columns of data
* Returned datapoint is in ThreadMapUtil
* @param dataToMergeColor colors of one or more columns of data
* @param dataToMergeData data of one or more columns of data
* @param dataToMergeFlags flags of one or more columns of data
* @param inputVerticalData vertical size of an input data
* @param maxVerticalData max vertical size of the merged data
* @return one column of correctly parsed data
*/
public static DataPoint[] mergeMultiData(DataPoint[] dataToMerge, int inputVerticalData, int maxVerticalData)
public static void mergeMultiData(int[] dataToMergeColor, int[] dataToMergeData, byte[] dataToMergeFlags, int inputVerticalData, int maxVerticalData)
{
int size = dataToMerge.length / inputVerticalData;
int size = dataToMergeData.length / inputVerticalData;
// We initialize the arrays that are going to be used
short[] heightAndDepth = ThreadMapUtil.getHeightAndDepth((WORLD_HEIGHT / 2 + 1) * 2);
DataPoint[] dataPoint = ThreadMapUtil.getVerticalDataArray(DetailDistanceUtil.getMaxVerticalData(0));
int[] dataPointColor = ThreadMapUtil.getVerticalDataArrayColor(DetailDistanceUtil.getMaxVerticalData(0));
int[] dataPointData = ThreadMapUtil.getVerticalDataArrayData(DetailDistanceUtil.getMaxVerticalData(0));
byte[] dataPointFlags = ThreadMapUtil.getVerticalDataArrayFlags(DetailDistanceUtil.getMaxVerticalData(0));
int genMode = DistanceGenerationMode.FULL.complexity;
byte genMode = DistanceGenerationMode.FULL.complexity;
boolean allEmpty = true;
boolean allVoid = true;
boolean allDefault;
DataPoint singleData;
int singleDataData;
byte singleDataFlags;
short depth;
@@ -281,16 +287,17 @@ public class DataPointUtil
{
for (dataIndex = 0; dataIndex < inputVerticalData; dataIndex++)
{
singleData = dataToMerge[index * inputVerticalData + dataIndex];
if (singleData != null && doesItExist(singleData))
singleDataData = dataToMergeData[index * inputVerticalData + dataIndex];
singleDataFlags = dataToMergeFlags[index * inputVerticalData + dataIndex];
if (doesItExist(singleDataFlags))
{
genMode = Math.min(genMode, getGenerationMode(singleData));
genMode = (byte) Math.min(genMode, getGenerationMode(singleDataFlags));
allEmpty = false;
if (!isVoid(singleData))
if (!isVoid(singleDataFlags))
{
allVoid = false;
depth = getDepth(singleData);
height = getHeight(singleData);
depth = getDepth(singleDataData);
height = getHeight(singleDataData);
int botPos = -1;
int topPos = -1;
@@ -393,11 +400,11 @@ public class DataPointUtil
//We check if there is any data that's not empty or void
if (allEmpty)
return dataPoint;
return;
if (allVoid)
{
dataPoint[0] = createVoidDataPoint(genMode);
return dataPoint;
dataPointFlags[0] = createVoidDataPoint(genMode);
return;
}
//we limit the vertical portion to maxVerticalData
@@ -442,73 +449,90 @@ public class DataPointUtil
allEmpty = true;
allVoid = true;
allDefault = true;
DataPoint data = EMPTY_DATA;
int singleDataColor;
int data = EMPTY_DATA;
int color = EMPTY_DATA;
byte flags = EMPTY_DATA;
for (int index = 0; index < size; index++)
{
for (dataIndex = 0; dataIndex < inputVerticalData; dataIndex++)
{
singleData = dataToMerge[index * inputVerticalData + dataIndex];
if (doesItExist(singleData) && !isVoid(singleData))
singleDataColor = dataToMergeColor[index * inputVerticalData + dataIndex];
singleDataData = dataToMergeData[index * inputVerticalData + dataIndex];
singleDataFlags = dataToMergeFlags[index * inputVerticalData + dataIndex];
if (doesItExist(singleDataFlags) && !isVoid(singleDataFlags))
{
if ((depth <= getDepth(singleData) && getDepth(singleData) <= height)
|| (depth <= getHeight(singleData) && getHeight(singleData) <= height))
if ((depth <= getDepth(singleDataData) && getDepth(singleDataData) <= height)
|| (depth <= getHeight(singleDataData) && getHeight(singleDataData) <= height))
{
if (getHeight(singleData) > getHeight(data))
data = singleData;
if (getHeight(singleDataData) > getHeight(data))
{
color = singleDataColor;
data = singleDataData;
flags = singleDataFlags;
}
}
}
else
break;
}
if (!doesItExist(data))
if (!doesItExist(flags))
{
singleData = dataToMerge[index * inputVerticalData];
if (doesItExist(singleData))
data = createVoidDataPoint(getGenerationMode(singleData));
singleDataFlags = dataToMergeFlags[index * inputVerticalData];
if (doesItExist(singleDataFlags))
flags = createVoidDataPoint(getGenerationMode(singleDataFlags));
else
data = createVoidDataPoint(0);
flags = createVoidDataPoint((byte) 0);
data = EMPTY_DATA;
color = EMPTY_DATA;
}
if (doesItExist(data))
if (doesItExist(flags))
{
allEmpty = false;
if (!isVoid(data))
if (!isVoid(flags))
{
numberOfChildren++;
allVoid = false;
tempAlpha += getAlpha(data);
tempRed += getRed(data);
tempGreen += getGreen(data);
tempBlue += getBlue(data);
tempAlpha += getAlpha(color);
tempRed += getRed(color);
tempGreen += getGreen(color);
tempBlue += getBlue(color);
tempLightBlock += getLightBlock(data);
tempLightSky += getLightSky(data);
if (!getFlag(data)) allDefault = false;
if (!getFlag(flags))
allDefault = false;
}
tempGenMode = (byte) Math.min(tempGenMode, getGenerationMode(data));
tempGenMode = (byte) Math.min(tempGenMode, getGenerationMode(flags));
}
else
tempGenMode = (byte) Math.min(tempGenMode, DistanceGenerationMode.NONE.complexity);
}
if (allEmpty)
//no child has been initialized
dataPoint[j] = EMPTY_DATA;
else if (allVoid)
//all the children are void
dataPoint[j] = createVoidDataPoint(tempGenMode);
else
if (!allEmpty)
{
//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, allDefault);
//child has been initialized
if (allVoid)
{
//all the children are void
dataPointFlags[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;
createDataPoint(tempAlpha, tempRed, tempGreen, tempBlue, height, depth, tempLightSky, tempLightBlock, tempGenMode, allDefault);
dataPointColor[j] = ThreadMapUtil.dataPointColor;
dataPointData[j] = ThreadMapUtil.dataPointData;
dataPointFlags[j] = ThreadMapUtil.dataPointFlags;
}
}
}
return dataPoint;
}
}
@@ -27,7 +27,6 @@ import java.util.concurrent.ConcurrentMap;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.objects.Box;
import com.seibel.lod.core.objects.lod.DataPoint;
/**
* Holds data used by specific threads so
@@ -39,15 +38,18 @@ import com.seibel.lod.core.objects.lod.DataPoint;
*/
public class ThreadMapUtil
{
public static final ConcurrentMap<String, DataPoint[]> threadSingleUpdateMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, DataPoint[][]> threadBuilderArrayMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, DataPoint[][]> threadBuilderVerticalArrayMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, DataPoint[]> threadVerticalAddDataMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, int[][]> threadBuilderVerticalArrayMapColor = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, int[][]> threadBuilderVerticalArrayMapData = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, byte[][]> threadBuilderVerticalArrayMapFlags = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, int[]> threadVerticalAddDataMapColor = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, int[]> threadVerticalAddDataMapData = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, byte[]> threadVerticalAddDataMapFlags = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, byte[][]> saveContainer = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, short[]> projectionArrayMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, short[]> heightAndDepthMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, DataPoint[]> singleDataToMergeMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, DataPoint[][]> verticalUpdate = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, int[][]> verticalUpdateColor = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, int[][]> verticalUpdateData = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, byte[][]> verticalUpdateFlags = new ConcurrentHashMap<>();
//________________________//
@@ -55,9 +57,14 @@ public class ThreadMapUtil
//________________________//
public static final ConcurrentMap<String, boolean[]> adjShadeDisabled = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, Map<LodDirection, DataPoint[]>> adjDataMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, Map<LodDirection, int[]>> adjDataMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, Map<LodDirection, byte[]>> adjFlagsMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, Box> boxMap = new ConcurrentHashMap<>();
public static int dataPointColor = 0;
public static int dataPointData = 0;
public static byte dataPointFlags = 0;
/** returns the array NOT cleared every time */
@@ -73,7 +80,7 @@ public class ThreadMapUtil
}
/** returns the array NOT cleared every time */
public static Map<LodDirection, DataPoint[]> getAdjDataArray(int verticalData)
public static Map<LodDirection, int[]> getAdjDataArray(int verticalData)
{
if (!adjDataMap.containsKey(Thread.currentThread().getName())
|| (adjDataMap.get(Thread.currentThread().getName()) == null)
@@ -81,20 +88,41 @@ public class ThreadMapUtil
|| (adjDataMap.get(Thread.currentThread().getName()).get(LodDirection.NORTH).length != verticalData))
{
adjDataMap.put(Thread.currentThread().getName(), new HashMap<>());
adjDataMap.get(Thread.currentThread().getName()).put(LodDirection.UP, new DataPoint[1]);
adjDataMap.get(Thread.currentThread().getName()).put(LodDirection.DOWN, new DataPoint[1]);
adjDataMap.get(Thread.currentThread().getName()).put(LodDirection.UP, new int[1]);
adjDataMap.get(Thread.currentThread().getName()).put(LodDirection.DOWN, new int[1]);
for (LodDirection lodDirection : Box.ADJ_DIRECTIONS)
adjDataMap.get(Thread.currentThread().getName()).put(lodDirection, new DataPoint[verticalData]);
adjDataMap.get(Thread.currentThread().getName()).put(lodDirection, new int[verticalData]);
}
else
{
for (LodDirection lodDirection : Box.ADJ_DIRECTIONS)
Arrays.fill(adjDataMap.get(Thread.currentThread().getName()).get(lodDirection), DataPointUtil.EMPTY_DATA);
Arrays.fill(adjDataMap.get(Thread.currentThread().getName()).get(lodDirection), 0);
}
return adjDataMap.get(Thread.currentThread().getName());
}
/** returns the array NOT cleared every time */
public static Map<LodDirection, byte[]> getAdjFlagsArray(int verticalData)
{
if (!adjFlagsMap.containsKey(Thread.currentThread().getName())
|| (adjFlagsMap.get(Thread.currentThread().getName()) == null)
|| (adjFlagsMap.get(Thread.currentThread().getName()).get(LodDirection.NORTH) == null)
|| (adjFlagsMap.get(Thread.currentThread().getName()).get(LodDirection.NORTH).length != verticalData))
{
adjFlagsMap.put(Thread.currentThread().getName(), new HashMap<>());
adjFlagsMap.get(Thread.currentThread().getName()).put(LodDirection.UP, new byte[1]);
adjFlagsMap.get(Thread.currentThread().getName()).put(LodDirection.DOWN, new byte[1]);
for (LodDirection lodDirection : Box.ADJ_DIRECTIONS)
adjFlagsMap.get(Thread.currentThread().getName()).put(lodDirection, new byte[verticalData]);
}
else
{
for (LodDirection lodDirection : Box.ADJ_DIRECTIONS)
Arrays.fill(adjFlagsMap.get(Thread.currentThread().getName()).get(lodDirection), (byte) 0);
}
return adjFlagsMap.get(Thread.currentThread().getName());
}
public static Box getBox()
{
if (!boxMap.containsKey(Thread.currentThread().getName())
@@ -120,21 +148,57 @@ public class ThreadMapUtil
/** returns the array filled with 0's */
public static DataPoint[] getBuilderVerticalArray(int detailLevel)
public static int[] getBuilderVerticalArrayColor(int detailLevel)
{
if (!threadBuilderVerticalArrayMap.containsKey(Thread.currentThread().getName()) || (threadBuilderVerticalArrayMap.get(Thread.currentThread().getName()) == null))
if (!threadBuilderVerticalArrayMapColor.containsKey(Thread.currentThread().getName()) || (threadBuilderVerticalArrayMapColor.get(Thread.currentThread().getName()) == null))
{
DataPoint[][] array = new DataPoint[5][];
int[][] array = new int[5][];
int size;
for (int i = 0; i < 5; i++)
{
size = 1 << i;
array[i] = new DataPoint[size * size * (DataPointUtil.WORLD_HEIGHT / 2 + 1)];
array[i] = new int[size * size * (DataPointUtil.WORLD_HEIGHT / 2 + 1)];
}
threadBuilderVerticalArrayMap.put(Thread.currentThread().getName(), array);
threadBuilderVerticalArrayMapColor.put(Thread.currentThread().getName(), array);
}
Arrays.fill(threadBuilderVerticalArrayMap.get(Thread.currentThread().getName())[detailLevel], DataPointUtil.EMPTY_DATA);
return threadBuilderVerticalArrayMap.get(Thread.currentThread().getName())[detailLevel];
Arrays.fill(threadBuilderVerticalArrayMapColor.get(Thread.currentThread().getName())[detailLevel], 0);
return threadBuilderVerticalArrayMapColor.get(Thread.currentThread().getName())[detailLevel];
}
/** returns the array filled with 0's */
public static int[] getBuilderVerticalArrayData(int detailLevel)
{
if (!threadBuilderVerticalArrayMapData.containsKey(Thread.currentThread().getName()) || (threadBuilderVerticalArrayMapData.get(Thread.currentThread().getName()) == null))
{
int[][] array = new int[5][];
int size;
for (int i = 0; i < 5; i++)
{
size = 1 << i;
array[i] = new int[size * size * (DataPointUtil.WORLD_HEIGHT / 2 + 1)];
}
threadBuilderVerticalArrayMapData.put(Thread.currentThread().getName(), array);
}
Arrays.fill(threadBuilderVerticalArrayMapData.get(Thread.currentThread().getName())[detailLevel], 0);
return threadBuilderVerticalArrayMapData.get(Thread.currentThread().getName())[detailLevel];
}
/** returns the array filled with 0's */
public static byte[] getBuilderVerticalArrayFlags(int detailLevel)
{
if (!threadBuilderVerticalArrayMapFlags.containsKey(Thread.currentThread().getName()) || (threadBuilderVerticalArrayMapFlags.get(Thread.currentThread().getName()) == null))
{
byte[][] array = new byte[5][];
int size;
for (int i = 0; i < 5; i++)
{
size = 1 << i;
array[i] = new byte[size * size * (DataPointUtil.WORLD_HEIGHT / 2 + 1)];
}
threadBuilderVerticalArrayMapFlags.put(Thread.currentThread().getName(), array);
}
Arrays.fill(threadBuilderVerticalArrayMapFlags.get(Thread.currentThread().getName())[detailLevel], (byte) 0);
return threadBuilderVerticalArrayMapFlags.get(Thread.currentThread().getName())[detailLevel];
}
/** returns the array NOT cleared every time */
@@ -157,19 +221,46 @@ public class ThreadMapUtil
/** returns the array filled with 0's */
public static DataPoint[] getVerticalDataArray(int arrayLength)
public static int[] getVerticalDataArrayColor(int arrayLength)
{
if (!threadVerticalAddDataMap.containsKey(Thread.currentThread().getName()) || (threadVerticalAddDataMap.get(Thread.currentThread().getName()) == null))
{
threadVerticalAddDataMap.put(Thread.currentThread().getName(), new DataPoint[arrayLength]);
}
if (!threadVerticalAddDataMapColor.containsKey(Thread.currentThread().getName()) || (threadVerticalAddDataMapColor.get(Thread.currentThread().getName()) == null))
threadVerticalAddDataMapColor.put(Thread.currentThread().getName(), new int[arrayLength]);
else
{
Arrays.fill(threadVerticalAddDataMap.get(Thread.currentThread().getName()), DataPointUtil.EMPTY_DATA);
}
return threadVerticalAddDataMap.get(Thread.currentThread().getName());
Arrays.fill(threadVerticalAddDataMapColor.get(Thread.currentThread().getName()), 0);
return threadVerticalAddDataMapColor.get(Thread.currentThread().getName());
}
public static int[] getRawVerticalDataArrayColor()
{
return threadVerticalAddDataMapColor.get(Thread.currentThread().getName());
}
/** returns the array filled with 0's */
public static int[] getVerticalDataArrayData(int arrayLength)
{
if (!threadVerticalAddDataMapData.containsKey(Thread.currentThread().getName()) || (threadVerticalAddDataMapData.get(Thread.currentThread().getName()) == null))
threadVerticalAddDataMapData.put(Thread.currentThread().getName(), new int[arrayLength]);
else
Arrays.fill(threadVerticalAddDataMapData.get(Thread.currentThread().getName()), 0);
return threadVerticalAddDataMapData.get(Thread.currentThread().getName());
}
public static int[] getRawVerticalDataArrayData()
{
return threadVerticalAddDataMapData.get(Thread.currentThread().getName());
}
/** returns the array filled with 0's */
public static byte[] getVerticalDataArrayFlags(int arrayLength)
{
if (!threadVerticalAddDataMapFlags.containsKey(Thread.currentThread().getName()) || (threadVerticalAddDataMapFlags.get(Thread.currentThread().getName()) == null))
threadVerticalAddDataMapFlags.put(Thread.currentThread().getName(), new byte[arrayLength]);
else
Arrays.fill(threadVerticalAddDataMapFlags.get(Thread.currentThread().getName()), (byte) 0);
return threadVerticalAddDataMapFlags.get(Thread.currentThread().getName());
}
public static byte[] getRawVerticalDataArrayFlags()
{
return threadVerticalAddDataMapFlags.get(Thread.currentThread().getName());
}
/** returns the array NOT cleared every time */
@@ -182,22 +273,49 @@ public class ThreadMapUtil
return heightAndDepthMap.get(Thread.currentThread().getName());
}
/** returns the array filled with 0's */
public static DataPoint[] getVerticalUpdateArray(int detailLevel)
public static int[] getVerticalUpdateArrayColor(int detailLevel)
{
if (!verticalUpdate.containsKey(Thread.currentThread().getName()) || (verticalUpdate.get(Thread.currentThread().getName()) == null))
if (!verticalUpdateColor.containsKey(Thread.currentThread().getName()) || (verticalUpdateColor.get(Thread.currentThread().getName()) == null))
{
DataPoint[][] array = new DataPoint[LodUtil.DETAIL_OPTIONS][];
int[][] array = new int[LodUtil.DETAIL_OPTIONS][];
for (int i = 1; i < LodUtil.DETAIL_OPTIONS; i++)
array[i] = new DataPoint[DetailDistanceUtil.getMaxVerticalData(i - 1) * 4];
verticalUpdate.put(Thread.currentThread().getName(), array);
array[i] = new int[DetailDistanceUtil.getMaxVerticalData(i - 1) * 4];
verticalUpdateColor.put(Thread.currentThread().getName(), array);
}
else
Arrays.fill(verticalUpdateColor.get(Thread.currentThread().getName())[detailLevel], 0);
return verticalUpdateColor.get(Thread.currentThread().getName())[detailLevel];
}
/** returns the array filled with 0's */
public static int[] getVerticalUpdateArrayData(int detailLevel)
{
if (!verticalUpdateData.containsKey(Thread.currentThread().getName()) || (verticalUpdateData.get(Thread.currentThread().getName()) == null))
{
Arrays.fill(verticalUpdate.get(Thread.currentThread().getName())[detailLevel], DataPointUtil.EMPTY_DATA);
int[][] array = new int[LodUtil.DETAIL_OPTIONS][];
for (int i = 1; i < LodUtil.DETAIL_OPTIONS; i++)
array[i] = new int[DetailDistanceUtil.getMaxVerticalData(i - 1) * 4];
verticalUpdateData.put(Thread.currentThread().getName(), array);
}
return verticalUpdate.get(Thread.currentThread().getName())[detailLevel];
else
Arrays.fill(verticalUpdateData.get(Thread.currentThread().getName())[detailLevel], 0);
return verticalUpdateData.get(Thread.currentThread().getName())[detailLevel];
}
/** returns the array filled with 0's */
public static byte[] getVerticalUpdateArrayFlags(int detailLevel)
{
if (!verticalUpdateFlags.containsKey(Thread.currentThread().getName()) || (verticalUpdateFlags.get(Thread.currentThread().getName()) == null))
{
byte[][] array = new byte[LodUtil.DETAIL_OPTIONS][];
for (int i = 1; i < LodUtil.DETAIL_OPTIONS; i++)
array[i] = new byte[DetailDistanceUtil.getMaxVerticalData(i - 1) * 4];
verticalUpdateFlags.put(Thread.currentThread().getName(), array);
}
else
Arrays.fill(verticalUpdateFlags.get(Thread.currentThread().getName())[detailLevel], (byte) 0);
return verticalUpdateFlags.get(Thread.currentThread().getName())[detailLevel];
}
/** clears all arrays so they will have to be rebuilt */
@@ -206,14 +324,24 @@ public class ThreadMapUtil
adjShadeDisabled.clear();
adjDataMap.clear();
boxMap.clear();
threadSingleUpdateMap.clear();
threadBuilderArrayMap.clear();
threadBuilderVerticalArrayMap.clear();
threadVerticalAddDataMap.clear();
threadBuilderVerticalArrayMapColor.clear();
threadBuilderVerticalArrayMapData.clear();
threadBuilderVerticalArrayMapFlags.clear();
threadVerticalAddDataMapColor.clear();
threadVerticalAddDataMapData.clear();
threadVerticalAddDataMapFlags.clear();
saveContainer.clear();
projectionArrayMap.clear();
heightAndDepthMap.clear();
singleDataToMergeMap.clear();
verticalUpdate.clear();
verticalUpdateColor.clear();
verticalUpdateData.clear();
verticalUpdateFlags.clear();
}
public static void saveDataPoint(int color, int data, byte flags)
{
dataPointColor = color;
dataPointData = data;
dataPointFlags = flags;
}
}