aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common.h19
-rw-r--r--src/graphics.c32
-rw-r--r--src/main.c55
-rw-r--r--src/physics.c112
-rw-r--r--src/physics.h6
5 files changed, 92 insertions, 132 deletions
diff --git a/src/common.h b/src/common.h
index b56d70f..7664233 100644
--- a/src/common.h
+++ b/src/common.h
@@ -1,4 +1,8 @@
-// common.h
+/**
+ * @file common.h
+ * @brief Functions and values used throughout most files
+ * @date 2026-04-27
+*/
#ifndef COMMON_H
#define COMMON_H
@@ -10,14 +14,6 @@ typedef int_least16_t i16;
typedef uint_least32_t u32;
typedef int_least32_t i32;
-/* #define SHAPE_ENUM_SIZE 4 */
-/* typedef enum { */
-/* SHAPE_CIRCLE, */
-/* SHAPE_SQUARE, */
-/* SHAPE_RECTANGLE, */
-/* SHAPE_TRIANGLE */
-/* } shape_t; */
-
typedef struct {
Color color;
float elast;
@@ -33,6 +29,9 @@ typedef struct {
float mass;
Vector2* vertices;
Vector2* edges;
+ float line_thickness;
+ u32 vertex_n; // number of vertices
+ u32 edge_n; // number of edges
} object_t;
@@ -50,8 +49,6 @@ typedef struct {
#define ARR_LEN(arr) (sizeof(arr)/sizeof(arr[0]))
-#define RANDOM_SHAPE() ((shape_t)(GetRandomValue(0, SHAPE_ENUM_SIZE - 1)))
-
#define RANDOM_COLOR() ((Color) { \
GetRandomValue(0, 255), \
GetRandomValue(0, 255), \
diff --git a/src/graphics.c b/src/graphics.c
index 60ad4ff..0f31d6a 100644
--- a/src/graphics.c
+++ b/src/graphics.c
@@ -1,10 +1,15 @@
-// graphics.c
+/**
+ * @file graphics.c
+ * @brief All things related to graphics
+ * @date 2026-04-27
+ */
#include <raylib.h>
#include <stdint.h>
#include <stdio.h>
#include "graphics.h"
#include "common.h"
+
void init_graphics(uint32_t x, uint32_t y, const char* title)
{
InitWindow(x, y, title);
@@ -33,28 +38,17 @@ void clear_graphics(const Color color)
void draw_graphics_object(const object_t* obj)
{
- const Color color = obj->color;
- if(!obj->registered) return;
-
- Vector2 pos = obj->pos;
+ // shapes smaller than 3 don't make sense
+ if(obj->vertices == NULL || obj->vertex_n < 3) return;
- switch(obj->obj_type) {
- case SHAPE_CIRCLE:
- DrawCircleV(pos, obj->size_x/2.0f, color);
- break;
- case SHAPE_SQUARE:
- DrawRectangleV(
- (Vector2){pos.x - obj->size_x/2, pos.y - obj->size_y/2},
- (Vector2){obj->size_x, obj->size_y}, color);
- break;
- case SHAPE_RECTANGLE:
- DrawRectangleV(
- (Vector2){pos.x - obj->size_x/2, pos.y - obj->size_y/2},
- (Vector2){obj->size_x, obj->size_y}, color);
- break;
+ for(u32 iter = 0; iter < obj->vertex_n; iter++) {
+ Vector2 start = obj->vertices[iter];
+ Vector2 end = obj->vertices[(iter + 1) % obj->vertex_n];
+ DrawLineEx(start, end, obj->line_thickness, obj->color);
}
}
+
void draw_graphics_objects(const object_t* world, uint32_t count)
{
for (uint32_t iter = 0; iter < count; iter++)
diff --git a/src/main.c b/src/main.c
index 4d69c1b..f6a1de3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,4 +1,8 @@
-// main.c
+/**
+ * @file main.c
+ * @brief The main loop and controls
+ * @date 2026-04-27
+ */
#include <math.h>
#include <raylib.h>
#include <stdbool.h>
@@ -20,43 +24,29 @@ int main(void)
object_t* grabbed_obj = NULL;
bool anti_gravity_toggle = false;
- world[0] = (object_t){
- .color = RANDOM_COLOR(),
- .elast = 0.9f,
- .frict = 0.99f,
- .grabbed = true,
- .pos_prev = {0},
- .registered = true,
- .size_x = 75,
- .size_y = 75,
- .vel = {200, 200},
- .pos = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f },
- .obj_type = RANDOM_SHAPE()
- };
-
objs_count = 1;
init_physics(world, MAX_OBJECTS);
init_graphics(WINDOW_X, WINDOW_Y, SCREEN_TITLE);
while(!WindowShouldClose()) {
Vector2 pos_cursor = GetMousePosition();
- if(IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) {
- if(objs_count == 0) {
- grabbed_obj = NULL;
- } else {
- for(uint32_t iter = objs_count; iter > 0; iter--) {
- object_t* obj = &world[iter - 1];
- float dx = pos_cursor.x - obj->pos.x;
- float dy = pos_cursor.y - obj->pos.y;
+ /* if(IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) { */
+ /* if(objs_count == 0) { */
+ /* grabbed_obj = NULL; */
+ /* } else { */
+ /* for(uint32_t iter = objs_count; iter > 0; iter--) { */
+ /* object_t* obj = &world[iter - 1]; */
+ /* float dx = pos_cursor.x - obj->pos.x; */
+ /* float dy = pos_cursor.y - obj->pos.y; */
- if(hypot(dx, dy) <= (obj->size_x && obj->size_y)) {
- obj->grabbed = true;
- grabbed_obj = obj;
- break;
- }
- }
- }
- }
+ /* if(hypot(dx, dy) <= (obj->size_x && obj->size_y)) { */
+ /* obj->grabbed = true; */
+ /* grabbed_obj = obj; */
+ /* break; */
+ /* } */
+ /* } */
+ /* } */
+ /* } */
if (IsMouseButtonReleased(MOUSE_BUTTON_RIGHT)) {
if(grabbed_obj != NULL) {
@@ -80,9 +70,6 @@ int main(void)
.grabbed = false,
.registered = true,
.mass = GetRandomValue(3, 100), // will be done later
- .size_x = GetRandomValue(50, 100), //everything smaller than 3 would xbe too small
- .size_y = GetRandomValue(50, 100),
- .obj_type = RANDOM_SHAPE()
};
}
}
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)) {
}
diff --git a/src/physics.h b/src/physics.h
index e9c0c0e..a191860 100644
--- a/src/physics.h
+++ b/src/physics.h
@@ -8,11 +8,7 @@
void init_physics(object_t* world, uint32_t max_objs);
-bool check_collision(object_t obj1, object_t obj2);
+bool check_collision(object_t* obj1, object_t* obj2);
void update_physics(object_t* world, uint32_t objs_count, float gravity, float dt);
-void apply_force(object_t* obj, Vector2 force);
-void add_object(object_t* world, uint32_t* count, shape_t type, Vector2 pos);
void clear_all_physics(object_t* world, uint32_t* count);
-void push_pos(object_t* world, uint32_t count, Vector2 pos, float radius, float strength);
-
#endif // PHYSICS_H