diff options
author | taw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5> | 2008-05-22 12:43:23 +0000 |
---|---|---|
committer | taw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5> | 2008-05-22 12:43:23 +0000 |
commit | 5074aa838702ec42b89be0adc32098f9d14cc34d (patch) | |
tree | eabb4823f06f7567aa3ac85a97885a77e0e56d56 /src/physics.c | |
parent | a5f2f4662ae54c6e073934e64805e3f837cfc278 (diff) |
Subdivision fixes
First part of collision detection (needs work, commented out)
Wireframe mode ('w' to enter, 'e' to exit)
Spotlighting
git-svn-id: svn://cook.msm.cam.ac.uk:745/thrust3d/thrust3d@35 84d2e878-0bd5-11dd-ad15-13eda11d74c5
Diffstat (limited to 'src/physics.c')
-rw-r--r-- | src/physics.c | 129 |
1 files changed, 127 insertions, 2 deletions
diff --git a/src/physics.c b/src/physics.c index 0bcbae7..0c33e63 100644 --- a/src/physics.c +++ b/src/physics.c @@ -39,8 +39,130 @@ /* Conversion factor between friction and 'yawthrust' */ #define TORQUE 3 +static int physics_will_collide_face(GLfloat sx, GLfloat sy, GLfloat sz, GLfloat vx, GLfloat vy, GLfloat vz, + GLfloat nx, GLfloat ny, GLfloat nz, GLfloat *fvert, int nfvert, Uint32 dt) { + + GLfloat px, py, pz; + GLfloat t1, t2, b; + int t; + + /* Range test */ + px = fvert[3*0 + 0]; + py = fvert[3*0 + 1]; + pz = fvert[3*0 + 2]; + + t1 = px*nx + py*ny + pz*nz; + t2 = sx*nx + sy*ny + sz*nz; + b = vx*nx + vy*ny + vz*nz; + if ( b == 0 ) return 0; /* Collision happens infinitely far in the future */ + t = (t1 - t2) / b; + +// printf("Testing vertex %8f %8f %8f, velocity %8f %8f %8f against face %8f %8f %8f\n", +// sx, sy, sz, vx, vy, vz, px, py, pz); +// printf("Collision happens at t + %i\n", t); +// exit(0); + + /* If the vertex is exactly on the plane, then moving away from the plane is OK */ + if ( (t == 0) && (b > 0) ) return 0; + + if ( t < 0 ) return 0; /* Collided in the past */ + if ( t > dt ) return 0; /* Not going to collide this step */ + + /* Boundary test */ + + + return 1; + +} + +/* Return non-zero if 'obj' will collide with 'other' with 'dt' milliseconds */ +static int physics_will_collide(ModelInstance *obj, ModelInstance *other, Uint32 dt) { + + int i; + + const GLfloat vx = obj->vx; + const GLfloat vy = obj->vy; + const GLfloat vz = obj->vz; + + /* Consider all the primitives in 'obj' */ + for ( i=0; i<obj->model->num_primitives; i++ ) { + + int j; + + /* Consider all the vertices in this primitive */ + for ( j=0; j<obj->model->primitives[i]->num_vertices; j++ ) { + + int a; + const GLfloat sx = obj->x + obj->model->primitives[i]->vertices[3*j+0]; + const GLfloat sy = obj->y + obj->model->primitives[i]->vertices[3*j+1]; + const GLfloat sz = obj->z + obj->model->primitives[i]->vertices[3*j+2]; + + /* Consider all the primitives in 'other' */ + for ( a=0; a<other->model->num_primitives; a++ ) { + + const GLfloat nx = other->model->primitives[a]->normals[0]; + const GLfloat ny = other->model->primitives[a]->normals[1]; + const GLfloat nz = other->model->primitives[a]->normals[2]; + + switch ( other->model->primitives[a]->type ) { + + case PRIMITIVE_QUADS : { + + int f; + + /* Faces are quads */ + for ( f=0; f<other->model->primitives[a]->num_vertices/4; f++ ) { + + GLfloat face[3*4]; + int q; + + for ( q=0; q<4; q++ ) { + face[3*q + 0] = other->x + other->model->primitives[a]->vertices[4*(f+q) + 0]; + face[3*q + 1] = other->y + other->model->primitives[a]->vertices[4*(f+q) + 1]; + face[3*q + 2] = other->z + other->model->primitives[a]->vertices[4*(f+q) + 2]; + } + + if ( physics_will_collide_face(sx, sy, sz, vx, vy, vz, nx, ny, nz, + face, 4, dt) != 0 ) { + return 1; /* Don't waste time looking anywhere else */ + } + } + break; + } + + } + + } + + } + } + + return 0; + +} + /* Called once for each object which isn't just "scenery" */ -static void physics_process(ModelInstance *obj, Uint32 dt) { +static void physics_process(ModelInstance *obj, Uint32 dt, Room **rooms, int num_rooms) { + + int i; + + #if 0 + /* Consider all the currently relevant rooms */ + for ( i=0; i<num_rooms; i++ ) { + int j; + /* Consider all the objects in this room */ + for ( j=0; j<rooms[i]->num_objects; j++ ) { + if ( physics_will_collide(obj, rooms[i]->objects[j], dt) ) { + /* Stop the object in its tracks and return */ + obj->vx = 0.0; + obj->vy = 0.0; + obj->vz = 0.0; + obj->yawspeed = 0.0; + return; + } + } + } + #endif /* Air friction */ if ( obj->vx > 0.0 ) { @@ -115,7 +237,10 @@ void physics_step(Game *game, Uint32 t) { if ( game->turn_right ) { game->lander->yawspeed += YAWTHRUST *dt; /* +ve yaw is "right" */ } - physics_process(game->lander, dt); + + /* The number of rooms to consider for physics purposes can probably be further reduced */ + physics_process(game->lander, dt, game->rooms, game->num_rooms); + game_check_handoff(game); game->tlast = t; |