From 1578eb37806822abdeb5f34f91ea4c3423e1d087 Mon Sep 17 00:00:00 2001 From: austin Date: Sun, 28 Jul 2024 12:07:44 -0400 Subject: [PATCH] partially fix first person attachment to viewmodel --- docs/src/progress/renderertodo.md | 4 + .../controls/ControlHandler.java | 2 +- .../entity/types/attach/AttachUtils.java | 14 +- .../renderer/RenderingEngine.java | 3 +- .../renderer/pipelines/CompositePipeline.java | 36 ----- .../pipelines/FirstPersonItemsPipeline.java | 127 +++++++++--------- .../pipelines/MainContentPipeline.java | 21 +++ 7 files changed, 100 insertions(+), 107 deletions(-) diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 33084b38..66afa721 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -467,6 +467,10 @@ Small bugfix with blocking Refactor math to be client/server agnostic in attach utils Attach utils fixes for first person handling +(07/28/2024) +Tear out first person rendering pipeline +Partially fix first person attachment to viewmodel + # TODO diff --git a/src/main/java/electrosphere/controls/ControlHandler.java b/src/main/java/electrosphere/controls/ControlHandler.java index 23cc57ee..4e33e6b9 100644 --- a/src/main/java/electrosphere/controls/ControlHandler.java +++ b/src/main/java/electrosphere/controls/ControlHandler.java @@ -249,7 +249,7 @@ public class ControlHandler { boolean shouldRecaptureScreen = false; //controls whether the camera is first or third person - boolean cameraIsThirdPerson = true; + boolean cameraIsThirdPerson = false; //The list of window strings that would block main game controls static String[] controlBlockingWindows = new String[]{ diff --git a/src/main/java/electrosphere/entity/types/attach/AttachUtils.java b/src/main/java/electrosphere/entity/types/attach/AttachUtils.java index 02b185fe..c527841e 100644 --- a/src/main/java/electrosphere/entity/types/attach/AttachUtils.java +++ b/src/main/java/electrosphere/entity/types/attach/AttachUtils.java @@ -5,6 +5,7 @@ import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityTags; import electrosphere.entity.EntityUtils; +import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.renderer.actor.Actor; import electrosphere.server.datacell.ServerDataCell; @@ -203,7 +204,7 @@ public class AttachUtils { Vector3d facingAngle; if(parent == Globals.firstPersonEntity){ - facingAngle = CreatureUtils.getFacingVector(Globals.playerEntity); + facingAngle = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera)).mul(1,0,1).normalize(); } else { facingAngle = CreatureUtils.getFacingVector(parent); } @@ -309,9 +310,9 @@ public class AttachUtils { ){ //transform bone space Vector3d position = new Vector3d(bonePosition); + position = position.add(offsetVector); position = position.mul(parentScale); position = position.rotate(new Quaterniond(parentRotation.x,parentRotation.y,parentRotation.z,parentRotation.w)); - position = position.add(offsetVector); //transform worldspace position.add(parentPosition); //set @@ -589,6 +590,15 @@ public class AttachUtils { return (Entity)e.getData(EntityDataStrings.ATTACH_PARENT); } + /** + * Checks if the entity has a parent + * @param e The entity + * @return true if has a parent, false otherwise + */ + public static boolean hasParent(Entity e){ + return e.containsKey(EntityDataStrings.ATTACH_PARENT); + } + /** * Gets the rotation offset of a given entity * @param e The entity diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java index 49f0d3c3..85846e82 100644 --- a/src/main/java/electrosphere/renderer/RenderingEngine.java +++ b/src/main/java/electrosphere/renderer/RenderingEngine.java @@ -427,8 +427,7 @@ public class RenderingEngine { // //Init pipelines // - firstPersonItemsPipeline.init(Globals.renderingEngine.getOpenGLState()); - compositePipeline.setFirstPersonPipeline(firstPersonItemsPipeline); + mainContentPipeline.setFirstPersonPipeline(firstPersonItemsPipeline); // // Projection and View matrix creation diff --git a/src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java b/src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java index 8d3b0415..71254b91 100644 --- a/src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java @@ -9,9 +9,6 @@ import electrosphere.renderer.RenderingEngine; public class CompositePipeline implements RenderPipeline { - //the pipeline for the first person render items - FirstPersonItemsPipeline firstPersonItemsPipeline; - @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { Globals.profiler.beginCpuSample("CompositePipeline.render"); @@ -63,31 +60,6 @@ public class CompositePipeline implements RenderPipeline { openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.transparencyAccumulatorTexture.getTexturePointer()); openGLState.glActiveTexture(GL40.GL_TEXTURE1); openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.transparencyRevealageTexture.getTexturePointer()); - openGLState.glActiveTexture(GL40.GL_TEXTURE2); - openGLState.glBindTexture(GL40.GL_TEXTURE_2D, firstPersonItemsPipeline.getFramebuffer().getTexturePointer()); - - GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); - - - - - - // - //Draw the first person texture on top of the other textures - // - openGLState.setActiveShader(renderPipelineState, RenderingEngine.screenTextureShaders); - - openGLState.glActiveTexture(GL40.GL_TEXTURE0); - openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); - openGLState.glActiveTexture(GL40.GL_TEXTURE1); - openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); - openGLState.glActiveTexture(GL40.GL_TEXTURE2); - openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); - openGLState.glActiveTexture(GL40.GL_TEXTURE3); - openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); - openGLState.glActiveTexture(GL40.GL_TEXTURE0); - openGLState.glBindTexture(GL40.GL_TEXTURE_2D, firstPersonItemsPipeline.getFramebuffer().getTexturePointer()); - openGLState.glActiveTexture(GL40.GL_TEXTURE1); GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); @@ -105,13 +77,5 @@ public class CompositePipeline implements RenderPipeline { Globals.profiler.endCpuSample(); } - - /** - * Get the first person pipeline - * @param firstPersonItemsPipeline the first person pipeline - */ - public void setFirstPersonPipeline(FirstPersonItemsPipeline firstPersonItemsPipeline){ - this.firstPersonItemsPipeline = firstPersonItemsPipeline; - } } diff --git a/src/main/java/electrosphere/renderer/pipelines/FirstPersonItemsPipeline.java b/src/main/java/electrosphere/renderer/pipelines/FirstPersonItemsPipeline.java index 6975cdcd..45188bad 100644 --- a/src/main/java/electrosphere/renderer/pipelines/FirstPersonItemsPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/FirstPersonItemsPipeline.java @@ -1,7 +1,5 @@ package electrosphere.renderer.pipelines; -import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER; - import org.joml.Matrix4d; import org.joml.Quaterniond; import org.joml.Quaternionf; @@ -14,89 +12,81 @@ import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityUtils; import electrosphere.entity.state.client.firstPerson.FirstPersonTree; +import electrosphere.entity.state.equip.ClientEquipState; +import electrosphere.entity.types.attach.AttachUtils; import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.actor.Actor; -import electrosphere.renderer.framebuffer.Framebuffer; -import electrosphere.renderer.framebuffer.FramebufferUtils; /** * Renders content that should only be rendered in first person (ie the view model/hands/whatever) */ public class FirstPersonItemsPipeline implements RenderPipeline { - //framebuffer to store what is rendered in this pass - Framebuffer firstPersonFramebuffer; - //internal model matrix Matrix4d modelTransformMatrix = new Matrix4d(); - /** - * Initializes the pipeline - */ - public void init(OpenGLState openGLState){ - this.firstPersonFramebuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); - } - @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { - //update logic - if(Globals.firstPersonEntity != null){ + if(Globals.firstPersonEntity != null && !Globals.controlHandler.cameraIsThirdPerson()){ + //update logic updateFirstPersonModelPosition(Globals.firstPersonEntity); + + //setup opengl state + renderPipelineState.setUseBones(true); + renderPipelineState.setUseLight(false); + renderPipelineState.setUseMaterial(true); + renderPipelineState.setUseMeshShader(true); + renderPipelineState.setUseShadowMap(false); + renderPipelineState.setBufferStandardUniforms(true); + renderPipelineState.setFrustumCheck(false); + + openGLState.glDepthTest(true); + openGLState.glDepthFunc(GL40.GL_LESS); + GL40.glDepthMask(true); + + //render + + // + //Draw viewmodel + { + Vector3d position = EntityUtils.getPosition(Globals.firstPersonEntity); + Actor actor = EntityUtils.getActor(Globals.firstPersonEntity); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + //calculate and apply model transform + modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(EntityUtils.getRotation(Globals.firstPersonEntity)); + modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(Globals.firstPersonEntity))); + actor.applySpatialData(modelTransformMatrix,position); + //draw + actor.draw(renderPipelineState, openGLState); + } + + //draw children of viewmodel + if(AttachUtils.hasChildren(Globals.firstPersonEntity)){ + for(Entity child : AttachUtils.getChildrenList(Globals.firstPersonEntity)){ + Vector3d position = EntityUtils.getPosition(child); + Actor actor = EntityUtils.getActor(child); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + //calculate and apply model transform + modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(EntityUtils.getRotation(child)); + modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(child))); + actor.applySpatialData(modelTransformMatrix,position); + //draw + actor.draw(renderPipelineState, openGLState); + } + } + + } - //setup opengl state - this.firstPersonFramebuffer.bind(openGLState); - renderPipelineState.setUseBones(true); - renderPipelineState.setUseLight(false); - renderPipelineState.setUseMaterial(true); - renderPipelineState.setUseMeshShader(true); - renderPipelineState.setUseShadowMap(false); - renderPipelineState.setBufferStandardUniforms(true); - renderPipelineState.setFrustumCheck(false); - - openGLState.glDepthTest(true); - openGLState.glDepthFunc(GL40.GL_LESS); - GL40.glDepthMask(true); - - //clear - GL40.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - GL40.glClear(GL40.GL_COLOR_BUFFER_BIT); - GL40.glClear(GL40.GL_DEPTH_BUFFER_BIT); - - - //render - if( - !Globals.controlHandler.cameraIsThirdPerson() && - Globals.firstPersonEntity != null - ){ - Vector3d position = EntityUtils.getPosition(Globals.firstPersonEntity); - Actor actor = EntityUtils.getActor(Globals.firstPersonEntity); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - //calculate and apply model transform - modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(EntityUtils.getRotation(Globals.firstPersonEntity)); - modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(Globals.firstPersonEntity))); - actor.applySpatialData(modelTransformMatrix,position); - - //draw - actor.draw(renderPipelineState, openGLState); - } - - //finish up - openGLState.glBindFramebuffer(GL_FRAMEBUFFER,0); - } - - /** - * Gets the framebuffer of the pipeline - * @return the framebuffer - */ - public Framebuffer getFramebuffer(){ - return this.firstPersonFramebuffer; } /** @@ -116,6 +106,11 @@ public class FirstPersonItemsPipeline implements RenderPipeline { Vector4d behindCameraOffsetRaw = rotationMat.transform(new Vector4d(0,tree.getCameraViewDirOffsetY(),tree.getCameraViewDirOffsetZ(),1)); //pushes the model behind the camera Vector3d behindCameraOffset = new Vector3d(behindCameraOffsetRaw.x,behindCameraOffsetRaw.y,behindCameraOffsetRaw.z); EntityUtils.getPosition(Globals.firstPersonEntity).set(playerPos).add(0.0f,tree.getHeightFromOrigin(),0.0f).add(behindCameraOffset); + + if(ClientEquipState.hasEquipState(Globals.playerEntity)){ + ClientEquipState clientEquipState = ClientEquipState.getClientEquipState(Globals.playerEntity); + clientEquipState.evaluatePlayerAttachments(); + } } } diff --git a/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java b/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java index c3edd591..29ba4ad4 100644 --- a/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java @@ -13,6 +13,7 @@ import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityTags; import electrosphere.entity.EntityUtils; +import electrosphere.entity.types.attach.AttachUtils; import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; @@ -27,6 +28,9 @@ import electrosphere.renderer.buffer.ShaderAttribute; */ public class MainContentPipeline implements RenderPipeline { + //First person drawing routine + FirstPersonItemsPipeline firstPersonSubPipeline; + @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { Globals.profiler.beginCpuSample("MainContentPipeline.render"); @@ -114,6 +118,7 @@ public class MainContentPipeline implements RenderPipeline { } //draw all instanced models Globals.clientInstanceManager.draw(renderPipelineState,openGLState); + this.firstPersonSubPipeline.render(openGLState, renderPipelineState); // // Pass Two: Transparency Accumulator + Revealage @@ -255,8 +260,24 @@ public class MainContentPipeline implements RenderPipeline { ( !Globals.controlHandler.cameraIsThirdPerson() && entity == Globals.playerEntity + ) || + + //don't draw items if they're attached to viewmodel + ( + !Globals.controlHandler.cameraIsThirdPerson() && + AttachUtils.hasParent(entity) && + Globals.firstPersonEntity != null && + AttachUtils.getParent(entity) == Globals.firstPersonEntity ) ; } + + /** + * Get the first person pipeline + * @param firstPersonItemsPipeline the first person pipeline + */ + public void setFirstPersonPipeline(FirstPersonItemsPipeline firstPersonItemsPipeline){ + this.firstPersonSubPipeline = firstPersonItemsPipeline; + } }