diff --git a/bin/back b/bin/back index e5fc72f..532c23d 100755 Binary files a/bin/back and b/bin/back differ diff --git a/obj/base.o b/obj/base.o index f2f35f5..753bd9d 100644 Binary files a/obj/base.o and b/obj/base.o differ diff --git a/obj/display.o b/obj/display.o index 398dae9..b471401 100644 Binary files a/obj/display.o and b/obj/display.o differ diff --git a/src/base.c b/src/base.c index 9913b24..e0f54c7 100644 --- a/src/base.c +++ b/src/base.c @@ -188,6 +188,10 @@ double convex_pt(double a, double b, double theta) { return (a+(b-a)*theta) ; } +double convex_tri(double a, double b, double c, double tha, double thb, double thc) { + return (a*tha + b*thb + c*thc) ; +} + double distance_pt_pt_3d(double x0, double y0, double z0, double x1, double y1, double z1) { return sqrt((x1 - x0)*(x1 - x0)+(y1 - y0)*(y1 - y0)+(z1 - z0)*(z1 - z0)) ; } @@ -345,7 +349,7 @@ bool intersects_seg_seg_2d( double x4, double y4, double* rett, double* retu ) { - /*if(absf((x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4)) < 0.01) { + if(absf((x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4)) < 0.01) { return false; } double t = @@ -354,8 +358,8 @@ bool intersects_seg_seg_2d( double u = -( ((x1 - x2)*(y1 - y3) - (y1 - y2)*(x1 - x3))/ - ((x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4)));*/ - if(absf((y2 - y1)*(x4 - x3) - (y4 - y3)*(x2 - x1)) < 0.01) { + ((x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4))); + /*if(absf((y2 - y1)*(x4 - x3) - (y4 - y3)*(x2 - x1)) < 0.01) { return false; } @@ -365,7 +369,7 @@ bool intersects_seg_seg_2d( double u = ((y2 - y1)*(x3 - x1) - (x2 - x1)*(y3 - y1))/ - ((x2 - x1)*(y4 - y3) - (y2 - y1)*(x4 - x3)); + ((x2 - x1)*(y4 - y3) - (y2 - y1)*(x4 - x3));*/ if(rett != NULL) {*rett = t;} if(retu != NULL) {*retu = u;} @@ -406,7 +410,39 @@ 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) { +pt_2d to_pt2d(double x0, double y0, double z0) { + pt_2d res; + res.x = x0; + res.y = y0; + res.z = z0; + return res; +} + +double dot_product_3D(pt_2d p1, pt_2d p2) { + return p1.x*p2.x + p1.y*p2.y + p1.z*p2.z ; +} + +double dot_product_2D(pt_2d p1, pt_2d p2) { + return p1.x*p2.x + p1.y*p2.y ; +} + +void return_barycentric(pt_2d p, pt_2d a, pt_2d b, pt_2d c, double* u, double* v, double* w) { + // get barycentric coords of p inside ABC triangle + pt_2d v0 = to_pt2d(b.x - a.x, b.y - a.y, b.z - a.z); + pt_2d v1 = to_pt2d(c.x - a.x, c.y - a.y, c.z - a.z); + pt_2d v2 = to_pt2d(p.x - a.x, p.y - a.y, p.z - a.z); + double d00 = dot_product_2D(v0, v0); + double d01 = dot_product_2D(v0, v1); + double d11 = dot_product_2D(v1, v1); + double d20 = dot_product_2D(v2, v0); + double d21 = dot_product_2D(v2, v1); + double denom = d00 * d11 - d01 * d01; + *v = (d11 * d20 - d01 * d21) / denom; + *w = (d00 * d21 - d01 * d20) / denom; + *u = 1.0 - *v - *w; +} + +bool pointInTriangle (pt_2d pt, pt_2d v1, pt_2d v2, pt_2d v3, double* thetaA, double* thetaB, double* thetaC) { double d1, d2, d3; bool has_neg, has_pos; @@ -417,14 +453,19 @@ bool pointInTriangle (pt_2d pt, pt_2d v1, pt_2d v2, pt_2d v3) { has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0); has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0); - return !(has_neg && has_pos); + if(!(has_neg && has_pos)) { + return_barycentric(pt, v1, v2, v3, thetaA, thetaB, thetaC); + return true; + } + return false; } +double thA, thB, thC; 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 0 ; // arbitrary } - for(int k1 = 0; k1 < len_1; k1++) { + for(int k1 = 0; k1 < len_1; k1++) { // Segment intersection [FAULTY] 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, @@ -437,11 +478,20 @@ int intersects_poly_poly_2d(pt_2d* t1, int len_1, pt_2d* t2, int len_2, int* ret } } } - for(int k1 = 0; k1 < len_1; k1++) { + for(int k1 = 0; k1 < len_1; k1++) { // T1 is inside T2 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;} + if(pointInTriangle(t1[k1], t2[3*k2], t2[3*k2+1], t2[3*k2+2], &thA, &thB, &thC)) { + if(rettheta1 != NULL) {*rettheta1 = t1[k1].z;} + if(rettheta2 != NULL) {*rettheta2 = convex_tri(t2[3*k2].z, t2[3*k2+1].z, t2[3*k2+2].z, thA, thB, thC);} + return 2; + } + } + } + for(int k2 = 0; k2 < len_2; k2++) { // T2 is inside T1 + for(int k1 = 0; k1 < len_1/3; k1++) { + if(pointInTriangle(t2[k2], t1[3*k1], t1[3*k1+1], t1[3*k1+2], &thA, &thB, &thC)) { + if(rettheta1 != NULL) {*rettheta1 = convex_tri(t1[3*k1].z, t1[3*k1+1].z, t1[3*3*k1+2].z, thA, thB, thC);} + if(rettheta2 != NULL) {*rettheta2 = t2[k2].z;} return 2; } } diff --git a/src/base.h b/src/base.h index 287aa6d..b06eada 100644 --- a/src/base.h +++ b/src/base.h @@ -11,6 +11,7 @@ double mind(double a, double b); double maxd(double a, double b); double absf(double n); int convex_seg(int x1, int x2, double theta); +double convex_tri(double a, double b, double c, double tha, double thb, double thc); bool is_an_integer(char c); double to_double(int n); int to_int(double n); @@ -29,6 +30,7 @@ teleporter create_teleporter( double convex_pt(double a, double b, double theta); double distance_pt_pt_3d(double x0, double y0, double z0, double x1, double y1, double z1); double distance_pt_seg_3d(double x, double y, double z, double sx, double sy, double sz, double ex, double ey, double ez); +pt_2d to_pt2d(double x0, double y0, double z0); double convex_pt(double a, double b, double theta); double distance_pt_pt_3d(double x0, double y0, double z0, double x1, double y1, double z1) ; @@ -67,6 +69,7 @@ bool intersects_seg_seg_2d( double x4, double y4, double* rett, double* retu ); +bool pointInTriangle (pt_2d pt, pt_2d v1, pt_2d v2, pt_2d v3, double* thetaA, double* thetaB, double* thetaC); 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); diff --git a/src/display.c b/src/display.c index 0c23502..0a90579 100644 --- a/src/display.c +++ b/src/display.c @@ -841,8 +841,11 @@ bool isCollidingSfOfCube(int sf1, cube_0 c1, int sf2, cube_0 c2, double* dz) { 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) { + if(absf(depth_2 - depth_1) > 0.01 && depth_1 > 0.01 && depth_2 > 0.01) { *dz = depth_2 - depth_1; + if(*dz > 0.0001) { + printf("-1-%lf-\n", *dz); + } return true; } } else { @@ -850,8 +853,13 @@ bool isCollidingSfOfCube(int sf1, cube_0 c1, int sf2, cube_0 c2, double* dz) { } } else if(itgt == 2) { if(dz != NULL) { - *dz = tri2[0].z - tri1[0].z ; - return true; + if(absf(th2 - th1) >= 0.01 && th2 > 0.01 && th1 > 0.01) { + *dz = th2 - th1 ; + if(*dz > 0.0001) { + printf("-2-%lf-\n", *dz); + } + return true; + } } else { return true; } @@ -874,7 +882,7 @@ 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++) { + for(int k2 = 0; k2 < 6; k2++) { if(compat(k1, k2) && isCollidingSfOfCube(k1, c1, k2, c2, &dz)) { return dz; } @@ -1051,14 +1059,16 @@ void slide_cb(cube_0* arr, int left, int right) { void visit(int k, cube_0* arr, int len, int vflag, int* cur) { if(toDrawVisited[k] != vflag) { + printf("--> %d\n", k); toDrawVisited[k] = vflag; for(int k2 = 0; k2 < len; k2++) { if(toDrawVisited[k2] != vflag) { - if(is_overlapping_all(arr[k], arr[k2]) >= 0.001) { + if(is_overlapping_all(arr[k], arr[k2]) >= 0.00001) { visit(k2, arr, len, vflag, cur); } } } + printf("[%d]\n", k); toDraw[*cur] = arr[k]; *cur += 1; } @@ -1066,11 +1076,12 @@ void visit(int k, cube_0* arr, int len, int vflag, int* cur) { void insertionDepthSort_cb(cube_0* arr, int len) { toDrawLen = 0; - int vflag = toDrawVisited[0]+1; + int vflag = (toDrawVisited[0]+1)%4096; int current = 0; for(int k = 0; k < len; k++) { visit(k, arr, len, vflag, ¤t); } + printf("\n"); } void drawCurrentRoom(SDL_Renderer* renderer) { @@ -1078,6 +1089,7 @@ void drawCurrentRoom(SDL_Renderer* renderer) { 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); + printf("\n\n\n"); if(true || draw_type == 0) { for(int k = 0; k < current_room->map_size; k++) {