commit 6bb1b1f05bcf2d7900cef18fc6ba1134769418c8
parent 985bab86476cf435f7fe92d8d8a902b5cc2b1d1b
Author: William Casarin <jb55@jb55.com>
Date: Sun, 28 Jul 2019 14:06:26 -0700
terrain collision working!!
Diffstat:
4 files changed, 66 insertions(+), 19 deletions(-)
diff --git a/src/terrain.h b/src/terrain.h
@@ -63,7 +63,6 @@ struct terrain {
double old_noisy_boi(struct terrain *, double x, double y);
-void collide_terrain(struct terrain *terrain, struct node *node, struct model *model, vec3 *move);
void update_terrain(struct terrain *terrain, const double pdist);
void gen_terrain_samples(struct terrain *terrain, float scale, const double pdist);
void init_terrain(struct terrain *terrain, float size);
diff --git a/src/terrain_collision.c b/src/terrain_collision.c
@@ -12,6 +12,8 @@ struct tri_query {
struct vert_tri *vtri;
};
+/** Get the top 3 closest terrain vertices to a specific world position `pos`
+ */
static void get_closest_verts(struct terrain *terrain,
vec3 *pos,
struct grid_query closest[3],
@@ -50,6 +52,8 @@ static void get_closest_verts(struct terrain *terrain,
}
}
+
+
static inline float sign (float *p1, float *p2, float *p3)
{
return (p1[0] - p3[0]) * (p2[1] - p3[1]) - (p2[0] - p3[0]) * (p1[1] - p3[1]);
@@ -70,11 +74,9 @@ bool point_in_tri(float *pt, float *v1, float *v2, float *v3)
return !(has_neg && has_pos);
}
-static void get_closest_tris(struct terrain *terrain, struct vert_tris *vtris)
-{
-}
+#ifdef DEBUG
static void terrain_tri_debug(float *verts, struct tri *tri)
{
@@ -107,8 +109,49 @@ static void terrain_tri_debug(float *verts, struct tri *tri)
}
}
+#endif
+
+
+/** Test all of the triangles around a specific terrain vertex, looking to see if
+ * we are inside any of them. Return the intersecting triangle. This is all
+ * done in a 2d way.
+ */
+static struct tri *point_in_vert_tris(float *verts, struct vert_tris *vtris, float *point)
+{
+ for (int i = 0; i < vtris->tri_count; i++) {
+ struct tri *tri = &vtris->tris[i];
+ float *v1 = &verts[tri->vert_indices[0]];
+ float *v2 = &verts[tri->vert_indices[1]];
+ float *v3 = &verts[tri->vert_indices[2]];
+ if (point_in_tri(point, v1, v2, v3))
+ return tri;
+ }
+
+ return NULL;
+}
+
+
+
+static void get_terrain_penetration(float *verts, struct tri *tri, float *pos, float *move)
+{
+ float tmp[3], normal[3];
+
+ float *v1 = &verts[tri->vert_indices[0]];
+ float *v2 = &verts[tri->vert_indices[1]];
+ float *v3 = &verts[tri->vert_indices[2]];
+
+ vec3_subtract(v3, v2, tmp);
+ vec3_subtract(v2, v1, normal);
+ vec3_cross(tmp, normal, normal);
+ vec3_normalize(normal, normal);
+ vec3_subtract(v1, pos, tmp);
+ float d = vec3_dot(tmp, normal);
+ vec3_scale(normal, d, move);
+ /* vec3_add(pos, tmp, move); */
+}
-void collide_terrain(struct terrain *terrain, struct node *node, struct model *model, vec3 *move)
+
+void collide_terrain(struct terrain *terrain, float *pos, struct model *model, vec3 *move)
{
struct terrain_cell *cells[9] = {0};
struct grid_query queries[3];
@@ -118,8 +161,6 @@ void collide_terrain(struct terrain *terrain, struct node *node, struct model *m
queries[i].cell_vert_index = -1;
}
- float *pos = node_world(node);
-
query_terrain_grid(terrain, pos[0], pos[1], cells);
get_closest_verts(terrain, pos, queries, cells);
@@ -129,11 +170,12 @@ void collide_terrain(struct terrain *terrain, struct node *node, struct model *m
for (int i = 0; i < vtris->tri_count; i++) {;
/* terrain_cell_debug(terrain, queries[i].cell, queries[i].cell_vert_index, pos); */
- terrain_tri_debug(terrain->verts, &vtris->tris[i]);
+
+ 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);
+ return;
+ }
}
}
-
-
- /* assert(closest_cells[0]); */
- /* assert(closest_cells[1]); */
- /* assert(closest_cells[2]); */
diff --git a/src/terrain_collision.h b/src/terrain_collision.h
@@ -6,6 +6,6 @@
#include "node.h"
#include "model.h"
-void collide_terrain(struct terrain *terrain, struct node *node, struct model *model, float *move);
+void collide_terrain(struct terrain *terrain, float *pos, struct model *model, float *move);
#endif /* TERRAIN_COLLISION_H */
diff --git a/src/update.c b/src/update.c
@@ -1,7 +1,7 @@
#include "gl.h"
#include "update.h"
-#include "terrain.h"
+#include "terrain_collision.h"
#include "util.h"
#include "mat4.h"
#include "vec3.h"
@@ -338,10 +338,14 @@ static void player_update(struct game *game, struct entity *player)
struct terrain *terrain = &game->terrain;
- player_terrain_collision(terrain, node);
+ /* player_terrain_collision(terrain, node); */
+
+ float move[3];
+ collide_terrain(terrain, node_world(node), NULL, move);
+ node_translate(node, move);
+ /* vec3_add(player->velocity, move, player->velocity); */
+
- collide_terrain(terrain, node, NULL, NULL);
- node_recalc(node);
}
@@ -362,7 +366,7 @@ void update (struct game *game) {
float *time = &res->time;
float *light = res->light_dir;
- gravity(game);
+ /* gravity(game); */
if (needs_terrain_update) {
/* update_terrain(terrain); */
@@ -419,6 +423,8 @@ void update (struct game *game) {
toggle_fog = 0;
}
+ /* for (int i = 0; i < ) */
+
*time = SDL_GetTicks();
day_night_cycle(*time, res);