aboutsummaryrefslogtreecommitdiffstats
path: root/src/physics.c
diff options
context:
space:
mode:
authorkotorifan <kotorifan05@gmail.com>2026-04-27 17:02:49 +0200
committerkotorifan <kotorifan05@gmail.com>2026-04-27 17:02:49 +0200
commit1ff5ed07b840f4f5de81592f7a9b04debf38c447 (patch)
treea25b2cccd860522d944f1e19fd186462ff842a9c /src/physics.c
parentc8ec0d2d0c57c42499f9ea95ef0ddd6ef3764f26 (diff)
downloadtrashbinphysics-1ff5ed07b840f4f5de81592f7a9b04debf38c447.tar.gz
SAT works now
Diffstat (limited to 'src/physics.c')
-rw-r--r--src/physics.c112
1 files changed, 49 insertions, 63 deletions
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 <raylib.h>
+#include <raymath.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
+#include <math.h>
#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)) {
}