mapblock_mesh: Optimize a few things ()

This commit is contained in:
sfan5 2020-04-25 12:39:17 +02:00 committed by GitHub
parent 49ed0ca00a
commit 73180a73da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -225,7 +225,7 @@ static u16 getSmoothLightCombined(const v3s16 &p,
return f.light_propagates; return f.light_propagates;
}; };
std::array<bool, 4> obstructed = {{ 1, 1, 1, 1 }}; bool obstructed[4] = { true, true, true, true };
add_node(0); add_node(0);
bool opaque1 = !add_node(1); bool opaque1 = !add_node(1);
bool opaque2 = !add_node(2); bool opaque2 = !add_node(2);
@ -372,6 +372,32 @@ void final_color_blend(video::SColor *result,
Mesh generation helpers Mesh generation helpers
*/ */
// This table is moved outside getNodeVertexDirs to avoid the compiler using
// a mutex to initialize this table at runtime right in the hot path.
// For details search the internet for "cxa_guard_acquire".
static const v3s16 vertex_dirs_table[] = {
// ( 1, 0, 0)
v3s16( 1,-1, 1), v3s16( 1,-1,-1),
v3s16( 1, 1,-1), v3s16( 1, 1, 1),
// ( 0, 1, 0)
v3s16( 1, 1,-1), v3s16(-1, 1,-1),
v3s16(-1, 1, 1), v3s16( 1, 1, 1),
// ( 0, 0, 1)
v3s16(-1,-1, 1), v3s16( 1,-1, 1),
v3s16( 1, 1, 1), v3s16(-1, 1, 1),
// invalid
v3s16(), v3s16(), v3s16(), v3s16(),
// ( 0, 0,-1)
v3s16( 1,-1,-1), v3s16(-1,-1,-1),
v3s16(-1, 1,-1), v3s16( 1, 1,-1),
// ( 0,-1, 0)
v3s16( 1,-1, 1), v3s16(-1,-1, 1),
v3s16(-1,-1,-1), v3s16( 1,-1,-1),
// (-1, 0, 0)
v3s16(-1,-1,-1), v3s16(-1,-1, 1),
v3s16(-1, 1, 1), v3s16(-1, 1,-1)
};
/* /*
vertex_dirs: v3s16[4] vertex_dirs: v3s16[4]
*/ */
@ -384,44 +410,16 @@ static void getNodeVertexDirs(const v3s16 &dir, v3s16 *vertex_dirs)
2: top-left 2: top-left
3: top-right 3: top-right
*/ */
if (dir == v3s16(0, 0, 1)) {
// If looking towards z+, this is the face that is behind // Direction must be (1,0,0), (-1,0,0), (0,1,0), (0,-1,0),
// the center point, facing towards z+. // (0,0,1), (0,0,-1)
vertex_dirs[0] = v3s16(-1,-1, 1); assert(dir.X * dir.X + dir.Y * dir.Y + dir.Z * dir.Z == 1);
vertex_dirs[1] = v3s16( 1,-1, 1);
vertex_dirs[2] = v3s16( 1, 1, 1); // Convert direction to single integer for table lookup
vertex_dirs[3] = v3s16(-1, 1, 1); u8 idx = (dir.X + 2 * dir.Y + 3 * dir.Z) & 7;
} else if (dir == v3s16(0, 0, -1)) { idx = (idx - 1) * 4;
// faces towards Z-
vertex_dirs[0] = v3s16( 1,-1,-1); memcpy(vertex_dirs, &vertex_dirs_table[idx], 4 * sizeof(v3s16));
vertex_dirs[1] = v3s16(-1,-1,-1);
vertex_dirs[2] = v3s16(-1, 1,-1);
vertex_dirs[3] = v3s16( 1, 1,-1);
} else if (dir == v3s16(1, 0, 0)) {
// faces towards X+
vertex_dirs[0] = v3s16( 1,-1, 1);
vertex_dirs[1] = v3s16( 1,-1,-1);
vertex_dirs[2] = v3s16( 1, 1,-1);
vertex_dirs[3] = v3s16( 1, 1, 1);
} else if (dir == v3s16(-1, 0, 0)) {
// faces towards X-
vertex_dirs[0] = v3s16(-1,-1,-1);
vertex_dirs[1] = v3s16(-1,-1, 1);
vertex_dirs[2] = v3s16(-1, 1, 1);
vertex_dirs[3] = v3s16(-1, 1,-1);
} else if (dir == v3s16(0, 1, 0)) {
// faces towards Y+ (assume Z- as "down" in texture)
vertex_dirs[0] = v3s16( 1, 1,-1);
vertex_dirs[1] = v3s16(-1, 1,-1);
vertex_dirs[2] = v3s16(-1, 1, 1);
vertex_dirs[3] = v3s16( 1, 1, 1);
} else if (dir == v3s16(0, -1, 0)) {
// faces towards Y- (assume Z+ as "down" in texture)
vertex_dirs[0] = v3s16( 1,-1, 1);
vertex_dirs[1] = v3s16(-1,-1, 1);
vertex_dirs[2] = v3s16(-1,-1,-1);
vertex_dirs[3] = v3s16( 1,-1,-1);
}
} }
static void getNodeTextureCoords(v3f base, const v3f &scale, const v3s16 &dir, float *u, float *v) static void getNodeTextureCoords(v3f base, const v3f &scale, const v3s16 &dir, float *u, float *v)
@ -892,6 +890,8 @@ static void updateFastFaceRow(
u16 lights[4] = {0, 0, 0, 0}; u16 lights[4] = {0, 0, 0, 0};
u8 waving; u8 waving;
TileSpec tile; TileSpec tile;
// Get info of first tile
getTileInfo(data, p, face_dir, getTileInfo(data, p, face_dir,
makes_face, p_corrected, face_dir_corrected, makes_face, p_corrected, face_dir_corrected,
lights, waving, tile); lights, waving, tile);
@ -902,8 +902,6 @@ static void updateFastFaceRow(
// If tiling can be done, this is set to false in the next step // If tiling can be done, this is set to false in the next step
bool next_is_different = true; bool next_is_different = true;
v3s16 p_next;
bool next_makes_face = false; bool next_makes_face = false;
v3s16 next_p_corrected; v3s16 next_p_corrected;
v3s16 next_face_dir_corrected; v3s16 next_face_dir_corrected;
@ -912,9 +910,9 @@ static void updateFastFaceRow(
// If at last position, there is nothing to compare to and // If at last position, there is nothing to compare to and
// the face must be drawn anyway // the face must be drawn anyway
if (j != MAP_BLOCKSIZE - 1) { if (j != MAP_BLOCKSIZE - 1) {
p_next = p + translate_dir; p += translate_dir;
getTileInfo(data, p_next, face_dir, getTileInfo(data, p, face_dir,
next_makes_face, next_p_corrected, next_makes_face, next_p_corrected,
next_face_dir_corrected, next_lights, next_face_dir_corrected, next_lights,
waving, waving,
@ -923,7 +921,7 @@ static void updateFastFaceRow(
if (next_makes_face == makes_face if (next_makes_face == makes_face
&& next_p_corrected == p_corrected + translate_dir && next_p_corrected == p_corrected + translate_dir
&& next_face_dir_corrected == face_dir_corrected && next_face_dir_corrected == face_dir_corrected
&& memcmp(next_lights, lights, ARRLEN(lights) * sizeof(u16)) == 0 && memcmp(next_lights, lights, sizeof(lights)) == 0
// Don't apply fast faces to waving water. // Don't apply fast faces to waving water.
&& (waving != 3 || !waving_liquids) && (waving != 3 || !waving_liquids)
&& next_tile.isTileable(tile)) { && next_tile.isTileable(tile)) {
@ -961,10 +959,9 @@ static void updateFastFaceRow(
makes_face = next_makes_face; makes_face = next_makes_face;
p_corrected = next_p_corrected; p_corrected = next_p_corrected;
face_dir_corrected = next_face_dir_corrected; face_dir_corrected = next_face_dir_corrected;
std::memcpy(lights, next_lights, ARRLEN(lights) * sizeof(u16)); memcpy(lights, next_lights, sizeof(lights));
if (next_is_different) if (next_is_different)
tile = next_tile; tile = std::move(next_tile); // faster than copy
p = p_next;
} }
} }