Mgcarpathian: Mapgen loop optimisations. fabs() -> std::fabs()
authorParamat <paramat@users.noreply.github.com>
Thu, 29 Mar 2018 20:08:42 +0000 (21:08 +0100)
committerGitHub <noreply@github.com>
Thu, 29 Mar 2018 20:08:42 +0000 (21:08 +0100)
* Mgcarpathian: ZYX -> ZXY mapgen loop optimisation.

* 'pow(n, 3)' to 'n * n * n' type optimisations.

* fabs() -> std::fabs().

src/mapgen/mapgen_carpathian.cpp

index 1a2456ae999a5c3e37e6de60f514419fd408f1e3..0cde170378f996bf1417cc9b978ddd0ca66b81ce 100644 (file)
@@ -192,7 +192,7 @@ void MapgenCarpathianParams::writeParams(Settings *settings) const
 }
 
 
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 
 // Lerp function
@@ -212,7 +212,7 @@ float MapgenCarpathian::getSteps(float noise)
 }
 
 
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 
 void MapgenCarpathian::makeChunk(BlockMakeData *data)
@@ -298,7 +298,7 @@ void MapgenCarpathian::makeChunk(BlockMakeData *data)
 }
 
 
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 
 int MapgenCarpathian::getSpawnLevelAtPoint(v2s16 p)
@@ -338,14 +338,15 @@ float MapgenCarpathian::terrainLevelAtPoint(s16 x, s16 z)
                float hill2 = getLerp(height3, height4, mnt_var);
                float hill3 = getLerp(height3, height2, mnt_var);
                float hill4 = getLerp(height1, height4, mnt_var);
-               float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
+               float hilliness =
+                       std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
 
                // Rolling hills
                float hill_mnt = hilliness * pow(n_hills, 2.f);
                float hills = pow(hter, 3.f) * hill_mnt;
 
                // Ridged mountains
-               float ridge_mnt = hilliness * (1.f - fabs(n_ridge_mnt));
+               float ridge_mnt = hilliness * (1.f - std::fabs(n_ridge_mnt));
                float ridged_mountains = pow(rter, 3.f) * ridge_mnt;
 
                // Step (terraced) mountains
@@ -364,7 +365,7 @@ float MapgenCarpathian::terrainLevelAtPoint(s16 x, s16 z)
 }
 
 
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 
 int MapgenCarpathian::generateTerrain()
@@ -373,10 +374,6 @@ int MapgenCarpathian::generateTerrain()
        MapNode mn_stone(c_stone);
        MapNode mn_water(c_water_source);
 
-       s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
-       u32 index2d = 0;
-       u32 index3d = 0;
-
        // Calculate noise for terrain generation
        noise_base->perlinMap2D(node_min.X, node_min.Z);
        noise_height1->perlinMap2D(node_min.X, node_min.Z);
@@ -392,70 +389,81 @@ int MapgenCarpathian::generateTerrain()
        noise_mnt_var->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
 
        //// Place nodes
