Index: binaries/data/mods/public/maps/random/rmgen/painter/DunePainter.js =================================================================== --- /dev/null +++ binaries/data/mods/public/maps/random/rmgen/painter/DunePainter.js @@ -0,0 +1,62 @@ +/** + *@param {Boolean} type - ELEVATION_MODIFY or ELEVATION_SET + *@param {Number} scale - Global scale of dune size + *@param {Number} vertical_scale - Vertical scale of dune size + *@param {Number} baseHeight - Dunes base altitude if type=ELEVATION_SET + */ +class DunePainter +{ + constructor(type = ELEVATION_MODIFY, scale = 1, verticalScale = 1, baseHeight = 0) + { + this.type = type; + this.scale = scale; + this.verticalScale = verticalScale; + } + + /** + *Dune base shape + *@param {Number} x [0,1] value + *@param {Number} xCrest [0,1] position of the dune crest + *@param {Boolean} dune true is dune, false is dome + */ + dune(x, xCrest = 0.75, dune = true) + { + return x < xCrest ? (1 - Math.cos(Math.PI * x / xCrest)) * 0.5 : + dune ? (1 - Math.cos(Math.PI * (x - 1) / (xCrest - 1))) * 0.5 : + 1 - Math.cos(Math.PI * (x - 1) / (xCrest - 1) * 0.5); + } + + paint(area) + { + let points = area.getPoints(); + + // 1st dune layer + let height1_1 = PerlinNoise(points, 6, 2, 1, 1.1, true); + let height1_2 = PerlinNoise(points, 3, 2, 1, 1, true); + let widht1 = 17.0 * this.scale; + + // 2on dune layer + let height2_1 = PerlinNoise(points, 8, 1, 2, 2, true); + let height2_2 = PerlinNoise(points, 4, 2, 2, 2, true); + let width2 = 14.0 * this.scale; + + // Loop all the points + for (let i = 0; i < points.length; i++) + { + // Main dunes creation + let value1 = ((points[i].x + height1_1[i] * 13 + points[i].y * 0.1) % widht1) / widht1; + let height1 = this.dune(value1, 0.60, false) * 9 * 0.9 + height1_1[i] * height1_2[i] * 150 * 0.1; + + // Secondary dunes + let value2 = ((points[i].x + height2_1[i] * 13 + points[i].y * 0.1) % width2) / width2; + let height2 = this.dune(value2, 0.60, false) * 9 * 0.9 + height2_2[i] * 50 * 0.1; + let height = (height1 * 0.8 + height2 * 0.2) * this.verticalScale * this.scale; + + // Add or set height + if (this.type) + g_Map.setHeight(points[i], height + g_Map.getHeight(points[i])); + else + g_Map.setHeight(points[i], baseHeight + height); + } + } +}