diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java index e3c5b0313..49e8ec6b1 100644 --- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java @@ -172,7 +172,7 @@ public class LodBufferBuilder long startTime = System.currentTimeMillis(); - ArrayList> nodeToRenderThreads = new ArrayList<>(lodDim.regions.length * lodDim.regions.length); + ArrayList> nodeToRenderThreads = new ArrayList<>(lodDim.getWidth() * lodDim.getWidth()); startBuffers(fullRegen, lodDim); @@ -185,25 +185,25 @@ public class LodBufferBuilder center = playerRegionPos; if (setsToRender == null) - setsToRender = new PosToRenderContainer[lodDim.regions.length][lodDim.regions.length]; + setsToRender = new PosToRenderContainer[lodDim.getWidth()][lodDim.getWidth()]; - if (setsToRender.length != lodDim.regions.length) - setsToRender = new PosToRenderContainer[lodDim.regions.length][lodDim.regions.length]; + if (setsToRender.length != lodDim.getWidth()) + setsToRender = new PosToRenderContainer[lodDim.getWidth()][lodDim.getWidth()]; if (boxCache == null) - boxCache = new Box[lodDim.regions.length][lodDim.regions.length]; + boxCache = new Box[lodDim.getWidth()][lodDim.getWidth()]; - if (boxCache.length != lodDim.regions.length) - boxCache = new Box[lodDim.regions.length][lodDim.regions.length]; + if (boxCache.length != lodDim.getWidth()) + boxCache = new Box[lodDim.getWidth()][lodDim.getWidth()]; // this will be the center of the VBOs once they have been built buildableCenterChunkPos = playerChunkPos; - for (int xRegion = 0; xRegion < lodDim.regions.length; xRegion++) + for (int xRegion = 0; xRegion < lodDim.getWidth(); xRegion++) { - for (int zRegion = 0; zRegion < lodDim.regions.length; zRegion++) + for (int zRegion = 0; zRegion < lodDim.getWidth(); zRegion++) { - if (lodDim.regen[xRegion][zRegion] || fullRegen) + if (lodDim.getRegenByArrayIndex(xRegion, zRegion) || fullRegen) { RegionPos regionPos = new RegionPos( xRegion + lodDim.getCenterX() - Math.floorDiv(lodDim.getWidth(), 2), @@ -483,7 +483,7 @@ public class LodBufferBuilder { for (int z = 0; z < buildableBuffers.length; z++) { - if (fullRegen || lodDim.regen[x][z]) + if (fullRegen || lodDim.getRegenByArrayIndex(x, z)) { buildableBuffers[x][z].begin(GL11.GL_QUADS, LodRenderer.LOD_VERTEX_FORMAT); } @@ -498,7 +498,7 @@ public class LodBufferBuilder { for (int x = 0; x < buildableBuffers.length; x++) for (int z = 0; z < buildableBuffers.length; z++) - if (buildableBuffers[x][z] != null && buildableBuffers[x][z].building() && (fullRegen || lodDim.regen[x][z])) + if (buildableBuffers[x][z] != null && buildableBuffers[x][z].building() && (fullRegen || lodDim.getRegenByArrayIndex(x, z))) buildableBuffers[x][z].end(); } @@ -520,11 +520,11 @@ public class LodBufferBuilder { for (int z = 0; z < buildableVbos.length; z++) { - if (fullRegen || lodDim.regen[x][z]) + if (fullRegen || lodDim.getRegenByArrayIndex(x, z)) { ByteBuffer builderBuffer = buildableBuffers[x][z].popNextBuffer().getSecond(); vboUpload(buildableVbos[x][z], builderBuffer); - lodDim.regen[x][z] = false; + lodDim.setRegenByArrayIndex(x, z, false); } } } diff --git a/src/main/java/com/seibel/lod/builders/LodBuilder.java b/src/main/java/com/seibel/lod/builders/LodBuilder.java index 0efbbc9a8..af62a853f 100644 --- a/src/main/java/com/seibel/lod/builders/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBuilder.java @@ -714,6 +714,7 @@ public class LodBuilder // block special cases + // TODO: this needs to be replaced by a config file of some sort if (blockState == Blocks.AIR.defaultBlockState() || blockState == Blocks.CAVE_AIR.defaultBlockState() || blockState == Blocks.BARRIER.defaultBlockState()) @@ -737,7 +738,7 @@ public class LodBuilder { colorInt = Blocks.NETHER_WART_BLOCK.defaultMaterialColor().col; } else if (blockState.getBlock().equals(Blocks.TWISTING_VINES) - || blockState.equals(Blocks.TWISTING_VINES_PLANT) + || blockState.equals(Blocks.TWISTING_VINES_PLANT.defaultBlockState()) || blockState == Blocks.WARPED_ROOTS.defaultBlockState() || blockState == Blocks.WARPED_FUNGUS.defaultBlockState() || blockState == Blocks.NETHER_SPROUTS.defaultBlockState()) diff --git a/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java b/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java index 95536420c..429627f07 100644 --- a/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java +++ b/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java @@ -17,7 +17,14 @@ */ package com.seibel.lod.handlers; -import java.io.*; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.concurrent.ExecutorService; @@ -25,7 +32,10 @@ import java.util.concurrent.Executors; import com.seibel.lod.enums.DistanceGenerationMode; import com.seibel.lod.enums.LodQualityMode; -import com.seibel.lod.objects.*; +import com.seibel.lod.objects.LodDimension; +import com.seibel.lod.objects.LodRegion; +import com.seibel.lod.objects.RegionPos; +import com.seibel.lod.objects.SingleLevelContainer; import com.seibel.lod.proxy.ClientProxy; import com.seibel.lod.util.LodThreadFactory; import com.seibel.lod.util.LodUtil; @@ -212,10 +222,10 @@ public class LodDimensionFileHandler { for (int j = 0; j < loadedDimension.getWidth(); j++) { - if (loadedDimension.isRegionDirty[i][j] && loadedDimension.regions[i][j] != null) + if (loadedDimension.getRegenByArrayIndex(i,j) && loadedDimension.getRegionByArrayIndex(i,j) != null) { - saveRegionToFile(loadedDimension.regions[i][j]); - loadedDimension.isRegionDirty[i][j] = false; + saveRegionToFile(loadedDimension.getRegionByArrayIndex(i,j)); + loadedDimension.setRegenByArrayIndex(i, j,false); } } } diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index 4229d16dd..c8d4353dc 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -26,7 +26,11 @@ import com.seibel.lod.config.LodConfig; import com.seibel.lod.enums.DistanceGenerationMode; import com.seibel.lod.enums.LodQualityMode; import com.seibel.lod.handlers.LodDimensionFileHandler; -import com.seibel.lod.util.*; +import com.seibel.lod.util.DataPointUtil; +import com.seibel.lod.util.DetailDistanceUtil; +import com.seibel.lod.util.LevelPosUtil; +import com.seibel.lod.util.LodThreadFactory; +import com.seibel.lod.util.LodUtil; import com.seibel.lod.wrappers.MinecraftWrapper; import net.minecraft.util.math.ChunkPos; @@ -41,13 +45,13 @@ import net.minecraft.world.server.ServerWorld; * * @author Leonardo Amato * @author James Seibel - * @version 8-8-2021 + * @version 9-18-2021 */ public class LodDimension { - + public final DimensionType dimension; - + /** * measured in regions */ @@ -56,23 +60,28 @@ public class LodDimension * measured in regions */ private volatile int halfWidth; - - - public volatile LodRegion regions[][]; - public volatile boolean isRegionDirty[][]; - public volatile boolean regen[][]; + + // these three variables are private to force use of the getWidth() method + // which is a safer way to get the width then directly asking the arrays + /** stores all the regions in this dimension */ + private volatile LodRegion regions[][]; + /** stores if the region at the given x and z index needs to be saved to disk */ + private volatile boolean isRegionDirty[][]; + /** stores if the region at the given x and z index needs to be regenerated */ + private volatile boolean regionNeedsRegen[][]; + /** * if true that means there are regions in this dimension * that need to have their buffers rebuilt. */ public volatile boolean regenDimension = false; - + private volatile RegionPos center; private volatile ChunkPos lastGenChunk; private volatile ChunkPos lastCutChunk; private LodDimensionFileHandler fileHandler; private ExecutorService cutAndGenThreads = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName() + " - cutAndGen")); - + /** * Creates the dimension centered at (0,0) * @@ -90,14 +99,14 @@ public class LodDimension { try { - + File saveDir; if (mc.hasSingleplayerServer()) { // local world - + ServerWorld serverWorld = LodUtil.getServerWorldFromDimension(newDimension); - + // provider needs a separate variable to prevent // the compiler from complaining ServerChunkProvider provider = serverWorld.getChunkSource(); @@ -105,11 +114,11 @@ public class LodDimension } else { // connected to server - + saveDir = new File(mc.getGameDirectory().getCanonicalFile().getPath() + - File.separatorChar + "lod server data" + File.separatorChar + mc.getCurrentDimensionId()); + File.separatorChar + "lod server data" + File.separatorChar + mc.getCurrentDimensionId()); } - + fileHandler = new LodDimensionFileHandler(saveDir, this); } catch (IOException e) { @@ -117,23 +126,23 @@ public class LodDimension // we won't be able to read or write any files } } - - + + regions = new LodRegion[width][width]; isRegionDirty = new boolean[width][width]; - regen = new boolean[width][width]; - + regionNeedsRegen = new boolean[width][width]; + //treeGenerator((int) mc.player.getX(),(int) mc.player.getZ()); - + // populate isRegionDirty for (int i = 0; i < width; i++) for (int j = 0; j < width; j++) isRegionDirty[i][j] = false; - + center = new RegionPos(0, 0); } - - + + /** * Move the center of this LodDimension and move all owned * regions over by the given x and z offset.

