package electrosphere.renderer.pipelines; import org.joml.Matrix4d; import org.joml.Quaterniond; import org.joml.Quaternionf; import org.joml.Vector3d; import org.joml.Vector3f; import org.lwjgl.opengl.GL40; import org.ode4j.ode.DCapsule; import org.ode4j.ode.DGeom; import org.ode4j.ode.DSphere; import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; import electrosphere.entity.state.hitbox.HitboxCollectionState; import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState; import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.game.data.collidable.CollidableTemplate; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.RenderingEngine; import electrosphere.renderer.model.Model; import electrosphere.renderer.texture.Texture; import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.utils.EntityLookupUtils; import electrosphere.server.pathfinding.navmesh.NavCube; import electrosphere.server.pathfinding.navmesh.NavMesh; import electrosphere.server.pathfinding.navmesh.NavShape; /** * Pipeline for rendering content to assist debugging */ public class DebugContentPipeline implements RenderPipeline { @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { Globals.profiler.beginCpuSample("DebugContentPipeline.render"); //bind screen fbo RenderingEngine.screenFramebuffer.bind(); openGLState.glDepthTest(true); openGLState.glDepthFunc(GL40.GL_LESS); GL40.glDepthMask(true); openGLState.glViewport(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); /// /// R E N D E R I N G S T U F F /// //Sets the background color. // // Set render pipeline state // renderPipelineState.setUseMeshShader(true); renderPipelineState.setBufferStandardUniforms(true); renderPipelineState.setBufferNonStandardUniforms(false); renderPipelineState.setUseMaterial(false); renderPipelineState.setUseShadowMap(true); renderPipelineState.setUseBones(true); renderPipelineState.setUseLight(true); Matrix4d modelTransformMatrix = new Matrix4d(); if(Globals.userSettings.getGraphicsDebugDrawCollisionSpheresClient()){ Model hitboxModel; for(HitboxCollectionState hitboxState : Globals.clientSceneWrapper.getHitboxManager().getAllHitboxes()){ for(DGeom geom : hitboxState.getGeometries()){ if(geom instanceof DSphere){ DSphere sphereView = (DSphere)geom; HitboxState shapeStatus = hitboxState.getShapeStatus(geom); if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere.glb")) != null){ //set color based on collision status, type, etc Texture texture = null; if(shapeStatus.getHadCollision()){ texture = Globals.assetManager.fetchTexture("Textures/transparent_red.png"); } else { texture = Globals.assetManager.fetchTexture("Textures/transparent_grey.png"); } if(texture != null){ texture.bind(openGLState); } Vector3d position = PhysicsUtils.odeVecToJomlVec(sphereView.getPosition()); //calculate camera-modified vector3f Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); modelTransformMatrix.identity(); modelTransformMatrix.translate(cameraModifiedPosition); // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere modelTransformMatrix.scale(sphereView.getRadius() * 2); hitboxModel.setModelMatrix(modelTransformMatrix); hitboxModel.draw(renderPipelineState,openGLState); } } if(geom instanceof DCapsule){ DCapsule capsuleView = (DCapsule)geom; HitboxState shapeStatus = hitboxState.getShapeStatus(geom); if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitcapsule.glb")) != null){ //set color based on collision status, type, etc Texture texture = null; if(shapeStatus.getHadCollision()){ texture = Globals.assetManager.fetchTexture("Textures/transparent_red.png"); } else { texture = Globals.assetManager.fetchTexture("Textures/transparent_grey.png"); } if(texture != null){ texture.bind(openGLState); } Vector3d position = PhysicsUtils.odeVecToJomlVec(capsuleView.getPosition()); //calculate camera-modified vector3f Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); modelTransformMatrix.identity(); modelTransformMatrix.translate(cameraModifiedPosition); //since you're directly accessing the quat from the body, need to adjust it to be in the correct orientation modelTransformMatrix.rotate(PhysicsUtils.odeQuatToJomlQuat(capsuleView.getQuaternion()).mul(new Quaterniond(0.707,0,0,0.707))); //the ode4j capsule's end caps are always at least radius length, the length only controls the distance between the two caps. //unfortunately that won't be easy to replicate with rendering tech currently; instead, run logic below double radius = capsuleView.getRadius(); double length = capsuleView.getLength(); if(length < radius) length = radius; modelTransformMatrix.scale(radius,length,radius); hitboxModel.setModelMatrix(modelTransformMatrix); hitboxModel.draw(renderPipelineState,openGLState); } } } } // for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){ // if((boolean)currentHitbox.getData(EntityDataStrings.DATA_STRING_DRAW)){ // Model hitboxModel; // HitboxData data = HitboxUtils.getHitboxData(currentHitbox); // if(data.isActive()){ // if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){ // if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere.fbx")) != null){ // Vector3d position = EntityUtils.getPosition(currentHitbox); // //calculate camera-modified vector3f // Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); // modelTransformMatrix.identity(); // modelTransformMatrix.translate(cameraModifiedPosition); // // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere // modelTransformMatrix.scale(data.getRadius() * 2); // hitboxModel.setModelMatrix(modelTransformMatrix); // hitboxModel.draw(renderPipelineState,openGLState); // } // } else if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){ // if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere_1.fbx")) != null){ // Vector3d position = EntityUtils.getPosition(currentHitbox); // //calculate camera-modified vector3f // Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); // modelTransformMatrix.identity(); // modelTransformMatrix.translate(cameraModifiedPosition); // // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere // modelTransformMatrix.scale(data.getRadius() * 2); // hitboxModel.setModelMatrix(modelTransformMatrix); // hitboxModel.draw(renderPipelineState,openGLState); // } // } // } else { // if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere_grey.fbx")) != null){ // Vector3d position = EntityUtils.getPosition(currentHitbox); // modelTransformMatrix.identity(); // modelTransformMatrix.translate(new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera))); // // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere // modelTransformMatrix.scale(data.getRadius() * 2); // hitboxModel.setModelMatrix(modelTransformMatrix); // hitboxModel.draw(renderPipelineState,openGLState); // } // } // } // } } if(Globals.userSettings.getGraphicsDebugDrawCollisionSpheresServer()){ Model hitboxModel; int serverIdForClientEntity = Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()); Entity serverPlayerEntity = EntityLookupUtils.getEntityById(serverIdForClientEntity); Realm playerRealm = Globals.realmManager.getEntityRealm(serverPlayerEntity); for(HitboxCollectionState hitboxState : playerRealm.getHitboxManager().getAllHitboxes()){ for(DGeom geom : hitboxState.getGeometries()){ if(geom instanceof DSphere){ DSphere sphereView = (DSphere)geom; HitboxState shapeStatus = hitboxState.getShapeStatus(geom); if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere.glb")) != null){ //set color based on collision status, type, etc Texture texture = null; if(shapeStatus.getHadCollision()){ texture = Globals.assetManager.fetchTexture("Textures/transparent_red.png"); } else { texture = Globals.assetManager.fetchTexture("Textures/transparent_grey.png"); } if(texture != null){ texture.bind(openGLState); } Vector3d position = PhysicsUtils.odeVecToJomlVec(sphereView.getPosition()); //calculate camera-modified vector3f Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); modelTransformMatrix.identity(); modelTransformMatrix.translate(cameraModifiedPosition); // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere modelTransformMatrix.scale(sphereView.getRadius() * 2); hitboxModel.setModelMatrix(modelTransformMatrix); hitboxModel.draw(renderPipelineState,openGLState); } } if(geom instanceof DCapsule){ DCapsule capsuleView = (DCapsule)geom; HitboxState shapeStatus = hitboxState.getShapeStatus(geom); if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitcapsule.glb")) != null){ //set color based on collision status, type, etc Texture texture = null; if(shapeStatus.getHadCollision()){ texture = Globals.assetManager.fetchTexture("Textures/transparent_red.png"); } else { texture = Globals.assetManager.fetchTexture("Textures/transparent_grey.png"); } if(texture != null){ texture.bind(openGLState); } Vector3d position = PhysicsUtils.odeVecToJomlVec(capsuleView.getPosition()); //calculate camera-modified vector3f Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); modelTransformMatrix.identity(); modelTransformMatrix.translate(cameraModifiedPosition); //since you're directly accessing the quat from the body, need to adjust it to be in the correct orientation modelTransformMatrix.rotate(PhysicsUtils.odeQuatToJomlQuat(capsuleView.getQuaternion()).mul(new Quaterniond(0.707,0,0,0.707))); //the ode4j capsule's end caps are always at least radius length, the length only controls the distance between the two caps. //unfortunately that won't be easy to replicate with rendering tech currently; instead, run logic below double radius = capsuleView.getRadius(); double length = capsuleView.getLength(); if(length < radius) length = radius; modelTransformMatrix.scale(radius,length,radius); hitboxModel.setModelMatrix(modelTransformMatrix); hitboxModel.draw(renderPipelineState,openGLState); } } } } } //update pipeline state to use mats again renderPipelineState.setUseMaterial(true); if(Globals.userSettings.graphicsDebugDrawPhysicsObjects()){ Model physicsGraphicsModel; for(Collidable collidable : Globals.clientSceneWrapper.getCollisionEngine().getCollidables()){ Entity physicsEntity = collidable.getParent(); if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE) != null){ CollidableTemplate template = (CollidableTemplate)physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE); switch(template.getType()){ case "CYLINDER": if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcylinder.fbx")) != null){ Vector3d position = EntityUtils.getPosition(physicsEntity); //calculate camera-modified vector3f Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); modelTransformMatrix.identity(); modelTransformMatrix.translate(cameraModifiedPosition); modelTransformMatrix.rotate(EntityUtils.getRotation(physicsEntity)); // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere modelTransformMatrix.scale(template.getDimension1(),template.getDimension2() * 0.5,template.getDimension3()); physicsGraphicsModel.setModelMatrix(modelTransformMatrix); physicsGraphicsModel.draw(renderPipelineState,openGLState); } break; case "CUBE": if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){ Vector3d position = EntityUtils.getPosition(physicsEntity); // Vector3f scale = EntityUtils.getScale(physicsEntity); Quaterniond rotation = EntityUtils.getRotation(physicsEntity); //calculate camera-modified vector3f Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); modelTransformMatrix.identity(); modelTransformMatrix.translate(cameraModifiedPosition); modelTransformMatrix.rotate(rotation); // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere modelTransformMatrix.scale(template.getDimension1(),template.getDimension2(),template.getDimension3()); physicsGraphicsModel.setModelMatrix(modelTransformMatrix); physicsGraphicsModel.draw(renderPipelineState,openGLState); } break; } } } for(Collidable collidable : Globals.clientSceneWrapper.getCollisionEngine().getCollidables()){ Entity physicsEntity = collidable.getParent(); if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){ if(physicsEntity.containsKey(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE)){ if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitplane.fbx")) != null){ Vector3d position = EntityUtils.getPosition(physicsEntity); Vector3f scale = EntityUtils.getScale(physicsEntity); Quaterniond rotation = EntityUtils.getRotation(physicsEntity); //calculate camera-modified vector3f Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); modelTransformMatrix.identity(); modelTransformMatrix.translate(cameraModifiedPosition); modelTransformMatrix.rotate(rotation); // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere modelTransformMatrix.scale(new Vector3d(scale)); physicsGraphicsModel.setModelMatrix(modelTransformMatrix); physicsGraphicsModel.draw(renderPipelineState,openGLState); } } else if(physicsEntity.containsKey(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE)){ if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){ Vector3d position = EntityUtils.getPosition(physicsEntity); Vector3f scale = EntityUtils.getScale(physicsEntity); Quaterniond rotation = EntityUtils.getRotation(physicsEntity); //calculate camera-modified vector3f Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); modelTransformMatrix.identity(); modelTransformMatrix.translate(cameraModifiedPosition); modelTransformMatrix.rotate(rotation); // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere modelTransformMatrix.scale(new Vector3d(scale)); physicsGraphicsModel.setModelMatrix(modelTransformMatrix); physicsGraphicsModel.draw(renderPipelineState,openGLState); } } } } } if(Globals.userSettings.graphicsDebugDrawNavmesh()){ Model shapeGraphicsModel; for(NavMesh mesh : Globals.navMeshManager.getMeshes()){ for(NavShape shape : mesh.getNodes()){ if(shape instanceof NavCube){ if((shapeGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){ NavCube cube = (NavCube)shape; Vector3d position = new Vector3d(cube.getMinPoint()).add(cube.getMaxPoint()).mul(0.5); Vector3f scale = new Vector3f((float)(cube.getMaxPoint().x-cube.getMinPoint().x)/2,(float)(cube.getMaxPoint().y-cube.getMinPoint().y)/2,(float)(cube.getMaxPoint().z-cube.getMinPoint().z)/2); Quaternionf rotation = new Quaternionf(); //calculate camera-modified vector3f Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); modelTransformMatrix.identity(); modelTransformMatrix.translate(cameraModifiedPosition); modelTransformMatrix.rotate(rotation); // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere modelTransformMatrix.scale(new Vector3d(scale)); shapeGraphicsModel.setModelMatrix(modelTransformMatrix); shapeGraphicsModel.draw(renderPipelineState,openGLState); } } } } } Globals.profiler.endCpuSample(); } }