Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
226 lines
8.4 KiB
Java
226 lines
8.4 KiB
Java
package electrosphere.controls;
|
|
|
|
import org.joml.Quaterniond;
|
|
import org.joml.Vector3d;
|
|
|
|
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
|
|
Vector3d cameraRotationVector = new Vector3d();
|
|
//the radial offset of the camera
|
|
Vector3d radialOffset = new Vector3d(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(Vector3d 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()){
|
|
|
|
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);
|
|
|
|
Quaterniond pitchQuat = new Quaterniond().fromAxisAngleDeg(SpatialMathUtils.getLeftVector(), -pitch);
|
|
Quaterniond yawQuat = new Quaterniond().fromAxisAngleDeg(SpatialMathUtils.getUpVector(), -yaw);
|
|
|
|
cameraRotationVector = pitchQuat.transform(SpatialMathUtils.getOriginVector());
|
|
cameraRotationVector = yawQuat.transform(cameraRotationVector);
|
|
cameraRotationVector.normalize();
|
|
}
|
|
if(trackPlayerEntity && Globals.playerEntity != null){
|
|
Vector3d entityPos = EntityUtils.getPosition(Globals.playerEntity);
|
|
CameraEntityUtils.setCameraCenter(Globals.playerCamera, new Vector3d(entityPos).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);
|
|
Vector3d radialOffset = CameraEntityUtils.getOrbitalCameraRadialOffset(Globals.playerCamera);
|
|
Vector3d trueOffset = new Vector3d(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){
|
|
cursorPos = new Vector3d(centerPos).add(new Vector3d(eyePos).normalize().mul(-CollisionEngine.DEFAULT_INTERACT_DISTANCE));
|
|
}
|
|
EntityUtils.getPosition(Globals.playerCursor).set(cursorPos);
|
|
|
|
//clamp block cursor to nearest voxel
|
|
cursorPos.set(PlayerCursor.clampPositionToNearestBlock(cursorPos));
|
|
EntityUtils.getPosition(Globals.playerBlockCursor).set(cursorPos);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|