From 5177c672eb67b1ca1beec929abd74d2655e8242e Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 5 Jul 2018 22:14:42 +1000 Subject: [PATCH] Fix skybox rotating wrongly after rotating camera --- .../Rendering/Env/SkyboxRenderer.cs | 13 +++---- ClassicalSharp/Utils/Camera.cs | 39 +++++++++---------- src/Client/Camera.c | 36 ++++++++--------- src/Client/Camera.h | 1 - src/Client/SkyboxRenderer.c | 14 +++---- 5 files changed, 46 insertions(+), 57 deletions(-) diff --git a/ClassicalSharp/Rendering/Env/SkyboxRenderer.cs b/ClassicalSharp/Rendering/Env/SkyboxRenderer.cs index 02395bd14..3cc9cbc5d 100644 --- a/ClassicalSharp/Rendering/Env/SkyboxRenderer.cs +++ b/ClassicalSharp/Rendering/Env/SkyboxRenderer.cs @@ -68,7 +68,7 @@ namespace ClassicalSharp.Renderers { game.Graphics.BindTexture(tex); game.Graphics.SetBatchFormat(VertexFormat.P3fT2fC4b); - Matrix4 m = Matrix4.Identity, rotY, rotX; + Matrix4 m = Matrix4.Identity, rotY, rotX, view; // Base skybox rotation float rotTime = (float)(game.accumulator * 2 * Math.PI); // So speed of 1 rotates whole skybox every second @@ -79,12 +79,11 @@ namespace ClassicalSharp.Renderers { Matrix4.Mult(out m, ref m, ref rotX); // Rotate around camera - 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 Camera.tiltM); + Vector3 pos = game.CurrentCameraPos; + game.CurrentCameraPos = Vector3.Zero; + game.Camera.GetView(out view); + Matrix4.Mult(out m, ref m, ref view); + game.CurrentCameraPos = pos; game.Graphics.LoadMatrix(ref m); game.Graphics.BindVb(vb); diff --git a/ClassicalSharp/Utils/Camera.cs b/ClassicalSharp/Utils/Camera.cs index a9d98037e..d176a4866 100644 --- a/ClassicalSharp/Utils/Camera.cs +++ b/ClassicalSharp/Utils/Camera.cs @@ -17,7 +17,6 @@ namespace ClassicalSharp { public abstract Vector2 GetOrientation(); public abstract Vector3 GetPosition(float t); - public abstract Vector3 GetTarget(); public abstract bool IsThirdPerson { get; } public virtual bool Zoom(float amount) { return false; } @@ -30,8 +29,10 @@ namespace ClassicalSharp { public abstract class PerspectiveCamera : Camera { - protected static Vector2 offset; + protected static Vector2 rotOffset; + protected static Vector3 targetOffset; protected LocalPlayer player; + public PerspectiveCamera(Game game) { this.game = game; player = game.LocalPlayer; @@ -58,7 +59,9 @@ namespace ClassicalSharp { } public override void GetView(out Matrix4 m) { - Vector3 pos = game.CurrentCameraPos, target = GetTarget(); + Vector3 pos = game.CurrentCameraPos; + Vector3 target = pos + targetOffset; + Matrix4.LookAt(pos, target, Vector3.UnitY, out m); Matrix4.Mult(out m, ref m, ref tiltM); } @@ -115,7 +118,7 @@ namespace ClassicalSharp { void UpdateMouseRotation() { Vector2 rot = CalcMouseDelta(); if (game.Input.AltDown && IsThirdPerson) { - offset.X += rot.X; offset.Y += rot.Y; + rotOffset.X += rot.X; rotOffset.Y += rot.Y; return; } @@ -174,24 +177,22 @@ namespace ClassicalSharp { Vector2 v = new Vector2(player.HeadYRadians, player.HeadXRadians); if (forward) { v.X += (float)Math.PI; v.Y = -v.Y; } - v.X += offset.X * Utils.Deg2Rad; v.Y += offset.Y * Utils.Deg2Rad; + v.X += rotOffset.X * Utils.Deg2Rad; + v.Y += rotOffset.Y * Utils.Deg2Rad; return v; } public override Vector3 GetPosition(float t) { CalcViewBobbing(t, dist); - Vector3 eyePos = player.EyePosition; - eyePos.Y += bobbingVer; + Vector3 target = player.EyePosition; + target.Y += bobbingVer; 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; + Picking.ClipCameraPos(game, target, dir, dist, game.CameraClipPos); + Vector3 camPos = game.CameraClipPos.Intersect; + + targetOffset = target - camPos; + return camPos; } } @@ -211,13 +212,9 @@ namespace ClassicalSharp { double headY = player.HeadYRadians; camPos.X += bobbingHor * (float)Math.Cos(headY); camPos.Z += bobbingHor * (float)Math.Sin(headY); + + targetOffset = GetDirVector(); return camPos; } - - public override Vector3 GetTarget() { - Vector3 camPos = game.CurrentCameraPos; - Vector3 dir = GetDirVector(); - return camPos + dir; - } } } \ No newline at end of file diff --git a/src/Client/Camera.c b/src/Client/Camera.c index 6131fa6ae..fa4a45cc4 100644 --- a/src/Client/Camera.c +++ b/src/Client/Camera.c @@ -8,7 +8,8 @@ #include "Entity.h" #include "Input.h" -Vector2 cam_offset; +Vector2 cam_rotOffset; +Vector3 cam_targetOffset; Camera Camera_Cameras[3]; Int32 Camera_ActiveIndex; #define Cam_IsForward_Third() (Camera_ActiveIndex == 2) @@ -33,8 +34,8 @@ static void PerspectiveCamera_GetProjection(Matrix* proj) { } static void PerspectiveCamera_GetView(Matrix* mat) { - Vector3 pos = Game_CurrentCameraPos, target = Camera_Active->GetTarget(); - Vector3 up = Vector3_UnitY; + Vector3 pos = Game_CurrentCameraPos, target, up = Vector3_UnitY; + Vector3_Add(&target, &pos, &cam_targetOffset); Matrix_LookAt(mat, pos, target, up); Matrix_MulBy(mat, &Camera_TiltM); @@ -92,7 +93,7 @@ static Vector2 PerspectiveCamera_GetMouseDelta(void) { static void PerspectiveCamera_UpdateMouseRotation(void) { Vector2 rot = PerspectiveCamera_GetMouseDelta(); if (Key_IsAltPressed() && Camera_Active->IsThirdPerson) { - cam_offset.X += rot.X; cam_offset.Y += rot.Y; + cam_rotOffset.X += rot.X; cam_rotOffset.Y += rot.Y; return; } LocalPlayer* player = &LocalPlayer_Instance; @@ -165,14 +166,9 @@ static Vector3 FirstPersonCamera_GetPosition(Real32 t) { Real32 headY = (p->HeadY * MATH_DEG2RAD); camPos.X += Camera_BobbingHor * Math_CosF(headY); camPos.Z += Camera_BobbingHor * Math_SinF(headY); - return camPos; -} -static Vector3 FirstPersonCamera_GetTarget(void) { - Vector3 pos = Game_CurrentCameraPos; - Vector3 dir = PerspectiveCamera_GetDirVector(); - Vector3 target; Vector3_Add(&target, &pos, &dir); - return target; + cam_targetOffset = PerspectiveCamera_GetDirVector(); + return camPos; } static bool FirstPersonCamera_Zoom(Real32 amount) { return false; } @@ -182,7 +178,6 @@ static void FirstPersonCamera_Init(Camera* cam) { cam->IsThirdPerson = false; cam->GetOrientation = FirstPersonCamera_GetOrientation; cam->GetPosition = FirstPersonCamera_GetPosition; - cam->GetTarget = FirstPersonCamera_GetTarget; cam->Zoom = FirstPersonCamera_Zoom; } @@ -193,7 +188,8 @@ static Vector2 ThirdPersonCamera_GetOrientation(void) { Vector2 v = { p->HeadY * MATH_DEG2RAD, p->HeadX * MATH_DEG2RAD }; if (Cam_IsForward_Third()) { v.X += MATH_PI; v.Y = -v.Y; } - v.X += cam_offset.X * MATH_DEG2RAD; v.Y += cam_offset.Y * MATH_DEG2RAD; + v.X += cam_rotOffset.X * MATH_DEG2RAD; + v.Y += cam_rotOffset.Y * MATH_DEG2RAD; return v; } @@ -202,14 +198,15 @@ static Vector3 ThirdPersonCamera_GetPosition(Real32 t) { PerspectiveCamera_CalcViewBobbing(t, dist); Entity* p = &LocalPlayer_Instance.Base; - Vector3 eyePos = Entity_GetEyePosition(p); - eyePos.Y += Camera_BobbingVer; + Vector3 target = Entity_GetEyePosition(p); + target.Y += Camera_BobbingVer; - Vector3 dir = PerspectiveCamera_GetDirVector(); - Vector3_Negate(&dir, &dir); + Vector3 dir = PerspectiveCamera_GetDirVector(); Vector3_Negate(&dir, &dir); + Picking_ClipCameraPos(target, dir, dist, &Game_CameraClipPos); + Vector3 camPos = Game_CameraClipPos.Intersect; - Picking_ClipCameraPos(eyePos, dir, dist, &Game_CameraClipPos); - return Game_CameraClipPos.Intersect; + Vector3_Sub(&cam_targetOffset, &target, &camPos); + return camPos; } static Vector3 ThirdPersonCamera_GetTarget(void) { @@ -232,7 +229,6 @@ static void ThirdPersonCamera_Init(Camera* cam) { cam->IsThirdPerson = true; cam->GetOrientation = ThirdPersonCamera_GetOrientation; cam->GetPosition = ThirdPersonCamera_GetPosition; - cam->GetTarget = ThirdPersonCamera_GetTarget; cam->Zoom = ThirdPersonCamera_Zoom; } diff --git a/src/Client/Camera.h b/src/Client/Camera.h index bde5f118a..9783dcdad 100644 --- a/src/Client/Camera.h +++ b/src/Client/Camera.h @@ -16,7 +16,6 @@ typedef struct Camera_ { Vector2 (*GetOrientation)(void); Vector3 (*GetPosition)(Real32 t); - Vector3 (*GetTarget)(void); void (*UpdateMouse)(void); void (*RegrabMouse)(void); diff --git a/src/Client/SkyboxRenderer.c b/src/Client/SkyboxRenderer.c index bbe516dcc..3f42d485d 100644 --- a/src/Client/SkyboxRenderer.c +++ b/src/Client/SkyboxRenderer.c @@ -39,7 +39,7 @@ void SkyboxRenderer_Render(Real64 deltaTime) { Gfx_SetBatchFormat(VERTEX_FORMAT_P3FT2FC4B); Matrix m = Matrix_Identity; - Matrix rotX, rotY; + Matrix rotX, rotY, view; /* Base skybox rotation */ Real32 rotTime = (Real32)(Game_Accumulator * 2 * MATH_PI); /* So speed of 1 rotates whole skybox every second */ @@ -49,13 +49,11 @@ void SkyboxRenderer_Render(Real64 deltaTime) { Matrix_MulBy(&m, &rotX); /* Rotate around camera */ - Vector2 rotation = Camera_Active->GetOrientation(); - Matrix_RotateY(&rotY, rotation.X); /* Camera yaw */ - Matrix_MulBy(&m, &rotY); - Matrix_RotateX(&rotX, rotation.Y); /* Camera pitch */ - Matrix_MulBy(&m, &rotX); - /* Tilt skybox too. */ - Matrix_MulBy(&m, &Camera_TiltM); + Vector3 pos = Game_CurrentCameraPos, zero = Vector3_Zero; + Game_CurrentCameraPos = zero; + Camera_Active->GetView(&view); + Matrix_MulBy(&m, &view); + Game_CurrentCameraPos = pos; Gfx_LoadMatrix(&m); Gfx_BindVb(skybox_vb);