polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

commit 055372c3c8a50c6bb18230890cd86ca5fc6441ad
parent 991995701746671c527797fbed11933ac9c67c65
Author: William Casarin <jb55@jb55.com>
Date:   Sat, 28 Apr 2018 13:01:45 -0700

initial terrain exploration controller

Diffstat:
Msrc/game.c | 2++
Msrc/game.h | 1+
Msrc/main.c | 9+++++----
Msrc/terrain.c | 23++++++++++++++++-------
Msrc/terrain.h | 3++-
Msrc/update.c | 95++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/util.c | 4++++
Msrc/util.h | 1+
8 files changed, 86 insertions(+), 52 deletions(-)

diff --git a/src/game.c b/src/game.c @@ -14,6 +14,7 @@ void game_init(struct game *game) { float *mvp = game->test_resources.test_mvp; float *normal = game->test_resources.normal_matrix; float *camera = game->test_resources.camera; + float *terrain = game->test_resources.terrain_node; float *player = game->test_resources.player; float *light_dir = game->test_resources.light_dir; @@ -30,6 +31,7 @@ void game_init(struct game *game) { mat4_copy(cam_init, camera); mat4_id(player); + mat4_id(terrain); mat4_scale(player, V3(0.36,0.36,1.7), player); input_init(&game->input); diff --git a/src/game.h b/src/game.h @@ -26,6 +26,7 @@ struct resources { gpu_addr normal; } attributes; + float terrain_node[MAT4_ELEMS]; float normal_matrix[MAT4_ELEMS]; float test_mvp[MAT4_ELEMS]; float light_dir[3]; diff --git a/src/main.c b/src/main.c @@ -45,14 +45,14 @@ int main(void) game.terrain = &terrain; const double size = 200; - const double pdist = (sqrt(2)*size)/(size-1.0); + const double pdist = 1.7; /* printf("samples seed %d\n", seed); */ /* struct point *samples = poisson_disk_samples(pdist, size, 30, &terrain.n_samples); */ struct point *samples = load_samples(NULL, &terrain.n_samples); draw_samples(samples, pdist, terrain.n_samples, size); save_samples(samples, seed, terrain.n_samples); - struct perlin_settings terrain_settings = { + terrain.settings = (struct perlin_settings){ .depth = 1, .freq = 0.02, .o1 = 2.0, .o1s = 0.5, @@ -60,13 +60,14 @@ int main(void) .amplitude = 1.0, .ox = 0, .oy = 0, - .exp = 7.3, + .exp = 6.3, + .scale = 1.0 }; terrain_init(&terrain); terrain.size = size; terrain.samples = samples; - terrain_create(&terrain, &terrain_settings); + terrain_create(&terrain); /* slab_buffer = file_contents(SLAB("test.slab"), &length); */ /* slab_parse(&slab, slab_buffer); */ diff --git a/src/terrain.c b/src/terrain.c @@ -21,7 +21,10 @@ static const u32 plane_indices[] = { double old_noisy_boi(void *data, double x, double y) { /* return cos(x/10.0) * sin(y/10.0) * 20.0; */ - struct perlin_settings *s = (struct perlin_settings*)data; + struct terrain *t = (struct terrain*)data; + struct perlin_settings *s = &t->settings; + x *= s->scale; + y *= s->scale; double e = perlin2d(x, y, s->freq, s->depth) + s->o1s * perlin2d(s->o1 * x, s->o1 * y, s->freq, s->depth) + s->o2s * perlin2d(s->o2 * x, s->o2 * y, s->freq, s->depth); @@ -43,34 +46,40 @@ terrain_init(struct terrain *terrain) { } void -terrain_create(struct terrain *terrain, struct perlin_settings *perlin) { +terrain_create(struct terrain *terrain) { u32 i; const double size = terrain->size; const double hsize = size; int num_verts = hsize*hsize; float tmp1[3], tmp2[3]; del_point2d_t *points = calloc(num_verts, sizeof(*points)); + struct perlin_settings *perlin = &terrain->settings; float *verts = calloc(num_verts * 3, sizeof(*verts)); float *normals = calloc(num_verts * 3, sizeof(*normals)); - double ox = perlin->ox; - double oy = perlin->oy; + double ox = perlin->ox * (1/perlin->scale); + double oy = perlin->oy * (1/perlin->scale); // 100 random samples from our noise function for (i = 0; i < (u32)terrain->n_samples; i++) { int n = i*3; - double dx, dy, x, y; + double x, y; x = terrain->samples[i].x; y = terrain->samples[i].y; - double z = old_noisy_boi((void*)perlin, ox+x, oy+y); + double z = old_noisy_boi((void*)terrain, ox+x, oy+y); points[i].x = x; points[i].y = y; verts[n] = (float)x; verts[n+1] = (float)y; - verts[n+2] = (float)z; + + static const double limit = 1.4; + if (x < limit || x > size-limit || y < limit || y > size-limit) + verts[n+2] = 0; + else + verts[n+2] = (float)z; } delaunay2d_t *del = delaunay2d_from(points, terrain->n_samples); diff --git a/src/terrain.h b/src/terrain.h @@ -14,6 +14,7 @@ struct perlin_settings { double ox, oy; double o1, o1s; double o2, o2s; + double scale; double exp; }; @@ -26,7 +27,7 @@ struct terrain { }; void terrain_init(struct terrain *terrain); -void terrain_create(struct terrain *terrain, struct perlin_settings *); +void terrain_create(struct terrain *terrain); void terrain_destroy(struct terrain *terrain); diff --git a/src/update.c b/src/update.c @@ -50,26 +50,27 @@ void movement(struct game *game, float *obj) { void update (struct game *game, u32 dt) { static int passed = 0; + static int last_input = 0; static int last_gen_time = 50; static float n = 1; + static double offset = 0.5; + static int first = 1; struct resources *res = &game->test_resources; - int once = 0; - static struct perlin_settings terrain_settings = { - .depth = 1, - .freq = 0.04, - .amplitude = 1.0, - .ox = 0, - .oy = 0, - .o1 = 2.0, .o1s = 0.5, - .o2 = 4.0, .o2s = 0.25, - .exp = 7.3 - }; + static int stopped = 0; + struct perlin_settings *ts = &game->terrain->settings; + float *tnode = game->test_resources.terrain_node; float *light = res->light_dir; + if (first) { + ts->ox = rand_0to1() * 1000.0; + ts->oy = rand_0to1() * 1000.0; + first = 0; + } + if (game->input.modifiers & KMOD_LALT) movement(game, res->camera); else { - movement(game, res->player); + movement(game, res->terrain_node); /* movement(game, res->camera); */ } @@ -79,48 +80,62 @@ void update (struct game *game, u32 dt) { } int space_down = game->input.keystates[SDL_SCANCODE_SPACE]; + int ctrl_down = game->input.modifiers & KMOD_CTRL; + int now = SDL_GetTicks(); + int dinput = now - last_input; - if (space_down || passed < last_gen_time) { - if (space_down && once) { + if (dinput > 100 && space_down) { + last_input = SDL_GetTicks(); + if (!stopped) { printf("terrain amp %f exp %f freq %f (%d ms)\n", - terrain_settings.amplitude, - terrain_settings.exp, - terrain_settings.freq, + ts->amplitude, + ts->exp, + ts->freq, last_gen_time); + stopped = 1; } + else { + stopped = 0; + } + } + + if (space_down || passed < last_gen_time) { passed += dt; - once = 0; } else { - once = 1; passed = 0; - terrain_settings.oy += 1.0; - terrain_settings.ox += 1.0; - /* terrain_settings.o1s = fabs(sin(1/n) * 0.25); */ - /* terrain_settings.o1 = fabs(cos(n*0.2) * 0.5); */ - /* terrain_settings.o2s = fabs(cos(n+2) * 0.5); */ - /* terrain_settings.o2 = fabs(sin(n*0.02) * 2); */ - /* terrain_settings.freq = fabs(-sin(n)*0.002 * cos(-n)) + 0.02; */ - terrain_settings.exp = fabs(cos(n)*2.0*cos(n)) + 5.0; - terrain_settings.amplitude = cos(1/n)*2.0*cos(n) + 0.5; + if (!stopped) { + double scale = tnode[14] * 0.02; + + double ox = min(tnode[12], 0); + double oy = min(tnode[13], 0); + + printf("terrain %f %f %f\n", tnode[12], tnode[13], tnode[14]); - terrain_destroy(game->terrain); - terrain_init(game->terrain); + ts->ox = ox; + ts->oy = oy; - int t1 = SDL_GetTicks(); - terrain_create(game->terrain, &terrain_settings); - int t2 = SDL_GetTicks(); - last_gen_time = t2 - t1; + ts->scale = scale; + /* ts.o1s = fabs(sin(1/n) * 0.25); */ + /* ts.o1 = fabs(cos(n*0.2) * 0.5); */ + /* ts.o2s = fabs(cos(n+2) * 0.5); */ + /* ts.o2 = fabs(sin(n*0.02) * 2); */ + /* ts->freq = 1/scale*0.2; */ + /* ts->exp = fabs(cos(n)*2.0*cos(n)) + 4.0; */ + /* ts->amplitude = fabs(cos(1/n)*cos(n) + 0.5); */ - /* printf("terrain amp %f exp %f freq %f (%d ms)\n", */ - /* terrain_settings.amplitude, */ - /* terrain_settings.exp, */ - /* terrain_settings.freq, */ - /* last_gen_time); */ + terrain_destroy(game->terrain); + terrain_init(game->terrain); + int t1 = SDL_GetTicks(); + terrain_create(game->terrain); + int t2 = SDL_GetTicks(); + last_gen_time = t2 - t1; + + n += 0.01f; + } /* res->light_dir[0] = cos(n) * 0.8; */ - n += 0.01f; } } diff --git a/src/util.c b/src/util.c @@ -12,6 +12,10 @@ int clampi(int a, int mina, int maxa) { return a; } +double min(double a, double b) { + return a < b ? a : b; +} + double clamp(double a, double mina, double maxa) { if (a > maxa) return maxa; diff --git a/src/util.h b/src/util.h @@ -10,6 +10,7 @@ void check_gl(void); int clampi(int a, int mina, int maxa); double clamp(double a, double mina, double maxa); +double min(double a, double b); double rand_0to1();