moving bodies with physics-ish
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 23 Oct 2020 01:41:38 +0000 (20:41 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 23 Oct 2020 01:41:38 +0000 (20:41 -0500)
include/container.h
include/physics.h
src/physics.cpp
src/sim.cpp

index 3fdaa6b798d6dea3584a5325c094ec3412885a97..18bd5b3dcacb4365c41ec3e8189370724311827a 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "types.h"
 #include <assert.h>
+#include <stdlib.h>
 
 template <typename T>
 struct Array
index 881dfa4e91177fa59d428700e8353e6a25e58c30..3c77e6c0c1dc5dcc6185c133975fc4e5eddeac9a 100644 (file)
@@ -2,13 +2,19 @@
 #define PHYSICS_H
 
 #include <vecmath.h>
+#include "container.h"
 
 struct Body
 {
     V2f pos;
     V2f vel;
     
+    V2f post_update_vel;
+    
     f32 mass;
 };
 
+void body_calculate_move(Body* body, const Array<Body> other_bodies, f64 dt);
+void body_apply_move(Body* body);
+
 #endif //PHYSICS_H
\ No newline at end of file
index 90ca46c1bb119dbb5af50e383d6044b1b9e96554..1fae686c63b9575d17c47ca17179c88727965a4e 100644 (file)
@@ -2,3 +2,45 @@
 #include "utils.h"
 #include "types.h"
 
+internal bool
+bodies_collide(Body* b1, Body* b2)
+{
+    const f32 dist_2 = v2f_smag(b1->pos - b2->pos);
+    const f32 radii_sum_2 = (b1->mass + b2->mass) * (b1->mass + b2->mass);
+    return dist_2 < radii_sum_2;
+}
+
+// NOTE(Brendan): Leaves body unmodified, returns if the body can move along the specified vector.
+internal bool
+body_can_move(Body* body, const Array<Body> other_bodies, V2f d)
+{
+    // HACK(Brendan): There should be a way to not have to move the body to test collisions with it.
+    body->pos += d;
+    defer { body->pos -= d; };
+    
+    For (other_bodies)
+    {
+        if (body == &it) continue;
+        if (bodies_collide(body, &it)) return false;
+    }
+    
+    return true;
+}
+
+void
+body_calculate_move(Body* body, const Array<Body> other_bodies, f64 dt)
+{
+    body->post_update_vel = V2f { 0.0f, 0.0f, };
+    
+    if (body_can_move(body, other_bodies, V2f { (f32) (body->vel.x * dt), 0.0f }))
+        body->post_update_vel.x += body->vel.x * dt;
+    
+    if (body_can_move(body, other_bodies, V2f { 0.0f, (f32) (body->vel.y * dt) }))
+        body->post_update_vel.y += body->vel.y * dt;
+}
+
+void
+body_apply_move(Body* body)
+{
+    body->pos += body->post_update_vel;
+}
\ No newline at end of file
index 1d81471c5a314312c5f4fb6d662d58abc9d61cd8..f2ba13119a2f8bb568b0ae19e11b468e19404a5d 100644 (file)
@@ -167,8 +167,8 @@ create_circle_mesh()
     foreach (i, 0, CIRCLE_POINT_COUNT)
     {
         f32 t = (f32) i / (f32) CIRCLE_POINT_COUNT;
-        circle_points[i].x = cos(t * 2 * PI) / 2.0f;
-        circle_points[i].y = sin(t * 2 * PI) / 2.0f;
+        circle_points[i].x = cos(t * 2 * PI);
+        circle_points[i].y = sin(t * 2 * PI);
     }
     
     GLuint vertex_buffer;
@@ -198,7 +198,17 @@ update(SimState* state, f64 dt)
 {
     For (state->bodies)
     {
-        it.pos += it.vel * dt;
+        if (rand() % 50 == 0)
+        {
+            it.vel = V2f{ randf(-50.0f, 50.0f), randf(-50.0f, 50.0f) };
+        }
+        
+        body_calculate_move(&it, state->bodies, dt);
+    }
+    
+    For (state->bodies)
+    {
+        body_apply_move(&it);
     }
 }
 
@@ -280,7 +290,7 @@ main(i32 argc, char* argv[])
         Body tmp_body;
         tmp_body.pos = V2f{ randf(0, 800), randf(0, 800) };
         tmp_body.vel = V2f{ randf(-50.0f, 50.0f), randf(-50.0f, 50.0f) };
-        tmp_body.mass = randf(10.0f, 50.0f);
+        tmp_body.mass = randf(5.0f, 25.0f);
         state->bodies.push(tmp_body);
     }