You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
7.6 KiB
Plaintext

#import "Basic";
#import "Math";
#import "Window_Creation";
Input :: #import "Input";
Simp :: #import "Simp";
2 years ago
TIMESTEP: float = 1.0 / 60.0;
window_width : s32 = 1280;
window_height : s32 = 720;
xy :: (x: int, y: int) -> Vector2 {
return xy(cast(float)x, cast(float)y);
}
drawing_in_world_space: bool = false;
2 years ago
WHITE :: Vector4.{1.0, 1.0, 1.0, 1.0};
GREEN :: Vector4.{0.0, 1.0, 0.0, 1.0};
drawing_color: Vector4 = WHITE;
line_thickness: float = 1.0;
line :: (_from: Vector2, _to: Vector2) {
width := line_thickness;
from := _from;
to := _to;
if drawing_in_world_space {
from = world_to_screen(from);
to = world_to_screen(to);
}
Simp.set_shader_for_color();
normal := rotate(unit_vector(to - from), PI/2.0);
2 years ago
Simp.immediate_quad(from + normal*width, from - normal*width, to + normal*width, to - normal*width, color = drawing_color);
}
Rect :: struct {
2 years ago
halfsize: Vector2;
pos , vel , force : Vector2; // pos is in world space
angle, angle_vel, torque: float;
};
2 years ago
MASS :: 1.0;
moment_of_inertia :: (using r: Rect) -> float {
return MASS*(halfsize.y*halfsize.y + halfsize.x*halfsize.x)/12.0;
}
apply_force_at_point :: (r: *Rect, force: Vector2, point_world_space: Vector2) {
r.force += force;
offset_from_center_of_mass := point_world_space - r.pos;
r.torque += offset_from_center_of_mass.x * force.y - offset_from_center_of_mass.y * force.x;
}
Manifold :: struct {
count: int;
depths: [2] float;
contact_points: [2] Vector2;
normal: Vector2;
};
MAX_POLYGON_VERTS :: 8;
Polygon :: struct {
count: int;
verts: [MAX_POLYGON_VERTS] Vector2;
norms: [MAX_POLYGON_VERTS] Vector2;
};
// a halfspace (aka plane, aka line)
Halfspace :: struct {
n: Vector2;
d: float;
}
poly_from :: (using r: Rect) -> Polygon {
to_return: Polygon;
facing_to_right := rotate(xy(halfsize.x,0.0), angle);
facing_to_up := rotate(xy(0.0,halfsize.y), angle);
to_return.count = 4;
to_return.verts[0] = -facing_to_right + facing_up; // upper left
to_return.norms[0] = #run normalize(xy(-1.0, 1.0));
to_return.verts[1] = facing_to_right + facing_up; // upper right
to_return.norms[1] = #run normalize(xy(1.0, 1.0));
to_return.verts[2] = facing_to_right + -facing_up; // lower right
to_return.norms[2] = #run normalize(xy(1.0, -1.0));
to_return.verts[3] = -facing_to_right + -facing_up; // lower left
to_return.norms[3] = #run normalize(xy(-1.0, -1.0));
return to_return;
}
rect_to_rect :: (a: Rect, b: Rect) -> Manifold {
to_return : Manifold;
check_faces :: (a: Polygon, b: Polygon) -> float {
plane_at :: (p : Polygon, i: int) -> Halfspace {
return .{n = p.norms[i], d = dot(p.norms[i], p.verts[i]};
}
support :: (verts: [] Vector2, d: Vector2 {
}
sep : float = FLT_MAX;
index: int = ~0;
for 0..a.count-1 {
h := plane_at(a, i);
idx :=
}
}
}
draw_rect :: (using r: Rect) {
2 years ago
facing_to_right := rotate(xy(halfsize.x,0.0), angle);
facing_to_up := rotate(xy(0.0,halfsize.y), angle);
upper_right := pos + facing_to_right + facing_to_up;
upper_left := pos - facing_to_right + facing_to_up;
lower_left := pos - facing_to_right - facing_to_up;
lower_right := pos + facing_to_right - facing_to_up;
line(upper_left, upper_right);
line(upper_right, lower_right);
line(lower_right, lower_left);
line(lower_left, upper_left);
}
mouse :: () -> Vector2 {
x, y := get_mouse_pointer_position();
pos: Vector2 = xy(cast(float)x, cast(float)y);
// simp is lower left is (0, 0) and y+ is up
pos.y = window_height - pos.y;
return pos;
}
Camera :: struct {
pos: Vector2;
zoom: float = 1.0;
};
camera : Camera;
screen_to_world :: (screen: Vector2) -> Vector2 {
using camera;
return (screen + pos)*zoom;
}
world_to_screen :: (world: Vector2) -> Vector2 {
using camera;
// world = (screen + pos)*zoom;
// world/zoom = screen + pos;
// world/zoom - pos = screen;
return (world/zoom) - pos;
}
main :: () {
window := create_window(window_width, window_height, "A Window");
// Actual render size in pixels can be different from the window dimensions we specified above (for example on high-resolution displays on macOS/iOS).
window_width, window_height = Simp.get_render_dimensions(window);
2 years ago
camera.pos = -xy(window_width, window_height)/2.0;
camera.zoom = 0.01;
Simp.set_render_target(window);
rects: [..]Rect;
2 years ago
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)});
2 years ago
quit := false;
last_time := get_time();
panning: bool = false;
last_mouse_pos := mouse();
2 years ago
unprocessed_time: float = 0.0;
while !quit {
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();
for Input.get_window_resizes() {
Simp.update_window(it.window); // Simp will do nothing if it doesn't care about this window.
if it.window == window {
should_reinit := (it.width != window_width) || (it.height != window_height);
window_width = it.width;
window_height = it.height;
//if should_reinit my_init_fonts(); // Resize the font for the new window size.
}
}
camera.zoom *= 1.0 - 0.1*Input.mouse_delta_z/120.0;
if panning {
camera.pos -= mouse_delta;
// this doesn't fix it
//Input.mouse_delta_x = 0;
//Input.mouse_delta_y = 0;
}
2 years ago
// process physics
unprocessed_time += dt;
{
dt: string = "do not use";
while unprocessed_time > TIMESTEP
{
defer unprocessed_time -= TIMESTEP;
if get_time() < 0.5
{
apply_force_at_point(*rects[0], xy(3, 0), rects[0].pos + xy(-0.1, 0.03));
}
for * rects
{
defer { it.force = .{}; it.torque = 0.0; };
it.vel += (it.force/MASS) * TIMESTEP;
it.pos += it.vel * TIMESTEP;
it.angle_vel += (it.torque / moment_of_inertia(it)) * TIMESTEP;
it.angle += it.angle_vel * TIMESTEP;
}
2 years ago
}
}
Simp.clear_render_target(0.0, 0.0, 0.0, 1.0);
drawing_in_world_space = true;
2 years ago
// draw grid
drawing_color = .{0.2, 0.2, 0.2, 0.2};
for x: -30..30 {
line(xy(x, 30), xy(x, -30));
}
for y: -30..30 {
line(xy(30, y), xy(-30, y));
}
drawing_color = WHITE;
line_thickness = 2.0;
drawing_color = GREEN;
for rects draw_rect(it);
2 years ago
line_thickness = 1.0;
drawing_color = WHITE;
//line(xy(0.0, 0.0), screen_to_world(mouse()));
drawing_in_world_space = false;
Simp.swap_buffers(window);
for Input.events_this_frame {
if it.type == .QUIT then quit = true;
if it.type == {
case .KEYBOARD;
if it.key_pressed && it.key_code == .ESCAPE {
quit = true;
}
if it.key_code == .MOUSE_BUTTON_LEFT {
panning = cast(bool)it.key_pressed;
}
}
}
}
}