From: Brendan Hansen Date: Sun, 15 Nov 2020 19:27:33 +0000 (-0600) Subject: working on integrating a settings file X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=1a5938baf7db2bb9cbfbeffc4f688ba73622ae98;p=csc718.git working on integrating a settings file --- diff --git a/Makefile b/Makefile index edeb4e3..f5d17e9 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ OBJ_FILES=\ build/utils.o \ build/vecmath.o \ build/physics.o \ + build/settings.o \ build/ui.o \ build/sim.o diff --git a/dummy.settings b/dummy.settings new file mode 100644 index 0000000..642fbd8 --- /dev/null +++ b/dummy.settings @@ -0,0 +1,43 @@ +# Determines the number of parallel execution units to be used. +# This must be at least 2 (for now). +thread_count 4 + +# Determines the number of physics bodies in the simulation. +body_count 2500 + +# Determines the number of different types of bodies. +# This must be specified before the body_color or interaction settings. +body_type_count 4 + +# Determines what the color is of each of the body types. +# Uses standard RGB with values ranging from 0 to 1. +# Type# R G B +body_color 0 1.0 0.0 0.0 +body_color 1 0.0 1.0 0.0 +body_color 2 0.0 0.0 1.0 +body_color 3 1.0 1.0 1.0 + +# Determines the range of values a bodies mass can be, sampled from +# a uniform distribution. +# Type# Min Max +body_mass_range 0 2.0 4.0 +body_mass_range 1 20.0 22.0 +body_mass_range 2 5.0 7.0 +body_mass_range 3 3.0 15.0 + +# Determines the friction coeffient, u. +# Equation of friction used: +# F = -u * v; +# where v is the velocity of the body. +# Set to 0.0 to watch very wild behavior. +friction 6.0 + +# Determines the scale of the interaction calcuations. +# Mostly an implementation detail, but effectively, the "distance" column on +# the interactions plus one, is multipled by this number and that is the maximum distance +# two bodies will interact in terms of pixels. +universe_scale 20.0 + +# Determines how two bodies will interact. Note, that this is not a symmetric relation. +# Body Type# Other Type# Distance Force +interaction 0 1 5.0 200.0 diff --git a/include/container.h b/include/container.h index 5ced00c..08bfb05 100644 --- a/include/container.h +++ b/include/container.h @@ -22,6 +22,14 @@ struct Array data = nullptr; } + void init(u32 initial_capacity) + { + count = 0; + capacity = 0; + data = nullptr; + this->ensure_capacity(initial_capacity); + } + T& operator[](i32 elem) { #if defined(DEBUG) diff --git a/include/log.h b/include/log.h index f23d3e8..0d4856e 100644 --- a/include/log.h +++ b/include/log.h @@ -1,6 +1,8 @@ #ifndef LOG_H #define LOG_H +#include + enum LogLevel { LOG_LEVEL_INFO, @@ -17,4 +19,4 @@ extern LogLevel LOG_LEVEL_MINIMUM; void logprint(LogLevel level, const char* format, ...); void logvprint(LogLevel level, const char* format, va_list va); -#endif //LOG_H \ No newline at end of file +#endif //LOG_H diff --git a/include/physics.h b/include/physics.h index 18cfb56..d2ac939 100644 --- a/include/physics.h +++ b/include/physics.h @@ -5,29 +5,32 @@ #include "container.h" #include "utils.h" -enum struct BodyType : u8 -{ - Red = 0, - Green = 1, - Blue = 2, - White = 3, - - Count -}; - struct Body { V2f pos; V2f vel; V2f acc; - + f32 mass; - - BodyType body_type; + + u32 body_type; +}; + +// NOTE(Brendan): This represents the piecewise function: +// +// F(d) = { +// 0 < d < 1: r * (1 - d) / d +// 1 <= d < distance_range + 1: (-4 * max_force / (distance_range ^ 2)) * (d - (distance_range / 2) - 1) ^ 2 + max_force, +// otherwise: 0 +// } +struct BodyRelation +{ + f32 distance_range; + f32 max_force; }; void nocheckin_init_other_bodies(); void body_accumulate_move(Body* body, QuadTree* qt_bodies, f64 dt); void body_apply_move(Body* body, f64 dt); -#endif //PHYSICS_H \ No newline at end of file +#endif //PHYSICS_H diff --git a/include/settings.h b/include/settings.h new file mode 100644 index 0000000..ec5b8d5 --- /dev/null +++ b/include/settings.h @@ -0,0 +1,43 @@ +#ifndef SETTINGS_H +#define SETTINGS_H + +#include "container.h" +#include "log.h" +#include "utils.h" +#include "physics.h" + +struct BodyColor +{ + f32 r, g, b; +}; + +struct BodyMassRange +{ + f32 min, max; +}; + +struct SimSettings +{ + u32 body_count; + u32 body_type_count; + + Array body_colors; + Array body_mass_range; + + // NOTE(Brendan): This is effectively a 2D array. + // Accessed using [b1 * num_bodies + b2] + Array body_relations; + + f32 friction; + f32 near_repulsive_force; + f32 universe_scale; + u32 thread_count; +}; + +extern SimSettings global_settings; + +void load_settings_from_file(SimSettings* settings, const char* filename); +void save_settings_to_file(SimSettings* settings, const char* filename); +void generate_random_settings(SimSettings* settings); + +#endif diff --git a/src/physics.cpp b/src/physics.cpp index 38de5f8..4270996 100644 --- a/src/physics.cpp +++ b/src/physics.cpp @@ -1,27 +1,14 @@ #include "physics.h" #include "utils.h" #include "types.h" - -// NOTE(Brendan): This represents the piecewise function: -// -// F(d) = { -// 0 < d < 1: r * (1 - d) / d -// 1 <= d < distance_range + 1: (-4 * max_force / (distance_range ^ 2)) * (d - (distance_range / 2) - 1) ^ 2 + max_force, -// otherwise: 0 -// } -struct BodyRelation -{ - f32 distance_range; - f32 max_force; -}; +#include "settings.h" internal f32 get_force_magnitude_at_distance(BodyRelation br, f32 d) { if (0 < d && d < 1) { - persist const f32 repulsion_force = 100.0f; // :ArbitraryConstant - return repulsion_force * (1 - d) / d; + return global_settings.near_repulsive_force * (1 - d) / d; } if (1 <= d && d < br.distance_range + 1) @@ -36,8 +23,6 @@ get_force_magnitude_at_distance(BodyRelation br, f32 d) return 0; } -internal BodyRelation body_relations[(i32) BodyType::Count][(i32) BodyType::Count]; - internal bool bodies_collide(Body* b1, Body* b2) { @@ -67,15 +52,6 @@ body_can_move(Body* body, const Array other_bodies, V2f d) thread_local internal Array other_bodies; void nocheckin_init_other_bodies() { - foreach (i, 0, (i32) BodyType::Count) - { - foreach (j, 0, (i32) BodyType::Count) - { - body_relations[i][j].max_force = randf(-200.0f, 200.0f); - body_relations[i][j].distance_range = randf(4.0f, 7.0f); - } - } - other_bodies.ensure_capacity(1024); } @@ -92,16 +68,16 @@ body_accumulate_move(Body* body, QuadTree* qt_bodies, f64 dt) if (body == it) continue; auto norm_dir = body->pos - it->pos; - auto d = v2f_mag(norm_dir) / 20.0f; // :ArbitraryConstant + auto d = v2f_mag(norm_dir) / global_settings.universe_scale; norm_dir = v2f_norm(norm_dir); - auto br = body_relations[static_cast(body->body_type)][static_cast(it->body_type)]; + auto br = global_settings.body_relations[static_cast(body->body_type) * global_settings.body_type_count + static_cast(it->body_type)]; f32 force_mag = get_force_magnitude_at_distance(br, d); force += norm_dir * force_mag; } - force += body->vel * -6.f; // :ArbitraryConstant + force += body->vel * -global_settings.friction; body->acc = force * (1.0f / body->mass); body->vel += body->acc * dt; diff --git a/src/settings.cpp b/src/settings.cpp new file mode 100644 index 0000000..c6a51f3 --- /dev/null +++ b/src/settings.cpp @@ -0,0 +1,57 @@ +#include "settings.h" + +SimSettings global_settings; + +void +load_settings_from_file(SimSettings* settings, const char* filename) +{ + FILE* file = fopen(filename, "r"); + defer { fclose(file); }; + + +} + +void +save_settings_to_file(SimSettings* settings, const char* filename) +{ +} + +void +generate_random_settings(SimSettings* settings) +{ + settings->body_count = 2500; + + const u32 num_body_types = 4; + settings->body_type_count = num_body_types; + + settings->body_colors.init(num_body_types); + settings->body_colors[0] = { 1.0, 0.0, 0.0 }; + settings->body_colors[1] = { 0.0, 1.0, 0.0 }; + settings->body_colors[2] = { 0.0, 0.0, 1.0 }; + settings->body_colors[3] = { 1.0, 1.0, 1.0 }; + + settings->body_mass_range.init(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->friction = 6.0; + settings->near_repulsive_force = 100.0; + settings->universe_scale = 20.0; + + settings->thread_count = 4; + + settings->body_relations.init(num_body_types * num_body_types); + foreach (i, 0, num_body_types) + { + foreach (j, 0, num_body_types) + { + settings->body_relations[i * num_body_types] = + { + .distance_range = randf(4.0f, 7.0f), + .max_force = randf(-200.0f, 200.0f), + }; + } + } +} diff --git a/src/sim.cpp b/src/sim.cpp index 76462f3..75b4a46 100644 --- a/src/sim.cpp +++ b/src/sim.cpp @@ -18,12 +18,7 @@ #include "physics.h" #include "ui.h" #include "log.h" - -// :ArbitraryConstant -#define PARTICLE_COUNT 2500 - -// :ArbitraryConstant -#define NUM_THREADS 2 +#include "settings.h" // TODO(Brendan): Maybe this can be removed because it isn't really necessary? internal void @@ -131,19 +126,18 @@ struct SimState Camera camera; pthread_barrier_t thread_sync_barrier; - pthread_t threads[NUM_THREADS - 1]; - ThreadData thread_data[NUM_THREADS - 1]; + Array threads; + Array thread_data; }; +// @CLEANUP internal f64 TEMP_dt = 0; internal void update_bodies_partial(SimState *state, i32 index) { - i32 low = index * (PARTICLE_COUNT / NUM_THREADS); - i32 high = (index + 1) * (PARTICLE_COUNT / NUM_THREADS); - - persist const f64 step = 0.01; + i32 low = index * (global_settings.body_count / global_settings.thread_count); + i32 high = (index + 1) * (global_settings.body_count / global_settings.thread_count); foreach (i, low, high) body_accumulate_move(&state->bodies[i], &state->qt_bodies, TEMP_dt); pthread_barrier_wait(&state->thread_sync_barrier); @@ -177,29 +171,35 @@ internal void sim_state_init(SimState* state) { // NOTE(Brendan): Need to initialize the array since it does not get constructed because I refuse to use the 'new' keyword. alloc uses malloc under the hood and cannot initialize the result. - state->bodies.init(); - state->bodies.ensure_capacity(PARTICLE_COUNT); + state->bodies.init(global_settings.body_count); - foreach (i, 0, PARTICLE_COUNT) + foreach (i, 0, global_settings.body_count) { Body tmp_body; + tmp_body.body_type = (rand() % global_settings.body_type_count); tmp_body.pos = V2f{ randf(-1000, 1000), randf(-1000, 1000) }; tmp_body.vel = V2f{ 0.0f, 0.0f }; - tmp_body.mass = randf(3.0f, 6.0f); - tmp_body.body_type = static_cast ((rand() % 4)); + + BodyMassRange bmr = global_settings.body_mass_range[tmp_body.body_type]; + tmp_body.mass = randf(bmr.min, bmr.max); + state->bodies.push(tmp_body); } - state->qt_body_allocator.init(PARTICLE_COUNT); + state->qt_body_allocator.init(global_settings.body_count); state->qt_bodies.init(AABB { -2000, -2000, 4000, 4000 }); state->camera.scale = 1.0f; - pthread_barrier_init(&state->thread_sync_barrier, NULL, NUM_THREADS); + pthread_barrier_init(&state->thread_sync_barrier, NULL, global_settings.thread_count); + + state->threads.init(global_settings.thread_count); + state->threads.count = global_settings.thread_count; - foreach (i, 0, NUM_THREADS - 1) + state->thread_data.init(global_settings.thread_count); + foreach (i, 0, global_settings.thread_count - 1) { - state->thread_data[i] = ThreadData { i, state }; + state->thread_data.push(ThreadData { i, state }); pthread_create(&state->threads[i], NULL, thread_start, (void *) &state->thread_data[i]); } } @@ -316,6 +316,8 @@ main(i32 argc, char* argv[]) { srand(time(NULL)); + generate_random_settings(&global_settings); + init_glfw(); defer { deinit_glfw(); };