diff options
author | chai <chaifix@163.com> | 2020-02-22 23:33:06 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2020-02-22 23:33:06 +0800 |
commit | b656c9415a8e7e3b5b7d8bf1f3c8a5444f830c79 (patch) | |
tree | f4f0578d58e5f12b00d2753efef83aaedc03137e /src/extend | |
parent | 9c89460e136ed6c6c43704d9a3a15105e0f006b0 (diff) |
*misc
Diffstat (limited to 'src/extend')
-rw-r--r-- | src/extend/camera.c | 55 | ||||
-rw-r--r-- | src/extend/camera.h | 35 | ||||
-rw-r--r-- | src/extend/transform.c | 37 | ||||
-rw-r--r-- | src/extend/transform.h | 15 |
4 files changed, 128 insertions, 14 deletions
diff --git a/src/extend/camera.c b/src/extend/camera.c index e69de29..377a09e 100644 --- a/src/extend/camera.c +++ b/src/extend/camera.c @@ -0,0 +1,55 @@ +#include "camera.h" + +void camera_init(Camera* cam) { + cam->is_viewdirty = cam->is_projdirty = TRUE; + 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->aspect = 600/500.f; + cam->fov = 90; + cam->zoom_speed = 20; +} + +void camera_getmatrix(Camera* cam, Mat4* view, Mat4* proj) { + camera_getviewmatrix(cam, view); + camera_getprojmatrix(cam, proj); +} + +void camera_getviewmatrix(Camera* cam, Mat4* out) { + if (!cam->is_viewdirty) { + if (out)*out = cam->view_matrix; + return; + } + transform_getinvmatrixnoscale(&cam->transform, &cam->view_matrix); + if(out) *out = cam->view_matrix; + cam->is_viewdirty = FALSE; +} + +void camera_getprojmatrix(Camera* cam, Mat4* out) { + if (!cam->is_projdirty) { + if (out)*out = cam->proj_matrix; + return; + } + mat4_setperspective(cam->fov, cam->aspect, cam->near, cam->far, &cam->proj_matrix); + if(out) *out = cam->proj_matrix; + cam->is_projdirty = FALSE; +} + +static void _onwheelscroll(Camera* cam, int wheel) { + 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_plus(&forward, &cam->transform.localposition, &cam->transform.localposition); + cam->is_viewdirty = TRUE; +} + +void camera_onevent(Camera* cam, wog_Event* e) { + if(e == NULL) return ; + if (e->type == WOG_EMOUSEWHEEL) {//zoom in\zoom out + _onwheelscroll(cam, e->wheel); + } +} diff --git a/src/extend/camera.h b/src/extend/camera.h index 2b7afa5..8227dbf 100644 --- a/src/extend/camera.h +++ b/src/extend/camera.h @@ -2,18 +2,37 @@ #define _SOFTSHADEROOM_CAMERA_H_ #include "../math/math.h" +#include "transform.h" +#include "../extern/wog.h" -typedef struct Camera { - Vec3 front; +#undef near +#undef far + +typedef struct { + Transform transform; + float fov, aspect, near, far; + /*matrix*/ + Mat4 view_matrix; /*or WorldToCameraMatrix*/ + Mat4 proj_matrix; + bool is_viewdirty, is_projdirty; + /*operations*/ + float zoom_speed; } Camera; -void camera_onmousemove(float x, float y); -void camera_onleftdown(); -void camera_onleftup(); -void camera_onrightdown(); -void camera_onrightup(); -void camera_onscroll(int amount); +typedef struct CameraConfig { + float fov, aspect, near, far; + Vec3 pos; +}CameraConfig; + +void camera_init(Camera* cam); + +void camera_setposition(float x, float y, float z); + +void camera_onevent(Camera* cam, wog_Event* e); void camera_getmatrix(Mat4* view, Mat4* proj); +void camera_getviewmatrix(Camera* cam, Mat4* view); +void camera_getprojmatrix(Camera* cam, Mat4* proj); + #endif
\ No newline at end of file diff --git a/src/extend/transform.c b/src/extend/transform.c index e69de29..7724614 100644 --- a/src/extend/transform.c +++ b/src/extend/transform.c @@ -0,0 +1,37 @@ +#include "transform.h" + +void transform_getpositionandrotation(Transform* trans, Vec3* pos, Quat* rot) { + *pos = trans->localposition; + *rot = trans->localrotation; + Transform* cur = trans->parent; + while (cur) { + /*按照srt的顺序计算pos*/ + vec3_scale3(pos, &cur->localscale, pos); + quat_applytovec3(&cur->localrotation, pos, pos); + vec3_plus(pos, &cur->localposition, pos); + /*计算旋转*/ + quat_multiply(&cur->localrotation, rot, rot); + + cur = cur->parent; + } +} + +void transform_getinvmatrixnoscale(Transform* trans, Mat4* worldToLocal) { + Vec3 pos; Quat rot; + transform_getpositionandrotation(trans, &pos, &rot); + quat_invert(&rot, &rot); + /*(TR)^-1 = R^-1T^-1*/ + quat_tomat4(&rot, worldToLocal); + vec3_scale(&pos, -1, &pos); + mat4_translate(worldToLocal, &pos, worldToLocal); +} + +void transform_getrotation(Transform* trans, Quat* rot) { + *rot = trans->localrotation; + Transform* cur = trans->parent; + while (cur) { + quat_multiply(&cur->localrotation, rot, rot); + } +} + + diff --git a/src/extend/transform.h b/src/extend/transform.h index 16b7c7f..f647819 100644 --- a/src/extend/transform.h +++ b/src/extend/transform.h @@ -1,5 +1,7 @@ #include "../math/math.h" + +typedef struct Transform Transform; /* ** Transform要注意按 scale -> rotation -> position 顺序计算 */ @@ -13,15 +15,16 @@ typedef struct Transform { Vec3 position; Vec3 scale; Quat rotation; - bool isdirty; } Transform; -void transform_translate(Transform* trans, Vec4* v, Vec4* out); - -Vec4 transform_translate(Transform* trans, Vec4* v); +void transform_translate(Transform* trans, Vec3* v); -void transform_getrotation(Quat* out); /*get global rotation*/ -void transform_getposition(Vec3* out); +void transform_getrotation(Transform* trans, Quat* out); /*get global rotation*/ +void transform_getposition(Transform* trans, Vec3* out); void transform_getscale(Vec3* out); +void transform_getpositionandrotation(Transform* trans, Vec3* pos, Quat* rot); void transform_setdirty(Transform* trans); + +/*get world to local matrix(no scale)*/ +void transform_getinvmatrixnoscale(Transform* transform, Mat4* worldToLocal); |