#include "Physics_Component.h" #include "Entity.h" #include "Types.h" #include "util/tree.h" #include "util/vector.h" #include "util/assert.h" #include #include double physics_Gravity = 5.0; Box2 physics_HitboxAbsolute(Component_Hitbox *hitbox) { Entity *super = hitbox->super; if (!super->position) return hitbox->box; else { Box2 box = hitbox->box; box.lefttop = vec2_Add(box.lefttop, super->position->position); return box; } } System_Physics *physics_NewSystem() { System_Physics *sys = malloc(sizeof(System_Physics)); sys->pos = tree_Create(sizeof(uintptr_t)); sys->hit = tree_Create(sizeof(uintptr_t)); sys->flaggedDelete = vector_Create(sizeof(uintptr_t)); return sys; } void physics_DeleteSystem(System_Physics *sys) { tree_Destroy(sys->pos); tree_Destroy(sys->hit); vector_Destroy(sys->flaggedDelete); } void physics_AddEntity(System_Physics *sys, Entity *e) { if (e->position) memcpy(tree_Insert(sys->pos, e->id, NULL), &e->position, sizeof(uintptr_t)); if (e->hitbox) { ASSERT(!e->hitbox->fixed && !e->position && "Entity has non-Fixed Hitbox but no position"); memcpy(tree_Insert(sys->hit, e->id, NULL), &e->hitbox, sizeof(uintptr_t)); } } void physics_DeleteEntity(System_Physics *sys, uintptr_t id) { vector_Push(sys->flaggedDelete, &id); } // Defined in Physics_Move.c void _physics_MoveX(System_Physics *sys, Entity *e, Duration deltaTime); void _physics_MoveY(System_Physics *sys, Entity *e, Duration deltaTime); static inline void _physics_AdvanceEntity(System_Physics *sys, Entity *e, Duration deltaTime) { ASSERT(e->position && "_physics_AdvanceEntity() called on entity with no position"); // Short path if (!e->hitbox || e->hitbox->fixed) { e->position->position = vec2_Add( e->position->position, vec2_Scale( e->position->velocity, duration_Seconds(deltaTime))); return; } // Long path _physics_MoveX(sys, e, deltaTime); _physics_MoveY(sys, e, deltaTime); } void physics_Advance(System_Physics *sys, Duration deltaTime) { // Delete flagged entities while (vector_Size(sys->flaggedDelete)) { uintptr_t id; vector_Pop(sys->flaggedDelete, &id); tree_Node *n; n = tree_FindNode(sys->pos, id); if (n) tree_Delete(sys->pos, n); n = tree_FindNode(sys->hit, id); if (n) tree_Delete(sys->hit, n); } for (tree_Node *i = tree_FirstNode(sys->pos); i != NULL; i = tree_Node_Next(i)) { Component_Position *pos = *((Component_Position **)i->data); _physics_AdvanceEntity(sys, pos->super, deltaTime); } }