# HG changeset patch # User John Tsiombikas # Date 1335206590 -10800 # Node ID 2723dc026c4f7772262d236c3021f54ea9179a82 # Parent aab0d8ea21cdeeeda1e91fc95ca51220a1476c87 collision detection diff -r aab0d8ea21cd -r 2723dc026c4f Makefile --- a/Makefile Sun Apr 22 06:26:08 2012 +0300 +++ b/Makefile Mon Apr 23 21:43:10 2012 +0300 @@ -9,6 +9,8 @@ LDFLAGS = -L/usr/local/lib $(add_lib) $(libgl) $(libal) -lm -lvmath -limago ifeq ($(shell uname -s), Darwin) + CC = clang + CXX = clang++ libgl = -framework OpenGL -framework GLUT -lGLEW add_inc += -I/opt/local/include add_lib += -L/opt/local/lib diff -r aab0d8ea21cd -r 2723dc026c4f sdr/vein.p.glsl --- a/sdr/vein.p.glsl Sun Apr 22 06:26:08 2012 +0300 +++ b/sdr/vein.p.glsl Mon Apr 23 21:43:10 2012 +0300 @@ -1,7 +1,7 @@ uniform sampler2D tex_norm; uniform vec3 fog_col; -varying vec3 vpos, vnorm; +varying vec3 vpos; varying vec3 ldir, vdir; const float fog_dens = 0.075; @@ -13,7 +13,7 @@ vec3 tnorm = texture2D(tex_norm, gl_TexCoord[0].st).xyz * 2.0 - 1.0; vec3 n = normalize(tnorm); vec3 v = normalize(vdir); - vec3 l = v;//normalize(ldir); + vec3 l = normalize(ldir); vec3 h = normalize(l + v); vec3 diff = vec3(0.8, 0.25, 0.2) * (1.0 - max(dot(l, n), 0.0)); diff -r aab0d8ea21cd -r 2723dc026c4f sdr/vein.v.glsl --- a/sdr/vein.v.glsl Sun Apr 22 06:26:08 2012 +0300 +++ b/sdr/vein.v.glsl Mon Apr 23 21:43:10 2012 +0300 @@ -1,6 +1,6 @@ attribute vec3 attr_tang; -varying vec3 vpos, vnorm; +varying vec3 vpos; varying vec3 ldir, vdir; void main() @@ -18,9 +18,8 @@ t.x, b.x, n.x, t.y, b.y, n.y, t.z, b.z, n.z); - ldir = tbn_mat * (gl_LightSource[0].position.xyz - vpos); + ldir = tbn_mat * vec3(0, 0, 1); vdir = tbn_mat * -vpos; - vnorm = n; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; } diff -r aab0d8ea21cd -r 2723dc026c4f src/game.cc --- a/src/game.cc Sun Apr 22 06:26:08 2012 +0300 +++ b/src/game.cc Mon Apr 23 21:43:10 2012 +0300 @@ -6,10 +6,10 @@ #include "camera.h" #include "cockpit.h" -static const Vector3 fog_color{0.64, 0.1, 0.1}; +static const Vector3 fog_color(0.64, 0.1, 0.1); static Vein *vein; -static Ship ship; +static Ship *ship; static int keystate[256]; static int dbg_inside = false; @@ -39,6 +39,9 @@ } vein->set_fog_color(fog_color); + // create the player's ship + ship = new Ship(vein); + glClearColor(fog_color.x, fog_color.y, fog_color.z, 1); return true; @@ -64,25 +67,19 @@ // handle key input if(keystate['w'] || keystate['W']) { - ship.accelerate(1.0 * dt); + ship->accelerate(1.0 * dt); } if(keystate['s'] || keystate['S']) { - ship.accelerate(-1.0 * dt); + ship->accelerate(-1.0 * dt); } if(keystate['d'] || keystate['D']) { - ship.accelerate_side(1.0 * dt); + ship->accelerate_side(1.0 * dt); } if(keystate['a'] || keystate['A']) { - ship.accelerate_side(-1.0 * dt); + ship->accelerate_side(-1.0 * dt); } - /*if(keystate['e'] || keystate['E']) { - ship.turn(0.0, 1.0 * dt); - } - if(keystate['c'] || keystate['C']) { - ship.turn(0.0, -1.0 * dt); - }*/ - ship.update(dt); + ship->update(dt); last_upd = msec; } @@ -92,15 +89,15 @@ glMatrixMode(GL_MODELVIEW); if(dbg_inside) { - load_gl_matrix(ship.get_matrix().inverse()); + load_gl_matrix(ship->get_matrix().inverse()); } else { dbgcam.use(); } - vein->draw(ship.get_position()); + vein->draw(ship->get_position()); if(!dbg_inside) { - ship.dbg_draw(); + ship->dbg_draw(); } else { cockpit_draw(); } @@ -115,6 +112,7 @@ break; case '\b': + case 127: dbg_inside = !dbg_inside; if(dbg_inside) { glutPassiveMotionFunc(game_input_mmotion); @@ -163,7 +161,7 @@ } if(dbg_inside) { - ship.turn((float)-dx / win_xsz, (float)-dy / win_ysz); + ship->turn((float)-dx / win_xsz, (float)-dy / win_ysz); ignore_next_motion = true; glutWarpPointer(win_xsz / 2, win_ysz / 2); diff -r aab0d8ea21cd -r 2723dc026c4f src/ship.cc --- a/src/ship.cc Sun Apr 22 06:26:08 2012 +0300 +++ b/src/ship.cc Mon Apr 23 21:43:10 2012 +0300 @@ -1,9 +1,11 @@ #include "opengl.h" #include "ship.h" +#include "vein.h" -Ship::Ship() +Ship::Ship(Vein *vein) { friction = 0.2; + this->vein = vein; } void Ship::accelerate(double a) @@ -27,8 +29,37 @@ void Ship::update(time_sec_t dt) { - pos += velocity * dt; + Vector3 newpos = pos + velocity * dt; velocity -= velocity * friction * dt; + + HitPoint hit; + if(collision(vein, pos, newpos, &hit)) { + newpos = hit.pos; + // TODO damp velocity along normal + } + + pos = newpos; +} + +#define SHIP_RAD 0.25 +bool Ship::collision(const Vein *vein, const Vector3 &start, const Vector3 &end, HitPoint *hit) const +{ + Vector3 cent = vein->calc_center(end); + float rad = vein->get_radius(); + + Vector3 dir = end - cent; + float dist = dir.length(); + + if(dist < rad - SHIP_RAD) { + return false; + } + + if(hit) { + Vector3 dir_norm = dir / dist; + hit->pos = cent + dir_norm * (rad - SHIP_RAD); + hit->normal = -dir_norm; + } + return true; } const Vector3 &Ship::get_position() const @@ -38,13 +69,13 @@ Vector3 Ship::get_direction() const { - static const Vector3 dir{0, 0, -1}; + static const Vector3 dir(0, 0, -1); return dir.transformed(rot); } Vector3 Ship::get_right() const { - static const Vector3 dir{1, 0, 0}; + static const Vector3 dir(1, 0, 0); return dir.transformed(rot); } diff -r aab0d8ea21cd -r 2723dc026c4f src/ship.h --- a/src/ship.h Sun Apr 22 06:26:08 2012 +0300 +++ b/src/ship.h Mon Apr 23 21:43:10 2012 +0300 @@ -4,14 +4,22 @@ #include #include "game.h" +class Vein; + +struct HitPoint { + Vector3 pos; + Vector3 normal; +}; + class Ship { private: Vector3 pos, velocity; Quaternion rot; double friction; + Vein *vein; public: - Ship(); + Ship(Vein *vein); void accelerate(double a); void accelerate_side(double a); @@ -19,6 +27,8 @@ void update(time_sec_t dt); + bool collision(const Vein *vein, const Vector3 &start, const Vector3 &end, HitPoint *hit) const; + const Vector3 &get_position() const; Vector3 get_direction() const; Vector3 get_right() const; diff -r aab0d8ea21cd -r 2723dc026c4f src/sys.c --- a/src/sys.c Sun Apr 22 06:26:08 2012 +0300 +++ b/src/sys.c Mon Apr 23 21:43:10 2012 +0300 @@ -5,9 +5,6 @@ #elif defined(WIN32) #include #elif defined(__APPLE__) -#error "not ported to mac yet" -#else -#error "unrecognized or unsupported platform" #endif int sys_lock_mouse(void) diff -r aab0d8ea21cd -r 2723dc026c4f src/vein.cc --- a/src/vein.cc Sun Apr 22 06:26:08 2012 +0300 +++ b/src/vein.cc Mon Apr 23 21:43:10 2012 +0300 @@ -29,20 +29,6 @@ free_program(sdr); } -Vector3 Vein::calc_center(const Vector3 &ppos) const -{ - Vector3 pt{0, 0, ppos.z}; - pt.x = sin(ppos.z * 0.75); - pt.y = cos(ppos.z * 0.2) * 0.6; - return pt; -} - -Vector3 Vein::calc_dir(const Vector3 &ppos) const -{ - Vector3 dir = calc_center(ppos + Vector3(0, 0, 0.01)) - calc_center(ppos - Vector3(0, 0, 0.01)); - return dir.normalized(); -} - void Vein::build_idxbuf() { delete [] idxbuf; @@ -80,6 +66,16 @@ return true; } +void Vein::set_radius(float rad) +{ + this->rad = rad; +} + +float Vein::get_radius() const +{ + return rad; +} + void Vein::set_fog_color(const Vector3 &col) { fog_color = col; @@ -110,12 +106,12 @@ Vector3 right = cross_product(up, dir); up = cross_product(dir, right); - Matrix3x3 vrot{right, up, dir}; + Matrix3x3 vrot(right, up, dir); vrot.transpose(); float theta = 0.0, dtheta = 2.0 * M_PI / (ring_subdiv - 1); for(int j=0; j