]> git.lizzy.rs Git - dragonblocks_alpha.git/commitdiff
Proper collision; add jumping
authorElias Fleckenstein <eliasfleckenstein@web.de>
Sat, 10 Jul 2021 21:16:12 +0000 (23:16 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Sat, 10 Jul 2021 21:16:12 +0000 (23:16 +0200)
14 files changed:
src/Makefile
src/blockmesh.c
src/camera.c
src/camera.h
src/client.c
src/clientplayer.c
src/clientplayer.h
src/cube.c [new file with mode: 0644]
src/cube.h [new file with mode: 0644]
src/facecache.c
src/input.c
src/mesh.c
src/mesh.h
textures/player.png [new file with mode: 0644]

index 089576571947036c3edd1771197d3a1fdcf58df0..9efbb23921b7a57a7465a3bdf3c2a47e1c7c08f0 100644 (file)
@@ -1,6 +1,6 @@
 COMMON = array.o list.o map.o signal.o util.o types.o node.o queue.o
 SERVER = $(COMMON) server.o servercommands.o servermap.o perlin.o facecache.o mapgen.o mapdb.o
-CLIENT = $(COMMON) camera.o client.o clientcommands.o clientmap.o clientnode.o clientplayer.o input.o mesh.o scene.o shaders.o blockmesh.o texture.o
+CLIENT = $(COMMON) camera.o client.o clientcommands.o clientmap.o clientnode.o clientplayer.o cube.o input.o mesh.o scene.o shaders.o blockmesh.o texture.o
 LIBRARIES = -lpthread -lm -lz
 FLAGS = -g -fmax-errors=4
 
index d590fe06e20340f06f6462da73753e397af68ab0..12bbcdfa667688d0f5a7067a23ea4d23f15fa246 100644 (file)
@@ -1,56 +1,6 @@
 #include "blockmesh.h"
 #include "clientnode.h"
-
-Vertex cube_vertices[6][6] = {
-       {
-               {-0.5, -0.5, -0.5, +0.0, +0.0},
-               {+0.5, -0.5, -0.5, +1.0, +0.0},
-               {+0.5, +0.5, -0.5, +1.0, +1.0},
-               {+0.5, +0.5, -0.5, +1.0, +1.0},
-               {-0.5, +0.5, -0.5, +0.0, +1.0},
-               {-0.5, -0.5, -0.5, +0.0, +0.0},
-       },
-       {
-               {-0.5, -0.5, +0.5, +0.0, +0.0},
-               {+0.5, +0.5, +0.5, +1.0, +1.0},
-               {+0.5, -0.5, +0.5, +1.0, +0.0},
-               {+0.5, +0.5, +0.5, +1.0, +1.0},
-               {-0.5, -0.5, +0.5, +0.0, +0.0},
-               {-0.5, +0.5, +0.5, +0.0, +1.0},
-       },
-       {
-               {-0.5, +0.5, +0.5, +1.0, +1.0},
-               {-0.5, -0.5, -0.5, +0.0, +0.0},
-               {-0.5, +0.5, -0.5, +0.0, +1.0},
-               {-0.5, -0.5, -0.5, +0.0, +0.0},
-               {-0.5, +0.5, +0.5, +1.0, +1.0},
-               {-0.5, -0.5, +0.5, +1.0, +0.0},
-       },
-       {
-               {+0.5, +0.5, +0.5, +1.0, +1.0},
-               {+0.5, +0.5, -0.5, +0.0, +1.0},
-               {+0.5, -0.5, -0.5, +0.0, +0.0},
-               {+0.5, -0.5, -0.5, +0.0, +0.0},
-               {+0.5, -0.5, +0.5, +1.0, +0.0},
-               {+0.5, +0.5, +0.5, +1.0, +1.0},
-       },
-       {
-               {-0.5, -0.5, -0.5, +0.0, +1.0},
-               {+0.5, -0.5, -0.5, +1.0, +1.0},
-               {+0.5, -0.5, +0.5, +1.0, +0.0},
-               {+0.5, -0.5, +0.5, +1.0, +0.0},
-               {-0.5, -0.5, +0.5, +0.0, +0.0},
-               {-0.5, -0.5, -0.5, +0.0, +1.0},
-       },
-       {
-               {-0.5, +0.5, -0.5, +0.0, +1.0},
-               {+0.5, +0.5, -0.5, +1.0, +1.0},
-               {+0.5, +0.5, +0.5, +1.0, +0.0},
-               {+0.5, +0.5, +0.5, +1.0, +0.0},
-               {-0.5, +0.5, +0.5, +0.0, +0.0},
-               {-0.5, +0.5, -0.5, +0.0, +1.0},
-       },
-};
+#include "cube.h"
 
 static v3s8 fdir[6] = {
        {+0, +0, -1},
@@ -67,7 +17,7 @@ static VertexBuffer make_vertices(MapBlock *block, Map *map)
 
        ITERATE_MAPBLOCK {
                if (node_definitions[block->data[x][y][z].type].visible) {
-                       v3f offset = {x + 8.5f, y + 8.5f, z + 8.5f};
+                       v3f offset = {x + 8.0f, y + 8.0f, z + 8.0f};
 
                        vertexbuffer_set_texture(&buffer, client_node_definitions[block->data[x][y][z].type].texture);
 
index 6341c02e9066ba491afe9045da27b8bf63f461f8..f534ff307ff16a0d473efb685df63e03af6bb6f7 100644 (file)
@@ -52,8 +52,6 @@ void set_camera_angle(f32 yaw, f32 pitch)
        vec3_mul_cross(camera.up, camera.right, camera.front);
        vec3_norm(camera.up, camera.up);
 
-       movement_dirs.up[1] = world_up[1];
-
        update_camera();
 }
 
index c2aaa2098c5404916f7860d13198dab7f9785d76..d0725a6e42c6c8a8fd935fd5403428b6b5f5bbf4 100644 (file)
@@ -16,7 +16,6 @@ extern struct movement_dirs
 {
        vec3 front;
        vec3 right;
-       vec3 up;
 } movement_dirs;
 
 #endif
index e3c3a402ebf43deb350ae08a6d4a8de6cee3df2c..27f424d081671bf66a299c028c500c3ec8c446f5 100644 (file)
@@ -99,7 +99,7 @@ static void client_loop()
 
        init_input(&client, window);
 
-       clientplayer_send_pos(&client.player);
+       clientplayer_add_to_scene(&client.player);
 
        struct timespec ts, ts_old;
        clock_gettime(CLOCK_REALTIME, &ts_old);
@@ -112,6 +112,7 @@ static void client_loop()
                glEnable(GL_DEPTH_TEST);
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                glClearColor(0.52941176470588f, 0.8078431372549f, 0.92156862745098f, 1.0f);
+               glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 
                process_input();
                clientplayer_tick(&client.player, dtime);
index d12d4acb0169b847d7d93684c4e459b8c903b88f..a6259a62f3dfff1bc5bbf913c30bcfd0d5a8f07c 100644 (file)
@@ -1,46 +1,97 @@
-#include <stdio.h>
 #include "camera.h"
 #include "client.h"
 #include "clientplayer.h"
+#include "cube.h"
+#include "texture.h"
 
-void clientplayer_send_pos(ClientPlayer *player)
+static void update_pos(ClientPlayer *player)
 {
+       set_camera_position((v3f) {player->pos.x, player->pos.y + player->eye_height, player->pos.z});
+
        pthread_mutex_lock(&player->client->mtx);
        (void) (write_u32(player->client->fd, SC_POS) && write_v3f32(player->client->fd, player->pos));
        pthread_mutex_unlock(&player->client->mtx);
+
+       player->obj->pos = player->pos;
+       meshobject_transform(player->obj);
 }
 
 void clientplayer_init(Client *client)
 {
        client->player.client = client;
        client->player.pos = (v3f) {0.0f, 25.0f, 0.0f};
-       client->player.velocity = (v3f) {0.0f, 25.0f, 0.0f};
+       client->player.velocity = (v3f) {0.0f, 0.0f, 0.0f};
        client->player.box = (aabb3f) {{-0.3f, 0.0f, -0.3f}, {0.3f, 1.75f, 0.3f}};
        client->player.yaw = client->player.pitch = 0.0f;
-       client->player.eye_height = 1.6f;
+       client->player.eye_height = 1.5f;
+}
+
+void clientplayer_add_to_scene(ClientPlayer *player)
+{
+       VertexBuffer buffer = vertexbuffer_create();
+       vertexbuffer_set_texture(&buffer, get_texture(RESSOURCEPATH "textures/player.png"));
+
+       for (int f = 0; f < 6; f++) {
+               for (int v = 0; v < 6; v++) {
+                       Vertex vertex = cube_vertices[f][v];
+                       vertex.y += 0.5;
+                       vertexbuffer_add_vertex(&buffer, &vertex);
+               }
+       }
+
+       player->obj = meshobject_create(buffer, player->client->scene, (v3f) {0.0f, 0.0f, 0.0f});
+       player->obj->scale = (v3f) {0.6f, 1.75f, 0.6f};
+       player->obj->visible = false;
+
+       update_pos(player);
 }
 
-static bool collision(ClientPlayer *player)
+static aabb3f get_box(ClientPlayer *player)
 {
-       aabb3f box = {
+       return (aabb3f) {
                {player->box.min.x + player->pos.x, player->box.min.y + player->pos.y, player->box.min.z + player->pos.z},
                {player->box.max.x + player->pos.x, player->box.max.y + player->pos.y, player->box.max.z + player->pos.z},
        };
+}
 
-       for (s32 x = floor(box.min.x); x <= ceil(box.max.x - 0.01f) - 1; x++) {
-               for (s32 y = floor(box.min.y); y <= ceil(box.max.y - 0.01f) - 1; y++) {
-                       for (s32 z = floor(box.min.z); z <= ceil(box.max.z - 0.01f) - 1; z++) {
-                               Node node = map_get_node(player->client->map, (v3s32) {x, y, z}).type;
+static aabb3s32 round_box(aabb3f box)
+{
+       return (aabb3s32) {
+               {floor(box.min.x + 0.5f), floor(box.min.y + 0.5f), floor(box.min.z + 0.5f)},
+               {ceil(box.max.x - 0.5f), ceil(box.max.y - 0.5f), ceil(box.max.z - 0.5f)},
+       };
+}
 
-                               if (node == NODE_UNLOADED || node_definitions[node].solid)
-                                       return true;
-                       }
-               }
-       }
+static bool is_solid(Map *map, s32 x, s32 y, s32 z)
+{
+       Node node = map_get_node(map, (v3s32) {x, y, z}).type;
+       return node == NODE_UNLOADED || node_definitions[node].solid;
+}
+
+static bool can_jump(ClientPlayer *player)
+{
+       aabb3f fbox = get_box(player);
+       fbox.min.y -= 0.5f;
+
+       aabb3s32 box = round_box(fbox);
+
+       if (fbox.min.y - (f32) box.min.y > 0.01f)
+               return false;
+
+       for (s32 x = box.min.x; x <= box.max.x; x++)
+               for (s32 z = box.min.z; z <= box.max.z; z++)
+                       if (is_solid(player->client->map, x, box.min.y, z))
+                               return true;
 
        return false;
 }
 
+void clientplayer_jump(ClientPlayer *player)
+{
+       if (can_jump(player))
+               player->velocity.y += 6.5f;
+}
+
 void clientplayer_tick(ClientPlayer *player, f64 dtime)
 {
        v3f old_pos = player->pos;
@@ -48,21 +99,51 @@ void clientplayer_tick(ClientPlayer *player, f64 dtime)
 
        player->velocity.y -= 9.81f * dtime;
 
-#define CALC_PHYSICS(pos, velocity, old_pos, old_velocity) \
-       pos += (velocity + old_velocity) / 2.0f * dtime; \
-       if (collision(player)) { \
-               pos = old_pos; \
-               velocity = 0.0f; \
+#define GETS(vec, comp) *(s32 *) ((char *) &vec + offsetof(v3s32, comp))
+#define GETF(vec, comp) *(f32 *) ((char *) &vec + offsetof(v3f32, comp))
+#define PHYSICS(a, b, c) { \
+               f32 v = (GETF(player->velocity, a) + GETF(old_velocity, a)) / 2.0f; \
+               if (v == 0.0f) \
+                       goto a ## _physics_done; \
+               aabb3s32 box = round_box(get_box(player)); \
+               v3f old_pos = player->pos; \
+               GETF(player->pos, a) += v * dtime; \
+               s32 dir; \
+               f32 offset; \
+               if (v > 0.0f) { \
+                       dir = +1; \
+                       offset = GETF(player->box.max, a); \
+                       GETS(box.min, a) = ceil(GETF(old_pos, a) + offset + 0.5f); \
+                       GETS(box.max, a) = floor(GETF(player->pos, a) + offset + 0.5f); \
+               } else { \
+                       dir = -1; \
+                       offset = GETF(player->box.min, a); \
+                       GETS(box.min, a) = floor(GETF(old_pos, a) + offset - 0.5f); \
+                       GETS(box.max, a) = ceil(GETF(player->pos, a) + offset - 0.5f); \
+               } \
+               GETS(box.max, a) += dir; \
+               for (s32 a = GETS(box.min, a); a != GETS(box.max, a); a += dir) { \
+                       for (s32 b = GETS(box.min, b); b <= GETS(box.max, b); b++) { \
+                               for (s32 c = GETS(box.min, c); c <= GETS(box.max, c); c++) { \
+                                       if (is_solid(player->client->map, x, y, z)) { \
+                                               GETF(player->pos, a) = (f32) a - offset - 0.5f * (f32) dir; \
+                                               GETF(player->velocity, a) = 0.0f; \
+                                               goto a ## _physics_done; \
+                                       } \
+                               } \
+                       } \
+               } \
+               a ## _physics_done: (void) 0;\
        }
 
-       CALC_PHYSICS(player->pos.x, player->velocity.x, old_pos.x, old_velocity.x)
-       CALC_PHYSICS(player->pos.y, player->velocity.y, old_pos.y, old_velocity.y)
-       CALC_PHYSICS(player->pos.z, player->velocity.z, old_pos.z, old_velocity.z)
+       PHYSICS(x, y, z)
+       PHYSICS(y, x, z)
+       PHYSICS(z, x, y)
 
-#undef CALC_PHYSICS
+#undef GETS
+#undef GETF
+#undef PHYSICS
 
-       if (old_pos.x != player->pos.x || old_pos.y != player->pos.y || old_pos.z != player->pos.z) {
-               clientplayer_send_pos(player);
-               set_camera_position((v3f) {player->pos.x, player->pos.y + player->eye_height, player->pos.z});
-       }
+       if (old_pos.x != player->pos.x || old_pos.y != player->pos.y || old_pos.z != player->pos.z)
+               update_pos(player);
 }
index e976ea045787f7d2a974e01d6666a6528a095f2b..b28410814f57d7b83a9e6b41022522b0a13f4141 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _CLIENTPLAYER_H_
 #define _CLIENTPLAYER_H_
 
+#include "mesh.h"
 #include "types.h"
 
 typedef struct
@@ -11,10 +12,12 @@ typedef struct
        aabb3f box;
        f32 yaw, pitch;
        f32 eye_height;
+       MeshObject *obj;
 } ClientPlayer;
 
 void clientplayer_init(struct Client *client);
-void clientplayer_send_pos(ClientPlayer *player);
+void clientplayer_add_to_scene(ClientPlayer *player);
+void clientplayer_jump(ClientPlayer *player);
 void clientplayer_tick(ClientPlayer *player, f64 dtime);
 
 #endif
diff --git a/src/cube.c b/src/cube.c
new file mode 100644 (file)
index 0000000..80d6d82
--- /dev/null
@@ -0,0 +1,53 @@
+#include "cube.h"
+
+Vertex cube_vertices[6][6] = {
+       {
+               {-0.5, -0.5, -0.5, +0.0, +0.0},
+               {+0.5, -0.5, -0.5, +1.0, +0.0},
+               {+0.5, +0.5, -0.5, +1.0, +1.0},
+               {+0.5, +0.5, -0.5, +1.0, +1.0},
+               {-0.5, +0.5, -0.5, +0.0, +1.0},
+               {-0.5, -0.5, -0.5, +0.0, +0.0},
+       },
+       {
+               {-0.5, -0.5, +0.5, +0.0, +0.0},
+               {+0.5, +0.5, +0.5, +1.0, +1.0},
+               {+0.5, -0.5, +0.5, +1.0, +0.0},
+               {+0.5, +0.5, +0.5, +1.0, +1.0},
+               {-0.5, -0.5, +0.5, +0.0, +0.0},
+               {-0.5, +0.5, +0.5, +0.0, +1.0},
+       },
+       {
+               {-0.5, +0.5, +0.5, +1.0, +1.0},
+               {-0.5, -0.5, -0.5, +0.0, +0.0},
+               {-0.5, +0.5, -0.5, +0.0, +1.0},
+               {-0.5, -0.5, -0.5, +0.0, +0.0},
+               {-0.5, +0.5, +0.5, +1.0, +1.0},
+               {-0.5, -0.5, +0.5, +1.0, +0.0},
+       },
+       {
+               {+0.5, +0.5, +0.5, +1.0, +1.0},
+               {+0.5, +0.5, -0.5, +0.0, +1.0},
+               {+0.5, -0.5, -0.5, +0.0, +0.0},
+               {+0.5, -0.5, -0.5, +0.0, +0.0},
+               {+0.5, -0.5, +0.5, +1.0, +0.0},
+               {+0.5, +0.5, +0.5, +1.0, +1.0},
+       },
+       {
+               {-0.5, -0.5, -0.5, +0.0, +1.0},
+               {+0.5, -0.5, -0.5, +1.0, +1.0},
+               {+0.5, -0.5, +0.5, +1.0, +0.0},
+               {+0.5, -0.5, +0.5, +1.0, +0.0},
+               {-0.5, -0.5, +0.5, +0.0, +0.0},
+               {-0.5, -0.5, -0.5, +0.0, +1.0},
+       },
+       {
+               {-0.5, +0.5, -0.5, +0.0, +1.0},
+               {+0.5, +0.5, -0.5, +1.0, +1.0},
+               {+0.5, +0.5, +0.5, +1.0, +0.0},
+               {+0.5, +0.5, +0.5, +1.0, +0.0},
+               {-0.5, +0.5, +0.5, +0.0, +0.0},
+               {-0.5, +0.5, -0.5, +0.0, +1.0},
+       },
+};
+
diff --git a/src/cube.h b/src/cube.h
new file mode 100644 (file)
index 0000000..837c593
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _CUBE_H_
+#define _CUBE_H_
+
+#include "mesh.h"
+
+extern Vertex cube_vertices[6][6];
+
+#endif
index 8c8176586321e32b465366d1f7f061af051711b9..341cb24b2aee7e36b1fa9d6ce731196a0bc580cd 100644 (file)
@@ -13,7 +13,7 @@ __attribute((constructor)) static void init_face_cache()
 {
        facecache.size = 0;
        facecache.positions = array_create(sizeof(v3s32));
-       v3s32 pos = {0};
+       v3s32 pos = {0, 0, 0};
        array_append(&facecache.positions, &pos);
        pthread_mutex_init(&facecache.mtx, NULL);
 }
@@ -86,5 +86,5 @@ v3s32 get_face(size_t i, v3s32 *base)
 size_t get_face_count(u32 size)
 {
        size_t len = 1 + size * 2;
-       return len * len * len;
+       return 1 + len * len * len;
 }
index dcccddcc6b9de70903bf64067fecd02d2e8fe18b..52f6d1d6725f82281ae43b65647f644b60f9ad96 100644 (file)
@@ -29,7 +29,7 @@ static void cursor_pos_callback(__attribute__((unused)) GLFWwindow* window, doub
 static bool move(int forward, int backward, vec3 dir)
 {
        f32 sign;
-       f32 speed = 10.0f;
+       f32 speed = 4.0f;
 
        if (glfwGetKey(input.window, forward) == GLFW_PRESS)
                sign = +1.0f;
@@ -39,7 +39,6 @@ static bool move(int forward, int backward, vec3 dir)
                return false;
 
        input.client->player.velocity.x += dir[0] * speed * sign;
-       // input.client->player.velocity.y += dir[1] * speed * sign;
        input.client->player.velocity.z += dir[2] * speed * sign;
 
        return true;
@@ -48,12 +47,13 @@ static bool move(int forward, int backward, vec3 dir)
 void process_input()
 {
        input.client->player.velocity.x = 0.0f;
-       // input.client->player.velocity.y = 0.0f;
        input.client->player.velocity.z = 0.0f;
 
        move(GLFW_KEY_W, GLFW_KEY_S, movement_dirs.front);
-       move(GLFW_KEY_SPACE, GLFW_KEY_LEFT_SHIFT, movement_dirs.up);
        move(GLFW_KEY_D, GLFW_KEY_A, movement_dirs.right);
+
+       if (glfwGetKey(input.window, GLFW_KEY_SPACE) == GLFW_PRESS)
+               clientplayer_jump(&input.client->player);
 }
 
 void init_input(Client *client, GLFWwindow *window)
index a9489d0e6971e6599b6c243ca652526f6bd96157..341789038291d933be249ce83b2ef8d1d2cbbc35 100644 (file)
@@ -61,6 +61,7 @@ MeshObject *meshobject_create(VertexBuffer buffer, struct Scene *scene, v3f pos)
        obj->rot = (v3f) {0.0f, 0.0f, 0.0f};
        obj->scale = (v3f) {1.0f, 1.0f, 1.0f};
        obj->angle = 0.0f;
+       obj->visible = true;
        meshobject_transform(obj);
 
        qsort(buffer.faces.ptr, buffer.faces.siz, sizeof(Face), &qsort_compare_faces);
@@ -147,6 +148,9 @@ static void mesh_configure(Mesh *mesh)
 
 void meshobject_render(MeshObject *obj, ShaderProgram *prog)
 {
+       if (! obj->visible)
+               return;
+
        glUniformMatrix4fv(prog->loc_model, 1, GL_FALSE, obj->transform[0]);
 
        glActiveTexture(GL_TEXTURE0);
index e7471e81b7552c66e1098fd33b9f644d286a2c45..a7b11affca4be83f3680c0fcfd36cdc8a5ef73d3 100644 (file)
@@ -39,6 +39,7 @@ typedef struct
 {
        v3f pos, rot, scale;
        f32 angle;
+       bool visible;
        mat4x4 transform;
        bool remove;
        Mesh **meshes;
diff --git a/textures/player.png b/textures/player.png
new file mode 100644 (file)
index 0000000..677a773
Binary files /dev/null and b/textures/player.png differ