WorldOctTree optimization + more logging
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-03-30 16:03:21 -04:00
parent 0a3fbb8e27
commit 86b0de24e6
6 changed files with 54 additions and 27 deletions

View File

@ -1391,6 +1391,7 @@ ServerGroundMovementTree concurrent modify fix
TransvoxelModelGeneration allocation reduction
More allocation reduction
Vector pooling
Simplify WorldOctTree to reduce lag with large node counts

View File

@ -640,10 +640,14 @@ public class ClientDrawCellManager {
this.recursivelyDestroy(node);
//perform op
Globals.profiler.beginCpuSample("ClientDrawCellManager.join - Perform Op");
DrawCell newLeafCell = DrawCell.generateTerrainCell(node.getMinBound(),node.getData().lod);
Globals.profiler.beginCpuSample("ClientDrawCellManager.join - Perform Op - Tree join");
WorldOctTreeNode<DrawCell> newLeaf = chunkTree.join(node, newLeafCell);
Globals.profiler.endCpuSample();
newLeaf.getData().transferChunkData(node.getData());
newLeaf.getData().setHasGenerated(false);
Globals.profiler.endCpuSample();
//update neighbors
this.conditionalUpdateAdjacentNodes(newLeaf, newLeaf.getLevel());

View File

@ -92,6 +92,7 @@ public class AssetManager {
public void loadAssetsInQueue(){
//models
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load models");
Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load Models");
for(String currentPath : modelsInQueue){
modelsInQueue.remove(currentPath);
AIScene aiScene = ModelLoader.loadAIScene(currentPath);
@ -113,22 +114,28 @@ public class AssetManager {
}
}
}
Globals.profiler.endCpuSample();
//textures from disk to gpu
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load textures");
Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load textures");
for(String currentPath : texturesInQueue){
texturesInQueue.remove(currentPath);
texturesLoadedIntoMemory.put(currentPath, new Texture(Globals.renderingEngine.getOpenGLState(), currentPath));
}
Globals.profiler.endCpuSample();
//audio from disk
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load audio");
Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load audio");
if(Globals.audioEngine != null && Globals.audioEngine.initialized()){
for(String currentPath : audioInQueue){
audioInQueue.remove(currentPath);
audioLoadedIntoMemory.put(currentPath, new AudioBuffer(currentPath));
}
}
Globals.profiler.endCpuSample();
//shaders
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load shaders");
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load visual shaders");
Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load visual shaders");
for(ActorShaderMask currentShader : shadersInQueue){
shadersInQueue.remove(currentShader);
String key = getShaderKey(currentShader.getVertexShaderPath(),currentShader.getFragmentShaderPath());
@ -137,8 +144,10 @@ public class AssetManager {
VisualShader.loadSpecificShader(currentShader.getVertexShaderPath(),currentShader.getFragmentShaderPath())
);
}
Globals.profiler.endCpuSample();
//compute shaders
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load compute shaders");
Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load compute shaders");
for(String computePath : computeShadersInQueue){
computeShadersInQueue.remove(computePath);
String key = getComputeShaderKey(computePath);
@ -151,15 +160,19 @@ public class AssetManager {
e.printStackTrace();
}
}
Globals.profiler.endCpuSample();
//pose models
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load pose models");
Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load pose models");
for(String currentPath: poseModelsInQueue){
poseModelsInQueue.remove(currentPath);
AIScene scene = ModelLoader.loadAIScene(currentPath);
poseModelsLoadedIntoMemory.put(currentPath, new PoseModel(currentPath, scene));
}
Globals.profiler.endCpuSample();
//queued assets
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load queued assets");
Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load queued assets");
queuedAssetLock.lock();
for(QueuedAsset<?> queuedAsset : queuedAssets){
queuedAsset.load();
@ -171,14 +184,19 @@ public class AssetManager {
}
queuedAssets.clear();
queuedAssetLock.unlock();
Globals.profiler.endCpuSample();
//allocate homogenous buffers
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Allocate homogenous buffers");
Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Allocate homogenous buffers");
this.allocateHomogenousBuffers();
Globals.profiler.endCpuSample();
//allocate instance array buffers
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Allocate instance array buffers");
Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Allocate instance array buffers");
this.allocateInstanceArrayBuffers();
Globals.profiler.endCpuSample();
//override meshes
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Override meshes");

View File

@ -116,9 +116,9 @@ public class MainContentPipeline implements RenderPipeline {
scaleVec.set(EntityUtils.getScale(currentEntity))
);
//set actor value
currentActor.setAttribute(modelAttribute, modelTransformMatrix);
currentActor.setAttribute(modelAttribute, new Matrix4d(modelTransformMatrix));
//draw
currentActor.draw(renderPipelineState, cameraModifiedPosition);
currentActor.draw(renderPipelineState, new Vector3d(cameraModifiedPosition));
} else {
currentActor.draw(renderPipelineState);
}
@ -199,9 +199,9 @@ public class MainContentPipeline implements RenderPipeline {
scaleVec.set(EntityUtils.getScale(currentEntity))
);
//set actor value
currentActor.setAttribute(modelAttribute, modelTransformMatrix);
currentActor.setAttribute(modelAttribute, new Matrix4d(modelTransformMatrix));
//draw
currentActor.draw(renderPipelineState, cameraModifiedPosition);
currentActor.draw(renderPipelineState, new Vector3d(cameraModifiedPosition));
} else {
currentActor.draw(renderPipelineState);
}

View File

@ -113,14 +113,14 @@ public class ShadowMapPipeline implements RenderPipeline {
//fetch actor
Actor currentActor = EntityUtils.getActor(currentEntity);
//calculate camera-modified vector3d
Vector3d cameraCenter = posVec.set(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
Vector3d cameraModifiedPosition = position.sub(cameraCenter);
Vector3d cameraCenter = scaleVec.set(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
Vector3d cameraModifiedPosition = posVec.set(position).sub(cameraCenter);
//calculate and apply model transform
modelTransformMatrix = modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
modelTransformMatrix.scale(scaleVec.set(EntityUtils.getScale(currentEntity)));
currentActor.applySpatialData(modelTransformMatrix,position);
currentActor.applySpatialData(new Matrix4d(modelTransformMatrix),new Vector3d(position));
//draw
currentActor.draw(renderPipelineState,openGLState);
}

View File

@ -1,11 +1,11 @@
package electrosphere.util.ds.octree;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.joml.Vector3i;
import electrosphere.engine.Globals;
import io.github.studiorailgun.MathUtils;
/**
@ -22,11 +22,6 @@ public class WorldOctTree <T> {
*/
private WorldOctTreeNode<T> root = null;
/**
* The list of all nodes in the tree
*/
List<WorldOctTreeNode<T>> nodes = null;
/**
* The minimum position
*/
@ -59,10 +54,8 @@ public class WorldOctTree <T> {
//calculate max level
int dimRaw = max.x - min.x;
this.maxLevel = (int)MathUtils.log2(dimRaw);
this.nodes = new ArrayList<WorldOctTreeNode<T>>();
this.root = new WorldOctTreeNode<T>(this, 0, new Vector3i(min), new Vector3i(max));
this.root.setLeaf(true);
this.nodes.add(this.root);
}
/**
@ -112,11 +105,6 @@ public class WorldOctTree <T> {
//replace existing node
replaceNode(existing,newContainer);
//update tracking
this.nodes.remove(existing);
this.nodes.add(newContainer);
this.nodes.addAll(newContainer.getChildren());
return newContainer;
}
@ -130,20 +118,23 @@ public class WorldOctTree <T> {
if(existing.isLeaf()){
throw new IllegalArgumentException("Tried to split non-leaf!");
}
Globals.profiler.beginCpuSample("WorldOctTree.join - allocation");
Vector3i min = existing.getMinBound();
Vector3i max = existing.getMaxBound();
int currentLevel = existing.getLevel();
WorldOctTreeNode<T> newContainer = new WorldOctTreeNode<>(this, currentLevel, min, max);
newContainer.setData(data);
newContainer.setLeaf(true);
Globals.profiler.endCpuSample();
//replace existing node
Globals.profiler.beginCpuSample("WorldOctTree.join - replace");
this.replaceNode(existing,newContainer);
Globals.profiler.endCpuSample();
//update tracking
this.nodes.remove(existing);
this.nodes.removeAll(existing.getChildren());
this.nodes.add(newContainer);
Globals.profiler.beginCpuSample("WorldOctTree.join - tracking");
Globals.profiler.endCpuSample();
return newContainer;
}
@ -191,10 +182,8 @@ public class WorldOctTree <T> {
* Clears the tree
*/
public void clear(){
this.nodes.clear();
this.root = new WorldOctTreeNode<T>(this, 0, new Vector3i(min), new Vector3i(max));
this.root.isLeaf = true;
this.nodes.add(this.root);
}
/**
@ -275,7 +264,22 @@ public class WorldOctTree <T> {
* @return The number of nodes
*/
public int getNodeCount(){
return nodes.size();
return this.recursivelyCountNotes(this.root);
}
/**
* Recursively counts all nodes
* @param searchTarget The root node
* @return The number of nodes underneath this one
*/
private int recursivelyCountNotes(WorldOctTreeNode<T> searchTarget){
int rVal = 1;
if(searchTarget.children.size() > 0){
for(WorldOctTreeNode<T> child : searchTarget.children){
rVal += this.recursivelyCountNotes(child);
}
}
return rVal;
}