Added spiral generation, changed how some arrays are created

This commit is contained in:
Leonardo
2021-09-21 18:12:15 +02:00
parent 8228a3b7a6
commit 46bdf5763f
9 changed files with 169 additions and 102 deletions
+2
View File
@@ -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();
}
*/
}
}
@@ -264,6 +264,7 @@ public class LodBuilder
} catch (Exception e)
{
e.printStackTrace();
throw e;
}
}
@@ -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)
@@ -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;
@@ -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');
@@ -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');
@@ -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++)
{
@@ -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;
}
@@ -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);
}