Add node selection box

master
Elias Fleckenstein 2022-04-18 22:18:40 +02:00
parent 2146387676
commit 32781feeff
No known key found for this signature in database
GPG Key ID: 06927A5199D6C9B2
13 changed files with 218 additions and 8 deletions

2
deps/dragonnet vendored

@ -1 +1 @@
Subproject commit 6d8f26f523570f440152abcfab5f2839d3c6b5b0
Subproject commit 431e3bd29073d9c10ab3a853116860ba83ed1c5e

View File

@ -0,0 +1,8 @@
out vec4 outColor;
uniform vec3 color;
void main()
{
outColor = vec4(color, 0.1);
}

View File

@ -0,0 +1,8 @@
layout(location = 0) in vec3 vertexPosition;
uniform mat4 MVP;
void main()
{
gl_Position = MVP * vec4(vertexPosition, 1.0);
}

View 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

View 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},
},
};

View 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[];

View 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);

View 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;
}

91
src/client/interact.c Normal file
View File

@ -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);
}

9
src/client/interact.h Normal file
View File

@ -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_

46
src/client/raycast.c Normal file
View File

@ -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;
}

10
src/client/raycast.h Normal file
View File

@ -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_

View 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)