collisions are working

This commit is contained in:
Clément Le Bihan
2020-03-09 00:30:06 +01:00
parent db72c2c0f3
commit cf6bd28424
7 changed files with 135 additions and 67 deletions
+22 -11
View File
@@ -7,17 +7,28 @@
#include "engine.h"
#include <stdbool.h>
#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);
//! @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);
+1 -1
View File
@@ -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);
+64 -40
View File
@@ -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) {
+2 -2
View File
@@ -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");
+8 -3
View File
@@ -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)
+1 -1
View File
@@ -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);
}
+37 -9
View File
@@ -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 <math.h>
#include <stdint.h>
#include <SFML/Graphics.h>
@@ -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]);
}
}