diff options
| author | tech kaczynski <tk@techkaczynski.dev> | 2026-10-19 01:47:08 +1000 |
|---|---|---|
| committer | tech kaczynski <tk@techkaczynski.dev> | 2026-10-19 01:47:08 +1000 |
| commit | edc50a43a0ab064472aa7fde90f14cf456d92076 (patch) | |
| tree | c0281123898ddfa2d94683cbcd4cd85dd0d6ad6b /cam.c | |
| parent | cc4ba95edf2927eda63af1aeb79a503bc6fe6182 (diff) | |
lots of editor work. Improved editor camera controls.
Diffstat (limited to 'cam.c')
| -rw-r--r-- | cam.c | 203 |
1 files changed, 193 insertions, 10 deletions
@@ -1,25 +1,157 @@ #include "cam.h" +#include "reasings.h" #include <rcamera.h> +static void cam_ctrl_editor(void); +static void cam_ctrl_orbit(void); + CameraInfo main_cam = {0}; void cam_init(void) { rlSetClipPlanes(0.3, 5000); main_cam.cam = (Camera3D) { - .position = { 0, 10, -10 }, + .position = { 0, 10, 10 }, .target = { 0, 1, 0 }, .up = { 0, 1, 0}, .fovy = 70.0f, .projection = CAMERA_PERSPECTIVE, }; main_cam.update = false; + main_cam.allow_fly = true; + main_cam.state = CAM_MODE_EDIT_FLY; + main_cam.perspective_fov = main_cam.cam.fovy; main_cam.mv_speed = 10; main_cam.mv_scale = 1; - main_cam.lk_speed = 0.2; + main_cam.lk_speed = 0.003f; } void +cam_focus(Vec3 target, f32 distance, f32 view_height) { + Camera *cam = &main_cam.cam; + Vec3 backward = Vector3Normalize( + Vector3Subtract(cam->position, cam->target)); + + main_cam.transition.start_pos = cam->position; + main_cam.transition.start_target = cam->target; + + main_cam.transition.end_target = target; + main_cam.transition.end_pos = Vector3Add(target, + Vector3Scale(backward, fmaxf(distance, 0.5f))); + + main_cam.transition.start_fovy = cam->fovy; + main_cam.transition.end_fovy = cam->fovy; + + if (cam->projection == CAMERA_ORTHOGRAPHIC) { + main_cam.transition.end_fovy = fmaxf(view_height, 0.1f); + } + + main_cam.transition.elapsed = 0; + main_cam.transition.active = true; + main_cam.state = CAM_MODE_EDIT_ORBIT; +} + +void +cam_update(void) { + if (main_cam.input) { + if (!main_cam.update && !main_cam.transition.active && + IsKeyPressed(KEY_P)) { + Camera *cam = &main_cam.cam; + f32 distance = Vector3Distance( + cam->position, cam->target); + + if (cam->projection == CAMERA_PERSPECTIVE) { + main_cam.perspective_fov = cam->fovy; + + cam->fovy = 2.0f * distance * + tanf(main_cam.perspective_fov * + DEG2RAD * 0.5f); + + cam->projection = CAMERA_ORTHOGRAPHIC; + main_cam.state = CAM_MODE_EDIT_ORBIT; + } else { + Vec3 backward = Vector3Normalize( + Vector3Subtract(cam->position, + cam->target)); + + distance = cam->fovy / (2.0f * + tanf(main_cam.perspective_fov * + DEG2RAD * 0.5f)); + + cam->position = Vector3Add( + cam->target, + Vector3Scale(backward, distance) + ); + + cam->fovy = main_cam.perspective_fov; + cam->projection = CAMERA_PERSPECTIVE; + } + } + + bool fly = main_cam.update && + main_cam.allow_fly && + IsMouseButtonDown(MOUSE_BUTTON_RIGHT) && + (IsKeyDown(KEY_W) || IsKeyDown(KEY_A) || + IsKeyDown(KEY_S) || IsKeyDown(KEY_D) || + IsKeyDown(KEY_Q) || IsKeyDown(KEY_E)); + + if (fly) { + main_cam.transition.active = false; + main_cam.state = CAM_MODE_EDIT_FLY; + } + + bool navigate = main_cam.update || + (main_cam.state == CAM_MODE_EDIT_ORBIT && + GetMouseWheelMove() != 0); + + if (navigate && !main_cam.transition.active) { + switch (main_cam.state) { + case CAM_MODE_EDIT_FLY: + cam_ctrl_editor(); + break; + + case CAM_MODE_EDIT_ORBIT: + cam_ctrl_orbit(); + break; + + default: + break; + } + } + } + + if (!main_cam.transition.active) { + return; + } + + const f32 duration = 0.25f; + main_cam.transition.elapsed = fminf( + main_cam.transition.elapsed + GetFrameTime(), duration); + + f32 t = EaseSineInOut( + main_cam.transition.elapsed, 0.0f, 1.0f, duration); + + main_cam.cam.position = Vector3Lerp( + main_cam.transition.start_pos, + main_cam.transition.end_pos, t); + + main_cam.cam.target = Vector3Lerp( + main_cam.transition.start_target, + main_cam.transition.end_target, t); + + main_cam.cam.fovy = Lerp( + main_cam.transition.start_fovy, + main_cam.transition.end_fovy, t); + + if (main_cam.transition.elapsed >= duration) { + main_cam.cam.position = main_cam.transition.end_pos; + main_cam.cam.target = main_cam.transition.end_target; + main_cam.cam.fovy = main_cam.transition.end_fovy; + main_cam.transition.active = false; + } +} + +static void cam_ctrl_editor(void) { if (!main_cam.update) { return; @@ -61,14 +193,14 @@ cam_ctrl_editor(void) { // makes it so you can stop faster than you can speed up f32 ms_amount = GetMouseWheelMove() < 0 ? - GetMouseWheelMove() * 1.5 : - GetMouseWheelMove() * 0.75; + GetMouseWheelMove() * 1.0 : + GetMouseWheelMove() * 0.5; main_cam.mv_scale += ms_amount; - main_cam.mv_scale = CLAMP(main_cam.mv_scale, 0.1, 50); + main_cam.mv_scale = CLAMP(main_cam.mv_scale, 0.05, 80); mv_speed *= main_cam.mv_scale; - mv_speed = CLAMP(mv_speed, 2, 1000); + mv_speed = CLAMP(mv_speed, 1, 1000); CameraMoveForward(&main_cam.cam, input_dir.z * mv_speed * GetFrameTime(), @@ -80,9 +212,60 @@ cam_ctrl_editor(void) { CameraMoveUp(&main_cam.cam, input_dir.y * mv_speed * GetFrameTime()); - CameraYaw(&main_cam.cam, - -GetMouseDelta().x * lk_speed * GetFrameTime(), 0); + Vec2 delta = GetMouseDelta(); + CameraYaw(&main_cam.cam, -delta.x * lk_speed, false); + CameraPitch(&main_cam.cam, -delta.y * lk_speed, true, false, false); +} + +static void +cam_ctrl_orbit(void) { + Camera *cam = &main_cam.cam; + f32 wheel = GetMouseWheelMove(); + f32 view_height; + + if (cam->projection == CAMERA_ORTHOGRAPHIC) { + if (wheel != 0) { + cam->fovy = Clamp( + cam->fovy * powf(0.85f, wheel), 0.1f, 2000.0f); + } - CameraPitch(&main_cam.cam, - -GetMouseDelta().y * lk_speed * GetFrameTime(), 1, 0, 0); + view_height = cam->fovy; + } else { + f32 distance = Vector3Distance(cam->position, cam->target); + + if (wheel != 0) { + f32 zoom = Clamp( + distance * powf(0.85f, wheel), 0.5f, 1000.0f); + CameraMoveToTarget(cam, zoom - distance); + distance = zoom; + } + + view_height = 2.0f * distance * + tanf(cam->fovy * DEG2RAD * 0.5f); + } + + if (!main_cam.update) { + return; + } + + Vec2 delta = GetMouseDelta(); + + if (IsMouseButtonDown(MOUSE_MIDDLE_BUTTON)) { + Vec3 forward = GetCameraForward(cam); + Vec3 right = GetCameraRight(cam); + Vec3 up = Vector3Normalize( + Vector3CrossProduct(right, forward)); + + f32 scale = view_height / GetScreenHeight(); + Vec3 offset = Vector3Add( + Vector3Scale(right, -delta.x * scale), + Vector3Scale(up, delta.y * scale)); + + cam->position = Vector3Add(cam->position, offset); + cam->target = Vector3Add(cam->target, offset); + } else { + CameraYaw(cam, -delta.x * main_cam.lk_speed, true); + CameraPitch(cam, -delta.y * main_cam.lk_speed, + true, true, false); + } } |
