]> git.lizzy.rs Git - dragonblocks_alpha.git/blobdiff - src/client/blockmesh.c
Fix NULL pointer bug in meshgen
[dragonblocks_alpha.git] / src / client / blockmesh.c
index fb6ed0e955676c88af41622d1fd6791d620e2d2a..25274e21a671ed9539c6e0563c93d407bf641dd1 100644 (file)
@@ -12,17 +12,27 @@ static v3s8 fdir[6] = {
        {+0, +1, +0},
 };
 
-static void make_vertices(Object *object, MapBlock *block)
+static s32 half_block_size = MAPBLOCK_SIZE / 2;
+
+static void make_vertices(Object *object, MapBlock *block, bool hide_edges)
 {
-       v3s32 node_bp = {block->pos.x * MAPBLOCK_SIZE, block->pos.y * MAPBLOCK_SIZE, block->pos.z * MAPBLOCK_SIZE};
+       object->visible = false;
+       v3s32 node_bp = {
+               block->pos.x * MAPBLOCK_SIZE,
+               block->pos.y * MAPBLOCK_SIZE,
+               block->pos.z * MAPBLOCK_SIZE
+       };
 
        ITERATE_MAPBLOCK {
                MapNode *node = &block->data[x][y][z];
+               ClientNodeDefinition *def = &client_node_definitions[node->type];
 
-               if (node_definitions[node->type].visible) {
-                       v3f32 offset = {x + (f32) MAPBLOCK_SIZE / 2.0f, y + (f32) MAPBLOCK_SIZE / 2.0f, z + (f32) MAPBLOCK_SIZE / 2.0f};
-
-                       ClientNodeDefintion *client_node_def = &client_node_definitions[node->type];
+               if (def->visibility != NV_NONE) {
+                       v3f32 offset = {
+                               x - half_block_size - 0.5,
+                               y - half_block_size - 0.5,
+                               z - half_block_size - 0.5
+                       };
 
                        for (int f = 0; f < 6; f++) {
                                v3s8 npos = {
@@ -31,17 +41,28 @@ static void make_vertices(Object *object, MapBlock *block)
                                        z + fdir[f].z,
                                };
 
-                               Node neighbor;
+                               bool direct_neighbor = npos.x >= 0 && npos.x < MAPBLOCK_SIZE
+                                       && npos.y >= 0 && npos.y < MAPBLOCK_SIZE
+                                       && npos.z >= 0 && npos.z < MAPBLOCK_SIZE;
 
-                               if (npos.x >= 0 && npos.x < MAPBLOCK_SIZE && npos.y >= 0 && npos.y < MAPBLOCK_SIZE && npos.z >= 0 && npos.z < MAPBLOCK_SIZE)
-                                       neighbor = block->data[npos.x][npos.y][npos.z].type;
-                               else {
-                                       MapNode nn = map_get_node(client_map.map, (v3s32) {npos.x + node_bp.x, npos.y + node_bp.y, npos.z + node_bp.z});
-                                       neighbor = nn.type;
-                               }
+                               MapNode neighbor = direct_neighbor
+                                       ? block->data[npos.x][npos.y][npos.z]
+                                       : map_get_node(client_map.map, (v3s32) {npos.x + node_bp.x, npos.y + node_bp.y, npos.z + node_bp.z});
+
+                               bool transparency_edge = def->visibility != NV_BLEND || neighbor.type != node->type;
+
+                               bool render_node = def->visibility == NV_CLIP || (neighbor.type != NODE_UNLOADED
+                                       && client_node_definitions[neighbor.type].visibility != NV_SOLID
+                                       && transparency_edge);
 
-                               if (neighbor != NODE_UNLOADED && ! node_definitions[neighbor].visible) {
-                                       object_set_texture(object, client_node_def->tiles.textures[f]);
+                               object->visible = object->visible || render_node;
+
+                               if (! hide_edges && ! direct_neighbor)
+                                       render_node = transparency_edge;
+
+                               if (render_node) {
+                                       object->transparent = object->transparent || def->visibility == NV_BLEND;
+                                       object_set_texture(object, def->tiles.textures[f]);
 
                                        for (int v = 0; v < 6; v++) {
                                                Vertex3D vertex = cube_vertices[f][v];
@@ -49,8 +70,8 @@ static void make_vertices(Object *object, MapBlock *block)
                                                vertex.position.y += offset.y;
                                                vertex.position.z += offset.z;
 
-                                               if (client_node_def->render)
-                                                       client_node_def->render((v3s32) {x + node_bp.x, y + node_bp.y, z + node_bp.z}, node, &vertex, f, v);
+                                               if (def->render)
+                                                       def->render((v3s32) {x + node_bp.x, y + node_bp.y, z + node_bp.z}, node, &vertex, f, v);
 
                                                object_add_vertex(object, &vertex);
                                        }
@@ -60,22 +81,50 @@ static void make_vertices(Object *object, MapBlock *block)
        }
 }
 
+static void animate_mapblock_mesh(Object *obj, f64 dtime)
+{
+       obj->scale.x += dtime * 2.0;
+
+       if (obj->scale.x > 1.0f) {
+               obj->scale.x = 1.0f;
+               client_map_schedule_update_block_mesh(obj->extra);
+       }
+
+       obj->scale.z = obj->scale.y = obj->scale.x;
+
+       object_transform(obj);
+}
+
 void blockmesh_make(MapBlock *block)
 {
+       MapBlockExtraData *extra = block->extra;
+
        Object *obj = object_create();
-       obj->pos = (v3f32) {block->pos.x * (f32) MAPBLOCK_SIZE - (f32) MAPBLOCK_SIZE / 2.0f, block->pos.y * (f32) MAPBLOCK_SIZE - (f32) MAPBLOCK_SIZE / 2.0f, block->pos.z * (f32) MAPBLOCK_SIZE - (f32) MAPBLOCK_SIZE / 2.0};
 
-       make_vertices(obj, block);
+       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};
+       obj->scale = (v3f32) {0.1f, 0.1f, 0.1f};
+       obj->frustum_culling = true;
+       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}};
+       obj->on_render = (obj->scale.x == 1.0f) ? NULL : &animate_mapblock_mesh;
+       obj->extra = block;
+
+       make_vertices(obj, block, obj->scale.x == 1.0f);
 
        if (! object_add_to_scene(obj)) {
                object_delete(obj);
                obj = NULL;
        }
 
-       MapBlockExtraData *extra = block->extra;
+       pthread_mutex_lock(&block->mtx);
+       if (extra->obj) {
+               if (obj) {
+                       obj->scale = extra->obj->scale;
+                       object_transform(obj);
+               }
 
-       if (extra->obj)
                extra->obj->remove = true;
+       }
 
        extra->obj = obj;
+       pthread_mutex_unlock(&block->mtx);
 }