diff --git a/.vscode/settings.json b/.vscode/settings.json index d909400..74f4b13 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,6 +8,9 @@ "generation.h": "c", "time.h": "c", "limits": "c", - "sdl.h": "c" + "sdl.h": "c", + "triangles.h": "c", + "base.h": "c", + "move.h": "c" } } \ No newline at end of file diff --git a/bin/back b/bin/back index b2da8bc..6f16127 100755 Binary files a/bin/back and b/bin/back differ diff --git a/obj/base.o b/obj/base.o index a955de7..3fef6e4 100644 Binary files a/obj/base.o and b/obj/base.o differ diff --git a/obj/display.o b/obj/display.o index 145d470..a1e0e96 100644 Binary files a/obj/display.o and b/obj/display.o differ diff --git a/obj/entities.o b/obj/entities.o index 63a0e5e..778c1d2 100644 Binary files a/obj/entities.o and b/obj/entities.o differ diff --git a/obj/generation.o b/obj/generation.o index 87bbab4..8c3c53d 100644 Binary files a/obj/generation.o and b/obj/generation.o differ diff --git a/obj/main.o b/obj/main.o index 88b382c..4267838 100644 Binary files a/obj/main.o and b/obj/main.o differ diff --git a/obj/move.o b/obj/move.o index 8f6b7c1..20a86aa 100644 Binary files a/obj/move.o and b/obj/move.o differ diff --git a/obj/triangles.o b/obj/triangles.o index e578db8..8507888 100644 Binary files a/obj/triangles.o and b/obj/triangles.o differ diff --git a/src/base.c b/src/base.c index 82d9ba9..9f7973a 100644 --- a/src/base.c +++ b/src/base.c @@ -95,6 +95,10 @@ int convex_seg(int x1, int x2, double theta) { return (int)(((1.0f - theta) * x1 + theta * x2)); } +double convex_tri(double a, double tha, double b, double thb, double c, double thc) { + return (a*tha + b*thb + c*thc); +} + bool is_an_integer(char c) { return ((int)c >= 48 && (int)c <= 57); } @@ -339,6 +343,29 @@ void project_to_cube(double x0, double y0, double z0, double* rx, double* ry, do if(rz != NULL) {*rz = zry*cos(c.vt_angle) + yry*sin(c.vt_angle);} } +double dist_to_cam_cube(double x0, double y0, double z0, cube_0 c) { + double px0, py0, pz0; + project_to_cube(x0, y0, z0, &px0, &py0, &pz0, c); + return distance_pt_pt_3d(px0 + c.x + c.w/2.0, py0 + c.y + c.h/2.0, pz0 + c.z + c.d/2.0, camx, camy, camz); +} + +bool pt_equal_3D(pt_2d p1, pt_2d p2) { + return (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z); +} + +bool pt_equal_2D(pt_2d p1, pt_2d p2) { + return (p1.x == p2.x && p1.y == p2.y); +} + +bool pt_equal_3D_eps(pt_2d p1, pt_2d p2, double epsilon) { + return (absf(p1.x - p2.x) <= epsilon && absf(p1.y - p2.y) <= epsilon && absf(p1.z - p2.z) <= epsilon); +} + +bool pt_equal_2D_eps(pt_2d p1, pt_2d p2, double epsilon, bool debug0) { + if(debug0) {printf("(%lf, %lf)\n", absf(p1.x - p2.x), absf(p1.y - p2.y));} + return (absf(p1.x - p2.x) <= epsilon && absf(p1.y - p2.y) <= epsilon); +} + // ------------------------------------------------------------------------------------------------ // void remove_entity(entity** arr, int* memlen, int* len, int index) { diff --git a/src/base.h b/src/base.h index a00fa31..87d09c0 100644 --- a/src/base.h +++ b/src/base.h @@ -11,12 +11,17 @@ 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 tha, double b, double thb, double c, double thc); bool is_an_integer(char c); double to_double(int n); int to_int(double n); int line_count(char* filename); int str_to_int(char* s); bool str_equal(char* s1, char* s2); +bool pt_equal_3D(pt_2d p1, pt_2d p2); +bool pt_equal_2D(pt_2d p1, pt_2d p2); +bool pt_equal_3D_eps(pt_2d p1, pt_2d p2, double epsilon); +bool pt_equal_2D_eps(pt_2d p1, pt_2d p2, double epsilon, bool debug0); cube_0 create_cube_0(double x, double y, double z, double w, double h, double d, double hz_a, double vt_a, int r, int g, int b); cube create_cube(double x, double y, double z, double w, double h, double d, double hz_a, double vt_a, int r, int g, int b); @@ -51,6 +56,7 @@ void add_entity(entity** arr, int* memlen, int* len, entity ent); double distance_pt_cube_3d(double x0, double y0, double z0, cube cb); void project_to_camera(double x0, double y0, double z0, double* rx, double* ry, double* rz); void project_to_cube(double x0, double y0, double z0, double* rx, double* ry, double* rz, cube_0 c); +double dist_to_cam_cube(double x0, double y0, double z0, cube_0 c); void import_digits(SDL_Renderer* renderer); void import_letters(SDL_Renderer* renderer); diff --git a/src/display.c b/src/display.c index 876d58a..aeb18d1 100644 --- a/src/display.c +++ b/src/display.c @@ -24,8 +24,17 @@ int* drawOrder; double draw_constant ; +int* cubeDrawOrder; +bool* seen ; + void init_draworder() { drawOrder = malloc(sizeof(int)*6) ; + cubeDrawOrder = malloc(sizeof(int)*2048); + seen = malloc(sizeof(bool)*2048); + for(int k = 0; k < 2048; k++) { + cubeDrawOrder[k] = 0; + seen[k] = false; + } draw_constant = 0.4 ; } @@ -420,12 +429,12 @@ int surfaceDrawOrder(double x0, double y0, double z0, cube_0 cb) { } } -SDL_Vertex construct_vertex(double px, double py, int r, int g, int b) { +SDL_Vertex construct_vertex(double px, double py, int r, int g, int b, int a) { SDL_Vertex vtx ; vtx.color.r = r ; vtx.color.g = g ; vtx.color.b = b ; - vtx.color.a = SDL_ALPHA_OPAQUE; + vtx.color.a = a ; vtx.position.x = (float)px ; vtx.position.y = (float)py ; vtx.tex_coord.x = 0.0f; @@ -433,22 +442,51 @@ SDL_Vertex construct_vertex(double px, double py, int r, int g, int b) { return vtx ; } +void renderTriangleNoProject( + SDL_Renderer* renderer, + double px0, double py0, double pz0, + double px1, double py1, double pz1, + double px2, double py2, double pz2, + int red, int green, int blue, bool debug +) { + + const SDL_Vertex vtxs[3] = { + construct_vertex(px0, py0, red, green, blue, 128), + construct_vertex(px1, py1, red, green, blue, 128), + construct_vertex(px2, py2, red, green, blue, 128), + }; + if(debug) { + printf("P[*] : (%f, %f), (%f, %f), (%f, %f)\n", vtxs[0].position.x, vtxs[0].position.y, vtxs[1].position.x, vtxs[1].position.y, vtxs[2].position.x, vtxs[2].position.y); + } + SDL_RenderGeometry(renderer, NULL, vtxs, 3, NULL, 0); +} + void renderTriangle( SDL_Renderer* renderer, double x0, double y0, double z0, double x1, double y1, double z1, double x2, double y2, double z2, - int red, int green, int blue + int red, int green, int blue, bool debug ) { + 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; project_to_camera(x0, y0, z0, &px0, &py0, &pz0); 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) { const SDL_Vertex vtxs[3] = { - construct_vertex(1500.0 * (1.0 + (px0 / (1.5 * pz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py0 / (pz0 * tan_fov))) / 2.0, red, green, blue), - construct_vertex(1500.0 * (1.0 + (px1 / (1.5 * pz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py1 / (pz1 * tan_fov))) / 2.0, red, green, blue), - construct_vertex(1500.0 * (1.0 + (px2 / (1.5 * pz2 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py2 / (pz2 * tan_fov))) / 2.0, red, green, blue), + construct_vertex(1500.0 * (1.0 + (px0 / (1.5 * pz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py0 / (pz0 * tan_fov))) / 2.0, red, green, blue, 255), + construct_vertex(1500.0 * (1.0 + (px1 / (1.5 * pz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py1 / (pz1 * tan_fov))) / 2.0, red, green, blue, 255), + construct_vertex(1500.0 * (1.0 + (px2 / (1.5 * pz2 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py2 / (pz2 * tan_fov))) / 2.0, red, green, blue, 255), }; + if(debug) { + printf("P[3] : (%f, %f), (%f, %f), (%f, %f)\n", vtxs[0].position.x, vtxs[0].position.y, vtxs[1].position.x, vtxs[1].position.y, vtxs[2].position.x, vtxs[2].position.y); + } SDL_RenderGeometry(renderer, NULL, vtxs, 3, NULL, 0); } else if((pz0 >= draw_constant) + (pz1 >= draw_constant) + (pz2 >= draw_constant) == 2) { if(pz0 < draw_constant) { @@ -505,13 +543,17 @@ void renderTriangle( } const SDL_Vertex vtxs[6] = { - construct_vertex(1500.0 * (1.0 + (fpx0 / (1.5 * fpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy0 / (fpz0 * tan_fov))) / 2.0, red, green, blue), - construct_vertex(1500.0 * (1.0 + (mpx0 / (1.5 * mpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy0 / (mpz0 * tan_fov))) / 2.0, red, green, blue), - construct_vertex(1500.0 * (1.0 + (fpx1 / (1.5 * fpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy1 / (fpz1 * tan_fov))) / 2.0, red, green, blue), - construct_vertex(1500.0 * (1.0 + (mpx0 / (1.5 * mpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy0 / (mpz0 * tan_fov))) / 2.0, red, green, blue), - construct_vertex(1500.0 * (1.0 + (mpx1 / (1.5 * mpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy1 / (mpz1 * tan_fov))) / 2.0, red, green, blue), - construct_vertex(1500.0 * (1.0 + (fpx1 / (1.5 * fpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy1 / (fpz1 * tan_fov))) / 2.0, red, green, blue), + construct_vertex(1500.0 * (1.0 + (fpx0 / (1.5 * fpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy0 / (fpz0 * tan_fov))) / 2.0, red, green, blue, 255), + construct_vertex(1500.0 * (1.0 + (mpx0 / (1.5 * mpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy0 / (mpz0 * tan_fov))) / 2.0, red, green, blue, 255), + construct_vertex(1500.0 * (1.0 + (fpx1 / (1.5 * fpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy1 / (fpz1 * tan_fov))) / 2.0, red, green, blue, 255), + construct_vertex(1500.0 * (1.0 + (mpx0 / (1.5 * mpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy0 / (mpz0 * tan_fov))) / 2.0, red, green, blue, 255), + construct_vertex(1500.0 * (1.0 + (mpx1 / (1.5 * mpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy1 / (mpz1 * tan_fov))) / 2.0, red, green, blue, 255), + construct_vertex(1500.0 * (1.0 + (fpx1 / (1.5 * fpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy1 / (fpz1 * tan_fov))) / 2.0, red, green, blue, 255), }; + if(debug) { + printf("P[2] : (%f, %f), (%f, %f), (%f, %f)\n", vtxs[0].position.x, vtxs[0].position.y, vtxs[1].position.x, vtxs[1].position.y, vtxs[2].position.x, vtxs[2].position.y); + printf(" (%f, %f), (%f, %f), (%f, %f)\n", vtxs[3].position.x, vtxs[3].position.y, vtxs[4].position.x, vtxs[4].position.y, vtxs[5].position.x, vtxs[5].position.y); + } SDL_RenderGeometry(renderer, NULL, vtxs, 6, NULL, 0); } else if((pz0 >= draw_constant) + (pz1 >= draw_constant) + (pz2 >= draw_constant) == 1) { if(pz0 >= draw_constant) { @@ -549,11 +591,18 @@ void renderTriangle( &px1, &py1, &pz1); } const SDL_Vertex vtxs[3] = { - construct_vertex(1500.0 * (1.0 + (px0 / (1.5 * pz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py0 / (pz0 * tan_fov))) / 2.0, red, green, blue), - construct_vertex(1500.0 * (1.0 + (px1 / (1.5 * pz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py1 / (pz1 * tan_fov))) / 2.0, red, green, blue), - construct_vertex(1500.0 * (1.0 + (px2 / (1.5 * pz2 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py2 / (pz2 * tan_fov))) / 2.0, red, green, blue), + construct_vertex(1500.0 * (1.0 + (px0 / (1.5 * pz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py0 / (pz0 * tan_fov))) / 2.0, red, green, blue, 255), + construct_vertex(1500.0 * (1.0 + (px1 / (1.5 * pz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py1 / (pz1 * tan_fov))) / 2.0, red, green, blue, 255), + construct_vertex(1500.0 * (1.0 + (px2 / (1.5 * pz2 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py2 / (pz2 * tan_fov))) / 2.0, red, green, blue, 255), }; + if(debug) { + printf("P[1] : (%f, %f), (%f, %f), (%f, %f)\n", vtxs[0].position.x, vtxs[0].position.y, vtxs[1].position.x, vtxs[1].position.y, vtxs[2].position.x, vtxs[2].position.y); + } SDL_RenderGeometry(renderer, NULL, vtxs, 3, NULL, 0); + } else { + if(debug) { + printf("P[0] : (-)\n"); + } } } @@ -565,13 +614,16 @@ void renderTriangleRotated( int red, int green, int blue, cube_0 cb ) { + double px0; double py0; double pz0; + double px1; double py1; double pz1; + double px2; double py2; double pz2; /*double px0; double py0; double pz0; double px1; double py1; double pz1; double px2; double py2; double pz2;*/ rotate_cube(x0, y0, z0, &px0, &py0, &pz0, cb); rotate_cube(x1, y1, z1, &px1, &py1, &pz1, cb); rotate_cube(x2, y2, z2, &px2, &py2, &pz2, cb); - renderTriangle(renderer, px0, py0, pz0, px1, py1, pz1, px2, py2, pz2, red, green, blue); + renderTriangle(renderer, px0, py0, pz0, px1, py1, pz1, px2, py2, pz2, red, green, blue, false); } void drawSfOfCube(SDL_Renderer* renderer, int sf, cube_0 c) { @@ -703,10 +755,35 @@ void insertionSort_ent(entity* arr, int len) { } } +void visit(SDL_Renderer* renderer, int k, cube_0* arr, int len, bool vflag, int* retptr) { + double overlap = 0.0; + if(seen[k] != vflag) { + seen[k] = vflag; + for(int k2 = 0; k2 < len; k2++) { + if(k != k2 && seen[k2] != vflag) { + if(cubeOverlap(renderer, arr[k], arr[k2], &overlap) && overlap > 0.0) { + visit(renderer, k2, arr, len, vflag, retptr); + } + } + } + cubeDrawOrder[*retptr] = k; + *retptr += 1; + } +} + +void insertionDepthSort(SDL_Renderer* renderer, cube_0* arr, int len) { + bool vflag = !seen[0]; + int rptr = 0; + for(int k = 0; k < len; k++) { + visit(renderer, k, arr, len, vflag, &rptr); + } +} + void drawCurrentRoom(SDL_Renderer* renderer) { insertionSort_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); + insertionDepthSort(NULL, current_room->map, current_room->map_size); /*for(int k1 = 0; k1 < current_room->map_size; k1++) { current_room->map[k1].red = 188 ; @@ -728,7 +805,8 @@ void drawCurrentRoom(SDL_Renderer* renderer) { 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, current_room->map[cubeDrawOrder[k]]); } for(int k = 0; k < current_room->ent_len; k++) { drawFullCube(renderer, *(current_room->ents[k].pos)); diff --git a/src/display.h b/src/display.h index cba0a79..e27a30e 100644 --- a/src/display.h +++ b/src/display.h @@ -49,7 +49,14 @@ void renderTriangle( double x0, double y0, double z0, double x1, double y1, double z1, double x2, double y2, double z2, - int red, int green, int blue + int red, int green, int blue, bool debug +); +void renderTriangleNoProject( + SDL_Renderer* renderer, + double x0, double y0, double z0, + double x1, double y1, double z1, + double x2, double y2, double z2, + int red, int green, int blue, bool debug ); void renderTriangleRotated( SDL_Renderer* renderer, diff --git a/src/main.c b/src/main.c index 41b4e26..3b53fae 100644 --- a/src/main.c +++ b/src/main.c @@ -15,6 +15,7 @@ #include "structure.h" #include "base.h" #include "move.h" +#include "triangles.h" #include "entities.h" #include "display.h" #include "generation.h" @@ -55,7 +56,7 @@ int main(int argc, char** argv) { init_hashtbl() ; init_draworder() ; trInit(); - parse_rooms(3); + parse_rooms(4); import_digits(rend) ; import_letters(rend) ; sim_time = 0.0 ; diff --git a/src/structure.h b/src/structure.h index 9a8bcb1..e533dad 100644 --- a/src/structure.h +++ b/src/structure.h @@ -115,12 +115,5 @@ extern int draw_type ; extern double draw_constant ; -extern double px0; extern double py0; extern double pz0; -extern double px1; extern double py1; extern double pz1; -extern double px2; extern double py2; extern double pz2; -extern double fpx0; extern double fpy0; extern double fpz0; -extern double fpx1; extern double fpy1; extern double fpz1; -extern double mpx0; extern double mpy0; extern double mpz0; -extern double mpx1; extern double mpy1; extern double mpz1; #endif \ No newline at end of file diff --git a/src/triangles.c b/src/triangles.c index 24e2a7f..38b4b0d 100644 --- a/src/triangles.c +++ b/src/triangles.c @@ -14,15 +14,10 @@ #include "hash.h" #include "structure.h" #include "base.h" +#include "display.h" #include "triangles.h" -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 draw_incr = 0.0 ; int errno = 0; pt_2d* triangle_1 ; @@ -132,7 +127,7 @@ bool triTri2D(pt_2d* t1, pt_2d* t2, double eps, bool allowReversed, bool onBound } bool triangleIntersection(pt_2d* tri1, pt_2d* tri2) { - return triTri2D(tri1, tri2, 0.0, false, true); + return triTri2D(tri1, tri2, 0.0, false, false); } bool triangleIntersectionDec(pt_2d t1_1, pt_2d t1_2, pt_2d t1_3, pt_2d t2_1, pt_2d t2_2, pt_2d t2_3) { @@ -145,10 +140,12 @@ bool triangleIntersectionDec(pt_2d t1_1, pt_2d t1_2, pt_2d t1_3, pt_2d t2_1, pt_ return triangleIntersection(triangle_1, triangle_2); } -bool multipleTrianglesIntersection(pt_2d* tri1, int len1, pt_2d* tri2, int len2) { +bool multipleTrianglesIntersection(pt_2d* tri1, int len1, pt_2d* tri2, int len2, int* ret1, int* ret2) { for(int k1 = 0; k1 < len1; k1+=3) { for(int k2 = 0; k2 < len2; k2+=3) { if(triangleIntersection(&tri1[k1], &tri2[k2])) { + if(ret1 != NULL) {*ret1 = k1;} + if(ret2 != NULL) {*ret2 = k2;} return true; } } @@ -170,17 +167,24 @@ int returnTriangle( double x2, double y2, double z2, pt_2d* retarr ) { + 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; project_to_camera(x0, y0, z0, &px0, &py0, &pz0); 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) { + if(pz0 >= (draw_constant + draw_incr) && pz1 >= (draw_constant + draw_incr) && pz2 >= (draw_constant + draw_incr)) { 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) { - // pz1 >= draw_constant and pz2 >+ draw_constant + } else if((pz0 >= (draw_constant + draw_incr)) + (pz1 >= (draw_constant + draw_incr)) + (pz2 >= (draw_constant + draw_incr)) == 2) { + if(pz0 < (draw_constant + draw_incr)) { + // pz1 >= (draw_constant + draw_incr) and pz2 >+ (draw_constant + draw_incr) fpx0 = px1 ; fpy0 = py1 ; fpz0 = pz1 ; fpx1 = px2 ; fpy1 = py2 ; fpz1 = pz2 ; // 1-0 segment @@ -196,8 +200,8 @@ int returnTriangle( convex_pt(y2, y0, (pz2 - draw_constant)/(pz2 - pz0)), convex_pt(z2, z0, (pz2 - draw_constant)/(pz2 - pz0)), &mpx1, &mpy1, &mpz1) ; - } else if(pz1 < draw_constant) { - // pz0 >= draw_constant and pz2 >+ draw_constant + } else if(pz1 < (draw_constant + draw_incr)) { + // pz0 >= (draw_constant + draw_incr) and pz2 >+ (draw_constant + draw_incr) fpx0 = px0 ; fpy0 = py0 ; fpz0 = pz0 ; fpx1 = px2 ; fpy1 = py2 ; fpz1 = pz2 ; // 0-1 segment @@ -213,8 +217,8 @@ int returnTriangle( convex_pt(y2, y1, (pz2 - draw_constant)/(pz2 - pz1)), convex_pt(z2, z1, (pz2 - draw_constant)/(pz2 - pz1)), &mpx1, &mpy1, &mpz1) ; - } else /*if(pz2 < draw_constant)*/ { - // pz1 >= draw_constant and pz0 >+ draw_constant + } else /*if(pz2 < (draw_constant + draw_incr))*/ { + // pz1 >= (draw_constant + draw_incr) and pz0 >+ (draw_constant + draw_incr) fpx0 = px0 ; fpy0 = py0 ; fpz0 = pz0 ; fpx1 = px1 ; fpy1 = py1 ; fpz1 = pz1 ; // 0-2 segment @@ -239,8 +243,8 @@ int returnTriangle( 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) { + } else if((pz0 >= (draw_constant + draw_incr)) + (pz1 >= (draw_constant + draw_incr)) + (pz2 >= (draw_constant + draw_incr)) == 1) { + if(pz0 >= (draw_constant + draw_incr)) { project_to_camera( convex_pt(x0, x1, (pz0 - draw_constant)/(pz0 - pz1)), convex_pt(y0, y1, (pz0 - draw_constant)/(pz0 - pz1)), @@ -251,7 +255,7 @@ int returnTriangle( convex_pt(y0, y2, (pz0 - draw_constant)/(pz0 - pz2)), convex_pt(z0, z2, (pz0 - draw_constant)/(pz0 - pz2)), &px2, &py2, &pz2); - } else if(pz1 >= draw_constant) { + } else if(pz1 >= (draw_constant + draw_incr)) { project_to_camera( convex_pt(x1, x0, (pz1 - draw_constant)/(pz1 - pz0)), convex_pt(y1, y0, (pz1 - draw_constant)/(pz1 - pz0)), @@ -262,7 +266,7 @@ int returnTriangle( convex_pt(y1, y2, (pz1 - draw_constant)/(pz1 - pz2)), convex_pt(z1, z2, (pz1 - draw_constant)/(pz1 - pz2)), &px2, &py2, &pz2); - } else if(pz2 >= draw_constant) { + } else if(pz2 >= (draw_constant + draw_incr)) { project_to_camera( convex_pt(x2, x0, (pz2 - draw_constant)/(pz2 - pz0)), convex_pt(y2, y0, (pz2 - draw_constant)/(pz2 - pz0)), @@ -389,63 +393,150 @@ int visibleSurfaces(double x0, double y0, double z0, cube_0 cb, int* dOrd) { } } -void get_zdepths(cube_0 c, int sf, double* ret) { - pt_2d campt = to_fpoint(camx, camy, camz); - if(sf == 0 || sf == 1) { // x - ret[0] = zdepth_of_pt(c.x + c.w*(sf==0), c.y, c.z ); - ret[1] = zdepth_of_pt(c.x + c.w*(sf==0), c.y + c.h, c.z ); - ret[2] = zdepth_of_pt(c.x + c.w*(sf==0), c.y , c.z + c.d); - ret[3] = zdepth_of_pt(c.x + c.w*(sf==0), c.y + c.h, c.z + c.d); - } else if(sf == 2 || sf == 3) { // y - ret[0] = zdepth_of_pt(c.x, c.y + c.h*(sf==2), c.z ); - ret[1] = zdepth_of_pt(c.x + c.w, c.y + c.h*(sf==2), c.z ); - ret[2] = zdepth_of_pt(c.x , c.y + c.h*(sf==2), c.z + c.d); - ret[3] = zdepth_of_pt(c.x + c.w, c.y + c.h*(sf==2), c.z + c.d); - } else { // z - ret[0] = zdepth_of_pt(c.x, c.y, c.z + c.d*(sf==4)); - ret[1] = zdepth_of_pt(c.x + c.w, c.y, c.z + c.d*(sf==4)); - ret[2] = zdepth_of_pt(c.x , c.y + c.h, c.z + c.d*(sf==4)); - ret[3] = zdepth_of_pt(c.x + c.w, c.y + c.h, c.z + c.d*(sf==4)); - } +bool noWT; +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 is_all_behind(double* back, double* front) { - for(int k = 0; k < 3; k++) { - if(back[k] > front[k]) { - return false; +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; + if(v != NULL) {*v = (d11 * d20 - d01 * d21) / denom;} + if(w != NULL) {*w = (d00 * d21 - d01 * d20) / denom;} + if(u != NULL && v != NULL && w != NULL) {*u = 1.0 - *v - *w;} +} + +bool point_in_triangle(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; + + 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); + + if(!(has_neg && has_pos)) { + return_barycentric(pt, v1, v2, v3, thetaA, thetaB, thetaC); + return true; + } + return false; +} + +bool seg_seg_inter(pt_2d p1, pt_2d p2, pt_2d p3, pt_2d p4, double* ret0, double* ret1) { + double deno = (p4.x - p3.x)*(p2.y - p1.y) - (p4.y - p3.y)*(p2.x - p1.x); + if(0.0 <= deno && deno <= 0.001) { + //printf("%lf -->", deno); + deno = 0.001 ; + } else if(-0.001 <= deno && deno <= 0.0) { + //printf("%lf -->", deno); + deno = -0.001 ; + } + //printf("%lf\n", deno); + double alpha = + ((p4.x - p3.x)*(p3.y - p1.y) - (p4.y - p3.y)*(p3.x - p1.x))/ + (deno) ; + + double beta = + ((p2.x - p1.x)*(p3.y - p1.y) - (p2.y - p1.y)*(p3.x - p1.x))/ + (deno) ; + + if(ret0 != NULL) {*ret0 = alpha;} + if(ret1 != NULL) {*ret1 = beta;} + return (alpha >= 0.0 && alpha <= 1.0 && beta >= 0.0 && beta <= 1.0); +} + +void print_tri(pt_2d* t) { + printf("T :\n (%lf, %lf, %lf)\n (%lf, %lf, %lf)\n (%lf, %lf, %lf)\n", t[0].x, t[0].y, t[0].z, t[1].x, t[1].y, t[1].z, t[2].x, t[2].y, t[2].z); +} + +bool delta_get(pt_2d* tri1, pt_2d* tri2, double* ret) { + double th1 = 0.0; + double th2 = 0.0; + double th3 = 0.0; + for(int k = 0; k < 3; k++) { // pt + if(point_in_triangle(tri1[k], tri2[0], tri2[1], tri2[2], &th1, &th2, &th3)) { + //printf("%lf, %lf, %lf\n", th1, th2, th3); + //if(ret != NULL) {*ret = convex_tri(tri2[0].z, th1, tri2[1].z, th2, tri2[2].z, th3) - tri1[k].z;} + return true; + } + if(point_in_triangle(tri2[k], tri1[0], tri1[1], tri1[2], &th1, &th2, &th3)) { + //printf("%lf, %lf, %lf\n", th1, th2, th3); + //if(ret != NULL) {*ret = tri2[k].z - convex_tri(tri1[0].z, th1, tri1[1].z, th2, tri1[2].z, th3);} + return true; } } - return true; -} - -int which_is_in_front(cube_0 c1, int sfc1, cube_0 c2, int sfc2) { - int nVis1 = visibleSurfaces(camx, camy, camz, c1, dOrder1); - int nVis2 = visibleSurfaces(camx, camy, camz, c2, dOrder2); - for(int k1 = 0; k1 < nVis1; k1++) { - for(int k2 = 0; k2 < nVis2; k2++) { - get_zdepths(c1, dOrder1[k1], zdepths1); - get_zdepths(c2, dOrder2[k2], zdepths2); - if(is_all_behind(zdepths1, zdepths2)) { - return 1; - } else if(is_all_behind(zdepths2, zdepths1)) { - return -1; + for(int k1 = 0; k1 < 3; k1++) { // seg + for(int k2 = 0; k2 < 3; k2++) { + if(seg_seg_inter(tri1[k1], tri1[(k1+1)%3], tri2[k2], tri2[(k2+1)%3], &th1, &th2)) { + print_tri(tri1); + print_tri(tri2); + printf("%lf, %lf\n\n", th1, th2); + if(ret != NULL) {*ret = convex_pt(tri2[k2].z, tri2[(k2+1)%3].z, th2) - convex_pt(tri1[k1].z, tri1[(k1+1)%3].z, th1);} //no + return true; } } } - return 0; + return false; } -bool cubeOverlap(cube_0 c1, cube_0 c2, int* retval) { +bool cubeOverlap(SDL_Renderer* renderer, cube_0 c1, cube_0 c2, double* retval) { int len1 = 0; int len2 = 0; + int id1, id2; + double dz = 0.0; for(int i1 = 0; i1 < 6; i1++) { - for(int i2 = i1+1; i2 < 6; i2++) { + for(int i2 = i1; i2 < 6; i2++) { for(int n = 0; n < 4; n++) { len1 = fillPolygon(i1, c1, n%2, cube_t1); len2 = fillPolygon(i2, c2, n/2, cube_t2); - if(multipleTrianglesIntersection(cube_t1, len1, cube_t2, len2)) { - if(retval != NULL) {*retval = which_is_in_front(c1, i1, c2, i2);} - return true; + if(multipleTrianglesIntersection(cube_t1, len1, cube_t2, len2, &id1, &id2)) { + if(delta_get(&(cube_t1[id1]), &(cube_t2[id2]), &dz) && absf(dz) >= 0.001) { + if(retval != NULL) {*retval = dz;; printf("%lf\n", dz);} + return true; + } else if(renderer != NULL) { + // debug things // + SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); + printf("ids : 1 = (%d / %d), 2 = (%d / %d)\n", id1, len1, id2, len2); + renderTriangleNoProject(renderer, + cube_t1[id1].x, cube_t1[id1].y, cube_t1[id1].z, + cube_t1[id1+1].x, cube_t1[id1+1].y, cube_t1[id1+1].z, + cube_t1[id1+2].x, cube_t1[id1+2].y, cube_t1[id1+2].z, + 255, 0, 0, true); + renderTriangleNoProject(renderer, + cube_t2[id2].x, cube_t2[id2].y, cube_t2[id2].z, + cube_t2[id2+1].x, cube_t2[id2+1].y, cube_t2[id2+1].z, + cube_t2[id2+2].x, cube_t2[id2+2].y, cube_t2[id2+2].z, + 0, 255, 0, true); + updateRenderer(renderer); + usleep(2000000); + exit(1); + } } } } diff --git a/src/triangles.h b/src/triangles.h index 631d81f..55c2348 100644 --- a/src/triangles.h +++ b/src/triangles.h @@ -11,10 +11,11 @@ bool boundaryDoesntCollideChk(pt_2d *p1, pt_2d *p2, pt_2d *p3, double eps) ; bool triTri2D(pt_2d* t1, pt_2d* t2, double eps, bool allowReversed, bool onBoundary) ; bool triangleIntersection(pt_2d* tri1, pt_2d* tri2); bool triangleIntersectionDec(pt_2d t1_1, pt_2d t1_2, pt_2d t1_3, pt_2d t2_1, pt_2d t2_2, pt_2d t2_3); +bool multipleTrianglesIntersection(pt_2d* tri1, int len1, pt_2d* tri2, int len2, int* ret1, int* ret2); int returnTriangle(double x0, double y0, double z0, double x1, double y1, double z1, double x2, double y2, double z2, pt_2d* retarr); int fillPolygon(int sf, cube_0 c, int trig, pt_2d* ret); -bool cubeOverlap(cube_0 c1, cube_0 c2, int* retval); +bool cubeOverlap(SDL_Renderer* renderer, cube_0 c1, cube_0 c2, double* retval); #endif \ No newline at end of file diff --git a/templates/room_3 b/templates/room_3 new file mode 100644 index 0000000..0248989 --- /dev/null +++ b/templates/room_3 @@ -0,0 +1,16 @@ +Blocks : +[-10.0, 0.0, -10.0, 20.0, 0.9, 20.0, 0.0, 0.0, 192, 192, 192] +[-10.0, 7.1, -10.0, 20.0, 0.9, 20.0, 0.0, 0.0, 192, 192, 192] +[-10.0, 1.0, -10.0, 5.0, 6.0, 5.0, 0.0, 0.0, 92, 92, 92] +[5.0, 1.0, 5.0, 5.0, 6.0, 5.0, 0.0, 0.0, 92, 92, 93] + +Teleporters : +[-10.0, 1.0, -5.0, 1.0, 2.0, 10.0, 0.0, 0.0, 255, 0, 0; 0, -1] +[-5.0, 1.0, -10.0, 10.0, 2.0, 1.0, 0.0, 0.0, 255, 255, 0; -1, 0] +[9.0, 1.0, -5.0, 1.0, 2.0, 10.0, 0.0, 0.0, 0, 255, 0; 0, 1] +[-5.0, 1.0, 9.0, 10.0, 2.0, 1.0, 0.0, 0.0, 0, 0, 255; 1, 0] + +Weight : +50 + +$ \ No newline at end of file