-       for (s16 z = node_min.Z; z <= node_max.Z; z++) {
-               for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
-                       u32 vi = vm->m_area.index(node_min.X, y, z);
-                       for (s16 x = node_min.X; x <= node_max.X;
-                                       x++, vi++, index2d++, index3d++) {
-                               if (vm->m_data[vi].getContent() != CONTENT_IGNORE)
-                                       continue;
-
-                               // Base terrain
-                               float ground = noise_base->result[index2d];
-
-                               // Gradient & shallow seabed
-                               s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y;
-
-                               // Hill/Mountain height (hilliness)
-                               float height1 = noise_height1->result[index2d];
-                               float height2 = noise_height2->result[index2d];
-                               float height3 = noise_height3->result[index2d];
-                               float height4 = noise_height4->result[index2d];
-                               float mnt_var = noise_mnt_var->result[index3d];
-                               // Combine height noises and apply 3D variation
-                               float hill1 = getLerp(height1, height2, mnt_var);
-                               float hill2 = getLerp(height3, height4, mnt_var);
-                               float hill3 = getLerp(height3, height2, mnt_var);
-                               float hill4 = getLerp(height1, height4, mnt_var);
-                               // 'hilliness' determines whether hills/mountains are
-                               // small or large
-                               float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
-
-                               // Rolling hills
-                               float hter = noise_hills_terrain->result[index2d];
-                               float n_hills = noise_hills->result[index2d];
-                               float hill_mnt = hilliness * pow(n_hills, 2.f);
-                               float hills = pow(fabs(hter), 3.f) * hill_mnt;
-
-                               // Ridged mountains
-                               float rter = noise_ridge_terrain->result[index2d];
-                               float n_ridge_mnt = noise_ridge_mnt->result[index2d];
-                               float ridge_mnt = hilliness * (1.f - fabs(n_ridge_mnt));
-                               float ridged_mountains = pow(fabs(rter), 3.f) * ridge_mnt;
-
-                               // Step (terraced) mountains
-                               float ster = noise_step_terrain->result[index2d];
-                               float n_step_mnt = noise_step_mnt->result[index2d];
-                               float step_mnt = hilliness * getSteps(n_step_mnt);
-                               float step_mountains = pow(fabs(ster), 3.f) * step_mnt;
-
-                               // Final terrain level
-                               float mountains = hills + ridged_mountains + step_mountains;
-                               float surface_level = ground + mountains + grad;
-
-                               if (y < surface_level) {
-                                       vm->m_data[vi] = mn_stone; // Stone
-                                       if (y > stone_surface_max_y)
-                                               stone_surface_max_y = y;
-                               } else if (y <= water_level) {
-                                       vm->m_data[vi] = mn_water; // Sea water
-                               } else {
-                                       vm->m_data[vi] = mn_air; // Air
-                               }
+       const v3s16 &em = vm->m_area.getExtent();
+       s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT;
+       u32 index2d = 0;
+
+       for (s16 z = node_min.Z; z <= node_max.Z; z++)
+       for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
+               // Base terrain
+               float ground = noise_base->result[index2d];
+
+               // Hill/Mountain height (hilliness)
+               float height1 = noise_height1->result[index2d];
+               float height2 = noise_height2->result[index2d];
+               float height3 = noise_height3->result[index2d];
+               float height4 = noise_height4->result[index2d];
+
+               // Rolling hills
+               float hterabs = std::fabs(noise_hills_terrain->result[index2d]);
+               float n_hills = noise_hills->result[index2d];
+               float hill_mnt = hterabs * hterabs * hterabs * n_hills * n_hills;
+
+               // Ridged mountains
+               float rterabs = std::fabs(noise_ridge_terrain->result[index2d]);
+               float n_ridge_mnt = noise_ridge_mnt->result[index2d];
+               float ridge_mnt = rterabs * rterabs * rterabs *
+                       (1.f - std::fabs(n_ridge_mnt));
+
+               // Step (terraced) mountains
+               float sterabs = std::fabs(noise_step_terrain->result[index2d]);
+               float n_step_mnt = noise_step_mnt->result[index2d];
+               float step_mnt = sterabs * sterabs * sterabs * getSteps(n_step_mnt);
+
+               // Initialise 3D noise index and voxelmanip index to column base
+               u32 index3d = (z - node_min.Z) * zstride_1u1d + (x - node_min.X);
+               u32 vi = vm->m_area.index(x, node_min.Y - 1, z);
+
+               for (s16 y = node_min.Y - 1; y <= node_max.Y + 1;
+                               y++,
+                               index3d += ystride,
+                               VoxelArea::add_y(em, vi, 1)) {
+                       if (vm->m_data[vi].getContent() != CONTENT_IGNORE)
+                               continue;
+
+                       // Combine height noises and apply 3D variation
+                       float mnt_var = noise_mnt_var->result[index3d];
+                       float hill1 = getLerp(height1, height2, mnt_var);
+                       float hill2 = getLerp(height3, height4, mnt_var);
+                       float hill3 = getLerp(height3, height2, mnt_var);
+                       float hill4 = getLerp(height1, height4, mnt_var);
+
+                       // 'hilliness' determines whether hills/mountains are
+                       // small or large
+                       float hilliness =
+                               std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4));
+                       float hills = hill_mnt * hilliness;
+                       float ridged_mountains = ridge_mnt * hilliness;
+                       float step_mountains = step_mnt * hilliness;
+
+                       // Gradient & shallow seabed
+                       s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 :
+                               1 - y;
+
+                       // Final terrain level
+                       float mountains = hills + ridged_mountains + step_mountains;
+                       float surface_level = ground + mountains + grad;
+
+                       if (y < surface_level) {
+                               vm->m_data[vi] = mn_stone; // Stone
+                               if (y > stone_surface_max_y)
+                                       stone_surface_max_y = y;
+                       } else if (y <= water_level) {
+                               vm->m_data[vi] = mn_water; // Sea water
+                       } else {
+                               vm->m_data[vi] = mn_air; // Air
                        }
-                       index2d -= ystride;
                }
-               index2d += ystride;
        }
 
        return stone_surface_max_y;