aboutsummaryrefslogtreecommitdiff
path: root/src/physics.c
diff options
context:
space:
mode:
authortaw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5>2008-05-22 12:43:23 +0000
committertaw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5>2008-05-22 12:43:23 +0000
commit5074aa838702ec42b89be0adc32098f9d14cc34d (patch)
treeeabb4823f06f7567aa3ac85a97885a77e0e56d56 /src/physics.c
parenta5f2f4662ae54c6e073934e64805e3f837cfc278 (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.c129
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;