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.joml.Vector4d; import org.lwjgl.opengl.GL40; 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; /** * Renders content that should only be rendered in first person (ie the view model/hands/whatever) */ public class FirstPersonItemsPipeline implements RenderPipeline { //internal model matrix Matrix4d modelTransformMatrix = new Matrix4d(); @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { 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); } } } } /** * Updates the position and rotation of the first person model */ private void updateFirstPersonModelPosition(Entity target){ FirstPersonTree tree = FirstPersonTree.getTree(target); Quaternionf quatRaw = CameraEntityUtils.getYawQuat(Globals.playerCamera).mul(CameraEntityUtils.getPitchQuat(Globals.playerCamera)); Quaterniond quatd = new Quaterniond(quatRaw).normalize(); EntityUtils.getRotation(Globals.firstPersonEntity).set(quatd); Matrix4d rotationMat = new Matrix4d().rotate(quatd); Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity); 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(); } } }