diff --git a/src/main/java/com/seibel/lod/Main.java b/src/main/java/com/seibel/lod/Main.java index 1619bf7fe..9201cf7d6 100644 --- a/src/main/java/com/seibel/lod/Main.java +++ b/src/main/java/com/seibel/lod/Main.java @@ -12,6 +12,7 @@ public class Main { public static void main(String[] args) { + /* try { @SuppressWarnings("serial") @@ -49,5 +50,6 @@ public class Main { e.printStackTrace(); } + */ } } diff --git a/src/main/java/com/seibel/lod/builders/LodBuilder.java b/src/main/java/com/seibel/lod/builders/LodBuilder.java index 9cc7cdfc4..f72053bb6 100644 --- a/src/main/java/com/seibel/lod/builders/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBuilder.java @@ -264,6 +264,7 @@ public class LodBuilder } catch (Exception e) { e.printStackTrace(); + throw e; } } diff --git a/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java b/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java index 7f8c991e2..59d7e9b6a 100644 --- a/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java +++ b/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java @@ -107,11 +107,8 @@ public class LodWorldGenerator ServerWorld serverWorld = LodUtil.getServerWorldFromDimension(lodDim.dimension); - byte farDetail = (byte) 8; PosToGenerateContainer posToGenerate = lodDim.getDataToGenerate( - farDetail, maxChunkGenRequests, - 0.25, playerPosX, playerPosZ); //System.out.println(posToGenerate); @@ -121,15 +118,13 @@ public class LodWorldGenerator byte detailLevel; int posX; int posZ; - int[] levelPos; for (int index = 0; index < posToGenerate.getNumberOfPos(); index++) { - levelPos = posToGenerate.getNthPos(index); - if(levelPos[0] == 0) + if(posToGenerate.getNthDetail(index) == 0) continue; - detailLevel = (byte) (levelPos[0] -1); - posX = levelPos[1]; - posZ = levelPos[2]; + detailLevel = (byte) (posToGenerate.getNthDetail(index) - 1); + posX = posToGenerate.getNthPosX(index); + posZ = posToGenerate.getNthPosZ(index); ChunkPos chunkPos = new ChunkPos(LevelPosUtil.getChunkPos(detailLevel,posX), LevelPosUtil.getChunkPos(detailLevel,posZ)); if (numberOfChunksWaitingToGenerate.get() < maxChunkGenRequests) diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index 5c72c3269..1e12068d3 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -502,23 +502,74 @@ public class LodDimension * * @return list of quadTrees */ - public PosToGenerateContainer getDataToGenerate(byte farDetail, int maxDataToGenerate, double farRatio, int playerPosX, int playerPosZ) + public PosToGenerateContainer getDataToGenerate(int maxDataToGenerate, int playerPosX, int playerPosZ) { - PosToGenerateContainer posToGenerate = new PosToGenerateContainer(farDetail, maxDataToGenerate, (int) (maxDataToGenerate * farRatio), playerPosX, playerPosZ); - int n = regions.length; - int xIndex; - int zIndex; - LodRegion region; - for (int xRegion = 0; xRegion < n; xRegion++) + PosToGenerateContainer posToGenerate; + boolean circularGeneration = true; + if (circularGeneration) { - for (int zRegion = 0; zRegion < n; zRegion++) - { - xIndex = (xRegion + center.x) - halfWidth; - zIndex = (zRegion + center.z) - halfWidth; - region = getRegion(xIndex, zIndex); - if (region != null) - region.getDataToGenerate(posToGenerate, playerPosX, playerPosZ); + posToGenerate = new PosToGenerateContainer((byte) 10, maxDataToGenerate, 0, playerPosX, playerPosZ); + int numbChunksWide = width * 32; + int playerChunkPosX = Math.floorDiv(playerPosX, LodUtil.CHUNK_WIDTH); + int playerChunkPosZ = Math.floorDiv(playerPosZ, LodUtil.CHUNK_WIDTH); + int xChunkToCheck; + int zChunkToCheck; + byte detailLevel; + int posX; + int posZ; + int distance; + int x,z,dx,dz; + long data; + x = z = dx =0; + dz = -1; + int width = numbChunksWide; + int t = width; + int maxI = t*t; + for(int i =0; i < maxI; i++){ + if(maxDataToGenerate < 0){ + break; + } + if ((-width/2 <= x) && (x <= width/2) && (-width/2 <= z) && (z <= width/2)){ + xChunkToCheck = x * LodUtil.CHUNK_WIDTH + playerChunkPosX; + zChunkToCheck = z * LodUtil.CHUNK_WIDTH + playerChunkPosZ; + distance = LevelPosUtil.maxDistance(LodUtil.CHUNK_DETAIL_LEVEL,x,z,0,0); + detailLevel = DetailDistanceUtil.getGenerationDetailFromDistance(distance); + posX = LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL,xChunkToCheck, detailLevel); + posZ = LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL,zChunkToCheck, detailLevel); + data = getSingleData(detailLevel,posX,posZ); + if(!DataPointUtil.doesItExist(data)) + { + posToGenerate.addPosToGenerate(detailLevel,posX,posZ); + maxDataToGenerate--; + } + } + if( (x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1-z))){ + t = dx; + dx = -dz; + dz = t; + } + x += dx; + z += dz; + } + } else + { + posToGenerate = new PosToGenerateContainer((byte) 8, maxDataToGenerate, (int) (maxDataToGenerate * 0.25f), playerPosX, playerPosZ); + int n = regions.length; + int xIndex; + int zIndex; + LodRegion region; + for (int xRegion = 0; xRegion < n; xRegion++) + { + for (int zRegion = 0; zRegion < n; zRegion++) + { + xIndex = (xRegion + center.x) - halfWidth; + zIndex = (zRegion + center.z) - halfWidth; + region = getRegion(xIndex, zIndex); + if (region != null) + region.getDataToGenerate(posToGenerate, playerPosX, playerPosZ); + + } } } return posToGenerate; diff --git a/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java b/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java index 2f05f75dc..608ceff1f 100644 --- a/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java +++ b/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java @@ -12,7 +12,7 @@ public class PosToGenerateContainer private int maxFarSize; private int nearSize; private int farSize; - private int[][] posToGenerate; + private int[] posToGenerate; public PosToGenerateContainer(byte farMinDetail, int maxDataToGenerate, int maxFarDataToGenerate, int playerPosX, int playerPosZ) { @@ -24,7 +24,7 @@ public class PosToGenerateContainer maxSize = maxDataToGenerate; nearSize = 0; farSize = 0; - posToGenerate = new int[maxDataToGenerate][4]; + posToGenerate = new int[maxDataToGenerate*4]; } public void addPosToGenerate(byte detailLevel, int posX, int posZ) @@ -43,20 +43,20 @@ public class PosToGenerateContainer maxNearSize--; } index = posToGenerate.length - farSize; - while (index < posToGenerate.length - 1 && LevelPosUtil.compareLevelAndDistance(detailLevel, distance, (byte) (posToGenerate[index + 1][0] - 1), posToGenerate[index + 1][3]) <= 0) + while (index < posToGenerate.length - 1 && LevelPosUtil.compareLevelAndDistance(detailLevel, distance, (byte) (posToGenerate[(index + 1)*4 + 0] - 1), posToGenerate[(index + 1)*4 + 3]) <= 0) { - posToGenerate[index][0] = posToGenerate[index + 1][0]; - posToGenerate[index][1] = posToGenerate[index + 1][1]; - posToGenerate[index][2] = posToGenerate[index + 1][2]; - posToGenerate[index][3] = posToGenerate[index + 1][3]; + posToGenerate[index*4 + 0] = posToGenerate[(index + 1)*4 + 0]; + posToGenerate[index*4 + 1] = posToGenerate[(index + 1)*4 + 1]; + posToGenerate[index*4 + 2] = posToGenerate[(index + 1)*4 + 2]; + posToGenerate[index*4 + 3] = posToGenerate[(index + 1)*4 + 3]; index++; } if (index <= posToGenerate.length - 1) { - posToGenerate[index][0] = detailLevel + 1; - posToGenerate[index][1] = posX; - posToGenerate[index][2] = posZ; - posToGenerate[index][3] = distance; + posToGenerate[index*4 + 0] = detailLevel + 1; + posToGenerate[index*4 + 1] = posX; + posToGenerate[index*4 + 2] = posZ; + posToGenerate[index*4 + 3] = distance; } } else {//We are introducing a position in the near array @@ -64,20 +64,20 @@ public class PosToGenerateContainer nearSize++; index = nearSize - 1; - while (index > 0 && LevelPosUtil.compareDistance(distance, posToGenerate[index - 1][3]) <= 0) + while (index > 0 && LevelPosUtil.compareDistance(distance, posToGenerate[(index - 1)*4 + 3]) <= 0) { - posToGenerate[index][0] = posToGenerate[index - 1][0]; - posToGenerate[index][1] = posToGenerate[index - 1][1]; - posToGenerate[index][2] = posToGenerate[index - 1][2]; - posToGenerate[index][3] = posToGenerate[index - 1][3]; + posToGenerate[index*4 + 0] = posToGenerate[(index - 1)*4 + 0]; + posToGenerate[index*4 + 1] = posToGenerate[(index - 1)*4 + 1]; + posToGenerate[index*4 + 2] = posToGenerate[(index - 1)*4 + 2]; + posToGenerate[index*4 + 3] = posToGenerate[(index - 1)*4 + 3]; index--; } if (index >= 0) { - posToGenerate[index][0] = detailLevel + 1; - posToGenerate[index][1] = posX; - posToGenerate[index][2] = posZ; - posToGenerate[index][3] = distance; + posToGenerate[index*4 + 0] = detailLevel + 1; + posToGenerate[index*4 + 1] = posX; + posToGenerate[index*4 + 2] = posZ; + posToGenerate[index*4 + 3] = distance; } } } @@ -88,12 +88,8 @@ public class PosToGenerateContainer return farSize + nearSize; } - public int[] getNthPos(int n) + public int getNthDetail(int n) { - /*if(n < farSize) - return posToGenerate[maxSize - n - 1]; - else - return posToGenerate[n - farSize];*/ int index; if (n > farSize * 2) index = n - farSize; @@ -101,7 +97,40 @@ public class PosToGenerateContainer index = n / 2; else index = posToGenerate.length - n / 2 - 1; - return posToGenerate[index]; + return posToGenerate[index*4 + 0]; + } + public int getNthPosX(int n) + { + int index; + if (n > farSize * 2) + index = n - farSize; + else if (n % 2 == 0) + index = n / 2; + else + index = posToGenerate.length - n / 2 - 1; + return posToGenerate[index*4 + 1]; + } + public int getNthPosZ(int n) + { + int index; + if (n > farSize * 2) + index = n - farSize; + else if (n % 2 == 0) + index = n / 2; + else + index = posToGenerate.length - n / 2 - 1; + return posToGenerate[index*4 + 2]; + } + public int getNthGeneration(int n) + { + int index; + if (n > farSize * 2) + index = n - farSize; + else if (n % 2 == 0) + index = n / 2; + else + index = posToGenerate.length - n / 2 - 1; + return posToGenerate[index*4 + 3]; } public String toString() @@ -121,13 +150,13 @@ public class PosToGenerateContainer builder.append('\n'); for (int i = 0; i < nearSize; i++) { - builder.append(posToGenerate[i][0]-1); + builder.append(posToGenerate[i*4 +0]-1); builder.append(" "); - builder.append(posToGenerate[i][1]); + builder.append(posToGenerate[i*4 +1]); builder.append(" "); - builder.append(posToGenerate[i][2]); + builder.append(posToGenerate[i*4 +2]); builder.append(" "); - builder.append(posToGenerate[i][3]); + builder.append(posToGenerate[i*4 +3]); builder.append('\n'); } builder.append('\n'); @@ -135,13 +164,13 @@ public class PosToGenerateContainer builder.append('\n'); for (int i = maxSize - 1; i >= maxSize - farSize; i--) { - builder.append(posToGenerate[i][0]-1); + builder.append(posToGenerate[i*4 +0]-1); builder.append(" "); - builder.append(posToGenerate[i][1]); + builder.append(posToGenerate[i*4 +1]); builder.append(" "); - builder.append(posToGenerate[i][2]); + builder.append(posToGenerate[i*4 +2]); builder.append(" "); - builder.append(posToGenerate[i][3]); + builder.append(posToGenerate[i*4 +3]); builder.append('\n'); } builder.append('\n'); diff --git a/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java b/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java index bff00e7a2..cd4912f6e 100644 --- a/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java +++ b/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java @@ -4,6 +4,8 @@ import com.seibel.lod.proxy.ClientProxy; import com.seibel.lod.util.LevelPosUtil; import com.seibel.lod.util.LodUtil; +import java.util.Arrays; + /** * * @author Leonardo Amato @@ -12,12 +14,13 @@ import com.seibel.lod.util.LodUtil; public class PosToRenderContainer { public byte minDetail; + private int size; private int regionPosX; private int regionPosZ; private int numberOfPosToRender; - private int[][] posToRender; + private int[] posToRender; /*TODO this population matrix could be converted to boolean to improve memory use*/ - private byte[][] population; + private byte[] population; public PosToRenderContainer(byte minDetail, int regionPosX, int regionPosZ) { @@ -25,9 +28,9 @@ public class PosToRenderContainer this.numberOfPosToRender = 0; this.regionPosX = regionPosX; this.regionPosZ = regionPosZ; - int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - minDetail); - posToRender = new int[size*size][3]; - population = new byte[size][size]; + this.size = 1 << (LodUtil.REGION_DETAIL_LEVEL - minDetail); + posToRender = new int[size*size*3]; + population = new byte[size*size]; } public void addPosToRender(byte detailLevel, int posX, int posZ) @@ -46,20 +49,20 @@ public class PosToRenderContainer //if(numberOfPosToRender >= posToRender.length) // posToRender = Arrays.copyOf(posToRender, posToRender.length*2); - posToRender[numberOfPosToRender][0] = detailLevel; - posToRender[numberOfPosToRender][1] = posX; - posToRender[numberOfPosToRender][2] = posZ; + posToRender[numberOfPosToRender*3 + 0] = detailLevel; + posToRender[numberOfPosToRender*3 + 1] = posX; + posToRender[numberOfPosToRender*3 + 2] = posZ; numberOfPosToRender++; - population[LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posX,minDetail))] - [LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posZ,minDetail))] = (byte) (detailLevel + 1); + population[LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posX,minDetail))*size + + LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posZ,minDetail))] = (byte) (detailLevel + 1); } public boolean contains(byte detailLevel, int posX, int posZ) { if(LevelPosUtil.getRegion(detailLevel, posX) == regionPosX && LevelPosUtil.getRegion(detailLevel, posZ) == regionPosZ) { - return (population[LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posX,minDetail))] - [LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posZ,minDetail))] == (detailLevel + 1)); + return (population[LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posX,minDetail)) * size + + LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posZ,minDetail))] == (detailLevel + 1)); }else { return false; @@ -71,22 +74,13 @@ public class PosToRenderContainer this.regionPosZ = regionPosZ; if(this.minDetail == minDetail) { - int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - minDetail); - for (int x = 0; x < size; x++) - { - for (int z = 0; z < size; z++) - { - posToRender[0][0] = 0; - posToRender[0][1] = 0; - posToRender[0][2] = 0; - population[x][z] = 0; - } - } + Arrays.fill(posToRender, 0); + Arrays.fill(population, (byte) 0); }else{ this.minDetail = minDetail; int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - minDetail); - posToRender = new int[size*size][3]; - population = new byte[size][size]; + posToRender = new int[size*size*3]; + population = new byte[size*size]; } } @@ -97,20 +91,15 @@ public class PosToRenderContainer public byte getNthDetailLevel(int n) { - return (byte) posToRender[n][0]; + return (byte) posToRender[n*3 + 0]; } public int getNthPosX(int n) { - return posToRender[n][1]; + return posToRender[n*3 + 1]; } public int getNthPosZ(int n) { - return posToRender[n][2]; - } - - public int[] getNthPos(int n) - { - return posToRender[n]; + return posToRender[n*3 + 2]; } @Override @@ -123,11 +112,11 @@ public class PosToRenderContainer builder.append('\n'); for(int i = 0; i < numberOfPosToRender; i++) { - builder.append(posToRender[i][0]); + builder.append(posToRender[i*3 + 0]); builder.append(" "); - builder.append(posToRender[i][1]); + builder.append(posToRender[i*3 + 1]); builder.append(" "); - builder.append(posToRender[i][2]); + builder.append(posToRender[i*3 + 2]); builder.append('\n'); } builder.append('\n'); diff --git a/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java b/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java index 5b95489bb..c69fd343c 100644 --- a/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java +++ b/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java @@ -134,8 +134,10 @@ public class VerticalLevelContainer implements LevelContainer public void updateData(LevelContainer lowerLevelContainer, int posX, int posZ) { //We reset the array - long[] dataToMerge = ThreadMapUtil.getVerticalUpdateArray(detailLevel, lowerLevelContainer.getMaxVerticalData()); + int lowerMaxVerticalData = lowerLevelContainer.getMaxVerticalData(); + long[] dataToMerge = ThreadMapUtil.getVerticalUpdateArray(detailLevel); Arrays.fill(dataToMerge, DataPointUtil.EMPTY_DATA); + int lowerMaxVertical = dataToMerge.length/4; int childPosX; int childPosZ; long[] data; @@ -147,11 +149,11 @@ public class VerticalLevelContainer implements LevelContainer { childPosX = 2 * posX + x; childPosZ = 2 * posZ + z; - for(int verticalIndex = 0; verticalIndex < maxVerticalData; verticalIndex++) - dataToMerge[(z*2+x)*maxVerticalData + verticalIndex] = lowerLevelContainer.getData(childPosX, childPosZ, verticalIndex); + for(int verticalIndex = 0; verticalIndex < lowerMaxVertical; verticalIndex++) + dataToMerge[(z*2+x)*lowerMaxVertical + verticalIndex] = lowerLevelContainer.getData(childPosX, childPosZ, verticalIndex); } } - data = DataPointUtil.mergeMultiData(dataToMerge, lowerLevelContainer.getMaxVerticalData(), getMaxVerticalData()); + data = DataPointUtil.mergeMultiData(dataToMerge, lowerMaxVertical, getMaxVerticalData()); for(int verticalIndex = 0; (verticalIndex < data.length) && (verticalIndex < maxVerticalData); verticalIndex++) { diff --git a/src/main/java/com/seibel/lod/util/LevelPosUtil.java b/src/main/java/com/seibel/lod/util/LevelPosUtil.java index 06b047557..fc66d9a65 100644 --- a/src/main/java/com/seibel/lod/util/LevelPosUtil.java +++ b/src/main/java/com/seibel/lod/util/LevelPosUtil.java @@ -229,13 +229,11 @@ public class LevelPosUtil int compareResult = Integer.compare( secondDetail, firstDetail); -// System.out.println("comparing level "+ firstDetail + " " + secondDetail + " " + compareResult); if (compareResult == 0) { compareResult = compareDistance( firstDistance, secondDistance); -// System.out.println("Equal level "+ firstDistance + " " + secondDistance + " " + compareResult); } return compareResult; } diff --git a/src/main/java/com/seibel/lod/util/ThreadMapUtil.java b/src/main/java/com/seibel/lod/util/ThreadMapUtil.java index 98ffaf77a..6adb8c30e 100644 --- a/src/main/java/com/seibel/lod/util/ThreadMapUtil.java +++ b/src/main/java/com/seibel/lod/util/ThreadMapUtil.java @@ -86,13 +86,13 @@ public class ThreadMapUtil return saveContainer.get(Thread.currentThread().getName()); } - public static long[] getVerticalUpdateArray(byte detailLevel,int size){ - if(!verticalUpdate.containsKey(Thread.currentThread().getName()) || (verticalUpdate.get(Thread.currentThread().getName()) == null) || (verticalUpdate.get(Thread.currentThread().getName())[detailLevel].length != size)) + public static long[] getVerticalUpdateArray(byte detailLevel){ + if(!verticalUpdate.containsKey(Thread.currentThread().getName()) || (verticalUpdate.get(Thread.currentThread().getName()) == null) || (verticalUpdate.get(Thread.currentThread().getName())[detailLevel].length != 4*DetailDistanceUtil.getMaxVerticalData(detailLevel))) { long[][] array = new long[10][]; for(int i = 0; i < array.length; i++) { - array[i] = new long[4 * size]; + array[i] = new long[4 * DetailDistanceUtil.getMaxVerticalData(detailLevel)]; } verticalUpdate.put(Thread.currentThread().getName(), array); }