chunk data storage dimension change

This commit is contained in:
austin 2024-11-11 11:08:22 -05:00
parent 1b5d6c1795
commit 4f2fcc62c9
11 changed files with 219 additions and 265 deletions

View File

@ -988,6 +988,9 @@ Two layer destruction optimization
Non-reallocating list iteration for children in draw cell manager optimization Non-reallocating list iteration for children in draw cell manager optimization
Split leaf/nonleaf tracks for node evaluation optimization Split leaf/nonleaf tracks for node evaluation optimization
(11/11/2024)
Chunk data now stored/transmitted in 17 dim instead of 16 dim (Thereby cutting down on network/storage cost)
# TODO # TODO

View File

@ -310,9 +310,9 @@ public class FluidCellManager {
private void queueNewCells(){ private void queueNewCells(){
if(Globals.playerEntity != null && Globals.clientWorldData != null){ if(Globals.playerEntity != null && Globals.clientWorldData != null){
Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity); Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity);
for(int x = -(int)drawRadius; x < drawRadius; x = x + ChunkData.CHUNK_SIZE){ for(int x = -(int)drawRadius; x < drawRadius; x = x + ChunkData.CHUNK_DATA_SIZE){
for(int y = -(int)drawRadius; y < drawRadius; y = y + ChunkData.CHUNK_SIZE){ for(int y = -(int)drawRadius; y < drawRadius; y = y + ChunkData.CHUNK_DATA_SIZE){
for(int z = -(int)drawRadius; z < drawRadius; z = z + ChunkData.CHUNK_SIZE){ for(int z = -(int)drawRadius; z < drawRadius; z = z + ChunkData.CHUNK_DATA_SIZE){
Vector3d newPos = new Vector3d(playerPos.x + x, playerPos.y + y, playerPos.z + z); Vector3d newPos = new Vector3d(playerPos.x + x, playerPos.y + y, playerPos.z + z);
Vector3i worldPos = new Vector3i( Vector3i worldPos = new Vector3i(
Globals.clientWorldData.convertRealToChunkSpace(newPos.x), Globals.clientWorldData.convertRealToChunkSpace(newPos.x),

View File

@ -128,9 +128,9 @@ public class FoliageChunk {
if(data == null){ if(data == null){
return false; return false;
} }
for(int x = 0; x < ChunkData.CHUNK_SIZE; x++){ for(int x = 0; x < ChunkData.CHUNK_DATA_SIZE; x++){
for(int y = 0; y < ChunkData.CHUNK_SIZE; y++){ for(int y = 0; y < ChunkData.CHUNK_DATA_SIZE; y++){
for(int z = 0; z < ChunkData.CHUNK_SIZE; z++){ for(int z = 0; z < ChunkData.CHUNK_DATA_SIZE; z++){
List<String> foliageTypesSupported = Globals.gameConfigCurrent.getVoxelData().getTypeFromId(data.getType(new Vector3i(x,y,z))).getAmbientFoliage(); List<String> foliageTypesSupported = Globals.gameConfigCurrent.getVoxelData().getTypeFromId(data.getType(new Vector3i(x,y,z))).getAmbientFoliage();
if(foliageTypesSupported != null && foliageTypesSupported.size() > 0){ if(foliageTypesSupported != null && foliageTypesSupported.size() > 0){
return true; return true;
@ -167,9 +167,9 @@ public class FoliageChunk {
//do creations //do creations
container.getChildren().forEach(child -> { container.getChildren().forEach(child -> {
Vector3d realPos = new Vector3d( Vector3d realPos = new Vector3d(
worldPos.x * ChunkData.CHUNK_SIZE + child.getMinBound().x, worldPos.x * ChunkData.CHUNK_DATA_SIZE + child.getMinBound().x,
worldPos.y * ChunkData.CHUNK_SIZE + child.getMinBound().y, worldPos.y * ChunkData.CHUNK_DATA_SIZE + child.getMinBound().y,
worldPos.z * ChunkData.CHUNK_SIZE + child.getMinBound().z worldPos.z * ChunkData.CHUNK_DATA_SIZE + child.getMinBound().z
); );
child.convertToLeaf(new FoliageCell(worldPos, child.getMinBound(), realPos, 5 - child.getLevel())); child.convertToLeaf(new FoliageCell(worldPos, child.getMinBound(), realPos, 5 - child.getLevel()));
}); });

View File

@ -22,10 +22,10 @@ public class ChunkData {
*/ */
public static final int NOT_HOMOGENOUS = -1; public static final int NOT_HOMOGENOUS = -1;
//The size of a chunk in virtual data /**
public static final int CHUNK_SIZE = ServerTerrainChunk.CHUNK_DIMENSION; * The size of the chunk data stored on the client
//The size of the data passed into marching cubes/transvoxel algorithm to get a fully connected and seamless chunk */
public static final int CHUNK_DATA_GENERATOR_SIZE = ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; public static final int CHUNK_DATA_SIZE = ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE;
//What type of terrain is in this voxel, eg stone vs dirt vs grass, etc //What type of terrain is in this voxel, eg stone vs dirt vs grass, etc
int[][][] voxelType; int[][][] voxelType;
@ -93,9 +93,9 @@ public class ChunkData {
public void setVoxelType(int[][][] voxelType){ public void setVoxelType(int[][][] voxelType){
//mark changed cells //mark changed cells
if(this.voxelType != null){ if(this.voxelType != null){
for(int x = 0; x < CHUNK_SIZE; x++){ for(int x = 0; x < CHUNK_DATA_SIZE; x++){
for(int y = 0; y < CHUNK_SIZE; y++){ for(int y = 0; y < CHUNK_DATA_SIZE; y++){
for(int z = 0; z < CHUNK_SIZE; z++){ for(int z = 0; z < CHUNK_DATA_SIZE; z++){
if(voxelType[x][y][z] != this.voxelType[x][y][z]){ if(voxelType[x][y][z] != this.voxelType[x][y][z]){
String key = getVoxelPositionKey(new Vector3i(x,y,z)); String key = getVoxelPositionKey(new Vector3i(x,y,z));
if(!modifiedSinceLastGeneration.contains(key)){ if(!modifiedSinceLastGeneration.contains(key)){
@ -125,9 +125,9 @@ public class ChunkData {
public void setVoxelWeight(float[][][] voxelWeight){ public void setVoxelWeight(float[][][] voxelWeight){
//mark changed cells //mark changed cells
if(this.voxelWeight != null){ if(this.voxelWeight != null){
for(int x = 0; x < CHUNK_SIZE; x++){ for(int x = 0; x < CHUNK_DATA_SIZE; x++){
for(int y = 0; y < CHUNK_SIZE; y++){ for(int y = 0; y < CHUNK_DATA_SIZE; y++){
for(int z = 0; z < CHUNK_SIZE; z++){ for(int z = 0; z < CHUNK_DATA_SIZE; z++){
if(voxelWeight[x][y][z] != this.voxelWeight[x][y][z]){ if(voxelWeight[x][y][z] != this.voxelWeight[x][y][z]){
String key = getVoxelPositionKey(new Vector3i(x,y,z)); String key = getVoxelPositionKey(new Vector3i(x,y,z));
if(!modifiedSinceLastGeneration.contains(key)){ if(!modifiedSinceLastGeneration.contains(key)){

View File

@ -801,27 +801,21 @@ public class ClientDrawCellManager {
DrawCell cell = node.getData(); DrawCell cell = node.getData();
int lod = this.chunkTree.getMaxLevel() - node.getLevel(); int lod = this.chunkTree.getMaxLevel() - node.getLevel();
int spacingFactor = (int)Math.pow(2,lod); int spacingFactor = (int)Math.pow(2,lod);
for(int i = 0; i < 2; i++){ Vector3i worldPos = node.getMinBound();
for(int j = 0; j < 2; j++){ if(
for(int k = 0; k < 2; k++){ worldPos.x >= 0 &&
Vector3i posToCheck = new Vector3i(cell.getWorldPos()).add(i*spacingFactor,j*spacingFactor,k*spacingFactor); worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() &&
if( worldPos.y >= 0 &&
posToCheck.x >= 0 && worldPos.y < Globals.clientWorldData.getWorldDiscreteSize() &&
posToCheck.x < Globals.clientWorldData.getWorldDiscreteSize() && worldPos.z >= 0 &&
posToCheck.y >= 0 && worldPos.z < Globals.clientWorldData.getWorldDiscreteSize() &&
posToCheck.y < Globals.clientWorldData.getWorldDiscreteSize() && !Globals.clientTerrainManager.containsChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z, lod)
posToCheck.z >= 0 && ){
posToCheck.z < Globals.clientWorldData.getWorldDiscreteSize() && //client should request chunk data from server for each chunk necessary to create the model
!Globals.clientTerrainManager.containsChunkDataAtWorldPoint(posToCheck.x, posToCheck.y, posToCheck.z, lod) LoggerInterface.loggerNetworking.DEBUG("(Client) Send Request for terrain at " + worldPos);
){ if(!Globals.clientTerrainManager.requestChunk(worldPos.x, worldPos.y, worldPos.z, lod)){
//client should request chunk data from server for each chunk necessary to create the model return false;
LoggerInterface.loggerNetworking.DEBUG("(Client) Send Request for terrain at " + posToCheck);
if(!Globals.clientTerrainManager.requestChunk(posToCheck.x, posToCheck.y, posToCheck.z, lod)){
return false;
}
}
} }
}
} }
int highResLod = this.chunkTree.getMaxLevel() - (node.getLevel() + 1); int highResLod = this.chunkTree.getMaxLevel() - (node.getLevel() + 1);
int highResSpacingFactor = (int)Math.pow(2,highResLod); int highResSpacingFactor = (int)Math.pow(2,highResLod);
@ -883,31 +877,17 @@ public class ClientDrawCellManager {
DrawCell cell = node.getData(); DrawCell cell = node.getData();
int lod = this.chunkTree.getMaxLevel() - node.getLevel(); int lod = this.chunkTree.getMaxLevel() - node.getLevel();
int spacingFactor = (int)Math.pow(2,lod); int spacingFactor = (int)Math.pow(2,lod);
for(int i = 0; i < 2; i++){ Vector3i worldPos = cell.getWorldPos();
for(int j = 0; j < 2; j++){ if(!Globals.clientTerrainManager.containsChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z, lod)){
for(int k = 0; k < 2; k++){ return false;
Vector3i posToCheck = new Vector3i(cell.getWorldPos()).add(i*spacingFactor,j*spacingFactor,k*spacingFactor);
if(
posToCheck.x >= 0 &&
posToCheck.x < Globals.clientWorldData.getWorldDiscreteSize() &&
posToCheck.y >= 0 &&
posToCheck.y < Globals.clientWorldData.getWorldDiscreteSize() &&
posToCheck.z >= 0 &&
posToCheck.z < Globals.clientWorldData.getWorldDiscreteSize() &&
!Globals.clientTerrainManager.containsChunkDataAtWorldPoint(posToCheck.x, posToCheck.y, posToCheck.z, lod)
){
return false;
}
}
}
} }
int highResLod = this.chunkTree.getMaxLevel() - (node.getLevel() + 1); int highResLod = this.chunkTree.getMaxLevel() - (node.getLevel() + 1);
int highResSpacingFactor = (int)Math.pow(2,highResLod); int highResSpacingFactor = (int)Math.pow(2,highResLod);
if(highResFaces != null){ if(highResFaces != null){
for(DrawCellFace highResFace : highResFaces){ for(DrawCellFace highResFace : highResFaces){
//x & y are in face-space //x & y are in face-space
for(int x = 0; x < 3; x++){ for(int x = 0; x < 2; x++){
for(int y = 0; y < 3; y++){ for(int y = 0; y < 2; y++){
Vector3i posToCheck = null; Vector3i posToCheck = null;
//implicitly performing transforms to adapt from face-space to world space //implicitly performing transforms to adapt from face-space to world space
switch(highResFace){ switch(highResFace){

View File

@ -14,6 +14,7 @@ import electrosphere.entity.Entity;
import electrosphere.entity.types.terrain.TerrainChunk; import electrosphere.entity.types.terrain.TerrainChunk;
import electrosphere.renderer.meshgen.TransvoxelModelGeneration; import electrosphere.renderer.meshgen.TransvoxelModelGeneration;
import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData; import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
import electrosphere.util.ds.octree.WorldOctTree.FloatingChunkTreeNode; import electrosphere.util.ds.octree.WorldOctTree.FloatingChunkTreeNode;
import electrosphere.util.math.GeomUtils; import electrosphere.util.math.GeomUtils;
@ -47,8 +48,8 @@ public class DrawCell {
Entity modelEntity; Entity modelEntity;
//Allocated once instead of continuously, used to generate the visual/physics models //Allocated once instead of continuously, used to generate the visual/physics models
float[][][] weights = new float[ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE]; float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
int[][][] types = new int[ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE]; int[][][] types = new int[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
/** /**
* Tracks whether the draw cell has requested its chunk data or not * Tracks whether the draw cell has requested its chunk data or not
@ -81,11 +82,6 @@ public class DrawCell {
*/ */
int failedGenerationAttempts = 0; int failedGenerationAttempts = 0;
/**
* The number of valid fill lookups
*/
int validLookups = 0;
/** /**
* Labels an invalid distance cache * Labels an invalid distance cache
*/ */
@ -145,7 +141,7 @@ public class DrawCell {
} }
} }
modelEntity = TerrainChunk.clientCreateTerrainChunkEntity(chunkData, lod, atlas, this.hasPolygons()); modelEntity = TerrainChunk.clientCreateTerrainChunkEntity(chunkData, lod, atlas, this.hasPolygons());
ClientEntityUtils.initiallyPositionEntity(modelEntity, getRealPos(), new Quaterniond()); ClientEntityUtils.initiallyPositionEntity(modelEntity, this.getRealPos(), new Quaterniond());
// this.weights = null; // this.weights = null;
// this.types = null; // this.types = null;
this.setHasGenerated(true); this.setHasGenerated(true);
@ -157,9 +153,9 @@ public class DrawCell {
*/ */
protected Vector3d getRealPos(){ protected Vector3d getRealPos(){
return new Vector3d( return new Vector3d(
worldPos.x * ChunkData.CHUNK_SIZE, worldPos.x * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET,
worldPos.y * ChunkData.CHUNK_SIZE, worldPos.y * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET,
worldPos.z * ChunkData.CHUNK_SIZE worldPos.z * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET
); );
} }
@ -197,63 +193,33 @@ public class DrawCell {
*/ */
private boolean fillInData(int lod){ private boolean fillInData(int lod){
// if(lod == ClientDrawCellManager.FULL_RES_LOD){ // if(lod == ClientDrawCellManager.FULL_RES_LOD){
ChunkData homogenousLookupChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(
worldPos.x, worldPos.x,
worldPos.y, worldPos.y,
worldPos.z, worldPos.z,
lod lod
); );
if(homogenousLookupChunk != null && homogenousLookupChunk.getHomogenousValue() != ChunkData.NOT_HOMOGENOUS){ if(currentChunk == null){
return false;
}
if(currentChunk.getHomogenousValue() != ChunkData.NOT_HOMOGENOUS){
return true; return true;
} }
// } for(int x = 0; x < ChunkData.CHUNK_DATA_SIZE; x++){
int spacingFactor = (int)Math.pow(2,lod); for(int y = 0; y < ChunkData.CHUNK_DATA_SIZE; y++){
int i = 0; for(int z = 0; z < ChunkData.CHUNK_DATA_SIZE; z++){
for(int x = i / ChunkData.CHUNK_DATA_GENERATOR_SIZE / ChunkData.CHUNK_DATA_GENERATOR_SIZE; x < ChunkData.CHUNK_DATA_GENERATOR_SIZE; x++){ weights[x][y][z] = currentChunk.getWeight(
for(int y = 0; y < ChunkData.CHUNK_DATA_GENERATOR_SIZE; y++){ x,
for(int z = 0; z < ChunkData.CHUNK_DATA_GENERATOR_SIZE; z++){ y,
if(i < validLookups){ z
i++;
continue;
}
ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(
worldPos.x + (x / ChunkData.CHUNK_SIZE) * spacingFactor,
worldPos.y + (y / ChunkData.CHUNK_SIZE) * spacingFactor,
worldPos.z + (z / ChunkData.CHUNK_SIZE) * spacingFactor,
lod
); );
if(currentChunk == null){ types[x][y][z] = currentChunk.getType(
Vector3i posToCheck = new Vector3i( x,
worldPos.x + (x / ChunkData.CHUNK_SIZE) * spacingFactor, y,
worldPos.y + (y / ChunkData.CHUNK_SIZE) * spacingFactor, z
worldPos.z + (z / ChunkData.CHUNK_SIZE) * spacingFactor );
); if(currentChunk.getHomogenousValue() == ChunkData.NOT_HOMOGENOUS){
if( this.homogenous = false;
posToCheck.x >= 0 &&
posToCheck.x < Globals.clientWorldData.getWorldDiscreteSize() &&
posToCheck.y >= 0 &&
posToCheck.y < Globals.clientWorldData.getWorldDiscreteSize() &&
posToCheck.z >= 0 &&
posToCheck.z < Globals.clientWorldData.getWorldDiscreteSize()
){
return false;
}
} else {
weights[x][y][z] = currentChunk.getWeight(
x % ChunkData.CHUNK_SIZE,
y % ChunkData.CHUNK_SIZE,
z % ChunkData.CHUNK_SIZE
);
types[x][y][z] = currentChunk.getType(
x % ChunkData.CHUNK_SIZE,
y % ChunkData.CHUNK_SIZE,
z % ChunkData.CHUNK_SIZE
);
if(currentChunk.getHomogenousValue() == ChunkData.NOT_HOMOGENOUS){
this.homogenous = false;
}
i++;
validLookups++;
} }
@ -287,11 +253,11 @@ public class DrawCell {
//allocate face array //allocate face array
for(int x = 0; x < TransvoxelModelGeneration.FACE_DATA_DIMENSIONS; x++){ for(int x = 0; x < TransvoxelModelGeneration.FACE_DATA_DIMENSIONS; x++){
for(int y = 0; y < TransvoxelModelGeneration.FACE_DATA_DIMENSIONS; y++){ for(int y = 0; y < TransvoxelModelGeneration.FACE_DATA_DIMENSIONS; y++){
int worldCoordOffset1 = x / ChunkData.CHUNK_SIZE * higherResSpacing; int worldCoordOffset1 = x / ChunkData.CHUNK_DATA_SIZE * higherResSpacing;
int worldCoordOffset2 = y / ChunkData.CHUNK_SIZE * higherResSpacing; int worldCoordOffset2 = y / ChunkData.CHUNK_DATA_SIZE * higherResSpacing;
//solve coordinates relative to the face //solve coordinates relative to the face
int localCoord1 = x % ChunkData.CHUNK_SIZE; int localCoord1 = x % ChunkData.CHUNK_DATA_SIZE;
int localCoord2 = y % ChunkData.CHUNK_SIZE; int localCoord2 = y % ChunkData.CHUNK_DATA_SIZE;
//implicitly performing transforms to adapt from face-space to world & local space //implicitly performing transforms to adapt from face-space to world & local space
switch(higherLODFace){ switch(higherLODFace){

View File

@ -360,9 +360,9 @@ public class DrawCellManager {
private void queueNewCells(){ private void queueNewCells(){
if(Globals.playerEntity != null && Globals.clientWorldData != null){ if(Globals.playerEntity != null && Globals.clientWorldData != null){
Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity); Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity);
for(int x = -(int)drawFullModelRadius; x < drawFullModelRadius; x = x + ChunkData.CHUNK_SIZE){ for(int x = -(int)drawFullModelRadius; x < drawFullModelRadius; x = x + ChunkData.CHUNK_DATA_SIZE){
for(int y = -(int)drawFullModelRadius; y < drawFullModelRadius; y = y + ChunkData.CHUNK_SIZE){ for(int y = -(int)drawFullModelRadius; y < drawFullModelRadius; y = y + ChunkData.CHUNK_DATA_SIZE){
for(int z = -(int)drawFullModelRadius; z < drawFullModelRadius; z = z + ChunkData.CHUNK_SIZE){ for(int z = -(int)drawFullModelRadius; z < drawFullModelRadius; z = z + ChunkData.CHUNK_DATA_SIZE){
Vector3d newPos = new Vector3d(playerPos.x + x, playerPos.y + y, playerPos.z + z); Vector3d newPos = new Vector3d(playerPos.x + x, playerPos.y + y, playerPos.z + z);
Vector3i worldPos = new Vector3i( Vector3i worldPos = new Vector3i(
Globals.clientWorldData.convertRealToChunkSpace(newPos.x), Globals.clientWorldData.convertRealToChunkSpace(newPos.x),

View File

@ -94,22 +94,22 @@ public class ClientTerrainManager {
for(TerrainMessage message : messageQueue){ for(TerrainMessage message : messageQueue){
switch(message.getMessageSubtype()){ switch(message.getMessageSubtype()){
case SENDCHUNKDATA: { case SENDCHUNKDATA: {
int[][][] values = new int[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE]; int[][][] values = new int[ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE];
float[][][] weights = new float[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE]; float[][][] weights = new float[ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE];
ByteBuffer buffer = ByteBuffer.wrap(message.getchunkData()); ByteBuffer buffer = ByteBuffer.wrap(message.getchunkData());
FloatBuffer floatBuffer = buffer.asFloatBuffer(); FloatBuffer floatBuffer = buffer.asFloatBuffer();
for(int x = 0; x < ChunkData.CHUNK_SIZE; x++){ for(int x = 0; x < ChunkData.CHUNK_DATA_SIZE; x++){
for(int y = 0; y < ChunkData.CHUNK_SIZE; y++){ for(int y = 0; y < ChunkData.CHUNK_DATA_SIZE; y++){
for(int z = 0; z < ChunkData.CHUNK_SIZE; z++){ for(int z = 0; z < ChunkData.CHUNK_DATA_SIZE; z++){
weights[x][y][z] = floatBuffer.get(); weights[x][y][z] = floatBuffer.get();
} }
} }
} }
IntBuffer intView = buffer.asIntBuffer(); IntBuffer intView = buffer.asIntBuffer();
intView.position(floatBuffer.position()); intView.position(floatBuffer.position());
for(int x = 0; x < ChunkData.CHUNK_SIZE; x++){ for(int x = 0; x < ChunkData.CHUNK_DATA_SIZE; x++){
for(int y = 0; y < ChunkData.CHUNK_SIZE; y++){ for(int y = 0; y < ChunkData.CHUNK_DATA_SIZE; y++){
for(int z = 0; z < ChunkData.CHUNK_SIZE; z++){ for(int z = 0; z < ChunkData.CHUNK_DATA_SIZE; z++){
values[x][y][z] = intView.get(); values[x][y][z] = intView.get();
} }
} }
@ -123,13 +123,13 @@ public class ClientTerrainManager {
); );
} break; } break;
case SENDREDUCEDCHUNKDATA: { case SENDREDUCEDCHUNKDATA: {
int[][][] values = new int[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE]; int[][][] values = new int[ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE];
float[][][] weights = new float[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE]; float[][][] weights = new float[ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE];
ByteBuffer buffer = ByteBuffer.wrap(message.getchunkData()); ByteBuffer buffer = ByteBuffer.wrap(message.getchunkData());
FloatBuffer floatBuffer = buffer.asFloatBuffer(); FloatBuffer floatBuffer = buffer.asFloatBuffer();
for(int x = 0; x < ChunkData.CHUNK_SIZE; x++){ for(int x = 0; x < ChunkData.CHUNK_DATA_SIZE; x++){
for(int y = 0; y < ChunkData.CHUNK_SIZE; y++){ for(int y = 0; y < ChunkData.CHUNK_DATA_SIZE; y++){
for(int z = 0; z < ChunkData.CHUNK_SIZE; z++){ for(int z = 0; z < ChunkData.CHUNK_DATA_SIZE; z++){
weights[x][y][z] = floatBuffer.get(); weights[x][y][z] = floatBuffer.get();
} }
} }
@ -138,9 +138,9 @@ public class ClientTerrainManager {
intView.position(floatBuffer.position()); intView.position(floatBuffer.position());
int firstType = -1; int firstType = -1;
boolean homogenous = true; boolean homogenous = true;
for(int x = 0; x < ChunkData.CHUNK_SIZE; x++){ for(int x = 0; x < ChunkData.CHUNK_DATA_SIZE; x++){
for(int y = 0; y < ChunkData.CHUNK_SIZE; y++){ for(int y = 0; y < ChunkData.CHUNK_DATA_SIZE; y++){
for(int z = 0; z < ChunkData.CHUNK_SIZE; z++){ for(int z = 0; z < ChunkData.CHUNK_DATA_SIZE; z++){
values[x][y][z] = intView.get(); values[x][y][z] = intView.get();
if(firstType == -1){ if(firstType == -1){
firstType = values[x][y][z]; firstType = values[x][y][z];

View File

@ -74,9 +74,9 @@ public class PhysicsDataCell {
fillInData(); fillInData();
Vector3d realPos = new Vector3d( Vector3d realPos = new Vector3d(
worldPos.x * ServerTerrainChunk.CHUNK_DIMENSION, worldPos.x * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET,
worldPos.y * ServerTerrainChunk.CHUNK_DIMENSION, worldPos.y * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET,
worldPos.z * ServerTerrainChunk.CHUNK_DIMENSION worldPos.z * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET
); );
physicsEntity = TerrainChunk.serverCreateTerrainChunkEntity(realm, realPos, weights, types); physicsEntity = TerrainChunk.serverCreateTerrainChunkEntity(realm, realPos, weights, types);
physicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); physicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
@ -104,125 +104,125 @@ public class PhysicsDataCell {
// //
//main chunk //main chunk
ServerTerrainChunk currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z); ServerTerrainChunk currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z);
for(int x = 0; x < ChunkData.CHUNK_SIZE; x++){ for(int x = 0; x < ChunkData.CHUNK_DATA_SIZE; x++){
for(int y = 0; y < ChunkData.CHUNK_SIZE; y++){ for(int y = 0; y < ChunkData.CHUNK_DATA_SIZE; y++){
for(int z = 0; z < ChunkData.CHUNK_SIZE; z++){ for(int z = 0; z < ChunkData.CHUNK_DATA_SIZE; z++){
weights[x][y][z] = currentChunk.getWeight(x,y,z); weights[x][y][z] = currentChunk.getWeight(x,y,z);
types[x][y][z] = currentChunk.getType(x,y,z); types[x][y][z] = currentChunk.getType(x,y,z);
} }
} }
} }
//face X // //face X
if(worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){ // if(worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){
currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z); // currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ // for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){ // for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[ChunkData.CHUNK_SIZE][i][j] = currentChunk.getWeight(0, i, j); // weights[ChunkData.CHUNK_SIZE][i][j] = currentChunk.getWeight(0, i, j);
types[ChunkData.CHUNK_SIZE][i][j] = currentChunk.getType(0, i, j); // types[ChunkData.CHUNK_SIZE][i][j] = currentChunk.getType(0, i, j);
} // }
} // }
} else { // } else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ // for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){ // for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[ChunkData.CHUNK_SIZE][i][j] = 0; // weights[ChunkData.CHUNK_SIZE][i][j] = 0;
types[ChunkData.CHUNK_SIZE][i][j] = 0; // types[ChunkData.CHUNK_SIZE][i][j] = 0;
} // }
} // }
} // }
//face Y // //face Y
if(worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){ // if(worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){
currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z); // currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ // for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){ // for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[i][ChunkData.CHUNK_SIZE][j] = currentChunk.getWeight(i, 0, j); // weights[i][ChunkData.CHUNK_SIZE][j] = currentChunk.getWeight(i, 0, j);
types[i][ChunkData.CHUNK_SIZE][j] = currentChunk.getType(i, 0, j); // types[i][ChunkData.CHUNK_SIZE][j] = currentChunk.getType(i, 0, j);
} // }
} // }
} else { // } else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ // for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){ // for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[i][ChunkData.CHUNK_SIZE][j] = 0; // weights[i][ChunkData.CHUNK_SIZE][j] = 0;
types[i][ChunkData.CHUNK_SIZE][j] = 0; // types[i][ChunkData.CHUNK_SIZE][j] = 0;
} // }
} // }
} // }
//face Z // //face Z
if(worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){ // if(worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){
currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z + 1); // currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z + 1);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ // for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){ // for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[i][j][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(i, j, 0); // weights[i][j][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(i, j, 0);
types[i][j][ChunkData.CHUNK_SIZE] = currentChunk.getType(i, j, 0); // types[i][j][ChunkData.CHUNK_SIZE] = currentChunk.getType(i, j, 0);
} // }
} // }
} else { // } else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ // for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){ // for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[i][j][ChunkData.CHUNK_SIZE] = 0; // weights[i][j][ChunkData.CHUNK_SIZE] = 0;
types[i][j][ChunkData.CHUNK_SIZE] = 0; // types[i][j][ChunkData.CHUNK_SIZE] = 0;
} // }
} // }
} // }
//edge X-Y //edge X-Y
if( // if(
worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete() && // worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete() // worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete()
){ // ){
currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z); // currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ // for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = currentChunk.getWeight(0, 0, i); // weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = currentChunk.getWeight(0, 0, i);
types [ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = currentChunk.getType(0, 0, i); // types [ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = currentChunk.getType(0, 0, i);
} // }
} else { // } else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ // for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = 0; // weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = 0;
types [ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = 0; // types [ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = 0;
} // }
} // }
//edge X-Z // //edge X-Z
if( // if(
worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete() && // worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete() // worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete()
){ // ){
currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z + 1); // currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z + 1);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ // for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(0, i, 0); // weights[ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(0, i, 0);
types [ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = currentChunk.getType(0, i, 0); // types [ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = currentChunk.getType(0, i, 0);
} // }
} else { // } else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ // for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = 0; // weights[ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = 0;
types [ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = 0; // types [ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = 0;
} // }
} // }
//edge Y-Z // //edge Y-Z
if( // if(
worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete() && // worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete() // worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete()
){ // ){
currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z + 1); // currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z + 1);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ // for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(i, 0, 0); // weights[i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(i, 0, 0);
types [i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getType(i, 0, 0); // types [i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getType(i, 0, 0);
} // }
} else { // } else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){ // for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0; // weights[i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
types [i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0; // types [i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
} // }
} // }
if( // if(
worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete() && // worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete() && // worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete() // worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete()
){ // ){
currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z + 1); // currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z + 1);
weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(0, 0, 0); // weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(0, 0, 0);
types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getType(0, 0, 0); // types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getType(0, 0, 0);
} else { // } else {
weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0; // weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0; // types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
} // }
} }
} }

View File

@ -93,8 +93,8 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
public ServerTerrainChunk generateChunk(int worldX, int worldY, int worldZ, int stride) { public ServerTerrainChunk generateChunk(int worldX, int worldY, int worldZ, int stride) {
Globals.profiler.beginAggregateCpuSample("TestGenerationChunkGenerator.generateChunk"); Globals.profiler.beginAggregateCpuSample("TestGenerationChunkGenerator.generateChunk");
ServerTerrainChunk rVal = null; ServerTerrainChunk rVal = null;
float[][][] weights = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION];; float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];;
int[][][] values = new int[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION]; int[][][] values = new int[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
int firstType = -1; int firstType = -1;
boolean homogenous = true; boolean homogenous = true;
@ -114,9 +114,9 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
int strideValue = (int)Math.pow(2,stride); int strideValue = (int)Math.pow(2,stride);
//presolve heightfield //presolve heightfield
float[][] heightfield = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION]; float[][] heightfield = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){ for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){ for(int z = 0; z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; z++){
int finalWorldX = worldX + ((x * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); int finalWorldX = worldX + ((x * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION);
int finalWorldZ = worldZ + ((z * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); int finalWorldZ = worldZ + ((z * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION);
int finalChunkX = (x * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION; int finalChunkX = (x * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION;
@ -159,10 +159,10 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
// } // }
// }); // });
} else { } else {
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){ for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){
Globals.profiler.beginAggregateCpuSample("TestGenerationChunkGenerator - Generate slice"); Globals.profiler.beginAggregateCpuSample("TestGenerationChunkGenerator - Generate slice");
for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){ for(int y = 0; y < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; y++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){ for(int z = 0; z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; z++){
int finalWorldX = worldX + ((x * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); int finalWorldX = worldX + ((x * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION);
int finalWorldY = worldY + ((y * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); int finalWorldY = worldY + ((y * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION);
int finalWorldZ = worldZ + ((z * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); int finalWorldZ = worldZ + ((z * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION);

View File

@ -22,6 +22,11 @@ public class ServerTerrainChunk {
*/ */
public static final int CHUNK_DATA_GENERATOR_SIZE = CHUNK_DIMENSION + 1; public static final int CHUNK_DATA_GENERATOR_SIZE = CHUNK_DIMENSION + 1;
/**
* The units that should be used when placing chunks in the scene
*/
public static final int CHUNK_PLACEMENT_OFFSET = CHUNK_DATA_GENERATOR_SIZE - 1;
/** /**
* Gets the x coordinate of the world position of the chunk * Gets the x coordinate of the world position of the chunk
*/ */