polyadvent

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

commit 9a514f8bd443952ce1c3ec57219de6ca1fb27f19
parent 17d00c8004ddb16ea5f75c323c86507a5d918ea7
Author: William Casarin <jb55@jb55.com>
Date:   Thu, 25 Jul 2019 17:09:23 -0700

actually workingish

Diffstat:
Msrc/entity.c | 2+-
Msrc/game.c | 1+
Msrc/terrain.c | 127+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Msrc/terrain.h | 2+-
Msrc/update.c | 40++++++++++------------------------------
5 files changed, 114 insertions(+), 58 deletions(-)

diff --git a/src/entity.c b/src/entity.c @@ -31,7 +31,7 @@ struct entity *init_entity(struct entity *ent, node_id *id) { else { ent->node_id = *id; } - ent->casts_shadows = 1; + ent->casts_shadows = 0; return ent; } diff --git a/src/game.c b/src/game.c @@ -176,6 +176,7 @@ void game_init(struct game *game, int width, int height) { // player entity init_id(&res->player_id); player = &static_entities()[entity_player]; + player->casts_shadows = 1; struct node *pnode = &static_nodes()[node_player]; assert(pnode); res->player_id = make_static_id(entity_player); diff --git a/src/terrain.c b/src/terrain.c @@ -154,17 +154,93 @@ void query_terrain_grid(struct terrain *terrain, float x, float y, static void insert_grid_vertex(struct terrain_cell *cell, float *verts, float x, float y, int ind) { - for (int i = 0; i < cell->vert_count; i++) { - float *vert = &verts[ind]; - if (approxeq(x, vert[0]) && approxeq(y, vert[1])) { - return; + assert(cell->vert_count + 1 <= MAX_CELL_VERTS); + cell->verts_index[cell->vert_count++] = ind; +} + +static void collide_terrain_debug(struct terrain *terrain, struct terrain_cell *cell) +{ + for (int j = 0; j < cell->vert_count; j++) { + entity_id *ent_id = &cell->debug_ent[j]; + + if (is_null_id(ent_id)) { + init_id(ent_id); + struct entity *ent = new_entity(ent_id); + ent->model_id = get_static_model(model_barrel, NULL); + struct node *enode = get_node(&ent->node_id); + node_set_label(enode, "grid_debug"); + assert(cell->verts_index[j] < terrain->n_verts); + float *vert = &terrain->verts[cell->verts_index[j]]; + /* debug("creating new grid_debug entity at %f %f %f\n", vert[0], vert[1], vert[2]); */ + vec3_copy(vert, enode->pos); + node_scale(enode, 5.0); + node_mark_for_recalc(enode); + node_recalc(enode); } } +} - assert(cell->vert_count + 1 <= MAX_CELL_VERTS); - cell->verts_index[cell->vert_count++] = ind; +static inline void get_closest_cells(struct terrain *terrain, + vec3 *pos, + struct terrain_cell *cell, + struct terrain_cell *closest_cells[3], + float closest[3]) +{ + for (int j = 0; j < cell->vert_count; j++) { + vec3 *vpos = &terrain->verts[cell->verts_index[j]]; + float d = vec3_distsq(pos, vpos); + + if (d < closest[0]) { + closest[2] = closest[1]; + closest[1] = closest[0]; + closest[0] = d; + + closest_cells[2] = closest_cells[1]; + closest_cells[1] = closest_cells[0]; + closest_cells[0] = cell; + } + else if (d < closest[1]) { + closest[2] = closest[1]; + closest[1] = d; + + closest_cells[2] = closest_cells[1]; + closest_cells[1] = cell; + } + else if (d < closest[2]) { + closest[2] = d; + closest_cells[2] = cell; + } + } } +void collide_terrain(struct terrain *terrain, struct node *node, struct model *model, vec3 *move) +{ + struct terrain_cell *cells[9]; + struct terrain_cell *closest_cells[3] = {0}; + float closest[3] = {FLT_MAX}; + + query_terrain_grid(terrain, node->mat[M_X], node->mat[M_Y], cells); + + for (int i = 0; i < ARRAY_SIZE(cells); i++) { + struct terrain_cell *cell = cells[i]; + if (!cell) + continue; + + collide_terrain_debug(terrain, cell); + + get_closest_cells(terrain, node_world(node), cell, closest_cells, closest); + + assert(closest_cells[0]); + assert(closest_cells[1]); + assert(closest_cells[2]); + + // safe bail here + if (closest_cells[2] == NULL || closest_cells[1] == NULL || closest_cells[0] == NULL) + return; + + + } +} void create_terrain(struct terrain *terrain, float scale, int seed) { u32 i; @@ -182,10 +258,9 @@ void create_terrain(struct terrain *terrain, float scale, int seed) { del_point2d_t *points = calloc(terrain->n_samples, sizeof(*points)); float *verts = calloc(terrain->n_samples * 3, sizeof(*verts)); - terrain->cell_size = pdist; + terrain->cell_size = pdist * 1.5; terrain->n_cells = round(size / terrain->cell_size); debug("n_cells %d\n", terrain->n_cells); - assert(terrain->n_cells == 417); struct terrain_cell *grid = calloc(terrain->n_cells * terrain->n_cells, sizeof(struct terrain_cell)); @@ -213,6 +288,18 @@ void create_terrain(struct terrain *terrain, float scale, int seed) { verts[n] = (float)x; verts[n+1] = (float)y; + int grid_x = x / terrain->cell_size; + int grid_y = y / terrain->cell_size; + + /* if (i > 169000) */ + /* debug("grid %f %f %d %d\n", x, y, grid_x, grid_y); */ + struct terrain_cell *cell = + index_terrain_cell(terrain, grid_x, grid_y); + + assert(cell); + + insert_grid_vertex(cell, verts, x, y, n); + static const double limit = 1.4; if (x < limit || x > size-limit || y < limit || y > size-limit) verts[n+2] = 0; @@ -249,21 +336,9 @@ void create_terrain(struct terrain *terrain, float scale, int seed) { for (int j = 0; j < 3; j++) { int ind = ndv + j*3; - float x = del_verts[ind+0] = v[j][0]; - float y = del_verts[ind+1] = v[j][1]; - del_verts[ind+2] = v[j][2]; - - int grid_x = x / terrain->cell_size; - int grid_y = y / terrain->cell_size; - - /* if (i > 169000) */ - /* debug("grid %f %f %d %d\n", x, y, grid_x, grid_y); */ - struct terrain_cell *cell = - index_terrain_cell(terrain, grid_x, grid_y); - - assert(cell); - - insert_grid_vertex(cell, del_verts, x, y, ind); + del_verts[ind+0] = v[j][0]; + del_verts[ind+1] = v[j][1]; + del_verts[ind+2] = v[j][2]; } // normals @@ -310,10 +385,10 @@ void create_terrain(struct terrain *terrain, float scale, int seed) { free(points); // needed for collision - free(verts); - /* free(del_verts); */ + /* free(verts); */ + free(del_verts); - terrain->verts = del_verts; + terrain->verts = verts; terrain->n_verts = num_verts; // we might need norms in memory eventually as well ? diff --git a/src/terrain.h b/src/terrain.h @@ -24,7 +24,7 @@ struct perlin_settings { struct terrain_cell { u8 vert_count; - u16 verts_index[MAX_CELL_VERTS]; + int verts_index[MAX_CELL_VERTS]; entity_id debug_ent[MAX_CELL_VERTS]; }; diff --git a/src/update.c b/src/update.c @@ -148,7 +148,7 @@ void resize_fbos(struct entity *player, struct fbo *shadow_buffer, } // TODO: compute better bounds based - const float factor = 4.5; + const float factor = 10.5; struct model *model = get_model(&player->model_id); assert(model); struct geometry *geom = get_geometry(&model->geom_id); assert(geom); @@ -158,6 +158,11 @@ void resize_fbos(struct entity *player, struct fbo *shadow_buffer, float bottom = geom->min[1] - factor; float top = geom->max[1] + factor/2.0; + /* float left = -factor; */ + /* float right = factor; */ + /* float bottom = factor; */ + /* float top = -factor; */ + const float near = -5.0; const float far = 5.0; @@ -307,9 +312,12 @@ static void camera_keep_above_ground(struct terrain *terrain, } } +static void terrain_collision_debug(struct terrain *terrain, struct node *node) +{ +} + static void player_update(struct game *game, struct entity *player) { - struct terrain_cell *cells[9]; struct resources *res = &game->test_resources; struct orbit *camera = &res->orbit_camera; @@ -334,34 +342,6 @@ static void player_update(struct game *game, struct entity *player) player_terrain_collision(terrain, player); node_recalc(node); - query_terrain_grid(terrain, node->mat[M_X], node->mat[M_Y], cells); - - for (int i = 0; i < ARRAY_SIZE(cells); i++) { - struct terrain_cell *cell = cells[i]; - if (!cell) - continue; - - for (int j = 0; j < cell->vert_count; j++) { - entity_id *ent_id = &cell->debug_ent[j]; - - if (is_null_id(ent_id)) { - init_id(ent_id); - struct entity *ent = new_entity(ent_id); - ent->model_id = get_static_model(model_barrel, NULL); - struct node *enode = get_node(&ent->node_id); - node_set_label(enode, "grid_debug");; - assert(cell->verts_index[j] < terrain->n_verts); - float *vert = &terrain->verts[cell->verts_index[j]]; - debug("creating new grid_debug entity at %f %f %f\n", vert[0], vert[1], vert[2]); - vec3_copy(vert, enode->pos); - node_scale(enode, 25.0); - node_mark_for_recalc(enode); - node_recalc(enode); - } - - } - - } }