Renderer/src/main/java/electrosphere/controls/CameraHandler.java
austin 9c672af15f
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
character creation menu work
2024-11-29 19:05:14 -05:00

245 lines
9.6 KiB
Java

package electrosphere.controls;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import electrosphere.client.entity.camera.CameraEntityUtils;
import electrosphere.client.entity.crosshair.Crosshair;
import electrosphere.collision.CollisionEngine;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.ui.events.MouseEvent;
import electrosphere.util.math.SpatialMathUtils;
/**
* Handler for camera-related events and controls
*/
public class CameraHandler {
//The first person camera perspective
public static final int CAMERA_PERSPECTIVE_FIRST = 1;
//The third person camera perspective
public static final int CAMERA_PERSPECTIVE_THIRD = 3;
//the horizontal mouse sensitivity
float mouseSensitivityHorizontal = .1f;
//the vertical mouse sensitivity
float mouseSensitivityVertical = .08f;
//the speed of the freecam
float cameraSpeed;
//the current yaw
float yaw = 150;
//the current pitch
float pitch = 50;
//the camera's rotation vector
Vector3f cameraRotationVector = new Vector3f();
//the radial offset of the camera
Vector3f radialOffset = new Vector3f(0,1,0);
//if set to true, the camera will track the player's entity
boolean trackPlayerEntity = true;
//sets whether the camera handler should update the player's camera or not
boolean update = true;
/**
* Handles a mouse event
* @param event The mouse event
*/
public void handleMouseEvent(MouseEvent event){
if(Globals.controlHandler != null && !Globals.controlHandler.isMouseVisible()){
yaw = yaw + event.getDeltaX() * mouseSensitivityHorizontal;
pitch = pitch + event.getDeltaY() * mouseSensitivityVertical;
if (pitch >= 89.9f) {
pitch = 89.9f;
}
if (pitch <= -89.9f) {
pitch = -89.9f;
}
}
this.updateGlobalCamera();
}
/**
* Updates the radial offset
* @param offset the radial offset
*/
public void updateRadialOffset(Vector3f offset){
radialOffset = offset;
}
/**
* Updates the global camera
*/
public void updateGlobalCamera(){
Globals.profiler.beginCpuSample("updateGlobalCamera");
if(update){
if(Globals.playerCamera != null){
cameraSpeed = 2.5f * (float)Globals.timekeeper.getMostRecentRawFrametime();
if(Crosshair.getCrosshairActive()){
// if(Globals.playerCharacter != null){
// Vector3d charPos = EntityUtils.getPosition(Globals.playerCharacter);
// CameraEntityUtils.setCameraCenter(Globals.playerCamera, new Vector3f((float)charPos.x,(float)charPos.y,(float)charPos.z));
// }
Vector3d characterPos = EntityUtils.getPosition(Globals.playerEntity);
Vector3d targetPos = Crosshair.getTargetPosition();
Vector3d diffed = new Vector3d(targetPos).sub(characterPos).mul(-1).normalize();
cameraRotationVector.set((float)diffed.x, 0.5f, (float)diffed.z).normalize();
yaw = (float)Math.toDegrees(Math.atan2(diffed.z, diffed.x));
CameraEntityUtils.setCameraPitch(Globals.playerCamera, pitch);
CameraEntityUtils.setCameraYaw(Globals.playerCamera, yaw);
} else {
CameraEntityUtils.setCameraPitch(Globals.playerCamera, pitch);
CameraEntityUtils.setCameraYaw(Globals.playerCamera, yaw);
// System.out.println(pitch);
// if(Globals.playerCharacter != null){
// Vector3d charPos = EntityUtils.getPosition(Globals.playerCharacter);
// CameraEntityUtils.setCameraCenter(Globals.playerCamera, new Vector3f((float)charPos.x,(float)charPos.y,(float)charPos.z));
// }
Quaternionf pitchQuat = new Quaternionf().fromAxisAngleDeg(SpatialMathUtils.getLeftVectorf(), -pitch);
Quaternionf yawQuat = new Quaternionf().fromAxisAngleDeg(SpatialMathUtils.getUpVectorf(), -yaw);
// float yawRad = yaw / 180.0f * (float)Math.PI;
// float pitchRad = pitch / 180.0f * (float)Math.PI;
// float rollRad = 0.0f;
// pitchQuat.mul(yawQuat);
cameraRotationVector = pitchQuat.transform(SpatialMathUtils.getOriginVectorf());
cameraRotationVector = yawQuat.transform(cameraRotationVector);
cameraRotationVector.normalize();
// cameraRotationVector.x = 0 + (float) Math.cos(yaw / 180.0f * Math.PI) * 1;
// cameraRotationVector.y = 0 + (float) Math.sin(pitch / 180.0f * Math.PI) * 1;
// cameraRotationVector.z = 0 + (float) Math.sin(yaw / 180.0f * Math.PI) * 1;
// cameraRotationVector.normalize();
// System.out.println(yaw + " " + pitch);
}
if(trackPlayerEntity && Globals.playerEntity != null){
Vector3d entityPos = EntityUtils.getPosition(Globals.playerEntity);
CameraEntityUtils.setCameraCenter(Globals.playerCamera, new Vector3f((float)entityPos.x,(float)entityPos.y,(float)entityPos.z).add(CameraEntityUtils.getOrbitalCameraRadialOffset(Globals.playerCamera)));
}
//update view matrix offset
float xFactor = (float)Math.cos(yaw / 180.0f * Math.PI);
float yFactor = (float)Math.sin(yaw / 180.0f * Math.PI);
Vector3f radialOffset = CameraEntityUtils.getOrbitalCameraRadialOffset(Globals.playerCamera);
Vector3f trueOffset = new Vector3f(radialOffset).mul(xFactor,1.0f,yFactor);
CameraEntityUtils.setOrbitalCameraRadialOffset(Globals.playerCamera, trueOffset);
cameraRotationVector.mul(CameraEntityUtils.getOrbitalCameraDistance(Globals.playerCamera));
CameraEntityUtils.setCameraEye(Globals.playerCamera, cameraRotationVector);
//tell the server that we changed where we're looking, if we're in first person
int perspectiveVal = CameraHandler.CAMERA_PERSPECTIVE_FIRST;
if(Globals.controlHandler.cameraIsThirdPerson()){
perspectiveVal = CameraHandler.CAMERA_PERSPECTIVE_THIRD;
}
if(Globals.cameraHandler.getTrackPlayerEntity() && Globals.playerEntity != null){
Globals.clientConnection.queueOutgoingMessage(
EntityMessage.constructupdateEntityViewDirMessage(
Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()),
Globals.timekeeper.getNumberOfSimFramesElapsed(),
perspectiveVal,
yaw,
pitch
)
);
}
//the view matrix
Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera);
//update the cursor on client side
this.updatePlayerCursor();
}
}
Globals.profiler.endCpuSample();
}
/**
* Updates the position of the player's in world cursor
*/
private void updatePlayerCursor(){
CollisionEngine collisionEngine = Globals.clientSceneWrapper.getCollisionEngine();
Entity camera = Globals.playerCamera;
if(
collisionEngine != null &&
camera != null &&
Globals.playerCursor != null
){
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(camera));
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(camera));
Vector3d cursorPos = collisionEngine.rayCastPosition(centerPos, new Vector3d(eyePos).mul(-1.0), CollisionEngine.DEFAULT_INTERACT_DISTANCE);
if(cursorPos != null){
EntityUtils.getPosition(Globals.playerCursor).set(cursorPos);
} else {
EntityUtils.getPosition(Globals.playerCursor).set(new Vector3d(centerPos).add(new Vector3d(eyePos).normalize().mul(-CollisionEngine.DEFAULT_INTERACT_DISTANCE)));
}
}
}
/**
* Gets the yaw of the camera handler
* @return the yaw
*/
public float getYaw(){
return yaw;
}
/**
* Sets the yaw of the camera handler
* @param yaw The yaw
*/
public void setYaw(double yaw){
this.yaw = (float)yaw;
}
/**
* Gets the pitch of the camera handler
* @return the pitch
*/
public float getPitch(){
return pitch;
}
/**
* Sets the pitch of the camera handler
* @param pitch The pitch
*/
public void setPitch(double pitch){
this.pitch = (float)pitch;
}
//set player tracking
public void setTrackPlayerEntity(boolean track){
trackPlayerEntity = track;
}
//get trackPlayerEntity
public boolean getTrackPlayerEntity(){
return trackPlayerEntity;
}
/**
* Sets whether the camera should update with player input or not
* @param update true to update with input, false otherwise
*/
public void setUpdate(boolean update){
this.update = update;
}
}