Merge branch '1.16.5' of https://gitlab.com/jeseibel/minecraft-lod-mod into vertical_merging
Conflicts: src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java src/main/java/com/seibel/lod/util/DataPointUtil.java
This commit is contained in:
@@ -28,6 +28,7 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import com.seibel.lod.util.*;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import org.lwjgl.opengl.GL15C;
|
||||
@@ -43,10 +44,6 @@ import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.proxy.GlProxy;
|
||||
import com.seibel.lod.proxy.GlProxy.GlProxyContext;
|
||||
import com.seibel.lod.render.LodRenderer;
|
||||
import com.seibel.lod.util.DataPointUtil;
|
||||
import com.seibel.lod.util.LevelPosUtil;
|
||||
import com.seibel.lod.util.LodThreadFactory;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.vertex.VertexBuffer;
|
||||
@@ -224,12 +221,21 @@ public class LodBufferBuilder
|
||||
Callable<Boolean> dataToRenderThread = () ->
|
||||
{
|
||||
Map<Direction, long[]> adjData = new HashMap<>();
|
||||
int maxVerticalData;
|
||||
if (LodConfig.CLIENT.worldGenerator.lodQualityMode.get() == LodQualityMode.HEIGHTMAP)
|
||||
{
|
||||
adjData.put(Direction.WEST, new long[1]);
|
||||
adjData.put(Direction.EAST, new long[1]);
|
||||
adjData.put(Direction.SOUTH, new long[1]);
|
||||
adjData.put(Direction.NORTH, new long[1]);
|
||||
maxVerticalData = 1;
|
||||
} else
|
||||
{
|
||||
maxVerticalData = DetailDistanceUtil.getMaxVerticalData(0);
|
||||
}
|
||||
|
||||
for (Direction direction : Box.ADJ_DIRECTIONS)
|
||||
{
|
||||
if (adjData.containsKey(direction) && LodConfig.CLIENT.worldGenerator.lodQualityMode.get() == LodQualityMode.MULTI_LOD)
|
||||
{
|
||||
adjData.put(direction, new long[DetailDistanceUtil.getMaxVerticalData(0)]);
|
||||
}
|
||||
}
|
||||
//previous setToRender chache
|
||||
if (setsToRender[xR][zR] == null)
|
||||
@@ -257,12 +263,12 @@ public class LodBufferBuilder
|
||||
int zAdj;
|
||||
int chunkXdist;
|
||||
int chunkZdist;
|
||||
|
||||
|
||||
// keep a local version so we don't have to worry about indexOutOfBounds Exceptions
|
||||
// if it changes in the LodRenderer while we are working here
|
||||
boolean[][] vanillaRenderedChunks = renderer.vanillaRenderedChunks;
|
||||
boolean[][] vanillaRenderedChunks = renderer.vanillaRenderedChunks;
|
||||
short gameChunkRenderDistance = (short) (vanillaRenderedChunks.length / 2 - 1);
|
||||
|
||||
|
||||
for (int index = 0; index < posToRender.getNumberOfPos(); index++)
|
||||
{
|
||||
detailLevel = posToRender.getNthDetailLevel(index);
|
||||
@@ -297,7 +303,9 @@ public class LodBufferBuilder
|
||||
adjData.get(direction)[0] = lodDim.getSingleData(detailLevel, xAdj, zAdj);
|
||||
} else
|
||||
{
|
||||
adjData.put(direction, lodDim.getData(detailLevel, xAdj, zAdj));
|
||||
adjData.put(direction, new long[DetailDistanceUtil.getMaxVerticalData(lodDim.getMaxVerticalData(detailLevel,posX,posZ))]);
|
||||
for (int verticalIndex = 0; verticalIndex < lodDim.getMaxVerticalData(detailLevel, xAdj, zAdj); verticalIndex++)
|
||||
adjData.get(direction)[verticalIndex] = lodDim.getData(detailLevel, xAdj, zAdj, verticalIndex);
|
||||
}
|
||||
|
||||
} else
|
||||
@@ -319,7 +327,9 @@ public class LodBufferBuilder
|
||||
adjData.get(direction)[0] = lodDim.getSingleData(detailLevel, xAdj, zAdj);
|
||||
} else
|
||||
{
|
||||
adjData.put(direction, lodDim.getData(detailLevel, xAdj, zAdj));
|
||||
adjData.put(direction, new long[DetailDistanceUtil.getMaxVerticalData(lodDim.getMaxVerticalData(detailLevel,posX,posZ))]);
|
||||
for (int verticalIndex = 0; verticalIndex < lodDim.getMaxVerticalData(detailLevel, xAdj, zAdj); verticalIndex++)
|
||||
adjData.get(direction)[verticalIndex] = lodDim.getData(detailLevel, xAdj, zAdj, verticalIndex);
|
||||
}
|
||||
} else
|
||||
{
|
||||
@@ -346,13 +356,14 @@ public class LodBufferBuilder
|
||||
|
||||
} else if (region.getLodQualityMode() == LodQualityMode.MULTI_LOD)
|
||||
{
|
||||
for (long dataPoint : lodDim.getData(detailLevel, posX, posZ))
|
||||
long data;
|
||||
for (int verticalIndex = 0; verticalIndex < lodDim.getMaxVerticalData(detailLevel, posX, posZ); verticalIndex++)
|
||||
{
|
||||
if (!DataPointUtil.isItVoid(dataPoint) && DataPointUtil.doesItExist(dataPoint))
|
||||
{
|
||||
LodConfig.CLIENT.graphics.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPosRounded, dataPoint, adjData,
|
||||
detailLevel, posX, posZ, boxCache[xR][zR], renderer.previousDebugMode, renderer.lightMap);
|
||||
}
|
||||
data = lodDim.getData(detailLevel, posX, posZ, verticalIndex);
|
||||
if (DataPointUtil.isItVoid(data) || DataPointUtil.doesItExist(data))
|
||||
break;
|
||||
LodConfig.CLIENT.graphics.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPosRounded, data, adjData,
|
||||
detailLevel, posX, posZ, boxCache[xR][zR], renderer.previousDebugMode, renderer.lightMap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,14 +523,14 @@ public class LodBufferBuilder
|
||||
private void uploadBuffers(boolean fullRegen, LodDimension lodDim)
|
||||
{
|
||||
GlProxy glProxy = GlProxy.getInstance();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// make sure we are uploading to a different OpenGL context,
|
||||
// to prevent interference (IE stuttering) with the Minecraft context.
|
||||
glProxy.setGlContext(GlProxyContext.LOD_BUILDER);
|
||||
|
||||
|
||||
|
||||
|
||||
for (int x = 0; x < buildableVbos.length; x++)
|
||||
{
|
||||
for (int z = 0; z < buildableVbos.length; z++)
|
||||
@@ -532,25 +543,23 @@ public class LodBufferBuilder
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// make sure all the buffers have been uploaded.
|
||||
// this probably is necessary, but it makes me feel good :)
|
||||
GL11.glFlush();
|
||||
}
|
||||
catch (IllegalStateException e)
|
||||
} catch (IllegalStateException e)
|
||||
{
|
||||
ClientProxy.LOGGER.error(LodBufferBuilder.class.getSimpleName() + " - UploadBuffers failed: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
} finally
|
||||
{
|
||||
// make sure no buffer is bound
|
||||
if (glProxy.getGlContext() == GlProxyContext.LOD_BUILDER)
|
||||
{
|
||||
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
|
||||
// make sure the context is disabled
|
||||
glProxy.setGlContext(GlProxyContext.NONE);
|
||||
}
|
||||
@@ -579,8 +588,8 @@ public class LodBufferBuilder
|
||||
// is faster for transferring data. They must put the data in different memory
|
||||
// or something.
|
||||
GL15C.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, uploadBuffer);
|
||||
|
||||
|
||||
|
||||
|
||||
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ public class LodBuilder
|
||||
public static final ConcurrentMap<Block, Integer> colorMap = new ConcurrentHashMap<>();
|
||||
public static final ConcurrentMap<Block, VoxelShape> shapeMap = new ConcurrentHashMap<>();
|
||||
|
||||
public static final ModelDataMap dataMap = new ModelDataMap.Builder().build() ;
|
||||
public static final ModelDataMap dataMap = new ModelDataMap.Builder().build();
|
||||
|
||||
/**
|
||||
* If no blocks are found in the area in determineBottomPointForArea return this
|
||||
@@ -134,7 +134,7 @@ public class LodBuilder
|
||||
// get the textures for blocks
|
||||
if (mc.getClientWorld() == null)
|
||||
return;
|
||||
|
||||
|
||||
DimensionType dim = world.dimensionType();
|
||||
|
||||
LodDimension lodDim;
|
||||
@@ -239,17 +239,28 @@ public class LodBuilder
|
||||
isServer);
|
||||
break;
|
||||
case MULTI_LOD:
|
||||
long[][] dataToMergeVertical;
|
||||
long[] dataToMergeVertical;
|
||||
dataToMergeVertical = createVerticalDataToMerge(detail, chunk, config, startX, startZ, endX, endZ);
|
||||
data = DataPointUtil.mergeMultiData(dataToMergeVertical);
|
||||
data = DataPointUtil.mergeMultiData(dataToMergeVertical, detailLevel);
|
||||
if (data.length == 0 || data == null)
|
||||
data = new long[]{DataPointUtil.EMPTY_DATA};
|
||||
lodDim.addData(detailLevel,
|
||||
posX,
|
||||
posZ,
|
||||
data,
|
||||
false,
|
||||
isServer);
|
||||
//lodDim.clear(detailLevel, posX, posZ);
|
||||
for (int verticalIndex = 0; (verticalIndex < data.length) && (verticalIndex < lodDim.getMaxVerticalData(detailLevel, posX, posZ)); verticalIndex++)
|
||||
{
|
||||
lodDim.addData(detailLevel,
|
||||
posX,
|
||||
posZ,
|
||||
verticalIndex,
|
||||
data[verticalIndex],
|
||||
false,
|
||||
isServer);
|
||||
long dataTest = lodDim.getData(detailLevel,
|
||||
posX,
|
||||
posZ,
|
||||
verticalIndex);
|
||||
System.out.println(DataPointUtil.toString(dataTest));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -263,11 +274,12 @@ public class LodBuilder
|
||||
|
||||
}
|
||||
|
||||
private long[][] createVerticalDataToMerge(LodDetail detail, IChunk chunk, LodBuilderConfig config, int startX, int startZ, int endX, int endZ)
|
||||
private long[] createVerticalDataToMerge(LodDetail detail, IChunk chunk, LodBuilderConfig config, int startX, int startZ, int endX, int endZ)
|
||||
{
|
||||
long[][] dataToMerge = ThreadMapUtil.getBuilderVerticalArray()[detail.detailLevel];
|
||||
ChunkPos chunkPos = chunk.getPos();
|
||||
long[] dataToMerge = ThreadMapUtil.getBuilderVerticalArray()[detail.detailLevel];
|
||||
int verticalData = DataPointUtil.WORLD_HEIGHT;
|
||||
|
||||
ChunkPos chunkPos = chunk.getPos();
|
||||
int size = 1 << detail.detailLevel;
|
||||
int height = 0;
|
||||
int depth = 0;
|
||||
@@ -286,17 +298,18 @@ public class LodBuilder
|
||||
|
||||
BlockPos.Mutable blockPos = new BlockPos.Mutable(0, 0, 0);
|
||||
int index = 0;
|
||||
|
||||
if (dataToMerge == null)
|
||||
{
|
||||
dataToMerge = new long[size * size][DataPointUtil.WORLD_HEIGHT];
|
||||
dataToMerge = new long[size * size * DataPointUtil.WORLD_HEIGHT];
|
||||
}
|
||||
//dataToMerge = new long[size * size][1024];
|
||||
|
||||
for (index = 0; index < size * size; index++)
|
||||
{
|
||||
for (int i = 0; i < dataToMerge[index].length; i++)
|
||||
for (int verticalIndex = 0; verticalIndex < verticalData; verticalIndex++)
|
||||
{
|
||||
dataToMerge[index][i] = 0;
|
||||
dataToMerge[index * verticalData + verticalIndex] = DataPointUtil.EMPTY_DATA;
|
||||
}
|
||||
xRel = Math.floorMod(index, size) + startX;
|
||||
zRel = Math.floorDiv(index, size) + startZ;
|
||||
@@ -314,21 +327,20 @@ public class LodBuilder
|
||||
//If the lod is at default, then we set this as void data
|
||||
if (height == DEFAULT_HEIGHT)
|
||||
{
|
||||
dataToMerge[index][0] = DataPointUtil.createVoidDataPoint(generation);
|
||||
dataToMerge[index * verticalData + 0] = DataPointUtil.createVoidDataPoint(generation);
|
||||
break;
|
||||
}
|
||||
|
||||
yAbs = height - 1;
|
||||
// We search light on above air block
|
||||
depth = determineBottomPointFrom(chunk, config, xRel, zRel, yAbs, blockPos);
|
||||
if(hasCeiling && topBlock)
|
||||
if (hasCeiling && topBlock)
|
||||
{
|
||||
yAbs = depth;
|
||||
color = generateLodColor(chunk, config, xRel, yAbs, zRel, blockPos);
|
||||
blockPos.set(xAbs, yAbs - 1, zAbs);
|
||||
light = getLightValue(chunk, blockPos, true);
|
||||
}
|
||||
else
|
||||
} else
|
||||
{
|
||||
color = generateLodColor(chunk, config, xRel, yAbs, zRel, blockPos);
|
||||
blockPos.set(xAbs, yAbs + 1, zAbs);
|
||||
@@ -337,14 +349,14 @@ public class LodBuilder
|
||||
blockPos.set(xAbs, yAbs + 1, zAbs);
|
||||
light = getLightValue(chunk, blockPos, hasCeiling && topBlock);
|
||||
lightBlock = light & 0b1111;
|
||||
if(!hasCeiling && topBlock)
|
||||
if (!hasCeiling && topBlock)
|
||||
lightSky = 15; //default max light
|
||||
else
|
||||
lightSky = (light >> 4) & 0b1111;
|
||||
|
||||
topBlock = false;
|
||||
|
||||
dataToMerge[index][count] = DataPointUtil.createDataPoint(height, depth, color, lightSky, lightBlock, generation);
|
||||
dataToMerge[index * verticalData + count] = DataPointUtil.createDataPoint(height, depth, color, lightSky, lightBlock, generation);
|
||||
yAbs = depth - 1;
|
||||
count++;
|
||||
}
|
||||
@@ -605,7 +617,7 @@ public class LodBuilder
|
||||
blockLight = world.getBrightness(LightType.BLOCK, blockPos);
|
||||
skyLight = world.getBrightness(LightType.SKY, blockPos);
|
||||
|
||||
if(ceilingTopBlock)
|
||||
if (ceilingTopBlock)
|
||||
blockPos.set(blockPos.getX(), blockPos.getY() + 1, blockPos.getZ());
|
||||
else
|
||||
blockPos.set(blockPos.getX(), blockPos.getY() - 1, blockPos.getZ());
|
||||
@@ -625,19 +637,17 @@ public class LodBuilder
|
||||
|
||||
World world = mc.getClientWorld();
|
||||
TextureAtlasSprite texture;
|
||||
if(topTextureRequired)
|
||||
if (topTextureRequired)
|
||||
{
|
||||
List<BakedQuad> quad = ((IForgeBakedModel) mc.getModelManager().getBlockModelShaper().getBlockModel(blockState)).getQuads(blockState, Direction.UP, new Random(0), dataMap);
|
||||
if (!quad.isEmpty())
|
||||
{
|
||||
texture = quad.get(0).getSprite();
|
||||
}
|
||||
else
|
||||
} else
|
||||
{
|
||||
texture = mc.getModelManager().getBlockModelShaper().getTexture(blockState, world, blockPos);
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
{
|
||||
texture = mc.getModelManager().getBlockModelShaper().getTexture(blockState, world, blockPos);
|
||||
}
|
||||
@@ -660,7 +670,7 @@ public class LodBuilder
|
||||
/*if (blockState.getBlock() instanceof LeavesBlock)
|
||||
color = 0;
|
||||
else*/
|
||||
continue;
|
||||
continue;
|
||||
} else
|
||||
{
|
||||
color = texture.getPixelRGBA(k, i, j);
|
||||
|
||||
@@ -4,14 +4,16 @@ public interface LevelContainer
|
||||
{
|
||||
public static final char VERTICAL_DATA_DELIMITER = '\t';
|
||||
public static final char DATA_DELIMITER = ' ';
|
||||
|
||||
/**With this you can add data to the level container
|
||||
*
|
||||
* @param data actual data to add in a array of long format.
|
||||
* @param posX x position in the detail level
|
||||
* @param posZ z position in the detail level
|
||||
* @param index z position in the detail level
|
||||
* @return true if correctly added, false otherwise
|
||||
*/
|
||||
public boolean addData(long[] data, int posX, int posZ);
|
||||
public boolean addData(long data, int posX, int posZ, int index);
|
||||
|
||||
/**With this you can add data to the level container
|
||||
*
|
||||
@@ -28,7 +30,7 @@ public interface LevelContainer
|
||||
* @param posZ z position in the detail level
|
||||
* @return the data in long array format
|
||||
*/
|
||||
public long[] getData(int posX, int posZ);
|
||||
public long getData(int posX, int posZ, int index);
|
||||
|
||||
/**With this you can get data from the level container
|
||||
*
|
||||
@@ -50,6 +52,11 @@ public interface LevelContainer
|
||||
*/
|
||||
public byte getDetailLevel();
|
||||
|
||||
|
||||
public int getMaxVerticalData();
|
||||
|
||||
public void clear(int posX, int posZ);
|
||||
|
||||
/**This return a level container with detail level lower than the current level.
|
||||
* The new level container may use information of this level.
|
||||
* @return the new level container
|
||||
|
||||
@@ -444,23 +444,23 @@ public class LodDimension
|
||||
cutAndGenThreads.execute(thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add the given LOD to this dimension at the coordinate
|
||||
* stored in the LOD. If an LOD already exists at the given
|
||||
* coordinates it will be overwritten.
|
||||
*/
|
||||
public Boolean addData(byte detailLevel, int posX, int posZ, long[] dataPoint, boolean dontSave, boolean serverQuality)
|
||||
public Boolean addData(byte detailLevel, int posX, int posZ, int verticalIndex, long data, boolean dontSave, boolean serverQuality)
|
||||
{
|
||||
|
||||
|
||||
// don't continue if the region can't be saved
|
||||
int regionPosX = LevelPosUtil.getRegion(detailLevel, posX);
|
||||
int regionPosZ = LevelPosUtil.getRegion(detailLevel, posZ);
|
||||
|
||||
|
||||
LodRegion region = getRegion(regionPosX, regionPosZ);
|
||||
if (region == null)
|
||||
return false;
|
||||
boolean nodeAdded = region.addData(detailLevel, posX, posZ, dataPoint, serverQuality);
|
||||
boolean nodeAdded = region.addData(detailLevel, posX, posZ, verticalIndex, data, serverQuality);
|
||||
// only save valid LODs to disk
|
||||
if (!dontSave && fileHandler != null)
|
||||
{
|
||||
@@ -565,7 +565,22 @@ public class LodDimension
|
||||
if (region != null)
|
||||
region.getDataToRender(posToRender, playerPosX, playerPosZ);
|
||||
}
|
||||
|
||||
|
||||
public int getMaxVerticalData(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 0;
|
||||
}
|
||||
|
||||
return region.getMaxVerticalData(detailLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data point at the given X and Z coordinates
|
||||
* in this dimension.
|
||||
@@ -573,7 +588,7 @@ public class LodDimension
|
||||
* Returns null if the LodChunk doesn't exist or
|
||||
* is outside the loaded area.
|
||||
*/
|
||||
public long[] getData(byte detailLevel, int posX, int posZ)
|
||||
public long 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.");
|
||||
@@ -582,12 +597,13 @@ public class LodDimension
|
||||
|
||||
if (region == null)
|
||||
{
|
||||
return new long[]{DataPointUtil.EMPTY_DATA};
|
||||
return DataPointUtil.EMPTY_DATA;
|
||||
}
|
||||
|
||||
return region.getData(detailLevel, posX, posZ);
|
||||
return region.getData(detailLevel, posX, posZ, verticalIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the data point at the given X and Z coordinates
|
||||
* in this dimension.
|
||||
@@ -609,7 +625,21 @@ public class LodDimension
|
||||
|
||||
return region.getSingleData(detailLevel, posX, posZ);
|
||||
}
|
||||
|
||||
|
||||
public void clear(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;
|
||||
}
|
||||
|
||||
region.clear(detailLevel, posX, posZ);
|
||||
}
|
||||
|
||||
public boolean getRegenByArrayIndex(int xIndex, int zIndex)
|
||||
{
|
||||
@@ -761,4 +791,5 @@ public class LodDimension
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -79,13 +79,17 @@ public class LodRegion
|
||||
return generationMode;
|
||||
}
|
||||
|
||||
public int getMaxVerticalData(byte detailLevel)
|
||||
{
|
||||
return dataContainer[detailLevel].getMaxVerticalData();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method can be used to insert data into the LodRegion
|
||||
*
|
||||
* @param dataPoint
|
||||
* @return if the data was added successfully
|
||||
*/
|
||||
public boolean addData(byte detailLevel, int posX, int posZ, long[] dataPoint, boolean serverQuality)
|
||||
public boolean addData(byte detailLevel, int posX, int posZ, int verticalIndex, long data, boolean serverQuality)
|
||||
{
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
@@ -97,12 +101,12 @@ public class LodRegion
|
||||
try
|
||||
{
|
||||
//add the node data
|
||||
this.dataContainer[detailLevel].addData(dataPoint, posX, posZ);
|
||||
this.dataContainer[detailLevel].addData(data, posX, posZ, verticalIndex);
|
||||
return true;
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
{
|
||||
String detailMessage = "pos: [" + posX + "," + posZ + "] dataPoint: [" + dataPoint + "] serverQuality: [" + serverQuality + "] dataContainer";
|
||||
String detailMessage = "pos: [" + posX + "," + posZ + "] dataPoint: [" + data + "] serverQuality: [" + serverQuality + "] dataContainer";
|
||||
detailMessage += this.dataContainer != null ? ": [NULL]" : " at detailLevel: [" + dataContainer[detailLevel] + "]";
|
||||
|
||||
ClientProxy.LOGGER.error("addSingleData: " + e.getMessage() + "\t" + detailMessage);
|
||||
@@ -156,11 +160,9 @@ public class LodRegion
|
||||
*
|
||||
* @return the data at the relative pos and level
|
||||
*/
|
||||
public long[] getData(byte detailLevel, int posX, int posZ)
|
||||
public long getData(byte detailLevel, int posX, int posZ, int verticalIndex)
|
||||
{
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
return dataContainer[detailLevel].getData(posX, posZ);
|
||||
return dataContainer[detailLevel].getData(posX, posZ,verticalIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,12 +172,13 @@ public class LodRegion
|
||||
*/
|
||||
public long getSingleData(byte detailLevel, int posX, int posZ)
|
||||
{
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
return dataContainer[detailLevel].getSingleData(posX, posZ);
|
||||
}
|
||||
|
||||
|
||||
public void clear(byte detailLevel, int posX, int posZ)
|
||||
{
|
||||
dataContainer[detailLevel].clear(posX, posZ);
|
||||
}
|
||||
/**
|
||||
* This method will return all the levelPos that are renderable according to the requisite given in input
|
||||
*
|
||||
@@ -378,7 +381,7 @@ public class LodRegion
|
||||
if(dataContainer[detailLevel].doesItExist(posX,posZ))
|
||||
{
|
||||
//We take the bottom information always
|
||||
return DataPointUtil.getGenerationMode(dataContainer[detailLevel].getData(posX,posZ)[0]);
|
||||
return DataPointUtil.getGenerationMode(dataContainer[detailLevel].getSingleData(posX,posZ));
|
||||
}else
|
||||
{
|
||||
return DistanceGenerationMode.NONE.complexity;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.seibel.lod.objects;
|
||||
|
||||
import com.seibel.lod.util.*;
|
||||
|
||||
import javax.xml.crypto.Data;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SingleLevelContainer implements LevelContainer
|
||||
@@ -8,51 +10,61 @@ public class SingleLevelContainer implements LevelContainer
|
||||
public final byte detailLevel;
|
||||
public final int size;
|
||||
|
||||
public final long[][] data;
|
||||
public final long[][] dataContainer;
|
||||
|
||||
public SingleLevelContainer(byte detailLevel)
|
||||
{
|
||||
this.detailLevel = detailLevel;
|
||||
size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel);
|
||||
data = new long[size][size];
|
||||
dataContainer = new long[size][size];
|
||||
}
|
||||
|
||||
public boolean addData(long[] newData, int posX, int posZ){
|
||||
|
||||
public void clear(int posX, int posZ)
|
||||
{
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
data[posX][posZ] = newData[0];
|
||||
dataContainer[posX][posZ] = DataPointUtil.EMPTY_DATA;
|
||||
}
|
||||
|
||||
public boolean addData(long data, int posX, int posZ, int index)
|
||||
{
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
dataContainer[posX][posZ] = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean addSingleData(long newData, int posX, int posZ){
|
||||
public boolean addSingleData(long newData, int posX, int posZ)
|
||||
{
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
data[posX][posZ] = newData;
|
||||
dataContainer[posX][posZ] = newData;
|
||||
return true;
|
||||
}
|
||||
|
||||
public long[] getData(int posX, int posZ){
|
||||
long[] dataArray = ThreadMapUtil.getSingleGetDataArray();
|
||||
public long getData(int posX, int posZ, int index)
|
||||
{
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
//Improve this using a thread map to long[]
|
||||
dataArray[0] = data[posX][posZ];
|
||||
return dataArray;
|
||||
return dataContainer[posX][posZ];
|
||||
}
|
||||
|
||||
public long getSingleData(int posX, int posZ){
|
||||
public long getSingleData(int posX, int posZ)
|
||||
{
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
//Improve this using a thread map to long[]
|
||||
return data[posX][posZ];
|
||||
return dataContainer[posX][posZ];
|
||||
}
|
||||
|
||||
public byte getDetailLevel(){
|
||||
public byte getDetailLevel()
|
||||
{
|
||||
return detailLevel;
|
||||
}
|
||||
|
||||
public LevelContainer expand(){
|
||||
public LevelContainer expand()
|
||||
{
|
||||
return new SingleLevelContainer((byte) (getDetailLevel() - 1));
|
||||
}
|
||||
|
||||
@@ -64,22 +76,23 @@ public class SingleLevelContainer implements LevelContainer
|
||||
detailLevel = inputData[index];
|
||||
index++;
|
||||
size = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel);
|
||||
this.data = new long[size][size];
|
||||
this.dataContainer = new long[size][size];
|
||||
for (int x = 0; x < size; x++)
|
||||
{
|
||||
for (int z = 0; z < size; z++)
|
||||
{
|
||||
newData = 0;
|
||||
if(inputData[index] == 0)
|
||||
if (inputData[index] == 0)
|
||||
index++;
|
||||
else if(index + 7 >= inputData.length)
|
||||
break;
|
||||
else {
|
||||
for (tempIndex = 0; tempIndex < 8; tempIndex++)
|
||||
newData += (((long) inputData[index + tempIndex]) & 0xff) << (8 * tempIndex);
|
||||
index = index + 8;
|
||||
}
|
||||
data[x][z] = newData;
|
||||
else if (index + 7 >= inputData.length)
|
||||
break;
|
||||
else
|
||||
{
|
||||
for (tempIndex = 0; tempIndex < 8; tempIndex++)
|
||||
newData += (((long) inputData[index + tempIndex]) & 0xff) << (8 * tempIndex);
|
||||
index = index + 8;
|
||||
}
|
||||
dataContainer[x][z] = newData;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -101,15 +114,19 @@ public class SingleLevelContainer implements LevelContainer
|
||||
{
|
||||
childPosX = 2 * posX + x;
|
||||
childPosZ = 2 * posZ + z;
|
||||
dataToMerge[2*x + z] = ((SingleLevelContainer) lowerLevelContainer).getSingleData(childPosX, childPosZ);
|
||||
dataToMerge[2 * x + z] = ((SingleLevelContainer) lowerLevelContainer).getSingleData(childPosX, childPosZ);
|
||||
}
|
||||
}
|
||||
data = DataPointUtil.mergeSingleData(dataToMerge);
|
||||
addSingleData(data,posX,posZ);
|
||||
addSingleData(data, posX, posZ);
|
||||
}
|
||||
|
||||
public int getMaxVerticalData(){
|
||||
return 1;
|
||||
}
|
||||
|
||||
public boolean doesItExist(int posX, int posZ){
|
||||
public boolean doesItExist(int posX, int posZ)
|
||||
{
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
//Improve this using a thread map to long[]
|
||||
@@ -127,14 +144,16 @@ public class SingleLevelContainer implements LevelContainer
|
||||
{
|
||||
for (int z = 0; z < size; z++)
|
||||
{
|
||||
if(data[x][z] == 0){
|
||||
if (dataContainer[x][z] == 0)
|
||||
{
|
||||
tempData[index] = 0;
|
||||
index++;
|
||||
} else {
|
||||
for (tempIndex = 0; tempIndex < 8; tempIndex++)
|
||||
tempData[index + tempIndex] = (byte) (data[x][z] >>> (8 * tempIndex));
|
||||
index += 8;
|
||||
}
|
||||
} else
|
||||
{
|
||||
for (tempIndex = 0; tempIndex < 8; tempIndex++)
|
||||
tempData[index + tempIndex] = (byte) (dataContainer[x][z] >>> (8 * tempIndex));
|
||||
index += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Arrays.copyOfRange(tempData, 0, index);
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package com.seibel.lod.objects;
|
||||
|
||||
import com.seibel.lod.util.DataPointUtil;
|
||||
import com.seibel.lod.util.LevelPosUtil;
|
||||
import com.seibel.lod.util.LodUtil;
|
||||
import com.seibel.lod.util.ThreadMapUtil;
|
||||
import com.seibel.lod.util.*;
|
||||
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.Arrays;
|
||||
@@ -15,13 +12,14 @@ public class VerticalLevelContainer implements LevelContainer
|
||||
public final int size;
|
||||
public final int maxVerticalData;
|
||||
|
||||
public final long[][][] dataContainer;
|
||||
public final long[] dataContainer;
|
||||
|
||||
public VerticalLevelContainer(byte detailLevel)
|
||||
{
|
||||
this.detailLevel = detailLevel;
|
||||
size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel);
|
||||
dataContainer = new long[size][size][1];
|
||||
maxVerticalData = DetailDistanceUtil.getMaxVerticalData(detailLevel);
|
||||
dataContainer = new long[size * size * DetailDistanceUtil.getMaxVerticalData(detailLevel)];
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -30,38 +28,51 @@ public class VerticalLevelContainer implements LevelContainer
|
||||
return detailLevel;
|
||||
}
|
||||
|
||||
public boolean addData(long[] newData, int posX, int posZ){
|
||||
public void clear(int posX, int posZ){
|
||||
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
dataContainer[posX][posZ] = newData;
|
||||
int index = 0;
|
||||
for(int i = 0; i < maxVerticalData; i++){
|
||||
index = posX*size*maxVerticalData + posZ*maxVerticalData + i;
|
||||
dataContainer[index] = DataPointUtil.EMPTY_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addData(long data, int posX, int posZ, int verticalIndex){
|
||||
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
dataContainer[posX*size*maxVerticalData + posZ*maxVerticalData + verticalIndex] = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean addSingleData(long newData, int posX, int posZ){
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
dataContainer[posX][posZ][0] = newData;
|
||||
return true;
|
||||
public boolean addSingleData(long data, int posX, int posZ){
|
||||
return addData(data, posX, posZ, 0);
|
||||
}
|
||||
|
||||
public long[] getData(int posX, int posZ){
|
||||
public long getData(int posX, int posZ, int verticalIndex){
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
return dataContainer[posX][posZ];
|
||||
return dataContainer[posX*size*maxVerticalData + posZ*maxVerticalData + verticalIndex];
|
||||
}
|
||||
|
||||
public long getSingleData(int posX, int posZ){
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
//Improve this using a thread map to long[]
|
||||
return dataContainer[posX][posZ][0];
|
||||
return getData(posX,posZ,0);
|
||||
}
|
||||
|
||||
public int getMaxVerticalData(){
|
||||
return maxVerticalData;
|
||||
}
|
||||
|
||||
public int getSize(){
|
||||
return size;
|
||||
}
|
||||
|
||||
public boolean doesItExist(int posX, int posZ){
|
||||
long[] data = getData(posX,posZ);
|
||||
if(data == null)
|
||||
return false;
|
||||
return DataPointUtil.doesItExist(data[0]);
|
||||
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
|
||||
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
|
||||
return DataPointUtil.doesItExist(getSingleData(posX,posZ));
|
||||
}
|
||||
|
||||
public VerticalLevelContainer(byte inputData[])
|
||||
@@ -104,7 +115,8 @@ public class VerticalLevelContainer implements LevelContainer
|
||||
public void updateData(LevelContainer lowerLevelContainer, int posX, int posZ)
|
||||
{
|
||||
//We reset the array
|
||||
long[][] dataToMerge = ThreadMapUtil.getVerticalUpdateArray();
|
||||
//long[] dataToMerge = ThreadMapUtil.getVerticalUpdateArray(maxVerticalData);
|
||||
long[] dataToMerge = new long[4*lowerLevelContainer.getMaxVerticalData()];
|
||||
|
||||
int childPosX;
|
||||
int childPosZ;
|
||||
@@ -117,11 +129,19 @@ public class VerticalLevelContainer implements LevelContainer
|
||||
{
|
||||
childPosX = 2 * posX + x;
|
||||
childPosZ = 2 * posZ + z;
|
||||
dataToMerge[2*z + x] = lowerLevelContainer.getData(childPosX, childPosZ);
|
||||
for(int verticalIndex = 0; verticalIndex < maxVerticalData; verticalIndex++)
|
||||
dataToMerge[(z*2+x)*maxVerticalData + verticalIndex] = lowerLevelContainer.getData(childPosX, childPosZ, verticalIndex);
|
||||
}
|
||||
}
|
||||
data = DataPointUtil.mergeMultiData(dataToMerge);
|
||||
addData(data,posX,posZ);
|
||||
data = DataPointUtil.mergeMultiData(dataToMerge, lowerLevelContainer.getDetailLevel());
|
||||
|
||||
for(int verticalIndex = 0; (verticalIndex < data.length) && (verticalIndex < maxVerticalData); verticalIndex++)
|
||||
{
|
||||
addData(data[verticalIndex],
|
||||
posX,
|
||||
posZ,
|
||||
verticalIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] toDataString()
|
||||
|
||||
@@ -4,6 +4,9 @@ import com.seibel.lod.enums.DistanceGenerationMode;
|
||||
|
||||
import net.minecraft.client.renderer.texture.NativeImage;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class DataPointUtil
|
||||
{
|
||||
/*
|
||||
@@ -281,7 +284,7 @@ public class DataPointUtil
|
||||
int size = dataToMerge.length / inputVerticalData;
|
||||
short[] projection = ThreadMapUtil.getProjectionShort((WORLD_HEIGHT + 1) / 16);
|
||||
short[][] heightAndDepth = ThreadMapUtil.getHeightAndDepth(inputVerticalData);
|
||||
long[] singleDataToMerge = ThreadMapUtil.getSingleAddDataToMerge(dataToMerge.length);
|
||||
long[] singleDataToMerge = ThreadMapUtil.getSingleAddDataToMerge(size);
|
||||
int genMode = DistanceGenerationMode.SERVER.complexity;
|
||||
boolean allEmpty = true;
|
||||
boolean allVoid = true;
|
||||
@@ -383,7 +386,7 @@ public class DataPointUtil
|
||||
{
|
||||
depth = heightAndDepth[j][0];
|
||||
height = heightAndDepth[j][1];
|
||||
for(int k = 0; k < dataToMerge.length; k++){
|
||||
for(int k = 0; k < size; k++){
|
||||
singleDataToMerge[k] = 0;
|
||||
}
|
||||
for (int index = 0; index < size; index++)
|
||||
|
||||
@@ -11,7 +11,7 @@ public class ThreadMapUtil
|
||||
public static final ConcurrentMap<String, long[]> threadSingleGetDataMap = new ConcurrentHashMap<>();
|
||||
public static final ConcurrentMap<String, long[]> threadSingleUpdateMap = new ConcurrentHashMap<>();
|
||||
public static final ConcurrentMap<String, long[][]> threadBuilderArrayMap = new ConcurrentHashMap<>();
|
||||
public static final ConcurrentMap<String, long[][][]> threadBuilderVerticalArrayMap = new ConcurrentHashMap<>();
|
||||
public static final ConcurrentMap<String, long[][]> threadBuilderVerticalArrayMap = new ConcurrentHashMap<>();
|
||||
public static final ConcurrentMap<String, long[]> threadVerticalAddDataMap = new ConcurrentHashMap<>();
|
||||
public static final ConcurrentMap<String, long[]> threadVerticalGetDataMap = new ConcurrentHashMap<>();
|
||||
public static final ConcurrentMap<String, long[][]> threadVerticalUpdateMap = new ConcurrentHashMap<>();
|
||||
@@ -62,11 +62,11 @@ public class ThreadMapUtil
|
||||
return threadBuilderArrayMap.get(Thread.currentThread().getName());
|
||||
}
|
||||
|
||||
public static long[][][] getBuilderVerticalArray()
|
||||
public static long[][] getBuilderVerticalArray()
|
||||
{
|
||||
if (!threadBuilderVerticalArrayMap.containsKey(Thread.currentThread().getName()) || (threadBuilderVerticalArrayMap.get(Thread.currentThread().getName()) == null))
|
||||
{
|
||||
long[][][] array = new long[5][][];
|
||||
long[][] array = new long[5][];
|
||||
threadBuilderVerticalArrayMap.put(Thread.currentThread().getName(), array);
|
||||
}
|
||||
return threadBuilderVerticalArrayMap.get(Thread.currentThread().getName());
|
||||
|
||||
Reference in New Issue
Block a user