diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/extend/camera.c | 87 | ||||
-rw-r--r-- | src/extend/camera.h | 17 | ||||
-rw-r--r-- | src/extend/transform.c | 4 | ||||
-rw-r--r-- | src/extend/transform.h | 2 | ||||
-rw-r--r-- | src/extern/wog.c | 18 | ||||
-rw-r--r-- | src/extern/wog.h | 6 | ||||
-rw-r--r-- | src/main.c | 13 | ||||
-rw-r--r-- | src/math/mat.c | 2 | ||||
-rw-r--r-- | src/math/math.h | 4 | ||||
-rw-r--r-- | src/math/quat.c | 2 | ||||
-rw-r--r-- | src/math/vec3.c | 6 |
11 files changed, 138 insertions, 23 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 diff --git a/src/extend/camera.h b/src/extend/camera.h index 8227dbf..e43efe6 100644 --- a/src/extend/camera.h +++ b/src/extend/camera.h @@ -4,6 +4,7 @@ #include "../math/math.h" #include "transform.h" #include "../extern/wog.h" +#include "../extern/wog.h" #undef near #undef far @@ -16,7 +17,16 @@ typedef struct { Mat4 proj_matrix; bool is_viewdirty, is_projdirty; /*operations*/ - float zoom_speed; + float zoom_speed; + Vec2 rotate_sensitivity; + Vec2 move_sensitivity; + Euler euler; + /*events*/ + bool look_around; + Vec2 mouse_prev; + bool move_around; + /*window*/ + wog_Window* wnd; } Camera; typedef struct CameraConfig { @@ -24,11 +34,12 @@ typedef struct CameraConfig { Vec3 pos; }CameraConfig; -void camera_init(Camera* cam); +void camera_init(Camera* cam, wog_Window* wnd); void camera_setposition(float x, float y, float z); -void camera_onevent(Camera* cam, wog_Event* e); +void camera_onevent(Camera* cam, wog_Event* e, float dt); +void camera_onupdate(Camera* cam, float dt); void camera_getmatrix(Mat4* view, Mat4* proj); diff --git a/src/extend/transform.c b/src/extend/transform.c index 7724614..6979e40 100644 --- a/src/extend/transform.c +++ b/src/extend/transform.c @@ -34,4 +34,8 @@ void transform_getrotation(Transform* trans, Quat* rot) { } } +void transform_localtoworlddir(Transform* trans, Vec3* dir, Vec3* out) { +//RrRs + +} diff --git a/src/extend/transform.h b/src/extend/transform.h index f647819..330c023 100644 --- a/src/extend/transform.h +++ b/src/extend/transform.h @@ -28,3 +28,5 @@ void transform_setdirty(Transform* trans); /*get world to local matrix(no scale)*/ void transform_getinvmatrixnoscale(Transform* transform, Mat4* worldToLocal); + +void transform_localtoworlddir(Transform* trans, Vec3* dir, Vec3* out); diff --git a/src/extern/wog.c b/src/extern/wog.c index 6cdfb6f..28d4dd1 100644 --- a/src/extern/wog.c +++ b/src/extern/wog.c @@ -131,6 +131,8 @@ void wog_handleEvent(wog_Window* window, MSG* msg, wog_Event* e) zero_mem(e, sizeof(wog_Event)); e->type = WOG_EMOUSEBUTTONDOWN; e->button = WOG_MOUSE_LBUTTON; + wog_getMouse(window, &e->pos.x, &e->pos.y); + SetCapture(hWnd); return ; } @@ -139,6 +141,8 @@ void wog_handleEvent(wog_Window* window, MSG* msg, wog_Event* e) zero_mem(e, sizeof(wog_Event)); e->type = WOG_EMOUSEBUTTONDOWN; e->button = WOG_MOUSE_RBUTTON; + wog_getMouse(window, &e->pos.x, &e->pos.y); + SetCapture(hWnd); return ; } @@ -147,6 +151,8 @@ void wog_handleEvent(wog_Window* window, MSG* msg, wog_Event* e) zero_mem(e, sizeof(wog_Event)); e->type = WOG_EMOUSEBUTTONDOWN; e->button = WOG_MOUSE_MIDDLE; + wog_getMouse(window, &e->pos.x, &e->pos.y); + SetCapture(hWnd); return ; } @@ -155,6 +161,8 @@ void wog_handleEvent(wog_Window* window, MSG* msg, wog_Event* e) zero_mem(e, sizeof(wog_Event)); e->type = WOG_EMOUSEBUTTONUP; e->button = WOG_MOUSE_LBUTTON; + wog_getMouse(window, &e->pos.x, &e->pos.y); + ReleaseCapture(); return ; } @@ -163,6 +171,8 @@ void wog_handleEvent(wog_Window* window, MSG* msg, wog_Event* e) zero_mem(e, sizeof(wog_Event)); e->type = WOG_EMOUSEBUTTONUP; e->button = WOG_MOUSE_RBUTTON; + wog_getMouse(window, &e->pos.x, &e->pos.y); + ReleaseCapture(); return ; } @@ -171,6 +181,8 @@ void wog_handleEvent(wog_Window* window, MSG* msg, wog_Event* e) zero_mem(e, sizeof(wog_Event)); e->type = WOG_EMOUSEBUTTONUP; e->button = WOG_MOUSE_MIDDLE; + wog_getMouse(window, &e->pos.x, &e->pos.y); + ReleaseCapture(); return ; } @@ -626,8 +638,10 @@ void wog_getMouse(wog_Window* wnd, int *x, int *y) ScreenToClient(wnd->hwnd, &p); int w, h; wog_getwindowsize(wnd, &w, &h); - *x = clamp(p.x, 0, w); - *y = clamp(p.y, 0, h); + //*x = clamp(p.x, 0, w); + //*y = clamp(p.y, 0, h); + *x = p.x; + *y = p.y; } diff --git a/src/extern/wog.h b/src/extern/wog.h index f616d82..ba11556 100644 --- a/src/extern/wog.h +++ b/src/extern/wog.h @@ -42,8 +42,8 @@ enum // mouse button event, e.button value typedef struct wog_Event { int type; - union // event value - { + //union // event value + //{ int key; // for key, simply use windows virtual key value // see https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx struct // for mouse motion @@ -52,7 +52,7 @@ typedef struct wog_Event }pos; int wheel; // 1 indicate scroll up and -1 indicate scrool down int button; // mouse button - }; + //}; }wog_Event; typedef struct { @@ -42,16 +42,18 @@ int main(int argc, char* argv[]) { onload(NULL); /*set up global camera*/ Camera cam; - camera_init(&cam); + camera_init(&cam, wnd); /* main loop */ uint prev = wog_tick(); uint dt = 0; + float _dt = 0; uint frame_count = 0; uint time_stamp = 0; wog_Event e; while (1) { + /*handle events*/ while (wog_pollEvent(wnd, &e)) { - camera_onevent(&cam, &e); + camera_onevent(&cam, &e, _dt); if (e.type == WOG_ECLOSE) { goto quit; } else { @@ -59,6 +61,7 @@ int main(int argc, char* argv[]) { } } + /*frame count*/ dt = wog_tick() - prev; prev += dt; time_stamp += dt; @@ -69,7 +72,10 @@ int main(int argc, char* argv[]) { frame_count = 0; } - onupdate(&dt); + /*update*/ + _dt = dt / 1000.f; + camera_onupdate(&cam, _dt); + onupdate(&_dt); /*set vp matrix*/ ssr_matrixmode(MATRIX_PROJECTION); @@ -80,6 +86,7 @@ int main(int argc, char* argv[]) { ssr_loadmatrix(&cam.view_matrix); ssr_matrixmode(MATRIX_MODEL); + /*draw*/ ondraw(NULL); ssr_present(); diff --git a/src/math/mat.c b/src/math/mat.c index 592dd5e..c254c02 100644 --- a/src/math/mat.c +++ b/src/math/mat.c @@ -748,7 +748,7 @@ void mat4_toquat(Mat4* in, Quat* out) { quat_normalize(out, out); } -void mat3_applytovec3(Mat3* m, Vec3* v, Vec3* out) { +void mat3_multvec3(Mat3* m, Vec3* v, Vec3* out) { ssr_assert(m && v && out); out->x = m->e00 * v->x + m->e01 * v->y + m->e02 * v->z; out->y = m->e10 * v->x + m->e11 * v->y + m->e12 * v->z; diff --git a/src/math/math.h b/src/math/math.h index 03e156e..a69dabe 100644 --- a/src/math/math.h +++ b/src/math/math.h @@ -11,7 +11,7 @@ #define PI 3.141592653f #define RAD2DEG 57.295779523f /*180.f/PI*/ #define DEG2RAG 0.0174532925f /*PI/180.f*/ -#define EPSILON 1e-6f +#define EPSILON 1e-4f /* 用来打印的公共buffer */ extern char printbuffer[1024]; @@ -251,7 +251,7 @@ void mat4_toquat(Mat4* in, Quat* out); /*in是正交矩阵*/ #define ROWMAT(A, ...)\ Mat4 A={__VA_ARGS__};mat4_transpose(&A, &A); -void mat3_applytovec3(Mat3* m, Vec3* v, Vec3* out); +void mat3_multvec3(Mat3* m, Vec3* v, Vec3* out); void mat23_applytovec3(Mat23* m, Vec3* v, Vec2* out); void mat43_applytovec3(Mat43* m, Vec3* v, Vec4* out); diff --git a/src/math/quat.c b/src/math/quat.c index 4dedbed..8f7274d 100644 --- a/src/math/quat.c +++ b/src/math/quat.c @@ -81,6 +81,7 @@ void euler_toquat(Euler* euler, Quat* out) { quat_fromeuler(euler, out); } +/*这里精度不对*/ bool quat_isidentity(Quat* q) { return compare(quat_magnitude(q), 1.f); } @@ -147,6 +148,7 @@ void quat_applytovec3(Quat* q, Vec3* v, Vec3* out) { void quat_tomat4(Quat* q, Mat4* out) { ssr_assert(q && out); ssr_assert(quat_isidentity(q)); + mat4_setidentity(out); float x = q->x * 2.0F; /*从quat_applytovec3能得到矩阵形式*/ diff --git a/src/math/vec3.c b/src/math/vec3.c index 5d273d8..df56f3f 100644 --- a/src/math/vec3.c +++ b/src/math/vec3.c @@ -110,7 +110,11 @@ void vec3_multiply(Vec3* v1, Vec3* v2, Quat* out) { void vec3_normalize(Vec3* v, Vec3* out) { ssr_assert(v && out); //float mag = rsqrt(v->x * v->x + v->y * v->y + v->z * v->z); - float mag = 1.f / vec3_magnitude(v); + float mag = vec3_magnitude(v); + if (compare(mag, 0)) { + return; + } + mag = 1.f / mag; out->x = v->x * mag; out->y = v->y * mag; out->z = v->z * mag; |