Renderer/src/main/java/electrosphere/renderer/target/DrawTargetEvaluator.java
austin 33cfc3601b
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
reduce visual lod cutoff
2025-05-24 20:55:25 -04:00

151 lines
7.0 KiB
Java

package electrosphere.renderer.target;
import java.util.List;
import java.util.Set;
import org.joml.Matrix4d;
import org.joml.Vector3d;
import electrosphere.client.entity.camera.CameraEntityUtils;
import electrosphere.engine.Globals;
import electrosphere.entity.DrawableUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.pipelines.MainContentPipeline;
import electrosphere.renderer.pipelines.NormalsForOutlinePipeline;
import electrosphere.renderer.pipelines.ShadowMapPipeline;
/**
* Evaluates the draw targets
*/
public class DrawTargetEvaluator {
/**
* Cutoff after which we start using LOD models
*/
public static final int LOD_CUTOFF = 50;
/**
* Evaluates the draw targets
*/
public static void evaluate(){
Globals.profiler.beginCpuSample("DrawTargetEvaluator.evaluate");
//main content pipeline structures
DrawTargetAccumulator mainAccumulator = Globals.renderingEngine.getMainContentPipeline().getDrawTargetAccumulator();
List<Entity> mainQueue = Globals.renderingEngine.getMainContentPipeline().getStandardEntityQueue();
mainAccumulator.clearCalls();
mainQueue.clear();
//shadow map pipeline structures
DrawTargetAccumulator shadowAccumulator = Globals.renderingEngine.getShadowMapPipeline().getDrawTargetAccumulator();
List<Entity> shadowQueue = Globals.renderingEngine.getShadowMapPipeline().getStandardEntityQueue();
shadowAccumulator.clearCalls();
shadowQueue.clear();
//normals pipeline structures
DrawTargetAccumulator normalAccumulator = Globals.renderingEngine.getNormalsForOutlinePipeline().getDrawTargetAccumulator();
List<Entity> normalQueue = Globals.renderingEngine.getNormalsForOutlinePipeline().getStandardEntityQueue();
normalAccumulator.clearCalls();
normalQueue.clear();
//reused objects
Vector3d posVec = new Vector3d();
Matrix4d modelTransformMatrix = new Matrix4d();
//calculate camera-modified vector3d
Vector3d cameraCenter = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.clientState.playerCamera));
Vector3d positionVec = new Vector3d();
//different entity lists
Set<Entity> drawables = Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE);
Set<Entity> shadowList = Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAW_CAST_SHADOW);
for(Entity currentEntity : drawables){
Vector3d position = EntityUtils.getPosition(currentEntity);
//fetch actor
Actor currentActor = EntityUtils.getActor(currentEntity);
//get distance from camera
posVec.set(position);
double dist = posVec.distance(cameraCenter);
//evaluate LOD level
if(currentActor.getLowResPath() != null){
if(dist < LOD_CUTOFF){
currentActor.setLodLevel(Actor.LOD_LEVEL_FULL);
} else {
currentActor.setLodLevel(Actor.LOD_LEVEL_LOWER);
}
}
//queue calls accordingly
if(!DrawableUtils.hasUniqueModel(currentEntity) && currentActor.isStaticDrawCall()){
//calculate camera-modified vector3d
Vector3d cameraModifiedPosition = positionVec.set(position).sub(cameraCenter);
//calculate and apply model transform
modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
modelTransformMatrix.scale(positionVec.set(EntityUtils.getScale(currentEntity)));
currentActor.applySpatialData(modelTransformMatrix,position);
//draw
if(currentActor.frustumTest(Globals.renderingEngine.getRenderPipelineState(), modelTransformMatrix.getTranslation(posVec))){
//queue for batching
if(MainContentPipeline.shouldDrawSolidPass(currentEntity)){
mainAccumulator.addCall(currentActor.getModelPath(), position, modelTransformMatrix);
}
if(dist < ShadowMapPipeline.DRAW_CUTOFF_DIST && shadowList.contains(currentEntity)){
shadowAccumulator.addCall(currentActor.getModelPath(), position, modelTransformMatrix);
}
if(dist < NormalsForOutlinePipeline.DRAW_CUTOFF_DIST && NormalsForOutlinePipeline.shouldDraw(currentEntity)){
normalAccumulator.addCall(currentActor.getModelPath(), position, modelTransformMatrix);
}
}
} else {
if(MainContentPipeline.shouldDrawSolidPass(currentEntity)){
mainQueue.add(currentEntity);
}
if(dist < ShadowMapPipeline.DRAW_CUTOFF_DIST && shadowList.contains(currentEntity)){
shadowQueue.add(currentEntity);
}
if(dist < NormalsForOutlinePipeline.DRAW_CUTOFF_DIST && NormalsForOutlinePipeline.shouldDraw(currentEntity)){
normalQueue.add(currentEntity);
}
}
}
// //iterate over all shadow cast entities
// for(Entity currentEntity : Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAW_CAST_SHADOW)){
// if(currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW)!=null){
// Vector3d position = EntityUtils.getPosition(currentEntity);
// //fetch actor
// Actor currentActor = EntityUtils.getActor(currentEntity);
// if(currentActor.isStaticDrawCall()){
// 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)));
// posVec.set(0,0,0);
// if(currentActor.frustumTest(Globals.renderingEngine.getRenderPipelineState(), modelTransformMatrix.getTranslation(posVec))){
// //queue for batching
// shadowAccumulator.addCall(currentActor.getModelPath(), position, modelTransformMatrix);
// }
// } else {
// //queue for not-batching
// shadowQueue.add(currentEntity);
// }
// }
// }
Globals.profiler.endCpuSample();
}
}