Mapblock_mesh_generate_special: Improve performance

Remove uses of std::map.
Make sure we use ContentFeatures reference not value.
Original commit by gregorycu.
master
paramat 2016-10-03 00:56:17 +01:00
parent 61e112b43b
commit 1079aeaa13
1 changed files with 36 additions and 15 deletions

View File

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