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
@@ -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];
}
}