1
1
Fork 0
Browse Source

Handles collisions inside the physics engine

thread-physics
user 5 years ago
parent
commit
f4fb8919b9
  1. 55
      game.c

55
game.c

@ -183,7 +183,7 @@ Vect get_normal(SDL_Point start, SDL_Point end) { @@ -183,7 +183,7 @@ Vect get_normal(SDL_Point start, SDL_Point end) {
// reference:
// http://www.dyn4j.org/2010/01/sat/#sat-inter
bool sat_collision_check(Body *one, Body *two) {
bool sat_collision_check(Body *one, Body *two, Vect *translation) {
int num_axes = one->collision_poly_size + two->collision_poly_size;
Vect *axes = calloc(num_axes, sizeof(Vect));
@ -223,6 +223,9 @@ bool sat_collision_check(Body *one, Body *two) { @@ -223,6 +223,9 @@ bool sat_collision_check(Body *one, Body *two) {
double *proj_one, *proj_two;
proj_one = proj_two = 0;
Vect min_axis;
double min_overlap = 99999999;
for (int i = 0; i < num_axes; i++) {
// project
if (proj_one) {
@ -244,19 +247,30 @@ bool sat_collision_check(Body *one, Body *two) { @@ -244,19 +247,30 @@ bool sat_collision_check(Body *one, Body *two) {
return false;
} else {
double overlap;
double left = proj_one[0] < proj_two[0] ? proj_one[0] : proj_two[0];
double right = proj_one[1] > proj_two[1] ? proj_one[1] : proj_two[1];
double left = proj_one[1] < proj_two[1] ? proj_one[1] : proj_two[1];
double right = proj_one[0] > proj_two[0] ? proj_one[0] : proj_two[0];
overlap = left - right;
printf("OVERLAP : %f\n", overlap);
printf("OVERLAP : %e\n", overlap);
if (overlap < min_overlap) {
min_overlap = overlap;
min_axis = axes[i];
}
}
}
// return the MTV
Vect trans;
trans.x = min_overlap * min_axis.x;
trans.y = min_overlap * min_axis.y;
*translation = trans;
free(axes);
free(proj_one);
free(proj_two);
return true;
}
bool route_collision(Body *one, Body *two) {
bool check_collision(Body *one, Body *two, Vect *translation) {
int onesize = one->collision_poly_size;
int twosize = two->collision_poly_size;
@ -300,16 +314,11 @@ bool route_collision(Body *one, Body *two) { @@ -300,16 +314,11 @@ bool route_collision(Body *one, Body *two) {
// poly-poly
if ((onesize > 2 && twosize > 2)) {
return sat_collision_check(one, two);
return sat_collision_check(one, two, translation);
}
}
bool check_collision(Body *one, Body *two) {
return route_collision(one, two);
}
Wall *get_long_wall(int numNodes, int *nodes) {
Wall wall;
memset(&wall, 0, sizeof(wall));
@ -391,11 +400,11 @@ void add_motor(Body *thing, double x, double y) { @@ -391,11 +400,11 @@ void add_motor(Body *thing, double x, double y) {
}
// basic collision handler for testing
bool process_collisions(Body *thing) {
bool process_collisions(Body *thing, Vect *trans) {
for (int k = 0; k < things_in_world; k++) {
if (world[k].kind == STATIC_WALL_W
&& world[k].wall->physics->uid != thing->uid) {
if (check_collision(world[k].wall->physics, thing)) {
if (check_collision(world[k].wall->physics, thing, trans)) {
thing->colliding = true;
return true;
}
@ -416,8 +425,23 @@ void advance_thing(Body * thing) { @@ -416,8 +425,23 @@ void advance_thing(Body * thing) {
thing->updateCollisionPoly(thing);
if (process_collisions(thing)) {
return;
Vect translation;
if (process_collisions(thing, &translation)) {
thing->position.x += translation.x;
thing->position.y += translation.y;
double mag = vect_mag(translation);
translation.x = translation.x / mag;
translation.y = translation.y / mag;
mag = vect_scalar_projection(thing->vel, translation);
Vect revert_vel;
revert_vel.x = cos(vect_dir(translation)) * mag;
revert_vel.y = sin(vect_dir(translation)) * mag;
thing->vel.x -= revert_vel.x;
thing->vel.y -= revert_vel.y;
}
if (!thing->dynamics) {
@ -506,7 +530,6 @@ void advance_thing(Body * thing) { @@ -506,7 +530,6 @@ void advance_thing(Body * thing) {
/*return;*/
/*}*/
// wrap screen
/*if (thing->x_pos > width) {*/
/*thing->x_pos = 0;*/

Loading…
Cancel
Save