diff options
Diffstat (limited to 'src/extend/camera.c')
-rw-r--r-- | src/extend/camera.c | 87 |
1 files changed, 79 insertions, 8 deletions
diff --git a/src/extend/camera.c b/src/extend/camera.c index 377a09e..f349006 100644 --- a/src/extend/camera.c +++ b/src/extend/camera.c @@ -1,16 +1,31 @@ #include "camera.h" -void camera_init(Camera* cam) { +// A unity editor style camera + +void camera_init(Camera* cam, wog_Window* wnd) { cam->is_viewdirty = cam->is_projdirty = TRUE; + + // camera local = world cam->transform.parent = NULL ; cam->transform.localposition = vec3_make(0, 0, 800); cam->transform.localscale = vec3_make(1, 1, 1); cam->transform.localrotation = quat_make(0, 0, 0); + cam->near = 1; - cam->far = 1500; + cam->far = 5500; cam->aspect = 600/500.f; - cam->fov = 90; - cam->zoom_speed = 20; + cam->fov = 60; + cam->zoom_speed = 4000; + + cam->look_around = FALSE; + cam->move_around = FALSE; + cam->rotate_sensitivity.x = 5; + cam->rotate_sensitivity.y = 5; + cam->move_sensitivity.x = 150; + cam->move_sensitivity.y = 100; + cam->euler.yaw = cam->euler.pitch = cam->euler.roll = 0; + + cam->wnd = wnd; } void camera_getmatrix(Camera* cam, Mat4* view, Mat4* proj) { @@ -38,18 +53,74 @@ void camera_getprojmatrix(Camera* cam, Mat4* out) { cam->is_projdirty = FALSE; } -static void _onwheelscroll(Camera* cam, int wheel) { +static void _onwheelscroll(Camera* cam, int wheel, float dt) { Quat rot; transform_getrotation(&cam->transform, &rot); Vec3 forward = {0,0,-1}; quat_applytovec3(&rot, &forward, &forward); - vec3_scale(&forward, cam->zoom_speed * wheel, &forward); + vec3_scale(&forward, cam->zoom_speed * wheel * dt, &forward); vec3_plus(&forward, &cam->transform.localposition, &cam->transform.localposition); cam->is_viewdirty = TRUE; } -void camera_onevent(Camera* cam, wog_Event* e) { +static void _onlookaround(Camera* cam,float dt) { + if(!cam->look_around) return; + static Quat rot; + static Euler angle; + int x, y; + wog_getMouse(cam->wnd, &x, &y); + float dx = cam->mouse_prev.x - x, dy = y - cam->mouse_prev.y; + angle.x = dy * cam->rotate_sensitivity.y * dt; + angle.y = dx * cam->rotate_sensitivity.x * dt; + cam->euler.pitch += angle.x; + cam->euler.yaw += angle.y; + //printf("%f %f\n", cam->euler.pitch, cam->euler.yaw); + quat_fromeuler(&cam->euler, &cam->transform.localrotation); + cam->mouse_prev.x = x; cam->mouse_prev.y = y; + cam->is_viewdirty = TRUE; +} + +static void _onmovearound(Camera* cam, float dt) { + if(!cam->move_around) return ; + int x, y; + wog_getMouse(cam->wnd, &x, &y); + Vec3 dd = { cam->mouse_prev.x - x, y - cam->mouse_prev.y , 0}; + dd.x *= cam->move_sensitivity.x * dt; + dd.y *= cam->move_sensitivity.y * dt; + quat_applytovec3(&cam->transform.localrotation, &dd, &dd); + //printf("%f %f %f\n", dd.x, dd.y, dd.z); + vec3_plus(&cam->transform.localposition, &dd, &cam->transform.localposition); + cam->mouse_prev.x = x; cam->mouse_prev.y = y; + cam->is_viewdirty = TRUE; +} + +void camera_onevent(Camera* cam, wog_Event* e, float dt) { if(e == NULL) return ; if (e->type == WOG_EMOUSEWHEEL) {//zoom in\zoom out - _onwheelscroll(cam, e->wheel); + _onwheelscroll(cam, e->wheel, dt); + } + else if (e->type == WOG_EMOUSEBUTTONDOWN) { + if (!cam->look_around && e->button == WOG_MOUSE_RBUTTON) { + cam->look_around = TRUE; + cam->mouse_prev.x = e->pos.x; + cam->mouse_prev.y = e->pos.y; + } + if (!cam->move_around && e->button == WOG_MOUSE_MIDDLE) { + cam->move_around = TRUE; + cam->mouse_prev.x = e->pos.x; + cam->mouse_prev.y = e->pos.y; + } + } + else if (e->type == WOG_EMOUSEBUTTONUP) { + if (e->button == WOG_MOUSE_RBUTTON) + cam->look_around = FALSE; + if (e->button == WOG_MOUSE_MIDDLE) + cam->move_around = FALSE; } } + +void camera_onupdate(Camera* cam, float dt) { + if (cam->look_around) + _onlookaround(cam, dt); + if (cam->move_around) + _onmovearound(cam, dt); +}
\ No newline at end of file |