LCOV - code coverage report
Current view: top level - maps/random/rmgen/painter - SmoothingPainter.js (source / functions) Hit Total Coverage
Test: lcov.info Lines: 28 31 90.3 %
Date: 2023-04-02 12:52:40 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /**
       2             :  * Applies smoothing to the given area using Inverse-Distance-Weighting / Shepard's method.
       3             :  *
       4             :  * @param {Number} size - Determines the number of neighboring heights to interpolate. The area is a square with the length twice this size.
       5             :  * @param {Number} strength - Between 0 (no effect) and 1 (only neighbor heights count). This parameter has the lowest performance impact.
       6             :  * @param {Number} iterations - How often the process should be repeated. Typically 1. Can be used to gain even more smoothing.
       7             :  */
       8             : function SmoothingPainter(size, strength, iterations)
       9             : {
      10           1 :         if (size < 1)
      11           0 :                 throw new Error("Invalid size: " + size);
      12             : 
      13           1 :         if (strength <= 0 || strength > 1)
      14           0 :                 throw new Error("Invalid strength: " + strength);
      15             : 
      16           1 :         if (iterations <= 0)
      17           0 :                 throw new Error("Invalid iterations: " + iterations);
      18             : 
      19           1 :         this.size = Math.floor(size);
      20           1 :         this.strength = strength;
      21           1 :         this.iterations = iterations;
      22             : }
      23             : 
      24           6 : SmoothingPainter.prototype.paint = function(area)
      25             : {
      26           1 :         let brushPoints = getPointsInBoundingBox(getBoundingBox(
      27           2 :                 new Array(2).fill(0).map((zero, i) => new Vector2D(1, 1).mult(this.size).mult(i ? 1 : -1))));
      28             : 
      29           1 :         for (let i = 0; i < this.iterations; ++i)
      30             :         {
      31           1 :                 let heightmap = clone(g_Map.height);
      32             : 
      33             :                 // Additional complexity to process all 4 vertices of each tile, i.e the last row too
      34         513 :                 let seen = new Array(heightmap.length).fill(0).map(zero => new Uint8Array(heightmap.length).fill(0));
      35             : 
      36           1 :                 for (let point of area.getPoints())
      37           9 :                         for (let tileVertex of g_TileVertices)
      38             :                         {
      39          36 :                                 let vertex = Vector2D.add(point, tileVertex);
      40          36 :                                 if (!g_Map.validHeight(vertex) || seen[vertex.x][vertex.y])
      41          20 :                                         continue;
      42             : 
      43          16 :                                 seen[vertex.x][vertex.y] = 1;
      44             : 
      45          16 :                                 let sumWeightedHeights = 0;
      46          16 :                                 let sumWeights = 0;
      47             : 
      48          16 :                                 for (let brushPoint of brushPoints)
      49             :                                 {
      50         400 :                                         let position = Vector2D.add(vertex, brushPoint);
      51         400 :                                         let distance = Math.abs(brushPoint.x) + Math.abs(brushPoint.y);
      52         400 :                                         if (!distance || !g_Map.validHeight(position))
      53          16 :                                                 continue;
      54             : 
      55         384 :                                         sumWeightedHeights += g_Map.getHeight(position) / distance;
      56         384 :                                         sumWeights += 1 / distance;
      57             :                                 }
      58             : 
      59          16 :                                 g_Map.setHeight(
      60             :                                         vertex,
      61             :                                         this.strength * sumWeightedHeights / sumWeights +
      62             :                                         (1 - this.strength) * g_Map.getHeight(vertex));
      63             :                         }
      64             :         }
      65             : };

Generated by: LCOV version 1.14