fixes to foliage rendering
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
795fbb6a1c
commit
a9c74e8d50
@ -1,3 +1,3 @@
|
||||
#maven.buildNumber.plugin properties file
|
||||
#Mon Nov 04 12:41:10 EST 2024
|
||||
buildNumber=375
|
||||
#Fri Nov 08 15:44:15 EST 2024
|
||||
buildNumber=376
|
||||
|
||||
@ -954,6 +954,12 @@ Fix LOD bounding sphere calculation
|
||||
Hook up content generation to test generation realm
|
||||
Reorganize biome data
|
||||
|
||||
(11/08/2024)
|
||||
Player and entity tracking overhaul in grid data cell manager
|
||||
Add more profiling points
|
||||
Height manual adjustment for content placement
|
||||
Fast track client draw cell manager cell evaluation
|
||||
|
||||
|
||||
# TODO
|
||||
|
||||
|
||||
@ -99,7 +99,7 @@ public class ClientFoliageManager {
|
||||
} else {
|
||||
chunkUpdateCache.remove(foundChunk);
|
||||
}
|
||||
foundChunk.updateCells(false);
|
||||
foundChunk.updateCells();
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ public class ClientFoliageManager {
|
||||
public void evaluateChunk(Vector3i worldPos){
|
||||
for(FoliageChunk chunk : chunkUpdateCache){
|
||||
if(chunk.getWorldPos().equals(worldPos)){
|
||||
chunk.updateCells(true);
|
||||
chunk.updateCells();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ import electrosphere.entity.EntityCreationUtils;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.state.foliage.AmbientFoliage;
|
||||
import electrosphere.game.data.foliage.type.FoliageType;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.renderer.OpenGLState;
|
||||
import electrosphere.renderer.RenderPipelineState;
|
||||
import electrosphere.renderer.actor.instance.TextureInstancedActor;
|
||||
@ -60,6 +61,11 @@ public class FoliageCell {
|
||||
*/
|
||||
static final float SAMPLE_START_HEIGHT = 1.0f;
|
||||
|
||||
/**
|
||||
* The ID of the air voxel
|
||||
*/
|
||||
static final int AIR_VOXEL_ID = 0;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Size of a single item of foliage in the texture buffer
|
||||
@ -148,6 +154,11 @@ public class FoliageCell {
|
||||
*/
|
||||
static Sphered boundingSphere = new Sphered(0.5,0.5,0.5,2);
|
||||
|
||||
/**
|
||||
* Tracks whether the cell has generated or not
|
||||
*/
|
||||
boolean hasGenerated = false;
|
||||
|
||||
/**
|
||||
* Inits the foliage cell data
|
||||
*/
|
||||
@ -204,17 +215,17 @@ public class FoliageCell {
|
||||
*/
|
||||
protected void generate(){
|
||||
boolean shouldGenerate = false;
|
||||
//get foliage types supported
|
||||
ChunkData data = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPosition,ChunkData.NO_STRIDE);
|
||||
if(data == null){
|
||||
if(voxelPosition.y + 1 >= ServerTerrainChunk.CHUNK_DIMENSION){
|
||||
return;
|
||||
}
|
||||
if(voxelPosition.y + 1 >= ServerTerrainChunk.CHUNK_DIMENSION){
|
||||
ChunkData data = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPosition,ChunkData.NO_STRIDE);
|
||||
if(data == null){
|
||||
return;
|
||||
}
|
||||
if(!Globals.clientDrawCellManager.isFullLOD(worldPosition)){
|
||||
return;
|
||||
}
|
||||
//get foliage types supported
|
||||
List<String> foliageTypesSupported = Globals.gameConfigCurrent.getVoxelData().getTypeFromId(data.getType(voxelPosition)).getAmbientFoliage();
|
||||
boolean airAbove = data.getType(voxelPosition.x,voxelPosition.y+1,voxelPosition.z) == 0;
|
||||
if(foliageTypesSupported != null && foliageTypesSupported.size() > 0 && airAbove && scale < 3){
|
||||
@ -227,12 +238,15 @@ public class FoliageCell {
|
||||
|
||||
//create cell and buffer
|
||||
ByteBuffer buffer = BufferUtils.createByteBuffer(TARGET_FOLIAGE_PER_CELL * SINGLE_FOLIAGE_DATA_SIZE_BYTES);
|
||||
if(buffer.capacity() < TARGET_FOLIAGE_PER_CELL * SINGLE_FOLIAGE_DATA_SIZE_BYTES){
|
||||
LoggerInterface.loggerEngine.WARNING("Failed to allocate data for foliage cell! " + buffer.limit());
|
||||
}
|
||||
FloatBuffer floatBufferView = buffer.asFloatBuffer();
|
||||
int drawCount = 0;
|
||||
for(int x = 0; x < scale; x++){
|
||||
for(int y = 0; y < scale; y++){
|
||||
for(int z = 0; z < scale; z++){
|
||||
drawCount = drawCount + insertBlades(x, y, z, floatBufferView, data);
|
||||
drawCount = drawCount + this.insertBlades(x, y, z, floatBufferView, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -255,6 +269,7 @@ public class FoliageCell {
|
||||
this.addEntity(grassEntity);
|
||||
}
|
||||
}
|
||||
this.hasGenerated = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -278,7 +293,7 @@ public class FoliageCell {
|
||||
List<String> foliageTypesSupported = null;
|
||||
if(chunkData != null && currVoxelPos.y + 1 < ServerTerrainChunk.CHUNK_DIMENSION){
|
||||
foliageTypesSupported = Globals.gameConfigCurrent.getVoxelData().getTypeFromId(chunkData.getType(currVoxelPos)).getAmbientFoliage();
|
||||
boolean airAbove = chunkData.getType(currVoxelPos.x,currVoxelPos.y+1,currVoxelPos.z) == 0;
|
||||
boolean airAbove = chunkData.getType(currVoxelPos.x,currVoxelPos.y+1,currVoxelPos.z) == AIR_VOXEL_ID;
|
||||
if(foliageTypesSupported != null && airAbove){
|
||||
shouldGenerate = true;
|
||||
}
|
||||
@ -387,12 +402,14 @@ public class FoliageCell {
|
||||
offsetY = offsetY - realPosition.y;
|
||||
double rotVar = placementRandomizer.nextDouble() * Math.PI * 2;
|
||||
double rotVar2 = placementRandomizer.nextDouble();
|
||||
floatBufferView.put((float)offsetX + vX);
|
||||
floatBufferView.put((float)offsetY + vY);
|
||||
floatBufferView.put((float)offsetZ + vZ);
|
||||
floatBufferView.put((float)rotVar);
|
||||
floatBufferView.put((float)rotVar2);
|
||||
rVal++;
|
||||
if(floatBufferView.limit() >= floatBufferView.position() + 4){
|
||||
floatBufferView.put((float)offsetX + vX);
|
||||
floatBufferView.put((float)offsetY + vY);
|
||||
floatBufferView.put((float)offsetZ + vZ);
|
||||
floatBufferView.put((float)rotVar);
|
||||
floatBufferView.put((float)rotVar2);
|
||||
rVal++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -463,6 +480,14 @@ public class FoliageCell {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the cell has generated or not
|
||||
* @return true if has generated, false otherwise
|
||||
*/
|
||||
public boolean hasGenerated(){
|
||||
return this.hasGenerated;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SCAFFOLDING FOR BUILDING SCALE>1 CELLS AND ALSO FOR TOP LEVEL CELL CHECKING
|
||||
|
||||
@ -39,6 +39,12 @@ public class FoliageChunk {
|
||||
*/
|
||||
boolean containsFoliageVoxel = false;
|
||||
|
||||
/**
|
||||
* Tracks whether this foliage chunk has properly initialized or not.
|
||||
* It is only considered initialized once it has been evaluated with the data present in cache.
|
||||
*/
|
||||
boolean initialized = false;
|
||||
|
||||
/**
|
||||
* The octree holding all the chunks to evaluate
|
||||
*/
|
||||
@ -80,21 +86,19 @@ public class FoliageChunk {
|
||||
this.currentChunkData = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos,ChunkData.NO_STRIDE);
|
||||
// //evaluate top cells if chunk above this one exists
|
||||
this.aboveChunkData = Globals.clientTerrainManager.getChunkDataAtWorldPoint(new Vector3i(worldPos).add(0,1,0),ChunkData.NO_STRIDE);
|
||||
this.updateCells(true);
|
||||
this.updateCells();
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates all cells in the chunk
|
||||
* @param force true if should ignore cache, false otherwise
|
||||
*/
|
||||
public void updateCells(boolean force){
|
||||
public void updateCells(){
|
||||
Globals.profiler.beginCpuSample("FoliageChunk.updateCells");
|
||||
//re-evaluate whether contains foliage voxel or not
|
||||
if(force){
|
||||
this.containsFoliageVoxel = checkContainsFoliageVoxel();
|
||||
}
|
||||
if(force || containsFoliageVoxel){
|
||||
boolean hasData = Globals.clientTerrainManager.containsChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z, ChunkData.NO_STRIDE);
|
||||
boolean hasPhysics = Globals.clientDrawCellManager.hasGeneratedPhysics(worldPos.x, worldPos.y, worldPos.z);
|
||||
if(containsFoliageVoxel && hasData && hasPhysics){
|
||||
Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity);
|
||||
//the sets to iterate through
|
||||
boolean updated = true;
|
||||
@ -105,6 +109,13 @@ public class FoliageChunk {
|
||||
attempts++;
|
||||
}
|
||||
}
|
||||
if(!hasData){
|
||||
Globals.clientTerrainManager.requestChunk(worldPos.x, worldPos.y, worldPos.z, ChunkData.NO_STRIDE);
|
||||
}
|
||||
if(hasData && !this.initialized) {
|
||||
this.evaluateContainsFoliage();
|
||||
this.initialized = true;
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
@ -130,6 +141,13 @@ public class FoliageChunk {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the chunk to evaluate whether it has foliage or not
|
||||
*/
|
||||
public void evaluateContainsFoliage(){
|
||||
this.containsFoliageVoxel = this.checkContainsFoliageVoxel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively update child nodes
|
||||
* @param node The root node
|
||||
@ -137,8 +155,9 @@ public class FoliageChunk {
|
||||
*/
|
||||
private boolean recursivelyUpdateCells(ChunkTreeNode<FoliageCell> node, Vector3d playerPos){
|
||||
boolean updated = false;
|
||||
Globals.profiler.beginRecursiveCpuSample("FoliageChunk.recursivelyUpdateCells");
|
||||
if(this.shouldSplit(playerPos, node)){
|
||||
Globals.profiler.beginCpuSample("FoliageChunk.split");
|
||||
Globals.profiler.beginAggregateCpuSample("FoliageChunk.split");
|
||||
//perform op
|
||||
ChunkTreeNode<FoliageCell> container = chunkTree.split(node);
|
||||
|
||||
@ -157,7 +176,7 @@ public class FoliageChunk {
|
||||
Globals.profiler.endCpuSample();
|
||||
updated = true;
|
||||
} else if(this.shouldJoin(playerPos, node)) {
|
||||
// Globals.profiler.beginCpuSample("FoliageChunk.join");
|
||||
Globals.profiler.beginAggregateCpuSample("FoliageChunk.join");
|
||||
//perform op
|
||||
ChunkTreeNode<FoliageCell> newLeaf = chunkTree.join(node);
|
||||
|
||||
@ -166,12 +185,12 @@ public class FoliageChunk {
|
||||
|
||||
//do creations
|
||||
newLeaf.convertToLeaf(new FoliageCell(worldPos, newLeaf.getMinBound(), realPos, 5 - newLeaf.getLevel()));
|
||||
// Globals.profiler.endCpuSample();
|
||||
Globals.profiler.endCpuSample();
|
||||
updated = true;
|
||||
} else if(shouldGenerate(playerPos, node)){
|
||||
// Globals.profiler.beginCpuSample("FoliageChunk.generate");
|
||||
Globals.profiler.beginAggregateCpuSample("FoliageChunk.generate");
|
||||
node.getData().generate();
|
||||
// Globals.profiler.endCpuSample();
|
||||
Globals.profiler.endCpuSample();
|
||||
updated = true;
|
||||
} else if(!node.isLeaf()){
|
||||
List<ChunkTreeNode<FoliageCell>> children = new LinkedList<ChunkTreeNode<FoliageCell>>(node.getChildren());
|
||||
@ -180,6 +199,7 @@ public class FoliageChunk {
|
||||
updated = childUpdate || updated;
|
||||
}
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
return updated;
|
||||
}
|
||||
|
||||
@ -264,7 +284,7 @@ public class FoliageChunk {
|
||||
return
|
||||
node.isLeaf() &&
|
||||
node.getData() != null &&
|
||||
node.getData().containedEntities.size() < 1 &&
|
||||
!node.getData().hasGenerated() &&
|
||||
(
|
||||
(
|
||||
node.getLevel() == ChunkTree.MAX_LEVEL
|
||||
|
||||
@ -1,12 +1,15 @@
|
||||
package electrosphere.client.terrain.cells;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.terrain.cells.DrawCell.DrawCellFace;
|
||||
import electrosphere.collision.PhysicsEntityUtils;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
@ -90,6 +93,11 @@ public class ClientDrawCellManager {
|
||||
*/
|
||||
WorldOctTree<DrawCell> chunkTree;
|
||||
|
||||
/**
|
||||
* Tracks what nodes have been evaluated this frame -- used to deduplicate evaluation calls
|
||||
*/
|
||||
Map<FloatingChunkTreeNode<DrawCell>,Boolean> evaluationMap = new HashMap<FloatingChunkTreeNode<DrawCell>,Boolean>();
|
||||
|
||||
/**
|
||||
* Tracks whether the cell manager updated last frame or not
|
||||
*/
|
||||
@ -150,29 +158,40 @@ public class ClientDrawCellManager {
|
||||
* Updates all cells in the chunk
|
||||
*/
|
||||
public void update(){
|
||||
Globals.profiler.beginCpuSample("ClientDrawCellManager.updateCells");
|
||||
Globals.profiler.beginCpuSample("ClientDrawCellManager.update");
|
||||
if(shouldUpdate && Globals.playerEntity != null){
|
||||
Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity);
|
||||
//the sets to iterate through
|
||||
updatedLastFrame = true;
|
||||
validCellCount = 0;
|
||||
evaluationMap.clear();
|
||||
//update all full res cells
|
||||
FloatingChunkTreeNode<DrawCell> rootNode = this.chunkTree.getRoot();
|
||||
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos, HALF_RES_LOD);
|
||||
Globals.profiler.beginCpuSample("ClientDrawCellManager.update - full res cells");
|
||||
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos, evaluationMap, HALF_RES_LOD);
|
||||
Globals.profiler.endCpuSample();
|
||||
if(!updatedLastFrame && !this.initialized){
|
||||
this.initialized = true;
|
||||
}
|
||||
if(!updatedLastFrame){
|
||||
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos, QUARTER_RES_LOD);
|
||||
Globals.profiler.beginCpuSample("ClientDrawCellManager.update - half res cells");
|
||||
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos, evaluationMap, QUARTER_RES_LOD);
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
if(!updatedLastFrame){
|
||||
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos, EIGHTH_RES_LOD);
|
||||
Globals.profiler.beginCpuSample("ClientDrawCellManager.update - quarter res cells");
|
||||
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos, evaluationMap, EIGHTH_RES_LOD);
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
if(!updatedLastFrame){
|
||||
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos, SIXTEENTH_RES_LOD);
|
||||
Globals.profiler.beginCpuSample("ClientDrawCellManager.update - eighth res cells");
|
||||
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos, evaluationMap, SIXTEENTH_RES_LOD);
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
if(!updatedLastFrame){
|
||||
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos, ALL_RES_LOD);
|
||||
Globals.profiler.beginCpuSample("ClientDrawCellManager.update - all res cells");
|
||||
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos, evaluationMap, ALL_RES_LOD);
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
@ -183,11 +202,15 @@ public class ClientDrawCellManager {
|
||||
* @param node The root node
|
||||
* @param playerPos The player's position
|
||||
* @param minLeafLod The minimum LOD required to evaluate a leaf
|
||||
* @param evaluationMap Map of leaf nodes that have been evaluated this frame
|
||||
* @return true if there is work remaining to be done, false otherwise
|
||||
*/
|
||||
private boolean recursivelyUpdateCells(FloatingChunkTreeNode<DrawCell> node, Vector3d playerPos, int minLeafLod){
|
||||
private boolean recursivelyUpdateCells(FloatingChunkTreeNode<DrawCell> node, Vector3d playerPos, Map<FloatingChunkTreeNode<DrawCell>,Boolean> evaluationMap, int minLeafLod){
|
||||
Vector3d playerRealPos = EntityUtils.getPosition(Globals.playerEntity);
|
||||
boolean updated = false;
|
||||
if(evaluationMap.containsKey(node)){
|
||||
return false;
|
||||
}
|
||||
if(this.shouldSplit(playerPos, node)){
|
||||
Globals.profiler.beginCpuSample("ClientDrawCellManager.split");
|
||||
//perform op
|
||||
@ -205,6 +228,7 @@ public class ClientDrawCellManager {
|
||||
);
|
||||
DrawCell drawCell = DrawCell.generateTerrainCell(cellWorldPos);
|
||||
child.convertToLeaf(drawCell);
|
||||
evaluationMap.put(child,true);
|
||||
});
|
||||
|
||||
//update neighbors
|
||||
@ -226,6 +250,7 @@ public class ClientDrawCellManager {
|
||||
|
||||
//update neighbors
|
||||
this.conditionalUpdateAdjacentNodes(newLeaf, newLeaf.getLevel());
|
||||
evaluationMap.put(newLeaf,true);
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
updated = true;
|
||||
@ -240,6 +265,7 @@ public class ClientDrawCellManager {
|
||||
if(this.requestChunks(node, highResFaces)){
|
||||
cell.setHasRequested(true);
|
||||
}
|
||||
evaluationMap.put(node,true);
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
updated = true;
|
||||
@ -258,17 +284,21 @@ public class ClientDrawCellManager {
|
||||
node.getData().setHasRequested(false);
|
||||
}
|
||||
}
|
||||
evaluationMap.put(node,true);
|
||||
Globals.profiler.endCpuSample();
|
||||
updated = true;
|
||||
} else if(!node.isLeaf()){
|
||||
this.validCellCount++;
|
||||
List<FloatingChunkTreeNode<DrawCell>> children = new LinkedList<FloatingChunkTreeNode<DrawCell>>(node.getChildren());
|
||||
for(FloatingChunkTreeNode<DrawCell> child : children){
|
||||
boolean childUpdate = recursivelyUpdateCells(child, playerPos, minLeafLod);
|
||||
boolean childUpdate = recursivelyUpdateCells(child, playerPos, evaluationMap, minLeafLod);
|
||||
if(childUpdate == true){
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
if((this.chunkTree.getMaxLevel() - node.getLevel()) < minLeafLod){
|
||||
evaluationMap.put(node,true);
|
||||
}
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
@ -398,7 +428,7 @@ public class ClientDrawCellManager {
|
||||
*/
|
||||
private void conditionalUpdateAdjacentNodes(FloatingChunkTreeNode<DrawCell> node, int level){
|
||||
//don't bother to check if it's a lowest-res chunk
|
||||
if(this.chunkTree.getMaxLevel() - level > DrawCell.LOWEST_LOD){
|
||||
if(this.chunkTree.getMaxLevel() - level > ClientDrawCellManager.FULL_RES_LOD){
|
||||
return;
|
||||
}
|
||||
if(node.getMinBound().x - 1 >= 0){
|
||||
@ -887,6 +917,36 @@ public class ClientDrawCellManager {
|
||||
return this.initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the draw cell for a given world coordinate if it has been generated
|
||||
* @param worldX The world x coordinate
|
||||
* @param worldY The world y coordinate
|
||||
* @param worldZ The world z coordinate
|
||||
* @return The draw cell if it exists, null otherwise
|
||||
*/
|
||||
public DrawCell getDrawCell(int worldX, int worldY, int worldZ){
|
||||
FloatingChunkTreeNode<DrawCell> node = this.chunkTree.search(new Vector3i(worldX,worldY,worldZ), false);
|
||||
if(node != null){
|
||||
return node.getData();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if physics has been generated for a given world coordinate
|
||||
* @param worldX The world x coordinate
|
||||
* @param worldY The world y coordinate
|
||||
* @param worldZ The world z coordinate
|
||||
* @return true if physics has been generated, false otherwise
|
||||
*/
|
||||
public boolean hasGeneratedPhysics(int worldX, int worldY, int worldZ){
|
||||
DrawCell cell = this.getDrawCell(worldX, worldY, worldZ);
|
||||
if(cell != null && cell.getEntity() != null){
|
||||
return PhysicsEntityUtils.containsDBody(cell.getEntity());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -42,31 +42,6 @@ public class DrawCell {
|
||||
float[][][] weights = new float[ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE];
|
||||
int[][][] types = new int[ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE];
|
||||
|
||||
/**
|
||||
* An invalid LOD level
|
||||
*/
|
||||
public static final int INVALID_LOD_LEVEL = -1;
|
||||
|
||||
/**
|
||||
* The maximum detail LOD level
|
||||
*/
|
||||
public static final int FULL_DETAIL_LOD = 0;
|
||||
|
||||
/**
|
||||
* The half detail lod level
|
||||
*/
|
||||
public static final int HALF_DETAIL_LOD = 1;
|
||||
|
||||
/**
|
||||
* The lowest available LOD
|
||||
*/
|
||||
public static final int LOWEST_LOD = HALF_DETAIL_LOD;
|
||||
|
||||
/**
|
||||
* The lod level of this draw cell
|
||||
*/
|
||||
int lodLevel = FULL_DETAIL_LOD;
|
||||
|
||||
/**
|
||||
* Tracks whether the draw cell has requested its chunk data or not
|
||||
*/
|
||||
@ -139,9 +114,6 @@ public class DrawCell {
|
||||
}
|
||||
}
|
||||
}
|
||||
if(lod == INVALID_LOD_LEVEL){
|
||||
throw new Error("Trying to generate invalid LOD");
|
||||
}
|
||||
modelEntity = TerrainChunk.clientCreateTerrainChunkEntity(chunkData, lod, atlas, this.hasPolygons());
|
||||
ClientEntityUtils.initiallyPositionEntity(modelEntity, getRealPos(), new Quaterniond());
|
||||
this.setHasGenerated(true);
|
||||
@ -452,23 +424,6 @@ public class DrawCell {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the LOD level
|
||||
* @return The LOD level
|
||||
*/
|
||||
public int getLodLevel() {
|
||||
return lodLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the LOD level
|
||||
* @param lodLevel The LOD level
|
||||
*/
|
||||
public void setLodLevel(int lodLevel) {
|
||||
this.lodLevel = lodLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this draw cell has requested its chunk data or not
|
||||
* @return true if has requested, false otherwise
|
||||
|
||||
@ -42,7 +42,7 @@ public class ClientLoading {
|
||||
/**
|
||||
* The number of frames the draw cell is expected to take (minimum) to init
|
||||
*/
|
||||
static final int DRAW_CELL_EXPECTED_MINIMUM_FRAMES_TO_INIT = 100;
|
||||
static final int DRAW_CELL_EXPECTED_MINIMUM_FRAMES_TO_INIT = 10;
|
||||
|
||||
|
||||
protected static void loadCharacterServer(Object[] params){
|
||||
@ -313,7 +313,7 @@ public class ClientLoading {
|
||||
}
|
||||
}
|
||||
if(i < DRAW_CELL_EXPECTED_MINIMUM_FRAMES_TO_INIT){
|
||||
LoggerInterface.loggerEngine.WARNING("Probably didn't block for draw cell manager initialization!");
|
||||
LoggerInterface.loggerEngine.WARNING("Draw cell manager loaded exceptionally fast!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ public class Profiler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins an aggregate CPU sample (must create a regular cpu sample of same type outside function this is inside of to encapsule all calls to aggregate)
|
||||
* Begins an aggregate CPU sample
|
||||
* @param sampleName The name of the sample
|
||||
*/
|
||||
public void beginAggregateCpuSample(String sampleName){
|
||||
@ -49,6 +49,16 @@ public class Profiler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins an recursive CPU sample
|
||||
* @param sampleName The name of the sample
|
||||
*/
|
||||
public void beginRecursiveCpuSample(String sampleName){
|
||||
if(PROFILE){
|
||||
Remotery.rmt_BeginCPUSample(sampleName, Remotery.RMTSF_Recursive, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins a Root CPU sample (will assert if another sample is not ended before this one)
|
||||
* @param sampleName The name of the root sample
|
||||
|
||||
@ -64,6 +64,9 @@ public class ServerEntityUtils {
|
||||
throw new Error("Trying to set server entity position to null!");
|
||||
}
|
||||
Realm realm = Globals.realmManager.getEntityRealm(entity);
|
||||
if(position.x < 0 || position.y < 0 || position.z < 0){
|
||||
throw new Error("Providing invalid location to reposition! " + position);
|
||||
}
|
||||
//if server, get current server data cell
|
||||
ServerDataCell oldDataCell = Globals.entityDataCellMapper.getEntityDataCell(entity);
|
||||
ServerDataCell newDataCell = realm.getDataCellManager().getDataCellAtPoint(position);
|
||||
|
||||
@ -166,7 +166,7 @@ public class Scene {
|
||||
* Simulates all behavior trees stored in the entity manager
|
||||
*/
|
||||
public void simulateBehaviorTrees(float deltaTime){
|
||||
Globals.profiler.beginCpuSample("Scene.simulateBehaviorTrees");
|
||||
Globals.profiler.beginAggregateCpuSample("Scene.simulateBehaviorTrees");
|
||||
for(BehaviorTree tree : behaviorTreeList){
|
||||
tree.simulate(deltaTime);
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ public class AttachUtils {
|
||||
* @param cell The data cell
|
||||
*/
|
||||
public static void serverUpdateAttachedEntityPositions(ServerDataCell cell){
|
||||
Globals.profiler.beginCpuSample("AttachUtils.serverUpdateAttachedEntityPositions");
|
||||
Globals.profiler.beginAggregateCpuSample("AttachUtils.serverUpdateAttachedEntityPositions");
|
||||
serverUpdateBoneAttachedEntityPositions(cell);
|
||||
serverUpdateNonBoneAttachments(cell);
|
||||
Globals.profiler.endCpuSample();
|
||||
@ -95,7 +95,7 @@ public class AttachUtils {
|
||||
* @param cell the data cell
|
||||
*/
|
||||
private static void serverUpdateNonBoneAttachments(ServerDataCell cell){
|
||||
Globals.profiler.beginCpuSample("AttachUtils.serverUpdateNonBoneAttachments");
|
||||
Globals.profiler.beginAggregateCpuSample("AttachUtils.serverUpdateNonBoneAttachments");
|
||||
Matrix4d parentTransform = new Matrix4d().identity();
|
||||
Vector3d position = new Vector3d();
|
||||
Quaterniond rotation = new Quaterniond();
|
||||
|
||||
@ -3,7 +3,6 @@ package electrosphere.entity.state.movement.editor;
|
||||
|
||||
import electrosphere.entity.state.gravity.GravityUtils;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
||||
import electrosphere.entity.types.creature.CreatureUtils;
|
||||
import electrosphere.game.data.creature.type.movement.EditorMovementSystem;
|
||||
import electrosphere.entity.Entity;
|
||||
@ -259,7 +258,9 @@ public class ClientEditorMovementTree implements BehaviorTree {
|
||||
rotation.set(movementQuaternion);
|
||||
position.set(new Vector3d(position).add(new Vector3d(movementVector).mul(velocity)));
|
||||
if(serverEntity != null){
|
||||
ServerEntityUtils.repositionEntity(serverEntity, new Vector3d(position));
|
||||
if(position.x >= 0 && position.y >= 0 && position.z >= 0){
|
||||
ServerEntityUtils.repositionEntity(serverEntity, new Vector3d(position));
|
||||
}
|
||||
}
|
||||
|
||||
GravityUtils.clientAttemptActivateGravity(parent);
|
||||
@ -274,7 +275,9 @@ public class ClientEditorMovementTree implements BehaviorTree {
|
||||
rotation.set(movementQuaternion);
|
||||
position.set(new Vector3d(position).add(new Vector3d(movementVector).mul(velocity)));
|
||||
if(serverEntity != null){
|
||||
ServerEntityUtils.repositionEntity(serverEntity, new Vector3d(position));
|
||||
if(position.x >= 0 && position.y >= 0 && position.z >= 0){
|
||||
ServerEntityUtils.repositionEntity(serverEntity, new Vector3d(position));
|
||||
}
|
||||
}
|
||||
|
||||
GravityUtils.clientAttemptActivateGravity(parent);
|
||||
@ -295,7 +298,9 @@ public class ClientEditorMovementTree implements BehaviorTree {
|
||||
rotation.set(movementQuaternion);
|
||||
position.set(new Vector3d(position).add(new Vector3d(movementVector).mul(velocity)));
|
||||
if(serverEntity != null){
|
||||
ServerEntityUtils.repositionEntity(serverEntity, new Vector3d(position));
|
||||
if(position.x >= 0 && position.y >= 0 && position.z >= 0){
|
||||
ServerEntityUtils.repositionEntity(serverEntity, new Vector3d(position));
|
||||
}
|
||||
}
|
||||
|
||||
GravityUtils.clientAttemptActivateGravity(parent);
|
||||
|
||||
@ -3,9 +3,10 @@ package electrosphere.entity.types.terrain;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
|
||||
import electrosphere.client.terrain.cells.DrawCell;
|
||||
import electrosphere.client.terrain.cells.ClientDrawCellManager;
|
||||
import electrosphere.client.terrain.cells.VoxelTextureAtlas;
|
||||
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
||||
import electrosphere.collision.PhysicsEntityUtils;
|
||||
@ -13,7 +14,10 @@ import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityCreationUtils;
|
||||
import electrosphere.entity.EntityDataStrings;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.ServerEntityUtils;
|
||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.renderer.meshgen.TerrainChunkModelGeneration;
|
||||
import electrosphere.renderer.meshgen.TransvoxelModelGeneration;
|
||||
import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData;
|
||||
@ -27,7 +31,7 @@ public class TerrainChunk {
|
||||
/**
|
||||
* Used for generating terrain chunks
|
||||
*/
|
||||
static ExecutorService generationService = Executors.newFixedThreadPool(2);
|
||||
static final ExecutorService generationService = Executors.newFixedThreadPool(2);
|
||||
|
||||
/**
|
||||
* Creates a client terrain chunk based on weights and values provided
|
||||
@ -44,17 +48,22 @@ public class TerrainChunk {
|
||||
if(hasPolygons){
|
||||
generationService.submit(() -> {
|
||||
TerrainChunkData data;
|
||||
if(levelOfDetail == DrawCell.FULL_DETAIL_LOD){
|
||||
data = TerrainChunkModelGeneration.generateTerrainChunkData(chunkData.terrainGrid, chunkData.textureGrid);
|
||||
} else {
|
||||
try {
|
||||
data = TransvoxelModelGeneration.generateTerrainChunkData(chunkData);
|
||||
}
|
||||
if(Globals.clientScene.containsEntity(rVal)){
|
||||
String modelPath = ClientTerrainManager.queueTerrainGridGeneration(data, atlas);
|
||||
EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath);
|
||||
if(levelOfDetail == DrawCell.FULL_DETAIL_LOD){
|
||||
PhysicsEntityUtils.clientAttachTerrainChunkRigidBody(rVal, data);
|
||||
if(Globals.clientScene.containsEntity(rVal)){
|
||||
String modelPath = ClientTerrainManager.queueTerrainGridGeneration(data, atlas);
|
||||
EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath);
|
||||
if(levelOfDetail == ClientDrawCellManager.FULL_RES_LOD){
|
||||
PhysicsEntityUtils.clientAttachTerrainChunkRigidBody(rVal, data);
|
||||
CollisionObjUtils.clientPositionCharacter(rVal, new Vector3d(EntityUtils.getPosition(rVal)), new Quaterniond());
|
||||
}
|
||||
} else {
|
||||
LoggerInterface.loggerEngine.WARNING("Finished generating terrain polygons; however, entity has already been deleted.");
|
||||
}
|
||||
} catch (Error e){
|
||||
LoggerInterface.loggerEngine.ERROR(e);
|
||||
} catch(Exception e){
|
||||
LoggerInterface.loggerEngine.ERROR(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ import electrosphere.engine.Globals;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||
import electrosphere.net.template.ClientProtocolTemplate;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||
|
||||
/**
|
||||
* The client protocol for handling terrain messages
|
||||
@ -32,8 +33,16 @@ public class TerrainProtocol implements ClientProtocolTemplate<TerrainMessage> {
|
||||
case RESPONSEMETADATA:
|
||||
Globals.clientWorldData = new ClientWorldData(
|
||||
//Vector3f worldMinPoint, Vector3f worldMaxPoint, int dynamicInterpolationRatio, float randomDampener, int worldDiscreteSize
|
||||
new Vector3f(message.getworldMinX(),0,message.getworldMinY()),
|
||||
new Vector3f(message.getworldMaxX(),32,message.getworldMaxY()),
|
||||
new Vector3f(
|
||||
message.getworldMinX(),
|
||||
0,
|
||||
message.getworldMinY()
|
||||
),
|
||||
new Vector3f(
|
||||
message.getworldMaxX(),
|
||||
(int)(message.getworldSizeDiscrete() * ServerTerrainChunk.CHUNK_DIMENSION),
|
||||
message.getworldMaxY()
|
||||
),
|
||||
message.getrandomDampener(),
|
||||
message.getworldSizeDiscrete()
|
||||
);
|
||||
|
||||
@ -12,6 +12,7 @@ public class MainServerFunctions {
|
||||
* Calls the main server routines that should fire each frame
|
||||
*/
|
||||
public static void simulate(){
|
||||
Globals.profiler.beginCpuSample("MainServerFunctions.simulate");
|
||||
|
||||
//
|
||||
//Cleanup disconnected clients
|
||||
@ -21,12 +22,12 @@ public class MainServerFunctions {
|
||||
|
||||
//
|
||||
//Synchronous player message parsing\
|
||||
Globals.profiler.beginCpuSample("Server synchronous packet parsing");
|
||||
Globals.profiler.beginCpuSample("MainServerFunctions.simulate - Server synchronous packet parsing");
|
||||
if(Globals.server != null){
|
||||
Globals.server.synchronousPacketHandling();
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
Globals.profiler.beginCpuSample("Server process synchronization messages");
|
||||
Globals.profiler.beginCpuSample("MainServerFunctions.simulate - Server process synchronization messages");
|
||||
if(Globals.serverSynchronizationManager != null){
|
||||
Globals.serverSynchronizationManager.processMessages();
|
||||
}
|
||||
@ -34,7 +35,7 @@ public class MainServerFunctions {
|
||||
|
||||
//
|
||||
//Micro simulation (ie simulating each scene on the server)
|
||||
Globals.profiler.beginCpuSample("Server micro simulation");
|
||||
Globals.profiler.beginCpuSample("MainServerFunctions.simulate - Server micro simulation");
|
||||
LoggerInterface.loggerEngine.DEBUG_LOOP("Begin server micro simulation");
|
||||
if(Globals.realmManager != null){
|
||||
Globals.realmManager.simulate();
|
||||
@ -42,11 +43,13 @@ public class MainServerFunctions {
|
||||
|
||||
//
|
||||
//Macro simulation (ie simulating the larger world macro data)
|
||||
LoggerInterface.loggerEngine.DEBUG_LOOP("Server macro simulation");
|
||||
LoggerInterface.loggerEngine.DEBUG_LOOP("MainServerFunctions.simulate - Server macro simulation");
|
||||
if(Globals.macroSimulation != null && Globals.macroSimulation.isReady()){
|
||||
Globals.macroSimulation.simulate();
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -24,6 +24,12 @@ public class ServerContentGenerator {
|
||||
*/
|
||||
public static final int FOLIAGE_SEED = 0;
|
||||
|
||||
/**
|
||||
* Adjustment applied to generated height value to approximate the height of the actual terrain.
|
||||
* The voxels don't generate QUITE to the height of the heightmap, so this is applied to make the value line up better for entity placement.
|
||||
*/
|
||||
public static final float HEIGHT_MANUAL_ADJUSTMENT = -0.35f;
|
||||
|
||||
/**
|
||||
* Generates content for a given data cell
|
||||
* @param realm The realm
|
||||
@ -55,7 +61,7 @@ public class ServerContentGenerator {
|
||||
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);
|
||||
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
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package electrosphere.server.content;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.joml.Vector3i;
|
||||
|
||||
|
||||
@ -546,6 +546,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
* Calls the simulate function on all loaded cells
|
||||
*/
|
||||
public void simulate(){
|
||||
Globals.profiler.beginCpuSample("GriddedDataCellManager.simulate");
|
||||
loadedCellsLock.acquireUninterruptibly();
|
||||
for(ServerDataCell cell : this.groundDataCells.values()){
|
||||
if(Globals.microSimulation != null && Globals.microSimulation.isReady()){
|
||||
@ -561,6 +562,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
}
|
||||
loadedCellsLock.release();
|
||||
this.updatePlayerPositions();
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
|
||||
@ -748,11 +750,13 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
* @param worldPosition the world position
|
||||
*/
|
||||
private void rebroadcastFluidChunk(Vector3i worldPosition){
|
||||
Globals.profiler.beginAggregateCpuSample("GriddedDataCellManager.rebroadcastFluidChunk");
|
||||
ServerDataCell cell = getCellAtWorldPosition(worldPosition);
|
||||
ServerFluidChunk chunk = getFluidChunkAtPosition(worldPosition);
|
||||
cell.broadcastNetworkMessage(
|
||||
TerrainMessage.constructupdateFluidDataMessage(worldPosition.x, worldPosition.y, worldPosition.z, TerrainProtocol.constructFluidByteBuffer(chunk).array())
|
||||
);
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -187,6 +187,7 @@ public class Realm {
|
||||
* Tells the data cell manager to simulate all loaded cells
|
||||
*/
|
||||
protected void simulate(){
|
||||
Globals.profiler.beginCpuSample("Realm.simulate");
|
||||
//
|
||||
//simulate bullet physics engine step
|
||||
if(Globals.RUN_PHYSICS){
|
||||
@ -209,6 +210,8 @@ public class Realm {
|
||||
//clear collidable impulse lists
|
||||
collisionEngine.clearCollidableImpulseLists();
|
||||
chemistryEngine.clearCollidableImpulseLists();
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -158,9 +158,11 @@ public class RealmManager {
|
||||
* Simulates all realms in this manager
|
||||
*/
|
||||
public void simulate(){
|
||||
Globals.profiler.beginCpuSample("RealmManager.simulate");
|
||||
for(Realm realm : realms){
|
||||
realm.simulate();
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
//TODO: !!URGENT!! come up with some mechanism to enforce this actually being called every time a player is added to a server data cell
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.server.fluid.manager;
|
||||
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.game.server.world.ServerWorldData;
|
||||
import electrosphere.server.fluid.diskmap.FluidDiskMap;
|
||||
import electrosphere.server.fluid.generation.FluidGenerator;
|
||||
@ -270,14 +271,17 @@ public class ServerFluidManager {
|
||||
* Simulates a chunk
|
||||
*/
|
||||
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){
|
||||
return this.serverFluidSimulator.simulate(fluidChunk,terrainChunk,worldX,worldY,worldZ);
|
||||
rVal = this.serverFluidSimulator.simulate(fluidChunk,terrainChunk,worldX,worldY,worldZ);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
Globals.profiler.endCpuSample();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
//getter for simulate
|
||||
|
||||
@ -28,6 +28,7 @@ public class MicroSimulation {
|
||||
* @param dataCell The data cell
|
||||
*/
|
||||
public void simulate(ServerDataCell dataCell){
|
||||
Globals.profiler.beginAggregateCpuSample("MicroSimulation.simulate");
|
||||
if(dataCell.isReady()){
|
||||
//simulate ai
|
||||
Globals.aiManager.simulate();
|
||||
@ -58,6 +59,7 @@ public class MicroSimulation {
|
||||
ServerCollidableTree.getServerCollidableTree(collidable).simulate((float)Globals.timekeeper.getSimFrameTime());
|
||||
}
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
public boolean isReady(){
|
||||
|
||||
@ -225,7 +225,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
|
||||
){
|
||||
GeneratedVoxel voxel = new GeneratedVoxel();
|
||||
voxel.weight = (float)(surfaceHeight - flooredSurfaceHeight) * 2 - 1;
|
||||
voxel.type = 1;
|
||||
voxel.type = 2;
|
||||
return voxel;
|
||||
}
|
||||
|
||||
|
||||
@ -130,6 +130,8 @@ public class ChunkGenerationThread implements Runnable {
|
||||
this.onLoad.accept(chunk);
|
||||
} catch (Error e){
|
||||
LoggerInterface.loggerEngine.ERROR(e);
|
||||
} catch(Exception e){
|
||||
LoggerInterface.loggerEngine.ERROR(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ public class ServerTerrainManager {
|
||||
/**
|
||||
* The number of threads for chunk generation
|
||||
*/
|
||||
public static final int GENERATION_THREAD_POOL_SIZE = 1;
|
||||
public static final int GENERATION_THREAD_POOL_SIZE = 2;
|
||||
|
||||
/**
|
||||
* Full world discrete size
|
||||
@ -76,7 +76,7 @@ public class ServerTerrainManager {
|
||||
* The threadpool for chunk generation
|
||||
*/
|
||||
@Exclude
|
||||
ExecutorService chunkExecutorService = Executors.newFixedThreadPool(GENERATION_THREAD_POOL_SIZE);
|
||||
static final ExecutorService chunkExecutorService = Executors.newFixedThreadPool(GENERATION_THREAD_POOL_SIZE);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -225,7 +225,7 @@ public class ServerTerrainManager {
|
||||
* @return The ServerTerrainChunk
|
||||
*/
|
||||
public ServerTerrainChunk getChunk(int worldX, int worldY, int worldZ){
|
||||
Globals.profiler.beginCpuSample("ServerTerrainManager.getChunk");
|
||||
Globals.profiler.beginAggregateCpuSample("ServerTerrainManager.getChunk");
|
||||
//THIS FIRES IF THERE IS A MAIN GAME WORLD RUNNING
|
||||
ServerTerrainChunk returnedChunk = null;
|
||||
if(chunkCache.containsChunk(worldX,worldY,worldZ,ChunkData.NO_STRIDE)){
|
||||
@ -256,7 +256,7 @@ public class ServerTerrainManager {
|
||||
* @return The ServerTerrainChunk
|
||||
*/
|
||||
public double getElevation(int worldX, int worldZ, int chunkX, int chunkZ){
|
||||
Globals.profiler.beginCpuSample("ServerTerrainManager.getChunk");
|
||||
Globals.profiler.beginAggregateCpuSample("ServerTerrainManager.getChunk");
|
||||
double elevation = chunkGenerator.getElevation(worldX, worldZ, chunkX, chunkZ);
|
||||
Globals.profiler.endCpuSample();
|
||||
return elevation;
|
||||
@ -271,8 +271,8 @@ public class ServerTerrainManager {
|
||||
* @param onLoad The logic to run once the chunk is available
|
||||
*/
|
||||
public void getChunkAsync(int worldX, int worldY, int worldZ, int stride, Consumer<ServerTerrainChunk> onLoad){
|
||||
Globals.profiler.beginCpuSample("ServerTerrainManager.getChunkAsync");
|
||||
this.chunkExecutorService.submit(new ChunkGenerationThread(chunkDiskMap, chunkCache, chunkGenerator, worldX, worldY, worldZ, stride, onLoad));
|
||||
Globals.profiler.beginAggregateCpuSample("ServerTerrainManager.getChunkAsync");
|
||||
chunkExecutorService.submit(new ChunkGenerationThread(chunkDiskMap, chunkCache, chunkGenerator, worldX, worldY, worldZ, stride, onLoad));
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
@ -326,7 +326,7 @@ public class ServerTerrainManager {
|
||||
* Closes the generation threadpool
|
||||
*/
|
||||
public void closeThreads(){
|
||||
this.chunkExecutorService.shutdownNow();
|
||||
chunkExecutorService.shutdownNow();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ public class ClientDrawCellManagerTests {
|
||||
FloatingChunkTreeNode<DrawCell> node = FloatingChunkTreeNode.constructorForTests(manager.chunkTree, 1, new Vector3i(16,0,0), new Vector3i(32,16,16));
|
||||
node.convertToLeaf(DrawCell.generateTerrainCell(new Vector3i(0,0,0)));
|
||||
|
||||
assertFalse(manager.shouldSplit(playerPos, node));
|
||||
assertTrue(manager.shouldSplit(playerPos, node));
|
||||
|
||||
//cleanup
|
||||
Main.shutdown();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user