# HG changeset patch # User John Tsiombikas # Date 1422816976 -7200 # Node ID 2cbf85690e0323220f777e4bc2cbb31297bf5698 # Parent 282da6123fd41a61b52c77c191fdec341753479e more stuff diff -r 282da6123fd4 -r 2cbf85690e03 src/app.cc --- a/src/app.cc Sun Feb 01 12:51:10 2015 +0200 +++ b/src/app.cc Sun Feb 01 20:56:16 2015 +0200 @@ -2,12 +2,18 @@ #include "opengl.h" #include "app.h" #include "user.h" +#include "timer.h" static void draw_grid(int num, float sep); static User user; static float eye_level = 1.6; +static int win_width, win_height; +static bool keystate[256]; +static bool bnstate[16]; +static int prev_x, prev_y, click_x, click_y; + bool app_init() { if(!init_opengl()) { @@ -20,8 +26,40 @@ { } +static void update(unsigned int msec) +{ + static unsigned int prev_upd; + float dt = (float)(msec - prev_upd) / 1000.0f; + prev_upd = msec; + + static const float walk_speed = 1.0; + float fwd = 0.0f, right = 0.0f; + + if(keystate['w'] || keystate['W']) { + fwd += walk_speed * dt; + redisplay(); + } + if(keystate['s'] || keystate['S']) { + fwd -= walk_speed * dt; + redisplay(); + } + if(keystate['d'] || keystate['D']) { + right += walk_speed * 0.5 * dt; + redisplay(); + } + if(keystate['a'] || keystate['A']) { + right -= walk_speed * 0.5 * dt; + redisplay(); + } + + user.posrot.move(fwd, right); +} + void app_display() { + unsigned int msec = get_time_msec(); + update(msec); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); @@ -40,6 +78,9 @@ void app_reshape(int x, int y) { + win_width = x; + win_height = y; + glViewport(0, 0, x, y); glMatrixMode(GL_PROJECTION); @@ -55,14 +96,39 @@ quit(); } } + + if(key < 256) { + keystate[key] = pressed; + } + + redisplay(); } void app_mouse_button(int bn, bool pressed, int x, int y) { + bnstate[bn] = pressed; + prev_x = x; + prev_y = y; + + if(bn == 0 && pressed) { + click_x = x; + click_y = y; + } } void app_mouse_motion(int x, int y) { + static const float rot_speed = 10.0; + + float dx = (x - prev_x) / win_width; + float dy = (y - prev_y) / win_height; + prev_x = x; + prev_y = y; + + if(bnstate[0]) { + user.posrot.rotate(dx * rot_speed, dy * rot_speed); + redisplay(); + } } void app_sball_motion(float x, float y, float z) @@ -83,6 +149,7 @@ float max_dist = hnum * sep; glBegin(GL_LINES); + glColor3f(0.4, 0.4, 0.4); glVertex3f(0, 0, -max_dist); glVertex3f(0, 0, max_dist); glVertex3f(-max_dist, 0, 0); diff -r 282da6123fd4 -r 2cbf85690e03 src/timer.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/timer.cc Sun Feb 01 20:56:16 2015 +0200 @@ -0,0 +1,118 @@ +#include "timer.h" + +#if defined(__APPLE__) && !defined(__unix__) +#define __unix__ +#endif + +#ifdef __unix__ +#include +#include +#include + +#ifdef CLOCK_MONOTONIC +unsigned long get_time_msec(void) +{ + struct timespec ts; + static struct timespec ts0; + + clock_gettime(CLOCK_MONOTONIC, &ts); + if(ts0.tv_sec == 0 && ts0.tv_nsec == 0) { + ts0 = ts; + return 0; + } + return (ts.tv_sec - ts0.tv_sec) * 1000 + (ts.tv_nsec - ts0.tv_nsec) / 1000000; +} +#else /* no fancy POSIX clocks, fallback to good'ol gettimeofday */ +unsigned long get_time_msec(void) +{ + struct timeval tv; + static struct timeval tv0; + + gettimeofday(&tv, 0); + if(tv0.tv_sec == 0 && tv0.tv_usec == 0) { + tv0 = tv; + return 0; + } + return (tv.tv_sec - tv0.tv_sec) * 1000 + (tv.tv_usec - tv0.tv_usec) / 1000; +} +#endif /* !posix clock */ + +void sleep_msec(unsigned long msec) +{ + usleep(msec * 1000); +} +#endif + +#ifdef WIN32 +#include +#pragma comment(lib, "winmm.lib") + +unsigned long get_time_msec(void) +{ + return timeGetTime(); +} + +void sleep_msec(unsigned long msec) +{ + Sleep(msec); +} +#endif + +double get_time_sec(void) +{ + return get_time_msec() / 1000.0f; +} + +void sleep_sec(double sec) +{ + if(sec > 0.0f) { + sleep_msec(sec * 1000.0f); + } +} + + +Timer::Timer() +{ + reset(); +} + +void Timer::reset() +{ + pause_time = 0; + start_time = get_time_msec(); +} + +void Timer::start() +{ + if(!is_running()) { + // resuming + start_time += get_time_msec() - pause_time; + pause_time = 0; + } +} + +void Timer::stop() +{ + if(is_running()) { + pause_time = get_time_msec(); + } +} + +bool Timer::is_running() const +{ + return pause_time == 0; +} + +unsigned long Timer::get_msec() const +{ + if(!is_running()) { + // in paused state... + return pause_time - start_time; + } + return get_time_msec() - start_time; +} + +double Timer::get_sec() const +{ + return (double)get_msec() / 1000.0; +} diff -r 282da6123fd4 -r 2cbf85690e03 src/timer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/timer.h Sun Feb 01 20:56:16 2015 +0200 @@ -0,0 +1,29 @@ +#ifndef TIMER_H_ +#define TIMER_H_ + +unsigned long get_time_msec(void); +void sleep_msec(unsigned long msec); + +double get_time_sec(void); +void sleep_sec(double sec); + + +class Timer { +private: + unsigned long start_time, pause_time; + +public: + Timer(); + + void reset(); + + void start(); + void stop(); + + bool is_running() const; + + unsigned long get_msec() const; + double get_sec() const; +}; + +#endif // TIMER_H_ diff -r 282da6123fd4 -r 2cbf85690e03 src/user.cc --- a/src/user.cc Sun Feb 01 12:51:10 2015 +0200 +++ b/src/user.cc Sun Feb 01 20:56:16 2015 +0200 @@ -2,16 +2,28 @@ void PosRot::move(float dfwd, float dright, float dup) { + Vector3 dir = Vector3(dright, dup, dfwd); + dir.transform(rot); + pos += dir; } void PosRot::rotate(float dhoriz, float dvert) { + rot.rotate(Vector3(1, 0, 0), dvert); + rot.rotate(Vector3(0, 1, 0), dhoriz); } void PosRot::calc_matrix(Matrix4x4 *res) const { + Matrix4x4 rmat = rot.get_rotation_matrix(); + Matrix4x4 tmat; + tmat.set_translation(pos); + + *res = tmat * rmat; } void PosRot::calc_inv_matrix(Matrix4x4 *res) const { + calc_matrix(res); + *res = res->inverse(); } diff -r 282da6123fd4 -r 2cbf85690e03 src/user.h --- a/src/user.h Sun Feb 01 12:51:10 2015 +0200 +++ b/src/user.h Sun Feb 01 20:56:16 2015 +0200 @@ -7,7 +7,7 @@ Vector3 pos; Quaternion rot; - void move(float dfwd, float dright, float dup); + void move(float dfwd, float dright, float dup = 0.0f); void rotate(float dhoriz, float dvert); void calc_matrix(Matrix4x4 *res) const;