global_settings: Sim_Settings;
generate_random_settings :: (settings: ^Sim_Settings) {
- settings.body_count = 4000;
+ settings.body_count = 1200;
num_body_types :: 4;
settings.body_type_count = num_body_types;
settings.body_color[0] = .{ 1.0, 0.0, 0.0 };
settings.body_color[1] = .{ 0.0, 1.0, 0.0 };
settings.body_color[2] = .{ 0.0, 0.0, 1.0 };
- settings.body_color[3] = .{ 1.0, 1.0, 1.0 };
+ settings.body_color[3] = .{ 0.1, 0.1, 0.1 };
memory.alloc_slice(^settings.body_mass_range, num_body_types);
settings.body_mass_range[0] = .{ 4.0, 6.0 };
settings.body_mass_range[1] = .{ 4.0, 6.0 };
- settings.body_mass_range[2] = .{ 4.0, 6.0 };
- settings.body_mass_range[3] = .{ 4.0, 6.0 };
+ settings.body_mass_range[2] = .{ 4.0, 10.0 };
+ settings.body_mass_range[3] = .{ 4.0, 10.0 };
settings.friction = 6;
settings.near_repulsive_force = 100;
settings.universe_scale = 20;
- settings.thread_count = 4;
+ settings.thread_count = 3;
memory.alloc_slice(^settings.body_relations, num_body_types * num_body_types);
for i: num_body_types {
return vao;
}
-paused := false;
+paused := true;
handle_event :: (ev) => {
switch ev.kind {
case .KeyDown {
case .KeyUp {
if ev.keyboard.keycode == #char "P" do paused = !paused;
+ if ev.keyboard.keycode == #char " " do generate_random_settings(^global_settings);
+
keys->remove(ev.keyboard.keycode);
}
while true {
if thread_id == 0 {
- state.qt_bodies->init(.{ -2000, -2000, 4000, 4000 });
+ state.qt_bodies->init(.{ -5000, -5000, 10000, 10000 });
state.qt_pool_allocator = alloc.pool.make(state.qt_pool_buffer);
for ^it: state.bodies {
}
draw :: () {
+ frame_sync_sema.counter = 0;
+
gl.bindBuffer(gl.ARRAY_BUFFER, body_buffer);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, .{ ~~state.bodies.data, state.bodies.count * sizeof Body });
gl.bindBuffer(gl.ARRAY_BUFFER, -1);
camera_mat_loc := gl.getUniformLocation(body_program, "u_camera");
gl.uniformMatrix4(camera_mat_loc, false, camera_mat.data);
- gl.clearColor(.1, .1, .1, 1);
+ gl.clearColor(1, 1, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.bindVertexArray(circle_mesh);
gl.drawElementsInstanced(gl.TRIANGLE_FAN, 12, gl.UNSIGNED_BYTE, 0, state.bodies.count);
gl.bindVertexArray(-1);
+ draw_correlation_matrix();
+
sync.semaphore_post(^frame_sync_sema, 0 if paused else global_settings.thread_count);
}
+draw_correlation_matrix :: () {
+ gfx.set_texture();
+ gfx.rect(.{ 0, 0 }, .{ 256, 256 }, .{ 0, 0, 0 });
+
+ heading_size := 20.0f;
+ portion := (256.0f - heading_size) / ~~global_settings.body_type_count;
+
+ for i: global_settings.body_type_count {
+ col := to_col4(global_settings.body_color[i]);
+ gfx.rect(.{ heading_size + ~~i * portion, 0 }, .{ portion, heading_size }, col);
+ gfx.rect(.{ 0, heading_size + ~~i * portion }, .{ heading_size, portion }, col);
+ }
+
+ for row: global_settings.body_type_count do for col: global_settings.body_type_count {
+ color := gfx.Color4.{ 0, 0, 0 };
+
+ br := ^global_settings.body_relations[row * global_settings.body_type_count + col];
+ if br.max_force < 0 {
+ color.b = -br.max_force / 200;
+ } else {
+ color.r = br.max_force / 200;
+ }
+
+ gfx.rect(.{ heading_size + ~~col * portion, heading_size + ~~row * portion }, .{ portion, portion }, color);
+ }
+
+ gfx.flush();
+
+ to_col4 :: macro (x: $T) => gfx.Color4.{ x.r, x.g, x.b };
+}
+
main :: (args) => {
ouit.init("main_canvas", handle_event, update, draw);
+ time_now :: () -> i32 #foreign "ouit" "time_now" ---
+ random.set_seed(time_now());
+
generate_random_settings(^global_settings);
+ gl.enable(gl.BLEND);
+ gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
+
circle_mesh = create_circle_mesh();
body_vert_shader, _ := gfx.compile_shader(#file_contents "res/body_vertex.glsl", gl.VERTEX_SHADER);