Add node selection box
parent
2146387676
commit
32781feeff
|
@ -1 +1 @@
|
|||
Subproject commit 6d8f26f523570f440152abcfab5f2839d3c6b5b0
|
||||
Subproject commit 431e3bd29073d9c10ab3a853116860ba83ed1c5e
|
|
@ -0,0 +1,8 @@
|
|||
out vec4 outColor;
|
||||
|
||||
uniform vec3 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
outColor = vec4(color, 0.1);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
layout(location = 0) in vec3 vertexPosition;
|
||||
|
||||
uniform mat4 MVP;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = MVP * vec4(vertexPosition, 1.0);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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_
|
|
@ -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;
|
||||
}
|
|
@ -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_
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue