Introduced correctly spiral generation

This commit is contained in:
Leonardo
2021-09-21 18:35:48 +02:00
parent 46bdf5763f
commit bda963036d
5 changed files with 83 additions and 27 deletions
@@ -174,6 +174,7 @@ public class LodConfig
public ForgeConfigSpec.EnumValue<VerticalQuality> lodQualityMode;
public ForgeConfigSpec.EnumValue<HorizontalResolution> generationResolution;
public ForgeConfigSpec.EnumValue<DistanceGenerationMode> distanceGenerationMode;
public ForgeConfigSpec.EnumValue<GenerationPriority> generationPriority;
public ForgeConfigSpec.BooleanValue allowUnstableFeatureGeneration;
public ForgeConfigSpec.EnumValue<DistanceQualityDropOff> lodDistanceCalculatorType;
@@ -211,6 +212,18 @@ public class LodConfig
+ " quadratically to the distance of the player \n")
.defineEnum("lodDistanceComputation", DistanceQualityDropOff.LINEAR);
generationPriority = builder
.comment("\n\n"
+ " " + GenerationPriority.FAR + " \n"
+ " the fake chunk are generated from smallest to biggest\n"
+ " with a small priority for far regions \n"
+ "\n"
+ " " + GenerationPriority.NORMAL + " \n"
+ " the fake chunk are generated around the player \n"
+ " in spiral similar to vanilla minecraft \n")
.defineEnum("Generation priority", GenerationPriority.NORMAL);
distanceGenerationMode = builder
.comment("\n\n"
+ " Note: The times listed here are the amount of time it took \n"
@@ -0,0 +1,29 @@
/*
* This file is part of the LOD Mod, licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.enums;
/**
* @author James Seibel
* @author Leonardo Amato
*/
public enum GenerationPriority
{
NORMAL,
FAR;
}
@@ -24,6 +24,7 @@ import java.util.concurrent.Executors;
import com.seibel.lod.config.LodConfig;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.enums.GenerationPriority;
import com.seibel.lod.enums.VerticalQuality;
import com.seibel.lod.handlers.LodDimensionFileHandler;
import com.seibel.lod.util.DataPointUtil;
@@ -523,16 +524,15 @@ public class LodDimension
long data;
x = z = dx =0;
dz = -1;
int width = numbChunksWide;
int t = width;
int t = numbChunksWide;
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;
if ((-numbChunksWide/2 <= x) && (x <= numbChunksWide/2) && (-numbChunksWide/2 <= z) && (z <= numbChunksWide/2)){
xChunkToCheck = x + playerChunkPosX;
zChunkToCheck = z + 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);
@@ -584,7 +584,7 @@ public class LodDimension
{
LodRegion region = getRegion(regionPos.x, regionPos.z);
if (region != null)
region.getDataToRender(posToRender, playerPosX, playerPosZ);
region.getDataToRender(posToRender, playerPosX, playerPosZ, LodConfig.CLIENT.worldGenerator.generationPriority.get() == GenerationPriority.NORMAL);
}
public int getMaxVerticalData(byte detailLevel, int posX, int posZ)
@@ -215,15 +215,15 @@ public class LodRegion
/**
* @return
*/
public void getDataToRender(PosToRenderContainer posToRender, int playerPosX, int playerPosZ)
public void getDataToRender(PosToRenderContainer posToRender, int playerPosX, int playerPosZ, boolean requireCorrectDetailLevel)
{
getDataToRender(posToRender, LodUtil.REGION_DETAIL_LEVEL, 0, 0, playerPosX, playerPosZ);
getDataToRender(posToRender, LodUtil.REGION_DETAIL_LEVEL, 0, 0, playerPosX, playerPosZ, requireCorrectDetailLevel);
}
/**
* @return
*/
private void getDataToRender(PosToRenderContainer posToRender, byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ)
private void getDataToRender(PosToRenderContainer posToRender, byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ, boolean requireCorrectDetailLevel)
{
int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel);
@@ -249,25 +249,38 @@ public class LodRegion
{
for (int z = 0; z <= 1; z++)
{
if (doesDataExist(childDetailLevel, childPosX + x, childPosZ + z)) childrenCount++;
if (doesDataExist(childDetailLevel, childPosX + x, childPosZ + z))
{
if (!requireCorrectDetailLevel)
{
childrenCount++;
} else
{
getDataToRender(posToRender, childDetailLevel, childPosX + x, childPosZ + z, playerPosX, playerPosZ, requireCorrectDetailLevel);
}
}
}
}
//If all the four children exist we go deeper
if (childrenCount == 4)
if(!requireCorrectDetailLevel)
{
for (int x = 0; x <= 1; x++)
if (childrenCount == 4)
{
for (int z = 0; z <= 1; z++)
for (int x = 0; x <= 1; x++)
{
getDataToRender(posToRender, childDetailLevel, childPosX + x, childPosZ + z, playerPosX, playerPosZ);
for (int z = 0; z <= 1; z++)
{
getDataToRender(posToRender, childDetailLevel, childPosX + x, childPosZ + z, playerPosX, playerPosZ, requireCorrectDetailLevel);
}
}
} else
{
posToRender.addPosToRender(detailLevel,
posX + regionPosX * size,
posZ + regionPosZ * size);
}
} else
{
posToRender.addPosToRender(detailLevel,
posX + regionPosX * size,
posZ + regionPosZ * size);
}
}
}
@@ -20,7 +20,7 @@ public class PosToRenderContainer
private int numberOfPosToRender;
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)
{
@@ -30,7 +30,7 @@ public class PosToRenderContainer
this.regionPosZ = regionPosZ;
this.size = 1 << (LodUtil.REGION_DETAIL_LEVEL - minDetail);
posToRender = new int[size*size*3];
population = new byte[size*size];
population = new byte[size][size];
}
public void addPosToRender(byte detailLevel, int posX, int posZ)
@@ -53,16 +53,16 @@ public class PosToRenderContainer
posToRender[numberOfPosToRender*3 + 1] = posX;
posToRender[numberOfPosToRender*3 + 2] = posZ;
numberOfPosToRender++;
population[LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posX,minDetail))*size +
LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posZ,minDetail))] = (byte) (detailLevel + 1);
population[LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posX,minDetail))]
[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)) * size +
LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posZ,minDetail))] == (detailLevel + 1));
return (population[LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posX,minDetail))]
[LevelPosUtil.getRegionModule(minDetail, LevelPosUtil.convert(detailLevel,posZ,minDetail))] == (detailLevel + 1));
}else
{
return false;
@@ -75,12 +75,13 @@ public class PosToRenderContainer
if(this.minDetail == minDetail)
{
Arrays.fill(posToRender, 0);
Arrays.fill(population, (byte) 0);
for(int i = 0; i< population.length; i++)
Arrays.fill(population[i], (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];
population = new byte[size][size];
}
}