-Subproject commit 6d8f26f523570f440152abcfab5f2839d3c6b5b0
+Subproject commit 431e3bd29073d9c10ab3a853116860ba83ed1c5e
--- /dev/null
+out vec4 outColor;
+
+uniform vec3 color;
+
+void main()
+{
+ outColor = vec4(color, 0.1);
+}
--- /dev/null
+layout(location = 0) in vec3 vertexPosition;
+
+uniform mat4 MVP;
+
+void main()
+{
+ gl_Position = MVP * vec4(vertexPosition, 1.0);
+}
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
.visibility = VISIBILITY_SOLID,
.mipmap = true,
.render = NULL,
+ .pointable = true,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
// air
{
.visibility = VISIBILITY_NONE,
.mipmap = true,
.render = NULL,
+ .pointable = false,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
// grass
{
.visibility = VISIBILITY_SOLID,
.mipmap = true,
.render = &render_grass,
+ .pointable = true,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
// dirt
{
.visibility = VISIBILITY_SOLID,
.mipmap = true,
.render = NULL,
+ .pointable = true,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
// stone
{
.visibility = VISIBILITY_SOLID,
.mipmap = true,
.render = &render_stone,
+ .pointable = true,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
// snow
{
.visibility = VISIBILITY_SOLID,
.mipmap = true,
.render = NULL,
+ .pointable = true,
+ .selection_color = {0.1f, 0.5f, 1.0f},
},
// oak wood
{
.visibility = VISIBILITY_SOLID,
.mipmap = true,
.render = &render_color,
+ .pointable = true,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
// oak leaves
{
.visibility = VISIBILITY_SOLID,
.mipmap = true,
.render = &render_color,
+ .pointable = true,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
// pine wood
{
.visibility = VISIBILITY_SOLID,
.mipmap = true,
.render = &render_color,
+ .pointable = true,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
// pine leaves
{
.visibility = VISIBILITY_CLIP,
.mipmap = true,
.render = &render_color,
+ .pointable = true,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
// palm wood
{
.visibility = VISIBILITY_SOLID,
.mipmap = true,
.render = &render_color,
+ .pointable = true,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
// palm leaves
{
.visibility = VISIBILITY_SOLID,
.mipmap = true,
.render = &render_color,
+ .pointable = true,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
// sand
{
.visibility = VISIBILITY_SOLID,
.mipmap = true,
.render = NULL,
+ .pointable = true,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
// water
{
.visibility = VISIBILITY_BLEND,
.mipmap = true,
.render = NULL,
+ .pointable = false,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
// lava
{
.visibility = VISIBILITY_BLEND,
.mipmap = true,
.render = NULL,
+ .pointable = false,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
// vulcano_stone
{
.visibility = VISIBILITY_SOLID,
.mipmap = true,
.render = NULL,
+ .pointable = true,
+ .selection_color = {1.0f, 1.0f, 1.0f},
},
};
NodeVisibility visibility;
bool mipmap;
void (*render)(NodeArgsRender *args);
+ bool pointable;
+ v3f32 selection_color;
} ClientNodeDefinition;
extern ClientNodeDefinition client_node_definitions[];
}, 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);
#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"
sky_render();
model_scene_render(dtime);
+ interact_render();
gui_render();
}
input_tick(dtime);
client_player_tick(dtime);
+ interact_tick();
debug_menu_changed(ENTRY_TIME);
debug_menu_changed(ENTRY_DAYLIGHT);
client_player_gfx_init();
+ if (!interact_init())
+ return false;
+
client_node_init();
client_terrain_start();
terrain_gfx_deinit();
client_entity_gfx_deinit();
client_player_gfx_deinit();
+ interact_deinit();
return true;
}
--- /dev/null
+#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);
+}
--- /dev/null
+#ifndef _INTERACT_H_
+#define _INTERACT_H_
+
+bool interact_init();
+void interact_deinit();
+void interact_tick();
+void interact_render();
+
+#endif // _INTERACT_H_
--- /dev/null
+#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;
+}
--- /dev/null
+#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_
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)