From c045c0a0d40f5ef69a302ea261afda71447d9981 Mon Sep 17 00:00:00 2001 From: austin Date: Wed, 6 Nov 2024 14:18:47 -0500 Subject: [PATCH] Strided terrain data --- .../terrain/cells/ClientDrawCellManager.java | 86 ++-- .../client/terrain/cells/DrawCell.java | 391 +++++++++--------- .../meshgen/TransvoxelModelGeneration.java | 4 +- 3 files changed, 243 insertions(+), 238 deletions(-) diff --git a/src/main/java/electrosphere/client/terrain/cells/ClientDrawCellManager.java b/src/main/java/electrosphere/client/terrain/cells/ClientDrawCellManager.java index 8db77ca5..311ab8a5 100644 --- a/src/main/java/electrosphere/client/terrain/cells/ClientDrawCellManager.java +++ b/src/main/java/electrosphere/client/terrain/cells/ClientDrawCellManager.java @@ -548,48 +548,50 @@ public class ClientDrawCellManager { } } } - // if(highResFaces != null){ - // for(DrawCellFace highResFace : highResFaces){ - // //x & y are in face-space - // for(int x = 0; x < 4; x++){ - // for(int y = 0; y < 4; y++){ - // Vector3i posToCheck = null; - // //implicitly performing transforms to adapt from face-space to world space - // switch(highResFace){ - // case X_POSITIVE: { - // posToCheck = new Vector3i(cell.getWorldPos()).add(lodMultiplitier,x,y); - // } break; - // case X_NEGATIVE: { - // posToCheck = new Vector3i(cell.getWorldPos()).add(-1,x,y); - // } break; - // case Y_POSITIVE: { - // posToCheck = new Vector3i(cell.getWorldPos()).add(x,lodMultiplitier,y); - // } break; - // case Y_NEGATIVE: { - // posToCheck = new Vector3i(cell.getWorldPos()).add(x,-1,y); - // } break; - // case Z_POSITIVE: { - // posToCheck = new Vector3i(cell.getWorldPos()).add(x,y,lodMultiplitier); - // } break; - // case Z_NEGATIVE: { - // posToCheck = new Vector3i(cell.getWorldPos()).add(x,y,-1); - // } break; - // } - // 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, ChunkData.NO_STRIDE) - // ){ - // return false; - // } - // } - // } - // } - // } + int highResLod = this.chunkTree.getMaxLevel() - (node.getLevel() + 1); + int highResSpacingFactor = (int)Math.pow(2,highResLod); + if(highResFaces != null){ + for(DrawCellFace highResFace : highResFaces){ + //x & y are in face-space + for(int x = 0; x < 3; x++){ + for(int y = 0; y < 3; y++){ + Vector3i posToCheck = null; + //implicitly performing transforms to adapt from face-space to world space + switch(highResFace){ + case X_POSITIVE: { + posToCheck = new Vector3i(cell.getWorldPos()).add(spacingFactor,x*highResSpacingFactor,y*highResSpacingFactor); + } break; + case X_NEGATIVE: { + posToCheck = new Vector3i(cell.getWorldPos()).add(0,x*highResSpacingFactor,y*highResSpacingFactor); + } break; + case Y_POSITIVE: { + posToCheck = new Vector3i(cell.getWorldPos()).add(x*highResSpacingFactor,spacingFactor,y*highResSpacingFactor); + } break; + case Y_NEGATIVE: { + posToCheck = new Vector3i(cell.getWorldPos()).add(x*highResSpacingFactor,0,y*highResSpacingFactor); + } break; + case Z_POSITIVE: { + posToCheck = new Vector3i(cell.getWorldPos()).add(x*highResSpacingFactor,y*highResSpacingFactor,spacingFactor); + } break; + case Z_NEGATIVE: { + posToCheck = new Vector3i(cell.getWorldPos()).add(x*highResSpacingFactor,y*highResSpacingFactor,0); + } break; + } + 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, highResLod) + ){ + return false; + } + } + } + } + } return true; } diff --git a/src/main/java/electrosphere/client/terrain/cells/DrawCell.java b/src/main/java/electrosphere/client/terrain/cells/DrawCell.java index d80f7f91..9e09ccbc 100644 --- a/src/main/java/electrosphere/client/terrain/cells/DrawCell.java +++ b/src/main/java/electrosphere/client/terrain/cells/DrawCell.java @@ -12,7 +12,9 @@ import electrosphere.engine.Globals; import electrosphere.entity.ClientEntityUtils; import electrosphere.entity.Entity; import electrosphere.entity.types.terrain.TerrainChunk; +import electrosphere.renderer.meshgen.TransvoxelModelGeneration; import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData; +import electrosphere.server.terrain.manager.ServerTerrainChunk; /** * A single drawcell - contains an entity that has a physics mesh and potentially graphics @@ -232,201 +234,202 @@ public class DrawCell { * @return true if successfully filled in data, false otherwise */ private boolean fillInFaceData(TransvoxelChunkData chunkData, DrawCellFace higherLODFace, int lod){ - // int mainSpacing = (int)Math.pow(2,lod); - // int higherResSpacing = (int)Math.pow(2,lod - 1); - // float[][] faceWeights = new float[TransvoxelModelGeneration.FACE_DATA_DIMENSIONS][TransvoxelModelGeneration.FACE_DATA_DIMENSIONS]; - // int[][] faceTypes = new int[TransvoxelModelGeneration.FACE_DATA_DIMENSIONS][TransvoxelModelGeneration.FACE_DATA_DIMENSIONS]; - // //allocate face array - // for(int x = 0; x < TransvoxelModelGeneration.FACE_DATA_DIMENSIONS; x++){ - // for(int y = 0; y < TransvoxelModelGeneration.FACE_DATA_DIMENSIONS; y++){ - // int worldCoordOffset1 = (x * higherResSpacing) / ChunkData.CHUNK_SIZE; - // int worldCoordOffset2 = (y * higherResSpacing) / ChunkData.CHUNK_SIZE; - // //solve coordinates relative to the face - // int localCoord1 = (x * higherResSpacing) % ChunkData.CHUNK_SIZE; - // int localCoord2 = (y * higherResSpacing) % ChunkData.CHUNK_SIZE; + int mainSpacing = (int)Math.pow(2,lod); + int higherLOD = lod - 1; + int higherResSpacing = (int)Math.pow(2,higherLOD); + float[][] faceWeights = new float[TransvoxelModelGeneration.FACE_DATA_DIMENSIONS][TransvoxelModelGeneration.FACE_DATA_DIMENSIONS]; + int[][] faceTypes = new int[TransvoxelModelGeneration.FACE_DATA_DIMENSIONS][TransvoxelModelGeneration.FACE_DATA_DIMENSIONS]; + //allocate face array + for(int x = 0; x < TransvoxelModelGeneration.FACE_DATA_DIMENSIONS; x++){ + for(int y = 0; y < TransvoxelModelGeneration.FACE_DATA_DIMENSIONS; y++){ + int worldCoordOffset1 = x / ChunkData.CHUNK_SIZE * higherResSpacing; + int worldCoordOffset2 = y / ChunkData.CHUNK_SIZE * higherResSpacing; + //solve coordinates relative to the face + int localCoord1 = x % ChunkData.CHUNK_SIZE; + int localCoord2 = y % ChunkData.CHUNK_SIZE; - // //implicitly performing transforms to adapt from face-space to world & local space - // switch(higherLODFace){ - // case X_POSITIVE: { - // ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( - // new Vector3i( - // worldPos.x + (17 * mainSpacing) / ChunkData.CHUNK_SIZE, - // worldPos.y + worldCoordOffset1, - // worldPos.z + worldCoordOffset2 - // ), - // ChunkData.NO_STRIDE - // ); - // if(currentChunk == null){ - // return false; - // } - // faceWeights[x][y] = currentChunk.getWeight( - // 0, - // localCoord1, - // localCoord2 - // ); - // faceTypes[x][y] = currentChunk.getType( - // 0, - // localCoord1, - // localCoord2 - // ); - // } break; - // case X_NEGATIVE: { - // ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( - // new Vector3i( - // worldPos.x, - // worldPos.y + worldCoordOffset1, - // worldPos.z + worldCoordOffset2 - // ), - // ChunkData.NO_STRIDE - // ); - // if(currentChunk == null){ - // return false; - // } - // faceWeights[x][y] = currentChunk.getWeight( - // 0, - // localCoord1, - // localCoord2 - // ); - // faceTypes[x][y] = currentChunk.getType( - // 0, - // localCoord1, - // localCoord2 - // ); - // } break; - // case Y_POSITIVE: { - // ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( - // new Vector3i( - // worldPos.x + worldCoordOffset1, - // worldPos.y + (17 * mainSpacing) / ChunkData.CHUNK_SIZE, - // worldPos.z + worldCoordOffset2 - // ), - // ChunkData.NO_STRIDE - // ); - // if(currentChunk == null){ - // return false; - // } - // faceWeights[x][y] = currentChunk.getWeight( - // localCoord1, - // 0, - // localCoord2 - // ); - // faceTypes[x][y] = currentChunk.getType( - // localCoord1, - // 0, - // localCoord2 - // ); - // } break; - // case Y_NEGATIVE: { - // ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( - // new Vector3i( - // worldPos.x + worldCoordOffset1, - // worldPos.y, - // worldPos.z + worldCoordOffset2 - // ), - // ChunkData.NO_STRIDE - // ); - // if(currentChunk == null){ - // return false; - // } - // faceWeights[x][y] = currentChunk.getWeight( - // localCoord1, - // 0, - // localCoord2 - // ); - // faceTypes[x][y] = currentChunk.getType( - // localCoord1, - // 0, - // localCoord2 - // ); - // } break; - // case Z_POSITIVE: { - // ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( - // new Vector3i( - // worldPos.x + worldCoordOffset1, - // worldPos.y + worldCoordOffset2, - // worldPos.z + (17 * mainSpacing) / ChunkData.CHUNK_SIZE - // ), - // ChunkData.NO_STRIDE - // ); - // if(currentChunk == null){ - // return false; - // } - // faceWeights[x][y] = currentChunk.getWeight( - // localCoord1, - // localCoord2, - // 0 - // ); - // faceTypes[x][y] = currentChunk.getType( - // localCoord1, - // localCoord2, - // 0 - // ); - // } break; - // case Z_NEGATIVE: { - // ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( - // new Vector3i( - // worldPos.x + worldCoordOffset1, - // worldPos.y + worldCoordOffset2, - // worldPos.z - // ), - // ChunkData.NO_STRIDE - // ); - // if(currentChunk == null){ - // return false; - // } - // faceWeights[x][y] = currentChunk.getWeight( - // localCoord1, - // localCoord2, - // 0 - // ); - // faceTypes[x][y] = currentChunk.getType( - // localCoord1, - // localCoord2, - // 0 - // ); - // } break; - // } - // // Vector3i sampleChunkWorldPos = new Vector3i( - // // worldPos.x + (x * higherResSpacing) / ChunkData.CHUNK_SIZE, - // // worldPos.y + (y * higherResSpacing) / ChunkData.CHUNK_SIZE, - // // worldPos.z + (z * spacingFactor) / ChunkData.CHUNK_SIZE - // // ); - // // ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(sampleChunkWorldPos); - // // if(currentChunk == null){ - // // throw new Error("Chunk is null! " + worldPos); - // // } - // // weights[x][y][z] = currentChunk.getWeight( - // // (x * higherResSpacing) % ChunkData.CHUNK_SIZE, - // // (y * higherResSpacing) % ChunkData.CHUNK_SIZE, - // // (z * spacingFactor) % ChunkData.CHUNK_SIZE - // // ); - // // types[x][y][z] = currentChunk.getType( - // // (x * higherResSpacing) % ChunkData.CHUNK_SIZE, - // // (y * higherResSpacing) % ChunkData.CHUNK_SIZE, - // // (z * spacingFactor) % ChunkData.CHUNK_SIZE - // // ); - // } - // } - // switch(higherLODFace){ - // case X_POSITIVE: { - // chunkData.addXPositiveEdge(faceWeights, faceTypes); - // } break; - // case X_NEGATIVE: { - // chunkData.addXNegativeEdge(faceWeights, faceTypes); - // } break; - // case Y_POSITIVE: { - // chunkData.addYPositiveEdge(faceWeights, faceTypes); - // } break; - // case Y_NEGATIVE: { - // chunkData.addYNegativeEdge(faceWeights, faceTypes); - // } break; - // case Z_POSITIVE: { - // chunkData.addZPositiveEdge(faceWeights, faceTypes); - // } break; - // case Z_NEGATIVE: { - // chunkData.addZNegativeEdge(faceWeights, faceTypes); - // } break; - // } + //implicitly performing transforms to adapt from face-space to world & local space + switch(higherLODFace){ + case X_POSITIVE: { + ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( + new Vector3i( + worldPos.x + mainSpacing, + worldPos.y + worldCoordOffset1, + worldPos.z + worldCoordOffset2 + ), + higherLOD + ); + if(currentChunk == null){ + return false; + } + faceWeights[x][y] = currentChunk.getWeight( + 0, + localCoord1, + localCoord2 + ); + faceTypes[x][y] = currentChunk.getType( + 0, + localCoord1, + localCoord2 + ); + } break; + case X_NEGATIVE: { + ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( + new Vector3i( + worldPos.x, + worldPos.y + worldCoordOffset1, + worldPos.z + worldCoordOffset2 + ), + higherLOD + ); + if(currentChunk == null){ + return false; + } + faceWeights[x][y] = currentChunk.getWeight( + 0, + localCoord1, + localCoord2 + ); + faceTypes[x][y] = currentChunk.getType( + 0, + localCoord1, + localCoord2 + ); + } break; + case Y_POSITIVE: { + ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( + new Vector3i( + worldPos.x + worldCoordOffset1, + worldPos.y + mainSpacing, + worldPos.z + worldCoordOffset2 + ), + higherLOD + ); + if(currentChunk == null){ + return false; + } + faceWeights[x][y] = currentChunk.getWeight( + localCoord1, + 0, + localCoord2 + ); + faceTypes[x][y] = currentChunk.getType( + localCoord1, + 0, + localCoord2 + ); + } break; + case Y_NEGATIVE: { + ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( + new Vector3i( + worldPos.x + worldCoordOffset1, + worldPos.y, + worldPos.z + worldCoordOffset2 + ), + higherLOD + ); + if(currentChunk == null){ + return false; + } + faceWeights[x][y] = currentChunk.getWeight( + localCoord1, + 0, + localCoord2 + ); + faceTypes[x][y] = currentChunk.getType( + localCoord1, + 0, + localCoord2 + ); + } break; + case Z_POSITIVE: { + ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( + new Vector3i( + worldPos.x + worldCoordOffset1, + worldPos.y + worldCoordOffset2, + worldPos.z + mainSpacing + ), + higherLOD + ); + if(currentChunk == null){ + return false; + } + faceWeights[x][y] = currentChunk.getWeight( + localCoord1, + localCoord2, + 0 + ); + faceTypes[x][y] = currentChunk.getType( + localCoord1, + localCoord2, + 0 + ); + } break; + case Z_NEGATIVE: { + ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( + new Vector3i( + worldPos.x + worldCoordOffset1, + worldPos.y + worldCoordOffset2, + worldPos.z + ), + higherLOD + ); + if(currentChunk == null){ + return false; + } + faceWeights[x][y] = currentChunk.getWeight( + localCoord1, + localCoord2, + 0 + ); + faceTypes[x][y] = currentChunk.getType( + localCoord1, + localCoord2, + 0 + ); + } break; + } + // Vector3i sampleChunkWorldPos = new Vector3i( + // worldPos.x + (x * higherResSpacing) / ChunkData.CHUNK_SIZE, + // worldPos.y + (y * higherResSpacing) / ChunkData.CHUNK_SIZE, + // worldPos.z + (z * spacingFactor) / ChunkData.CHUNK_SIZE + // ); + // ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(sampleChunkWorldPos); + // if(currentChunk == null){ + // throw new Error("Chunk is null! " + worldPos); + // } + // weights[x][y][z] = currentChunk.getWeight( + // (x * higherResSpacing) % ChunkData.CHUNK_SIZE, + // (y * higherResSpacing) % ChunkData.CHUNK_SIZE, + // (z * spacingFactor) % ChunkData.CHUNK_SIZE + // ); + // types[x][y][z] = currentChunk.getType( + // (x * higherResSpacing) % ChunkData.CHUNK_SIZE, + // (y * higherResSpacing) % ChunkData.CHUNK_SIZE, + // (z * spacingFactor) % ChunkData.CHUNK_SIZE + // ); + } + } + switch(higherLODFace){ + case X_POSITIVE: { + chunkData.addXPositiveEdge(faceWeights, faceTypes); + } break; + case X_NEGATIVE: { + chunkData.addXNegativeEdge(faceWeights, faceTypes); + } break; + case Y_POSITIVE: { + chunkData.addYPositiveEdge(faceWeights, faceTypes); + } break; + case Y_NEGATIVE: { + chunkData.addYNegativeEdge(faceWeights, faceTypes); + } break; + case Z_POSITIVE: { + chunkData.addZPositiveEdge(faceWeights, faceTypes); + } break; + case Z_NEGATIVE: { + chunkData.addZNegativeEdge(faceWeights, faceTypes); + } break; + } return true; } diff --git a/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java b/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java index 76dd24b1..8622a1ff 100644 --- a/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java +++ b/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java @@ -1335,7 +1335,7 @@ public class TransvoxelModelGeneration { chunkData.yNegativeEdgeAtlas[(x+0)*2+0][(z+0)*2+0], chunkData.yNegativeEdgeAtlas[(x+1)*2+0][(z+0)*2+0], chunkData.yNegativeEdgeAtlas[(x+0)*2+0][(z+1)*2+0], chunkData.yNegativeEdgeAtlas[(x+1)*2+0][(z+1)*2+0] ); - polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + polygonizeTransition(currentTransitionCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); // //Generate the normal cell with half width @@ -1349,7 +1349,7 @@ public class TransvoxelModelGeneration { chunkData.yNegativeEdgeAtlas[(x+0)*2+0][(z+0)*2+0], chunkData.yNegativeEdgeAtlas[(x+0)*2+0][(z+1)*2+0], chunkData.yNegativeEdgeAtlas[(x+1)*2+0][(z+1)*2+0], chunkData.yNegativeEdgeAtlas[(x+1)*2+0][(z+0)*2+0] ); //polygonize the current gridcell - polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, false); + polygonize(currentCell, TerrainChunkModelGeneration.MIN_ISO_VALUE, triangles, samplerTriangles, vertMap, verts, normals, trianglesSharingVert, true); } } } else {