Fix skybox rotating wrongly after rotating camera

This commit is contained in:
UnknownShadow200 2018-07-05 22:14:42 +10:00
parent beefd2ec76
commit 5177c672eb
5 changed files with 46 additions and 57 deletions

View File

@ -68,7 +68,7 @@ namespace ClassicalSharp.Renderers {
game.Graphics.BindTexture(tex); game.Graphics.BindTexture(tex);
game.Graphics.SetBatchFormat(VertexFormat.P3fT2fC4b); game.Graphics.SetBatchFormat(VertexFormat.P3fT2fC4b);
Matrix4 m = Matrix4.Identity, rotY, rotX; Matrix4 m = Matrix4.Identity, rotY, rotX, view;
// Base skybox rotation // Base skybox rotation
float rotTime = (float)(game.accumulator * 2 * Math.PI); // So speed of 1 rotates whole skybox every second 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); Matrix4.Mult(out m, ref m, ref rotX);
// Rotate around camera // Rotate around camera
Vector2 rotation = game.Camera.GetOrientation(); Vector3 pos = game.CurrentCameraPos;
Matrix4.RotateY(out rotY, rotation.X); // Camera yaw game.CurrentCameraPos = Vector3.Zero;
Matrix4.Mult(out m, ref m, ref rotY); game.Camera.GetView(out view);
Matrix4.RotateX(out rotX, rotation.Y); // Cammera pitch Matrix4.Mult(out m, ref m, ref view);
Matrix4.Mult(out m, ref m, ref rotX); game.CurrentCameraPos = pos;
Matrix4.Mult(out m, ref m, ref Camera.tiltM);
game.Graphics.LoadMatrix(ref m); game.Graphics.LoadMatrix(ref m);
game.Graphics.BindVb(vb); game.Graphics.BindVb(vb);

View File

@ -17,7 +17,6 @@ namespace ClassicalSharp {
public abstract Vector2 GetOrientation(); public abstract Vector2 GetOrientation();
public abstract Vector3 GetPosition(float t); public abstract Vector3 GetPosition(float t);
public abstract Vector3 GetTarget();
public abstract bool IsThirdPerson { get; } public abstract bool IsThirdPerson { get; }
public virtual bool Zoom(float amount) { return false; } public virtual bool Zoom(float amount) { return false; }
@ -30,8 +29,10 @@ namespace ClassicalSharp {
public abstract class PerspectiveCamera : Camera { public abstract class PerspectiveCamera : Camera {
protected static Vector2 offset; protected static Vector2 rotOffset;
protected static Vector3 targetOffset;
protected LocalPlayer player; protected LocalPlayer player;
public PerspectiveCamera(Game game) { public PerspectiveCamera(Game game) {
this.game = game; this.game = game;
player = game.LocalPlayer; player = game.LocalPlayer;
@ -58,7 +59,9 @@ namespace ClassicalSharp {
} }
public override void GetView(out Matrix4 m) { 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.LookAt(pos, target, Vector3.UnitY, out m);
Matrix4.Mult(out m, ref m, ref tiltM); Matrix4.Mult(out m, ref m, ref tiltM);
} }
@ -115,7 +118,7 @@ namespace ClassicalSharp {
void UpdateMouseRotation() { void UpdateMouseRotation() {
Vector2 rot = CalcMouseDelta(); Vector2 rot = CalcMouseDelta();
if (game.Input.AltDown && IsThirdPerson) { if (game.Input.AltDown && IsThirdPerson) {
offset.X += rot.X; offset.Y += rot.Y; rotOffset.X += rot.X; rotOffset.Y += rot.Y;
return; return;
} }
@ -174,24 +177,22 @@ namespace ClassicalSharp {
Vector2 v = new Vector2(player.HeadYRadians, player.HeadXRadians); Vector2 v = new Vector2(player.HeadYRadians, player.HeadXRadians);
if (forward) { v.X += (float)Math.PI; v.Y = -v.Y; } 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; return v;
} }
public override Vector3 GetPosition(float t) { public override Vector3 GetPosition(float t) {
CalcViewBobbing(t, dist); CalcViewBobbing(t, dist);
Vector3 eyePos = player.EyePosition; Vector3 target = player.EyePosition;
eyePos.Y += bobbingVer; target.Y += bobbingVer;
Vector3 dir = -GetDirVector(); Vector3 dir = -GetDirVector();
Picking.ClipCameraPos(game, eyePos, dir, dist, game.CameraClipPos); Picking.ClipCameraPos(game, target, dir, dist, game.CameraClipPos);
return game.CameraClipPos.Intersect; Vector3 camPos = game.CameraClipPos.Intersect;
}
targetOffset = target - camPos;
public override Vector3 GetTarget() { return camPos;
Vector3 eyePos = player.EyePosition;
eyePos.Y += bobbingVer;
return eyePos;
} }
} }
@ -211,13 +212,9 @@ namespace ClassicalSharp {
double headY = player.HeadYRadians; double headY = player.HeadYRadians;
camPos.X += bobbingHor * (float)Math.Cos(headY); camPos.X += bobbingHor * (float)Math.Cos(headY);
camPos.Z += bobbingHor * (float)Math.Sin(headY); camPos.Z += bobbingHor * (float)Math.Sin(headY);
targetOffset = GetDirVector();
return camPos; return camPos;
} }
public override Vector3 GetTarget() {
Vector3 camPos = game.CurrentCameraPos;
Vector3 dir = GetDirVector();
return camPos + dir;
}
} }
} }

