#include "colla/colla.h" #include "libs/handmademath.h" #include "libs/sokol_gfx.h" #include "utils.h" #define WORLD_UP HMM_V3(0, 1, 0) #define NEAR_Z (0.1f) #define FAR_Z (1000.f) typedef struct camera_t camera_t; struct camera_t { HMM_Vec3 pos; HMM_Vec3 fwd; HMM_Vec3 up; float yaw, pitch; HMM_Mat4 lookat; float speed, mov_speed, look_speed; float fov; }; camera_t cam_init(void) { camera_t cam = { .fwd = { 0, 0, -1 }, .up = { 0, 1, 0 }, .pos = { 0, 0, 0 }, .look_speed = 0.3f, .mov_speed = 15.f, .fov = HMM_DegToRad * 60.f, }; return cam; } void cam_update(camera_t *cam, float dt) { float strafe = (float)((int)is_key_down(SAPP_KEYCODE_D) - (int)is_key_down(SAPP_KEYCODE_A)); float forward = (float)((int)is_key_down(SAPP_KEYCODE_W) - (int)is_key_down(SAPP_KEYCODE_S)); float movup = (float)((int)is_key_down(SAPP_KEYCODE_Q) - (int)is_key_down(SAPP_KEYCODE_E)); float move_speed = cam->mov_speed * dt; float look_speed = cam->look_speed * dt; HMM_Vec2 delta = mouse_delta(); cam->yaw += delta.X * look_speed; cam->pitch -= delta.Y * look_speed; float max_angle = HMM_DegToRad * 89.f; cam->pitch = HMM_Clamp(-max_angle, cam->pitch, max_angle); float yc = cosf(cam->yaw); float ys = sinf(cam->yaw); float pc = cosf(cam->pitch); float ps = sinf(cam->pitch); cam->fwd = HMM_Norm(HMM_V3( pc * ys, ps, -pc * yc )); HMM_Vec3 right = HMM_Norm(HMM_Cross(cam->fwd, WORLD_UP)); cam->up = HMM_Cross(right, cam->fwd); cam->pos = HMM_Add( cam->pos, HMM_Mul( HMM_Add( HMM_Add( HMM_Mul(cam->fwd, forward), HMM_Mul(right, strafe) ), HMM_Mul(cam->up, movup) ), move_speed ) ); } HMM_Mat4 cam_view(camera_t *cam) { HMM_Mat4 view = HMM_LookAt_RH(cam->pos, HMM_Add(cam->pos, cam->fwd), cam->up); return view; } HMM_Mat4 cam_proj(camera_t *cam) { float aspect = sapp_widthf() / sapp_heightf(); HMM_Mat4 proj = HMM_Perspective_RH_ZO(cam->fov, aspect, NEAR_Z, FAR_Z); return proj; }