From c9aed389ae52fa53ac7b3efeb7b4bd502a6e1217 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Thu, 23 Sep 2021 01:05:54 +0200 Subject: [PATCH 1/2] various changes to the generation + some small fixes --- .../com/seibel/lod/builders/LodBuilder.java | 93 +++++++++++-------- .../worldGeneration/LodWorldGenerator.java | 72 ++++++++++---- .../com/seibel/lod/objects/LodDimension.java | 6 +- .../com/seibel/lod/objects/LodRegion.java | 4 +- .../lod/objects/PosToGenerateContainer.java | 64 ++++++------- .../java/com/seibel/lod/proxy/GlProxy.java | 10 +- 6 files changed, 149 insertions(+), 100 deletions(-) diff --git a/src/main/java/com/seibel/lod/builders/LodBuilder.java b/src/main/java/com/seibel/lod/builders/LodBuilder.java index de19d478e..80b2c0915 100644 --- a/src/main/java/com/seibel/lod/builders/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBuilder.java @@ -322,32 +322,21 @@ public class LodBuilder yAbs = height - 1; // We search light on above air block depth = determineBottomPointFrom(chunk, config, xRel, zRel, yAbs, blockPos); + blockPos.set(xAbs, yAbs, zAbs); + light = getLightValue(chunk, blockPos, hasCeiling, hasSkyLight, topBlock); if (hasCeiling && topBlock) { yAbs = depth; color = generateLodColor(chunk, config, xRel, yAbs, zRel, blockPos); blockPos.set(xAbs, yAbs - 1, zAbs); - light = getLightValue(chunk, blockPos, true); } else { color = generateLodColor(chunk, config, xRel, yAbs, zRel, blockPos); blockPos.set(xAbs, yAbs + 1, zAbs); - light = getLightValue(chunk, blockPos, false); } lightBlock = light & 0b1111; - if (!hasCeiling && topBlock) - { - if (hasSkyLight) - { - lightSky = 15; //default max light - } else - { - lightSky = 0; - } - } else - { - lightSky = (light >> 4) & 0b1111; - } + lightSky = (light >> 4) & 0b1111; + dataToMerge[index * verticalData + count] = DataPointUtil.createDataPoint(height, depth, color, lightSky, lightBlock, generation); topBlock = false; @@ -448,6 +437,8 @@ public class LodBuilder int lightBlock; int lightSky; + boolean hasCeiling = mc.getClientWorld().dimensionType().hasCeiling(); + boolean hasSkyLight = mc.getClientWorld().dimensionType().hasSkyLight(); BlockPos.Mutable blockPos = new BlockPos.Mutable(0, 0, 0); int index = 0; @@ -479,7 +470,7 @@ public class LodBuilder depth = determineBottomPoint(chunk, config, xRel, zRel, blockPos); blockPos.set(xAbs, yAbs + 1, zAbs); - light = getLightValue(chunk, blockPos, false); + light = getLightValue(chunk, blockPos, hasCeiling, hasSkyLight, true); lightBlock = light & 0b1111; //lightSky = (light >> 4) & 0b1111; lightSky = 15; //default max light @@ -595,32 +586,54 @@ public class LodBuilder return colorInt; } - private int getLightValue(IChunk chunk, BlockPos.Mutable blockPos, boolean ceilingTopBlock) + private int getLightValue(IChunk chunk, BlockPos.Mutable blockPos, boolean hasCeiling, boolean hasSkyLight, boolean topBlock) { int skyLight; - int blockLight; - if (mc.getPlayer() == null) - return 0; - if (mc.getPlayer().level == null) + int blockLight = 0; + if (mc.getClientWorld() == null) return 0; - IWorld world = mc.getPlayer().level; + IWorld world = mc.getClientWorld(); - blockLight = world.getBrightness(LightType.BLOCK, blockPos); - skyLight = world.getBrightness(LightType.SKY, blockPos); + int blockBrightness = world.getBrightness(LightType.BLOCK, blockPos); - if (ceilingTopBlock) - blockPos.set(blockPos.getX(), blockPos.getY() + 1, blockPos.getZ()); - else + if (hasCeiling && topBlock) blockPos.set(blockPos.getX(), blockPos.getY() - 1, blockPos.getZ()); + else + blockPos.set(blockPos.getX(), blockPos.getY() + 1, blockPos.getZ()); + + if (!hasSkyLight && hasCeiling) + { + skyLight = 0; + } + else if(topBlock) + { + skyLight = 15; //default max light + } else + { + if (chunk.isLightCorrect() && false) + { + skyLight = world.getBrightness(LightType.SKY, blockPos); + } else + { + if (blockPos.getY() >= mc.getClientWorld().getSeaLevel()-5) + { + skyLight = 10; + } else + { + skyLight = 0; + } + } + } BlockState blockState = chunk.getBlockState(blockPos); - - blockLight = LodUtil.clamp(0, blockLight + blockState.getLightValue(chunk, blockPos), 15); + blockLight = blockState.getLightValue(chunk, blockPos); + blockLight = LodUtil.clamp(0, blockLight + blockBrightness, 15); return blockLight + (skyLight << 4); } + private int getColorTextureForBlock(BlockState blockState, BlockPos blockPos, boolean topTextureRequired) { Block block = blockState.getBlock(); @@ -661,6 +674,7 @@ public class LodBuilder int blue = 0; int numberOfGreyPixel = 0; int color; + int colorMultiplier; for (int k = 0; k < texture.getFrameCount(); k++) { for (int i = 0; i < texture.getHeight(); i++) @@ -670,17 +684,20 @@ public class LodBuilder if (texture.isTransparent(k, i, j)) continue; color = texture.getPixelRGBA(k, i, j); - if(Math.max(Math.max(ColorUtil.getBlue(color),ColorUtil.getGreen(color)),ColorUtil.getRed(color)) < 4 + Math.min(Math.min(ColorUtil.getBlue(color),ColorUtil.getGreen(color)),ColorUtil.getRed(color))) + if (Math.max(Math.max(ColorUtil.getBlue(color), ColorUtil.getGreen(color)), ColorUtil.getRed(color)) < 4 + Math.min(Math.min(ColorUtil.getBlue(color), ColorUtil.getGreen(color)), ColorUtil.getRed(color))) { numberOfGreyPixel++; } - if (block instanceof FlowerBlock && ColorUtil.getGreen(color) > (ColorUtil.getBlue(color) + 30) && ColorUtil.getGreen(color) > (ColorUtil.getRed(color) + 30)) - continue; - count++; - alpha += ColorUtil.getAlpha(color); - red += ColorUtil.getBlue(color); - green += ColorUtil.getGreen(color); - blue += ColorUtil.getRed(color); + if (block instanceof FlowerBlock && (!(ColorUtil.getGreen(color) > (ColorUtil.getBlue(color) + 30)) || !(ColorUtil.getGreen(color) > (ColorUtil.getRed(color) + 30)))) + colorMultiplier = 5; + else + colorMultiplier = 1; + count = colorMultiplier + count; + alpha += ColorUtil.getAlpha(color) * colorMultiplier; + ; + red += ColorUtil.getBlue(color) * colorMultiplier; + green += ColorUtil.getGreen(color) * colorMultiplier; + blue += ColorUtil.getRed(color) * colorMultiplier; } } } @@ -697,7 +714,7 @@ public class LodBuilder } if (blockState.getBlock().equals(Blocks.TALL_GRASS)) System.out.println(ColorUtil.toString(color) + " " + numberOfGreyPixel + " " + count); - if (block instanceof TallGrassBlock || (couldHaveGrassTint(block) || couldHaveLeavesTint(block) || couldHaveWaterTint(block)) && (float) (numberOfGreyPixel/count) > 0.75f) + if (block instanceof TallGrassBlock || (couldHaveGrassTint(block) || couldHaveLeavesTint(block) || couldHaveWaterTint(block)) && (float) (numberOfGreyPixel / count) > 0.75f) { toTint.replace(block, true); } 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 59d7e9b6a..c5ca2f81d 100644 --- a/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java +++ b/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java @@ -118,33 +118,67 @@ public class LodWorldGenerator byte detailLevel; int posX; int posZ; + boolean nearOrFar = true; + boolean stopSwitch = false; + int near = 0; + int far = 0; + for (int index = 0; index < posToGenerate.getNumberOfPos(); index++) { - if(posToGenerate.getNthDetail(index) == 0) - continue; - 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) + if (posToGenerate.getNthDetail(near, true) != 0 && far < posToGenerate.getNumberOfNearPos()) { - // prevent generating the same chunk multiple times - if (positionWaitingToBeGenerated.contains(chunkPos)) + detailLevel = (byte) (posToGenerate.getNthDetail(near, true) - 1); + posX = posToGenerate.getNthPosX(near, true); + posZ = posToGenerate.getNthPosZ(near, true); + near++; + ChunkPos chunkPos = new ChunkPos(LevelPosUtil.getChunkPos(detailLevel, posX), LevelPosUtil.getChunkPos(detailLevel, posZ)); + if (numberOfChunksWaitingToGenerate.get() < maxChunkGenRequests) { - continue; + // prevent generating the same chunk multiple times + if (positionWaitingToBeGenerated.contains(chunkPos)) + { + continue; + } } + + // don't add null chunkPos (which shouldn't happen anyway) + // or add more to the generation queue + if (chunkPos == null || numberOfChunksWaitingToGenerate.get() >= maxChunkGenRequests) + continue; + + positionWaitingToBeGenerated.add(chunkPos); + numberOfChunksWaitingToGenerate.addAndGet(1); + LodNodeGenWorker genWorker = new LodNodeGenWorker(chunkPos, DetailDistanceUtil.getDistanceGenerationMode(detailLevel), lodBuilder, lodDim, serverWorld); + WorldWorkerManager.addWorker(genWorker); } - // don't add null chunkPos (which shouldn't happen anyway) - // or add more to the generation queue - if (chunkPos == null || numberOfChunksWaitingToGenerate.get() >= maxChunkGenRequests) - continue; - positionWaitingToBeGenerated.add(chunkPos); - numberOfChunksWaitingToGenerate.addAndGet(1); - LodNodeGenWorker genWorker = new LodNodeGenWorker(chunkPos, DetailDistanceUtil.getDistanceGenerationMode(detailLevel), lodBuilder, lodDim, serverWorld); - WorldWorkerManager.addWorker(genWorker); + if (posToGenerate.getNthDetail(far, false) != 0 && far < posToGenerate.getNumberOfFarPos()) + { + detailLevel = (byte) (posToGenerate.getNthDetail(far, false) - 1); + posX = posToGenerate.getNthPosX(far, false); + posZ = posToGenerate.getNthPosZ(far, false); + far++; + ChunkPos chunkPos = new ChunkPos(LevelPosUtil.getChunkPos(detailLevel, posX), LevelPosUtil.getChunkPos(detailLevel, posZ)); + if (numberOfChunksWaitingToGenerate.get() < maxChunkGenRequests) + { + // prevent generating the same chunk multiple times + if (positionWaitingToBeGenerated.contains(chunkPos)) + { + continue; + } + } + + // don't add null chunkPos (which shouldn't happen anyway) + // or add more to the generation queue + if (chunkPos == null || numberOfChunksWaitingToGenerate.get() >= maxChunkGenRequests) + continue; + + positionWaitingToBeGenerated.add(chunkPos); + numberOfChunksWaitingToGenerate.addAndGet(1); + LodNodeGenWorker genWorker = new LodNodeGenWorker(chunkPos, DetailDistanceUtil.getDistanceGenerationMode(detailLevel), lodBuilder, lodDim, serverWorld); + WorldWorkerManager.addWorker(genWorker); + } } } catch (Exception e) diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index 0ac2ce1b0..3dc6c2ddd 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -534,8 +534,6 @@ public class LodDimension int numbChunksWide = (width) * 32 * 2; for (int i = 0; i < numbChunksWide * numbChunksWide; i++) { - - xChunkToCheck = x + playerChunkX; zChunkToCheck = z + playerChunkZ; //distance = LevelPosUtil.maxDistance(LodUtil.CHUNK_DETAIL_LEVEL, xChunkToCheck, zChunkToCheck, playerChunkX, playerChunkZ); @@ -564,7 +562,7 @@ public class LodDimension } break; case FAR_FIRST: - posToGenerate = new PosToGenerateContainer((byte) 8, maxDataToGenerate, (int) (maxDataToGenerate * 0.25f), playerPosX, playerPosZ); + posToGenerate = new PosToGenerateContainer((byte) 8, maxDataToGenerate, (int) (maxDataToGenerate * 0.25), playerPosX, playerPosZ); int n = regions.length; int xRegion; int zRegion; @@ -843,7 +841,7 @@ public class LodDimension int minDistance = LevelPosUtil.minDistance(LodUtil.REGION_DETAIL_LEVEL, x, z, halfWidth, halfWidth); int detail = DetailDistanceUtil.getTreeCutDetailFromDistance(minDistance); - int levelToGen = DetailDistanceUtil.getCutLodDetail(detail); + int levelToGen = DetailDistanceUtil.getCutLodDetail(detail)+1; int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - levelToGen); int maxVerticalData = DetailDistanceUtil.getMaxVerticalData(levelToGen); int numberOfLods = size * size * maxVerticalData; diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java index 66132de67..426d388af 100644 --- a/src/main/java/com/seibel/lod/objects/LodRegion.java +++ b/src/main/java/com/seibel/lod/objects/LodRegion.java @@ -273,7 +273,7 @@ public class LodRegion { if (doesDataExist(childDetailLevel, childPosX + x, childPosZ + z)) { - if (!requireCorrectDetailLevel && detailLevel > supposedLevel + 1) + if (!requireCorrectDetailLevel) { childrenCount++; } else @@ -286,7 +286,7 @@ public class LodRegion //If all the four children exist we go deeper - if(!requireCorrectDetailLevel && detailLevel > supposedLevel + 1) + if(!requireCorrectDetailLevel) { if (childrenCount == 4) { diff --git a/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java b/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java index a8ffa5577..ecd51449f 100644 --- a/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java +++ b/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java @@ -43,7 +43,8 @@ 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.compareDistance(distance, posToGenerate[index + 1][3]) <= 0) + //while (index < posToGenerate.length - 1 && LevelPosUtil.compareLevelAndDistance(detailLevel, distance, (byte) (posToGenerate[index + 1][0] - 1), posToGenerate[index + 1][3]) <= 0) { posToGenerate[index][0] = posToGenerate[index + 1][0]; posToGenerate[index][1] = posToGenerate[index + 1][1]; @@ -87,50 +88,43 @@ public class PosToGenerateContainer return nearSize+farSize; } - public int getNthDetail(int n) + public int getNumberOfNearPos() { - 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][0]; + return nearSize; } - public int getNthPosX(int n) + public int getNumberOfFarPos() { - 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][1]; + return farSize; } - public int getNthPosZ(int n) + + public int getNthDetail(int n, boolean near) { - int index; - if (n > farSize * 2) - index = n - farSize; - else if (n % 2 == 0) - index = n / 2; + if (near) + return posToGenerate[n][0]; else - index = posToGenerate.length - n / 2 - 1; - return posToGenerate[index][2]; + return posToGenerate[maxSize-1-n][0]; } - public int getNthGeneration(int n) + public int getNthPosX(int n, boolean near) { - int index; - if (n > farSize * 2) - index = n - farSize; - else if (n % 2 == 0) - index = n / 2; + if (near) + return posToGenerate[n][1]; else - index = posToGenerate.length - n / 2 - 1; - return posToGenerate[index][3]; + return posToGenerate[maxSize-1-n][1]; + } + public int getNthPosZ(int n, boolean near) + { + if (near) + return posToGenerate[n][2]; + else + return posToGenerate[maxSize-1-n][2]; + } + public int getNthGeneration(int n, boolean near) + { + if (near) + return posToGenerate[n][3]; + else + return posToGenerate[maxSize-1-n][3]; } public String toString() diff --git a/src/main/java/com/seibel/lod/proxy/GlProxy.java b/src/main/java/com/seibel/lod/proxy/GlProxy.java index 71f928495..d79755c40 100644 --- a/src/main/java/com/seibel/lod/proxy/GlProxy.java +++ b/src/main/java/com/seibel/lod/proxy/GlProxy.java @@ -168,8 +168,14 @@ public class GlProxy public static GlProxy getInstance() { - if (instance == null) - instance = new GlProxy(); + try + { + if (instance == null) + instance = new GlProxy(); + }catch (Exception e) + { + e.printStackTrace(); + } return instance; } From 593a014dfcfe331bd43922ec9af9e466d710ab99 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Thu, 23 Sep 2021 02:03:02 +0200 Subject: [PATCH 2/2] fixed far and near generation, fixed holes in the rendering in near gen --- .../worldGeneration/LodWorldGenerator.java | 2 +- .../com/seibel/lod/objects/LodDimension.java | 17 +++- .../com/seibel/lod/objects/LodRegion.java | 15 ++- .../lod/objects/PosToGenerateContainer.java | 91 +++++++++---------- .../com/seibel/lod/util/LevelPosUtil.java | 57 +++++++----- 5 files changed, 109 insertions(+), 73 deletions(-) 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 c5ca2f81d..7365ef00c 100644 --- a/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java +++ b/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java @@ -125,7 +125,7 @@ public class LodWorldGenerator for (int index = 0; index < posToGenerate.getNumberOfPos(); index++) { - if (posToGenerate.getNthDetail(near, true) != 0 && far < posToGenerate.getNumberOfNearPos()) + if (posToGenerate.getNthDetail(near, true) != 0 && near < posToGenerate.getNumberOfNearPos()) { detailLevel = (byte) (posToGenerate.getNthDetail(near, true) - 1); posX = posToGenerate.getNthPosX(near, true); diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index 3dc6c2ddd..bf6c81080 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -531,9 +531,20 @@ public class LodDimension int posX; int posZ; long data; - int numbChunksWide = (width) * 32 * 2; + int numbChunksWide = (width) * 32 ; + int circleLimit = Integer.MAX_VALUE; for (int i = 0; i < numbChunksWide * numbChunksWide; i++) { + // use this for square generation + + // use this for circular generation + if (circleLimit < Math.abs(x) && circleLimit < Math.abs(z)) + break; + if (maxDataToGenerate == 0) + { + circleLimit = (int) (Math.abs(x) * 1.41f); + } + xChunkToCheck = x + playerChunkX; zChunkToCheck = z + playerChunkZ; //distance = LevelPosUtil.maxDistance(LodUtil.CHUNK_DETAIL_LEVEL, xChunkToCheck, zChunkToCheck, playerChunkX, playerChunkZ); @@ -548,8 +559,8 @@ public class LodDimension if (DataPointUtil.getGenerationMode(data) < LodConfig.CLIENT.worldGenerator.distanceGenerationMode.get().complexity) { posToGenerate.addPosToGenerate(detailLevel, posX, posZ); - //if (maxDataToGenerate >= 0) - // maxDataToGenerate--; + if (maxDataToGenerate >= 0) + maxDataToGenerate--; } if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z))) { diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java index 426d388af..dd8ea26df 100644 --- a/src/main/java/com/seibel/lod/objects/LodRegion.java +++ b/src/main/java/com/seibel/lod/objects/LodRegion.java @@ -2,6 +2,7 @@ package com.seibel.lod.objects; import com.seibel.lod.config.LodConfig; +import com.seibel.lod.enums.DetailDropOff; import com.seibel.lod.enums.DistanceGenerationMode; import com.seibel.lod.enums.LodTemplate; import com.seibel.lod.enums.VerticalQuality; @@ -231,12 +232,17 @@ public class LodRegion //This is important to avoid any kind of hole in the rendering byte supposedLevel; int maxDistance; + boolean stopNow = false; switch (LodConfig.CLIENT.graphics.detailDropOff.get()) { default: case BY_BLOCK: maxDistance = LevelPosUtil.maxDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ); supposedLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(maxDistance)); + int minDistance = LevelPosUtil.minDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ); + int childLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(minDistance)); + stopNow = detailLevel == childLevel - 1; + break; case BY_REGION_FANCY: supposedLevel = minDetailLevel; @@ -254,8 +260,15 @@ public class LodRegion break; } - if (supposedLevel > detailLevel) + if(stopNow){ + posToRender.addPosToRender(detailLevel, + posX + regionPosX * size, + posZ + regionPosZ * size); + } + else if (supposedLevel > detailLevel) + { return; + } else if (supposedLevel == detailLevel) { posToRender.addPosToRender(detailLevel, diff --git a/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java b/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java index ecd51449f..fd0c530cc 100644 --- a/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java +++ b/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java @@ -12,19 +12,22 @@ public class PosToGenerateContainer private int maxFarSize; private int nearSize; private int farSize; - private int[][] posToGenerate; + private int[][] nearPosToGenerate; + private int[][] farPosToGenerate; + public PosToGenerateContainer(byte farMinDetail, int maxDataToGenerate, int maxFarDataToGenerate, int playerPosX, int playerPosZ) { this.playerPosX = playerPosX; this.playerPosZ = playerPosZ; this.farMinDetail = farMinDetail; - maxNearSize = maxDataToGenerate; + maxNearSize = maxDataToGenerate-maxFarDataToGenerate; maxFarSize = maxFarDataToGenerate; maxSize = maxDataToGenerate; nearSize = 0; farSize = 0; - posToGenerate = new int[maxDataToGenerate][4]; + nearPosToGenerate = new int[maxDataToGenerate][4]; + farPosToGenerate = new int[maxDataToGenerate][4]; } public void addPosToGenerate(byte detailLevel, int posX, int posZ) @@ -33,52 +36,45 @@ public class PosToGenerateContainer int index; if (detailLevel >= farMinDetail) {//We are introducing a position in the far array - if (farSize < maxFarSize) - { + + if(farSize < farPosToGenerate.length) farSize++; - if (nearSize == maxNearSize) - { - nearSize--; - } - maxNearSize--; - } - index = posToGenerate.length - farSize; - while (index < posToGenerate.length - 1 && LevelPosUtil.compareDistance(distance, posToGenerate[index + 1][3]) <= 0) - //while (index < posToGenerate.length - 1 && LevelPosUtil.compareLevelAndDistance(detailLevel, distance, (byte) (posToGenerate[index + 1][0] - 1), posToGenerate[index + 1][3]) <= 0) + index = farSize; + //while (index > 0 && LevelPosUtil.compareDistance(distance, farPosToGenerate[index - 1][3]) <= 0) + while (index > 0 && LevelPosUtil.compareDistance(distance, farPosToGenerate[index - 1][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]; - index++; + farPosToGenerate[index][0] = farPosToGenerate[index - 1][0]; + farPosToGenerate[index][1] = farPosToGenerate[index - 1][1]; + farPosToGenerate[index][2] = farPosToGenerate[index - 1][2]; + farPosToGenerate[index][3] = farPosToGenerate[index - 1][3]; + index--; } - if (index <= posToGenerate.length - 1) + if (index != farSize-1 || farSize != farPosToGenerate.length) { - posToGenerate[index][0] = detailLevel + 1; - posToGenerate[index][1] = posX; - posToGenerate[index][2] = posZ; - posToGenerate[index][3] = distance; + farPosToGenerate[index][0] = detailLevel + 1; + farPosToGenerate[index][1] = posX; + farPosToGenerate[index][2] = posZ; + farPosToGenerate[index][3] = distance; } } else {//We are introducing a position in the near array - if (nearSize < maxNearSize) + if(nearSize < nearPosToGenerate.length) nearSize++; - index = nearSize - 1; - - while (index > 0 && LevelPosUtil.compareDistance(distance, posToGenerate[index - 1][3]) <= 0) + index = nearSize-1; + while (index > 0 && LevelPosUtil.compareDistance(distance, nearPosToGenerate[index - 1][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]; + nearPosToGenerate[index][0] = nearPosToGenerate[index - 1][0]; + nearPosToGenerate[index][1] = nearPosToGenerate[index - 1][1]; + nearPosToGenerate[index][2] = nearPosToGenerate[index - 1][2]; + nearPosToGenerate[index][3] = nearPosToGenerate[index - 1][3]; index--; } - if (index >= 0) + if (index != nearSize-1 || nearSize != nearPosToGenerate.length) { - posToGenerate[index][0] = detailLevel + 1; - posToGenerate[index][1] = posX; - posToGenerate[index][2] = posZ; - posToGenerate[index][3] = distance; + nearPosToGenerate[index][0] = detailLevel + 1; + nearPosToGenerate[index][1] = posX; + nearPosToGenerate[index][2] = posZ; + nearPosToGenerate[index][3] = distance; } } } @@ -101,34 +97,34 @@ public class PosToGenerateContainer public int getNthDetail(int n, boolean near) { if (near) - return posToGenerate[n][0]; + return nearPosToGenerate[n][0]; else - return posToGenerate[maxSize-1-n][0]; + return farPosToGenerate[n][0]; } public int getNthPosX(int n, boolean near) { if (near) - return posToGenerate[n][1]; + return nearPosToGenerate[n][1]; else - return posToGenerate[maxSize-1-n][1]; + return farPosToGenerate[n][1]; } public int getNthPosZ(int n, boolean near) { if (near) - return posToGenerate[n][2]; + return nearPosToGenerate[n][2]; else - return posToGenerate[maxSize-1-n][2]; + return farPosToGenerate[n][2]; } public int getNthGeneration(int n, boolean near) { if (near) - return posToGenerate[n][3]; + return nearPosToGenerate[n][3]; else - return posToGenerate[maxSize-1-n][3]; + return farPosToGenerate[n][3]; } public String toString() - { + {/* StringBuilder builder = new StringBuilder(); builder.append("Number of pos to generate "); builder.append(farSize + nearSize); @@ -168,6 +164,7 @@ public class PosToGenerateContainer builder.append('\n'); } builder.append('\n'); - return builder.toString(); + return builder.toString();*/ + return " "; } } diff --git a/src/main/java/com/seibel/lod/util/LevelPosUtil.java b/src/main/java/com/seibel/lod/util/LevelPosUtil.java index 8b6104726..e8e7c059d 100644 --- a/src/main/java/com/seibel/lod/util/LevelPosUtil.java +++ b/src/main/java/com/seibel/lod/util/LevelPosUtil.java @@ -123,22 +123,6 @@ public class LevelPosUtil return convert(detailLevel,pos, LodUtil.CHUNK_DETAIL_LEVEL); } - public static int getChunkPosX(int[] levelPos) - { - levelPos = convert(levelPos, LodUtil.CHUNK_DETAIL_LEVEL); - return getPosX(levelPos); - } - - public static int getChunkPosZ(int[] levelPos) - { - levelPos = convert(levelPos, LodUtil.CHUNK_DETAIL_LEVEL); - return getPosZ(levelPos); - } - - public static int maxDistance(int[] levelPos, int playerPosX, int playerPosZ) - { - return maxDistance(getDetailLevel(levelPos), getPosX(levelPos), getPosZ(levelPos), playerPosX, playerPosZ); - } public static int maxDistance(byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ) { @@ -175,11 +159,6 @@ public class LevelPosUtil } - public static int minDistance(int[] levelPos, int playerPosX, int playerPosZ) - { - return minDistance(getDetailLevel(levelPos), getPosX(levelPos), getPosZ(levelPos), playerPosX, playerPosZ); - } - public static int minDistance(byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ) { int width = 1 << detailLevel; @@ -216,6 +195,42 @@ public class LevelPosUtil } } + public static int minDistance(byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ, int xRegion, int zRegion) + { + int width = 1 << detailLevel; + + int startPosX = xRegion * 512 + posX * width; + int startPosZ = zRegion * 512 + posZ * width; + int endPosX = startPosX + width; + int endPosZ = startPosZ + width; + + boolean inXArea = playerPosX >= startPosX && playerPosX <= endPosX; + boolean inZArea = playerPosZ >= startPosZ && playerPosZ <= endPosZ; + if (inXArea && inZArea) + { + return 0; + } else if (inXArea) + { + return Math.min( + Math.abs(playerPosZ - startPosZ), + Math.abs(playerPosZ - endPosZ) + ); + } else if (inZArea) + { + return Math.min( + Math.abs(playerPosX - startPosX), + Math.abs(playerPosX - endPosX) + ); + } else + { + int minDistance = (int) Math.sqrt(Math.pow(playerPosX - startPosX, 2) + Math.pow(playerPosZ - startPosZ, 2)); + minDistance = Math.min(minDistance, (int) Math.sqrt(Math.pow(playerPosX - startPosX, 2) + Math.pow(playerPosZ - endPosZ, 2))); + minDistance = Math.min(minDistance, (int) Math.sqrt(Math.pow(playerPosX - endPosX, 2) + Math.pow(playerPosZ - startPosZ, 2))); + minDistance = Math.min(minDistance, (int) Math.sqrt(Math.pow(playerPosX - endPosX, 2) + Math.pow(playerPosZ - endPosZ, 2))); + return minDistance; + } + } + public static int compareDistance(int firstDistance, int secondDistance) { return Integer.compare(