View File

@ -8,7 +8,8 @@
#include "Entity.h" #include "Entity.h"
#include "Input.h" #include "Input.h"
Vector2 cam_offset; Vector2 cam_rotOffset;
Vector3 cam_targetOffset;
Camera Camera_Cameras[3]; Camera Camera_Cameras[3];
Int32 Camera_ActiveIndex; Int32 Camera_ActiveIndex;
#define Cam_IsForward_Third() (Camera_ActiveIndex == 2) #define Cam_IsForward_Third() (Camera_ActiveIndex == 2)
@ -33,8 +34,8 @@ static void PerspectiveCamera_GetProjection(Matrix* proj) {
} }
static void PerspectiveCamera_GetView(Matrix* mat) { static void PerspectiveCamera_GetView(Matrix* mat) {
Vector3 pos = Game_CurrentCameraPos, target = Camera_Active->GetTarget(); Vector3 pos = Game_CurrentCameraPos, target, up = Vector3_UnitY;
Vector3 up = Vector3_UnitY; Vector3_Add(&target, &pos, &cam_targetOffset);
Matrix_LookAt(mat, pos, target, up); Matrix_LookAt(mat, pos, target, up);
Matrix_MulBy(mat, &Camera_TiltM); Matrix_MulBy(mat, &Camera_TiltM);
@ -92,7 +93,7 @@ static Vector2 PerspectiveCamera_GetMouseDelta(void) {
static void PerspectiveCamera_UpdateMouseRotation(void) { static void PerspectiveCamera_UpdateMouseRotation(void) {
Vector2 rot = PerspectiveCamera_GetMouseDelta(); Vector2 rot = PerspectiveCamera_GetMouseDelta();
if (Key_IsAltPressed() && Camera_Active->IsThirdPerson) { 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; return;
} }
LocalPlayer* player = &LocalPlayer_Instance; LocalPlayer* player = &LocalPlayer_Instance;
@ -165,14 +166,9 @@ static Vector3 FirstPersonCamera_GetPosition(Real32 t) {
Real32 headY = (p->HeadY * MATH_DEG2RAD); Real32 headY = (p->HeadY * MATH_DEG2RAD);
camPos.X += Camera_BobbingHor * Math_CosF(headY); camPos.X += Camera_BobbingHor * Math_CosF(headY);
camPos.Z += Camera_BobbingHor * Math_SinF(headY); camPos.Z += Camera_BobbingHor * Math_SinF(headY);
return camPos;
}
static Vector3 FirstPersonCamera_GetTarget(void) { cam_targetOffset = PerspectiveCamera_GetDirVector();
Vector3 pos = Game_CurrentCameraPos; return camPos;
Vector3 dir = PerspectiveCamera_GetDirVector();
Vector3 target; Vector3_Add(&target, &pos, &dir);
return target;
} }
static bool FirstPersonCamera_Zoom(Real32 amount) { return false; } static bool FirstPersonCamera_Zoom(Real32 amount) { return false; }
@ -182,7 +178,6 @@ static void FirstPersonCamera_Init(Camera* cam) {
cam->IsThirdPerson = false; cam->IsThirdPerson = false;
cam->GetOrientation = FirstPersonCamera_GetOrientation; cam->GetOrientation = FirstPersonCamera_GetOrientation;
cam->GetPosition = FirstPersonCamera_GetPosition; cam->GetPosition = FirstPersonCamera_GetPosition;
cam->GetTarget = FirstPersonCamera_GetTarget;
cam->Zoom = FirstPersonCamera_Zoom; cam->Zoom = FirstPersonCamera_Zoom;
} }
@ -193,7 +188,8 @@ static Vector2 ThirdPersonCamera_GetOrientation(void) {
Vector2 v = { p->HeadY * MATH_DEG2RAD, p->HeadX * MATH_DEG2RAD }; Vector2 v = { p->HeadY * MATH_DEG2RAD, p->HeadX * MATH_DEG2RAD };
if (Cam_IsForward_Third()) { v.X += MATH_PI; v.Y = -v.Y; } 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; return v;
} }
@ -202,14 +198,15 @@ static Vector3 ThirdPersonCamera_GetPosition(Real32 t) {
PerspectiveCamera_CalcViewBobbing(t, dist); PerspectiveCamera_CalcViewBobbing(t, dist);
Entity* p = &LocalPlayer_Instance.Base; Entity* p = &LocalPlayer_Instance.Base;
Vector3 eyePos = Entity_GetEyePosition(p); Vector3 target = Entity_GetEyePosition(p);
eyePos.Y += Camera_BobbingVer; target.Y += Camera_BobbingVer;
Vector3 dir = PerspectiveCamera_GetDirVector(); Vector3 dir = PerspectiveCamera_GetDirVector(); Vector3_Negate(&dir, &dir);
Vector3_Negate(&dir, &dir); Picking_ClipCameraPos(target, dir, dist, &Game_CameraClipPos);
Vector3 camPos = Game_CameraClipPos.Intersect;
Picking_ClipCameraPos(eyePos, dir, dist, &Game_CameraClipPos); Vector3_Sub(&cam_targetOffset, &target, &camPos);
return Game_CameraClipPos.Intersect; return camPos;
} }
static Vector3 ThirdPersonCamera_GetTarget(void) { static Vector3 ThirdPersonCamera_GetTarget(void) {
@ -232,7 +229,6 @@ static void ThirdPersonCamera_Init(Camera* cam) {
cam->IsThirdPerson = true; cam->IsThirdPerson = true;
cam->GetOrientation = ThirdPersonCamera_GetOrientation; cam->GetOrientation = ThirdPersonCamera_GetOrientation;
cam->GetPosition = ThirdPersonCamera_GetPosition; cam->GetPosition = ThirdPersonCamera_GetPosition;
cam->GetTarget = ThirdPersonCamera_GetTarget;
cam->Zoom = ThirdPersonCamera_Zoom; cam->Zoom = ThirdPersonCamera_Zoom;
} }

View File

@ -16,7 +16,6 @@ typedef struct Camera_ {
Vector2 (*GetOrientation)(void); Vector2 (*GetOrientation)(void);
Vector3 (*GetPosition)(Real32 t); Vector3 (*GetPosition)(Real32 t);
Vector3 (*GetTarget)(void);
void (*UpdateMouse)(void); void (*UpdateMouse)(void);
void (*RegrabMouse)(void); void (*RegrabMouse)(void);

View File

@ -39,7 +39,7 @@ void SkyboxRenderer_Render(Real64 deltaTime) {
Gfx_SetBatchFormat(VERTEX_FORMAT_P3FT2FC4B); Gfx_SetBatchFormat(VERTEX_FORMAT_P3FT2FC4B);
Matrix m = Matrix_Identity; Matrix m = Matrix_Identity;
Matrix rotX, rotY; Matrix rotX, rotY, view;
/* Base skybox rotation */ /* Base skybox rotation */
Real32 rotTime = (Real32)(Game_Accumulator * 2 * MATH_PI); /* So speed of 1 rotates whole skybox every second */ 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); Matrix_MulBy(&m, &rotX);
/* Rotate around camera */ /* Rotate around camera */
Vector2 rotation = Camera_Active->GetOrientation(); Vector3 pos = Game_CurrentCameraPos, zero = Vector3_Zero;
Matrix_RotateY(&rotY, rotation.X); /* Camera yaw */ Game_CurrentCameraPos = zero;
Matrix_MulBy(&m, &rotY); Camera_Active->GetView(&view);
Matrix_RotateX(&rotX, rotation.Y); /* Camera pitch */ Matrix_MulBy(&m, &view);
Matrix_MulBy(&m, &rotX); Game_CurrentCameraPos = pos;
/* Tilt skybox too. */
Matrix_MulBy(&m, &Camera_TiltM);
Gfx_LoadMatrix(&m); Gfx_LoadMatrix(&m);
Gfx_BindVb(skybox_vb); Gfx_BindVb(skybox_vb);