@@ -225,7 +225,7 @@ static u16 getSmoothLightCombined(const v3s16 &p,
225
225
return f.light_propagates ;
226
226
};
227
227
228
- std::array< bool , 4 > obstructed = {{ 1 , 1 , 1 , 1 } };
228
+ bool obstructed[ 4 ] = { true , true , true , true };
229
229
add_node (0 );
230
230
bool opaque1 = !add_node (1 );
231
231
bool opaque2 = !add_node (2 );
@@ -372,6 +372,32 @@ void final_color_blend(video::SColor *result,
372
372
Mesh generation helpers
373
373
*/
374
374
375
+ // This table is moved outside getNodeVertexDirs to avoid the compiler using
376
+ // a mutex to initialize this table at runtime right in the hot path.
377
+ // For details search the internet for "cxa_guard_acquire".
378
+ static const v3s16 vertex_dirs_table[] = {
379
+ // ( 1, 0, 0)
380
+ v3s16 ( 1 ,-1 , 1 ), v3s16 ( 1 ,-1 ,-1 ),
381
+ v3s16 ( 1 , 1 ,-1 ), v3s16 ( 1 , 1 , 1 ),
382
+ // ( 0, 1, 0)
383
+ v3s16 ( 1 , 1 ,-1 ), v3s16 (-1 , 1 ,-1 ),
384
+ v3s16 (-1 , 1 , 1 ), v3s16 ( 1 , 1 , 1 ),
385
+ // ( 0, 0, 1)
386
+ v3s16 (-1 ,-1 , 1 ), v3s16 ( 1 ,-1 , 1 ),
387
+ v3s16 ( 1 , 1 , 1 ), v3s16 (-1 , 1 , 1 ),
388
+ // invalid
389
+ v3s16 (), v3s16 (), v3s16 (), v3s16 (),
390
+ // ( 0, 0,-1)
391
+ v3s16 ( 1 ,-1 ,-1 ), v3s16 (-1 ,-1 ,-1 ),
392
+ v3s16 (-1 , 1 ,-1 ), v3s16 ( 1 , 1 ,-1 ),
393
+ // ( 0,-1, 0)
394
+ v3s16 ( 1 ,-1 , 1 ), v3s16 (-1 ,-1 , 1 ),
395
+ v3s16 (-1 ,-1 ,-1 ), v3s16 ( 1 ,-1 ,-1 ),
396
+ // (-1, 0, 0)
397
+ v3s16 (-1 ,-1 ,-1 ), v3s16 (-1 ,-1 , 1 ),
398
+ v3s16 (-1 , 1 , 1 ), v3s16 (-1 , 1 ,-1 )
399
+ };
400
+
375
401
/*
376
402
vertex_dirs: v3s16[4]
377
403
*/
@@ -384,44 +410,16 @@ static void getNodeVertexDirs(const v3s16 &dir, v3s16 *vertex_dirs)
384
410
2: top-left
385
411
3: top-right
386
412
*/
387
- if (dir == v3s16 (0 , 0 , 1 )) {
388
- // If looking towards z+, this is the face that is behind
389
- // the center point, facing towards z+.
390
- vertex_dirs[0 ] = v3s16 (-1 ,-1 , 1 );
391
- vertex_dirs[1 ] = v3s16 ( 1 ,-1 , 1 );
392
- vertex_dirs[2 ] = v3s16 ( 1 , 1 , 1 );
393
- vertex_dirs[3 ] = v3s16 (-1 , 1 , 1 );
394
- } else if (dir == v3s16 (0 , 0 , -1 )) {
395
- // faces towards Z-
396
- vertex_dirs[0 ] = v3s16 ( 1 ,-1 ,-1 );
397
- vertex_dirs[1 ] = v3s16 (-1 ,-1 ,-1 );
398
- vertex_dirs[2 ] = v3s16 (-1 , 1 ,-1 );
399
- vertex_dirs[3 ] = v3s16 ( 1 , 1 ,-1 );
400
- } else if (dir == v3s16 (1 , 0 , 0 )) {
401
- // faces towards X+
402
- vertex_dirs[0 ] = v3s16 ( 1 ,-1 , 1 );
403
- vertex_dirs[1 ] = v3s16 ( 1 ,-1 ,-1 );
404
- vertex_dirs[2 ] = v3s16 ( 1 , 1 ,-1 );
405
- vertex_dirs[3 ] = v3s16 ( 1 , 1 , 1 );
406
- } else if (dir == v3s16 (-1 , 0 , 0 )) {
407
- // faces towards X-
408
- vertex_dirs[0 ] = v3s16 (-1 ,-1 ,-1 );
409
- vertex_dirs[1 ] = v3s16 (-1 ,-1 , 1 );
410
- vertex_dirs[2 ] = v3s16 (-1 , 1 , 1 );
411
- vertex_dirs[3 ] = v3s16 (-1 , 1 ,-1 );
412
- } else if (dir == v3s16 (0 , 1 , 0 )) {
413
- // faces towards Y+ (assume Z- as "down" in texture)
414
- vertex_dirs[0 ] = v3s16 ( 1 , 1 ,-1 );
415
- vertex_dirs[1 ] = v3s16 (-1 , 1 ,-1 );
416
- vertex_dirs[2 ] = v3s16 (-1 , 1 , 1 );
417
- vertex_dirs[3 ] = v3s16 ( 1 , 1 , 1 );
418
- } else if (dir == v3s16 (0 , -1 , 0 )) {
419
- // faces towards Y- (assume Z+ as "down" in texture)
420
- vertex_dirs[0 ] = v3s16 ( 1 ,-1 , 1 );
421
- vertex_dirs[1 ] = v3s16 (-1 ,-1 , 1 );
422
- vertex_dirs[2 ] = v3s16 (-1 ,-1 ,-1 );
423
- vertex_dirs[3 ] = v3s16 ( 1 ,-1 ,-1 );
424
- }
413
+
414
+ // Direction must be (1,0,0), (-1,0,0), (0,1,0), (0,-1,0),
415
+ // (0,0,1), (0,0,-1)
416
+ assert (dir.X * dir.X + dir.Y * dir.Y + dir.Z * dir.Z == 1 );
417
+
418
+ // Convert direction to single integer for table lookup
419
+ u8 idx = (dir.X + 2 * dir.Y + 3 * dir.Z ) & 7 ;
420
+ idx = (idx - 1 ) * 4 ;
421
+
422
+ memcpy (vertex_dirs, &vertex_dirs_table[idx], 4 * sizeof (v3s16));
425
423
}
426
424
427
425
static void getNodeTextureCoords (v3f base, const v3f &scale, const v3s16 &dir, float *u, float *v)
@@ -892,6 +890,8 @@ static void updateFastFaceRow(
892
890
u16 lights[4 ] = {0 , 0 , 0 , 0 };
893
891
u8 waving;
894
892
TileSpec tile;
893
+
894
+ // Get info of first tile
895
895
getTileInfo (data, p, face_dir,
896
896
makes_face, p_corrected, face_dir_corrected,
897
897
lights, waving, tile);
@@ -902,8 +902,6 @@ static void updateFastFaceRow(
902
902
// If tiling can be done, this is set to false in the next step
903
903
bool next_is_different = true ;
904
904
905
- v3s16 p_next;
906
-
907
905
bool next_makes_face = false ;
908
906
v3s16 next_p_corrected;
909
907
v3s16 next_face_dir_corrected;
@@ -912,9 +910,9 @@ static void updateFastFaceRow(
912
910
// If at last position, there is nothing to compare to and
913
911
// the face must be drawn anyway
914
912
if (j != MAP_BLOCKSIZE - 1 ) {
915
- p_next = p + translate_dir;
913
+ p += translate_dir;
916
914
917
- getTileInfo (data, p_next , face_dir,
915
+ getTileInfo (data, p , face_dir,
918
916
next_makes_face, next_p_corrected,
919
917
next_face_dir_corrected, next_lights,
920
918
waving,
@@ -923,7 +921,7 @@ static void updateFastFaceRow(
923
921
if (next_makes_face == makes_face
924
922
&& next_p_corrected == p_corrected + translate_dir
925
923
&& next_face_dir_corrected == face_dir_corrected
926
- && memcmp (next_lights, lights, ARRLEN (lights) * sizeof (u16 )) == 0
924
+ && memcmp (next_lights, lights, sizeof (lights )) == 0
927
925
// Don't apply fast faces to waving water.
928
926
&& (waving != 3 || !waving_liquids)
929
927
&& next_tile.isTileable (tile)) {
@@ -961,10 +959,9 @@ static void updateFastFaceRow(
961
959
makes_face = next_makes_face;
962
960
p_corrected = next_p_corrected;
963
961
face_dir_corrected = next_face_dir_corrected;
964
- std:: memcpy (lights, next_lights, ARRLEN (lights) * sizeof (u16 ));
962
+ memcpy (lights, next_lights, sizeof (lights ));
965
963
if (next_is_different)
966
- tile = next_tile;
967
- p = p_next;
964
+ tile = std::move (next_tile); // faster than copy
968
965
}
969
966
}
970
967
0 commit comments