]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/client/blockmesh.c
f822092d7b71577812e4484ea139b4bcc7ef446c
[dragonblocks_alpha.git] / src / client / blockmesh.c
1 #include "client/blockmesh.h"
2 #include "client/client_map.h"
3 #include "client/client_node.h"
4 #include "client/cube.h"
5
6 static v3s8 fdir[6] = {
7         {+0, +0, -1},
8         {+0, +0, +1},
9         {-1, +0, +0},
10         {+1, +0, +0},
11         {+0, -1, +0},
12         {+0, +1, +0},
13 };
14
15 static s32 half_block_size = MAPBLOCK_SIZE / 2;
16
17 static void make_vertices(Object *object, MapBlock *block, bool hide_edges)
18 {
19         v3s32 node_bp = {block->pos.x * MAPBLOCK_SIZE, block->pos.y * MAPBLOCK_SIZE, block->pos.z * MAPBLOCK_SIZE};
20
21         ITERATE_MAPBLOCK {
22                 MapNode *node = &block->data[x][y][z];
23                 ClientNodeDefintion *def = &client_node_definitions[node->type];
24
25                 if (def->visibility != NV_NONE) {
26                         v3f32 offset = {x - half_block_size - 0.5, y - half_block_size - 0.5, z - half_block_size - 0.5};
27
28                         for (int f = 0; f < 6; f++) {
29                                 v3s8 npos = {
30                                         x + fdir[f].x,
31                                         y + fdir[f].y,
32                                         z + fdir[f].z,
33                                 };
34
35                                 Node neighbor;
36
37                                 if (npos.x >= 0 && npos.x < MAPBLOCK_SIZE && npos.y >= 0 && npos.y < MAPBLOCK_SIZE && npos.z >= 0 && npos.z < MAPBLOCK_SIZE)
38                                         neighbor = block->data[npos.x][npos.y][npos.z].type;
39                                 else if (hide_edges) {
40                                         MapNode nn = map_get_node(client_map.map, (v3s32) {npos.x + node_bp.x, npos.y + node_bp.y, npos.z + node_bp.z});
41                                         neighbor = nn.type;
42                                 } else {
43                                         neighbor = NODE_AIR;
44                                 }
45
46                                 if (neighbor != NODE_UNLOADED && client_node_definitions[neighbor].visibility != NV_SOLID && (def->visibility != NV_TRANSPARENT || neighbor != node->type)) {
47                                         object_set_texture(object, def->tiles.textures[f]);
48
49                                         for (int v = 0; v < 6; v++) {
50                                                 Vertex3D vertex = cube_vertices[f][v];
51                                                 vertex.position.x += offset.x;
52                                                 vertex.position.y += offset.y;
53                                                 vertex.position.z += offset.z;
54
55                                                 if (def->render)
56                                                         def->render((v3s32) {x + node_bp.x, y + node_bp.y, z + node_bp.z}, node, &vertex, f, v);
57
58                                                 object_add_vertex(object, &vertex);
59                                         }
60                                 }
61                         }
62                 }
63         }
64 }
65
66 static void animate_mapblock_mesh(Object *obj, f64 dtime)
67 {
68         obj->scale.x += dtime * 2.0;
69
70         if (obj->scale.x > 1.0f) {
71                 obj->scale.x = 1.0f;
72                 client_map_schedule_update_block_mesh(obj->extra);
73         }
74
75         obj->scale.z = obj->scale.y = obj->scale.x;
76
77         object_transform(obj);
78 }
79
80 void blockmesh_make(MapBlock *block)
81 {
82         MapBlockExtraData *extra = block->extra;
83
84         Object *obj = object_create();
85
86         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};
87         obj->scale = extra->obj ? extra->obj->scale : (v3f32) {0.1f, 0.1f, 0.1f};
88         obj->frustum_culling = false;
89         obj->box = (aabb3f32) {{-half_block_size, -half_block_size, -half_block_size}, {half_block_size, half_block_size, half_block_size}};
90         obj->on_render = (obj->scale.x == 1.0f) ? NULL : &animate_mapblock_mesh;
91         obj->extra = block;
92
93         make_vertices(obj, block, obj->scale.x == 1.0f);
94
95         if (! object_add_to_scene(obj)) {
96                 object_delete(obj);
97                 obj = NULL;
98         }
99
100         if (extra->obj)
101                 extra->obj->remove = true;
102
103         extra->obj = obj;
104 }