fixed nether roof bug

This commit is contained in:
Leonardo
2021-09-21 15:09:28 +02:00
parent c6b063a380
commit 435c5ee73a
5 changed files with 93 additions and 162 deletions
@@ -219,8 +219,6 @@ public class LodBuilder
posX = LevelPosUtil.convert((byte) 0, chunk.getPos().x * 16 + startX, detail.detailLevel);
posZ = LevelPosUtil.convert((byte) 0, chunk.getPos().z * 16 + startZ, detail.detailLevel);
long[] data;
boolean isServer = config.distanceGenerationMode == DistanceGenerationMode.SERVER;
switch (verticalQuality)
{
default:
@@ -228,35 +226,41 @@ public class LodBuilder
long singleData;
long[] dataToMergeSingle = createSingleDataToMerge(detail, chunk, config, startX, startZ, endX, endZ);
singleData = DataPointUtil.mergeSingleData(dataToMergeSingle);
lodDim.addSingleData(detailLevel,
lodDim.addData(detailLevel,
posX,
posZ,
0,
singleData,
false,
isServer);
false);
break;
case MULTI_LOD:
long[] dataToMergeVertical = createVerticalDataToMerge(detail, chunk, config, startX, startZ, endX, endZ);
/*for(long dat : dataToMergeVertical){
if(!DataPointUtil.doesItExist(dat) || DataPointUtil.isItVoid(dat))
continue;
System.out.println(DataPointUtil.toString(dat));
}*/
data = DataPointUtil.mergeMultiData(dataToMergeVertical, DataPointUtil.WORLD_HEIGHT, DetailDistanceUtil.getMaxVerticalData(detailLevel));
lodDim.clear(detailLevel, posX, posZ);
//lodDim.clear(detailLevel, posX, posZ);
if (data.length != 0 || data != null)
{
for (int verticalIndex = 0; (verticalIndex < data.length) && (verticalIndex < lodDim.getMaxVerticalData(detailLevel, posX, posZ)); verticalIndex++)
for (int verticalIndex = 0; verticalIndex < lodDim.getMaxVerticalData(detailLevel, posX, posZ); verticalIndex++)
{
if (!DataPointUtil.doesItExist(data[verticalIndex]))
break;
lodDim.addData(detailLevel,
posX,
posZ,
verticalIndex,
data[verticalIndex],
false,
isServer);
false);
}
}
break;
}
}
lodDim.updateData(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z);
} catch (Exception e)
@@ -287,15 +291,11 @@ public class LodBuilder
int yAbs;
int zAbs;
boolean hasCeiling = mc.getClientWorld().dimensionType().hasCeiling();
boolean hasSkyLight = mc.getClientWorld().dimensionType().hasSkyLight();
BlockPos.Mutable blockPos = new BlockPos.Mutable(0, 0, 0);
int index;
if (dataToMerge == null)
{
dataToMerge = new long[size * size * DataPointUtil.WORLD_HEIGHT];
}
for (index = 0; index < size * size; index++)
{
for (int verticalIndex = 0; verticalIndex < verticalData; verticalIndex++)
@@ -308,13 +308,12 @@ public class LodBuilder
zAbs = chunkPos.getMinBlockZ() + zRel;
//Calculate the height of the lod
yAbs = 255;
yAbs = 1024;
int count = 0;
boolean topBlock = true;
while (yAbs > 0)
{
height = determineHeightPointFrom(chunk, config, xRel, zRel, yAbs, blockPos);
//If the lod is at default, then we set this as void data
if (height == DEFAULT_HEIGHT)
{
@@ -339,13 +338,22 @@ public class LodBuilder
}
lightBlock = light & 0b1111;
if (!hasCeiling && topBlock)
lightSky = 15; //default max light
else
{
if (hasSkyLight)
{
lightSky = 15; //default max light
} else
{
lightSky = 0;
}
} else
{
lightSky = (light >> 4) & 0b1111;
topBlock = false;
}
dataToMerge[index * verticalData + count] = DataPointUtil.createDataPoint(height, depth, color, lightSky, lightBlock, generation);
topBlock = false;
yAbs = depth - 1;
count++;
}
@@ -883,8 +891,8 @@ public class LodBuilder
}
return blockState.getBlock() != Blocks.AIR
&& blockState.getBlock() != Blocks.CAVE_AIR
&& blockState.getBlock() != Blocks.BARRIER;
&& blockState.getBlock() != Blocks.CAVE_AIR
&& blockState.getBlock() != Blocks.BARRIER;
}
return false;
}
@@ -458,7 +458,7 @@ public class LodDimension
* 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, int verticalIndex, long data, boolean dontSave, boolean serverQuality)
public Boolean addData(byte detailLevel, int posX, int posZ, int verticalIndex, long data, boolean dontSave)
{
// don't continue if the region can't be saved
@@ -468,45 +468,7 @@ public class LodDimension
LodRegion region = getRegion(regionPosX, regionPosZ);
if (region == null)
return false;
boolean nodeAdded = region.addData(detailLevel, posX, posZ, verticalIndex, data, serverQuality);
// only save valid LODs to disk
if (!dontSave && fileHandler != null)
{
try
{
// mark the region as dirty so it will be saved to disk
int xIndex = (regionPosX - center.x) + halfWidth;
int zIndex = (regionPosZ - center.z) + halfWidth;
isRegionDirty[xIndex][zIndex] = true;
regionNeedsRegen[xIndex][zIndex] = true;
regenDimension = true;
} catch (ArrayIndexOutOfBoundsException e)
{
e.printStackTrace();
// This method was probably called when the dimension was changing size.
// Hopefully this shouldn't be an issue.
}
}
return nodeAdded;
}
/**
* 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 addSingleData(byte detailLevel, int posX, int posZ, long dataPoint, 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.addSingleData(detailLevel, posX, posZ, dataPoint, serverQuality);
boolean nodeAdded = region.addData(detailLevel, posX, posZ, verticalIndex, data);
// only save valid LODs to disk
if (!dontSave && fileHandler != null)
{
@@ -16,8 +16,6 @@ import com.seibel.lod.util.LodUtil;
* if an array contain coordinate the order is the following
* 0 for x, 1 for z in 2D
* 0 for x, 1 for y, 2 for z in 3D
*
*
*/
public class LodRegion
{
@@ -60,7 +58,8 @@ public class LodRegion
//Initialize all the different matrices
for (byte lod = minDetailLevel; lod <= LodUtil.REGION_DETAIL_LEVEL; lod++)
{
switch (verticalQuality){
switch (verticalQuality)
{
default:
case HEIGHTMAP:
dataContainer[lod] = new SingleLevelContainer(lod);
@@ -71,10 +70,12 @@ public class LodRegion
}
}
}
public VerticalQuality getLodQualityMode()
{
return verticalQuality;
}
public DistanceGenerationMode getGenerationMode()
{
return generationMode;
@@ -90,70 +91,15 @@ public class LodRegion
*
* @return if the data was added successfully
*/
public boolean addData(byte detailLevel, int posX, int posZ, int verticalIndex, long data, boolean serverQuality)
public boolean addData(byte detailLevel, int posX, int posZ, int verticalIndex, long data)
{
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
if (!doesDataExist(detailLevel, posX, posZ) || serverQuality)
{
//update the number of nodes present
//if (!doesDataExist(detailLevel, posX, posZ)) numberOfPoints++;
try
{
//add the node data
this.dataContainer[detailLevel].addData(data, posX, posZ, verticalIndex);
return true;
}
catch (NullPointerException e)
{
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);
return false;
}
}
else
{
return false;
}
}
/**
* This method can be used to insert data into the LodRegion
*
* @param dataPoint
* @return if the data was added successfully
*/
public boolean addSingleData(byte detailLevel, int posX, int posZ, long dataPoint, boolean serverQuality)
{
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
if (!doesDataExist(detailLevel, posX, posZ) || serverQuality)
{
//update the number of nodes present
//if (!doesDataExist(detailLevel, posX, posZ)) numberOfPoints++;
try
{
//add the node data
this.dataContainer[detailLevel].addSingleData(dataPoint, posX, posZ);
return true;
}
catch (NullPointerException e)
{
String detailMessage = "pos: [" + posX + "," + posZ + "] dataPoint: [" + dataPoint + "] serverQuality: [" + serverQuality + "] dataContainer";
detailMessage += this.dataContainer != null ? ": [NULL]" : " at detailLevel: [" + dataContainer[detailLevel] + "]";
ClientProxy.LOGGER.error("addSingleData: " + e.getMessage() + "\t" + detailMessage);
return false;
}
}
else
{
return false;
}
//update the number of nodes present
//if (!doesDataExist(detailLevel, posX, posZ)) numberOfPoints++;
//add the node data
this.dataContainer[detailLevel].addData(data, posX, posZ, verticalIndex);
return true;
}
/**
@@ -163,7 +109,7 @@ public class LodRegion
*/
public long getData(byte detailLevel, int posX, int posZ, int verticalIndex)
{
return dataContainer[detailLevel].getData(posX, posZ,verticalIndex);
return dataContainer[detailLevel].getData(posX, posZ, verticalIndex);
}
/**
@@ -180,6 +126,7 @@ public class LodRegion
{
dataContainer[detailLevel].clear(posX, posZ);
}
/**
* This method will return all the levelPos that are renderable according to the requisite given in input
*
@@ -326,6 +273,7 @@ public class LodRegion
}
/**
*
*/
public void updateArea(byte detailLevel, int posX, int posZ)
{
@@ -354,6 +302,7 @@ public class LodRegion
}
/**
*
*/
private void update(byte detailLevel, int posX, int posZ)
{
@@ -366,10 +315,10 @@ public class LodRegion
*/
public boolean doesDataExist(byte detailLevel, int posX, int posZ)
{
if(detailLevel < minDetailLevel) return false;
if (detailLevel < minDetailLevel) return false;
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
if(dataContainer == null || dataContainer[detailLevel] == null)
if (dataContainer == null || dataContainer[detailLevel] == null)
return false;
return dataContainer[detailLevel].doesItExist(posX, posZ);
}
@@ -379,11 +328,11 @@ public class LodRegion
*/
public byte getGenerationMode(byte detailLevel, int posX, int posZ)
{
if(dataContainer[detailLevel].doesItExist(posX,posZ))
if (dataContainer[detailLevel].doesItExist(posX, posZ))
{
//We take the bottom information always
return DataPointUtil.getGenerationMode(dataContainer[detailLevel].getSingleData(posX,posZ));
}else
return DataPointUtil.getGenerationMode(dataContainer[detailLevel].getSingleData(posX, posZ));
} else
{
return DistanceGenerationMode.NONE.complexity;
}
@@ -445,13 +394,13 @@ public class LodRegion
{
if (detailLevel < minDetailLevel)
{
for (byte tempLod = (byte) (minDetailLevel - 1); tempLod >= detailLevel ; tempLod--)
for (byte tempLod = (byte) (minDetailLevel - 1); tempLod >= detailLevel; tempLod--)
{
if(dataContainer[tempLod + 1] == null)
if (dataContainer[tempLod + 1] == null)
{
dataContainer[tempLod + 1] = new SingleLevelContainer((byte) (tempLod + 1));
}
dataContainer[tempLod] = dataContainer[tempLod+1].expand();
dataContainer[tempLod] = dataContainer[tempLod + 1].expand();
}
minDetailLevel = detailLevel;
}
@@ -467,6 +416,7 @@ public class LodRegion
/**
* return needed memory in byte
*
* @param template
*/
public int getMinMemoryNeeded(LodTemplate template)
@@ -489,9 +439,10 @@ public class LodRegion
return getLevel(LodUtil.REGION_DETAIL_LEVEL).toString();
}
public int getNumberOfLods(){
public int getNumberOfLods()
{
int count = 0;
for(LevelContainer container : dataContainer)
for (LevelContainer container : dataContainer)
count += container.getMaxNumberOfLods();
return count;
}
@@ -4,7 +4,6 @@ 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
@@ -43,7 +42,7 @@ public class DataPointUtil
public final static int BLUE_SHIFT = 36;
public final static int GREEN_SHIFT = BLUE_SHIFT + 8;
public final static int RED_SHIFT = BLUE_SHIFT + 16 ;
public final static int RED_SHIFT = BLUE_SHIFT + 16;
public final static int ALPHA_SHIFT = BLUE_SHIFT + 24;
public final static int COLOR_SHIFT = 36;
@@ -98,7 +97,7 @@ public class DataPointUtil
public static long createDataPoint(int alpha, int red, int green, int blue, int height, int depth, int lightSky, int lightBlock, int generationMode)
{
long dataPoint = 0;
dataPoint += ((alpha >>> ALPHA_DOWNSIZE_SHIFT) & ALPHA_MASK ) << ALPHA_SHIFT;
dataPoint += ((alpha >>> ALPHA_DOWNSIZE_SHIFT) & ALPHA_MASK) << ALPHA_SHIFT;
dataPoint += (red & RED_MASK) << RED_SHIFT;
dataPoint += (green & GREEN_MASK) << GREEN_SHIFT;
dataPoint += (blue & BLUE_MASK) << BLUE_SHIFT;
@@ -245,7 +244,7 @@ public class DataPointUtil
tempGreen += DataPointUtil.getGreen(data);
tempBlue += DataPointUtil.getBlue(data);
tempHeight = Math.max(tempHeight, DataPointUtil.getHeight(data));
tempDepth = Math.min(tempDepth, DataPointUtil.getDepth(data));
tempDepth = Math.min(tempDepth, DataPointUtil.getDepth(data));
tempLightBlock += DataPointUtil.getLightBlock(data);
tempLightSky += DataPointUtil.getLightSky(data);
}
@@ -277,19 +276,24 @@ public class DataPointUtil
}
}
public static long[] mergeMultiData(long[] dataToMerge, int inputVerticalData,int maxVerticalData)
public static long[] mergeMultiData(long[] dataToMerge, int inputVerticalData, int maxVerticalData)
{
int size = dataToMerge.length / inputVerticalData;
short[] projection = ThreadMapUtil.getProjectionShort((WORLD_HEIGHT) / 16 + 1);
short[] heightAndDepth = ThreadMapUtil.getHeightAndDepth(inputVerticalData * 2);
short[] projection = ThreadMapUtil.getProjectionShort((WORLD_HEIGHT) / 16 + 1);
short[] heightAndDepth = ThreadMapUtil.getHeightAndDepth((WORLD_HEIGHT + 1) * 2);
long[] singleDataToMerge = ThreadMapUtil.getSingleAddDataToMerge(size);
long[] dataPoint = ThreadMapUtil.verticalDataArray(WORLD_HEIGHT + 1);
Arrays.fill(projection, (short) 0);
Arrays.fill(heightAndDepth, (short) 0);
Arrays.fill(singleDataToMerge, EMPTY_DATA);
Arrays.fill(dataPoint, EMPTY_DATA);
int genMode = DistanceGenerationMode.SERVER.complexity;
boolean allEmpty = true;
boolean allVoid = true;
long singleData;
long[] dataPoint = ThreadMapUtil.verticalDataArray(WORLD_HEIGHT+1);
Arrays.fill(projection, (short) 0); //probably can remove
short depth;
short height;
@@ -314,11 +318,9 @@ public class DataPointUtil
}
}
}
//We check if there is any data that's not empty or void
if (allEmpty)
{
dataPoint[0] = EMPTY_DATA;
return dataPoint;
}
if (allVoid)
@@ -326,14 +328,13 @@ public class DataPointUtil
dataPoint[0] = createVoidDataPoint(genMode);
return dataPoint;
}
//We extract the merged data
int count = 0;
int i = 0;
int ii = 0;
while (i < projection.length)
{
while (i < projection.length && projection[i] == 0) i++;
while (i < projection.length && projection[i] == 0) i++;
if (i == projection.length)
break; //we reached end of WORLD_HEIGHT and it's nothing more here
while (ii < 15 && ((projection[i] >>> ii) & 1) == 0) ii++;
@@ -343,14 +344,14 @@ public class DataPointUtil
i++;
continue;
}
depth = (short)( i * 16 + ii);
depth = (short) (i * 16 + ii);
while (ii < 15 && ((projection[i] >>> ii) & 1) == 1) ii++;
if (ii >= 15 && ((projection[i] >>> ii) & 1) == 1) //if end is not in this chunk
{
ii = 0;
i++;
while (i < projection.length && ~(projection[i]) == 0) i++; //check for big solid blocks
while (i < projection.length && ~(projection[i]) == 0) i++; //check for big solid blocks
if (i == projection.length) //solid to WORLD_HEIGHT
{
heightAndDepth[count * 2] = depth;
@@ -359,7 +360,7 @@ public class DataPointUtil
}
while ((((projection[i] >>> ii) & 1) == 1)) ii++;
}
height = (short)(i * 16 + ii - 1);
height = (short) (i * 16 + ii - 1);
heightAndDepth[count * 2] = depth;
heightAndDepth[count * 2 + 1] = height;
count++;
@@ -379,20 +380,23 @@ public class DataPointUtil
}
}
heightAndDepth[j * 2 + 1] = heightAndDepth[(j + 1) * 2 + 1];
for (i = j + 1; i < count - 1; i++){
for (i = j + 1; i < count - 1; i++)
{
heightAndDepth[i * 2] = heightAndDepth[(i + 1) * 2];
heightAndDepth[i * 2 + 1] = heightAndDepth[(i + 1) * 2 + 1];
}
//System.arraycopy(heightAndDepth,j + 1, heightAndDepth, j,count - j - 1);
count--;
}
//As standard the vertical lods are ordered from top to bottom
for (j = count - 1; j >= 0; j--)
for (j = 0; j < count; j++)
{
depth = heightAndDepth[j * 2];
height = heightAndDepth[j * 2 + 1];
for(int k = 0; k < size; k++){
if ((depth == 0 && height == 0) || j >= heightAndDepth.length / 2)
break;
for (int k = 0; k < size; k++)
{
singleDataToMerge[k] = 0;
}
for (int index = 0; index < size; index++)
@@ -405,7 +409,7 @@ public class DataPointUtil
if ((depth <= getDepth(singleData) && getDepth(singleData) <= height)
|| (depth <= getHeight(singleData) && getHeight(singleData) <= height))
{
if(getHeight(singleData) > getHeight(singleDataToMerge[index]))
if (getHeight(singleData) > getHeight(singleDataToMerge[index]))
{
singleDataToMerge[index] = singleData;
}
@@ -414,7 +418,8 @@ public class DataPointUtil
}
}
long data = mergeSingleData(singleDataToMerge);
dataPoint[j] = createDataPoint(height, depth, getColor(data), getLightSky(data), getLightBlock(data), getGenerationMode(data));
dataPoint[count - j - 1] = createDataPoint(height, depth, getColor(data), getLightSky(data), getLightBlock(data), getGenerationMode(data));
}
return dataPoint;
}
@@ -38,6 +38,11 @@ public class ThreadMapUtil
if (!threadBuilderVerticalArrayMap.containsKey(Thread.currentThread().getName()) || (threadBuilderVerticalArrayMap.get(Thread.currentThread().getName()) == null))
{
long[][] array = new long[5][];
for(int i = 0; i < array.length; i++)
{
int size = 1 << i;
array[i] = new long[size * size * DataPointUtil.WORLD_HEIGHT];
}
threadBuilderVerticalArrayMap.put(Thread.currentThread().getName(), array);
}
return threadBuilderVerticalArrayMap.get(Thread.currentThread().getName());