diff --git a/circledemo.jai b/circledemo.jai new file mode 100644 index 0000000..e067e43 --- /dev/null +++ b/circledemo.jai @@ -0,0 +1,6 @@ +#import "Basic"; +#import "Math"; +#import,file "testkit.jai"; +#import,file "physics.jai"; + +main :: () diff --git a/physics.jai b/physics.jai index 4d6bb00..e3c64cf 100644 --- a/physics.jai +++ b/physics.jai @@ -1,6 +1,6 @@ #import "Basic"; #import "Math"; -#import "testkit.jai"; +#import,file "testkit.jai"; TIMESTEP: float = 1.0 / 60.0; DEBUGGING :: true; @@ -17,6 +17,17 @@ normalize :: (using v: *Vector2) -> float { 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); return v; @@ -35,12 +46,6 @@ negative :: (v: Vector2) -> Vector2 #must { cross :: (a: Vector2, b: Vector2) -> float { 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 { return .{0, -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; 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 = .{3.0, 0.0}, shape = .{type = .Circle, radius = 1.0}, elasticity = 0.3}); + unprocessed_time: float = 0.0; while !quit { + frame_start(); + defer frame_end(); // process physics unprocessed_time += dt; { @@ -244,28 +253,29 @@ main :: () { } 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 { d: DrawingSettings = .{true, GREEN}; if hovering == it { 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); } for Input.events_this_frame { if it.type == { + case .KEYBOARD; if it.key_code == .MOUSE_BUTTON_LEFT { 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(); } diff --git a/testkit.jai b/testkit.jai index 25aa591..4d854a7 100644 --- a/testkit.jai +++ b/testkit.jai @@ -1,36 +1,50 @@ - #import "Window_Creation"; Debug :: #import "Debug"; Simp :: #import "Simp"; Input :: #import "Input"; +#import "Math"; +#import "Basic"; Camera :: struct { pos: Vector2; zoom: float = 1.0; }; -window: Window; +window: Window_Type; quit: bool; +dt: float; panning: bool = false; camera : Camera; mouse_frozen: bool; mouse_frozen_at: Vector2; +last_time: float64; +last_mouse_pos: Vector2; -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); -} window_width : s32 = 1280; window_height : s32 = 720; dbgprint :: print; // so can be detected and removed +#scope_file; +normalize :: (using v: *Vector2) -> float { + sq := sqrt(x*x + y*y); + + factor := 1.0 / sq; + x *= factor; + y *= factor; + + return sq; +} +normalize :: (v: Vector2) -> Vector2 #must { + normalize(*v); + return v; +} +xy :: (x: int, y: int) -> Vector2 { + return xy(cast(float)x, cast(float)y); +} +#scope_export; + WHITE :: Vector4.{1.0, 1.0, 1.0, 1.0}; RED :: Vector4.{1.0, 0.0, 0.0, 1.0}; GREEN :: Vector4.{0.0, 1.0, 0.0, 1.0}; @@ -61,6 +75,12 @@ vector :: (d: DrawingSettings, from: Vector2, vector: Vector2) { line(d, from + vector, from + vector + rotate(normalize(vector)*arrow_head_length, -PI/2.0 + -PI/4.0)); } +LastingPip :: struct { + alive_for: float; + pos: Vector2; + d: DrawingSettings; +}; + pips : [10] LastingPip; push_pip :: (d: DrawingSettings, at: Vector2) { for * pips @@ -127,20 +147,17 @@ mouse_screen :: () -> Vector2 { return pos; } mouse_world :: () -> Vector2 { - return screen_to_world(mouse()); + return screen_to_world(mouse_screen()); } // query quit to see if should quit. Call this in a loop frame_start :: () { - last_time := get_time(); - last_mouse_pos := mouse(); - unprocessed_time: float = 0.0; - dt := cast(float)(get_time() - last_time); + dt = cast(float)(get_time() - last_time); last_time = get_time(); Input.update_window_events(); - mouse_delta := mouse() - last_mouse_pos; // using Input.mouse_delta_x seems to incorrectly accumulate - last_mouse_pos = mouse(); + mouse_delta := mouse_screen() - last_mouse_pos; // using Input.mouse_delta_x seems to incorrectly accumulate + last_mouse_pos = mouse_screen(); for Input.get_window_resizes() { Simp.update_window(it.window); // Simp will do nothing if it doesn't care about this window. @@ -194,7 +211,7 @@ frame_start :: () { quit = true; case #char "T"; - if !mouse_frozen mouse_frozen_at = mouse(); + if !mouse_frozen mouse_frozen_at = mouse_screen(); mouse_frozen = !mouse_frozen; } }