diff --git a/main.c b/main.c index 406087b..1654a10 100644 --- a/main.c +++ b/main.c @@ -36,29 +36,6 @@ Vector2 body_collision(mass_body_t *a, mass_body_t *b) { return result; } -Vector2 edge_collision(mass_body_t *b) { - float width = GetRenderWidth(); - float height = GetRenderHeight(); - Vector2 result = {0, 0}; - if (b->position.x + b->radius > width / 2) { - result.x = -1; - } else if (b->position.x - b->radius < -width / 2) { - result.x = 1; - } - - if (b->position.y + b->radius > height / 2) { - result.y = -1; - } else if (b->position.y - b->radius < -height / 2) { - result.y = 1; - } - - if (result.x == 0 && result.y == 0) { - return NULL_VEC2; - } - - return vec2_normalize(result); -} - void collide(mass_body_t *a, mass_body_t *b, const Vector2 *normal, float resitution) { float inverse_a = 1.0f / a->mass; @@ -91,12 +68,29 @@ void collide(mass_body_t *a, mass_body_t *b, const Vector2 *normal, b->speed = vec2_sum(&b->speed, &b_diff); } -void collide_rigid(mass_body_t *a, const Vector2 *normal, float restitution) { +void collide_rigid(mass_body_t *a, float restitution) { + float max_x = GetRenderWidth() / 2.0f - a->radius; + float max_y = GetRenderHeight() / 2.0f - a->radius; - float v_normal = vec2_dot(&a->speed, normal); + if (a->position.x > max_x) { + a->position.x = max_x; + if (a->speed.x > 0) + a->speed.x *= -restitution; + } else if (a->position.x < -max_x) { + a->position.x = -max_x; + if (a->speed.x < 0) + a->speed.x *= -restitution; + } - Vector2 delta_v = vec2_scale(normal, -(1.0 + restitution) * v_normal); - a->speed = vec2_sum(&a->speed, &delta_v); + if (a->position.y > max_y) { + a->position.y = max_y; + if (a->speed.y > 0) + a->speed.y *= -restitution; + } else if (a->position.y < -max_y) { + a->position.y = -max_y; + if (a->speed.y < 0) + a->speed.y *= -restitution; + } } bool vec2_is_null(Vector2 v) { @@ -129,15 +123,12 @@ void *physics(void *args) { body_2 = uni->bodies[y]; collision = body_collision(&body_1, &body_2); if (!vec2_is_null(collision)) { - collide(&body_1, &body_2, &collision, 0.99); + collide(&body_1, &body_2, &collision, 1.0); } uni->bodies[y] = body_2; } } - collision = edge_collision(&body_1); - if (!vec2_is_null(collision)) { - collide_rigid(&body_1, &collision, 1.0005); - } + collide_rigid(&body_1, 1.1); uni->bodies[i] = body_1; } ot = ct; @@ -163,16 +154,39 @@ int main(void) { const char *welcome_text = "Welcome to Fucked Physics!"; universe_t universe = {0, NULL}; universe.bodies = malloc(1024 * sizeof(mass_body_t)); - for (int i = 0; i < 100; i++) { - float radius = 12.0f + 8.0f / (i + 1); + universe.num_bodies = 0; + for (int slot = -1; slot < 32 * 20 && universe.num_bodies < 1024; slot++) { + float radius = 12.0f + 8.0f / (universe.num_bodies + 1); + float x = slot < 0 + ? 0.0f + : -387.5f + 25.0f * (slot % 32) + (slot / 32 % 2) * 12.5f; + float y = slot < 0 ? 0.0f : -209.0f + 22.0f * (slot / 32); + if (fabsf(x) + radius > 400.0f || fabsf(y) + radius > 225.0f) { + continue; + } + + bool overlaps = false; + for (unsigned int j = 0; j < universe.num_bodies; j++) { + float dx = x - universe.bodies[j].position.x; + float dy = y - universe.bodies[j].position.y; + float min_distance = radius + universe.bodies[j].radius; + if (dx * dx + dy * dy <= min_distance * min_distance) { + overlaps = true; + break; + } + } + if (overlaps) { + continue; + } + + unsigned int i = universe.num_bodies++; universe.bodies[i] = (mass_body_t){ radius, radius, - {-360.0f + 80.0f * (i % 10), -202.5f + 45.0f * (i / 10)}, + {x, y}, {-0.1f, 0.8f - i * 0.005f}, }; } - universe.num_bodies = 100; SetConfigFlags(FLAG_WINDOW_RESIZABLE); InitWindow(800, 450, "Fucked Physics"); SetTargetFPS(120);