111 lines
3.2 KiB
C++
111 lines
3.2 KiB
C++
#include "directxmath/directxmath.h"
|
|
|
|
#include "window.h"
|
|
#include "view.h"
|
|
|
|
constexpr bool third_person = false;
|
|
|
|
namespace view {
|
|
view_state state = {};
|
|
|
|
static inline XMMATRIX current_projection()
|
|
{
|
|
float fov_angle_y = XMConvertToRadians(45 * state.fov);
|
|
float aspect_ratio = window::width / window::height;
|
|
float near_z = 1.0;
|
|
float far_z = 0.1;
|
|
XMMATRIX projection = XMMatrixPerspectiveFovRH(fov_angle_y, aspect_ratio, near_z, far_z);
|
|
return projection;
|
|
}
|
|
|
|
static inline XMMATRIX current_view()
|
|
{
|
|
XMMATRIX view = XMMatrixLookAtRH(state.eye, state.at, state.up);
|
|
return view;
|
|
}
|
|
|
|
static inline float clamp_pitch(float delta_pitch)
|
|
{
|
|
float pitch = state.pitch + delta_pitch;
|
|
if (pitch > 1.57f) pitch = 1.57f;
|
|
if (pitch < -1.57f) pitch = -1.57f;
|
|
return pitch;
|
|
}
|
|
|
|
static inline XMVECTOR get_normal()
|
|
{
|
|
return XMVector3NormalizeEst(XMVector3Cross(state.forward, state.up));
|
|
}
|
|
|
|
static inline XMVECTOR get_direction()
|
|
{
|
|
XMMATRIX mrn = XMMatrixRotationAxis(state.normal, state.pitch);
|
|
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 * at_distance;
|
|
}
|
|
}
|
|
|
|
namespace third_person {
|
|
XMVECTOR 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 * at_distance;
|
|
*/
|
|
return state.forward * forward + state.normal * strafe + state.up * elevation;
|
|
}
|
|
}
|
|
|
|
void apply_fov(float delta)
|
|
{
|
|
float new_fov = state.fov + delta;
|
|
if (new_fov > 0.00001f) {
|
|
state.fov = new_fov;
|
|
}
|
|
}
|
|
|
|
void update_transforms()
|
|
{
|
|
state.projection_transform = current_projection();
|
|
state.view_transform = current_view();
|
|
state.transform = state.view_transform * state.projection_transform;
|
|
XMStoreFloat4x4(&state.float_transform, state.transform);
|
|
}
|
|
|
|
void load()
|
|
{
|
|
state.up = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
|
|
|
|
state.fov = 1.5;
|
|
state.pitch = -0.7;
|
|
|
|
state.forward = XMVector3Normalize(XMVectorSet(-0.64, 0.77, 0, 0));
|
|
state.normal = get_normal(); // on forward change
|
|
state.direction = get_direction(); // on forward/normal/pitch change
|
|
|
|
// position
|
|
state.eye = XMVectorSet(-45.5f, 43.25f, 63.0f, 1);
|
|
state.at = state.eye + state.direction * at_distance;
|
|
}
|
|
}
|