diff --git a/Makefile b/Makefile index ab7fd65..8a3c226 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,9 @@ SRC = src/quadtree.c \ src/qt_collide.c \ src/qt_destroy.c \ src/qt_layer.c \ - src/utility/calloc.c + src/qt_position_overlap.c \ + src/utility/calloc.c \ + src/array.c OBJ = $(SRC:%.c=%.o) diff --git a/include/array.h b/include/array.h new file mode 100644 index 0000000..959394e --- /dev/null +++ b/include/array.h @@ -0,0 +1,11 @@ +/* +** EPITECH PROJECT, 2020 +** Twac +** File description: +** array +*/ + +#pragma once + +void arr_add(int *arr, int n); +int arr_len(int *arr); \ No newline at end of file diff --git a/include/quadtree.h b/include/quadtree.h index 85ef384..64d3d07 100644 --- a/include/quadtree.h +++ b/include/quadtree.h @@ -10,6 +10,7 @@ #include #define MAXCOL 1024 +#define MAX_ENTITY 20 typedef struct quadtree quadtree; @@ -34,6 +35,7 @@ typedef struct qt_collision float distance_right; float distance_top; float distance_down; + int *collide_with; } qt_collision; struct quadtree @@ -49,8 +51,4 @@ qt_collision collision_get_info(quadtree *tree, int entity_id); bool qt_collide(qt_intrect r1, qt_intrect r2); qt_object *qt_getobj(quadtree *tree, int id); int qt_update(quadtree *tree, qt_object obj); -void qt_destroy(quadtree *tree); - - -#define CAN_BE_SEEN 0b10 -#define CAN_SEE 0b01 \ No newline at end of file +void qt_destroy(quadtree *tree); \ No newline at end of file diff --git a/include/quadtree_internal.h b/include/quadtree_internal.h index d1c0a37..22b4ab4 100644 --- a/include/quadtree_internal.h +++ b/include/quadtree_internal.h @@ -7,10 +7,24 @@ #pragma once +#include "quadtree.h" +#include + void *my_calloc(int capacity, int size); quadtree *qt_split(quadtree *tree); + +bool collision_overlapx(qt_intrect r1, qt_intrect r2); +bool collision_overlapy(qt_intrect r1, qt_intrect r2); + bool collision_can_see(int l1, int l2); #define MIN(x, y) ((x) < (y) ? (x) : (y)) -#define MAX(x, y) ((x) < (y) ? (y) : (x)) \ No newline at end of file +#define MAX(x, y) ((x) < (y) ? (y) : (x)) + +#define CAN_BE_SEEN 0b10 +#define CAN_SEE 0b01 + +#define TREEOBJ_AT(x) (&((qt_object *)tree->objects)[i]) + +#define COLLISION_MAX ((qt_collision){MAXCOL, MAXCOL, MAXCOL, MAXCOL, NULL}) \ No newline at end of file diff --git a/src/array.c b/src/array.c new file mode 100644 index 0000000..19ff0c8 --- /dev/null +++ b/src/array.c @@ -0,0 +1,27 @@ +/* +** EPITECH PROJECT, 2020 +** Twac +** File description: +** array +*/ + +#include "quadtree.h" + +int arr_len(int *arr) +{ + int i = 0; + + while (arr[i] != -1) + i++; + return (i); +} + +void arr_add(int *arr, int n) +{ + int new = arr_len(arr); + + if (new + 1 > MAX_ENTITY) + return; + arr[new] = n; + arr[new + 1] = -1; +} \ No newline at end of file diff --git a/src/qt_collide.c b/src/qt_collide.c index 00bcf48..f886eb1 100644 --- a/src/qt_collide.c +++ b/src/qt_collide.c @@ -7,86 +7,73 @@ #include "quadtree.h" #include "quadtree_internal.h" +#include "array.h" -//X1 is on the line or X2 is on the line or both X are on each side of the map -bool collision_overlapx(qt_intrect r1, qt_intrect r2) +qt_collision check_collisions(qt_object *obj1, qt_object *obj2, int *colwith) { - if (r1.x > r2.x && r1.x < r2.x + r2.w) - return (true); - if (r1.x + r1.w > r2.x && r1.x + r1.w < r2.x + r2.w) - return (true); - if (r1.x < r2.x && r1.x + r1.w > r2.x + r2.w) - return (true); - if (r1.x == r2.x) - return (true); - return (false); -} + qt_intrect r1 = obj1->rect; + qt_intrect r2 = obj2->rect; + qt_collision col = COLLISION_MAX; -bool collision_overlapy(qt_intrect r1, qt_intrect r2) -{ - if (r1.y - r1.h < r2.y && r1.y - r1.h > r2.y - r2.h) - return (true); - if (r1.y < r2.y && r1.y - r1.h > r2.y - r2.h) - return (true); - if (r1.y < r2.y && r1.y > r2.y - r2.h) - return (true); - if (r1.y == r2.y) - return (true); - return (false); -} - -qt_collision collision_complete(qt_collision col, qt_intrect r1, qt_intrect r2) -{ if (collision_overlapy(r1, r2)) { if (r1.x <= r2.x) - col.distance_right = MIN(col.distance_right, r2.x - (r1.x + r1.w)); + col.distance_right = r2.x - (r1.x + r1.w); if (r2.x <= r1.x) - col.distance_left = MIN(col.distance_left, r1.x - (r2.x + r2.w)); + col.distance_left = r1.x - (r2.x + r2.w); } if (collision_overlapx(r1, r2)) { if (r1.y >= r2.y) - col.distance_down = MIN(col.distance_down, r1.y - r2.y - r1.h); + col.distance_down = r1.y - r2.y - r1.h; if (r2.y >= r1.y) - col.distance_top = MIN(col.distance_top, r2.y - r1.y - r2.h); + col.distance_top = r2.y - r1.y - r2.h; } - col.distance_down = MAX(0, col.distance_down); - col.distance_top = MAX(0, col.distance_top); - col.distance_left = MAX(0, col.distance_left); - col.distance_right = MAX(0, col.distance_right); + if (col.distance_right == 0 || col.distance_down == 0 || + col.distance_left == 0 || col.distance_right == 0) + arr_add(colwith, obj2->id); return (col); } -qt_collision collision_get_real_info(quadtree *tree, int id, qt_collision col) +qt_collision sum_col(qt_collision col1, qt_collision col2) +{ + col1.distance_down = MAX(0, MIN(col1.distance_down, col2.distance_down)); + col1.distance_top = MAX(0, MIN(col1.distance_top, col2.distance_top)); + col1.distance_left = MAX(0, MIN(col1.distance_left, col2.distance_left)); + col1.distance_right = MAX(0, MIN(col1.distance_right, col2.distance_right)); + return (col1); +} + +qt_collision collrec(quadtree *tree, int id, qt_collision col, int *collidewith) { qt_object *obj; qt_object *tmp; - int cap = tree->capacity; quadtree *child; if (tree->capacity == -1) { for (int i = 0; i < 4; i++) { child = &((quadtree *)tree->objects)[i]; - col = collision_get_real_info(child, id, col); + col = collrec(child, id, col, collidewith); } return (col); } obj = qt_getobj(tree, id); if (!obj) return (col); - for (int i = 0; i < cap && ((qt_object *)tree->objects)[i].id != -1; i++) { - tmp = &((qt_object *)tree->objects)[i]; - if (tmp->id == id || !collision_can_see(obj->layer, tmp->layer)) { - if (tmp->id != id) - printf("%d (id %d) VS %d (id %d)\n", obj->layer, id, tmp->layer, tmp->id); + for (int i = 0; i < tree->capacity && TREEOBJ_AT(i)->id != -1; i++) { + tmp = TREEOBJ_AT(i); + if (tmp->id == id || !collision_can_see(obj->layer, tmp->layer)) continue; - } - col = collision_complete(col, obj->rect, tmp->rect); + col = sum_col(col, check_collisions(obj, tmp, collidewith)); } return (col); } qt_collision collision_get_info(quadtree *tree, int id) { - qt_collision col = (qt_collision){MAXCOL, MAXCOL, MAXCOL, MAXCOL}; - return (collision_get_real_info(tree, id, col)); + qt_collision col = COLLISION_MAX; + static int collidewith[MAX_ENTITY + 1]; + + collidewith[0] = -1; + col = collrec(tree, id, col, collidewith); + col.collide_with = collidewith; + return (col); } \ No newline at end of file diff --git a/src/qt_layer.c b/src/qt_layer.c index e244376..73815aa 100644 --- a/src/qt_layer.c +++ b/src/qt_layer.c @@ -5,7 +5,7 @@ ** qt_layer */ -#include "quadtree.h" +#include "quadtree_internal.h" #include bool collision_can_see(int l1, int l2) diff --git a/src/qt_position_overlap.c b/src/qt_position_overlap.c new file mode 100644 index 0000000..9bfa9fc --- /dev/null +++ b/src/qt_position_overlap.c @@ -0,0 +1,35 @@ +/* +** EPITECH PROJECT, 2020 +** Twac +** File description: +** qt_position_overlap +*/ + +#include "quadtree.h" + +//X1 is on the line or X2 is on the line or both X are on each side of the map +bool collision_overlapx(qt_intrect r1, qt_intrect r2) +{ + if (r1.x > r2.x && r1.x < r2.x + r2.w) + return (true); + if (r1.x + r1.w > r2.x && r1.x + r1.w < r2.x + r2.w) + return (true); + if (r1.x < r2.x && r1.x + r1.w > r2.x + r2.w) + return (true); + if (r1.x == r2.x) + return (true); + return (false); +} + +bool collision_overlapy(qt_intrect r1, qt_intrect r2) +{ + if (r1.y - r1.h < r2.y && r1.y - r1.h > r2.y - r2.h) + return (true); + if (r1.y < r2.y && r1.y - r1.h > r2.y - r2.h) + return (true); + if (r1.y < r2.y && r1.y > r2.y - r2.h) + return (true); + if (r1.y == r2.y) + return (true); + return (false); +} \ No newline at end of file