Cleanup Camera class

This commit is contained in:
UnknownShadow200 2018-07-03 02:57:05 +10:00
parent 4c47fb9f8b
commit 92827b419f
12 changed files with 130 additions and 147 deletions

View File

@ -216,7 +216,7 @@ namespace ClassicalSharp.Gui.Screens {
LocationUpdate update = LocationUpdate.MakePosAndOri(spawn, 0, 0, false);
game.LocalPlayer.SetLocation(update, false);
game.LocalPlayer.Spawn = spawn;
game.CurrentCameraPos = game.Camera.GetCameraPos(0);
game.CurrentCameraPos = game.Camera.GetPosition(0);
}
}
}

View File

@ -289,7 +289,7 @@ namespace ClassicalSharp {
LocalPlayer.SetInterpPosition(t);
if (!SkipClear) Graphics.Clear();
CurrentCameraPos = Camera.GetCameraPos(t);
CurrentCameraPos = Camera.GetPosition(t);
UpdateViewMatrix();
bool visible = Gui.activeScreen == null || !Gui.activeScreen.BlocksWorld;

View File

@ -214,6 +214,17 @@ namespace ClassicalSharp.Network {
return -1;
}
static DateTime GetLastModified(HttpWebResponse response) {
// System.NotSupportedException: Can't get timezone name.
// gets thrown on some platforms with DateTime.Now
try {
if (response.Headers.Get("Last-Modified") != null)
return response.LastModified;
} catch (NotSupportedException) {
}
return DateTime.MinValue;
}
void ProcessRequest(Request request) {
string url = request.Url;
Utils.LogDebug("Downloading {0} from: {1}", request.Type, url);
@ -223,9 +234,7 @@ namespace ClassicalSharp.Network {
HttpWebRequest req = MakeRequest(request);
using (HttpWebResponse response = (HttpWebResponse)req.GetResponse()) {
request.ETag = response.Headers.Get("ETag");
if (response.Headers.Get("Last-Modified") != null) {
request.LastModified = response.LastModified;
}
request.LastModified = GetLastModified(response);
request.Data = DownloadContent(request, response);
}
} catch (Exception ex) {

View File

@ -79,12 +79,12 @@ namespace ClassicalSharp.Renderers {
Matrix4.Mult(out m, ref m, ref rotX);
// Rotate around camera
Vector2 rotation = game.Camera.GetCameraOrientation();
Vector2 rotation = game.Camera.GetOrientation();
Matrix4.RotateY(out rotY, rotation.X); // Camera yaw
Matrix4.Mult(out m, ref m, ref rotY);
Matrix4.RotateX(out rotX, rotation.Y); // Cammera pitch
Matrix4.Mult(out m, ref m, ref rotX);
Matrix4.Mult(out m, ref m, ref game.Camera.tiltM);
Matrix4.Mult(out m, ref m, ref Camera.tiltM);
game.Graphics.LoadMatrix(ref m);
game.Graphics.BindVb(vb);

View File

@ -90,7 +90,7 @@ namespace ClassicalSharp.Renderers {
Matrix4 m, lookAt;
Matrix4.LookAt(eyePos, eyePos - Vector3.UnitZ, Vector3.UnitY, out lookAt);
Matrix4.Mult(out m, ref lookAt, ref game.Camera.tiltM);
Matrix4.Mult(out m, ref lookAt, ref Camera.tiltM);
game.Graphics.View = m;
}
@ -100,9 +100,9 @@ namespace ClassicalSharp.Renderers {
Vector3 eyePos = Vector3.Zero; eyePos.Y = p.EyeHeight;
held.Position = eyePos;
held.Position.X -= game.Camera.bobbingHor;
held.Position.Y -= game.Camera.bobbingVer;
held.Position.Z -= game.Camera.bobbingHor;
held.Position.X -= Camera.bobbingHor;
held.Position.Y -= Camera.bobbingVer;
held.Position.Z -= Camera.bobbingHor;
held.HeadY = -45; held.RotY = -45;
held.HeadX = 0; held.RotX = 0;

View File

@ -9,52 +9,23 @@ namespace ClassicalSharp {
public abstract class Camera {
protected Game game;
protected internal Matrix4 tiltM;
internal float bobbingVer, bobbingHor;
internal static Matrix4 tiltM;
internal static float bobbingVer, bobbingHor;
/// <summary> Calculates the projection matrix for this camera. </summary>
public abstract void GetProjection(out Matrix4 m);
/// <summary> Calculates the world/view matrix for this camera. </summary>
public abstract void GetView(out Matrix4 m);
/// <summary> Calculates the location of the camera's position in the world. </summary>
public abstract Vector3 GetCameraPos(float t);
public abstract Vector2 GetOrientation();
public abstract Vector3 GetPosition(float t);
public abstract Vector3 GetTarget();
/// <summary> Calculates the yaw and pitch of the camera in radians. </summary>
public abstract Vector2 GetCameraOrientation();
/// <summary> Whether this camera is using a third person perspective. </summary>
/// <remarks> Causes the player's own entity model to be renderered if true. </remarks>
public abstract bool IsThirdPerson { get; }
/// <summary> Attempts to zoom the camera's position closer to or further from its origin point. </summary>
/// <returns> true if this camera handled zooming </returns>
/// <example> Third person cameras override this method to zoom in or out, and hence return true.
/// The first person camera does not perform zomming, so returns false. </example>
public virtual bool Zoom(float amount) { return false; }
/// <summary> Called every frame for the camera to update its state. </summary>
/// <example> The perspective cameras gets delta between mouse cursor's current position and the centre of the window,
/// then uses this to adjust the player's horizontal and vertical rotation. </example>
public abstract void UpdateMouse();
/// <summary> Called after the camera has regrabbed the mouse from 2D input handling. </summary>
/// <example> The perspective cameras set the mouse cursor to the centre of the window. </example>
public abstract void RegrabMouse();
/// <summary> Calculates the picked block based on the camera's current state. </summary>
public virtual void GetPickedBlock(PickedPos pos) { }
/// <summary> Adjusts the head X rotation of the player to avoid looking straight up or down. </summary>
/// <remarks> Looking straight up or down (parallel to camera up vector) can otherwise cause rendering issues. </remarks>
protected float AdjustHeadX(float value) {
if (value >= 90.0f && value <= 90.1f) return 90.1f * Utils.Deg2Rad;
if (value >= 89.9f && value <= 90.0f) return 89.9f * Utils.Deg2Rad;
if (value >= 270.0f && value <= 270.1f) return 270.1f * Utils.Deg2Rad;
if (value >= 269.9f && value <= 270.0f) return 269.9f * Utils.Deg2Rad;
return value * Utils.Deg2Rad;
}
public abstract void GetPickedBlock(PickedPos pos);
}
public abstract class PerspectiveCamera : Camera {
@ -67,7 +38,15 @@ namespace ClassicalSharp {
}
protected Vector3 GetDirVector() {
return Utils.GetDirVector(player.HeadYRadians, AdjustHeadX(player.HeadX));
Vector2 rot = GetOrientation();
Vector3 dir = Utils.GetDirVector(rot.X, rot.Y);
// Adjusts pitch of the player to avoid looking straight up or down,
// as pitch parallel to camera up vector causes rendering issues
if (dir.Y > +0.999998f) dir.Y = +0.999998f;
if (dir.Y < -0.999998f) dir.Y = -0.999998f;
return dir;
}
public override void GetProjection(out Matrix4 m) {
@ -77,6 +56,12 @@ namespace ClassicalSharp {
game.Graphics.CalcPerspectiveMatrix(fov, aspectRatio, zNear, game.ViewDistance, out m);
}
public override void GetView(out Matrix4 m) {
Vector3 pos = game.CurrentCameraPos, target = GetTarget();
Matrix4.LookAt(pos, target, Vector3.UnitY, out m);
Matrix4.Mult(out m, ref m, ref tiltM);
}
public override void GetPickedBlock(PickedPos pos) {
Vector3 dir = GetDirVector();
Vector3 eyePos = player.EyePosition;
@ -172,52 +157,40 @@ namespace ClassicalSharp {
return true;
}
public override void GetView(out Matrix4 m) {
Vector3 camPos = game.CurrentCameraPos;
Vector3 eyePos = player.EyePosition;
eyePos.Y += bobbingVer;
Matrix4 lookAt;
Matrix4.LookAt(camPos, eyePos, Vector3.UnitY, out lookAt);
Matrix4.Mult(out m, ref lookAt, ref tiltM);
}
public override Vector2 GetCameraOrientation() {
if (!forward)
public override Vector2 GetOrientation() {
if (!forward) {
return new Vector2(player.HeadYRadians, player.HeadXRadians);
return new Vector2(player.HeadYRadians + (float)Math.PI, -player.HeadXRadians);
} else {
return new Vector2(player.HeadYRadians + (float)Math.PI, -player.HeadXRadians);
}
}
public override Vector3 GetCameraPos(float t) {
public override Vector3 GetPosition(float t) {
CalcViewBobbing(t, dist);
Vector3 eyePos = player.EyePosition;
eyePos.Y += bobbingVer;
Vector3 dir = GetDirVector();
if (!forward) dir = -dir;
Vector3 dir = -GetDirVector();
Picking.ClipCameraPos(game, eyePos, dir, dist, game.CameraClipPos);
return game.CameraClipPos.Intersect;
}
public override Vector3 GetTarget() {
Vector3 eyePos = player.EyePosition;
eyePos.Y += bobbingVer;
return eyePos;
}
}
public class FirstPersonCamera : PerspectiveCamera {
public FirstPersonCamera(Game window) : base(window) { }
public override bool IsThirdPerson { get { return false; } }
public override void GetView(out Matrix4 m) {
Vector3 camPos = game.CurrentCameraPos;
Vector3 dir = GetDirVector();
Matrix4 lookAt;
Matrix4.LookAt(camPos, camPos + dir, Vector3.UnitY, out lookAt);
Matrix4.Mult(out m, ref lookAt, ref tiltM);
}
public override Vector2 GetCameraOrientation() {
public override Vector2 GetOrientation() {
return new Vector2(player.HeadYRadians, player.HeadXRadians);
}
public override Vector3 GetCameraPos(float t) {
public override Vector3 GetPosition(float t) {
CalcViewBobbing(t, 1);
Vector3 camPos = player.EyePosition;
camPos.Y += bobbingVer;
@ -227,5 +200,11 @@ namespace ClassicalSharp {
camPos.Z += bobbingHor * (float)Math.Sin(headY);
return camPos;
}
public override Vector3 GetTarget() {
Vector3 camPos = game.CurrentCameraPos;
Vector3 dir = GetDirVector();
return camPos + dir;
}
}
}

View File

@ -1,6 +1,7 @@
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
using System;
using System.Collections.Generic;
using ClassicalSharp;
namespace Launcher.Patcher {
@ -105,7 +106,7 @@ namespace Launcher.Patcher {
public static string GetFile(string path) {
// Ignore directories: convert x/name to name and x\name to name.
string name = path.ToLower();
string name = Utils.ToLower(path);
int i = name.LastIndexOf('\\');
if (i >= 0) name = name.Substring(i + 1, name.Length - 1 - i);
i = name.LastIndexOf('/');

View File

@ -7,19 +7,17 @@
#include "Gui.h"
#include "Entity.h"
Real32 Camera_AdjustHeadX(Real32 value) {
if (value >= 90.00f && value <= 90.10f) return 90.10f * MATH_DEG2RAD;
if (value >= 89.90f && value <= 90.00f) return 89.90f * MATH_DEG2RAD;
if (value >= 270.0f && value <= 270.1f) return 270.1f * MATH_DEG2RAD;
if (value >= 269.9f && value <= 270.0f) return 269.9f * MATH_DEG2RAD;
return value * MATH_DEG2RAD;
}
static Vector3 PerspectiveCamera_GetDirVector(void) {
Entity* p = &LocalPlayer_Instance.Base;
Real32 yaw = p->HeadY * MATH_DEG2RAD;
Real32 pitch = Camera_AdjustHeadX(p->HeadX);
return Vector3_GetDirVector(yaw, pitch);
Vector2 rot = Camera_Active->GetOrientation();
Vector3 dir = Vector3_GetDirVector(rot.X, rot.Y);
/* Adjusts pitch of the player to avoid looking straight up or down, */
/* as pitch parallel to camera up vector causes rendering issues */
if (dir.Y > +0.999998f) dir.Y = +0.999998f;
if (dir.Y < -0.999998f) dir.Y = -0.999998f;
return dir;
}
static void PerspectiveCamera_GetProjection(Matrix* proj) {
@ -28,6 +26,14 @@ static void PerspectiveCamera_GetProjection(Matrix* proj) {
Matrix_PerspectiveFieldOfView(proj, fovy, aspectRatio, Gfx_MinZNear, (Real32)Game_ViewDistance);
}
static void PerspectiveCamera_GetView(Matrix* mat) {
Vector3 pos = Game_CurrentCameraPos, target = Camera_Active->GetTarget();
Vector3 up = Vector3_UnitY;
Matrix_LookAt(mat, pos, target, up);
Matrix_MulBy(mat, &Camera_TiltM);
}
static void PerspectiveCamera_GetPickedBlock(PickedPos* pos) {
Entity* p = &LocalPlayer_Instance.Base;
Vector3 dir = PerspectiveCamera_GetDirVector();
@ -119,23 +125,20 @@ static void PerspectiveCamera_CalcViewBobbing(Real32 t, Real32 velTiltScale) {
static void PerspectiveCamera_Init(Camera* cam) {
cam->GetProjection = PerspectiveCamera_GetProjection;
cam->GetView = PerspectiveCamera_GetView;
cam->UpdateMouse = PerspectiveCamera_UpdateMouse;
cam->RegrabMouse = PerspectiveCamera_RegrabMouse;
cam->GetPickedBlock = PerspectiveCamera_GetPickedBlock;
}
static void FirstPersonCamera_GetView(Matrix* mat) {
Vector3 camPos = Game_CurrentCameraPos;
Vector3 dir = PerspectiveCamera_GetDirVector();
Vector3 targetPos; Vector3_Add(&targetPos, &camPos, &dir);
Vector3 up = Vector3_UnitY;
Matrix_LookAt(mat, camPos, targetPos, up);
Matrix_MulBy(mat, &Camera_TiltM);
static Vector2 FirstPersonCamera_GetOrientation(void) {
Entity* p = &LocalPlayer_Instance.Base;
Vector2 ori = { p->HeadY * MATH_DEG2RAD, p->HeadX * MATH_DEG2RAD };
return ori;
}
static Vector3 FirstPersonCamera_GetCameraPos(Real32 t) {
static Vector3 FirstPersonCamera_GetPosition(Real32 t) {
PerspectiveCamera_CalcViewBobbing(t, 1);
Entity* p = &LocalPlayer_Instance.Base;
Vector3 camPos = Entity_GetEyePosition(p);
@ -147,10 +150,11 @@ static Vector3 FirstPersonCamera_GetCameraPos(Real32 t) {
return camPos;
}
static Vector2 FirstPersonCamera_GetCameraOrientation(void) {
Entity* p = &LocalPlayer_Instance.Base;
Vector2 ori = { p->HeadY * MATH_DEG2RAD, p->HeadX * MATH_DEG2RAD };
return ori;
static Vector3 FirstPersonCamera_GetTarget(void) {
Vector3 pos = Game_CurrentCameraPos;
Vector3 dir = PerspectiveCamera_GetDirVector();
Vector3 target; Vector3_Add(&target, &pos, &dir);
return target;
}
static bool FirstPersonCamera_Zoom(Real32 amount) { return false; }
@ -158,9 +162,9 @@ static bool FirstPersonCamera_Zoom(Real32 amount) { return false; }
static void FirstPersonCamera_Init(Camera* cam) {
PerspectiveCamera_Init(cam);
cam->IsThirdPerson = false;
cam->GetView = FirstPersonCamera_GetView;
cam->GetCameraPos = FirstPersonCamera_GetCameraPos;
cam->GetCameraOrientation = FirstPersonCamera_GetCameraOrientation;
cam->GetOrientation = FirstPersonCamera_GetOrientation;
cam->GetPosition = FirstPersonCamera_GetPosition;
cam->GetTarget = FirstPersonCamera_GetTarget;
cam->Zoom = FirstPersonCamera_Zoom;
}
@ -177,38 +181,44 @@ static void ThirdPersonCamera_GetView(Matrix* mat) {
Matrix_MulBy(mat, &Camera_TiltM);
}
static Vector3 ThirdPersonCamera_GetCameraPosShared(Real32 t, Real32 dist, bool forward) {
static Vector2 ThirdPersonCamera_GetOrientation(void) {
Entity* p = &LocalPlayer_Instance.Base;
Vector2 ori = { p->HeadY * MATH_DEG2RAD, p->HeadX * MATH_DEG2RAD };
return ori;
}
static Vector2 ForwardThirdPersonCamera_GetOrientation(void) {
Entity* p = &LocalPlayer_Instance.Base;
Vector2 ori = { p->HeadY * MATH_DEG2RAD + MATH_PI, -p->HeadX * MATH_DEG2RAD };
return ori;
}
static Vector3 ThirdPersonCamera_GetPositionShared(Real32 t, Real32 dist) {
PerspectiveCamera_CalcViewBobbing(t, dist);
Entity* p = &LocalPlayer_Instance.Base;
Vector3 eyePos = Entity_GetEyePosition(p);
eyePos.Y += Camera_BobbingVer;
Vector3 dir = PerspectiveCamera_GetDirVector();
if (!forward) Vector3_Negate(&dir, &dir);
Vector3_Negate(&dir, &dir);
Picking_ClipCameraPos(eyePos, dir, dist, &Game_CameraClipPos);
return Game_CameraClipPos.Intersect;
}
static Vector3 ThirdPersonCamera_GetCameraPos(Real32 t) {
return ThirdPersonCamera_GetCameraPosShared(t, dist_third, false);
static Vector3 ThirdPersonCamera_GetPosition(Real32 t) {
return ThirdPersonCamera_GetPositionShared(t, dist_third);
}
static Vector3 ForwardThirdPersonCamera_GetCameraPos(Real32 t) {
return ThirdPersonCamera_GetCameraPosShared(t, dist_forward, true);
static Vector3 ForwardThirdPersonCamera_GetPosition(Real32 t) {
return ThirdPersonCamera_GetPositionShared(t, dist_forward);
}
static Vector2 ThirdPersonCamera_GetCameraOrientation(void) {
static Vector3 ThirdPersonCamera_GetTarget(void) {
Entity* p = &LocalPlayer_Instance.Base;
Vector2 ori = { p->HeadY * MATH_DEG2RAD, p->HeadX * MATH_DEG2RAD };
return ori;
}
static Vector2 ForwardThirdPersonCamera_GetCameraOrientation(void) {
Entity* p = &LocalPlayer_Instance.Base;
Vector2 ori = { p->HeadY * MATH_DEG2RAD + MATH_PI, -p->HeadX * MATH_DEG2RAD };
return ori;
Vector3 eyePos = Entity_GetEyePosition(p);
eyePos.Y += Camera_BobbingVer;
return eyePos;
}
static bool ThirdPersonCamera_Zoom(Real32 amount) {
@ -217,7 +227,6 @@ static bool ThirdPersonCamera_Zoom(Real32 amount) {
return true;
}
static bool ForwardThirdPersonCamera_Zoom(Real32 amount) {
dist_forward -= amount;
if (dist_forward < 2.0f) dist_forward = 2.0f;
@ -227,19 +236,20 @@ static bool ForwardThirdPersonCamera_Zoom(Real32 amount) {
static void ThirdPersonCamera_Init(Camera* cam) {
PerspectiveCamera_Init(cam);
cam->IsThirdPerson = true;
cam->GetView = ThirdPersonCamera_GetView;
cam->GetCameraPos = ThirdPersonCamera_GetCameraPos;
cam->GetCameraOrientation = ThirdPersonCamera_GetCameraOrientation;
cam->GetOrientation = ThirdPersonCamera_GetOrientation;
cam->GetPosition = ThirdPersonCamera_GetPosition;
cam->GetTarget = ThirdPersonCamera_GetTarget;
cam->Zoom = ThirdPersonCamera_Zoom;
}
static void ForwardThirdPersonCamera_Init(Camera* cam) {
ThirdPersonCamera_Init(cam);
cam->GetCameraPos = ForwardThirdPersonCamera_GetCameraPos;
cam->GetCameraOrientation = ForwardThirdPersonCamera_GetCameraOrientation;
cam->GetOrientation = ForwardThirdPersonCamera_GetOrientation;
cam->GetPosition = ForwardThirdPersonCamera_GetPosition;
cam->Zoom = ForwardThirdPersonCamera_Zoom;
}
Camera Camera_Cameras[3];
Int32 Camera_ActiveIndex;
void Camera_Init(void) {

View File

@ -10,37 +10,21 @@ Matrix Camera_TiltM;
Real32 Camera_BobbingVer, Camera_BobbingHor;
typedef struct Camera_ {
/* Whether this camera is a third person camera.
NOTE: Causes the player's own entity model to be renderered if true.*/
bool IsThirdPerson;
/* Calculates the projection matrix for this camera. */
void (*GetProjection)(Matrix* proj);
/* Calculates the world/view matrix for this camera. */
void (*GetView)(Matrix* view);
/* Calculates the location of the camera's position in the world. */
Vector3 (*GetCameraPos)(Real32 t);
/* Calculates the yaw and pitch of the camera in radians. */
Vector2 (*GetCameraOrientation)(void);
/* Called every frame for the camera to update its state.
e.g. Perspective cameras adjusts player's rotatation using delta between mouse position and window centre. */
Vector2 (*GetOrientation)(void);
Vector3 (*GetPosition)(Real32 t);
Vector3 (*GetTarget)(void);
void (*UpdateMouse)(void);
/* Called after the camera has regrabbed the mouse from 2D input handling.
e.g. Perspective cameras set the mouse position to window centre. */
void (*RegrabMouse)(void);
/* Calculates the picked block based on the camera's current state. */
void (*GetPickedBlock)(PickedPos* pos);
/* Attempts to zoom the camera's position closer to or further from its origin point.
returns true if this camera handled zooming (Such as third person cameras) */
bool (*Zoom)(Real32 amount);
} Camera;
/* Adjusts head X rotation of the player to avoid looking straight up or down. Returns result angle in radians.
NOTE: looking straight up or down (parallel to camera up vector) can otherwise cause rendering issues. */
Real32 Camera_AdjustHeadX(Real32 degrees);
Camera* Camera_Active;
void Camera_Init(void);
void Camera_CycleActive(void);

View File

@ -693,7 +693,7 @@ static void Game_RenderFrame(Real64 delta) {
LocalPlayer_SetInterpPosition(t);
if (!Game_SkipClear) Gfx_Clear();
Game_CurrentCameraPos = Camera_Active->GetCameraPos(t);
Game_CurrentCameraPos = Camera_Active->GetPosition(t);
Game_UpdateViewMatrix();
bool visible = Gui_Active == NULL || !Gui_Active->BlocksWorld;

View File

@ -661,7 +661,7 @@ static void GeneratingScreen_EndGeneration(void) {
LocationUpdate update; LocationUpdate_MakePosAndOri(&update, p->Spawn, 0.0f, 0.0f, false);
p->Base.VTABLE->SetLocation(&p->Base, &update, false);
Game_CurrentCameraPos = Camera_Active->GetCameraPos(0.0f);
Game_CurrentCameraPos = Camera_Active->GetPosition(0.0f);
Event_RaiseVoid(&WorldEvents_MapLoaded);
}

View File

@ -49,7 +49,7 @@ void SkyboxRenderer_Render(Real64 deltaTime) {
Matrix_MulBy(&m, &rotX);
/* Rotate around camera */
Vector2 rotation = Camera_Active->GetCameraOrientation();
Vector2 rotation = Camera_Active->GetOrientation();
Matrix_RotateY(&rotY, rotation.X); /* Camera yaw */
Matrix_MulBy(&m, &rotY);
Matrix_RotateX(&rotX, rotation.Y); /* Camera pitch */