diff options
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | include/rodeo/collision.h | 29 | ||||
| -rw-r--r-- | include/rodeo/collision_t.h | 11 | ||||
| -rw-r--r-- | src/collision/rodeo_collision.c | 126 |
4 files changed, 161 insertions, 6 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 6cd566d..cccc4de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ add_library(${PROJECT_NAME} "src/log/rodeo_log.c" "src/input/rodeo_input.c" "src/audio/rodeo_audio.c" + "src/collision/rodeo_collision.c" ) set_property(TARGET RodeoKit PROPERTY C_STANDARD 99) diff --git a/include/rodeo/collision.h b/include/rodeo/collision.h index 9e7b856..277b780 100644 --- a/include/rodeo/collision.h +++ b/include/rodeo/collision.h @@ -7,7 +7,9 @@ rodeo_collision_2d_world_t rodeo_collision_2d_world_create(void); void -rodeo_collision_2d_world_destroy(void); +rodeo_collision_2d_world_destroy( + rodeo_collision_2d_world_t *world +); cvec_collision_2d_world_item_value* rodeo_collision_2d_world_item_create( @@ -17,19 +19,34 @@ rodeo_collision_2d_world_item_create( void rodeo_collision_2d_world_item_destroy( - rodeo_collision_2d_world_t *world, cvec_collision_2d_world_item_value* cvec_value ); void +rodeo_collision_2d_world_item_destroy_by_id( + world_id id +); + +rodeo_collision_2d_world_item_t* +rodeo_collision_2d_world_item_get_by_id( + world_id id +); + +void rodeo_collision_2d_world_compare_self( - rodeo_collision_2d_world_t *world - // resolve function? + rodeo_collision_2d_world_t *world, + void (*resolve)( + rodeo_collision_2d_world_item_t *a, + rodeo_collision_2d_world_item_t *b + ) ); void rodeo_collision_2d_world_compare_other( rodeo_collision_2d_world_t *world_a, - rodeo_collision_2d_world_t *world_b - // resolve function? + rodeo_collision_2d_world_t *world_b, + void (*resolve)( + rodeo_collision_2d_world_item_t *a, + rodeo_collision_2d_world_item_t *b + ) ); diff --git a/include/rodeo/collision_t.h b/include/rodeo/collision_t.h index e51386c..e75d243 100644 --- a/include/rodeo/collision_t.h +++ b/include/rodeo/collision_t.h @@ -4,10 +4,19 @@ #include <stdint.h> #include <stdbool.h> +struct cvec_collision_2d_world_item; + typedef struct { uint32_t id; + struct cvec_collision_2d_world_item *world; +} world_id; + +typedef +struct +{ + world_id id; float x; float y; float dx; @@ -18,6 +27,7 @@ struct } rodeo_collision_2d_world_item_t; + int rodeo_collision_2d_item_cmp( const rodeo_collision_2d_world_item_t* a, const rodeo_collision_2d_world_item_t* b @@ -28,4 +38,5 @@ int rodeo_collision_2d_item_cmp( #define i_type cvec_collision_2d_world_item #include "stc/cvec.h" + typedef cvec_collision_2d_world_item rodeo_collision_2d_world_t; diff --git a/src/collision/rodeo_collision.c b/src/collision/rodeo_collision.c new file mode 100644 index 0000000..e4791bf --- /dev/null +++ b/src/collision/rodeo_collision.c @@ -0,0 +1,126 @@ +#include "rodeo/collision.h" +#include "rodeo/collision_t.h" +#include <stdio.h> + +bool detect_collision( + const rodeo_collision_2d_world_item_t *a, + const rodeo_collision_2d_world_item_t *b +) +{ + return !(a->x+a->dx > b->x+b->dx + b->width || + b->x+b->dx > a->x+a->dx + a->width || + a->y+a->dy > b->y+b->dy + b->height || + b->y+b->dy > a->y+a->dy + a->height); +} + +rodeo_collision_2d_world_t +rodeo_collision_2d_world_create(void) +{ + return cvec_collision_2d_world_item_init(); +} + +void +rodeo_collision_2d_world_destroy( +rodeo_collision_2d_world_t *world +) +{ + cvec_collision_2d_world_item_drop(world); +} + +cvec_collision_2d_world_item_value* +rodeo_collision_2d_world_item_create( + rodeo_collision_2d_world_t *world, + rodeo_collision_2d_world_item_t item_params +) +{ + static uint32_t next_id = 0; + item_params.id.id = next_id++; + item_params.id.world = world; + cvec_collision_2d_world_item_value* new_item = cvec_collision_2d_world_item_push(world, item_params); + + return new_item; +} + +void +rodeo_collision_2d_world_item_destroy( + cvec_collision_2d_world_item_value* cvec_value +) +{ + + cvec_collision_2d_world_item_value temp = *cvec_collision_2d_world_item_back(cvec_value->id.world); + *cvec_collision_2d_world_item_back(cvec_value->id.world) = *cvec_value; + *cvec_value = temp; + cvec_collision_2d_world_item_pop(cvec_value->id.world); +} + +void +rodeo_collision_2d_world_item_destroy_by_id( + world_id id +) +{ + rodeo_collision_2d_world_item_t* item = rodeo_collision_2d_world_item_get_by_id(id); + rodeo_collision_2d_world_item_destroy(item); +} + +rodeo_collision_2d_world_item_t* +rodeo_collision_2d_world_item_get_by_id( + world_id id +) +{ + c_foreach(i, cvec_collision_2d_world_item, *id.world) { + if (i.ref->id.id == id.id) { + return i.ref; + } + } + return NULL; +} + +void +rodeo_collision_2d_world_compare_self( + rodeo_collision_2d_world_t *world, + void (*resolve)( + rodeo_collision_2d_world_item_t *a, + rodeo_collision_2d_world_item_t *b + ) +) +{ + c_foreach(i, cvec_collision_2d_world_item, *world) { + c_foreach(j, cvec_collision_2d_world_item, cvec_collision_2d_world_item_advance(i, 1), cvec_collision_2d_world_item_end(world)) { + if (detect_collision(i.ref, j.ref)) { + resolve(i.ref, j.ref); + } + } + } +} + +void +rodeo_collision_2d_world_compare_other( + rodeo_collision_2d_world_t *world_a, + rodeo_collision_2d_world_t *world_b, + void (*resolve)( + rodeo_collision_2d_world_item_t *a, + rodeo_collision_2d_world_item_t *b + ) +) +{ + c_foreach(i, cvec_collision_2d_world_item, *world_a) { + c_foreach(j, cvec_collision_2d_world_item, *world_b) { + if (detect_collision(i.ref, j.ref)) { + resolve(i.ref, j.ref); + } + } + } +} + + +int rodeo_collision_2d_item_cmp( + const rodeo_collision_2d_world_item_t* a, + const rodeo_collision_2d_world_item_t* b +) +{ + if (a->id.id == b->id.id) { + return 0; + } else { + return a->id.id > b->id.id ? 1 : -1; + } +} |
