added tilemap collision
This commit is contained in:
parent
878b4c5595
commit
47264c3da3
|
@ -1,23 +1,37 @@
|
|||
#include "physics_world.h"
|
||||
#include "debug.h"
|
||||
#include "collision.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
static PhysicsEntity* _world_bodies = NULL;
|
||||
static size_t _world_bodies_cap = 0;
|
||||
static size_t _world_bodies_len = 0;
|
||||
|
||||
static Tilemap** _world_maps = NULL;
|
||||
static size_t _world_maps_cap = 0;
|
||||
static size_t _world_maps_len = 0;
|
||||
|
||||
void physics_world_init() {
|
||||
_world_bodies = malloc(8 * sizeof(PhysicsEntity));
|
||||
_world_bodies_cap = 0;
|
||||
_world_bodies_cap = 8;
|
||||
_world_bodies_len = 0;
|
||||
|
||||
_world_maps = malloc(4 * (sizeof(Tilemap*)));
|
||||
_world_maps_cap = 4;
|
||||
_world_maps_len = 0;
|
||||
}
|
||||
|
||||
void physics_world_clean() {
|
||||
free(_world_bodies);
|
||||
_world_bodies_cap = 0;
|
||||
_world_bodies_cap = 0;
|
||||
_world_bodies_len = 0;
|
||||
|
||||
free(_world_maps);
|
||||
_world_maps_cap = 0;
|
||||
_world_maps_len = 0;
|
||||
}
|
||||
|
||||
void _physics_world_resize(size_t minimum) {
|
||||
void _internal_physics_world_resize_entities(size_t minimum) {
|
||||
if(minimum < _world_bodies_cap) {
|
||||
return;
|
||||
}
|
||||
|
@ -35,7 +49,7 @@ void _physics_world_resize(size_t minimum) {
|
|||
}
|
||||
|
||||
void physics_world_add_entity(PhysicsEntity entity) {
|
||||
_physics_world_resize(_world_bodies_len + 1);
|
||||
_internal_physics_world_resize_entities(_world_bodies_len + 1);
|
||||
|
||||
_world_bodies[_world_bodies_len] = entity;
|
||||
++_world_bodies_len;
|
||||
|
@ -59,6 +73,50 @@ void physics_world_remove_entity(PhysicsEntity entity) {
|
|||
ASSERT_RETURN(0,, "Physics entity with data at %p is not registered in physics world", entity.data);
|
||||
}
|
||||
|
||||
static
|
||||
void _internal_physics_world_resize_maps(size_t minimum) {
|
||||
if(minimum < _world_maps_cap) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t amount = _world_maps_cap;
|
||||
while(amount < minimum) {
|
||||
amount *= 2;
|
||||
}
|
||||
|
||||
Tilemap** new = realloc(_world_maps, amount * sizeof(Tilemap*));
|
||||
ASSERT_RETURN(new != NULL,, "Could not grow physics tilemaps array");
|
||||
|
||||
_world_maps = new;
|
||||
_world_maps_cap = amount;
|
||||
}
|
||||
|
||||
void physics_world_add_map(Tilemap* map) {
|
||||
_internal_physics_world_resize_maps(_world_maps_len + 1);
|
||||
|
||||
_world_maps[_world_maps_len] = map;
|
||||
++_world_maps_len;
|
||||
}
|
||||
|
||||
static
|
||||
void _internal_physics_world_remove_map(Tilemap** at) {
|
||||
Tilemap** from = at + 1;
|
||||
memmove(at, from, (at - _world_maps + _world_bodies_len) * sizeof(Tilemap*));
|
||||
--_world_bodies_len;
|
||||
}
|
||||
|
||||
void physics_world_remove_map(Tilemap* map) {
|
||||
Tilemap** end = _world_maps + _world_maps_len;
|
||||
for(Tilemap** itr = _world_maps; itr < end; ++itr) {
|
||||
if(*itr == map) {
|
||||
_internal_physics_world_remove_map(itr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_RETURN(0,, "Physics tilemap with data at %p is not registered in physics world and cannot be removed.", map);
|
||||
}
|
||||
|
||||
static
|
||||
void _internal_physics_narrow_collision() {
|
||||
PhysicsEntity* end = _world_bodies + _world_bodies_len;
|
||||
|
@ -75,6 +133,33 @@ void _internal_physics_narrow_collision() {
|
|||
}
|
||||
}
|
||||
|
||||
static
|
||||
void _internal_tilemap_entity_collision_check(Tilemap* map, PhysicsEntity entity) {
|
||||
Collision collision_a;
|
||||
Collision collision_b;
|
||||
PhysicsEntity tileentity;
|
||||
|
||||
size_t len = tilemap_get_tile_count(map);
|
||||
for(size_t i = 0; i < len; ++i) {
|
||||
tileentity = TileInstance_as_PhysicsEntity(tilemap_get_tile(map, i));
|
||||
|
||||
if(collision_check(entity, tileentity, &collision_a, &collision_b)) {
|
||||
entity.tc->on_collision(entity.data, collision_a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void _internal_physics_tilemap_collision() {
|
||||
PhysicsEntity* bodies_end = _world_bodies + _world_bodies_len;
|
||||
Tilemap** maps_end = _world_maps + _world_maps_len;
|
||||
for(PhysicsEntity* entity = _world_bodies; entity < bodies_end; ++entity) {
|
||||
for(Tilemap** map = _world_maps; map < maps_end; ++map) {
|
||||
_internal_tilemap_entity_collision_check(*map, *entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void _internal_physics_move() {
|
||||
PhysicsEntity* end = _world_bodies + _world_bodies_len;
|
||||
|
@ -89,5 +174,6 @@ void _internal_physics_move() {
|
|||
void physics_world_tick() {
|
||||
// _internal_physics_broad_collision();
|
||||
_internal_physics_narrow_collision();
|
||||
_internal_physics_tilemap_collision();
|
||||
_internal_physics_move();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _fencer_physics_world_h
|
||||
|
||||
#include "physics_entity.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
extern void physics_world_init();
|
||||
extern void physics_world_clean();
|
||||
|
@ -9,6 +10,9 @@ extern void physics_world_clean();
|
|||
extern void physics_world_add_entity(PhysicsEntity entity);
|
||||
extern void physics_world_remove_entity(PhysicsEntity entity);
|
||||
|
||||
extern void physics_world_add_map(Tilemap* map);
|
||||
extern void physics_world_remove_map(Tilemap* map);
|
||||
|
||||
extern void physics_world_tick();
|
||||
|
||||
#endif // !_fencer_physics_world_h
|
||||
|
|
Loading…
Reference in a new issue