Close #30 and 31 (LODs rendering on top of the player and distance based rendering)
This commit is contained in:
@@ -129,9 +129,9 @@ public class LodBuilder
|
||||
|
||||
|
||||
LodDetail detail = LodConfig.CLIENT.lodDetail.get();
|
||||
LodDataPoint[][] dataPoints = new LodDataPoint[detail.lengthCount][detail.lengthCount];
|
||||
LodDataPoint[][] dataPoints = new LodDataPoint[detail.dataPointLengthCount][detail.dataPointLengthCount];
|
||||
|
||||
for(int i = 0; i < detail.lengthCount * detail.lengthCount; i++)
|
||||
for(int i = 0; i < detail.dataPointLengthCount * detail.dataPointLengthCount; i++)
|
||||
{
|
||||
int startX = detail.startX[i];
|
||||
int startZ = detail.startZ[i];
|
||||
@@ -157,8 +157,8 @@ public class LodBuilder
|
||||
depth = 0;
|
||||
}
|
||||
|
||||
int x = i / detail.lengthCount;
|
||||
int z = i % detail.lengthCount;
|
||||
int x = i / detail.dataPointLengthCount;
|
||||
int z = i % detail.dataPointLengthCount;
|
||||
|
||||
dataPoints[x][z] = new LodDataPoint(height, depth, color);
|
||||
}
|
||||
|
||||
@@ -38,9 +38,9 @@ public class CubicLodTemplate extends AbstractLodTemplate
|
||||
// using the quality setting set by the config
|
||||
LodDetail detail = LodConfig.CLIENT.lodDetail.get();
|
||||
|
||||
int halfWidth = detail.width / 2;
|
||||
int halfWidth = detail.dataPointWidth / 2;
|
||||
|
||||
for(int i = 0; i < detail.lengthCount * detail.lengthCount; i++)
|
||||
for(int i = 0; i < detail.dataPointLengthCount * detail.dataPointLengthCount; i++)
|
||||
{
|
||||
int startX = detail.startX[i];
|
||||
int startZ = detail.startZ[i];
|
||||
@@ -51,7 +51,7 @@ public class CubicLodTemplate extends AbstractLodTemplate
|
||||
bbox = generateBoundingBox(
|
||||
centerLod.getAverageHeightOverArea(startX, startZ, endX, endZ),
|
||||
centerLod.getAverageDepthOverArea(startX, startZ, endX, endZ),
|
||||
detail.width,
|
||||
detail.dataPointWidth,
|
||||
xOffset - (halfWidth / 2) + detail.startX[i],
|
||||
yOffset,
|
||||
zOffset - (halfWidth / 2) + detail.startZ[i]);
|
||||
@@ -165,7 +165,7 @@ public class CubicLodTemplate extends AbstractLodTemplate
|
||||
public int getBufferMemoryForSingleLod(LodDetail detail)
|
||||
{
|
||||
// (sidesOnACube * pointsInASquare * (positionPoints + colorPoints))) * howManyPointsPerLodChunk
|
||||
return (6 * 4 * (3 + 4)) * detail.lengthCount * detail.lengthCount;
|
||||
return (6 * 4 * (3 + 4)) * detail.dataPointLengthCount * detail.dataPointLengthCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,11 +27,11 @@ public enum LodDetail
|
||||
FULL(16);
|
||||
|
||||
|
||||
/** How many LODs wide should
|
||||
* be drawn per LodChunk */
|
||||
public final int lengthCount;
|
||||
/** How wide each LOD is */
|
||||
public final int width;
|
||||
/** How many DataPoints should
|
||||
* be drawn per side per LodChunk */
|
||||
public final int dataPointLengthCount;
|
||||
/** How wide each LOD DataPoint is */
|
||||
public final int dataPointWidth;
|
||||
|
||||
/* Start/End X/Z give the block positions
|
||||
* for each individual dataPoint in a LodChunk */
|
||||
@@ -50,8 +50,8 @@ public enum LodDetail
|
||||
|
||||
private LodDetail(int newLengthCount)
|
||||
{
|
||||
lengthCount = newLengthCount;
|
||||
width = 16 / lengthCount;
|
||||
dataPointLengthCount = newLengthCount;
|
||||
dataPointWidth = 16 / dataPointLengthCount;
|
||||
|
||||
if(newLengthCount == LodChunk.WIDTH)
|
||||
{
|
||||
@@ -59,11 +59,11 @@ public enum LodDetail
|
||||
newLengthCount = LodChunk.WIDTH - 1;
|
||||
}
|
||||
|
||||
startX = new int[lengthCount * lengthCount];
|
||||
endX = new int[lengthCount * lengthCount];
|
||||
startX = new int[dataPointLengthCount * dataPointLengthCount];
|
||||
endX = new int[dataPointLengthCount * dataPointLengthCount];
|
||||
|
||||
startZ = new int[lengthCount * lengthCount];
|
||||
endZ = new int[lengthCount * lengthCount];
|
||||
startZ = new int[dataPointLengthCount * dataPointLengthCount];
|
||||
endZ = new int[dataPointLengthCount * dataPointLengthCount];
|
||||
|
||||
|
||||
int index = 0;
|
||||
@@ -71,19 +71,19 @@ public enum LodDetail
|
||||
{
|
||||
for(int z = 0; z < newLengthCount; z++)
|
||||
{
|
||||
startX[index] = x * width;
|
||||
startZ[index] = z * width;
|
||||
startX[index] = x * dataPointWidth;
|
||||
startZ[index] = z * dataPointWidth;
|
||||
|
||||
// special case for FULL
|
||||
if(width != 1)
|
||||
if(dataPointWidth != 1)
|
||||
{
|
||||
endX[index] = (x*width) + width - 1;
|
||||
endZ[index] = (z*width) + width - 1;
|
||||
endX[index] = (x*dataPointWidth) + dataPointWidth - 1;
|
||||
endZ[index] = (z*dataPointWidth) + dataPointWidth - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
endX[index] = (x*width) + width;
|
||||
endZ[index] = (z*width) + width;
|
||||
endX[index] = (x*dataPointWidth) + dataPointWidth;
|
||||
endZ[index] = (z*dataPointWidth) + dataPointWidth;
|
||||
}
|
||||
|
||||
index++;
|
||||
@@ -91,7 +91,7 @@ public enum LodDetail
|
||||
}
|
||||
|
||||
|
||||
lodChunkStringDelimiterCount = 2 + (lengthCount * lengthCount * LodDataPoint.NUMBER_OF_DELIMITERS);
|
||||
lodChunkStringDelimiterCount = 2 + (dataPointLengthCount * dataPointLengthCount * LodDataPoint.NUMBER_OF_DELIMITERS);
|
||||
|
||||
}// constructor
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class LodChunk
|
||||
|
||||
detail = LodDetail.SINGLE;
|
||||
|
||||
dataPoints = new LodDataPoint[detail.lengthCount][detail.lengthCount];
|
||||
dataPoints = new LodDataPoint[detail.dataPointLengthCount][detail.dataPointLengthCount];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,7 +127,7 @@ public class LodChunk
|
||||
throw new IllegalArgumentException("LodChunk constructor givin an invalid string. The data given had " + count + " delimiters when it should have had " + detail.lodChunkStringDelimiterCount + ".");
|
||||
|
||||
|
||||
dataPoints = new LodDataPoint[detail.lengthCount][detail.lengthCount];
|
||||
dataPoints = new LodDataPoint[detail.dataPointLengthCount][detail.dataPointLengthCount];
|
||||
|
||||
// index we will use when going through the String
|
||||
int index = 0;
|
||||
@@ -145,9 +145,9 @@ public class LodChunk
|
||||
|
||||
|
||||
// LodDataPoints
|
||||
for(int blockX = 0; blockX < detail.lengthCount; blockX++)
|
||||
for(int blockX = 0; blockX < detail.dataPointLengthCount; blockX++)
|
||||
{
|
||||
for(int blockZ = 0; blockZ < detail.lengthCount; blockZ++)
|
||||
for(int blockZ = 0; blockZ < detail.dataPointLengthCount; blockZ++)
|
||||
{
|
||||
// height
|
||||
lastIndex = index;
|
||||
@@ -281,7 +281,7 @@ public class LodChunk
|
||||
*/
|
||||
public LodDataPoint getDataPointForBlockPos(int blockX, int blockZ)
|
||||
{
|
||||
return dataPoints[blockX / detail.width][blockZ / detail.width];
|
||||
return dataPoints[blockX / detail.dataPointWidth][blockZ / detail.dataPointWidth];
|
||||
}
|
||||
|
||||
public Color getColorForBlockPos(int blockX, int blockZ)
|
||||
@@ -315,6 +315,22 @@ public class LodChunk
|
||||
return dataPoints[xIndex][zIndex].depth;
|
||||
}
|
||||
|
||||
public short calculateHighestPoint()
|
||||
{
|
||||
short highest = 0;
|
||||
|
||||
for(int x = 0; x < detail.dataPointLengthCount; x++)
|
||||
{
|
||||
for(int z = 0; z < detail.dataPointLengthCount; z++)
|
||||
{
|
||||
if (getHeight(x,z) > highest)
|
||||
highest = getHeight(x,z);
|
||||
}
|
||||
}
|
||||
|
||||
return highest;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -461,4 +477,5 @@ public class LodChunk
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -188,14 +188,15 @@ public class LodRenderer
|
||||
int totalLength = (int) farPlaneDistance * LodConfig.CLIENT.lodChunkRadiusMultiplier.get() * 2;
|
||||
int numbChunksWide = (totalLength / LodChunk.WIDTH);
|
||||
|
||||
// determine which LODs should not be rendered close to the player
|
||||
HashSet<ChunkPos> chunkPosToSkip = getNearbyLodChunkPosToSkip(lodDim, player.getPosition());
|
||||
|
||||
// see if the chunks Minecraft is going to render are the
|
||||
// same as last time
|
||||
// (This is done so we only render LODs )
|
||||
HashSet<ChunkPos> newRenderedChunks = getRenderedChunks();
|
||||
if (!vanillaRenderedChunks.containsAll(newRenderedChunks))
|
||||
if (!vanillaRenderedChunks.containsAll(chunkPosToSkip))
|
||||
{
|
||||
regen = true;
|
||||
vanillaRenderedChunks = newRenderedChunks;
|
||||
vanillaRenderedChunks = chunkPosToSkip;
|
||||
}
|
||||
|
||||
|
||||
@@ -679,6 +680,48 @@ public class LodRenderer
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a HashSet of all ChunkPos within the normal render distance
|
||||
* that should not be rendered.
|
||||
*/
|
||||
private HashSet<ChunkPos> getNearbyLodChunkPosToSkip(LodDimension lodDim, BlockPos playerPos)
|
||||
{
|
||||
int chunkRenderDist = mc.gameSettings.renderDistanceChunks;
|
||||
int blockRenderDist = chunkRenderDist * 16;
|
||||
ChunkPos centerChunk = new ChunkPos(playerPos);
|
||||
|
||||
// skip chunks that are already going to be rendered by Minecraft
|
||||
HashSet<ChunkPos> posToSkip = getRenderedChunks();
|
||||
|
||||
|
||||
// go through each chunk within the normal view distance
|
||||
for(int x = centerChunk.x - chunkRenderDist; x < centerChunk.x + chunkRenderDist; x++)
|
||||
{
|
||||
for(int z = centerChunk.z - chunkRenderDist; z < centerChunk.z + chunkRenderDist; z++)
|
||||
{
|
||||
LodChunk lod = lodDim.getLodFromCoordinates(x, z);
|
||||
if (lod != null)
|
||||
{
|
||||
short lodHighestPoint = lod.calculateHighestPoint();
|
||||
|
||||
if (playerPos.getY() < lodHighestPoint)
|
||||
{
|
||||
// don't draw Lod's that are taller than the player
|
||||
// to prevent LODs being drawn on top of the player
|
||||
posToSkip.add(new ChunkPos(x, z));
|
||||
}
|
||||
else if (blockRenderDist < Math.abs(playerPos.getY() - lodHighestPoint))
|
||||
{
|
||||
// draw Lod's that are lower than the player's view range
|
||||
posToSkip.remove(new ChunkPos(x, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return posToSkip;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the ChunkPos of all chunks that Minecraft
|
||||
* is going to render this frame. <br><br>
|
||||
|
||||
Reference in New Issue
Block a user