]> git.lizzy.rs Git - dragonblocks_alpha.git/commitdiff
Physics and collision
authorElias Fleckenstein <eliasfleckenstein@web.de>
Sat, 10 Jul 2021 13:05:52 +0000 (15:05 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Sat, 10 Jul 2021 13:05:52 +0000 (15:05 +0200)
src/client.c
src/clientplayer.c
src/clientplayer.h
src/node.c
src/node.h

index ab6460b912634b6adee4d359561c08d2680ec2c8..e3c3a402ebf43deb350ae08a6d4a8de6cee3df2c 100644 (file)
@@ -92,13 +92,15 @@ static void client_loop()
 
        init_camera(window, prog);
 
-       set_camera_position(client.player.pos);
-       set_camera_angle(client.player.yaw, client.player.pitch);
+       set_camera_position((v3f) {0.0f, 0.0f, 0.0f});
+       set_camera_angle(0.0f, 0.0f);
 
        set_window_size(width, height);
 
        init_input(&client, window);
 
+       clientplayer_send_pos(&client.player);
+
        struct timespec ts, ts_old;
        clock_gettime(CLOCK_REALTIME, &ts_old);
 
@@ -172,10 +174,8 @@ static void client_start(int fd)
        client.name = NULL;
        client.map = map_create();
        client.scene = scene_create();
-       client.player.client = &client;
-       client.player.pos = (v3f) {0.0f, 0.0f, 0.0f};
-       client.player.yaw = client.player.pitch = 0.0;
 
+       clientplayer_init(&client);
        clientmap_init(&client);
 
        pthread_t recv_thread;
index 4ed3f73076717f19c3bf4b1011a2dec3e1cc158a..19e1fdaa7f0859404c5e51f3608de544a9941630 100644 (file)
@@ -1,26 +1,68 @@
+#include <stdio.h>
 #include "camera.h"
 #include "client.h"
 #include "clientplayer.h"
 
-static void send_pos(ClientPlayer *player)
+void clientplayer_send_pos(ClientPlayer *player)
 {
        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);
 }
 
+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.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;
+}
+
+static bool collision(ClientPlayer *player)
+{
+       aabb3f box = {
+               {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;
+
+                               if (node == NODE_UNLOADED || node_definitions[node].solid)
+                                       return true;
+                       }
+               }
+       }
+
+       return false;
+}
+
 void clientplayer_tick(ClientPlayer *player, f64 dtime)
 {
        v3f old_pos = player->pos;
 
-       player->pos.x += player->velocity.x * dtime;
-       player->pos.y += player->velocity.y * dtime;
-       player->pos.z += player->velocity.z * dtime;
+#define CALC_PHYSICS(pos, velocity, old) \
+       pos += velocity * dtime; \
+       if (collision(player)) { \
+               pos = old; \
+               velocity = 0.0f; \
+       }
+
+       CALC_PHYSICS(player->pos.x, player->velocity.x, old_pos.x)
+       CALC_PHYSICS(player->pos.y, player->velocity.y, old_pos.y)
+       CALC_PHYSICS(player->pos.z, player->velocity.z, old_pos.z)
+
+#undef CALC_PHYSICS
 
+       // gravity
        player->velocity.y -= 9.81f * dtime;
 
        if (old_pos.x != player->pos.x || old_pos.y != player->pos.y || old_pos.z != player->pos.z) {
-               send_pos(player);
-               set_camera_position(player->pos);
+               clientplayer_send_pos(player);
+               set_camera_position((v3f) {player->pos.x, player->pos.y + player->eye_height, player->pos.z});
        }
 }
index 357e84f9e3b6fea92d5f8b999476711bed31fa4b..e976ea045787f7d2a974e01d6666a6528a095f2b 100644 (file)
@@ -7,10 +7,14 @@ typedef struct
 {
        struct Client *client;
        v3f pos;
-       f32 yaw, pitch;
        v3f velocity;
+       aabb3f box;
+       f32 yaw, pitch;
+       f32 eye_height;
 } ClientPlayer;
 
+void clientplayer_init(struct Client *client);
+void clientplayer_send_pos(ClientPlayer *player);
 void clientplayer_tick(ClientPlayer *player, f64 dtime);
 
 #endif
index 8c7de65d133aa0b77cf1238f76b1c46e9557aa6c..be90a69994a34ba993e8f54457c60f2862c8a57e 100644 (file)
@@ -2,9 +2,29 @@
 #include "util.h"
 
 NodeDefintion node_definitions[NODE_UNLOADED] = {
-       {true},
-       {false},
-       {true},
-       {true},
-       {true},
+       // invalid
+       {
+               .visible = true,
+               .solid = true,
+       },
+       // air
+       {
+               .visible = false,
+               .solid = false,
+       },
+       // grass
+       {
+               .visible = true,
+               .solid = true,
+       },
+       // dirt
+       {
+               .visible = true,
+               .solid = true,
+       },
+       // stone
+       {
+               .visible = true,
+               .solid = true,
+       },
 };
index aef57e8dfc10a769f84f98d1d9bf39fcd78ab776..6028500cc621a7cc1a1a791b712c78c96298fe69 100644 (file)
@@ -17,6 +17,7 @@ typedef enum
 typedef struct
 {
        bool visible;
+       bool solid;
 } NodeDefintion;
 
 extern NodeDefintion node_definitions[];