polyadvent

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

commit faab8b9abdfd959905a53a5aac36677540e15761
parent 468f0ad09807f8d29cdb448e8d59a680c7635690
Author: William Casarin <jb55@jb55.com>
Date:   Mon, 29 Jul 2019 23:31:15 -0700

camera: collide with terrain as well

Diffstat:
Msrc/terrain_collision.c | 7++++---
Msrc/terrain_collision.h | 2+-
Msrc/update.c | 33++++++++++++++++++++-------------
3 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/src/terrain_collision.c b/src/terrain_collision.c @@ -142,7 +142,7 @@ static struct tri *point_in_vert_tris(float *verts, struct vert_tris *vtris, flo -static void get_terrain_penetration(float *verts, struct tri *tri, float *pos, float *move) +static float get_terrain_penetration(float *verts, struct tri *tri, float *pos, float *move) { float tmp[3], normal[3]; @@ -158,10 +158,11 @@ static void get_terrain_penetration(float *verts, struct tri *tri, float *pos, f float d = vec3_dot(tmp, normal); vec3_scale(normal, d, move); /* vec3_add(pos, tmp, move); */ + return d; } -struct tri *collide_terrain(struct terrain *terrain, float *pos, struct model *model, vec3 *move) +struct tri *collide_terrain(struct terrain *terrain, float *pos, float *move, float *pen) { struct terrain_cell *cells[9] = {0}; struct grid_query queries[3]; @@ -184,7 +185,7 @@ struct tri *collide_terrain(struct terrain *terrain, float *pos, struct model *m struct tri *tri; if ((tri = point_in_vert_tris(terrain->verts, vtris, pos))) { terrain_tri_debug(terrain->verts, tri); - get_terrain_penetration(terrain->verts, tri, pos, move); + *pen = get_terrain_penetration(terrain->verts, tri, pos, move); return tri; } } diff --git a/src/terrain_collision.h b/src/terrain_collision.h @@ -6,6 +6,6 @@ #include "node.h" #include "model.h" -struct tri *collide_terrain(struct terrain *terrain, float *pos, struct model *model, float *move); +struct tri *collide_terrain(struct terrain *terrain, float *pos, float *move, float *pen); #endif /* TERRAIN_COLLISION_H */ diff --git a/src/update.c b/src/update.c @@ -325,18 +325,24 @@ void orbit_update_from_mouse(struct orbit *camera, struct input *input, } static void camera_keep_above_ground(struct terrain *terrain, - const struct node *camera) { + struct node *camera) { + float move[3], above[3]; + float *camworld = node_world(camera); + float pen; + static const float penlim = 1.0; + struct tri *tri = collide_terrain(terrain, camworld, move, &pen); + if (!tri) + return; if (!(get_entity(&terrain->entity_id)->flags & ENT_INVISIBLE)) { - float *camera_world = node_world((struct node*)camera); - /* float *target = node_world(&get_player(res)->node); */ - /* spherical_pos(&res->camera.coords, target, camera_world); */ - float cam_terrain_z = - terrain->fn(terrain, camera_world[0], camera_world[1]); - - const float bias = 1.0; - - if (camera_world[2] < cam_terrain_z + bias) - camera_world[2] = cam_terrain_z + bias; + if (pen < penlim) { + float dir[3]; + vec3_normalize(move, dir); + vec3_scale(dir, pen < 0 ? penlim : -penlim, above); + vec3_add(camworld, move, camworld); + vec3_add(camworld, above, camworld); + /* vec3_add(move, above, move); */ + /* vec3_add(camworld, move, camworld); */ + } } } @@ -376,16 +382,17 @@ static void player_update(struct game *game, struct entity *player) float move[3]; float pos[3]; + float pen; vec3_copy(node_world(node), pos); debug("node_world(player) %f %f %f\n", pos[0], pos[1], pos[2]); - struct tri *tri = collide_terrain(terrain, pos, NULL, move); + struct tri *tri = collide_terrain(terrain, pos, move, &pen); /* node_translate(node, move); */ if (tri) { if (vec3_eq(move, V3(0,0,0), 0.01)) { player->flags |= ENT_ON_GROUND; } - else if (move[2] >= 0) { + else if (pen < 0) { node_translate(node, move); /* vec3_all(player->velocity, 0); */ vec3_scale(player->velocity, 0.1, player->velocity);