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.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);

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

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

View File

@ -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);