Refactor and comment LodRegion

This commit is contained in:
James Seibel
2021-09-27 21:43:16 -05:00
parent 948b58d8e9
commit 69a72312e4
4 changed files with 216 additions and 158 deletions
@@ -188,10 +188,10 @@ public class LodDimensionFileHandler
{
default:
case HEIGHTMAP:
region.addLevel(new SingleLevelContainer(data));
region.addLevelContainer(new SingleLevelContainer(data));
break;
case VOXEL:
region.addLevel(new VerticalLevelContainer(data));
region.addLevelContainer(new VerticalLevelContainer(data));
break;
}
}
@@ -212,7 +212,7 @@ public class LodDimensionFileHandler
}// for each detail level
if (region.getMinDetailLevel() >= detailLevel)
region.expand(detailLevel);
region.growTree(detailLevel);
return region;
}
@@ -43,8 +43,12 @@ import net.minecraft.world.server.ServerWorld;
/**
* This object holds all loaded LOD regions
* for a given dimension.
*
* for a given dimension. <Br><Br>
*
* <strong>Coordinate Standard: </strong><br>
* Coordinate called posX or posZ are relative LevelPos coordinates <br>
* unless stated otherwise. <br>
*
* @author Leonardo Amato
* @author James Seibel
* @version 9-27-2021
@@ -442,7 +446,7 @@ public class LodDimension
// Second case, the region exists at a higher detail level.
// Expand the region by introducing the missing layer
region.expand(levelToGen);
region.growTree(levelToGen);
recreateRegionBuffer[x][z] = true;
}
}
@@ -506,7 +510,7 @@ public class LodDimension
/**
* Returns every position that need to be generated based on the position of the player
*/
public PosToGenerateContainer getDataToGenerate(int maxDataToGenerate, int playerPosX, int playerPosZ)
public PosToGenerateContainer getDataToGenerate(int maxDataToGenerate, int playerBlockPosX, int playerBlockPosZ)
{
PosToGenerateContainer posToGenerate;
LodRegion region;
@@ -522,10 +526,10 @@ public class LodDimension
{
default:
case NEAR_FIRST:
posToGenerate = new PosToGenerateContainer((byte) 10, maxDataToGenerate, 0, playerPosX, playerPosZ);
posToGenerate = new PosToGenerateContainer((byte) 10, maxDataToGenerate, 0, playerBlockPosX, playerBlockPosZ);
int playerChunkX = LevelPosUtil.getChunkPos(LodUtil.BLOCK_DETAIL_LEVEL, playerPosX);
int playerChunkZ = LevelPosUtil.getChunkPos(LodUtil.BLOCK_DETAIL_LEVEL, playerPosZ);
int playerChunkX = LevelPosUtil.getChunkPos(LodUtil.BLOCK_DETAIL_LEVEL, playerBlockPosX);
int playerChunkZ = LevelPosUtil.getChunkPos(LodUtil.BLOCK_DETAIL_LEVEL, playerBlockPosZ);
int xChunkToCheck;
int zChunkToCheck;
@@ -583,7 +587,7 @@ public class LodDimension
case FAR_FIRST:
posToGenerate = new PosToGenerateContainer((byte) 8, maxDataToGenerate, (int) (maxDataToGenerate * 0.25), playerPosX, playerPosZ);
posToGenerate = new PosToGenerateContainer((byte) 8, maxDataToGenerate, (int) (maxDataToGenerate * 0.25), playerBlockPosX, playerBlockPosZ);
int xRegion;
int zRegion;
@@ -595,7 +599,7 @@ public class LodDimension
region = getRegion(xRegion, zRegion);
if (region != null)
region.getDataToGenerate(posToGenerate, playerPosX, playerPosZ);
region.getDataToGenerate(posToGenerate, playerBlockPosX, playerBlockPosZ);
if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z)))
@@ -11,17 +11,21 @@ import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodUtil;
/**
* STANDARD TO FOLLOW
* every coordinate called posX or posZ is a relative coordinate and not and absolute coordinate
* 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
* This object holds all loaded LevelContainers
* for a given region. <Br><Br>
*
* <strong>Coordinate Standard: </strong><br>
* Coordinate called posX or posZ are relative LevelPos coordinates <br>
* unless stated otherwise. <br>
*
*
* @author Leonardo Amato
* @version 9-27-2021
*/
public class LodRegion
{
/** Holds the lowest (least detailed) detail level in this region
* TODO is that correct? */
private byte minDetailLevel;
private static final byte POSSIBLE_LOD = 10;
@@ -34,6 +38,9 @@ public class LodRegion
public final int regionPosX;
public final int regionPosZ;
public LodRegion(RegionPos regionPos)
{
this.minDetailLevel = LodUtil.REGION_DETAIL_LEVEL;
@@ -68,6 +75,8 @@ public class LodRegion
}
}
public VerticalQuality getLodQualityMode()
{
return verticalQuality;
@@ -84,16 +93,18 @@ public class LodRegion
}
/**
* This method can be used to insert data into the LodRegion
*
* @return if the data was added successfully
* Inserts the data point into the region.
*
* TODO this will always return true unless it has
* @return true if the data was added successfully
*/
public boolean addData(byte detailLevel, int posX, int posZ, int verticalIndex, long data)
{
posX = LevelPosUtil.getRegionModule(detailLevel, posX);
posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
// For some reason the dataContainer can contain null entries
// The dataContainer could have null entries if the
// detailLevel changes.
if (this.dataContainer[detailLevel] == null)
{
if (verticalQuality == VerticalQuality.HEIGHTMAP)
@@ -108,9 +119,10 @@ public class LodRegion
}
/**
* This method will return the data in the position relative to the level of detail
* Get the dataPoint at the given relative position.
*
* @return the data at the relative pos and level
* @return the data at the relative pos and detail level,
* 0 if the data doesn't exist.
*/
public long getData(byte detailLevel, int posX, int posZ, int verticalIndex)
{
@@ -118,99 +130,110 @@ public class LodRegion
}
/**
* This method will return the data in the position relative to the level of detail
* Get the dataPoint at the given relative position.
*
* @return the data at the relative pos and level
* @return the data at the relative pos and detail level,
* 0 if the data doesn't exist.
*/
public long getSingleData(byte detailLevel, int posX, int posZ)
{
return dataContainer[detailLevel].getSingleData(posX, posZ);
}
/** Clears the datapoint at the given relative position */
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
*
* @return
* This method will fill the posToGenerate array with all levelPos that
* are render-able.
*
* TODO why don't we return the posToGenerate, it would make this easier to understand
*/
public void getDataToGenerate(PosToGenerateContainer posToGenerate, int playerPosX, int playerPosZ)
public void getDataToGenerate(PosToGenerateContainer posToGenerate,
int playerBlockPosX, int playerBlockPosZ)
{
getDataToGenerate(posToGenerate, LodUtil.REGION_DETAIL_LEVEL, 0, 0, playerPosX, playerPosZ);
getDataToGenerate(posToGenerate, LodUtil.REGION_DETAIL_LEVEL, 0, 0, playerBlockPosX, playerBlockPosZ);
}
private void getDataToGenerate(PosToGenerateContainer posToGenerate, byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ)
/**
* A recursive method that fills the posToGenerate array with all levelPos that
* need to be generated.
*
* TODO why don't we return the posToGenerate, it would make this easier to understand
*/
private void getDataToGenerate(PosToGenerateContainer posToGenerate, byte detailLevel,
int childOffsetPosX, int childOffsetPosZ, int playerPosX, int playerPosZ)
{
// equivalent to 2^(...)
int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel);
//here i calculate the the LevelPos is in range
//This is important to avoid any kind of hole in the generation
//nt minDistance = LevelPosUtil.minDistance(detailLevel, posX + regionPosX * size, posZ + regionPosZ * size, playerPosX, playerPosZ);
int maxDistance = LevelPosUtil.maxDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ);
// calculate what LevelPos are in range to generate
int maxDistance = LevelPosUtil.maxDistance(detailLevel, childOffsetPosX, childOffsetPosZ, playerPosX, playerPosZ, regionPosX, regionPosZ);
// determine this child's levelPos
byte childDetailLevel = (byte) (detailLevel - 1);
int childPosX = posX * 2;
int childPosZ = posZ * 2;
int childPosX = childOffsetPosX * 2;
int childPosZ = childOffsetPosZ * 2;
int childSize = 1 << (LodUtil.REGION_DETAIL_LEVEL - childDetailLevel);
//we have reached the target detail level
byte targetDetailLevel = DetailDistanceUtil.getLodGenDetail(DetailDistanceUtil.getGenerationDetailFromDistance(maxDistance)).detailLevel;
if (targetDetailLevel > detailLevel)
{
// we have gone beyond the target Detail level
// we can stop generating
return;
} else if (targetDetailLevel == detailLevel)
}
else if (targetDetailLevel == detailLevel)
{
if (!doesDataExist(detailLevel, posX, posZ))
{
posToGenerate.addPosToGenerate(detailLevel, posX + regionPosX * size, posZ + regionPosZ * size);
}
} else
if (!doesDataExist(detailLevel, childOffsetPosX, childOffsetPosZ))
posToGenerate.addPosToGenerate(detailLevel, childOffsetPosX + regionPosX * size, childOffsetPosZ + regionPosZ * size);
}
else
{
//we want max a request per chunk. So for lod smaller than chunk we explore only the top rigth child
// we want at max one request per chunk (since the world generator creates chunks).
// So for lod smaller than a chunk, only recurse down
// the top right child
if (detailLevel > LodUtil.CHUNK_DETAIL_LEVEL)
{
int num = 0;
//We take all the children that are not generated to at least the generation level taken in input
int ungeneratedChildren = 0;
// make sure all children are generated to this detailLevel
for (int x = 0; x <= 1; x++)
{
for (int z = 0; z <= 1; z++)
{
if (!doesDataExist(childDetailLevel, childPosX + x, childPosZ + z))
{
num++;
ungeneratedChildren++;
posToGenerate.addPosToGenerate(childDetailLevel, childPosX + x + regionPosX * childSize, childPosZ + z + regionPosZ * childSize);
}
}
}
//only if all the children are correctly generated we go deeper
if (num == 0)
{
// only if all the children are correctly generated
// should we go deeper
if (ungeneratedChildren == 0)
for (int x = 0; x <= 1; x++)
{
for (int z = 0; z <= 1; z++)
{
getDataToGenerate(posToGenerate, childDetailLevel, childPosX + x, childPosZ + z, playerPosX, playerPosZ);
}
}
}
} else
//now we keep exploring the top right child
}
else
{
// The detail Level is smaller than a chunk.
// Only recurse down the top right child.
if (DetailDistanceUtil.getLodGenDetail(childDetailLevel).detailLevel <= (childDetailLevel))
{
if (!doesDataExist(childDetailLevel, childPosX, childPosZ))
{
posToGenerate.addPosToGenerate(childDetailLevel, childPosX + regionPosX * childSize, childPosZ + regionPosZ * childSize);
} else
{
else
getDataToGenerate(posToGenerate, childDetailLevel, childPosX, childPosZ, playerPosX, playerPosZ);
}
}
}
}
@@ -218,78 +241,99 @@ public class LodRegion
/**
* @return
* This method will fill the posToRender array with all levelPos that
* are render-able.
*
* TODO why don't we return the posToRender, it would make this easier to understand
*/
public void getDataToRender(PosToRenderContainer posToRender, int playerPosX, int playerPosZ, boolean requireCorrectDetailLevel)
public void getDataToRender(PosToRenderContainer posToRender,
int playerPosX, int playerPosZ, boolean requireCorrectDetailLevel)
{
getDataToRender(posToRender, LodUtil.REGION_DETAIL_LEVEL, 0, 0, playerPosX, playerPosZ, requireCorrectDetailLevel);
}
/**
* @return
* This method will fill the posToRender array with all levelPos that
* are render-able.
*
* TODO why don't we return the posToRender, it would make this easier to understand
* TODO this needs some more comments, James was only able to figure out part of it
*/
private void getDataToRender(PosToRenderContainer posToRender, byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ, boolean requireCorrectDetailLevel)
private void getDataToRender(PosToRenderContainer posToRender,
byte detailLevel, int posX, int posZ,
int playerPosX, int playerPosZ, boolean requireCorrectDetailLevel)
{
// equivalent to 2^(...)
int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel);
//here i calculate the the LevelPos is in range
//This is important to avoid any kind of hole in the rendering
byte supposedLevel;
byte desiredLevel;
int maxDistance;
boolean stopNow = false;
int minDistance;
int childLevel;
// calculate the LevelPos that are in range
switch (LodConfig.CLIENT.graphics.detailDropOff.get())
{
default:
case BY_CHUNK:
maxDistance = LevelPosUtil.maxDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ);
supposedLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(maxDistance));
desiredLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(maxDistance));
minDistance = LevelPosUtil.minDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ);
childLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(minDistance));
stopNow = detailLevel == childLevel - 1;
break;
break;
case BY_REGION_FANCY:
supposedLevel = minDetailLevel;
desiredLevel = minDetailLevel;
break;
case BY_REGION_FAST:
int playerRegionX = LevelPosUtil.getRegion(LodUtil.BLOCK_DETAIL_LEVEL, playerPosX);
int playerRegionZ = LevelPosUtil.getRegion(LodUtil.BLOCK_DETAIL_LEVEL, playerPosZ);
if (playerRegionX == regionPosX && playerRegionZ == regionPosZ)
{
maxDistance = LevelPosUtil.maxDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ);
supposedLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(maxDistance));
desiredLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(maxDistance));
minDistance = LevelPosUtil.minDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ);
childLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(minDistance));
stopNow = detailLevel == childLevel - 1;
} else
}
else
{
maxDistance = LevelPosUtil.maxDistance(LodUtil.REGION_DETAIL_LEVEL, regionPosX, regionPosZ, playerRegionX * 512 + 256, playerRegionZ * 512 + 256);
supposedLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(maxDistance));
desiredLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(maxDistance));
}
break;
}
if (stopNow)
{
posToRender.addPosToRender(detailLevel,
posX + regionPosX * size,
posZ + regionPosZ * size);
} else if (supposedLevel > detailLevel)
}
else if (desiredLevel > detailLevel)
{
// we have gone beyond the target Detail level
// we can stop generating
return;
} else if (supposedLevel == detailLevel)
}
else if (desiredLevel == detailLevel)
{
posToRender.addPosToRender(detailLevel,
posX + regionPosX * size,
posZ + regionPosZ * size);
} else //case where (detailLevel > supposedLevel)
}
else //case where (detailLevel > desiredLevel)
{
int childPosX = posX * 2;
int childPosZ = posZ * 2;
byte childDetailLevel = (byte) (detailLevel - 1);
int childrenCount = 0;
for (int x = 0; x <= 1; x++)
{
for (int z = 0; z <= 1; z++)
@@ -297,30 +341,24 @@ public class LodRegion
if (doesDataExist(childDetailLevel, childPosX + x, childPosZ + z))
{
if (!requireCorrectDetailLevel)
{
childrenCount++;
} else
{
else
getDataToRender(posToRender, childDetailLevel, childPosX + x, childPosZ + z, playerPosX, playerPosZ, requireCorrectDetailLevel);
}
}
}
}
//If all the four children exist we go deeper
if (!requireCorrectDetailLevel)
{
// If all the four children exist go deeper
if (childrenCount == 4)
{
for (int x = 0; x <= 1; x++)
{
for (int z = 0; z <= 1; z++)
{
getDataToRender(posToRender, childDetailLevel, childPosX + x, childPosZ + z, playerPosX, playerPosZ, requireCorrectDetailLevel);
}
}
} else
}
else
{
posToRender.addPosToRender(detailLevel,
posX + regionPosX * size,
@@ -330,27 +368,31 @@ public class LodRegion
}
}
/**
*
* Updates all children.
*
* TODO could this be renamed mergeArea?
*/
public void updateArea(byte detailLevel, int posX, int posZ)
{
int width;
int startX;
int startZ;
for (byte bottom = (byte) (minDetailLevel + 1); bottom <= detailLevel; bottom++)
// TODO what are each of these loops updating?
for (byte down = (byte) (minDetailLevel + 1); down <= detailLevel; down++)
{
startX = LevelPosUtil.convert(detailLevel, posX, bottom);
startZ = LevelPosUtil.convert(detailLevel, posZ, bottom);
width = 1 << (detailLevel - bottom);
startX = LevelPosUtil.convert(detailLevel, posX, down);
startZ = LevelPosUtil.convert(detailLevel, posZ, down);
width = 1 << (detailLevel - down);
for (int x = 0; x < width; x++)
{
for (int z = 0; z < width; z++)
{
update(bottom, startX + x, startZ + z);
}
}
update(down, startX + x, startZ + z);
}
for (byte up = (byte) (detailLevel + 1); up <= LodUtil.REGION_DETAIL_LEVEL; up++)
{
update(up,
@@ -360,7 +402,9 @@ public class LodRegion
}
/**
*
* Update the child at the given relative Pos
*
* TODO could this be renamed mergeChildData?
*/
private void update(byte detailLevel, int posX, int posZ)
{
@@ -369,126 +413,143 @@ public class LodRegion
/**
* @return
* Returns if data exists at the given relative Pos.
*/
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)
return false;
return dataContainer[detailLevel].doesItExist(posX, posZ);
}
/**
* @return
* Gets the generation mode for the data point at the given relative pos.
*/
public byte getGenerationMode(byte detailLevel, int posX, int posZ)
{
if (dataContainer[detailLevel].doesItExist(posX, posZ))
{
//We take the bottom information always
// We take the bottom information always
// TODO what does that mean? bottom of what?
return DataPointUtil.getGenerationMode(dataContainer[detailLevel].getSingleData(posX, posZ));
} else
{
else
return DistanceGenerationMode.NONE.complexity;
}
}
/** Returns the lowest detail level in this region
* TODO is that right? */
public byte getMinDetailLevel()
{
return minDetailLevel;
}
/**
* This will be used to save a level
*
* @param detailLevel
* @return
* Returns the LevelContainer for the detailLevel
*
* @throws IllegalArgumentException if the detailLevel is less than minDetailLevel
*/
public LevelContainer getLevel(byte detailLevel)
{
if (detailLevel < minDetailLevel)
{
throw new IllegalArgumentException("getLevel asked for a level that does not exist: minimum " + minDetailLevel + " level requested " + detailLevel);
}
throw new IllegalArgumentException("getLevel asked for a detail level that does not exist: minimum: [" + minDetailLevel + "] level requested: [" + detailLevel + "]");
return dataContainer[detailLevel];
}
/**
* @param levelContainer
* Add the levelContainer to this Region, updating the minDetailLevel
* if necessary.
*
* @throws IllegalArgumentException if the LevelContainer's detailLevel
* is 2 or more detail levels lower than the
* minDetailLevel of this region.
*/
public void addLevel(LevelContainer levelContainer)
public void addLevelContainer(LevelContainer levelContainer)
{
if (levelContainer.getDetailLevel() < minDetailLevel - 1)
{
throw new IllegalArgumentException("addLevel requires a level that is at least the minimum level of the region -1 ");
throw new IllegalArgumentException(
"the LevelContainer's detailLevel was "
+ "[" + levelContainer.getDetailLevel() + "] but this region "
+ "only allows adding LevelContainers with a "
+ "detail level of [" + (minDetailLevel - 1) + "]");
}
if (levelContainer.getDetailLevel() == minDetailLevel - 1) minDetailLevel = levelContainer.getDetailLevel();
dataContainer[levelContainer.getDetailLevel()] = levelContainer;
if (levelContainer.getDetailLevel() == minDetailLevel - 1)
minDetailLevel = levelContainer.getDetailLevel();
dataContainer[levelContainer.getDetailLevel()] = levelContainer;
}
// TODO James thinks cutTree and growTree (which he renamed to match cutTree)
// should have more descriptive names, to make sure the "Tree" portion isn't
// confused with Minecraft trees (the plant).
/**
* @param detailLevel
* Removes any dataContainers that are higher than
* the given detailLevel
*/
public void cutTree(byte detailLevel)
{
if (minDetailLevel < detailLevel)
if (detailLevel > minDetailLevel)
{
for (byte tempLod = 0; tempLod < detailLevel; tempLod++)
{
dataContainer[tempLod] = null;
}
for (byte detailLevelIndex = 0; detailLevelIndex < detailLevel; detailLevelIndex++)
dataContainer[detailLevelIndex] = null;
minDetailLevel = detailLevel;
}
}
/**
* TODO what does this do?
* @param detailLevel
* Make this region more detailed to the detailLevel given.
* TODO is that correct?
*/
public void expand(byte detailLevel)
public void growTree(byte detailLevel)
{
if (detailLevel < minDetailLevel)
{
for (byte tempLod = (byte) (minDetailLevel - 1); tempLod >= detailLevel; tempLod--)
for (byte detailLevelIndex = (byte) (minDetailLevel - 1); detailLevelIndex >= detailLevel; detailLevelIndex--)
{
if (dataContainer[tempLod + 1] == null)
{
dataContainer[tempLod + 1] = new SingleLevelContainer((byte) (tempLod + 1));
}
dataContainer[tempLod] = dataContainer[tempLod + 1].expand();
if (dataContainer[detailLevelIndex + 1] == null)
dataContainer[detailLevelIndex + 1] = new SingleLevelContainer((byte) (detailLevelIndex + 1));
dataContainer[detailLevelIndex] = dataContainer[detailLevelIndex + 1].expand();
}
minDetailLevel = detailLevel;
}
}
/**
* return RegionPos of this lod region
*/
/** return RegionPos of this lod region */
public RegionPos getRegionPos()
{
return new RegionPos(regionPosX, regionPosZ);
}
/**
* return needed memory in byte
*
* @param template
*/
/** Returns the minimum memory needed in bytes */
public int getMinMemoryNeeded(LodTemplate template)
{
int count = 0;
for (byte tempLod = LodUtil.REGION_DETAIL_LEVEL; tempLod > minDetailLevel; tempLod--)
int memory = 0;
for (byte detailLevelIndex = LodUtil.REGION_DETAIL_LEVEL; detailLevelIndex > minDetailLevel; detailLevelIndex--)
{
//i'm doing a upper limit of the minimum
//Color should be just 3 byte but i'm gonna calculate as 12 byte
//Height and depth should be just 4 byte but i'm gonna calculate as 8 byte
count += dataContainer[tempLod].getMaxMemoryUse() * template.getBufferMemoryForSingleLod(dataContainer[tempLod].getMaxVerticalData());
//count += Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - tempLod) * (24 + 8 + 8 + 8 + 8);
// TODO why are we multiplying the dataContainer's memory by the template's memory?
memory += dataContainer[detailLevelIndex].getMaxMemoryUse() * template.getBufferMemoryForSingleLod(dataContainer[detailLevelIndex].getMaxVerticalData());
}
return memory;
}
/** Returns how many LODs are in this region */
public int getNumberOfLods()
{
int count = 0;
for (LevelContainer container : dataContainer)
count += container.getMaxNumberOfLods();
return count;
}
@@ -497,12 +558,4 @@ public class LodRegion
{
return getLevel(LodUtil.REGION_DETAIL_LEVEL).toString();
}
public int getNumberOfLods()
{
int count = 0;
for (LevelContainer container : dataContainer)
count += container.getMaxNumberOfLods();
return count;
}
}
@@ -111,6 +111,7 @@ public class SingleLevelContainer implements LevelContainer
}
}
/** TODO could this be renamed mergeData? */
@Override
public void updateData(LevelContainer lowerLevelContainer, int posX, int posZ)
{