third person camera

This commit is contained in:
Zack Buhman 2026-03-11 21:43:28 -05:00
parent 1b71cf4281
commit 455c7c9f72
5 changed files with 85 additions and 37 deletions

View File

@ -2,26 +2,41 @@
namespace view { namespace view {
struct view_state { struct view_state {
XMVECTOR up; // positions
XMVECTOR eye; XMVECTOR eye;
XMVECTOR forward;
XMVECTOR direction;
XMVECTOR at; XMVECTOR at;
XMVECTOR normal;
// vectors
XMVECTOR up;
XMVECTOR forward;
XMVECTOR normal; // cross(forward, up)
XMVECTOR direction; // rotationaxis(forward, pitch)
// angles
float fov; float fov;
float pitch; float pitch;
// transforms
XMMATRIX projection_transform; XMMATRIX projection_transform;
XMMATRIX view_transform; XMMATRIX view_transform;
XMMATRIX transform; XMMATRIX transform;
// transform views
XMFLOAT4X4 float_transform; XMFLOAT4X4 float_transform;
}; };
extern view_state state; extern view_state state;
void apply_translation(float forward, float strafe, float elevation); namespace first_person {
void apply_yaw_pitch(float delta_yaw, float delta_pitch); void apply_transform(float forward, float strafe, float elevation,
float delta_yaw, float delta_pitch);
}
namespace third_person {
void apply_transform(float forward, float strafe, float elevation,
float delta_yaw, float delta_pitch);
}
void apply_fov(float delta); void apply_fov(float delta);
void update_transforms(); void update_transforms();
void load(); void load();

View File

@ -27,8 +27,6 @@ void update(float time);
end end
local update = function(time) local update = function(time)
test.update(time)
for joystick_index, joystick in ipairs(joysticks) do for joystick_index, joystick in ipairs(joysticks) do
if joystick_index > 8 then if joystick_index > 8 then
break break
@ -64,6 +62,8 @@ local update = function(time)
local left = love.keyboard.isDown("left") local left = love.keyboard.isDown("left")
local right = love.keyboard.isDown("right") local right = love.keyboard.isDown("right")
test.update_keyboard(up, down, left, right); test.update_keyboard(up, down, left, right);
test.update(time)
end end
local draw = function() local draw = function()

View File

@ -112,7 +112,7 @@ namespace non_block {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GREATER); glDepthFunc(GL_GREATER);
XMVECTOR offset = view::state.eye + view::state.forward * 4.0f; XMVECTOR offset = view::state.at;
XMMATRIX world_transform = XMMatrixTranslationFromVector(offset); XMMATRIX world_transform = XMMatrixTranslationFromVector(offset);
XMMATRIX transform = world_transform * view::state.transform; XMMATRIX transform = world_transform * view::state.transform;
XMFLOAT4X4 float_world_transform; XMFLOAT4X4 float_world_transform;

View File

@ -665,9 +665,9 @@ light_parameters lighting = {
void update_keyboard(int up, int down, int left, int right) void update_keyboard(int up, int down, int left, int right)
{ {
float forward = (0.1f * up + -0.1f * down); //float forward = (0.1f * up + -0.1f * down);
float strafe = (-0.1f * left + 0.1f * right); //float strafe = (-0.1f * left + 0.1f * right);
view::apply_translation(forward, strafe, 0); //view::third_person::apply_translation(forward, strafe, 0);
} }
const int max_joysticks = 8; const int max_joysticks = 8;
@ -680,11 +680,13 @@ void update_joystick(int joystick_index,
int leftshoulder, int rightshoulder, int leftshoulder, int rightshoulder,
int start) int start)
{ {
float forward = -ly; float forward = -ly * 0.5;
float strafe = lx; float strafe = lx * 0.5;
float elevation = tl - tr; float elevation = (tl - tr) * 0.5;
view::apply_yaw_pitch(rx * -0.035, ry * -0.035); float delta_yaw = rx * -0.035;
view::apply_translation(forward, strafe, elevation); float delta_pitch = ry * -0.035;
view::third_person::apply_transform(forward, strafe, elevation,
delta_yaw, delta_pitch);
view::apply_fov(0.01 * up + -0.01 * down); view::apply_fov(0.01 * up + -0.01 * down);
lighting.quadratic += 0.01 * a + -0.01 * b; lighting.quadratic += 0.01 * a + -0.01 * b;

View File

@ -6,7 +6,7 @@
constexpr bool third_person = false; constexpr bool third_person = false;
namespace view { namespace view {
view_state state; view_state state = {};
static inline XMMATRIX current_projection() static inline XMMATRIX current_projection()
{ {
@ -20,29 +20,57 @@ namespace view {
static inline XMMATRIX current_view() static inline XMMATRIX current_view()
{ {
state.at = XMVectorAdd(state.eye, state.direction);
XMMATRIX view = XMMatrixLookAtRH(state.eye, state.at, state.up); XMMATRIX view = XMMatrixLookAtRH(state.eye, state.at, state.up);
return view; return view;
} }
void apply_translation(float forward, float strafe, float elevation) static inline float clamp_pitch(float delta_pitch)
{ {
state.eye += state.forward * forward + state.normal * strafe + state.up * elevation; float pitch = state.pitch + delta_pitch;
if (pitch > 1.57f) pitch = 1.57f;
if (pitch < -1.57f) pitch = -1.57f;
return pitch;
} }
void apply_yaw_pitch(float delta_yaw, float delta_pitch) static inline XMVECTOR get_normal()
{ {
XMMATRIX mrz = XMMatrixRotationZ(delta_yaw); return XMVector3NormalizeEst(XMVector3Cross(state.forward, state.up));
state.forward = XMVector3Transform(state.forward, mrz); }
state.normal = XMVector3NormalizeEst(XMVector3Cross(state.forward, state.up));
state.pitch += delta_pitch;
if (state.pitch > 1.57f) state.pitch = 1.57f;
if (state.pitch < -1.57f) state.pitch = -1.57f;
static inline XMVECTOR get_direction()
{
XMMATRIX mrn = XMMatrixRotationAxis(state.normal, state.pitch); XMMATRIX mrn = XMMatrixRotationAxis(state.normal, state.pitch);
state.direction = XMVector3Transform(state.forward, mrn); return XMVector3Transform(state.forward, mrn);
}
namespace first_person {
void apply_transform(float forward, float strafe, float elevation,
float delta_yaw, float delta_pitch)
{
state.pitch = clamp_pitch(delta_pitch);
state.forward = XMVector3Transform(state.forward, XMMatrixRotationZ(delta_yaw));
state.normal = get_normal(); // on forward change
state.direction = get_direction(); // on forward/normal/pitch change
state.eye += state.forward * forward + state.normal * strafe + state.up * elevation;
state.at = state.eye + state.direction * 4;
}
}
namespace third_person {
void apply_transform(float forward, float strafe, float elevation,
float delta_yaw, float delta_pitch)
{
state.pitch = clamp_pitch(delta_pitch);
state.forward = XMVector3Transform(state.forward, XMMatrixRotationZ(delta_yaw));
state.normal = get_normal(); // on forward change
state.direction = get_direction(); // on forward/normal/pitch change
state.at += state.forward * forward + state.normal * strafe + state.up * elevation;
state.eye = state.at - state.direction * 4;
}
} }
void apply_fov(float delta) void apply_fov(float delta)
@ -64,13 +92,16 @@ namespace view {
void load() void load()
{ {
state.up = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f); state.up = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
state.eye = XMVectorSet(-55.5f, 48.25f, 50.0f, 1);
state.forward = XMVector3Normalize(XMVectorSet(-0.63, 0.78, 0, 0));
state.direction = state.forward;
state.normal = XMVector3Normalize(XMVector3Cross(state.forward, state.up));
state.fov = 1.5; state.fov = 1.5;
state.pitch = 0; state.pitch = 0;
state.forward = XMVector3Normalize(XMVectorSet(-0.63, 0.78, 0, 0));
state.normal = get_normal(); // on forward change
state.direction = get_direction(); // on forward/normal/pitch change
// position
state.eye = XMVectorSet(-55.5f, 48.25f, 50.0f, 1);
state.at = state.eye + state.direction * 4;
} }
} }