1 #include "client/blockmesh.h"
2 #include "client/client_map.h"
3 #include "client/client_node.h"
4 #include "client/cube.h"
6 static v3s8 fdir[6] = {
15 static s32 half_block_size = MAPBLOCK_SIZE / 2;
17 static void make_vertices(Object *object, MapBlock *block, bool hide_edges)
19 object->visible = false;
21 block->pos.x * MAPBLOCK_SIZE,
22 block->pos.y * MAPBLOCK_SIZE,
23 block->pos.z * MAPBLOCK_SIZE
27 MapNode *node = &block->data[x][y][z];
28 ClientNodeDefinition *def = &client_node_definitions[node->type];
30 if (def->visibility != NV_NONE) {
32 x - half_block_size - 0.5,
33 y - half_block_size - 0.5,
34 z - half_block_size - 0.5
37 for (int f = 0; f < 6; f++) {
44 bool direct_neighbor = npos.x >= 0 && npos.x < MAPBLOCK_SIZE
45 && npos.y >= 0 && npos.y < MAPBLOCK_SIZE
46 && npos.z >= 0 && npos.z < MAPBLOCK_SIZE;
48 MapNode neighbor = direct_neighbor
49 ? block->data[npos.x][npos.y][npos.z]
50 : map_get_node(client_map.map, (v3s32) {npos.x + node_bp.x, npos.y + node_bp.y, npos.z + node_bp.z});
52 bool transparency_edge = def->visibility != NV_BLEND || neighbor.type != node->type;
54 bool render_node = def->visibility == NV_CLIP || (neighbor.type != NODE_UNLOADED
55 && client_node_definitions[neighbor.type].visibility != NV_SOLID
56 && transparency_edge);
58 object->visible = object->visible || render_node;
60 if (! hide_edges && ! direct_neighbor)
61 render_node = transparency_edge;
64 object->transparent = object->transparent || def->visibility == NV_BLEND;
65 object_set_texture(object, def->tiles.textures[f]);
67 for (int v = 0; v < 6; v++) {
68 Vertex3D vertex = cube_vertices[f][v];
69 vertex.position.x += offset.x;
70 vertex.position.y += offset.y;
71 vertex.position.z += offset.z;
74 def->render((v3s32) {x + node_bp.x, y + node_bp.y, z + node_bp.z}, node, &vertex, f, v);
76 object_add_vertex(object, &vertex);
84 static void animate_mapblock_mesh(Object *obj, f64 dtime)
86 obj->scale.x += dtime * 2.0;
88 if (obj->scale.x > 1.0f) {
90 client_map_schedule_update_block_mesh(obj->extra);
93 obj->scale.z = obj->scale.y = obj->scale.x;
95 object_transform(obj);
98 void blockmesh_make(MapBlock *block)
100 MapBlockExtraData *extra = block->extra;
102 Object *obj = object_create();
104 obj->pos = (v3f32) {block->pos.x * MAPBLOCK_SIZE + half_block_size + 0.5f, block->pos.y * MAPBLOCK_SIZE + half_block_size + 0.5f, block->pos.z * MAPBLOCK_SIZE + half_block_size + 0.5f};
105 obj->scale = extra->obj ? extra->obj->scale : (v3f32) {0.1f, 0.1f, 0.1f};
106 obj->frustum_culling = true;
107 obj->box = (aabb3f32) {{-half_block_size - 1.0f, -half_block_size - 1.0f, -half_block_size - 1.0f}, {half_block_size + 1.0f, half_block_size + 1.0f, half_block_size + 1.0f}};
108 obj->on_render = (obj->scale.x == 1.0f) ? NULL : &animate_mapblock_mesh;
111 make_vertices(obj, block, obj->scale.x == 1.0f);
113 if (! object_add_to_scene(obj)) {
119 extra->obj->remove = true;