diff --git a/include/components/map_managment.h b/include/components/map_managment.h index 3e38a3d..4edf115 100644 --- a/include/components/map_managment.h +++ b/include/components/map_managment.h @@ -7,17 +7,28 @@ #include "engine.h" #include +#include "vertex_component.h" -static inline bool gc_vector2_is_ccw(gc_vector2 a, gc_vector2 b,gc_vector2 c) -{ - return ((c.y - a.y) * (b.x - a.x) > (b.y - a.x) * (c.x - a.x)); -} +//! @brief Checks if a point q is on the segment pr +bool is_on_segment(gc_vector2 p, gc_vector2 q, gc_vector2 r); -static inline bool gc_vector2_is_intersect(gc_vector2 a, gc_vector2 b, \ -gc_vector2 c, gc_vector2 d) -{ - return (gc_vector2_is_ccw(a, c, d) != gc_vector2_is_ccw(b, c, d) &&\ -gc_vector2_is_ccw(a, b, c) != gc_vector2_is_ccw(a, b, d)); -} +//! @brief Checks how the points are beetween each others +//! @return 0 if points are colinear +//! @return 1 if points are clockwise +//! @return 2 if points are counterclockwise +int orientation(gc_vector2 p, gc_vector2 q, gc_vector2 r); -bool map_manage_click(gc_engine *engine, int id, gc_vector2 pos); \ No newline at end of file +//! @brief Checks if segments p1q1 and p2q2 intersects +bool gc_vector2_do_intersect(gc_vector2 p1, gc_vector2 q1, gc_vector2 p2, gc_vector2 q2); + +//! @brief Checks if a point is in a polygon +//! @note The segment created to check is [10000, p.x] so beware when checking with large coordinates +//! @param polygon An array of points creating the polygon +//! @note Beware of the order of the points the polygon ABCD is different from ABDC +//! @param n The number of points of the polygon +//! @note you can't set n less than 3 +//! @param p Position of the point to check +bool is_point_in_polygon(gc_vector2 *polygon, int n, gc_vector2 p); + +bool map_manage_click(gc_engine *engine, int id, gc_vector2 pos); +bool is_pos_in_tile(gc_vector2 pos, struct tile *tile); \ No newline at end of file diff --git a/include/sfml_renderer.h b/include/sfml_renderer.h index f1edf3d..8576974 100644 --- a/include/sfml_renderer.h +++ b/include/sfml_renderer.h @@ -46,7 +46,7 @@ void sfml_play_music(void *music); void sfml_stop_music(gc_engine *engine); void sfml_resize(gc_engine *engine, gc_vector2 size); gc_vector2 sfml_get_screen_size(gc_engine *engine); -gc_vector2 sfml_engine_get_cursor_pos(gc_engine *engine); +gc_vector2i sfml_engine_get_cursor_pos(gc_engine *engine); void entities_update_to_cam(gc_scene *scene, \ struct sfml_renderer_system *renderer, struct camerafollow_system *cam); diff --git a/src/components/map_managment.c b/src/components/map_managment.c index 59f0de7..a56b224 100644 --- a/src/components/map_managment.c +++ b/src/components/map_managment.c @@ -15,6 +15,7 @@ #define ANGLE_X 45 #define ANGLE_Y 35 +#define INF 10000 gc_vector2 get_tile_coords_to_pixels(float x, float y, float z) { @@ -24,55 +25,78 @@ gc_vector2 get_tile_coords_to_pixels(float x, float y, float z) }; } -int nb_intersection_between_vectors(gc_vector2 x1, gc_vector2 x2, gc_vector2 polygon[4]) +bool is_on_segment(gc_vector2 p, gc_vector2 q, gc_vector2 r) { - int nb_intersects = 0; + if (q.x <= fmaxf(p.x, r.x) && q.x >= fminf(p.x, r.x) && \ +q.y <= fmaxf(p.y, r.y) && q.y >= fminf(p.y, r.y)) + return (true); + return (false); +} - //printf("pos x : %f y : %f\n", x1.x, x1.y); - //printf("x2 x : %f y : %f\n", x2.x, x2.y); - //printf("c1 x : %f y : %f\n", polygon[0].x, polygon[0].y); - if (gc_vector2_is_intersect(x1, x2, polygon[0], polygon[1])) { - nb_intersects++; - printf("1 p0 : x:%f f:%f\n", polygon[0].x, polygon[0].y); - printf("1 p1 : x:%f f:%f\n", polygon[1].x, polygon[1].y); - } - if (gc_vector2_is_intersect(x1, x2, polygon[1], polygon[3])) { - nb_intersects++; - printf("2 p1 : x:%f f:%f\n", polygon[1].x, polygon[1].y); - printf("2 p2 : x:%f f:%f\n", polygon[3].x, polygon[3].y); - } - if (gc_vector2_is_intersect(x1, x2, polygon[3], polygon[2])) { - nb_intersects++; - printf("3 p2 : x:%f f:%f\n", polygon[2].x, polygon[2].y); - printf("3 p3 : x:%f f:%f\n", polygon[3].x, polygon[3].y); - } - if (gc_vector2_is_intersect(x1, x2, polygon[2], polygon[0])) { - nb_intersects++; - printf("4 p2 : x:%f f:%f\n", polygon[2].x, polygon[2].y); - printf("4 p0 : x:%f f:%f\n", polygon[0].x, polygon[0].y); - } - return (nb_intersects); +int orientation(gc_vector2 p, gc_vector2 q, gc_vector2 r) +{ + int tmp = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); + + if (tmp == 0) + return (0); + return ((tmp > 0) ? 1 : 2); +} + +bool gc_vector2_do_intersect(gc_vector2 p1, gc_vector2 q1, gc_vector2 p2, gc_vector2 q2) +{ + int o1 = orientation(p1, q1, p2); + int o2 = orientation(p1, q1, q2); + int o3 = orientation(p2, q2, p1); + int o4 = orientation(p2, q2, q1); + + if (o1 != o2 && o3 != o4) + return (true); + if (o1 == 0 && is_on_segment(p1, p2, q1)) + return (true); + if (o2 == 0 && is_on_segment(p1, q2, q1)) + return (true); + if (o3 == 0 && is_on_segment(p2, p1, q2)) + return (true); + if (o4 == 0 && is_on_segment(p2, q1, q2)) + return (true); + return (false); +} + +bool is_point_in_polygon(gc_vector2 *polygon, int n, gc_vector2 p) +{ + gc_vector2 segment = {-INF, p.y}; + int count = 0; + int next = 0; + int i = 0; + + if (n < 3) + return (false); + do { + next = (i + 1) % n; + if (gc_vector2_do_intersect(polygon[i], polygon[next], p, segment)) { + if (orientation(polygon[i], p, polygon[next]) == 0) + return (is_on_segment(polygon[i], p, polygon[next])); + count++; + } + i = next; + } while (i != 0); + return (count & 1); } bool is_pos_in_tile(gc_vector2 pos, struct tile *tile) { struct vertex **c = tile->corners; - gc_vector2 inf = {INFINITY, INFINITY}; gc_vector2 corners[4]; - int ret; - for (int i = 0; i < 4; i++) { - corners[i] = get_tile_coords_to_pixels(c[i]->x, c[i]->y, c[i]->z); - } - - ret = nb_intersection_between_vectors(pos, inf, corners); - //my_printf("nb int : %i\n", ret); - if (!ret || ret % 2 != 0) - return (false); - printf("The polygon true\n"); for (int i = 0; i < 4; i++) - printf("%i :(x:%f, y:%f)\n", i + 1, corners[i].x, corners[i].y); - return (true); + corners[i] = get_tile_coords_to_pixels(c[i]->x, c[i]->y, c[i]->z); + if (is_point_in_polygon(corners, 4, pos)) { + //for (int i = 0; i < 4; i ++) + // printf("%i :(x:%f, y:%f)\n", i + 1, corners[i].x, corners[i].y); + // printf("\n"); + return (true); + } + return (false); } struct tile *get_tile_from_pos(gc_engine *engine, struct vertex_component *map, gc_vector2 pos) @@ -92,7 +116,7 @@ bool map_manage_click(gc_engine *engine, int id, gc_vector2 pos) gc_scene *scene = engine->scene; gc_entity *entity = scene->get_entity(scene, id); struct vertex_component *map = entity->get_component(entity, "vertex_component"); - struct tile *ret; + struct tile *ret = NULL; printf("map_manage_click called id: %i coords x: %f y:%f\n", id, pos.x, pos.y); if (!map) { diff --git a/src/components/vertex_component.c b/src/components/vertex_component.c index d8a7bec..54fe24e 100644 --- a/src/components/vertex_component.c +++ b/src/components/vertex_component.c @@ -51,8 +51,8 @@ static bool get_tiles(struct vertex_component *this, gc_scene *scene, node *n) for (vy = 0; this->vertices[v_x][vy].z != INT32_MIN; vy++) { this->map[inc].corners[0] = &this->vertices[v_x][vy]; this->map[inc].corners[1] = &this->vertices[v_x][vy + 1]; - this->map[inc].corners[2] = &this->vertices[v_x + 1][vy]; - this->map[inc].corners[3] = &this->vertices[v_x + 1][vy + 1]; + this->map[inc].corners[3] = &this->vertices[v_x + 1][vy]; + this->map[inc].corners[2] = &this->vertices[v_x + 1][vy + 1]; this->map[inc++].texture = scene->get_data(scene, "sprite", (inc % 2) ? "cobblestone" : "mossy_cobblestone"); if (inc > 31 && inc < 56) this->map[inc - 1].texture = scene->get_data(scene, "sprite", "crafting_table"); diff --git a/src/sfml_renderer/sfml_events.c b/src/sfml_renderer/sfml_events.c index c57c529..da797dc 100644 --- a/src/sfml_renderer/sfml_events.c +++ b/src/sfml_renderer/sfml_events.c @@ -36,10 +36,15 @@ void sfml_handle_events(gc_engine *engine) } } -gc_vector2 sfml_engine_get_cursor_pos(gc_engine *engine) +gc_vector2i sfml_engine_get_cursor_pos(gc_engine *engine) { - sfMouseMoveEvent mouse; - sfMouse_getPositionRenderWindow(GETSYS(engine, sfml_renderer_system)); + sfVector2i pos; + gc_vector2i ret; + + pos = sfMouse_getPositionRenderWindow(GETSYS(engine, sfml_renderer_system)); + ret.x = pos.x; + ret.y = pos.y; + return (ret); } void sfml_resize(gc_engine *engine, gc_vector2 size) diff --git a/src/sfml_renderer/sfml_init.c b/src/sfml_renderer/sfml_init.c index 8eecd85..bf9a715 100644 --- a/src/sfml_renderer/sfml_init.c +++ b/src/sfml_renderer/sfml_init.c @@ -34,6 +34,6 @@ sfVertexArray *sfml_init_verticies(void) for (int i = 0; i < 4; i++) sfVertexArray_append(arr, v[i]); - sfVertexArray_setPrimitiveType(arr, sfTriangleStrip); + sfVertexArray_setPrimitiveType(arr, sfTrianglesStrip); return (arr); } \ No newline at end of file diff --git a/src/sfml_renderer/sfml_vertex.c b/src/sfml_renderer/sfml_vertex.c index 7552d35..6964208 100644 --- a/src/sfml_renderer/sfml_vertex.c +++ b/src/sfml_renderer/sfml_vertex.c @@ -12,6 +12,7 @@ #include "components/transform_component.h" #include "systems/sfml_renderer_system.h" #include "components/vertex_component.h" +#include "map_managment.h" #include #include #include @@ -28,24 +29,51 @@ sfVector2f get_tile_coords(int x, int y, int z) } void draw_tile(struct sfml_renderer_system *this, struct vertex_component \ -*info, struct tile tile) +*info, struct tile *tile) { sfVertex *vert1 = sfVertexArray_getVertex(this->vertices, 1); - sfVertex *vert2 = sfVertexArray_getVertex(this->vertices, 2); - sfVertex *vert3 = sfVertexArray_getVertex(this->vertices, 3); + sfVertex *vert2 = sfVertexArray_getVertex(this->vertices, 3); + sfVertex *vert3 = sfVertexArray_getVertex(this->vertices, 2); int corners[9]; - if (tile.corners[0]->z == INT32_MAX || !tile.corners[3]->y) + + if (tile->corners[0]->z == INT32_MAX || !tile->corners[2]->y) return; for (int i = 0; i < 3; i++) { - corners[i * 3] = tile.corners[i + 1]->x; - corners[i * 3 + 1] = tile.corners[i + 1]->y; - corners[i * 3 + 2] = tile.corners[i + 1]->z; + corners[i * 3] = tile->corners[i + 1]->x; + corners[i * 3 + 1] = tile->corners[i + 1]->y; + corners[i * 3 + 2] = tile->corners[i + 1]->z; } vert1->position = get_tile_coords(corners[0], corners[1], corners[2]); vert2->position = get_tile_coords(corners[3], corners[4], corners[5]); vert3->position = get_tile_coords(corners[6], corners[7], corners[8]); - this->states->texture = (sfTexture *)tile.texture; + sfVector2i vec = sfMouse_getPosition(this->window); + sfVector2f world_pos = sfRenderWindow_mapPixelToCoords(this->window, vec, this->view); + world_pos.y *= -1; + //printf("mouse is x:%f, y:%f\n", world_pos.x, world_pos.y); + if (!is_pos_in_tile((gc_vector2){world_pos.x, world_pos.y}, tile)) + this->states->texture = (sfTexture *)tile->texture; + else + this->states->texture = NULL; + sfVertexArray_setPrimitiveType(this->vertices, sfTrianglesStrip); + sfVertex *vert0 = sfVertexArray_getVertex(this->vertices, 0); + vert0->color = sfWhite; + vert1->color = sfWhite; + vert2->color = sfWhite; + vert3->color = sfWhite; + sfRenderWindow_drawVertexArray(this->window, this->vertices, this->states); + world_pos.y *= -1; + sfVertexArray_setPrimitiveType(this->vertices, sfLinesStrip); + vert0->position = world_pos; + vert1->position = (sfVector2f){world_pos.x, world_pos.y}; + vert2->position = (sfVector2f){10000, -10000}; + vert3->position = (sfVector2f){10000, -10000}; + //printf("sfml inf is x:%f, y:%f\n", vert2->position.x, vert2->position.y); + this->states->texture = NULL; + vert0->color = sfRed; + vert1->color = sfRed; + vert2->color = sfRed; + vert3->color = sfRed; sfRenderWindow_drawVertexArray(this->window, this->vertices, this->states); } @@ -83,6 +111,6 @@ struct vertex_component *info) //if (!info->map[i].corners[0]->y) // continue; vert0->position = get_tile_coords(corners[0], corners[1], corners[2]); - draw_tile(this, info, info->map[i]); + draw_tile(this, info, &info->map[i]); } } \ No newline at end of file