summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/extend/camera.c87
-rw-r--r--src/extend/camera.h17
-rw-r--r--src/extend/transform.c4
-rw-r--r--src/extend/transform.h2
-rw-r--r--src/extern/wog.c18
-rw-r--r--src/extern/wog.h6
-rw-r--r--src/main.c13
-rw-r--r--src/math/mat.c2
-rw-r--r--src/math/math.h4
-rw-r--r--src/math/quat.c2
-rw-r--r--src/math/vec3.c6
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 {
diff --git a/src/main.c b/src/main.c
index 404b2d1..edc31bb 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;