add slider for updating number of boids

This commit is contained in:
Rokas Puzonas 2023-08-01 23:45:43 +03:00
parent c713b271c7
commit 115bb834a0
8 changed files with 62 additions and 45 deletions

View File

@ -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

View File

@ -2,3 +2,5 @@
-Idepends/raylib/src/
-Idepends/raygui/src/
-DRLGL_IMPLEMENTATION
-DRPROF_IMPLEMENTATION
-DRAYGUI_IMPLEMENTATION

View File

@ -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;

View File

@ -7,7 +7,6 @@
#include <emscripten/emscripten.h>
#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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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();

3
src/world.hpp Normal file
View File

@ -0,0 +1,3 @@
#include "boid-playground.hpp"
void world_adjust_boid_count(World *world, int new_boid_count);