]> git.lizzy.rs Git - dragonblocks_alpha.git/commitdiff
Add node selection box
authorElias Fleckenstein <eliasfleckenstein@web.de>
Mon, 18 Apr 2022 20:18:40 +0000 (22:18 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Mon, 18 Apr 2022 20:18:40 +0000 (22:18 +0200)
13 files changed:
deps/dragonnet
shaders/3d/selection/fragment.glsl [new file with mode: 0755]
shaders/3d/selection/vertex.glsl [new file with mode: 0755]
src/CMakeLists.txt
src/client/client_node.c
src/client/client_node.h
src/client/client_player.c
src/client/game.c
src/client/interact.c [new file with mode: 0644]
src/client/interact.h [new file with mode: 0644]
src/client/raycast.c [new file with mode: 0644]
src/client/raycast.h [new file with mode: 0644]
src/server/biomes.c

index 6d8f26f523570f440152abcfab5f2839d3c6b5b0..431e3bd29073d9c10ab3a853116860ba83ed1c5e 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 6d8f26f523570f440152abcfab5f2839d3c6b5b0
+Subproject commit 431e3bd29073d9c10ab3a853116860ba83ed1c5e
diff --git a/shaders/3d/selection/fragment.glsl b/shaders/3d/selection/fragment.glsl
new file mode 100755 (executable)
index 0000000..b591cd7
--- /dev/null
@@ -0,0 +1,8 @@
+out vec4 outColor;
+
+uniform vec3 color;
+
+void main()
+{
+       outColor = vec4(color, 0.1);
+}
diff --git a/shaders/3d/selection/vertex.glsl b/shaders/3d/selection/vertex.glsl
new file mode 100755 (executable)
index 0000000..65dc0d2
--- /dev/null
@@ -0,0 +1,8 @@
+layout(location = 0) in vec3 vertexPosition;
+
+uniform mat4 MVP;
+
+void main()
+{
+       gl_Position = MVP * vec4(vertexPosition, 1.0);
+}
index fe2de5104403c2192abc09e0693ad68b3b782438..4b7cede31fe2637ad84f89329514b12be1aec457 100644 (file)
@@ -106,9 +106,11 @@ add_executable(dragonblocks
        client/gl_debug.c
        client/gui.c
        client/input.c
+       client/interact.c
        client/light.c
        client/mesh.c
        client/model.c
+       client/raycast.c
        client/shader.c
        client/sky.c
        client/terrain_gfx.c
index 3a406196fc2f4138f3d13ce1e3d339368a5a9529..956e18fa0e49ab128f9e5c6fe01b4583b761c6ae 100644 (file)
@@ -45,6 +45,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_SOLID,
                .mipmap = true,
                .render = NULL,
+               .pointable = true,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
        // air
        {
@@ -52,6 +54,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_NONE,
                .mipmap = true,
                .render = NULL,
+               .pointable = false,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
        // grass
        {
@@ -59,6 +63,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_SOLID,
                .mipmap = true,
                .render = &render_grass,
+               .pointable = true,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
        // dirt
        {
@@ -66,6 +72,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_SOLID,
                .mipmap = true,
                .render = NULL,
+               .pointable = true,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
        // stone
        {
@@ -73,6 +81,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_SOLID,
                .mipmap = true,
                .render = &render_stone,
+               .pointable = true,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
        // snow
        {
@@ -80,6 +90,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_SOLID,
                .mipmap = true,
                .render = NULL,
+               .pointable = true,
+               .selection_color = {0.1f, 0.5f, 1.0f},
        },
        // oak wood
        {
@@ -91,6 +103,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_SOLID,
                .mipmap = true,
                .render = &render_color,
+               .pointable = true,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
        // oak leaves
        {
@@ -98,6 +112,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_SOLID,
                .mipmap = true,
                .render = &render_color,
+               .pointable = true,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
        // pine wood
        {
@@ -109,6 +125,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_SOLID,
                .mipmap = true,
                .render = &render_color,
+               .pointable = true,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
        // pine leaves
        {
@@ -116,6 +134,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_CLIP,
                .mipmap = true,
                .render = &render_color,
+               .pointable = true,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
        // palm wood
        {
@@ -127,6 +147,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_SOLID,
                .mipmap = true,
                .render = &render_color,
+               .pointable = true,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
        // palm leaves
        {
@@ -134,6 +156,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_SOLID,
                .mipmap = true,
                .render = &render_color,
+               .pointable = true,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
        // sand
        {
@@ -141,6 +165,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_SOLID,
                .mipmap = true,
                .render = NULL,
+               .pointable = true,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
        // water
        {
@@ -148,6 +174,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_BLEND,
                .mipmap = true,
                .render = NULL,
+               .pointable = false,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
        // lava
        {
@@ -155,6 +183,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_BLEND,
                .mipmap = true,
                .render = NULL,
+               .pointable = false,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
        // vulcano_stone
        {
@@ -162,6 +192,8 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .visibility = VISIBILITY_SOLID,
                .mipmap = true,
                .render = NULL,
+               .pointable = true,
+               .selection_color = {1.0f, 1.0f, 1.0f},
        },
 };
 
index a922df486fe63ab78ee103eb2cf042469a1dd0cc..7edcf661511ec4545b93c114d970d8892eac2921 100644 (file)
@@ -28,6 +28,8 @@ typedef struct {
        NodeVisibility visibility;
        bool mipmap;
        void (*render)(NodeArgsRender *args);
+       bool pointable;
+       v3f32 selection_color;
 } ClientNodeDefinition;
 
 extern ClientNodeDefinition client_node_definitions[];
index 3bc1b46a3743819b59fc126870a80658432b5e35..326ab53948e2033920a06ca1713acc3b34949e3d 100644 (file)
@@ -101,7 +101,7 @@ static void on_add(ClientEntity *entity)
        }, 7);
 
        entity->nametag_offset = bones->nametag ? &bones->nametag->abs : NULL;
-       entity->box_collision = (aabb3f32) {{-0.3f, 0.0f, -0.3f}, {0.3f, 1.8f, 0.3f}};
+       entity->box_collision = (aabb3f32) {{-0.45f, 0.0f, -0.45f}, {0.45f, 1.8f, 0.45f}};
 
        model_scene_add(entity->model);
        client_entity_transform(entity);
index 8cd2b7484f081ef755df614b313c8e5a2885ed24..c0554ebf5a02cc0d0efafa42d1e0fa9e687138c1 100644 (file)
@@ -18,6 +18,7 @@
 #include "client/gl_debug.h"
 #include "client/gui.h"
 #include "client/input.h"
+#include "client/interact.h"
 #include "client/sky.h"
 #include "client/window.h"
 #include "day.h"
@@ -62,6 +63,7 @@ static void render(f64 dtime)
 
        sky_render();
        model_scene_render(dtime);
+       interact_render();
        gui_render();
 }
 
@@ -89,6 +91,7 @@ static void game_loop()
 
                input_tick(dtime);
                client_player_tick(dtime);
+               interact_tick();
 
                debug_menu_changed(ENTRY_TIME);
                debug_menu_changed(ENTRY_DAYLIGHT);
@@ -123,6 +126,9 @@ bool game(Flag *gfx_init)
 
        client_player_gfx_init();
 
+       if (!interact_init())
+               return false;
+
        client_node_init();
        client_terrain_start();
 
@@ -148,6 +154,7 @@ bool game(Flag *gfx_init)
        terrain_gfx_deinit();
        client_entity_gfx_deinit();
        client_player_gfx_deinit();
+       interact_deinit();
 
        return true;
 }
diff --git a/src/client/interact.c b/src/client/interact.c
new file mode 100644 (file)
index 0000000..728bc29
--- /dev/null
@@ -0,0 +1,91 @@
+#include <linmath.h/linmath.h>
+#include <stdio.h>
+#include "client/camera.h"
+#include "client/client_node.h"
+#include "client/cube.h"
+#include "client/frustum.h"
+#include "client/gl_debug.h"
+#include "client/interact.h"
+#include "client/mesh.h"
+#include "client/raycast.h"
+#include "client/shader.h"
+
+static bool pointed;
+static v3s32 node_pos;
+static GLuint shader_prog;
+static GLint loc_MVP;
+static GLint loc_color;
+static mat4x4 model;
+
+typedef struct {
+       v3f32 position;
+} __attribute__((packed)) SelectionVertex;
+static Mesh selection_mesh = {
+       .layout = &(VertexLayout) {
+               .attributes = (VertexAttribute[]) {
+                       {GL_FLOAT, 3, sizeof(v3f32)},
+               },
+               .count = 1,
+               .size = sizeof(SelectionVertex),
+       },
+       .vao = 0,
+       .vbo = 0,
+       .data = NULL,
+       .count = 36,
+       .free_data = false,
+};
+
+bool interact_init()
+{
+       if (!shader_program_create(RESSOURCE_PATH "shaders/3d/selection", &shader_prog, NULL)) {
+               fprintf(stderr, "[error] failed to create selection shader program\n");
+               return false;
+       }
+
+       loc_MVP = glGetUniformLocation(shader_prog, "MVP"); GL_DEBUG
+       loc_color = glGetUniformLocation(shader_prog, "color"); GL_DEBUG
+
+       SelectionVertex vertices[6][6];
+       for (int f = 0; f < 6; f++)
+               for (int v = 0; v < 6; v++)
+                       vertices[f][v].position = v3f32_scale(cube_vertices[f][v].position, 1.1f);
+
+       selection_mesh.data = vertices;
+       mesh_upload(&selection_mesh);
+
+       return true;
+}
+
+void interact_deinit()
+{
+       glDeleteProgram(shader_prog); GL_DEBUG
+       mesh_destroy(&selection_mesh);
+}
+
+void interact_tick()
+{
+       v3s32 old_node_pos = node_pos;
+
+       NodeType node;
+       if ((pointed = raycast(
+                       (v3f64) {camera.eye  [0], camera.eye  [1], camera.eye  [2]}, 
+                       (v3f64) {camera.front[0], camera.front[1], camera.front[2]},
+                       5, &node_pos, &node)) && !v3s32_equals(node_pos, old_node_pos)) {
+               mat4x4_translate(model, node_pos.x, node_pos.y, node_pos.z);
+               v3f32 *color = &client_node_definitions[node].selection_color;
+               glProgramUniform3f(shader_prog, loc_color, color->x, color->y, color->z); GL_DEBUG
+       }
+}
+
+void interact_render()
+{
+       if (!pointed)
+               return;
+
+       mat4x4 mvp;
+       mat4x4_mul(mvp, frustum, model);
+
+       glUseProgram(shader_prog); GL_DEBUG
+       glUniformMatrix4fv(loc_MVP, 1, GL_FALSE, mvp[0]); GL_DEBUG
+       mesh_render(&selection_mesh);
+}
diff --git a/src/client/interact.h b/src/client/interact.h
new file mode 100644 (file)
index 0000000..707bb01
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _INTERACT_H_
+#define _INTERACT_H_
+
+bool interact_init();
+void interact_deinit();
+void interact_tick();
+void interact_render();
+
+#endif // _INTERACT_H_
diff --git a/src/client/raycast.c b/src/client/raycast.c
new file mode 100644 (file)
index 0000000..fba282d
--- /dev/null
@@ -0,0 +1,46 @@
+#include <math.h>
+#include "client/client_node.h"
+#include "client/client_terrain.h"
+#include "client/raycast.h"
+
+bool raycast(v3f64 pos, v3f64 dir, f64 len, v3s32 *node_pos, NodeType *node)
+{
+       f64 dir_len = sqrt(dir.x * dir.x + dir.y * dir.y + dir.z * dir.z);
+
+       while (len > 0) {
+               *node = terrain_get_node(client_terrain,
+                       *node_pos = (v3s32) {floor(pos.x + 0.5), floor(pos.y + 0.5), floor(pos.z + 0.5)}).type;
+
+               if (*node == NODE_UNLOADED)
+                       return false;
+
+               if (client_node_definitions[*node].pointable)
+                       return true;
+
+               f64 vpos[3] = {pos.x, pos.y, pos.z};
+               f64 vdir[3] = {dir.x, dir.y, dir.z};
+               f64 min_mul = 1.0;
+
+               for (int i = 0; i < 3; i++) {
+                       if (!vdir[i])
+                               continue;
+
+                       f64 p = vpos[i] + 0.5;
+                       f64 d = vdir[i] / fabs(vdir[i]);
+
+                       f64 f = floor(p) - p;
+                       if (d > 0.0)
+                               f += 1.0;
+                       f += 0.001 * d;
+
+                       f64 mul = f / vdir[i];
+                       if (min_mul > mul && mul)
+                               min_mul = mul;
+               }
+
+               pos = v3f64_add(pos, v3f64_scale(dir, min_mul));
+               len -= dir_len * min_mul;
+       }
+
+       return false;
+}
diff --git a/src/client/raycast.h b/src/client/raycast.h
new file mode 100644 (file)
index 0000000..eac7e17
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _RAYCAST_H_
+#define _RAYCAST_H_
+
+#include <stdbool.h>
+#include "node.h"
+#include "types.h"
+
+bool raycast(v3f64 pos, v3f64 dir, f64 len, v3s32 *node_pos, NodeType *node);
+
+#endif // _RAYCAST_H_
index c0342575dc1e33a04ad42ac5901f1bc938e95ae5..da21675b6ba9d2708cb44530c71ecb1a78d760ac 100644 (file)
@@ -215,15 +215,10 @@ static void before_chunk_hills(BiomeArgsChunk *args)
        memset(chunk_data->boulder_success, 0, sizeof chunk_data->boulder_success);
 }
 
-static void wrap_free(void *ptr)
-{
-       free(ptr);
-}
-
 static void after_chunk_hills(BiomeArgsChunk *args)
 {
        HillsChunkData *chunk_data = args->chunk_data;
-       tree_clr(&chunk_data->boulder_visit, &wrap_free, NULL, NULL, 0);
+       tree_clr(&chunk_data->boulder_visit, &free, NULL, NULL, 0);
 }
 
 static s32 height_hills(BiomeArgsHeight *args)