commit 81a52fbdaabd1fc1e321d6dce6cbf55677f46e1f
parent 6bb1b1f05bcf2d7900cef18fc6ba1134769418c8
Author: William Casarin <jb55@jb55.com>
Date: Sun, 28 Jul 2019 16:04:32 -0700
initial physics and jumping
Diffstat:
10 files changed, 79 insertions(+), 24 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 = 0;
+ ent->flags &= ~ENT_CASTS_SHADOWS;
return ent;
}
diff --git a/src/entity.h b/src/entity.h
@@ -11,8 +11,10 @@
#define MAX_ENTITIES 2048
enum entity_flags {
- ENT_IS_PLAYER = 1 << 0,
- ENT_INVISIBLE = 1 << 1,
+ ENT_IS_PLAYER = 1 << 0,
+ ENT_INVISIBLE = 1 << 1,
+ ENT_CASTS_SHADOWS = 1 << 2,
+ ENT_AT_REST = 1 << 3,
};
struct entity {
@@ -21,7 +23,6 @@ struct entity {
u32 flags;
float velocity[3];
float accel[3];
- int casts_shadows;
};
typedef struct resource_id entity_id;
diff --git a/src/game.c b/src/game.c
@@ -178,7 +178,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;
+ player->flags |= ENT_CASTS_SHADOWS;
struct node *pnode = &static_nodes()[node_player];
assert(pnode);
res->player_id = make_static_id(entity_player);
diff --git a/src/node.c b/src/node.c
@@ -83,7 +83,7 @@ void node_scale(struct node *node, float val) {
void node_translate(struct node *node, vec3 *p) {
if (vec3_isall(p, 0))
- return;
+ return;
/* printf("translating %f %f %f\n", p[0], p[1], p[2]); */
vec3_add(node->pos, p, node->pos);
diff --git a/src/render.c b/src/render.c
@@ -306,7 +306,7 @@ void render (struct game *game, struct render_config *config) {
if (entity->flags & ENT_INVISIBLE)
continue;
- if (config->is_depth_pass && !entity->casts_shadows)
+ if (config->is_depth_pass && !(entity->flags & ENT_CASTS_SHADOWS))
continue;
// TODO this is a bit wonky, refactor this
diff --git a/src/terrain.c b/src/terrain.c
@@ -66,7 +66,7 @@ void init_terrain(struct terrain *terrain, float size) {
model->shading = SHADING_TERRAIN;
node_set_label(node, "terrain");
- ent->casts_shadows = 0;
+ ent->flags &= ~ENT_CASTS_SHADOWS;
// this is scale for some reason!?
/* node->pos[2] = 20.0; */
diff --git a/src/terrain_collision.c b/src/terrain_collision.c
@@ -82,7 +82,7 @@ static void terrain_tri_debug(float *verts, struct tri *tri)
if (is_null_id(&tri->debug_id)) {
- float tmp[3];
+ float tmp[3], tmp2[3], normal[3];
float *v1 = &verts[tri->vert_indices[0]];
float *v2 = &verts[tri->vert_indices[1]];
@@ -94,7 +94,9 @@ static void terrain_tri_debug(float *verts, struct tri *tri)
/* v3[0], v3[1]); */
vec3_subtract(v1, v2, tmp);
+ vec3_subtract(v2, v3, tmp2);
+ vec3_cross(tmp, tmp2, normal);
/* debug("tmp %f %f\n", tmp[0], tmp[1]); */
vec3_scale(tmp, 0.5, tmp);
@@ -105,7 +107,13 @@ static void terrain_tri_debug(float *verts, struct tri *tri)
/* debug("creating new grid_debug entity at %f %f %f\n", tmp[0], tmp[1], tmp[2]); */
- new_debug_entity(&tri->debug_id, tmp);
+ struct entity *ent = new_debug_entity(&tri->debug_id, tmp);
+ struct node *node = get_node(&ent->node_id);
+
+ vec3_normalize(normal, normal);
+ /* vec3_scale(normal, 180/PI, normal); */
+ node_rotate(node, normal);
+ node_recalc(node);
}
}
@@ -151,7 +159,7 @@ static void get_terrain_penetration(float *verts, struct tri *tri, float *pos, f
}
-void collide_terrain(struct terrain *terrain, float *pos, struct model *model, vec3 *move)
+struct tri *collide_terrain(struct terrain *terrain, float *pos, struct model *model, vec3 *move)
{
struct terrain_cell *cells[9] = {0};
struct grid_query queries[3];
@@ -175,7 +183,9 @@ void collide_terrain(struct terrain *terrain, float *pos, struct model *model, v
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;
+ return tri;
}
}
+
+ return NULL;
}
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, float *pos, struct model *model, float *move);
+struct tri *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
@@ -23,7 +23,7 @@ static void movement(struct game *game, struct node *node, float speed_mult) {
amt *= speed_mult;
if (game->input.modifiers & KMOD_SHIFT)
- amt *= 50;
+ amt *= 20;
if (game->input.keystates[SDL_SCANCODE_A])
node_forward(node, V3(-amt,0,0));
@@ -240,12 +240,15 @@ static void day_night_cycle(float time, struct resources *res) {
static void gravity(struct game *game) {
struct entity *player = get_player(&game->test_resources);
+
+ if (player->flags & ENT_AT_REST)
+ return;
+
struct node *pnode = get_node(&player->node_id);
assert(pnode);
static const float g = -1.0;
-
- node_translate(pnode, V3(0.0, 0.0, g));
+ vec3_add(player->velocity, V3(0.0, 0.0, g * game->dt), player->velocity);
}
void orbit_update_from_mouse(struct orbit *camera, struct input *input,
@@ -315,6 +318,15 @@ static void camera_keep_above_ground(struct terrain *terrain,
}
}
+static void entity_jump(struct entity *ent)
+{
+ if (ent->flags & ENT_AT_REST) {
+ struct node *node = get_node(&ent->node_id);
+ debug("jumping\n");
+ vec3_forward(ent->velocity, node->orientation, V3(0.0, 0.0, 1.0), ent->velocity);
+ }
+}
+
static void player_update(struct game *game, struct entity *player)
{
@@ -341,11 +353,41 @@ static void player_update(struct game *game, struct entity *player)
/* 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); */
+ float scaled[3];
+ struct tri *tri = collide_terrain(terrain, node_world(node), NULL, move);
+ /* node_translate(node, move); */
+
+ if (tri) {
+ if (move[2] >= 0) {
+ node_translate(node, move);
+ player->flags |= ENT_AT_REST;
+ vec3_all(player->velocity, 0);
+ }
+ else {
+ player->flags &= ~ENT_AT_REST;
+ }
+ }
+
+ if (was_key_pressed_this_frame(game, SDL_SCANCODE_SPACE)) {
+ entity_jump(player);
+ }
+
+ if (!vec3_approxeq(player->velocity, V3(0,0,0)))
+ player->flags &= ~ENT_AT_REST;
+ /* debug("player velocity %f %f %f\n", */
+ /* player->velocity[0], */
+ /* player->velocity[1], */
+ /* player->velocity[2]); */
+ /* if (player->flags & ENT_AT_REST) */
+ /* vec3_scale(player->velocity, 0.00001, player->velocity); */
+
+ if (!(player->flags & ENT_AT_REST)) {
+ debug("player not a rest\n");
+ node_translate(node, player->velocity);
+ node_recalc(node);
+ }
}
@@ -366,7 +408,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); */
@@ -401,8 +443,9 @@ void update (struct game *game) {
game->wireframe ^= 1;
}
- if (was_key_pressed_this_frame(game, SDL_SCANCODE_C))
+ if (was_key_pressed_this_frame(game, SDL_SCANCODE_C)) {
printf("light_dir %f %f %f\n", light[0], light[1], light[2]);
+ }
if (was_key_pressed_this_frame(game, SDL_SCANCODE_F))
toggle_fog = 1;
diff --git a/src/vec3.h b/src/vec3.h
@@ -7,6 +7,9 @@
typedef float vec3;
+#define approxeq(a, b) (fabs(a-b) < EPSILON)
+#define EPSILON 0.0001
+#define vec3_approxeq(a, b) vec3_eq(a, b, EPSILON)
#define V3(x,y,z) ((vec3[3]){x,y,z})
static inline vec3 *vec3_create(vec3 *vec) {
@@ -221,7 +224,7 @@ static inline vec3 *vec3_all(vec3 *vec, float n) {
static inline int vec3_isall(vec3 *vec, float n) {
for (int i = 0; i < 3; ++i) {
- if (vec[i] != n)
+ if (!approxeq(vec[i], n))
return 0;
}
@@ -274,8 +277,6 @@ static inline vec3 *vec3_from_yaw_pitch(float yaw, float pitch, float *dest) {
return dest;
}
-#define EPSILON 0.0001
-#define vec3_approxeq(a, b) vec3_eq(a, b, EPSILON)
#endif /* VEC3_H */