diff --git a/bin/back b/bin/back index 7189976..e5fc72f 100755 Binary files a/bin/back and b/bin/back differ diff --git a/obj/base.o b/obj/base.o index 1320741..f2f35f5 100644 Binary files a/obj/base.o and b/obj/base.o differ diff --git a/obj/display.o b/obj/display.o index 14caf49..398dae9 100644 Binary files a/obj/display.o and b/obj/display.o differ diff --git a/obj/entities.o b/obj/entities.o index c004833..5bcf62a 100644 Binary files a/obj/entities.o and b/obj/entities.o differ diff --git a/obj/generation.o b/obj/generation.o index 767b7e0..c6316ab 100644 Binary files a/obj/generation.o and b/obj/generation.o differ diff --git a/obj/hash.o b/obj/hash.o index 0808bd8..b637cfe 100644 Binary files a/obj/hash.o and b/obj/hash.o differ diff --git a/obj/main.o b/obj/main.o index 075c34f..2e3ab4c 100644 Binary files a/obj/main.o and b/obj/main.o differ diff --git a/obj/move.o b/obj/move.o index ce2a5fc..67c5be4 100644 Binary files a/obj/move.o and b/obj/move.o differ diff --git a/src/base.c b/src/base.c index 3877ed3..9913b24 100644 --- a/src/base.c +++ b/src/base.c @@ -342,16 +342,33 @@ bool intersects_seg_seg_2d( double x1, double y1, double x2, double y2, double x3, double y3, - double x4, double y4 + double x4, double y4, + double* rett, double* retu ) { + /*if(absf((x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4)) < 0.01) { + return false; + } 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))); + ((x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4)));*/ + if(absf((y2 - y1)*(x4 - x3) - (y4 - y3)*(x2 - x1)) < 0.01) { + return false; + } + double t = + ((y4 - y3)*(x1 - x3) - (y1 - y3)*(x4 - x3))/ + ((y2 - y1)*(x4 - x3) - (y4 - y3)*(x2 - x1)); + + double u = + ((y2 - y1)*(x3 - x1) - (x2 - x1)*(y3 - y1))/ + ((x2 - x1)*(y4 - y3) - (y2 - y1)*(x4 - x3)); + + if(rett != NULL) {*rett = t;} + if(retu != NULL) {*retu = u;} return ((0.0 <= t && t <= 1.0) && (0.0 <= u && u <= 1.0)); } @@ -385,21 +402,51 @@ 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) { +double sign_triangle(pt_2d p1, pt_2d p2, pt_2d p3) { + return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y); +} + +bool pointInTriangle (pt_2d pt, pt_2d v1, pt_2d v2, pt_2d v3) { + double d1, d2, d3; + bool has_neg, has_pos; + + d1 = sign_triangle(pt, v1, v2); + d2 = sign_triangle(pt, v2, v3); + d3 = sign_triangle(pt, v3, v1); + + has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0); + has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0); + + return !(has_neg && has_pos); +} + +int intersects_poly_poly_2d(pt_2d* t1, int len_1, pt_2d* t2, int len_2, int* retk1, int* retk2, double* rettheta1, double* rettheta2) { if(len_1 == 0 || len_2 == 0) { - return false ; // arbitrary + return 0 ; // 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 + t2[k2].x, t2[k2].y, t2[(k2+1)%len_2].x, t2[(k2+1)%len_2].y, + rettheta1, rettheta2 )) { - return true; + if(retk1 != NULL) {*retk1 = k1;} + if(retk2 != NULL) {*retk2 = k2;} + return 1; } } } - return false; + for(int k1 = 0; k1 < len_1; k1++) { + for(int k2 = 0; k2 < len_2/3; k2++) { + if(pointInTriangle(t1[k1], t2[k2], t2[k2+1], t2[k2+2])) { + if(retk1 != NULL) {*retk1 = k1;} + if(retk2 != NULL) {*retk2 = k2;} + return 2; + } + } + } + return 0; } // ------------------------------------------------------------------------------------------------ // diff --git a/src/base.h b/src/base.h index 5fd65f6..287aa6d 100644 --- a/src/base.h +++ b/src/base.h @@ -64,9 +64,10 @@ bool intersects_seg_seg_2d( double x1, double y1, double x2, double y2, double x3, double y3, - double x4, double y4 + double x4, double y4, + double* rett, double* retu ); -bool intersects_poly_poly_2d(pt_2d* t1, int len_1, pt_2d* t2, int len_2); +int intersects_poly_poly_2d(pt_2d* t1, int len_1, pt_2d* t2, int len_2, int* retk1, int* retk2, double* rettheta1, double* rettheta2); 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 803b11a..0c23502 100644 --- a/src/display.c +++ b/src/display.c @@ -23,6 +23,9 @@ int* drawOrder; int* drawOrder2; pt_2d* tri1 ; pt_2d* tri2 ; +cube_0* toDraw ; +int* toDrawVisited ; +int toDrawLen ; double draw_constant = 0.4 ; @@ -31,6 +34,12 @@ void init_draworder() { drawOrder2 = malloc(sizeof(int)*6) ; tri1 = malloc(sizeof(pt_2d)*6); tri2 = malloc(sizeof(pt_2d)*6); + toDraw = malloc(sizeof(cube_0)*2048); + toDrawVisited = malloc(sizeof(int)*2048); + for(int k = 0; k < 2048; k++) { + toDrawVisited[k] = 0; + } + toDrawLen = 0; } void updateRenderer(SDL_Renderer* renderer) { @@ -639,10 +648,11 @@ void renderTriangle( } } -pt_2d to_fpoint(double x0, double y0) { +pt_2d to_fpoint(double x0, double y0, double z0) { pt_2d res; res.x = x0; res.y = y0; + res.z = z0; return res; } @@ -656,9 +666,9 @@ int returnTriangle( project_to_camera(x1, y1, z1, &px1, &py1, &pz1); project_to_camera(x2, y2, z2, &px2, &py2, &pz2); if(pz0 >= draw_constant && pz1 >= draw_constant && pz2 >= draw_constant) { - retarr[0] = to_fpoint(1500.0 * (1.0 + (px0 / (1.5 * pz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py0 / (pz0 * tan_fov))) / 2.0); - retarr[1] = to_fpoint(1500.0 * (1.0 + (px1 / (1.5 * pz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py1 / (pz1 * tan_fov))) / 2.0); - retarr[2] = to_fpoint(1500.0 * (1.0 + (px2 / (1.5 * pz2 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py2 / (pz2 * tan_fov))) / 2.0); + retarr[0] = to_fpoint(1500.0 * (1.0 + (px0 / (1.5 * pz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py0 / (pz0 * tan_fov))) / 2.0, pz0); + retarr[1] = to_fpoint(1500.0 * (1.0 + (px1 / (1.5 * pz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py1 / (pz1 * tan_fov))) / 2.0, pz1); + retarr[2] = to_fpoint(1500.0 * (1.0 + (px2 / (1.5 * pz2 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py2 / (pz2 * tan_fov))) / 2.0, pz2); return 3; } else if((pz0 >= draw_constant) + (pz1 >= draw_constant) + (pz2 >= draw_constant) == 2) { if(pz0 < draw_constant) { @@ -714,12 +724,12 @@ int returnTriangle( &mpx1, &mpy1, &mpz1) ; } - retarr[0] = to_fpoint(1500.0 * (1.0 + (fpx0 / (1.5 * fpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy0 / (fpz0 * tan_fov))) / 2.0); - retarr[1] = to_fpoint(1500.0 * (1.0 + (mpx0 / (1.5 * mpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy0 / (mpz0 * tan_fov))) / 2.0); - retarr[2] = to_fpoint(1500.0 * (1.0 + (fpx1 / (1.5 * fpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy1 / (fpz1 * tan_fov))) / 2.0); - retarr[3] = to_fpoint(1500.0 * (1.0 + (mpx0 / (1.5 * mpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy0 / (mpz0 * tan_fov))) / 2.0); - retarr[4] = to_fpoint(1500.0 * (1.0 + (mpx1 / (1.5 * mpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy1 / (mpz1 * tan_fov))) / 2.0); - retarr[5] = to_fpoint(1500.0 * (1.0 + (fpx1 / (1.5 * fpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy1 / (fpz1 * tan_fov))) / 2.0); + retarr[0] = to_fpoint(1500.0 * (1.0 + (fpx0 / (1.5 * fpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy0 / (fpz0 * tan_fov))) / 2.0, fpz0); + retarr[1] = to_fpoint(1500.0 * (1.0 + (mpx0 / (1.5 * mpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy0 / (mpz0 * tan_fov))) / 2.0, mpz0); + retarr[2] = to_fpoint(1500.0 * (1.0 + (fpx1 / (1.5 * fpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy1 / (fpz1 * tan_fov))) / 2.0, fpz1); + retarr[3] = to_fpoint(1500.0 * (1.0 + (mpx0 / (1.5 * mpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy0 / (mpz0 * tan_fov))) / 2.0, mpz0); + retarr[4] = to_fpoint(1500.0 * (1.0 + (mpx1 / (1.5 * mpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy1 / (mpz1 * tan_fov))) / 2.0, mpz1); + retarr[5] = to_fpoint(1500.0 * (1.0 + (fpx1 / (1.5 * fpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy1 / (fpz1 * tan_fov))) / 2.0, fpz1); return 6; } else if((pz0 >= draw_constant) + (pz1 >= draw_constant) + (pz2 >= draw_constant) == 1) { if(pz0 >= draw_constant) { @@ -757,9 +767,9 @@ int returnTriangle( &px1, &py1, &pz1); } - retarr[0] = to_fpoint(1500.0 * (1.0 + (px0 / (1.5 * pz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py0 / (pz0 * tan_fov))) / 2.0); - retarr[1] = to_fpoint(1500.0 * (1.0 + (px1 / (1.5 * pz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py1 / (pz1 * tan_fov))) / 2.0); - retarr[2] = to_fpoint(1500.0 * (1.0 + (px2 / (1.5 * pz2 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py2 / (pz2 * tan_fov))) / 2.0); + retarr[0] = to_fpoint(1500.0 * (1.0 + (px0 / (1.5 * pz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py0 / (pz0 * tan_fov))) / 2.0, pz0); + retarr[1] = to_fpoint(1500.0 * (1.0 + (px1 / (1.5 * pz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py1 / (pz1 * tan_fov))) / 2.0, pz1); + retarr[2] = to_fpoint(1500.0 * (1.0 + (px2 / (1.5 * pz2 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py2 / (pz2 * tan_fov))) / 2.0, pz2); return 3; } else { return 0; @@ -772,15 +782,15 @@ int fillPolygon(int sf, cube_0 c, int trig, pt_2d* ret) { if(sf == 0 || sf == 1) { // x if(trig == 0) { return returnTriangle( - c.x + c.w*(sf==0), c.y, c.z, + c.x + c.w*(sf==0), c.y, c.z, c.x + c.w*(sf==0), c.y + c.h, c.z, c.x + c.w*(sf==0), c.y + c.h, c.z + c.d, ret ); } else { return returnTriangle( - c.x + c.w*(sf==0), c.y, c.z, - c.x + c.w*(sf==0), c.y, c.z + c.d, + c.x + c.w*(sf==0), c.y, c.z, + c.x + c.w*(sf==0), c.y, c.z + c.d, c.x + c.w*(sf==0), c.y + c.h, c.z + c.d, ret ); @@ -788,15 +798,15 @@ int fillPolygon(int sf, cube_0 c, int trig, pt_2d* ret) { } 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.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.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 ); @@ -804,15 +814,15 @@ int fillPolygon(int sf, cube_0 c, int trig, pt_2d* ret) { } else { // z 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.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.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 ); @@ -820,28 +830,67 @@ int fillPolygon(int sf, cube_0 c, int trig, pt_2d* ret) { } } -bool isCollidingSfOfCube(int sf1, cube_0 c1, int sf2, cube_0 c2) { +bool isCollidingSfOfCube(int sf1, cube_0 c1, int sf2, cube_0 c2, double* dz) { + int k1, k2; + double th1, th2; 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; + int itgt = intersects_poly_poly_2d(tri1, len1, tri2, len2, &k1, &k2, &th1, &th2); + if(itgt == 1) { + if(dz != NULL) { + double depth_1 = convex_pt(tri1[k1].z, tri1[(k1+1)%len1].z, th1); + double depth_2 = convex_pt(tri2[k2].z, tri2[(k2+1)%len2].z, th2); + if(absf(depth_2 - depth_1) >= 0.00001) { + *dz = depth_2 - depth_1; + return true; + } + } else { + return true; + } + } else if(itgt == 2) { + if(dz != NULL) { + *dz = tri2[0].z - tri1[0].z ; + return true; + } else { + return true; + } } } return false ; } +bool compat(int k1, int k2) { + return + (k1 == 0 && k2 == 1) || + (k1 == 1 && k2 == 0) || + (k1 == 2 && k2 == 3) || + (k1 == 3 && k2 == 2) || + (k1 == 4 && k2 == 5) || + (k1 == 5 && k2 == 4) ; +} + +double is_overlapping_all(cube_0 c1, cube_0 c2) { + // 0 if no overlap >0 if c1 is in front of c2, <0 if c2 is in front of c1 + double dz = 1.0 ; + for(int k1 = 0; k1 < 6; k1++) { + for(int k2 = k1+1; k2 < 6; k2++) { + if(compat(k1, k2) && isCollidingSfOfCube(k1, c1, k2, c2, &dz)) { + return dz; + } + } + } + return 0.0; +} + double is_overlapping(cube_0 c1, cube_0 c2) { // 0 if no overlap >0 if c1 is in front of c2, <0 if c2 is in front of c1 int sfToDraw1 = surfaceDrawOrder(camx, camy, camz, c1); int sfToDraw2 = surfaceDrawOrder2(camx, camy, camz, c2); for(int k1 = 0; k1 < sfToDraw1; k1 ++) { for(int k2 = 0; k2 < sfToDraw2; k2 ++) { - 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 + if(isCollidingSfOfCube(drawOrder[k1], c1, drawOrder2[k2], c2, NULL)) { + return 1.0 ; } } } @@ -1000,18 +1049,27 @@ void slide_cb(cube_0* arr, int left, int right) { } } -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; +void visit(int k, cube_0* arr, int len, int vflag, int* cur) { + if(toDrawVisited[k] != vflag) { + toDrawVisited[k] = vflag; + for(int k2 = 0; k2 < len; k2++) { + if(toDrawVisited[k2] != vflag) { + if(is_overlapping_all(arr[k], arr[k2]) >= 0.001) { + visit(k2, arr, len, vflag, cur); + } } - j -= 1; } + toDraw[*cur] = arr[k]; + *cur += 1; + } +} + +void insertionDepthSort_cb(cube_0* arr, int len) { + toDrawLen = 0; + int vflag = toDrawVisited[0]+1; + int current = 0; + for(int k = 0; k < len; k++) { + visit(k, arr, len, vflag, ¤t); } } @@ -1021,55 +1079,10 @@ void drawCurrentRoom(SDL_Renderer* renderer) { 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]); + //drawFullCube(renderer, current_room->map[k]); + drawFullCube(renderer, toDraw[k]); } for(int k = 0; k < current_room->ent_len; k++) { drawFullCube(renderer, *(current_room->ents[k].pos)); diff --git a/src/structure.h b/src/structure.h index 87dfb55..621dda5 100644 --- a/src/structure.h +++ b/src/structure.h @@ -9,6 +9,7 @@ typedef struct imgs { typedef struct pt_2d { double x; double y; + double z; } pt_2d ; struct cube_0 { diff --git a/templates/room_1 b/templates/room_1 index d7b0c93..cb52214 100644 --- a/templates/room_1 +++ b/templates/room_1 @@ -22,6 +22,6 @@ Entities : [0.0, 10.0, 0.0, 0.5, 0.5, 0.5, 0.0, 0.0, 193, 192, 0, 1, 0] Weight : -10 +15 $ \ No newline at end of file