#include "directxmath/DirectXMath.h" #include "camera.h" struct CameraState { XMFLOAT3 eye; XMFLOAT3 look; XMFLOAT3 up; float yaw; float pitch; float fov; XMFLOAT3 light_position; }; struct ViewState { XMFLOAT4X4 viewProj; XMFLOAT4X4 lightViewProj; XMFLOAT4 lightPosition; XMFLOAT4 eyePosition; }; static inline XMMATRIX camera_view(CameraState const * state) { XMMATRIX view = XMMatrixLookToRH(XMLoadFloat3(&state->eye), XMLoadFloat3(&state->look), XMLoadFloat3(&state->up)); return view; } static inline XMMATRIX camera_projection(CameraState const * state, float aspect) { float near_z = 0.01; float far_z = 1000.0; XMMATRIX projection = XMMatrixPerspectiveFovRH(state->fov, aspect, near_z, far_z); return projection; }; extern "C" void log(float x); static inline float min(float a, float b) { return a < b ? a : b; } static inline float max(float a, float b) { return a > b ? a : b; } static inline float fract(float a) { return a - __builtin_floorf(a); } void camera_move(CameraState * state, int lu, int ll, int ld, int lr, int lal, int lar, int ru, int rl, int rd, int rr) { const float linearSpeed = 0.3; const float rotationalSpeed = 0.025; XMFLOAT3 move = {0, 0, 0}; if (ll) move.x -= 1.0; if (lr) move.x += 1.0; if (lu) move.z -= 1.0; if (ld) move.z += 1.0; if (lal) move.y += 1.0; if (lar) move.y -= 1.0; //XMStoreFloat3(&move, XMVector3Normalize(XMLoadFloat3(&move))); if (rl) state->yaw += rotationalSpeed; if (rr) state->yaw -= rotationalSpeed; if (ru) state->pitch += rotationalSpeed; if (rd) state->pitch -= rotationalSpeed; state->pitch = min(state->pitch, XM_PIDIV2 * 0.9); state->pitch = max(state->pitch, -XM_PIDIV2 * 0.9); state->yaw = fract(state->yaw * (1.0f / XM_2PI)) * XM_2PI; float sinyaw; float cosyaw; XMScalarSinCos(&sinyaw, &cosyaw, state->yaw); // eye float x = move.x * -cosyaw - move.z * sinyaw; float y = move.y; float z = move.x * sinyaw - move.z * cosyaw; state->eye.x += x * linearSpeed; state->eye.y += y * linearSpeed; state->eye.z += z * linearSpeed; // look float sinpitch; float cospitch; XMScalarSinCos(&sinpitch, &cospitch, state->pitch); state->look.x = cospitch * sinyaw; state->look.y = sinpitch; state->look.z = cospitch * cosyaw; } void camera_init(CameraState * camera_state) { camera_state->fov = XMConvertToRadians(45 * 1.5); camera_state->yaw = XM_PI; camera_state->pitch = 0.0f; camera_state->up = {0, 1, 0}; camera_state->look = {0, 0, -1}; camera_state->eye = {0, 0, 5}; camera_state->light_position = {10, 10, 10}; } void camera_view_projection(CameraState * camera_state, ViewState * view_state, float aspect) { XMVECTOR light_position = XMLoadFloat3(&camera_state->light_position); light_position = XMVector3Transform(light_position, XMMatrixRotationY(0.025)); XMStoreFloat3(&camera_state->light_position, light_position); XMMATRIX view = camera_view(camera_state); XMMATRIX projection = camera_projection(camera_state, aspect); XMMATRIX view_projection = view * projection; XMMATRIX light_world = XMMatrixTranslationFromVector(light_position); XMStoreFloat4x4(&view_state->viewProj, view_projection); XMStoreFloat4x4(&view_state->lightViewProj, light_world * view_projection); XMStoreFloat4(&view_state->lightPosition, light_position); XMStoreFloat4(&view_state->eyePosition, XMLoadFloat3(&camera_state->eye)); }