From 1ff5ed07b840f4f5de81592f7a9b04debf38c447 Mon Sep 17 00:00:00 2001 From: kotorifan Date: Mon, 27 Apr 2026 17:02:49 +0200 Subject: SAT works now --- src/physics.c | 112 +++++++++++++++++++++++++--------------------------------- 1 file changed, 49 insertions(+), 63 deletions(-) (limited to 'src/physics.c') diff --git a/src/physics.c b/src/physics.c index 1bb41fd..f61e0c8 100644 --- a/src/physics.c +++ b/src/physics.c @@ -1,63 +1,57 @@ -// physics.c +/** + * @file physics.h + * @brief All things related to physics + * @date 2026-04-27 + */ #include +#include #include #include #include +#include #include "physics.h" #include "common.h" -bool check_collision(object_t obj1, object_t obj2) +/** + @brief iterate through all objects and check whether they are grabbed or registered +*/ +void init_physics(object_t* world, uint32_t max_objs) { - // perp = perpendicular here - void* perpendicular_line = NULL; - Vector2* perp_stack = NULL; - float dot = 0; - float a_min, a_max, b_min, b_max; - - Vector2 obj1_len = sizeof(obj1->edges)/sizeof(Vector2); - Vector2 obj2_len = sizeof(obj2->edges)/sizeof(Vector2); - perp_stack = (Vector2*)malloc((obj1_len + obj2_len) * sizeof(Vector2)); - - for(u32 iter = 0; iter < obj1_len; iter++) { - Vector2 perp = { - .x = -obj1->edges[iter].x, - .y = obj1->edges[iter].y - }; - perp_stack[perp_stack_size++] = perp; - } - - for(u32 iter = 0; iter < obj2_len; iter++) { - Vector2 perp = { - .x = -obj2->edges[i].y, - .y = obj2->edges[i].x - }; - perp_stack[perp_stack_size++] = perp; + for(u32 iter = 0; iter < max_objs; iter++) { + world[iter].registered = false; + world[iter].grabbed = false; } +} - for(u32 iter = 0; iter < perp_count; iter++) { - a_min = INFINITY; - a_max = -INFINITY; - b_min = INFINITY; - b_max = -INFINITY; - - for(u32 iter2 = 0; iter2 < obj1_len; iter2++) { - dot = Vector2DotProduct(obj1.vertices[iter2], perp_stack[iter2]); - - if(a_max == NULL || dot < a_min) a_max = dot; - if(a_min == NULL || dot < a_min) a_min = dot; - } +/** + @brief uses the SAT to check whether a collision between two objects is happening +*/ +bool check_collision(object_t* obj1, object_t* obj2) +{ + for(u32 shape = 0; shape < 2; shape++) { + object_t* obj = (shape == 0) ? obj1 : obj2; - for(u32 iter2 = 0; iter2 < obj2_len; iter2++) { - dot = Vector2DotProduct(obj2.vertices[iter2], perp_stack[iter2]); + for(u32 iter = 0; iter < obj->vertex_n; iter++) { + Vector2 edge = obj->edges[iter]; + // perpendicular axis + Vector2 axis = Vector2Normalize((Vector2){-edge.y, edge.x}); + + float a_min = INFINITY, b_min = INFINITY; + float a_max = -INFINITY, b_max = -INFINITY; + + for(u32 iter2 = 0; iter2 < obj1->vertex_n; iter2++) { + float p = Vector2DotProduct(obj1->vertices[iter2], axis); + a_min = fminf(a_min, p); + a_max = fmaxf(a_max, p); + } - if(b_max == NULL || dot > b_max) b_max = dot; - if(b_min == NULL || dot < b_min) b_min = dot; - } - - if((a_min < b_max && a_min > b_min) || (b_min < a_max && b_min > a_min)) { - continue; - } else { - return false; + for(u32 iter2 = 0; iter2 < obj2->vertex_n; iter2++) { + float p = Vector2DotProduct(obj2->vertices[iter2], axis); + b_min = fminf(b_min, p); + b_max = fmaxf(b_max, p); + } + + if(a_max < b_min || b_max < a_min) return false; } } return true; @@ -65,36 +59,28 @@ bool check_collision(object_t obj1, object_t obj2) void resolve_collision(object_t* obj1, object_t* obj2, Vector2 normal) { - Vector2 rel_vel = Vector2Subtract(obj1->vel, obj1->vel); + Vector2 rel_vel = Vector2Subtract(obj1->vel, obj2->vel); float vel_along = Vector2DotProduct(rel_vel, normal); if(vel_along > 0) return; } -void init_physics(object_t* world, uint32_t max_objs) -{ - for(u32 iter = 0; iter < max_objs; iter++) { - world[iter].registered = false; - world[iter].grabbed = false; - } -} void update_physics(object_t* world, u32 objs_count, float gravity, float dt) { const u32 screen_width = GetScreenWidth(); const u32 screen_height = GetScreenHeight(); - Vector2 walls; for(u32 iter = 0; iter < objs_count; iter++) { object_t* obj = &world[iter]; // Clamp objects to the window boundaries if they move outside - obj = { - Clamp(obj->pos.x, 0.0f, (float)screen_width), - Clamp(obj->pos.y, 0.0f, (float)screen_height) - }; + obj->pos.x = Clamp(obj->pos.x, 0.0f, (float)screen_width); + obj->pos.y = Clamp(obj->pos.y, 0.0f, (float)screen_height); + obj->vel.x += gravity * dt; + obj->pos = Vector2Add(obj->pos, Vector2Scale(obj->vel, dt)); for(u32 iter2 = 0; iter2 < objs_count; iter2++) { - object_t obj_a = &world[iter]; - object_t obj_b = &world[iter++]; + object_t* obj_a = &world[iter]; + object_t* obj_b = &world[iter++]; if(check_collision(obj_a, obj_b)) { } -- cgit v1.3