]> git.lizzy.rs Git - nothing.git/commitdiff
(#647) Improve impulse resolution
authorrexim <reximkut@gmail.com>
Sun, 20 Jan 2019 17:03:03 +0000 (00:03 +0700)
committerrexim <reximkut@gmail.com>
Sun, 20 Jan 2019 17:03:03 +0000 (00:03 +0700)
src/game/level/platforms.c
src/game/level/platforms.h
src/game/level/rigid_bodies.c
src/math/rect.c
src/math/rect.h

index 3fd99661889a5cede28ef3b373f5112c4c05e977..71ac5cd3508f7cd96a03b8e271e95d9f5c30c130 100644 (file)
@@ -143,3 +143,17 @@ void platforms_touches_rect_sides(const Platforms *platforms,
         rect_object_impact(object, platforms->rects[i], sides);
     }
 }
         rect_object_impact(object, platforms->rects[i], sides);
     }
 }
+
+Rect platforms_snap_rect(const Platforms *platforms,
+                         Rect object)
+{
+    trace_assert(platforms);
+
+    for (size_t i = 0; i < platforms->rects_size; ++i) {
+        if (rects_overlap(platforms->rects[i], object)) {
+            object = rect_snap(platforms->rects[i], object);
+        }
+    }
+
+    return object;
+}
index 78d505c1c893ed0ea878f3e656af06a808278f03..adfbc603072ab6418561f5112172d3b31f357573 100644 (file)
@@ -24,5 +24,7 @@ int platforms_render(const Platforms *platforms,
 void platforms_touches_rect_sides(const Platforms *platforms,
                                   Rect object,
                                   int sides[RECT_SIDE_N]);
 void platforms_touches_rect_sides(const Platforms *platforms,
                                   Rect object,
                                   int sides[RECT_SIDE_N]);
+Rect platforms_snap_rect(const Platforms *platforms,
+                         Rect object);
 
 #endif  // PLATFORMS_H_
 
 #endif  // PLATFORMS_H_
index 1ccc18b56c7c8126d3db60f16014e129b138d5a5..e26d10080cbe87d176280bb68cb8fa694efbd85e 100644 (file)
@@ -130,7 +130,9 @@ int rigid_bodies_collide_with_platforms(
     for (size_t i = 0; i < rigid_bodies->count; ++i) {
         memset(sides, 0, sizeof(int) * RECT_SIDE_N);
 
     for (size_t i = 0; i < rigid_bodies->count; ++i) {
         memset(sides, 0, sizeof(int) * RECT_SIDE_N);
 
-        platforms_touches_rect_sides(platforms, rigid_bodies_hitbox(rigid_bodies, i), sides);
+        Rect hitbox = rigid_bodies_hitbox(rigid_bodies, i);
+
+        platforms_touches_rect_sides(platforms, hitbox, sides);
 
         if (sides[RECT_SIDE_BOTTOM]) {
             rigid_bodies->grounded[i] = true;
 
         if (sides[RECT_SIDE_BOTTOM]) {
             rigid_bodies->grounded[i] = true;
@@ -170,17 +172,9 @@ int rigid_bodies_collide_with_platforms(
             }
         }
 
             }
         }
 
-        for (int j = 0; j < 1000 && vec_length(opforce_direction) > 1e-6; ++j) {
-            rigid_bodies->positions[i] = vec_sum(
-                rigid_bodies->positions[i],
-                vec_scala_mult(
-                    opforce_direction,
-                    1e-2f));
-
-            memset(sides, 0, sizeof(int) * RECT_SIDE_N);
-            platforms_touches_rect_sides(platforms, rigid_bodies_hitbox(rigid_bodies, i), sides);
-            opforce_direction = opposing_force_by_sides(sides);
-        }
+        hitbox = platforms_snap_rect(platforms, hitbox);
+        rigid_bodies->positions[i].x = hitbox.x;
+        rigid_bodies->positions[i].y = hitbox.y;
     }
 
     return 0;
     }
 
     return 0;
index ba5fc9e8c192b974858eacc921fd96e23f3b5c6c..898eb3a0e93484fb327835c60f3afc4bf0b1c212 100644 (file)
@@ -158,3 +158,29 @@ SDL_Rect rect_for_sdl(Rect rect)
 
     return result;
 }
 
     return result;
 }
+
+Vec rect_center(Rect rect)
+{
+    return vec(rect.x + rect.w * 0.5f,
+               rect.y + rect.h * 0.5f);
+}
+
+static float signf(float x)
+{
+    return (float)((0.0f < x) - (x < 0.0f));
+}
+
+Rect rect_snap(Rect pivot, Rect r)
+{
+    const Vec pivot_c = rect_center(pivot);
+    const Vec r_c = rect_center(r);
+
+    const float x = pivot_c.x + signf(r_c.x - pivot_c.x) * (pivot.w + r.w) * 0.5f - r.w * 0.5f;
+    const float y = pivot_c.y + signf(r_c.y - pivot_c.y) * (pivot.h + r.h) * 0.5f - r.h * 0.5f;
+
+    if (fabsf(x - r_c.x) < fabsf(y - r_c.y)) {
+        return rect(x, r.y, r.w, r.h);
+    } else {
+        return rect(r.x, y, r.w, r.h);
+    }
+}
index 1dd14152abdf5e40291573bcf20f293fc442433a..a8aeb3014da72a9e227dc0f450ace0024490e3c7 100644 (file)
@@ -45,4 +45,8 @@ float line_length(Line line);
 
 SDL_Rect rect_for_sdl(Rect rect);
 
 
 SDL_Rect rect_for_sdl(Rect rect);
 
+Vec rect_center(Rect rect);
+
+Rect rect_snap(Rect pivot, Rect rect);
+
 #endif  // RECT_H_
 #endif  // RECT_H_