aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.zig8
-rw-r--r--src/imgui.zig68
-rw-r--r--src/main.zig34
-rw-r--r--src/particle.zig28
4 files changed, 114 insertions, 24 deletions
diff --git a/src/config.zig b/src/config.zig
index 1f72ad4..162f71c 100644
--- a/src/config.zig
+++ b/src/config.zig
@@ -1,11 +1,13 @@
const rl = @import("raylib");
+const part = @import("particle.zig");
pub const screenWidth = 2560;
pub const screenHeight = 1440;
pub const particleMax = 4000;
pub const initialParticles = 3000;
-pub const radius = 100.0;
-pub const minDistance = 20.0;
+pub var particleCount: i32 = initialParticles;
+pub var radius: f32 = 100.0;
+pub var minDistance: f32 = 20.0;
pub const colors = [_]rl.Color{
rl.Color.red,
rl.Color.green,
@@ -14,5 +16,7 @@ pub const colors = [_]rl.Color{
rl.Color.magenta,
rl.Color.brown,
rl.Color.orange,
+ rl.Color.gray,
};
pub const colorAmnt = colors.len;
+pub var rules: [colorAmnt][colorAmnt]f32 = undefined;
diff --git a/src/imgui.zig b/src/imgui.zig
new file mode 100644
index 0000000..fb9285d
--- /dev/null
+++ b/src/imgui.zig
@@ -0,0 +1,68 @@
+const std = @import("std");
+const rl = @import("raylib");
+const z = @import("zgui");
+const part = @import("particle.zig");
+const cfg = @import("config.zig");
+
+const c = @cImport({
+ @cDefine("NO_FONT_AWESOME", "1");
+ @cInclude("rlImGui.h");
+});
+
+pub fn update() !void {
+ c.rlImGuiBegin();
+ defer c.rlImGuiEnd();
+
+ z.setNextWindowCollapsed(.{ .collapsed = true, .cond = .first_use_ever });
+
+ _ = z.begin("Configuration", .{});
+ defer z.end();
+ if (z.collapsingHeader("General Settings", .{ .default_open = true })) {
+ if (z.button("Reset", .{})) {
+ cfg.particleCount = cfg.initialParticles;
+ cfg.radius = 100.0;
+ cfg.minDistance = 20.0;
+ }
+ _ = z.sliderInt("Particles", .{ .v = &cfg.particleCount, .min = 1, .max = cfg.particleMax });
+ _ = z.sliderFloat("Radius", .{ .v = &cfg.radius, .min = 1, .max = 500 });
+ _ = z.sliderFloat("Minimum Distance", .{ .v = &cfg.minDistance, .min = 1.0, .max = 100.0 });
+ }
+ if (z.collapsingHeader("Ruleset", .{ .default_open = true })) {
+ // comptime var string: [:0]const u8 = "";
+ // comptime for (0..cfg.colors.len) |cols| {
+ // string = string ++ part.colorToString(cols) ++ "\t\t\t\t\t";
+ // };
+ //
+ // z.text("{s:<}", .{string});
+ _ = z.beginTable("Rules", .{
+ .column = cfg.colorAmnt + 1,
+ .flags = .{},
+ .outer_size = .{ 0, 0 },
+ .inner_width = 0,
+ });
+ defer z.endTable();
+ _ = z.tableNextRow(.{});
+ _ = z.tableSetColumnIndex(0);
+ z.text("Rules", .{});
+ for (0..cfg.colorAmnt) |i| {
+ _ = z.tableNextColumn();
+ z.text("{s}", .{part.colorToString(i)});
+ }
+
+ for (&cfg.rules, 0..) |*row, i| {
+ _ = z.tableNextRow(.{});
+ _ = z.tableSetColumnIndex(0);
+ z.text("Row {}", .{i + 1});
+ _ = z.tableNextColumn();
+ for (row, 0..) |*cols, j| {
+ var id: [2:0]u8 = undefined;
+ id[0] = @intCast(i + 1);
+ id[1] = @intCast(j + 1);
+ _ = z.tableSetColumnIndex(@intCast(j + 1));
+ _ = z.pushItemWidth(z.getContentRegionAvail()[0]);
+ _ = z.inputFloat(&id, .{ .v = cols, .step = 0.001, .step_fast = 0.1 });
+ _ = z.popItemWidth();
+ }
+ }
+ }
+}
diff --git a/src/main.zig b/src/main.zig
index 47906e2..7d859fc 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -1,33 +1,49 @@
const std = @import("std");
const rl = @import("raylib");
+const z = @import("zgui");
const part = @import("particle.zig");
const cfg = @import("config.zig");
+const img = @import("imgui.zig");
+
+const c = @cImport({
+ @cDefine("NO_FONT_AWESOME", "1");
+ @cInclude("rlImGui.h");
+});
pub fn main() !void {
- const rules = part.ruleMatrix();
- part.printRules(rules);
+ cfg.rules = part.ruleMatrix();
+ part.printRules(cfg.rules);
+
+ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+ defer _ = gpa.deinit();
rl.initWindow(cfg.screenWidth, cfg.screenHeight, "Particle Simulator");
defer rl.closeWindow();
rl.setTargetFPS(60);
- var gpa = std.heap.GeneralPurposeAllocator(.{}){};
- defer _ = gpa.deinit();
+ c.rlImGuiSetup(true);
+ defer c.rlImGuiShutdown();
+
+ z.initNoContext(gpa.allocator());
+ defer z.deinitNoContext();
+ const imgui_width: f32 = cfg.screenWidth / 2;
+ const imgui_height: f32 = cfg.screenHeight / 3;
+ z.setNextWindowPos(.{ .x = 0, .y = 0 });
+ z.setNextWindowSize(.{ .w = imgui_width, .h = imgui_height });
var particles = try part.initParticles(gpa.allocator(), cfg.initialParticles);
defer particles.deinit(gpa.allocator());
while (!rl.windowShouldClose()) {
rl.beginDrawing();
- if (rl.isKeyPressed(rl.KeyboardKey.key_q)) break;
-
defer rl.endDrawing();
+ if (rl.isKeyPressed(rl.KeyboardKey.key_q)) break;
+ rl.clearBackground(rl.Color.black);
- part.updateVelocities(particles, rules);
+ part.updateVelocities(particles, cfg.rules);
part.updatePosition(particles);
part.draw(particles);
-
- rl.clearBackground(rl.Color.black);
+ try img.update();
}
}
diff --git a/src/particle.zig b/src/particle.zig
index cb1a323..8efae69 100644
--- a/src/particle.zig
+++ b/src/particle.zig
@@ -34,6 +34,21 @@ pub fn printRules(rules: [cfg.colorAmnt][cfg.colorAmnt]f32) void {
}
}
+/// Convert the color index to a string
+pub fn colorToString(c: usize) []const u8 {
+ return switch (c) {
+ 0 => "R",
+ 1 => "Grn",
+ 2 => "Bl",
+ 3 => "Y",
+ 4 => "M",
+ 5 => "Br",
+ 6 => "O",
+ 7 => "Gry",
+ else => " ",
+ };
+}
+
/// Initialize a MultiArrayList of size amnt with particles created by createParticle
pub fn initParticles(allocator: std.mem.Allocator, amnt: u32) !std.MultiArrayList(particle) {
var particles = std.MultiArrayList(particle){};
@@ -99,19 +114,6 @@ const particle = struct {
yvel: f32,
};
-fn colorToString(c: usize) []const u8 {
- return switch (c) {
- 0 => "R",
- 1 => "G",
- 2 => "Bl",
- 3 => "Y",
- 4 => "M",
- 5 => "Br",
- 6 => "O",
- else => " ",
- };
-}
-
fn force(distance: f32, attraction: f32) f32 {
const beta = cfg.minDistance / cfg.radius;
const r: f32 = distance / cfg.radius;