|
|
@ -1,6 +1,6 @@
|
|
|
|
#import "Basic";
|
|
|
|
#import "Basic";
|
|
|
|
#import "Math";
|
|
|
|
#import "Math";
|
|
|
|
#import "testkit.jai";
|
|
|
|
#import,file "testkit.jai";
|
|
|
|
|
|
|
|
|
|
|
|
TIMESTEP: float = 1.0 / 60.0;
|
|
|
|
TIMESTEP: float = 1.0 / 60.0;
|
|
|
|
DEBUGGING :: true;
|
|
|
|
DEBUGGING :: true;
|
|
|
@ -17,6 +17,17 @@ normalize :: (using v: *Vector2) -> float {
|
|
|
|
|
|
|
|
|
|
|
|
return sq;
|
|
|
|
return sq;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local_to_world :: (using b: Body, local_point: Vector2) -> Vector2 {
|
|
|
|
|
|
|
|
return rotate(local_point, angle) + pos;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
world_to_local :: (using b: Body, world_point: Vector2) -> Vector2 {
|
|
|
|
|
|
|
|
// world = rotate(local, angle) + pos
|
|
|
|
|
|
|
|
// world - pos = rotate(local, angle)
|
|
|
|
|
|
|
|
// rotate(world - pos, -angle) = local
|
|
|
|
|
|
|
|
return rotate(world_point - pos, -angle);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
normalize :: (v: Vector2) -> Vector2 #must {
|
|
|
|
normalize :: (v: Vector2) -> Vector2 #must {
|
|
|
|
normalize(*v);
|
|
|
|
normalize(*v);
|
|
|
|
return v;
|
|
|
|
return v;
|
|
|
@ -35,12 +46,6 @@ negative :: (v: Vector2) -> Vector2 #must {
|
|
|
|
cross :: (a: Vector2, b: Vector2) -> float {
|
|
|
|
cross :: (a: Vector2, b: Vector2) -> float {
|
|
|
|
return a.x * b.y - a.y * b.x;
|
|
|
|
return a.x * b.y - a.y * b.x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
LastingPip :: struct {
|
|
|
|
|
|
|
|
alive_for: float;
|
|
|
|
|
|
|
|
pos: Vector2;
|
|
|
|
|
|
|
|
d: DrawingSettings;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hit_impulse :: (body_pos: Vector2, mouse_pos: Vector2) -> Vector2 {
|
|
|
|
hit_impulse :: (body_pos: Vector2, mouse_pos: Vector2) -> Vector2 {
|
|
|
|
return .{0, -15.0};
|
|
|
|
return .{0, -15.0};
|
|
|
|
//return normalize(body_pos - mouse_pos) * 15.0;
|
|
|
|
//return normalize(body_pos - mouse_pos) * 15.0;
|
|
|
@ -184,14 +189,18 @@ draw_body :: (d: DrawingSettings, using b: Body) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
circledemo :: () {
|
|
|
|
|
|
|
|
init();
|
|
|
|
|
|
|
|
|
|
|
|
main :: () {
|
|
|
|
|
|
|
|
bodies: [..]Body;
|
|
|
|
bodies: [..]Body;
|
|
|
|
array_add(*bodies, .{pos = .{0.0, 0.0}, shape = .{type = .Circle, radius = 1.0}, elasticity = 0.5});
|
|
|
|
array_add(*bodies, .{pos = .{0.0, 0.0}, shape = .{type = .Circle, radius = 1.0}, elasticity = 0.5});
|
|
|
|
array_add(*bodies, .{pos = .{0.0, -1003.0}, shape = .{type = .Circle, radius = 1000.0, invmass = 0.0}, elasticity = 1.0}); // ground sphere
|
|
|
|
array_add(*bodies, .{pos = .{0.0, -1003.0}, shape = .{type = .Circle, radius = 1000.0, invmass = 0.0}, elasticity = 1.0}); // ground sphere
|
|
|
|
array_add(*bodies, .{pos = .{3.0, 0.0}, shape = .{type = .Circle, radius = 1.0}, elasticity = 0.3});
|
|
|
|
array_add(*bodies, .{pos = .{3.0, 0.0}, shape = .{type = .Circle, radius = 1.0}, elasticity = 0.3});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unprocessed_time: float = 0.0;
|
|
|
|
while !quit {
|
|
|
|
while !quit {
|
|
|
|
|
|
|
|
frame_start();
|
|
|
|
|
|
|
|
defer frame_end();
|
|
|
|
// process physics
|
|
|
|
// process physics
|
|
|
|
unprocessed_time += dt;
|
|
|
|
unprocessed_time += dt;
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -244,28 +253,29 @@ main :: () {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
b := bodies[0];
|
|
|
|
b := bodies[0];
|
|
|
|
pip(.{}, local_to_world(b, world_to_local(b, mouse())));
|
|
|
|
pip(.{}, local_to_world(b, world_to_local(b, mouse_screen())));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hovering: *Body = point_query(bodies, screen_to_world(mouse()));
|
|
|
|
hovering: *Body = point_query(bodies, screen_to_world(mouse_screen()));
|
|
|
|
for * bodies {
|
|
|
|
for * bodies {
|
|
|
|
d: DrawingSettings = .{true, GREEN};
|
|
|
|
d: DrawingSettings = .{true, GREEN};
|
|
|
|
if hovering == it {
|
|
|
|
if hovering == it {
|
|
|
|
d.color = RED;
|
|
|
|
d.color = RED;
|
|
|
|
vector(d, screen_to_world(mouse()), hit_impulse(it.pos, screen_to_world(mouse())) * TIMESTEP);
|
|
|
|
vector(d, screen_to_world(mouse_screen()), hit_impulse(it.pos, screen_to_world(mouse_screen())) * TIMESTEP);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
draw_body(d, it);
|
|
|
|
draw_body(d, it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for Input.events_this_frame {
|
|
|
|
for Input.events_this_frame {
|
|
|
|
if it.type == {
|
|
|
|
if it.type == {
|
|
|
|
|
|
|
|
case .KEYBOARD;
|
|
|
|
if it.key_code == .MOUSE_BUTTON_LEFT {
|
|
|
|
if it.key_code == .MOUSE_BUTTON_LEFT {
|
|
|
|
panning = cast(bool)it.key_pressed;
|
|
|
|
panning = cast(bool)it.key_pressed;
|
|
|
|
to_tap := point_query(bodies, screen_to_world(mouse()));
|
|
|
|
to_tap := point_query(bodies, screen_to_world(mouse_screen()));
|
|
|
|
|
|
|
|
if to_tap != null apply_impulse(to_tap, mouse_world(), hit_impulse(to_tap.pos, mouse_screen()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
main :: () { circledemo(); }
|
|
|
|