Improve how distance based quality is determined

This commit is contained in:
James Seibel
2021-08-11 21:52:16 -05:00
parent d1417069d9
commit c3709f726c
3 changed files with 80 additions and 34 deletions
@@ -150,6 +150,9 @@ public class LodNodeBufferBuilder
int minChunkDist = Integer.MAX_VALUE;
ChunkPos playerChunkPos = new ChunkPos((int)playerX / LodUtil.CHUNK_WIDTH, (int)playerZ / LodUtil.CHUNK_WIDTH);
// numbChunksWide / 2 = radius
// * 16 = to block coordinates
int maxDistance = (numbChunksWide / 2) * 16;
// generate our new buildable buffers
buildableNearBuffer.begin(GL11.GL_QUADS, LodNodeRenderer.LOD_VERTEX_FORMAT);
@@ -165,7 +168,8 @@ public class LodNodeBufferBuilder
// skip any chunks that Minecraft is going to render
if (isCoordInCenterArea(i, j, (numbChunksWide / 2))
&& renderer.vanillaRenderedChunks.contains(new ChunkPos(chunkX, chunkZ))) {
&& renderer.vanillaRenderedChunks.contains(new ChunkPos(chunkX, chunkZ)))
{
continue;
}
@@ -272,30 +276,10 @@ public class LodNodeBufferBuilder
currentBuffer = buildableFarBuffer;
// what detail level should this LOD be drawn at?
int distance = (int) Math.sqrt(Math.pow((mc.player.getX() - lod.startBlockPos.getX()),2) + Math.pow((mc.player.getZ() - lod.startBlockPos.getZ()),2));
LodDetail detail;
// determine detail level should this LOD be drawn at
int distance = (int) Math.sqrt(Math.pow((mc.player.getX() - lod.center.getX()),2) + Math.pow((mc.player.getZ() - lod.center.getZ()),2));
LodDetail detail = LodDetail.getDetailForDistance(LodConfig.CLIENT.maxDrawDetail.get(), distance, maxDistance);
if(distance < (numbChunksWide / 2) * 16 * 0.2)
{
detail = LodDetail.FULL;
}
else if(distance < (numbChunksWide / 2) * 16 * 0.4)
{
detail = LodDetail.HALF;
}
else if(distance < (numbChunksWide / 2) * 16 * 0.6)
{
detail = LodDetail.QUAD;
}
else if(distance < (numbChunksWide / 2) * 16 * 0.8)
{
detail = LodDetail.DOUBLE;
}
else
{
detail = LodDetail.SINGLE;
}
// get the desired LodTemplate and
// add this LOD to the buffer
@@ -17,13 +17,17 @@
*/
package com.seibel.lod.enums;
import java.util.ArrayList;
import java.util.Collections;
import com.seibel.lod.objects.LodDataPoint;
import com.seibel.lod.util.LodUtil;
/**
* single, double, quad, half, full
*
* @author James Seibel
* @version 8-10-2021
* @version 8-11-2021
*/
public enum LodDetail
{
@@ -48,7 +52,8 @@ public enum LodDetail
public final int dataPointLengthCount;
/** How wide each LOD DataPoint is */
public final int dataPointWidth;
/** This is the same as detailLevel in LodQuadTreeNode */
/** This is the same as detailLevel in LodQuadTreeNode,
* lowest is 0 highest is 9 */
public final int detailLevel;
/* Start/End X/Z give the block positions
@@ -63,6 +68,15 @@ public enum LodDetail
* when creating a LodChunk with this detail level */
public final int lodChunkStringDelimiterCount;
/**
* 1st dimension: LodDetail.detailLevel <br>
* 2nd dimension: An array of all LodDetails that are less than or <br>
* equal to that detailLevel
*/
private static LodDetail[][] lowerDetailArrays;
private LodDetail(int newLengthCount, int newDetailLevel)
{
@@ -96,4 +110,57 @@ public enum LodDetail
lodChunkStringDelimiterCount = 2 + (dataPointLengthCount * dataPointLengthCount * LodDataPoint.NUMBER_OF_DELIMITERS);
}// constructor
/**
* Returns an array of all LodDetails that have a detail level
* that is less than or equal to the given LodDetail
*/
public static LodDetail[] getSelfAndLowerDetails(LodDetail detail)
{
if (lowerDetailArrays == null)
{
// run first time setup
lowerDetailArrays = new LodDetail[LodDetail.values().length][];
// go through each LodDetail
for(LodDetail currentDetail : LodDetail.values())
{
ArrayList<LodDetail> lowerDetails = new ArrayList<>();
// find the details lower than currentDetail
for(LodDetail compareDetail : LodDetail.values())
{
if (currentDetail.detailLevel <= compareDetail.detailLevel)
{
lowerDetails.add(compareDetail);
}
}
// have the highest detail item first in the list
Collections.sort(lowerDetails);
Collections.reverse(lowerDetails);
lowerDetailArrays[currentDetail.detailLevel] = lowerDetails.toArray(new LodDetail[lowerDetails.size()]);
}
}
return lowerDetailArrays[detail.detailLevel];
}
/** Returns what detail level should be used at a given distance and maxDistance. */
public static LodDetail getDetailForDistance(LodDetail maxDetailLevel, int distance, int maxDistance)
{
LodDetail[] lowerDetails = getSelfAndLowerDetails(maxDetailLevel);
int distaneBetweenDetails = maxDistance / lowerDetails.length;
int index = LodUtil.clamp(0, distance / distaneBetweenDetails, lowerDetails.length - 1);
return lowerDetails[index];
}
}
@@ -48,17 +48,12 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
* and is the starting point for most of this program.
*
* @author James_Seibel
* @version 8-8-2021
* @version 8-11-2021
*/
public class ClientProxy
{
public static final Logger LOGGER = LogManager.getLogger("LOD");
// private static LodWorld lodWorld = new LodWorld();
// private static LodChunkBuilder lodChunkBuilder = new LodChunkBuilder();
// private static LodBufferBuilder lodBufferBuilder = new LodBufferBuilder(lodChunkBuilder);
// private static LodRenderer renderer = new LodRenderer(lodBufferBuilder);
private static LodQuadTreeWorld lodWorld = new LodQuadTreeWorld();
private static LodNodeBuilder lodNodeBuilder = new LodNodeBuilder();
private static LodNodeBufferBuilder lodBufferBuilder = new LodNodeBufferBuilder(lodNodeBuilder);
@@ -157,8 +152,8 @@ public class ClientProxy
// LodConfig.CLIENT.drawLODs.set(true);
// LodConfig.CLIENT.debugMode.set(false);
LodConfig.CLIENT.maxDrawDetail.set(LodDetail.QUAD);
LodConfig.CLIENT.maxGenerationDetail.set(LodDetail.QUAD);
LodConfig.CLIENT.maxDrawDetail.set(LodDetail.FULL);
LodConfig.CLIENT.maxGenerationDetail.set(LodDetail.FULL);
LodConfig.CLIENT.lodChunkRadiusMultiplier.set(12);
LodConfig.CLIENT.fogDistance.set(FogDistance.FAR);