diff --git a/bin/back b/bin/back index 0927327..7189976 100755 Binary files a/bin/back and b/bin/back differ diff --git a/obj/base.o b/obj/base.o index b7571fb..1320741 100644 Binary files a/obj/base.o and b/obj/base.o differ diff --git a/obj/display.o b/obj/display.o index 6be9d23..14caf49 100644 Binary files a/obj/display.o and b/obj/display.o differ diff --git a/src/base.c b/src/base.c index 8d7d303..3877ed3 100644 --- a/src/base.c +++ b/src/base.c @@ -299,6 +299,7 @@ double distance_pt_cube_3d(double x0, double y0, double z0, cube cb) { // ---------------- // +// intersects = !((a.max < b.min) || (b.max < a.min)) double distance_seg_seg_1d(double s0, double e0, double s1, double e1) { double theta_s0 = -(((e1 - s1) * (s1 - s0)) / ((e1 - s1) * (e1 - s1))); double theta_e0 = -(((e1 - s1) * (s1 - e0)) / ((e1 - s1) * (e1 - s1))); @@ -316,6 +317,14 @@ double distance_seg_seg_1d(double s0, double e0, double s1, double e1) { } } +bool intersects_seg_seg_1d(double s0, double e0, double s1, double e1) { + int amin = mind(s0, e0); + int amax = maxd(s0, e0); + int bmin = mind(s1, e1); + int bmax = maxd(s1, e1); + return !((amax < bmin) || (bmax < amin)); +} + double distance_seg_seg_2d( double s0x, double s0y, double e0x, double e0y, @@ -329,6 +338,23 @@ double distance_seg_seg_2d( ); } +bool intersects_seg_seg_2d( + double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4 +) { + double t = + ((x1 - x3)*(y3 - y4) - (y1 - y3)*(x3 - x4))/ + ((x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4)); + + double u = -( + ((x1 - x2)*(y1 - y3) - (y1 - y2)*(x1 - x3))/ + ((x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4))); + + return ((0.0 <= t && t <= 1.0) && (0.0 <= u && u <= 1.0)); +} + double distance_seg_seg_3d( double s0x, double s0y, double s0z, double e0x, double e0y, double e0z, @@ -345,8 +371,11 @@ double distance_seg_seg_3d( double distance_poly_poly_2d(pt_2d* t1, int len_1, pt_2d* t2, int len_2) { double res = 10000.0 ; + if(len_1 == 0 || len_2 == 0) { + return 727.27 ; // arbitrary + } for(int k1 = 0; k1 < len_1; k1++) { - for(int k2 = 0; k2 < len_1; k2++) { + for(int k2 = 0; k2 < len_2; k2++) { res = mind(res, distance_seg_seg_2d( t1[k1].x, t1[k1].y, t1[(k1+1)%len_1].x, t1[(k1+1)%len_1].y, t2[k2].x, t2[k2].y, t2[(k2+1)%len_2].x, t2[(k2+1)%len_2].y @@ -356,6 +385,23 @@ double distance_poly_poly_2d(pt_2d* t1, int len_1, pt_2d* t2, int len_2) { return res; } +bool intersects_poly_poly_2d(pt_2d* t1, int len_1, pt_2d* t2, int len_2) { + if(len_1 == 0 || len_2 == 0) { + return false ; // arbitrary + } + for(int k1 = 0; k1 < len_1; k1++) { + for(int k2 = 0; k2 < len_2; k2++) { + if(intersects_seg_seg_2d( + t1[k1].x, t1[k1].y, t1[(k1+1)%len_1].x, t1[(k1+1)%len_1].y, + t2[k2].x, t2[k2].y, t2[(k2+1)%len_2].x, t2[(k2+1)%len_2].y + )) { + return true; + } + } + } + return false; +} + // ------------------------------------------------------------------------------------------------ // void remove_entity(entity** arr, int* memlen, int* len, int index) { diff --git a/src/base.h b/src/base.h index 10a4703..5fd65f6 100644 --- a/src/base.h +++ b/src/base.h @@ -59,6 +59,15 @@ double distance_seg_seg_3d( ); double distance_poly_poly_2d(pt_2d* t1, int len_1, pt_2d* t2, int len_2); +bool intersects_seg_seg_1d(double s0, double e0, double s1, double e1); +bool intersects_seg_seg_2d( + double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4 +); +bool intersects_poly_poly_2d(pt_2d* t1, int len_1, pt_2d* t2, int len_2); + void remove_entity(entity** arr, int* memlen, int* len, int index); void add_entity(entity** arr, int* memlen, int* len, entity ent); diff --git a/src/display.c b/src/display.c index a7d6d99..803b11a 100644 --- a/src/display.c +++ b/src/display.c @@ -507,13 +507,14 @@ SDL_Vertex construct_vertex(double px, double py, int r, int g, int b) { return vtx ; } - double px0; double py0; double pz0; - double px1; double py1; double pz1; - double px2; double py2; double pz2; - double fpx0; double fpy0; double fpz0; - double fpx1; double fpy1; double fpz1; - double mpx0; double mpy0; double mpz0; - double mpx1; double mpy1; double mpz1; +double px0; double py0; double pz0; +double px1; double py1; double pz1; +double px2; double py2; double pz2; +double fpx0; double fpy0; double fpz0; +double fpx1; double fpy1; double fpz1; +double mpx0; double mpy0; double mpz0; +double mpx1; double mpy1; double mpz1; + void renderTriangle( SDL_Renderer* renderer, double x0, double y0, double z0, @@ -784,34 +785,50 @@ int fillPolygon(int sf, cube_0 c, int trig, pt_2d* ret) { ret ); } - }/* else if(sf == 2 || sf == 3) { // y - renderTriangleRotated(renderer, - c.x, c.y + c.h*(sf==2), c.z, - c.x + c.w, c.y + c.h*(sf==2), c.z, - c.x + c.w, c.y + c.h*(sf==2), c.z + c.d, - c.red, c.green, c.blue, c - ); - renderTriangleRotated(renderer, - c.x, c.y + c.h*(sf==2), c.z, - c.x, c.y + c.h*(sf==2), c.z + c.d, - c.x + c.w, c.y + c.h*(sf==2), c.z + c.d, - c.red, c.green, c.blue, c - ); + } else if(sf == 2 || sf == 3) { // y + if(trig == 0) { + return returnTriangle( + c.x, c.y + c.h*(sf==2), c.z, + c.x + c.w, c.y + c.h*(sf==2), c.z, + c.x + c.w, c.y + c.h*(sf==2), c.z + c.d, + ret + ); + } else { + return returnTriangle( + c.x, c.y + c.h*(sf==2), c.z, + c.x, c.y + c.h*(sf==2), c.z + c.d, + c.x + c.w, c.y + c.h*(sf==2), c.z + c.d, + ret + ); + } } else { // z - renderTriangleRotated(renderer, - c.x, c.y, c.z + c.d*(sf==4), - c.x + c.w, c.y, c.z + c.d*(sf==4), - c.x + c.w, c.y + c.h, c.z + c.d*(sf==4), - c.red, c.green, c.blue, c - ); - renderTriangleRotated(renderer, - c.x, c.y, c.z + c.d*(sf==4), - c.x, c.y + c.h, c.z + c.d*(sf==4), - c.x + c.w, c.y + c.h, c.z + c.d*(sf==4), - c.red, c.green, c.blue, c - ); - }*/ - return 0; + if(trig == 0) { + return returnTriangle( + c.x, c.y, c.z + c.d*(sf==4), + c.x + c.w, c.y, c.z + c.d*(sf==4), + c.x + c.w, c.y + c.h, c.z + c.d*(sf==4), + ret + ); + } else { + return returnTriangle( + c.x, c.y, c.z + c.d*(sf==4), + c.x, c.y + c.h, c.z + c.d*(sf==4), + c.x + c.w, c.y + c.h, c.z + c.d*(sf==4), + ret + ); + } + } +} + +bool isCollidingSfOfCube(int sf1, cube_0 c1, int sf2, cube_0 c2) { + for(int n = 0; n < 4; n++) { + int len1 = fillPolygon(sf1, c1, n%2, tri1); + int len2 = fillPolygon(sf2, c2, n/2, tri2); + if(intersects_poly_poly_2d(tri1, len1, tri2, len2)) { + return true; + } + } + return false ; } double is_overlapping(cube_0 c1, cube_0 c2) { @@ -820,8 +837,11 @@ double is_overlapping(cube_0 c1, cube_0 c2) { int sfToDraw2 = surfaceDrawOrder2(camx, camy, camz, c2); for(int k1 = 0; k1 < sfToDraw1; k1 ++) { for(int k2 = 0; k2 < sfToDraw2; k2 ++) { - if(false/*isCollidingSfOfCube(drawOrder[k1], c1, drawOrder2[k2], c2)*/) { - return 1.0; + if(isCollidingSfOfCube(drawOrder[k1], c1, drawOrder2[k2], c2)) { + return ( + distance_pt_cube_0_3d(camx, camy, camz, c2) - + distance_pt_cube_0_3d(camx, camy, camz, c1) + ); // cannot be 0 } } } @@ -974,11 +994,79 @@ void insertionSort_ent(entity* arr, int len) { } } +void slide_cb(cube_0* arr, int left, int right) { + for(int k = right-1; k >= left && k >= 0; k--) { + swap_cb(arr, k, k+1); + } +} + +void insertionDepthSort_cb(cube_0* arr, int len) { + // n³ // + for(int k0 = 0; k0 < len; k0++) { + int k = k0 ; + int j = k-1 ; + while(j >= 0) { + if(is_overlapping(arr[j], arr[k]) > 0.001) { + slide_cb(arr, j, k); + k = j; + } + j -= 1; + } + } +} + void drawCurrentRoom(SDL_Renderer* renderer) { - insertionSort_cb(current_room->map, current_room->map_size); + //insertionSort_cb(current_room->map, current_room->map_size); + insertionDepthSort_cb(current_room->map, current_room->map_size); insertionSort_tp(current_room->tps, current_room->tps_size); insertionSort_ent(current_room->ents, current_room->ent_len); + // debugPower + for(int k1 = 0; k1 < current_room->map_size; k1++) { + for(int k2 = k1+1; k2 < current_room->map_size; k2++) { + current_room->map[k1].blue = 0 ; + current_room->map[k1].green = 0 ; + current_room->map[k1].red = 182 ; + + current_room->map[k2].blue = 0 ; + current_room->map[k2].green = 0 ; + current_room->map[k2].red = 182 ; + } + } + + for(int k1 = 0; k1 < current_room->map_size; k1++) { + for(int k2 = k1+1; k2 < current_room->map_size; k2++) { + if(is_overlapping(current_room->map[k1], current_room->map[k2]) > 0.001) { + current_room->map[k1].blue = 0 ; + current_room->map[k1].green = 182 ; + current_room->map[k1].red = 0 ; + + current_room->map[k2].blue = 0 ; + current_room->map[k2].green = 182 ; + current_room->map[k2].red = 182 ; + } else if(is_overlapping(current_room->map[k1], current_room->map[k2]) < -0.001) { + current_room->map[k1].blue = 0 ; + current_room->map[k1].green = 182 ; + current_room->map[k1].red = 182 ; + + current_room->map[k2].blue = 0 ; + current_room->map[k2].green = 182 ; + current_room->map[k2].red = 0 ; + } else { + if(current_room->map[k1].green != 182) { + current_room->map[k1].blue = 0 ; + current_room->map[k1].green = 0 ; + current_room->map[k1].red = 182 ; + } + if(current_room->map[k2].green != 182) { + current_room->map[k2].blue = 0 ; + current_room->map[k2].green = 0 ; + current_room->map[k2].red = 182 ; + } + } + } + } + if(true || draw_type == 0) { for(int k = 0; k < current_room->map_size; k++) { drawFullCube(renderer, current_room->map[k]);