aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortaw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5>2008-07-08 23:49:48 +0000
committertaw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5>2008-07-08 23:49:48 +0000
commit62838fb8a4d27654998b6b304d1c485e497bfa4c (patch)
tree9548bd28c8ade169087dfd08ab70fb4d127b465e
parentdaae10d9ac6ad4f768b52bc528f5fe366a86e572 (diff)
Restructuring of collision detection
git-svn-id: svn://cook.msm.cam.ac.uk:745/thrust3d/thrust3d@134 84d2e878-0bd5-11dd-ad15-13eda11d74c5
-rw-r--r--src/physics.c114
-rw-r--r--src/types.h14
2 files changed, 70 insertions, 58 deletions
diff --git a/src/physics.c b/src/physics.c
index 7677a02..34e07da 100644
--- a/src/physics.c
+++ b/src/physics.c
@@ -142,7 +142,7 @@ int physics_will_collide_face(double sx, double sy, double sz, double vx, double
/* Check for collision with all faces in a primitive */
static int physics_check_collide_all_faces(ModelInstance *obj, ModelInstance *other, Uint32 dt, int a,
double sx, double sy, double sz, double vx, double vy, double vz,
- double *ttc_lowest, double *nxc, double *nyc, double *nzc) {
+ CollisionSpec *coll) {
switch ( other->model->primitives[a]->type ) {
@@ -172,12 +172,12 @@ static int physics_check_collide_all_faces(ModelInstance *obj, ModelInstance *ot
if ( physics_will_collide_face(sx, sy, sz, vx, vy, vz, nx, ny, nz, face, 4, dt, other, &ttc) != 0 ) {
- if ( ttc < *ttc_lowest ) {
+ if ( ttc < coll->ttc ) {
printf("PH: collides with %s/%p in %5.2f ms\n", other->model->name, other, ttc);
- *ttc_lowest = ttc;
- *nxc = nx;
- *nyc = ny;
- *nzc = nz;
+ coll->ttc = ttc;
+ coll->nx = nx;
+ coll->ny = ny;
+ coll->nz = nz;
}
}
@@ -193,7 +193,7 @@ static int physics_check_collide_all_faces(ModelInstance *obj, ModelInstance *ot
}
/* Return non-zero if 'obj' will collide with 'other' with 'dt' milliseconds */
-static int physics_check_collide(ModelInstance *obj, ModelInstance *other, Uint32 dt) {
+static int physics_check_collide(ModelInstance *obj, ModelInstance *other, double dt, CollisionSpec *coll) {
int i;
@@ -202,13 +202,6 @@ static int physics_check_collide(ModelInstance *obj, ModelInstance *other, Uint3
const double vz = obj->vz;
double ttc_lowest = +INFINITY;
- double nxc = 0.0;
- double nyc = 0.0;
- double nzc = 0.0;
-
- if ( strcmp(other->model->name, "platform") ) {
-// printf("Checking against platform\n");
- }
/* Consider all the primitives in 'obj' */
for ( i=0; i<obj->model->num_primitives; i++ ) {
@@ -225,8 +218,7 @@ static int physics_check_collide(ModelInstance *obj, ModelInstance *other, Uint3
/* Consider all the primitives in 'other' */
for ( a=0; a<other->model->num_primitives; a++ ) {
- // printf("Primitive %i\n", a);
- physics_check_collide_all_faces(obj, other, dt, a, sx, sy, sz, vx, vy, vz, &ttc_lowest, &nxc, &nyc, &nzc);
+ physics_check_collide_all_faces(obj, other, dt, a, sx, sy, sz, vx, vy, vz, coll);
}
}
@@ -239,49 +231,37 @@ static int physics_check_collide(ModelInstance *obj, ModelInstance *other, Uint3
return 0;
}
- if ( (nxc == 0.0) && (nyc == 0.0) && (nzc == 1.0) ) {
- obj->x += obj->vx * ttc_lowest;
- obj->y += obj->vy * ttc_lowest;
- obj->z += obj->vz * ttc_lowest;
- obj->vz = 0.0;
- obj->landed = 1;
- printf("PH: Landed!\n");
- } else {
- obj->vx = -obj->vx;
- obj->vy = -obj->vy;
- obj->vz = -obj->vz;
- obj->yawspeed = 0.0;
- printf("PH: Bounce!\n");
- }
-
return 1;
}
-/* Called once for each object which isn't just "scenery" */
-static void physics_process(ModelInstance *obj, Uint32 dt, Game *game) {
-
- int collided = 0;
- do {
+static int physics_find_earliest_collision(ModelInstance *obj, Game *game, double dt, CollisionSpec *coll) {
+
+ Room *room;
- Room *room;
+ /* Consider only the current room, for now */
+ room = game_find_room(game, game->cur_room_x, game->cur_room_y, game->cur_room_z);
+ if ( room != NULL ) {
- collided = 0;
-
- /* Consider only the current room */
- room = game_find_room(game, game->cur_room_x, game->cur_room_y, game->cur_room_z);
- if ( room != NULL ) {
- /* Consider all the objects in this room */
- int j;
- for ( j=0; j<room->num_objects; j++ ) {
- if ( physics_check_collide(obj, room->objects[j], dt) ) { /* Should be dt - ttc */
- collided = 1;
- audio_play(game->audio, "clang", 0.7, 0);
- }
+ /* Consider all the objects in this room */
+ int j;
+
+ for ( j=0; j<room->num_objects; j++ ) {
+ if ( physics_check_collide(obj, room->objects[j], dt, coll) ) {
+ return 1;
}
}
+
+ }
+
+ return 0;
+
+}
+
+/* Called once for each object which isn't just "scenery" */
+static void physics_process(ModelInstance *obj, Uint32 dt, Game *game) {
- } while ( collided );
+ int collided = 0;
/* Air friction */
if ( obj->vx > 0.0 ) {
@@ -321,13 +301,32 @@ static void physics_process(ModelInstance *obj, Uint32 dt, Game *game) {
obj->vz -= GRAVITY * dt;
}
- /* Take a step */
- if ( !obj->landed ) {
- obj->x += obj->vx * dt;
- obj->y += obj->vy * dt;
- obj->z += obj->vz * dt;
- obj->yaw += obj->yawspeed * dt;
- }
+ /* Take a step, allowing for collisions and landing */
+ double sttc = 0.0;
+ do {
+
+ CollisionSpec coll;
+ collided = physics_find_earliest_collision(obj, game, dt, &coll);
+
+ if ( collided ) {
+
+ if ( (coll.nx==0) && (coll.ny==0) && (coll.nz==1.0) ) {
+ obj->landed = 1;
+ obj->vx = 0.0;
+ obj->vy = 0.0;
+ obj->vz = 0.0;
+ }
+
+ } else {
+
+ obj->x += obj->vx * (dt-sttc);
+ obj->y += obj->vy * (dt-sttc);
+ obj->z += obj->vz * (dt-sttc);
+ obj->yaw += obj->yawspeed * (dt-sttc);
+
+ }
+
+ } while ( collided && !obj->landed );
if ( obj->yaw < -M_PI ) obj->yaw += 2*M_PI;
if ( obj->yaw > M_PI ) obj->yaw -= 2*M_PI;
@@ -362,7 +361,6 @@ void physics_step(Game *game, Uint32 t) {
game->lander->yawspeed += YAWTHRUST *dt; /* +ve yaw is "right" */
}
- /* The number of rooms to consider for physics purposes can probably be further reduced */
physics_process(game->lander, dt, game);
game_check_handoff(game);
diff --git a/src/types.h b/src/types.h
index d489be7..dcbc097 100644
--- a/src/types.h
+++ b/src/types.h
@@ -255,5 +255,19 @@ typedef struct {
} Game;
+typedef struct {
+
+ double nx;
+ double ny;
+ double nz; /* Normal of face being collided with */
+
+ double cx;
+ double cy;
+ double cz; /* Coordinates of object at the moment when it collides */
+
+ double ttc;
+
+} CollisionSpec;
+
#endif /* TYPES_H */