From 115bb834a01b1577d8dd52bf941afb302c841b1b Mon Sep 17 00:00:00 2001 From: Rokas Puzonas Date: Tue, 1 Aug 2023 23:45:43 +0300 Subject: [PATCH] add slider for updating number of boids --- Makefile | 9 ++++-- compile_flags.txt | 2 ++ src/boid-playground.hpp | 2 ++ src/main.cpp | 10 +++--- src/rprof.h | 3 +- src/ui.cpp | 8 +++++ src/world.cpp | 70 +++++++++++++++++++---------------------- src/world.hpp | 3 ++ 8 files changed, 62 insertions(+), 45 deletions(-) create mode 100644 src/world.hpp diff --git a/Makefile b/Makefile index c6743e1..1f671fc 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,9 @@ WEB_STACK_SIZE := 196608 WEB_SHELL := src/shell.html COMPILER_FLAGS := -std=c++17 -Wno-enum-compare -O3 -g -flto +COMPILER_FLAGS += -DRPROF_IMPLEMENTATION +COMPILER_FLAGS += -DRAYGUI_IMPLEMENTATION +# COMPILER_FLAGS += -DRLGL_IMPLEMENTATION LINKER_FLAGS := -lraylib # SOURCES := $(wildcard src/*.cpp) @@ -94,10 +97,12 @@ MAIN_TARGET := $(BUILD_DIR)/$(EXECUTABLE)$(EXT) .DEFAULT_GOAL := all # Lists phony targets for Makefile -.PHONY: all setup submodules run clean emsdk +.PHONY: all setup submodules run clean emsdk app + +app: $(MAIN_TARGET) # Default target, compiles, runss and cleans -all: clean $(MAIN_TARGET) run +all: clean app run # Sets up the project for compiling, generates includes and libs setup: lib diff --git a/compile_flags.txt b/compile_flags.txt index 18a844d..954dc52 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -2,3 +2,5 @@ -Idepends/raylib/src/ -Idepends/raygui/src/ -DRLGL_IMPLEMENTATION +-DRPROF_IMPLEMENTATION +-DRAYGUI_IMPLEMENTATION diff --git a/src/boid-playground.hpp b/src/boid-playground.hpp index 18cea93..21bdecb 100644 --- a/src/boid-playground.hpp +++ b/src/boid-playground.hpp @@ -69,6 +69,8 @@ struct Visuals { }; struct UI { + float target_boid_count; + bool min_speed_edit = false; bool max_speed_edit = false; bool steer_speed_edit = false; diff --git a/src/main.cpp b/src/main.cpp index c825374..7c3008f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,7 +7,6 @@ #include #endif -#define RPROF_IMPLEMENTATION // #define RPROF_STUB_OUT // #define RPROF_ONLY_TOTAL_TIME #include "rprof.h" @@ -22,8 +21,7 @@ //#define USE_TEST_MAIN -#define RAYGUI_IMPLEMENTATION -#include "raygui.h" +// #include "raygui.h" #define FRAMERATE 60 #define TIME_PER_FRAME (1.0/FRAMERATE) @@ -32,6 +30,9 @@ static World g_world; static Visuals g_visuals; static UI g_ui; +// TODO: Make boids form specific shapes defined by user, options: +// Circles, triangles, by image, text. + void UpdateDrawFrame(); static void profiling_test(); @@ -54,11 +55,12 @@ int main() { world_init(&g_world, screen_width, screen_height); float border = g_world.collision_avoidance_distance; - for (int i = 0; i < 45000; i++) { + for (int i = 0; i < 10000; i++) { Boid boid; boid_rand_init(&g_world, &boid, border); g_world.boids.push_back(boid); } + g_ui.target_boid_count = g_world.boids.size(); #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(UpdateDrawFrame, 0, 1); diff --git a/src/rprof.h b/src/rprof.h index 1a0c562..7b9d29c 100644 --- a/src/rprof.h +++ b/src/rprof.h @@ -81,7 +81,6 @@ void rprof_output(prof_sort_cmp_cb sort_cb); #define RPROF_START(label) rprof_start(__COUNTER__, label) #define RPROF_STOP() rprof_stop() -#define RPROF_IMPLEMENTATION // TODO: Remove this #define #ifdef RPROF_IMPLEMENTATION // ------------------------ CPU Timing ------------------------- @@ -219,7 +218,7 @@ static uint64_t rprof_get_cpu_timer_hz(uint64_t measure_time_ms) qsort(slots, slot_count, sizeof(rprof_slot*), (qsort_cmp*)sort_cb); } - printf("\nTotal time taken: %.3fms (%lu) (CPU: ~%.3fGHz)\n", (float)total_time*1000/cpu_hz, total_time, (float)cpu_hz/1000000000); + printf("\nTotal time taken: %.3fms (%llu) (CPU: ~%.3fGHz)\n", (float)total_time*1000/cpu_hz, total_time, (float)cpu_hz/1000000000); uint32_t duration_max_width = 0; uint32_t percent_max_width = 0; diff --git a/src/ui.cpp b/src/ui.cpp index 19d8c39..c1fe963 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -1,5 +1,6 @@ #include "boid-playground.hpp" #include "raygui.h" +#include "world.hpp" struct VerticalLayout { float x, y; @@ -88,6 +89,9 @@ static void ui_draw(World *world, Visuals *visuals, UI *ui) { GuiGroupBox({ 450, 55, 220, group_height }, "Flock"); { VerticalLayout layout = { .x = 605, .y = 65, .gap = 8 }; + GuiSlider(next_in_layout(&layout, 100, 15, -145), NULL, "Boid count", &ui->target_boid_count, 10, MAX_BOIDS); + world_adjust_boid_count(world, (int)ui->target_boid_count); + gui_valuebox_float(next_in_layout(&layout, 50, 15), "Alignment strength", &world->alignment_strength, 0, 100, &ui->alignment_strength_edit); gui_valuebox_float(next_in_layout(&layout, 50, 15), "Cohesion strength", &world->cohesion_strength, 0, 100, &ui->cohesion_strength_edit); gui_valuebox_float(next_in_layout(&layout, 50, 15), "Separation strength", &world->separation_strength, 0, 100, &ui->separation_strength_edit); @@ -95,9 +99,13 @@ static void ui_draw(World *world, Visuals *visuals, UI *ui) { } float window_width = GetScreenWidth(); + float window_height = GetScreenHeight(); DrawFPS(window_width - 90, 10); char boid_label[128] = { 0 }; snprintf(boid_label, sizeof(boid_label), "%lu boids", world->boids.size()); DrawText(boid_label, window_width - 125, 35, 20, GREEN); + + DrawText("W.I.P.", 20, window_height - 50, 20, RED); + DrawText("May crash sometimes", 20, window_height - 30, 20, RED); } diff --git a/src/world.cpp b/src/world.cpp index 1caf382..f546c58 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -99,16 +99,6 @@ static int count_out_of_bounds_boids(World *world) { return count; } -static void print_m256_f32(__m256 value) -{ - float *value_f32 = (float*)&value; - printf("%f", value_f32[0]); - for (int i = 1; i < 8; i++) { - printf(",%f", value_f32[i]); - } - printf("\n"); -} - // -------------------- Init/Cleanup ------------------------ static void boid_rand_init(World *world, Boid *boid, float border) { @@ -131,6 +121,26 @@ static void world_free(World *world) { arena_free(&world->frame_arena); } +// --------------------- Utils ----------------------- + +void world_adjust_boid_count(World *world, int new_boid_count) { + if (new_boid_count >= MAX_BOIDS) return; + + int boid_count = world->boids.size(); + int diff = new_boid_count - boid_count; + if (diff > 0) { + for (int i = 0; i < diff; i++) { + Boid boid; + boid_rand_init(world, &boid, 5); + world->boids.push_back(boid); + } + } else if (diff < 0) { + for (int i = 0; i < -diff ; i++) { + world->boids.pop_back(); + } + } +} + // --------------------- Update ----------------------- struct ChunkGrid { @@ -200,33 +210,14 @@ static void assign_local_boids_b2l(World *world, BoidList *local_boids, uboid_t } } -static void vector2_list_to_simd8(Vector2 *vecs, int vec_count, __m256 *vecs_x, __m256 *vecs_y) { - DEBUG_ASSERT(vec_count % 8 == 0 && "Vector2 count must be divisible by 8"); - - for (int i = 0; i < vec_count/8; i++) { - vecs_x[i] = _mm256_set_ps( - vecs[8*i+7].x, - vecs[8*i+6].x, - vecs[8*i+5].x, - vecs[8*i+4].x, - vecs[8*i+3].x, - vecs[8*i+2].x, - vecs[8*i+1].x, - vecs[8*i+0].x - ); - - vecs_y[i] = _mm256_set_ps( - vecs[8*i+7].y, - vecs[8*i+6].y, - vecs[8*i+5].y, - vecs[8*i+4].y, - vecs[8*i+3].y, - vecs[8*i+2].y, - vecs[8*i+1].y, - vecs[8*i+0].y - ); - +#ifndef __EMSCRIPTEN__ +static void print_m256_f32(__m256 value) { + float *value_f32 = (float*)&value; + printf("%f", value_f32[0]); + for (int i = 1; i < 8; i++) { + printf(",%f", value_f32[i]); } + printf("\n"); } static inline bool mm256_is_zero(__m256i x) { @@ -478,6 +469,7 @@ static void world_compute_local_boids_simd(BoidList *local_boids, World *world, RPROF_STOP(); } +#endif static void world_compute_local_boids_scalar(BoidList *local_boids, World *world, ChunkGrid *chunks) { RPROF_START("Calc dot products and ranges (scalar)"); @@ -551,8 +543,12 @@ static BoidList* world_compute_local_boids(World *world) { RPROF_STOP(); RPROF_START("world_compute_local_boids()"); - // TODO: Use scalar version for WASM or make 128bit version. +#ifdef __EMSCRIPTEN__ + // TODO: Rewrite simd version to only use SSE, not AVX2 + world_compute_local_boids_scalar(all_local_boids, world, &chunks); +#else world_compute_local_boids_simd(all_local_boids, world, &chunks); +#endif RPROF_STOP(); diff --git a/src/world.hpp b/src/world.hpp new file mode 100644 index 0000000..b7a593b --- /dev/null +++ b/src/world.hpp @@ -0,0 +1,3 @@ +#include "boid-playground.hpp" + +void world_adjust_boid_count(World *world, int new_boid_count);