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 mainQueue = Globals.renderingEngine.getMainContentPipeline().getStandardEntityQueue(); mainAccumulator.clearCalls(); mainQueue.clear(); //shadow map pipeline structures DrawTargetAccumulator shadowAccumulator = Globals.renderingEngine.getShadowMapPipeline().getDrawTargetAccumulator(); List shadowQueue = Globals.renderingEngine.getShadowMapPipeline().getStandardEntityQueue(); shadowAccumulator.clearCalls(); shadowQueue.clear(); //normals pipeline structures DrawTargetAccumulator normalAccumulator = Globals.renderingEngine.getNormalsForOutlinePipeline().getDrawTargetAccumulator(); List 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 drawables = Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE); Set 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(); } }