Renderer/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java
austin 09341af70c
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
par shapes work
2024-09-07 14:03:26 -04:00

360 lines
22 KiB
Java

package electrosphere.renderer.pipelines.debug;
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.engine.assetmanager.AssetDataStrings;
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.game.data.collidable.HitboxData;
import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.RenderPipelineState;
import electrosphere.renderer.RenderingEngine;
import electrosphere.renderer.model.Model;
import electrosphere.renderer.pipelines.RenderPipeline;
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 {
//The bone debugging pipeline
DebugBonesPipeline debugBonesPipeline = new DebugBonesPipeline();
@Override
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
Globals.profiler.beginCpuSample("DebugContentPipeline.render");
//bind screen fbo
RenderingEngine.screenFramebuffer.bind(openGLState);
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(AssetDataStrings.UNITSPHERE)) != null){
//set color based on collision status, type, etc
Texture texture = Globals.assetManager.fetchTexture(getHitboxColor(shapeStatus,shapeStatus.getHitboxData()));
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.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 = Globals.assetManager.fetchTexture(getHitboxColor(shapeStatus,shapeStatus.getHitboxData()));
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);
}
}
}
}
}
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(AssetDataStrings.UNITSPHERE)) != null){
//set color based on collision status, type, etc
Texture texture = Globals.assetManager.fetchTexture(getHitboxColor(shapeStatus,shapeStatus.getHitboxData()));
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.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 = Globals.assetManager.fetchTexture(getHitboxColor(shapeStatus,shapeStatus.getHitboxData()));
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);
}
}
}
}
}
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/basic/geometry/unitcylinder.glb")) != null){
//set color based on collision status, type, etc
Texture texture = Globals.assetManager.fetchTexture("Textures/transparent_blue.png");
if(texture != null){
texture.bind(openGLState);
}
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.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/basic/geometry/unitcube.fbx")) != null){
//set color based on collision status, type, etc
Texture texture = Globals.assetManager.fetchTexture("Textures/transparent_blue.png");
if(texture != null){
texture.bind(openGLState);
}
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.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/basic/geometry/unitplane.fbx")) != null){
//set color based on collision status, type, etc
Texture texture = Globals.assetManager.fetchTexture("Textures/transparent_blue.png");
if(texture != null){
texture.bind(openGLState);
}
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.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/basic/geometry/unitcube.fbx")) != null){
//set color based on collision status, type, etc
Texture texture = Globals.assetManager.fetchTexture("Textures/transparent_blue.png");
if(texture != null){
texture.bind(openGLState);
}
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.scale(new Vector3d(scale));
physicsGraphicsModel.setModelMatrix(modelTransformMatrix);
physicsGraphicsModel.draw(renderPipelineState,openGLState);
}
}
}
}
}
//update pipeline state to use mats again
renderPipelineState.setUseMaterial(true);
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);
}
}
}
}
}
debugBonesPipeline.render(openGLState, renderPipelineState);
Globals.profiler.endCpuSample();
}
/**
* Gets the color texture to use to draw a hitbox
* @param shapeStatus The hitbox status
* @param data The hitbox data
* @return The texture path to use
*/
private String getHitboxColor(HitboxState shapeStatus, HitboxData data){
switch(data.getType()){
case HitboxData.HITBOX_TYPE_BLOCK_CONNECTED: {
if(shapeStatus.getHadCollision()){
return "Textures/color/transparent_yellow.png";
}
if(shapeStatus.isActive()){
return "Textures/transparent_blue.png";
}
return "Textures/transparent_grey.png";
}
case HitboxData.HITBOX_TYPE_HIT:
case HitboxData.HITBOX_TYPE_HIT_CONNECTED: {
if(shapeStatus.getHadCollision()){
return "Textures/color/transparent_yellow.png";
}
if(shapeStatus.isActive()){
if(shapeStatus.isBlockOverride()){
return "Textures/transparent_blue.png";
}
return "Textures/transparent_red.png";
}
return "Textures/transparent_grey.png";
}
case HitboxData.HITBOX_TYPE_HURT:
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
if(shapeStatus.getHadCollision()){
return "Textures/color/transparent_yellow.png";
}
return "Textures/transparent_grey.png";
}
}
return "Textures/transparent_grey.png";
}
/**
* Gets the bone debugging pipeline
* @return The bone debugging pipeline
*/
public DebugBonesPipeline getDebugBonesPipeline(){
return this.debugBonesPipeline;
}
}