more optimizations
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-11-11 16:08:26 -05:00
parent 8ddbe36b3d
commit c2aacdd2ae
11 changed files with 120 additions and 145 deletions

View File

@ -999,6 +999,10 @@ Lower client cache size (to fight memory stalling)
Manual free button on memory debug window
passing chunk data between nodes
storing min lod of children at every level of tree
# TODO

View File

@ -235,6 +235,7 @@ public class ClientDrawCellManager {
//perform op
WorldOctTreeNode<DrawCell> container = chunkTree.split(node);
container.setData(DrawCell.generateTerrainCell(container.getMinBound(), this.chunkTree.getMaxLevel() - container.getLevel()));
container.getData().transferChunkData(node.getData());
//do creations
container.getChildren().forEach(child -> {
@ -617,6 +618,7 @@ public class ClientDrawCellManager {
Globals.profiler.beginCpuSample("ClientDrawCellManager.join");
//perform op
WorldOctTreeNode<DrawCell> newLeaf = chunkTree.join(node, DrawCell.generateTerrainCell(node.getMinBound(),node.getData().lod));
newLeaf.getData().transferChunkData(node.getData());
//do deletions
this.twoLayerDestroy(node);
@ -757,11 +759,9 @@ public class ClientDrawCellManager {
* @param node The top node
*/
private void twoLayerDestroy(WorldOctTreeNode<DrawCell> node){
if(node.getData() == null){
if(!node.getData().hasGenerated()){
for(WorldOctTreeNode<DrawCell> child : node.getChildren()){
if(child.getData() != null){
child.getData().destroy();
}
child.getData().destroy();
}
} else {
node.getData().destroy();

View File

@ -47,9 +47,10 @@ public class DrawCell {
//the main entity for the cell
Entity modelEntity;
//Allocated once instead of continuously, used to generate the visual/physics models
float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
int[][][] types = new int[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
/**
* The data for generating the visuals
*/
TransvoxelChunkData chunkData;
/**
* Tracks whether the draw cell has requested its chunk data or not
@ -62,16 +63,6 @@ public class DrawCell {
boolean hasGenerated = false;
/**
* The initial voxel type encountered
*/
int initialVoxelType = -1;
/**
* True if there are multiple types of voxels in this chunk
*/
boolean multiVoxelType = false;
/**
* Tracks whether this draw cell is flagged as homogenous from the server or not
*/
@ -91,7 +82,7 @@ public class DrawCell {
* The cached minimum distance
*/
double cachedMinDistance = -1;
/**
* Private constructor
@ -133,21 +124,30 @@ public class DrawCell {
* Generates a drawable entity based on this chunk
*/
public void generateDrawableEntity(VoxelTextureAtlas atlas, int lod, List<DrawCellFace> higherLODFaces){
Globals.profiler.beginAggregateCpuSample("DrawCell.fillInData");
boolean success = this.fillInData(lod);
Globals.profiler.endCpuSample();
if(!success){
this.setFailedGenerationAttempts(this.getFailedGenerationAttempts() + 1);
return;
boolean success = true;
if(chunkData == null){
ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(
worldPos.x,
worldPos.y,
worldPos.z,
lod
);
if(currentChunk == null){
success = false;
} else {
this.homogenous = currentChunk.getHomogenousValue() != ChunkData.NOT_HOMOGENOUS;
success = true;
}
if(!success){
this.setFailedGenerationAttempts(this.getFailedGenerationAttempts() + 1);
return;
}
this.chunkData = new TransvoxelChunkData(currentChunk.getVoxelWeight(), currentChunk.getVoxelType(), lod);
}
if(modelEntity != null){
Globals.clientScene.deregisterEntity(modelEntity);
}
TransvoxelChunkData chunkData = new TransvoxelChunkData(weights, types, lod);
if(higherLODFaces != null){
for(DrawCellFace face : higherLODFaces){
Globals.profiler.beginCpuSample("DrawCell.fillInFaceData");
success = this.fillInFaceData(chunkData,face,lod);
success = this.fillInFaceData(this.chunkData,face,lod);
Globals.profiler.endCpuSample();
if(!success){
this.setFailedGenerationAttempts(this.getFailedGenerationAttempts() + 1);
@ -155,10 +155,11 @@ public class DrawCell {
}
}
}
modelEntity = TerrainChunk.clientCreateTerrainChunkEntity(chunkData, lod, atlas, this.hasPolygons());
if(modelEntity != null){
ClientEntityUtils.destroyEntity(modelEntity);
}
modelEntity = TerrainChunk.clientCreateTerrainChunkEntity(this.chunkData, lod, atlas, this.hasPolygons());
ClientEntityUtils.initiallyPositionEntity(modelEntity, this.getRealPos(), new Quaterniond());
// this.weights = null;
// this.types = null;
this.setHasGenerated(true);
}
@ -201,57 +202,17 @@ public class DrawCell {
return modelEntity;
}
/**
* Fills in the internal arrays of data for generate terrain models
* @return true if the data was successfully filled, false otherwise
* Transfers chunk data from the source to this draw cell
* @param source The source draw cell
*/
private boolean fillInData(int lod){
// if(lod == ClientDrawCellManager.FULL_RES_LOD){
ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(
worldPos.x,
worldPos.y,
worldPos.z,
lod
);
if(currentChunk == null){
return false;
}
if(currentChunk.getHomogenousValue() != ChunkData.NOT_HOMOGENOUS){
return true;
}
for(int x = 0; x < ChunkData.CHUNK_DATA_SIZE; x++){
for(int y = 0; y < ChunkData.CHUNK_DATA_SIZE; y++){
for(int z = 0; z < ChunkData.CHUNK_DATA_SIZE; z++){
weights[x][y][z] = currentChunk.getWeight(
x,
y,
z
);
types[x][y][z] = currentChunk.getType(
x,
y,
z
);
if(currentChunk.getHomogenousValue() == ChunkData.NOT_HOMOGENOUS){
this.homogenous = false;
}
//checks to see if there is only one type of voxel in this chunk
if(!this.multiVoxelType){
if(this.initialVoxelType == -1){
this.initialVoxelType = types[x][y][z];
} else if(this.initialVoxelType != types[x][y][z]){
this.multiVoxelType = true;
}
}
}
}
}
return true;
public void transferChunkData(DrawCell source){
this.chunkData = source.chunkData;
this.homogenous = source.homogenous;
this.hasRequested = source.hasRequested;
}
/**
* Fills in the data for the higher resolution face
* @param chunkData The data for the chunk to generate
@ -517,7 +478,7 @@ public class DrawCell {
* @return true if it has polygons, false otherwise
*/
private boolean hasPolygons(){
return this.multiVoxelType;
return !this.homogenous;
}
/**

View File

@ -55,7 +55,7 @@ public class ClientTerrainManager {
public static final int INTERPOLATION_RATIO = ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO;
//caches chunks from server
static final int CACHE_SIZE = 1000 + (int)(ClientDrawCellManager.FULL_RES_DIST * 10) + (int)(ClientDrawCellManager.HALF_RES_DIST * 10);
static final int CACHE_SIZE = 2500 + (int)(ClientDrawCellManager.FULL_RES_DIST * 10) + (int)(ClientDrawCellManager.HALF_RES_DIST * 10);
/**
* Size of the cache in bytes

View File

@ -53,6 +53,14 @@ public class ClientEntityUtils {
//deregister all behavior trees
EntityUtils.cleanUpEntity(entity);
if(Globals.clientSceneWrapper != null){
Globals.clientSceneWrapper.getScene().deregisterEntity(entity);
Globals.clientSceneWrapper.deregisterTranslationMapping(entity);
}
if(Globals.clientScene != null){
Globals.clientScene.deregisterEntity(entity);
}
}
}

View File

@ -31,7 +31,7 @@ public class TerrainChunk {
/**
* Used for generating terrain chunks
*/
static final ExecutorService generationService = Executors.newFixedThreadPool(2);
static final ExecutorService generationService = Executors.newFixedThreadPool(4);
/**
* Creates a client terrain chunk based on weights and values provided

View File

@ -53,43 +53,43 @@ public class ServerContentGenerator {
//generate foliage
BiomeData biome = null;
if(realm.getServerWorldData() != null && realm.getServerWorldData().getServerTerrainManager() != null && realm.getServerWorldData().getServerTerrainManager().getModel() != null){
biome = realm.getServerWorldData().getServerTerrainManager().getModel().getSurfaceBiome(worldPos.x, worldPos.z);
}
List<BiomeFoliageDescription> foliageDescriptions = biome.getSurfaceGenerationParams().getFoliageDescriptions();
if(foliageDescriptions != null){
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){
double height = realm.getServerWorldData().getServerTerrainManager().getElevation(worldPos.x, worldPos.z, x, z) + HEIGHT_MANUAL_ADJUSTMENT;
if(
realm.getServerWorldData().convertVoxelToRealSpace(0, worldPos.y) <= height &&
realm.getServerWorldData().convertVoxelToRealSpace(ServerTerrainChunk.CHUNK_DIMENSION, worldPos.y) > height
){
for(BiomeFoliageDescription foliageDescription : foliageDescriptions){
double scale = foliageDescription.getScale();
double regularity = foliageDescription.getRegularity();
double threshold = foliageDescription.getThreshold();
double realX = realm.getServerWorldData().convertVoxelToRealSpace(x, worldPos.x);
double realZ = realm.getServerWorldData().convertVoxelToRealSpace(z, worldPos.z);
if(NoiseUtils.relaxedPointGen(realX * scale, realZ * scale, regularity, threshold) > 0){
String type = foliageDescription.getEntityIDs().get(random.nextInt(0,foliageDescription.getEntityIDs().size()));
FoliageUtils.serverSpawnTreeFoliage(
realm,
new Vector3d(
realX,
height,
realZ
),
type,
random.nextLong()
);
}
}
}
}
}
}
// BiomeData biome = null;
// if(realm.getServerWorldData() != null && realm.getServerWorldData().getServerTerrainManager() != null && realm.getServerWorldData().getServerTerrainManager().getModel() != null){
// biome = realm.getServerWorldData().getServerTerrainManager().getModel().getSurfaceBiome(worldPos.x, worldPos.z);
// }
// List<BiomeFoliageDescription> foliageDescriptions = biome.getSurfaceGenerationParams().getFoliageDescriptions();
// if(foliageDescriptions != null){
// for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){
// for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){
// double height = realm.getServerWorldData().getServerTerrainManager().getElevation(worldPos.x, worldPos.z, x, z) + HEIGHT_MANUAL_ADJUSTMENT;
// if(
// realm.getServerWorldData().convertVoxelToRealSpace(0, worldPos.y) <= height &&
// realm.getServerWorldData().convertVoxelToRealSpace(ServerTerrainChunk.CHUNK_DIMENSION, worldPos.y) > height
// ){
// for(BiomeFoliageDescription foliageDescription : foliageDescriptions){
// double scale = foliageDescription.getScale();
// double regularity = foliageDescription.getRegularity();
// double threshold = foliageDescription.getThreshold();
// double realX = realm.getServerWorldData().convertVoxelToRealSpace(x, worldPos.x);
// double realZ = realm.getServerWorldData().convertVoxelToRealSpace(z, worldPos.z);
// if(NoiseUtils.relaxedPointGen(realX * scale, realZ * scale, regularity, threshold) > 0){
// String type = foliageDescription.getEntityIDs().get(random.nextInt(0,foliageDescription.getEntityIDs().size()));
// FoliageUtils.serverSpawnTreeFoliage(
// realm,
// new Vector3d(
// realX,
// height,
// realZ
// ),
// type,
// random.nextLong()
// );
// }
// }
// }
// }
// }
// }
}

View File

@ -204,7 +204,7 @@ public class Realm {
//
//data cell manager update misc variables (player positions, unload not-in-use cells)
if(dataCellManager != null){
dataCellManager.unloadPlayerlessChunks();
// dataCellManager.unloadPlayerlessChunks();
}
//
//clear collidable impulse lists

View File

@ -273,13 +273,13 @@ public class ServerFluidManager {
public boolean simulate(int worldX, int worldY, int worldZ){
boolean rVal = false;
Globals.profiler.beginAggregateCpuSample("ServerFluidManager.simulate");
if(simulate){
ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ);
ServerTerrainChunk terrainChunk = this.serverTerrainManager.getChunk(worldX, worldY, worldZ);
if(fluidChunk != null && terrainChunk != null && this.serverFluidSimulator != null){
rVal = this.serverFluidSimulator.simulate(fluidChunk,terrainChunk,worldX,worldY,worldZ);
}
}
// if(simulate){
// ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ);
// ServerTerrainChunk terrainChunk = this.serverTerrainManager.getChunk(worldX, worldY, worldZ);
// if(fluidChunk != null && terrainChunk != null && this.serverFluidSimulator != null){
// rVal = this.serverFluidSimulator.simulate(fluidChunk,terrainChunk,worldX,worldY,worldZ);
// }
// }
Globals.profiler.endCpuSample();
return rVal;
}

View File

@ -159,6 +159,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
// }
// });
} else {
GeneratedVoxel voxel = new GeneratedVoxel();
for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){
Globals.profiler.beginAggregateCpuSample("TestGenerationChunkGenerator - Generate slice");
for(int y = 0; y < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; y++){
@ -169,7 +170,8 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
int finalChunkX = (x * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION;
int finalChunkY = (y * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION;
int finalChunkZ = (z * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION;
GeneratedVoxel voxel = this.getVoxel(
this.getVoxel(
voxel,
finalWorldX, finalWorldY, finalWorldZ,
finalChunkX, finalChunkY, finalChunkZ,
stride,
@ -182,7 +184,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
}
if(firstType == -1){
firstType = values[x][y][z];
} else if(homogenous && firstType == values[x][y][z]){
} else if(homogenous && firstType != values[x][y][z]){
homogenous = false;
}
}
@ -222,6 +224,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
/**
* Gets the value for a chunk
* @param voxel The voxel to fill
* @param worldX The world x pos
* @param worldY The world y pos
* @param worldZ The world z pos
@ -231,9 +234,9 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
* @param stride The stride of the data
* @param surfaceHeight The height of the surface at x,z
* @param surfaceBiome The surface biome of the chunk
* @return The value of the chunk
*/
private GeneratedVoxel getVoxel(
private void getVoxel(
GeneratedVoxel voxel,
int worldX, int worldY, int worldZ,
int chunkX, int chunkY, int chunkZ,
int stride,
@ -256,7 +259,8 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
double surfacePercent = TestGenerationChunkGenerator.getSurfaceWeight(surfaceHeight,realY,strideMultiplier);
Globals.profiler.endCpuSample();
if(heightDiff < -strideMultiplier * SURFACE_VOXEL_WIDTH){
return getSubsurfaceVoxel(
getSubsurfaceVoxel(
voxel,
worldX, worldY, worldZ,
chunkX, chunkY, chunkZ,
realX, realY, realZ,
@ -265,7 +269,8 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
surfaceBiome
);
} else if(heightDiff > 0) {
return getOverSurfaceVoxel(
getOverSurfaceVoxel(
voxel,
worldX, worldY, worldZ,
chunkX, chunkY, chunkZ,
realX, realY, realZ,-
@ -274,7 +279,8 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
surfaceBiome
);
} else {
return getSurfaceVoxel(
getSurfaceVoxel(
voxel,
worldX, worldY, worldZ,
chunkX, chunkY, chunkZ,
realX, realY, realZ,
@ -289,7 +295,8 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
* Gets the voxel on the surface
* @return The voxel
*/
private GeneratedVoxel getSurfaceVoxel(
private void getSurfaceVoxel(
GeneratedVoxel voxel,
int worldX, int worldY, int worldZ,
int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ,
@ -297,17 +304,16 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
float surfaceHeight,
BiomeData surfaceBiome
){
GeneratedVoxel voxel = new GeneratedVoxel();
voxel.weight = (float)surfacePercent * 2 - 1;
voxel.type = 2;
return voxel;
}
/**
* Gets the voxel below the surface
* @return The voxel
*/
private GeneratedVoxel getSubsurfaceVoxel(
private void getSubsurfaceVoxel(
GeneratedVoxel voxel,
int worldX, int worldY, int worldZ,
int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ,
@ -315,7 +321,6 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
float surfaceHeight,
BiomeData surfaceBiome
){
GeneratedVoxel voxel = new GeneratedVoxel();
if(realY < surfaceHeight - 5){
voxel.weight = 1;
voxel.type = 6;
@ -323,14 +328,14 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
voxel.weight = 1;
voxel.type = 1;
}
return voxel;
}
/**
* Gets the voxel above the service
* @return The voxel
*/
private GeneratedVoxel getOverSurfaceVoxel(
private void getOverSurfaceVoxel(
GeneratedVoxel voxel,
int worldX, int worldY, int worldZ,
int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ,
@ -338,10 +343,8 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
float surfaceHeight,
BiomeData surfaceBiome
){
GeneratedVoxel voxel = new GeneratedVoxel();
voxel.weight = -1;
voxel.type = 0;
return voxel;
}
/**

View File

@ -1,7 +1,6 @@
package electrosphere.util.ds.octree;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@ -381,7 +380,7 @@ public class WorldOctTree <T> {
* Gets the children of this node
*/
public List<WorldOctTreeNode<T>> getChildren() {
return Collections.unmodifiableList(this.children);
return this.children;
}
/**