summaryrefslogtreecommitdiff
path: root/src/extend
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2020-02-22 23:33:06 +0800
committerchai <chaifix@163.com>2020-02-22 23:33:06 +0800
commitb656c9415a8e7e3b5b7d8bf1f3c8a5444f830c79 (patch)
treef4f0578d58e5f12b00d2753efef83aaedc03137e /src/extend
parent9c89460e136ed6c6c43704d9a3a15105e0f006b0 (diff)
*misc
Diffstat (limited to 'src/extend')
-rw-r--r--src/extend/camera.c55
-rw-r--r--src/extend/camera.h35
-rw-r--r--src/extend/transform.c37
-rw-r--r--src/extend/transform.h15
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);