diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index 173649aee..8ce0f1e0a 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -172,6 +172,15 @@ static inline void getNeighborConnectingFace(v3s16 p, INodeDefManager *nodedef, *neighbors |= v; } +// For use in mapblock_mesh_generate_special +// X,Y,Z of position must be -1,0,1 +// This expression is a simplification of +// 3 * 3 * (pos.X + 1) + 3 * (pos.Y + 1) + (pos.Z + 1) +static inline int NeighborToIndex(const v3s16 &pos) +{ + return 9 * pos.X + 3 * pos.Y + pos.Z + 13; +} + /* TODO: Fix alpha blending for special nodes Currently only the last element rendered is blended correct @@ -401,9 +410,14 @@ void mapblock_mesh_generate_special(MeshMakeData *data, // Neighbor liquid levels (key = relative position) // Includes current node - std::map neighbor_levels; - std::map neighbor_contents; - std::map neighbor_flags; + + struct NeighborData { + f32 level; + content_t content; + u8 flags; + }; + NeighborData neighbor_data_matrix[27]; + const u8 neighborflag_top_is_same_liquid = 0x01; v3s16 neighbor_dirs[9] = { v3s16(0,0,0), @@ -449,9 +463,12 @@ void mapblock_mesh_generate_special(MeshMakeData *data, flags |= neighborflag_top_is_same_liquid; } - neighbor_levels[neighbor_dirs[i]] = level; - neighbor_contents[neighbor_dirs[i]] = content; - neighbor_flags[neighbor_dirs[i]] = flags; + NeighborData &neighbor_data = + neighbor_data_matrix[NeighborToIndex(neighbor_dirs[i])]; + + neighbor_data.level = level; + neighbor_data.content = content; + neighbor_data.flags = flags; } // Corner heights (average between four liquids) @@ -472,10 +489,12 @@ void mapblock_mesh_generate_special(MeshMakeData *data, for(u32 j=0; j<4; j++) { v3s16 neighbordir = cornerdir - halfdirs[j]; - content_t content = neighbor_contents[neighbordir]; + + NeighborData &neighbor_data = + neighbor_data_matrix[NeighborToIndex(neighbordir)]; + content_t content = neighbor_data.content; // If top is liquid, draw starting from top of node - if(neighbor_flags[neighbordir] & - neighborflag_top_is_same_liquid) + if (neighbor_data.flags & neighborflag_top_is_same_liquid) { cornerlevel = 0.5*BS; valid_count = 1; @@ -491,7 +510,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, // Flowing liquid has level information else if(content == c_flowing) { - cornerlevel += neighbor_levels[neighbordir]; + cornerlevel += neighbor_data.level; valid_count++; } else if(content == CONTENT_AIR) @@ -526,15 +545,17 @@ void mapblock_mesh_generate_special(MeshMakeData *data, { v3s16 dir = side_dirs[i]; + NeighborData& neighbor_data = + neighbor_data_matrix[NeighborToIndex(dir)]; /* If our topside is liquid and neighbor's topside is liquid, don't draw side face */ - if(top_is_same_liquid && - neighbor_flags[dir] & neighborflag_top_is_same_liquid) + if (top_is_same_liquid && + neighbor_data.flags & neighborflag_top_is_same_liquid) continue; - content_t neighbor_content = neighbor_contents[dir]; + content_t neighbor_content = neighbor_data.content; const ContentFeatures &n_feat = nodedef->get(neighbor_content); // Don't draw face if neighbor is blocking the view @@ -1506,8 +1527,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data, continue; MapNode n_xy = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x + xz, y + y0, z)); MapNode n_zy = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x, y + y0, z + xz)); - ContentFeatures def_xy = nodedef->get(n_xy); - ContentFeatures def_zy = nodedef->get(n_zy); + const ContentFeatures &def_xy = nodedef->get(n_xy); + const ContentFeatures &def_zy = nodedef->get(n_zy); // Check if current node would connect with the rail is_rail_x[index] = ((def_xy.drawtype == NDT_RAILLIKE