Scuffed momentum

main
Cameron Murphy Reikes 2 years ago
parent a42b9a19bd
commit 7c6766e874

@ -94,6 +94,7 @@ Rect :: struct {
halfsize: Vector2; halfsize: Vector2;
pos , vel , force : Vector2; // pos is in world space pos , vel , force : Vector2; // pos is in world space
angle, angle_vel, torque: float; angle, angle_vel, torque: float;
static: bool;
mass: float = 1.0; mass: float = 1.0;
}; };
moment_of_inertia :: (using r: Rect) -> float { moment_of_inertia :: (using r: Rect) -> float {
@ -106,6 +107,7 @@ apply_force_at_point :: (r: *Rect, force: Vector2, point_world_space: Vector2) {
} }
// everything needed to resolve the collision // everything needed to resolve the collision
Manifold :: struct { Manifold :: struct {
a, b: *Rect;
count: int; count: int;
depths: [2] float; depths: [2] float;
contact_points: [2] Vector2; // in absolute coordinates contact_points: [2] Vector2; // in absolute coordinates
@ -119,9 +121,24 @@ perp :: (v: Vector2) -> Vector2
{ {
return xy(-v.y, v.x); return xy(-v.y, v.x);
} }
handle_collision :: (m: Manifold, a: Rect, b: Rect) { handle_collision :: (m: Manifold, dt: float) {
a := m.a;
b := m.b;
if m.count == 0 return; if m.count == 0 return;
k_scalar :: (a: Rectangle, b: Rectangle, r1: Vector2, r2: Vector2, n: Vector2) { for 0..m.count-1
{
total_momentum: float = length(a.vel) * a.mass + length(b.vel) * b.mass;
impulse_strength: float = 0.0;
//impulse_strength += m.depths[it] * 3.0;
impulse_strength += total_momentum / 2.0;
if a.static || b.static impulse_strength *= 2.0;
impulse := m.normal * impulse_strength;
apply_force_at_point(b, impulse / dt, m.contact_points[it]);
apply_force_at_point(a, -impulse / dt, m.contact_points[it]);
}
/*k_scalar :: (a: Rectangle, b: Rectangle, r1: Vector2, r2: Vector2, n: Vector2) {
k_scalar_rect :: (a: Rectangle, r: Vector2, n: Vector2) k_scalar_rect :: (a: Rectangle, r: Vector2, n: Vector2)
{ {
rcn := cross(r, n); rcn := cross(r, n);
@ -134,7 +151,7 @@ handle_collision :: (m: Manifold, a: Rect, b: Rect) {
} }
r1 := m.contact_points[0] - a.pos; r1 := m.contact_points[0] - a.pos;
r2 := m.contact_points[0] - b.pos; r2 := m.contact_points[0] - b.pos;
nMass := 1.0 / k_scalar(a, b, r1, r2, nMass := 1.0 / k_scalar(a, b, r1, r2, */
} }
MAX_POLYGON_VERTS :: 8; MAX_POLYGON_VERTS :: 8;
@ -232,7 +249,7 @@ check_faces :: (a: Polygon, b: Polygon) -> (separation: float, face_index: int)
return sep, index; return sep, index;
} }
rect_to_rect :: (a: Rect, b: Rect) -> Manifold { rect_to_rect :: (a: *Rect, b: *Rect) -> Manifold {
to_return : Manifold; to_return : Manifold;
poly_a := poly_from(a); poly_a := poly_from(a);
@ -361,6 +378,8 @@ rect_to_rect :: (a: Rect, b: Rect) -> Manifold {
for 0..m.count-1 { for 0..m.count-1 {
push_pip(m.contact_points[it]); push_pip(m.contact_points[it]);
} }
m.a = a;
m.b = b;
return m; return m;
} }
dump_polygon :: (poly: Polygon) { dump_polygon :: (poly: Polygon) {
@ -379,7 +398,7 @@ do_test :: () {
#if true { #if true {
print("A %\n", A_rect); print("A %\n", A_rect);
print("B %\n", B_rect); print("B %\n", B_rect);
print("Collision %\n", rect_to_rect(A_rect, B_rect)); print("Collision %\n", rect_to_rect(*A_rect, *B_rect));
} }
@ -488,7 +507,8 @@ main :: () {
rects: [..]Rect; rects: [..]Rect;
array_add(*rects, .{pos = #run xy(0.0, 0.0), halfsize = #run xy(0.3)}); array_add(*rects, .{pos = #run xy(0.0, 0.0), halfsize = #run xy(0.3)});
array_add(*rects, .{pos = #run xy(2.5, 0.0), halfsize = #run xy(0.3)}); array_add(*rects, .{pos = #run xy(2.5, 0.0), halfsize = #run xy(0.3)});
array_add(*rects, .{pos = #run xy(-2.5, 0.0), halfsize = #run xy(0.3)});
array_add(*rects, .{pos = #run xy(0.0, -3.0), halfsize = #run xy(3.0, 0.2), static = true});
quit := false; quit := false;
last_time := get_time(); last_time := get_time();
@ -536,29 +556,46 @@ main :: () {
{ {
apply_force_at_point(*rects[0], xy(3, 0), rects[0].pos + xy(-0.1, 0.03)); apply_force_at_point(*rects[0], xy(3, 0), rects[0].pos + xy(-0.1, 0.03));
} }
for * rects collisions: [..] Manifold;
{ defer array_free(collisions);
defer { it.force = .{}; it.torque = 0.0; }; for * from_rect: rects {
it.vel += (it.force/MASS) * TIMESTEP;
it.pos += it.vel * TIMESTEP;
from_rect := it;
for * to_rect: rects { for * to_rect: rects {
if to_rect != from_rect if to_rect != from_rect
{ {
manifold_out := rect_to_rect(from_rect, to_rect); manifold_out := rect_to_rect(from_rect, to_rect);
if manifold_out.count > 0 { if manifold_out.count > 0 {
handle_collision(manifold_out, from_rect, to_rect); unique := true;
//from_rect.vel *= -1.0; for collisions {
if (it.a == manifold_out.a && it.b == manifold_out.b) || (it.a == manifold_out.b && it.b == manifold_out.a) {
unique = false;
break;
} }
} }
if unique array_add(*collisions, manifold_out);
} }
}
}
}
for collisions {
handle_collision(it, TIMESTEP);
}
for * rects {
defer it.force = .{};
defer it.torque = 0.0;
// gravity
it.force.y += -9.81;
if !it.static
{
it.vel += (it.force/it.mass) * TIMESTEP;
it.pos += it.vel * TIMESTEP;
it.angle_vel += (it.torque / moment_of_inertia(it)) * TIMESTEP; it.angle_vel += (it.torque / moment_of_inertia(it)) * TIMESTEP;
it.angle += it.angle_vel * TIMESTEP; it.angle += it.angle_vel * TIMESTEP;
} }
} }
} }
}

Loading…
Cancel
Save