@@ -144,7 +153,7 @@ public class LodDimension { int xOffset = regionOffset.x; int zOffset = regionOffset.z; - + // if the x or z offset is equal to or greater than // the total size, just delete the current data // and update the centerX and/or centerZ @@ -157,15 +166,15 @@ public class LodDimension regions[x][z] = null; } } - + // update the new center center.x += xOffset; center.z += zOffset; - + return; } - - + + // X if (xOffset > 0) { @@ -196,8 +205,8 @@ public class LodDimension } } } - - + + // Z if (zOffset > 0) { @@ -226,22 +235,22 @@ public class LodDimension } } } - - + + // update the new center center.x += xOffset; center.z += zOffset; } - - + + /** - * return needed memory in byte + * return needed memory in bytes */ public int getMinMemoryNeeded() { int count = 0; LodRegion region; - + for (int x = 0; x < regions.length; x++) { for (int z = 0; z < regions.length; z++) @@ -255,8 +264,8 @@ public class LodDimension } return count; } - - + + /** * Gets the region at the given X and Z *
@@ -269,19 +278,19 @@ public class LodDimension int zRegion = LevelPosUtil.getRegion(detailLevel, posZ); int xIndex = (xRegion - center.x) + halfWidth; int zIndex = (zRegion - center.z) + halfWidth; - + if (!regionIsInRange(xRegion, zRegion)) return null; - //throw new ArrayIndexOutOfBoundsException("Region for level pos " + LevelPosUtil.toString(detailLevel, posX, posZ) + " out of range"); + //throw new ArrayIndexOutOfBoundsException("Region for level pos " + LevelPosUtil.toString(detailLevel, posX, posZ) + " out of range"); else if (regions[xIndex][zIndex] == null) return null; - //throw new InvalidParameterException("Region for level pos " + LevelPosUtil.toString(detailLevel, posX, posZ) + " not currently initialized"); + //throw new InvalidParameterException("Region for level pos " + LevelPosUtil.toString(detailLevel, posX, posZ) + " not currently initialized"); else if (regions[xIndex][zIndex].getMinDetailLevel() > detailLevel) return null; //throw new InvalidParameterException("Region for level pos " + LevelPosUtil.toString(detailLevel, posX, posZ) + " currently only reach level " + regions[xIndex][zIndex].getMinDetailLevel()); return regions[xIndex][zIndex]; } - + /** * Gets the region at the given X and Z *
@@ -292,16 +301,22 @@ public class LodDimension { int xIndex = (regionPosX - center.x) + halfWidth; int zIndex = (regionPosZ - center.z) + halfWidth; - + if (!regionIsInRange(regionPosX, regionPosZ)) return null; - //throw new ArrayIndexOutOfBoundsException("Region " + regionPosX + " " + regionPosZ + " out of range"); + //throw new ArrayIndexOutOfBoundsException("Region " + regionPosX + " " + regionPosZ + " out of range"); else if (regions[xIndex][zIndex] == null) return null; //throw new InvalidParameterException("Region " + regionPosX + " " + regionPosZ + " not currently initialized"); return regions[xIndex][zIndex]; } - + + /** Useful when needing to iterate over every region. */ + public LodRegion getRegionByArrayIndex(int xIndex, int zIndex) + { + return regions[xIndex][zIndex]; + } + /** * Overwrite the LodRegion at the location of newRegion with newRegion. * @@ -311,15 +326,15 @@ public class LodDimension { int xIndex = (newRegion.regionPosX - center.x) + halfWidth; int zIndex = (newRegion.regionPosZ - center.z) + halfWidth; - + if (!regionIsInRange(newRegion.regionPosX, newRegion.regionPosZ)) // out of range throw new ArrayIndexOutOfBoundsException("Region " + newRegion.regionPosX + ", " + newRegion.regionPosZ + " out of range"); - + regions[xIndex][zIndex] = newRegion; } - - + + /** * */ @@ -338,7 +353,7 @@ public class LodDimension int minDistance; byte detail; byte levelToCut; - + for (int x = 0; x < regions.length; x++) { for (int z = 0; z < regions.length; z++) @@ -358,15 +373,15 @@ public class LodDimension regions[x][z].cutTree(levelToCut); } } - + }// region z }// region z - + }); cutAndGenThreads.execute(thread); } } - + /** * */ @@ -375,7 +390,7 @@ public class LodDimension DistanceGenerationMode generationMode = LodConfig.CLIENT.worldGenerator.distanceGenerationMode.get(); ChunkPos newPlayerChunk = new ChunkPos(LevelPosUtil.getChunkPos((byte) 0, playerPosX), LevelPosUtil.getChunkPos((byte) 0, playerPosZ)); LodQualityMode lodQualityMode = LodConfig.CLIENT.worldGenerator.lodQualityMode.get(); - + if (lastGenChunk == null) lastGenChunk = new ChunkPos(newPlayerChunk.x + 1, newPlayerChunk.z - 1); if (newPlayerChunk.x != lastGenChunk.x || newPlayerChunk.z != lastGenChunk.z) @@ -398,25 +413,25 @@ public class LodDimension final RegionPos regionPos = new RegionPos(regionX, regionZ); region = regions[x][z]; //We require that the region we are checking is loaded with at least this level - + minDistance = LevelPosUtil.minDistance(LodUtil.REGION_DETAIL_LEVEL, regionX, regionZ, playerPosX, playerPosZ); detail = DetailDistanceUtil.getDistanceTreeGenInverse(minDistance); levelToGen = DetailDistanceUtil.getLodGenDetail(detail).detailLevel; if (region == null || region.getGenerationMode() != generationMode) { //First case, region has to be initialized - + //We check if there is a file at the target level regions[x][z] = getRegionFromFile(regionPos, levelToGen, generationMode, lodQualityMode); - + //if there is no file we initialize the region if (regions[x][z] == null) { regions[x][z] = new LodRegion(levelToGen, regionPos, generationMode, lodQualityMode); } - regen[x][z] = true; + regionNeedsRegen[x][z] = true; regenDimension = true; - + } else if (region.getMinDetailLevel() > levelToGen) { //Second case, region has been initialized but at a higher level @@ -429,7 +444,7 @@ public class LodDimension cutAndGenThreads.execute(thread); } } - + /** * Add the given LOD to this dimension at the coordinate * stored in the LOD. If an LOD already exists at the given @@ -437,11 +452,11 @@ public class LodDimension */ public Boolean addData(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; @@ -455,7 +470,7 @@ public class LodDimension int xIndex = (regionPosX - center.x) + halfWidth; int zIndex = (regionPosZ - center.z) + halfWidth; isRegionDirty[xIndex][zIndex] = true; - regen[xIndex][zIndex] = true; + regionNeedsRegen[xIndex][zIndex] = true; regenDimension = true; } catch (ArrayIndexOutOfBoundsException e) { @@ -466,8 +481,8 @@ public class LodDimension } return nodeAdded; } - - + + /** * Add the given LOD to this dimension at the coordinate * stored in the LOD. If an LOD already exists at the given @@ -475,11 +490,11 @@ public class LodDimension */ 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; @@ -493,7 +508,7 @@ public class LodDimension int xIndex = (regionPosX - center.x) + halfWidth; int zIndex = (regionPosZ - center.z) + halfWidth; isRegionDirty[xIndex][zIndex] = true; - regen[xIndex][zIndex] = true; + regionNeedsRegen[xIndex][zIndex] = true; regenDimension = true; } catch (ArrayIndexOutOfBoundsException e) { @@ -504,14 +519,14 @@ public class LodDimension } return nodeAdded; } - + public void setToRegen(int xRegion, int zRegion) { int xIndex = (xRegion - center.x) + halfWidth; int zIndex = (zRegion - center.z) + halfWidth; - regen[xIndex][zIndex] = true; + regionNeedsRegen[xIndex][zIndex] = true; } - + /** * method to get all the quadtree level that have to be generated based on the position of the player * @@ -533,12 +548,12 @@ public class LodDimension region = getRegion(xIndex, zIndex); if (region != null) region.getDataToGenerate(posToGenerate, playerPosX, playerPosZ); - + } } return posToGenerate; } - + /** * method to get all the nodes that have to be rendered based on the position of the player * @@ -550,7 +565,7 @@ public class LodDimension if (region != null) region.getDataToRender(posToRender, playerPosX, playerPosZ); } - + /** * Get the data point at the given X and Z coordinates * in this dimension. @@ -562,17 +577,17 @@ public class LodDimension { if (detailLevel > LodUtil.REGION_DETAIL_LEVEL) throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max."); - + LodRegion region = getRegion(detailLevel, posX, posZ); - + if (region == null) { return new long[]{DataPointUtil.EMPTY_DATA}; } - + return region.getData(detailLevel, posX, posZ); } - + /** * Get the data point at the given X and Z coordinates * in this dimension. @@ -584,17 +599,28 @@ public class LodDimension { if (detailLevel > LodUtil.REGION_DETAIL_LEVEL) throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max."); - + LodRegion region = getRegion(detailLevel, posX, posZ); - + if (region == null) { return DataPointUtil.EMPTY_DATA; } - + return region.getSingleData(detailLevel, posX, posZ); } - + + + public boolean getRegenByArrayIndex(int xIndex, int zIndex) + { + return regionNeedsRegen[xIndex][zIndex]; + } + + public void setRegenByArrayIndex(int xIndex, int zIndex, boolean newRegen) + { + regionNeedsRegen[xIndex][zIndex] = newRegen; + } + /** * Get the data point at the given X and Z coordinates * in this dimension. @@ -606,32 +632,32 @@ public class LodDimension { if (detailLevel > LodUtil.REGION_DETAIL_LEVEL) throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max."); - + LodRegion region = getRegion(detailLevel, posX, posZ); - - + + if (region == null) { return; } region.updateArea(detailLevel, posX, posZ); } - + /** * return true if and only if the node at that position exist */ public boolean doesDataExist(byte detailLevel, int posX, int posZ) { LodRegion region = getRegion(detailLevel, posX, posZ); - + if (region == null) { return false; } - + return region.doesDataExist(detailLevel, posX, posZ); } - + /** * Get the region at the given X and Z coordinates from the * RegionFileHandler. @@ -643,7 +669,7 @@ public class LodDimension else return null; } - + /** * Save all dirty regions in this LodDimension to file. */ @@ -651,8 +677,8 @@ public class LodDimension { fileHandler.saveDirtyRegionsToFileAsync(); } - - + + /** * Returns whether the region at the given X and Z coordinates * is within the loaded range. @@ -661,22 +687,22 @@ public class LodDimension { int xIndex = (regionX - center.x) + halfWidth; int zIndex = (regionZ - center.z) + halfWidth; - + return xIndex >= 0 && xIndex < width && zIndex >= 0 && zIndex < width; } - - + + public int getCenterX() { return center.x; } - + public int getCenterZ() { return center.z; } - - + + /** returns the width of the dimension in regions */ public int getWidth() { if (regions != null) @@ -690,28 +716,29 @@ public class LodDimension return width; } } - + + public void setRegionWidth(int newWidth) { width = newWidth; halfWidth = Math.floorDiv(width, 2); - + regions = new LodRegion[width][width]; isRegionDirty = new boolean[width][width]; - regen = new boolean[width][width]; - + regionNeedsRegen = new boolean[width][width]; + // populate isRegionDirty for (int i = 0; i < width; i++) for (int j = 0; j < width; j++) isRegionDirty[i][j] = false; } - - + + @Override public String toString() { LodRegion region; - + StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("Dimension : \n"); for (int x = 0; x < regions.length; x++) @@ -723,7 +750,7 @@ public class LodDimension { stringBuilder.append("n"); stringBuilder.append("\t"); - + } else { stringBuilder.append(region.getMinDetailLevel()); diff --git a/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java b/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java index 2ec972613..bff00e7a2 100644 --- a/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java +++ b/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java @@ -1,8 +1,14 @@ package com.seibel.lod.objects; +import com.seibel.lod.proxy.ClientProxy; import com.seibel.lod.util.LevelPosUtil; import com.seibel.lod.util.LodUtil; +/** + * + * @author Leonardo Amato + * @version 9-18-2021 + */ public class PosToRenderContainer { public byte minDetail; @@ -26,6 +32,18 @@ public class PosToRenderContainer public void addPosToRender(byte detailLevel, int posX, int posZ) { + // When rapidly changing dimensions the bufferBuidler can cause this, + // James isn't sure why, but this will prevent an exception at + // the very least (while stilling logging the problem). + if (numberOfPosToRender >= posToRender.length) + { + // This is might be due to dimensions having a different width + // when first loading in + ClientProxy.LOGGER.error("Unable to addPosToRender. numberOfPosToRender [" + numberOfPosToRender +"] detailLevel [" + detailLevel + "] Pos [" + posX + "," + posZ + "]"); + numberOfPosToRender++; // incrementing so we can see how many pos over the limit we would go + return; + } + //if(numberOfPosToRender >= posToRender.length) // posToRender = Arrays.copyOf(posToRender, posToRender.length*2); posToRender[numberOfPosToRender][0] = detailLevel;