|
|
|
@ -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;*/ |
|
|
|
|