diff options
Diffstat (limited to 'src/collision/rodeo_collision.c')
| -rw-r--r-- | src/collision/rodeo_collision.c | 190 |
1 files changed, 124 insertions, 66 deletions
diff --git a/src/collision/rodeo_collision.c b/src/collision/rodeo_collision.c index d529e65..3d270cd 100644 --- a/src/collision/rodeo_collision.c +++ b/src/collision/rodeo_collision.c @@ -1,131 +1,189 @@ + +// -- internal -- +// public #include "rodeo/collision.h" #include "rodeo/collision_t.h" +#include "rodeo/log.h" + +// -- system -- #include <stdio.h> -bool detect_collision( - const rodeo_collision_2d_world_item_t a, - const rodeo_collision_2d_world_item_t b -) +bool irodeo_collision_2d_detect( + const cvec_collision_2d_item_data_value a, + const cvec_collision_2d_item_data_value b +) { - return !(a.id.id == b.id.id || + return !(a.id.self_handle == b.id.self_handle || a.rect.x+a.dx > b.rect.x+b.dx + b.rect.width || b.rect.x+b.dx > a.rect.x+a.dx + a.rect.width || a.rect.y+a.dy > b.rect.y+b.dy + b.rect.height || b.rect.y+b.dy > a.rect.y+a.dy + a.rect.height); } -rodeo_collision_2d_world_t -rodeo_collision_2d_world_create(void) +rodeo_collision_2d_collection_t +rodeo_collision_2d_collection_create(void) { - return cvec_collision_2d_world_item_init(); + rodeo_collision_2d_collection_t result = {0}; + result.data = calloc(1, sizeof(*result.data)); + return result; } void -rodeo_collision_2d_world_destroy( -rodeo_collision_2d_world_t *world +rodeo_collision_2d_collection_destroy( +rodeo_collision_2d_collection_t collection ) { - cvec_collision_2d_world_item_drop(world); + c_foreach(i, cvec_collision_2d_item_data, collection.data->collection) { + free(i.ref->id.self_handle); + } + cvec_collision_2d_item_data_drop(&collection.data->collection); + free(collection.data); } -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 +rodeo_collision_2d_item_t +rodeo_collision_2d_item_create( + rodeo_collision_2d_collection_t collection, + rodeo_collision_2d_item_data_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); + bool rewrite_self_pointers = false; + intptr_t capacity = cvec_collision_2d_item_data_capacity(&collection.data->collection); + intptr_t size = cvec_collision_2d_item_data_size(&collection.data->collection); + if(capacity >= size) + { + rewrite_self_pointers = true; + } + rodeo_collision_2d_item_t result = {0}; + result.data_handle = calloc(1, sizeof(result.data_handle)); + *result.data_handle = cvec_collision_2d_item_data_push( + &collection.data->collection, + item_params + ); + (*result.data_handle)->id.collection = collection; + (*result.data_handle)->id.self_handle = result.data_handle; + + if(rewrite_self_pointers) + { + c_foreach(i, cvec_collision_2d_item_data, collection.data->collection) { + i.ref->id.collection.data = collection.data; + (*i.ref->id.self_handle) = i.ref; + } + } - return new_item; + return result; } void -rodeo_collision_2d_world_item_destroy( - cvec_collision_2d_world_item_value* cvec_value +rodeo_collision_2d_item_destroy( + rodeo_collision_2d_item_t item ) { - if (cvec_value == NULL) { return; } - *cvec_value = *cvec_collision_2d_world_item_back(cvec_value->id.world); - cvec_collision_2d_world_item_pop(cvec_value->id.world); + if(item.data_handle == NULL || *item.data_handle == NULL) + { + rodeo_log( + rodeo_logLevel_warning, + "Attempted to destroy collision item that doesn't exist anymore" + ); + if(item.data_handle != NULL) + { + free(item.data_handle); + } + return; + } + cvec_collision_2d_item_data *collection = &((*item.data_handle)->id.collection.data->collection); + + // set the back item to point to deletion item + *cvec_collision_2d_item_data_back(collection)->id.self_handle = *item.data_handle; + + // copy back item into deletion item + (**item.data_handle) = *cvec_collision_2d_item_data_back(collection); + cvec_collision_2d_item_data_pop(collection); + + // free the handle + free(item.data_handle); } void -rodeo_collision_2d_world_item_destroy_by_id( - world_id id +rodeo_collision_2d_collection_item_destroy_by_id( + rodeo_collision_2d_item_id_t 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_item_t item = rodeo_collision_2d_item_get_by_id(id); + rodeo_collision_2d_item_destroy(item); } -rodeo_collision_2d_world_item_t* -rodeo_collision_2d_world_item_get_by_id( - world_id id +rodeo_collision_2d_item_t +rodeo_collision_2d_item_get_by_id( + rodeo_collision_2d_item_id_t id ) { - if(id.world == NULL) + if(id.collection.data == NULL) { - return NULL; + rodeo_log( + rodeo_logLevel_warning, + "Attempted to find collision item that doesn't belong to a collection. It also may not exist at all" + ); + return (rodeo_collision_2d_item_t){0}; } - c_foreach(i, cvec_collision_2d_world_item, *id.world) { - if (i.ref->id.id == id.id) { - return i.ref; - } + else if(id.self_handle == NULL || *id.self_handle == NULL) + { + rodeo_log( + rodeo_logLevel_warning, + "Attempted to find collision item that doesn't exist anymore" + ); + return (rodeo_collision_2d_item_t){0}; } - return NULL; + + return (rodeo_collision_2d_item_t){.data_handle = id.self_handle}; } 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 - ) +rodeo_collision_2d_collection_compare_self( + rodeo_collision_2d_collection_t collection, + rodeo_collision_2d_resolver_f resolver ) { - 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); + c_foreach(i, cvec_collision_2d_item_data, collection.data->collection) { + c_foreach( + j, + cvec_collision_2d_item_data, + cvec_collision_2d_item_data_advance(i, 1), + cvec_collision_2d_item_data_end(&collection.data->collection) + ) + { + if (irodeo_collision_2d_detect(*i.ref, *j.ref)) { + resolver(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 - ) +rodeo_collision_2d_collection_compare_other( + rodeo_collision_2d_collection_t collection_a, + rodeo_collision_2d_collection_t collection_b, + rodeo_collision_2d_resolver_f resolver ) { - 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); + c_foreach(i, cvec_collision_2d_item_data, collection_a.data->collection) { + c_foreach(j, cvec_collision_2d_item_data, collection_b.data->collection) { + if (irodeo_collision_2d_detect(*i.ref, *j.ref)) { + resolver(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 +int32_t irodeo_collision_2d_item_data_cmp( + const rodeo_collision_2d_item_data_t* a, + const rodeo_collision_2d_item_data_t* b ) { - if (a->id.id == b->id.id) { + if (a->id.self_handle == b->id.self_handle) { return 0; } else { - return a->id.id > b->id.id ? 1 : -1; + return a->id.self_handle > b->id.self_handle ? 1 : -1; } } |
