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:
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);