Gama C Library
Gama C API Documentation
Loading...
Searching...
No Matches
collision.h
Go to the documentation of this file.
1#pragma once
2
3#include "body.h"
4#include "system.h"
5#include <math.h>
6
7// ---------------------------------------------------------------------------
8// ----------------------------- Collision Detection -------------------------
9// ---------------------------------------------------------------------------
10
11static inline int gm_aabb_vs_aabb(gmBody *a, gmBody *b) {
12 double a_left = a->position.x - a->width / 2;
13 double a_right = a->position.x + a->width / 2;
14 double a_top = a->position.y + a->height / 2;
15 double a_bottom = a->position.y - a->height / 2;
16
17 double b_left = b->position.x - b->width / 2;
18 double b_right = b->position.x + b->width / 2;
19 double b_top = b->position.y + b->height / 2;
20 double b_bottom = b->position.y - b->height / 2;
21
22 // Check for no overlap and return early
23 if (a_right < b_left || a_left > b_right || a_top < b_bottom ||
24 a_bottom > b_top) {
25 return 0;
26 }
27 return 1;
28}
29
30// Helper for Circle vs Circle collision
31static inline int gm_circle_vs_circle(gmBody *a, gmBody *b) {
32 double dx = b->position.x - a->position.x;
33 double dy = b->position.y - a->position.y;
34 double distance_sq = dx * dx + dy * dy;
35 double total_radius = a->radius + b->radius;
36 return distance_sq < (total_radius * total_radius);
37}
38// Accurate Circle vs Axis-Aligned Bounding Box collision
39static inline int gm_circle_vs_aabb(const gmBody *circle, const gmBody *rect) {
40 double half_w = rect->width * 0.5;
41 double half_h = rect->height * 0.5;
42
43 // Clamp circle center to rectangle bounds
44 double closest_x = fmax(rect->position.x - half_w,
45 fmin(circle->position.x, rect->position.x + half_w));
46
47 double closest_y = fmax(rect->position.y - half_h,
48 fmin(circle->position.y, rect->position.y + half_h));
49
50 // Vector from closest point to circle center
51 double dx = circle->position.x - closest_x;
52 double dy = circle->position.y - closest_y;
53
54 // Check collision (<= catches "touching" cases)
55 return (dx * dx + dy * dy) <= (circle->radius * circle->radius);
56}
57
58// Main collision detection dispatcher
60 int collided = 0;
63 collided = gm_aabb_vs_aabb(a, b);
64 }
67 collided = gm_circle_vs_circle(a, b);
68 }
71 collided = gm_circle_vs_aabb(a, b);
72 }
75 collided = gm_circle_vs_aabb(b, a);
76 }
77 if (!collided)
78 return NULL; // No collision for other combinations
79 gmCollision *collision = malloc(sizeof(gmCollision));
80 collision->bodies[0] = a;
81 collision->bodies[1] = b;
82 collision->normals = gmpos(0, 0);
83 collision->penetration = 0;
84 collision->since = 0;
85 collision->sys = NULL;
86 return collision;
87}
88
89int gm_body_contains(gmBody *body, double x, double y) {
90 double dx = fabs(body->position.x - x);
91 double dy = fabs(body->position.y - y);
92 switch (body->collider_type) {
94 return (dx < body->width * 0.5) && (dy < body->height * 0.5);
96 return (dx * dx) + (dy * dy) < (body->radius * body->radius);
97 default:
98 return 0;
99 }
100}
101
102int gm_mouse_in_rect(const double x, const double y, const double w,
103 const double h) {
104 return fabs(gm_mouse.position.x - x) < w / 2 &&
105 fabs(gm_mouse.position.y - y) < h / 2;
106}
107int gm_mouse_in_circle(const double x, const double y, const double r) {
108 return pow(gm_mouse.position.x - x, 2) + pow(gm_mouse.position.y - y, 2) <
109 pow(r, 2);
110}
@ GM_COLLIDER_RECT
Definition body.h:13
@ GM_COLLIDER_CIRCLE
Definition body.h:12
int gm_mouse_in_rect(const double x, const double y, const double w, const double h)
Definition collision.h:102
gmCollision * gm_collision_detect(gmBody *a, gmBody *b)
Detects collision between two bodies.
Definition collision.h:59
int gm_mouse_in_circle(const double x, const double y, const double r)
Definition collision.h:107
int gm_body_contains(gmBody *body, double x, double y)
Checks if a point is contained within a body's collider.
Definition collision.h:89
struct _gmMouse gm_mouse
Definition gapi.h:19
Structure representing a physics body with properties for collision and movement.
Definition body.h:19
double width
Definition body.h:28
gmColliderType collider_type
Definition body.h:23
double height
Definition body.h:28
double radius
Definition body.h:28
gmPos position
Definition body.h:24
Structure representing a collision between two bodies.
Definition system.h:10
gmPos normals
Definition system.h:16
double since
Definition system.h:15
gmBody * bodies[2]
Definition system.h:13
double penetration
Definition system.h:14
struct gm_system * sys
Definition system.h:11
double x
Definition position.h:5
double y
Definition position.h:5