From 347b149037eec2ffb7b32e40dee3dd2627276ff1 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Thu, 26 Aug 2021 17:41:01 +0200 Subject: [PATCH] The generation is working now --- .../seibel/lod/builders/LodBufferBuilder.java | 3 +- .../com/seibel/lod/builders/LodBuilder.java | 62 +++--- .../com/seibel/lod/objects/LodRegion.java | 201 ++++++++++++++---- 3 files changed, 191 insertions(+), 75 deletions(-) diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java index 55b0ae361..8bb59b44d 100644 --- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java @@ -228,7 +228,6 @@ public class LodBufferBuilder { short[] lodData = lodDim.getData(posToRender); short[][][] adjData = new short[2][2][]; - /* for (int x : new int[]{0, 1}) { adjPos.changeParameters(posToRender.detailLevel, posToRender.posX + x * 2 - 1, posToRender.posZ); @@ -241,7 +240,7 @@ public class LodBufferBuilder adjPos.changeParameters(posToRender.detailLevel, posToRender.posX, posToRender.posZ + z * 2 - 1); if (!renderer.vanillaRenderedChunks.contains(adjPos.getChunkPos())) adjData[1][z] = lodDim.getData(adjPos); - }*/ + } LodConfig.CLIENT.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPos, lodData, adjData, posToRender, renderer.debugging); diff --git a/src/main/java/com/seibel/lod/builders/LodBuilder.java b/src/main/java/com/seibel/lod/builders/LodBuilder.java index 97f6bdeaa..63445558d 100644 --- a/src/main/java/com/seibel/lod/builders/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBuilder.java @@ -155,37 +155,45 @@ public class LodBuilder short depth; LevelPos levelPos = new LevelPos((byte) 0,0,0); short[] data; - - for (int i = 0; i < detail.dataPointLengthCount * detail.dataPointLengthCount; i++) + try { - startX = detail.startX[i]; - startZ = detail.startZ[i]; - endX = detail.endX[i]; - endZ = detail.endZ[i]; - - color = generateLodColorForArea(chunk, config, startX, startZ, endX, endZ); - - if (!config.useHeightmap) + for (int i = 0; i < detail.dataPointLengthCount * detail.dataPointLengthCount; i++) { - height = determineHeightPointForArea(chunk.getSections(), startX, startZ, endX, endZ); - depth = determineBottomPointForArea(chunk.getSections(), startX, startZ, endX, endZ); - } else - { - height = determineHeightPoint(chunk.getOrCreateHeightmapUnprimed(LodUtil.DEFAULT_HEIGHTMAP), startX, - startZ, endX, endZ); - depth = 0; + startX = detail.startX[i]; + startZ = detail.startZ[i]; + endX = detail.endX[i]; + endZ = detail.endZ[i]; + + color = generateLodColorForArea(chunk, config, startX, startZ, endX, endZ); + + if (!config.useHeightmap) + { + height = determineHeightPointForArea(chunk.getSections(), startX, startZ, endX, endZ); + depth = determineBottomPointForArea(chunk.getSections(), startX, startZ, endX, endZ); + } else + { + height = determineHeightPoint(chunk.getOrCreateHeightmapUnprimed(LodUtil.DEFAULT_HEIGHTMAP), startX, + startZ, endX, endZ); + depth = 0; + } + levelPos.changeParameters((byte) 0, + chunk.getPos().x * 16 + startX, + chunk.getPos().z * 16 + startZ); + levelPos.convert(detail.detailLevel); + data = DataPoint.createDataPoint(height, depth, color[0], color[1], color[2]); + lodDim.addData(levelPos, + data, + config.distanceGenerationMode, + false); } - levelPos.changeParameters((byte) 0, - chunk.getPos().x * 16 + startX, - chunk.getPos().z * 16 + startZ); - levelPos.convert(detail.detailLevel); - data = DataPoint.createDataPoint(height, depth, color[0], color[1], color[2]); - lodDim.addData(levelPos, - data, - config.distanceGenerationMode, - false); + //levelPos.changeParameters(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z); + + lodDim.updateData(new LevelPos(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z)); + }catch (NullPointerException e){ + e.printStackTrace(); + }catch (ArrayIndexOutOfBoundsException e){ + e.printStackTrace(); } - lodDim.updateData(new LevelPos(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z)); } diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java index 0d9472c46..403cb8edd 100644 --- a/src/main/java/com/seibel/lod/objects/LodRegion.java +++ b/src/main/java/com/seibel/lod/objects/LodRegion.java @@ -75,16 +75,16 @@ public class LodRegion implements Serializable generationType[lod] = new byte[size][size]; dataExistence[lod] = new boolean[size][size]; } - int sizeDiff; - LevelPos levelPos; + int width; + LevelPos levelPos = new LevelPos(); for (byte tempLod = (byte) (minDetailLevel + 1); tempLod <= LodUtil.REGION_DETAIL_LEVEL; tempLod++) { - sizeDiff = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - tempLod); - for (int x = 0; x < sizeDiff; x++) + width = 1 << (LodUtil.REGION_DETAIL_LEVEL - tempLod); + for (int x = 0; x < width; x++) { - for (int z = 0; z < sizeDiff; z++) + for (int z = 0; z < width; z++) { - levelPos = new LevelPos(tempLod, x, z); + levelPos.changeParameters(tempLod, x, z); update(levelPos); } } @@ -193,16 +193,16 @@ public class LodRegion implements Serializable * * @return */ - public List> getDataToGenerate(int playerPosX, int playerPosZ, int start, int end, byte generation, byte detailLevel, int dataNumber) + public List> getDataToGenerate(int playerPosX, int playerPosZ, int start, int end, byte generation, byte detailLevel, int dataNumber) { LevelPos levelPos = new LevelPos(LodUtil.REGION_DETAIL_LEVEL, 0, 0); - List> levelPosList = getDataToGenerate(levelPos, playerPosX, playerPosZ, start, end, generation, detailLevel); - List> levelMinPosList = new ArrayList<>(); + List> levelPosList = getDataToGenerate(levelPos, playerPosX, playerPosZ, start, end, generation, detailLevel); + List> levelMinPosList = new ArrayList<>(); dataNumber = Math.min(dataNumber, levelPosList.size()); - for(int i=0; i min = Collections.min(levelPosList, LevelPos.getPosComparator()); + Map.Entry min = Collections.min(levelPosList, LevelPos.getPosComparator()); levelPosList.remove(min); levelMinPosList.add(min); } @@ -211,17 +211,17 @@ public class LodRegion implements Serializable } - private List> getDataToGenerate(LevelPos levelPos, int playerPosX, int playerPosZ, int start, int end, byte generation, byte detailLevel) + private List> getDataToGenerate(LevelPos levelPos, int playerPosX, int playerPosZ, int start, int end, byte generation, byte detailLevel) { - List> levelPosList = new ArrayList<>(); + List> levelPosList = new ArrayList<>(); int size = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - levelPos.detailLevel); int width = (int) Math.pow(2, levelPos.detailLevel); //here i calculate the the LevelPos is in range //This is important to avoid any kind of hole in the generation - int maxDistance = levelPos.maxDistance(playerPosX,playerPosZ,regionPosX,regionPosZ); - int minDistance = levelPos.minDistance(playerPosX,playerPosZ,regionPosX,regionPosZ); + int maxDistance = levelPos.maxDistance(playerPosX, playerPosZ, regionPosX, regionPosZ); + int minDistance = levelPos.minDistance(playerPosX, playerPosZ, regionPosX, regionPosZ); if (!(start <= maxDistance && minDistance < end) || levelPos.detailLevel < detailLevel) { @@ -236,7 +236,7 @@ public class LodRegion implements Serializable //we have reached the target detail level if (detailLevel == levelPos.detailLevel) { - if(generationType[levelPos.detailLevel][levelPos.posX][levelPos.posZ] < generation) + if (generationType[levelPos.detailLevel][levelPos.posX][levelPos.posZ] < generation) { levelPosList.add( new AbstractMap.SimpleEntry( @@ -255,7 +255,7 @@ public class LodRegion implements Serializable { childPos = new LevelPos((byte) (levelPos.detailLevel - 1), childPosX + x, childPosZ + z); - minDistance = childPos.minDistance(playerPosX,playerPosZ,regionPosX,regionPosZ); + minDistance = childPos.minDistance(playerPosX, playerPosZ, regionPosX, regionPosZ); if (generationType[childPos.detailLevel][childPos.posX][childPos.posZ] < generation || !doesDataExist(childPos)) { @@ -285,7 +285,7 @@ public class LodRegion implements Serializable childPos = levelPos.getConvertedLevelPos((byte) (levelPos.detailLevel - 1)); if (generationType[childPos.detailLevel][childPos.posX][childPos.posZ] < generation) { - minDistance = childPos.minDistance(playerPosX,playerPosZ,regionPosX,regionPosZ); + minDistance = childPos.minDistance(playerPosX, playerPosZ, regionPosX, regionPosZ); levelPosList.add( new AbstractMap.SimpleEntry( @@ -325,16 +325,17 @@ public class LodRegion implements Serializable //here i calculate the the LevelPos is in range //This is important to avoid any kind of hole in the rendering - int maxDistance = levelPos.maxDistance(playerPosX,playerPosZ,regionPosX,regionPosZ); - int minDistance = levelPos.minDistance(playerPosX,playerPosZ,regionPosX,regionPosZ); + int maxDistance = levelPos.maxDistance(playerPosX, playerPosZ, regionPosX, regionPosZ); + int minDistance = levelPos.minDistance(playerPosX, playerPosZ, regionPosX, regionPosZ); //To avoid z fighting: if the pos is touching the end radius at detailLevel + 1 then we stop //cause this area will be occupied by bigger block - if(levelPos.detailLevel == detailLevel + 1 && end <= maxDistance && minDistance <= end && zFix){ + if (levelPos.detailLevel == detailLevel + 1 && end <= maxDistance && minDistance <= end && zFix) + { return levelPosList; } - if (!(start <= maxDistance && minDistance < end) || levelPos.detailLevel < detailLevel) + if (!(start <= maxDistance && minDistance < end) || levelPos.detailLevel < detailLevel) { return levelPosList; } @@ -354,7 +355,7 @@ public class LodRegion implements Serializable for (int z = 0; z <= 1; z++) { childPos = new LevelPos((byte) (levelPos.detailLevel - 1), childPosX + x, childPosZ + z); - if(doesDataExist(childPos)) childrenCount++; + if (doesDataExist(childPos)) childrenCount++; } } @@ -370,51 +371,45 @@ public class LodRegion implements Serializable levelPosList.addAll(getDataToRender(childPos, playerPosX, playerPosZ, start, end, detailLevel, zFix)); } } - }else{ + } else + { levelPosList.add(new LevelPos(levelPos.detailLevel, levelPos.posX + regionPosX * size, levelPos.posZ + regionPosZ * size)); } } return levelPosList; } - /** - * @param levelPos - */ public void updateArea(LevelPos levelPos) { LevelPos tempLevelPos; - int sizeDiff; + int width; int startX; int startZ; - for(byte bottom = (byte) (minDetailLevel + 1); bottom < levelPos.detailLevel ; bottom++){ + for(byte bottom = (byte) (minDetailLevel + 1); bottom <= levelPos.detailLevel ; bottom++){ tempLevelPos = levelPos.getConvertedLevelPos(bottom); startX = tempLevelPos.posX; startZ = tempLevelPos.posZ; - sizeDiff = (int) Math.pow(2, levelPos.detailLevel - bottom); - for(int x = 0; x < sizeDiff; x++){ - for(int z = 0; z < sizeDiff; z++) { + width = 1 << (levelPos.detailLevel - bottom); + for(int x = 0; x < width; x++){ + for(int z = 0; z < width; z++) { update(new LevelPos(bottom, startX+x, startZ+z)); } } } - for (byte tempLod = levelPos.detailLevel; tempLod <= LodUtil.REGION_DETAIL_LEVEL; tempLod++) { + for (byte tempLod = (byte) (levelPos.detailLevel + 1); tempLod <= LodUtil.REGION_DETAIL_LEVEL; tempLod++) { tempLevelPos = levelPos.getConvertedLevelPos(tempLod); update(tempLevelPos); } } - /** - * @param levelPos - */ private void update(LevelPos levelPos) { levelPos = levelPos.getRegionModuleLevelPos(); int numberOfChildren = 0; - /**TODO add the ability to change how the heigth and depth are determinated (for example min or max)**/ byte minGenerationType = 5; int tempRed = 0; int tempGreen = 0; @@ -459,6 +454,108 @@ public class LodRegion implements Serializable } } + /** + * @param levelPos + *//* + public void updateArea(LevelPos levelPos) + { + levelPos.performRegionModule(); + int width; + int startX; + int startZ; + byte detailLevel = levelPos.detailLevel; + for (byte bottom = (byte) (minDetailLevel + 1); bottom <= detailLevel; bottom++) + { + levelPos.convert(bottom); + startX = levelPos.posX; + startZ = levelPos.posZ; + width = 1 << (detailLevel - bottom); + for (int x = 0; x < width; x++) + { + for (int z = 0; z < width; z++) + { + levelPos.changeParameters(bottom, startX + x, startZ + z); + update(levelPos); + } + } + } + byte tempLod = 0; + try + { + for (tempLod = (byte) (detailLevel + 1); tempLod <= LodUtil.REGION_DETAIL_LEVEL; tempLod++) + { + levelPos.convert(tempLod); + update(levelPos); + } + }catch (Exception e){ + System.out.println(tempLod); + System.out.println(levelPos); + e.printStackTrace(); + throw e; + } + }*/ + /** + * @param levelPos + *//* + private void update(LevelPos levelPos) + { + levelPos.performRegionModule(); + int numberOfChildren = 0; + + byte minGenerationType = 5; + int tempRed = 0; + int tempGreen = 0; + int tempBlue = 0; + int tempHeight = 0; + int tempDepth = 0; + int newPosX; + int newPosZ; + byte newDetailLevel; + LevelPos childPos; + byte detailLevel = levelPos.detailLevel; + int posX = levelPos.posX; + int posZ = levelPos.posZ; + try + { + if(detailLevel > 0) + { + for (int x = 0; x <= 1; x++) + { + for (int z = 0; z <= 1; z++) + { + newPosX = 2 * posX + x; + newPosZ = 2 * posZ + z; + newDetailLevel = (byte) (detailLevel - 1); + levelPos.changeParameters(newDetailLevel, newPosX, newPosZ); + if (hasDataBeenGenerated(levelPos)) + { + numberOfChildren++; + + tempRed += colors[newDetailLevel][newPosX][newPosZ][0]; + tempGreen += colors[newDetailLevel][newPosX][newPosZ][1]; + tempBlue += colors[newDetailLevel][newPosX][newPosZ][2]; + tempHeight += height[newDetailLevel][newPosX][newPosZ]; + tempDepth += depth[newDetailLevel][newPosX][newPosZ]; + minGenerationType = (byte) Math.min(minGenerationType, generationType[newDetailLevel][newPosX][newPosZ]); + } + } + } + if (numberOfChildren > 0) + { + colors[detailLevel][posX][posZ][0] = (byte) (tempRed / numberOfChildren); + colors[detailLevel][posX][posZ][1] = (byte) (tempGreen / numberOfChildren); + colors[detailLevel][posX][posZ][2] = (byte) (tempBlue / numberOfChildren); + height[detailLevel][posX][posZ] = (short) (tempHeight / numberOfChildren); + depth[detailLevel][posX][posZ] = (short) (tempDepth / numberOfChildren); + generationType[detailLevel][posX][posZ] = minGenerationType; + dataExistence[detailLevel][posX][posZ] = true; + } + } + }catch (Exception e){ + throw e; + } + }*/ + /** * @param levelPos * @return @@ -543,8 +640,15 @@ public class LodRegion implements Serializable */ public boolean hasDataBeenGenerated(LevelPos levelPos) { - levelPos = levelPos.getRegionModuleLevelPos(); - return (generationType[levelPos.detailLevel][levelPos.posX][levelPos.posZ] != 0); + levelPos.performRegionModule(); + try + { + return (generationType[levelPos.detailLevel][levelPos.posX][levelPos.posZ] != 0); + }catch(Exception e){ + System.out.println(levelPos); + e.printStackTrace(); + throw e; + } } public byte getMinDetailLevel() @@ -560,7 +664,8 @@ public class LodRegion implements Serializable */ public LevelContainer getLevel(byte detailLevel) { - if(detailLevel < minDetailLevel){ + if (detailLevel < minDetailLevel) + { throw new IllegalArgumentException("getLevel asked for a level that does not exist: minimum " + minDetailLevel + " level requested " + detailLevel); } return new LevelContainer(detailLevel, colors[detailLevel], height[detailLevel], depth[detailLevel], generationType[detailLevel], dataExistence[detailLevel]); @@ -589,7 +694,7 @@ public class LodRegion implements Serializable */ public void cutTree(byte detailLevel) { - if(minDetailLevel < detailLevel) + if (minDetailLevel < detailLevel) { for (byte tempLod = 0; tempLod < detailLevel; tempLod++) { @@ -608,12 +713,15 @@ public class LodRegion implements Serializable */ public void expand(byte detailLevel) { - if(detailLevel < minDetailLevel){ - for(byte tempLod = minDetailLevel; tempLod < LodUtil.REGION_DETAIL_LEVEL; tempLod++){ + if (detailLevel < minDetailLevel) + { + for (byte tempLod = minDetailLevel; tempLod < LodUtil.REGION_DETAIL_LEVEL; tempLod++) + { int size = (short) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - tempLod); generationType[tempLod] = new byte[size][size]; } - for(byte tempLod = detailLevel; tempLod < minDetailLevel; tempLod++){ + for (byte tempLod = detailLevel; tempLod < minDetailLevel; tempLod++) + { int size = (short) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - tempLod); colors[tempLod] = new byte[size][size][3]; height[tempLod] = new short[size][size]; @@ -639,12 +747,13 @@ public class LodRegion implements Serializable public int getMinMemoryNeeded() { int count = 0; - for(byte tempLod = LodUtil.REGION_DETAIL_LEVEL; tempLod > minDetailLevel; tempLod--){ + for (byte tempLod = LodUtil.REGION_DETAIL_LEVEL; tempLod > minDetailLevel; tempLod--) + { //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 += Math.pow(2,LodUtil.REGION_DETAIL_LEVEL-tempLod) * (8 + 3 + 2 + 2 + 1 + 1) - count += Math.pow(2,LodUtil.REGION_DETAIL_LEVEL-tempLod) * (24 + 8 + 8 + 8 + 8 + 8); + count += Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - tempLod) * (24 + 8 + 8 + 8 + 8 + 8); } return count; }