diff --git a/index.html b/index.html index 20704075..577b4140 100644 --- a/index.html +++ b/index.html @@ -2959,6 +2959,7 @@ + diff --git a/modules/heightmap-generator.js b/modules/heightmap-generator.js index 80eecde1..762350ce 100644 --- a/modules/heightmap-generator.js +++ b/modules/heightmap-generator.js @@ -365,8 +365,8 @@ window.HeightmapGenerator = (function () { const endX = vert ? Math.floor(graphWidth - startX - graphWidth * 0.1 + Math.random() * graphWidth * 0.2) : graphWidth - 5; const endY = vert ? graphHeight - 5 : Math.floor(graphHeight - startY - graphHeight * 0.1 + Math.random() * graphHeight * 0.2); - const start = findGridCell(startX, startY), - end = findGridCell(endX, endY); + const start = findGridCell(startX, startY); + const end = findGridCell(endX, endY); let range = getRange(start, end); const query = []; @@ -446,6 +446,26 @@ window.HeightmapGenerator = (function () { }); }; + const invert = (count, axes) => { + if (!P(count)) return; + + const invertX = axes !== "y"; + const invertY = axes !== "x"; + const {cellsX, cellsY} = grid; + + const inverted = cells.h.map((h, i) => { + const x = i % cellsX; + const y = Math.floor(i / cellsX); + + const nx = invertX ? cellsX - x - 1 : x; + const ny = invertY ? cellsY - y - 1 : y; + const invertedI = nx + ny * cellsX; + return cells.h[invertedI]; + }); + + cells.h = inverted; + }; + function getPointInRange(range, length) { if (typeof range !== "string") { ERROR && console.error("Range should be a string"); @@ -465,5 +485,5 @@ window.HeightmapGenerator = (function () { } } - return {generate, addHill, addRange, addTrough, addStrait, addPit, smooth, modify, mask}; + return {generate, addHill, addRange, addTrough, addStrait, addPit, smooth, modify, mask, invert}; })(); diff --git a/modules/heightmap-templates.js b/modules/heightmap-templates.js index baff264c..7e0cd20c 100644 --- a/modules/heightmap-templates.js +++ b/modules/heightmap-templates.js @@ -69,7 +69,7 @@ window.HeightmapTemplates = (function () { Hill .5 30-50 25-35 30-70 Smooth 1 0 0 0 Multiply 0.2 25-100 0 0 - Hill .5 10-20 50-55 48-52`; + Hill 0.5 10-20 50-55 48-52`; const mediterranean = `Range 4-6 30-80 0-100 0-10 Range 4-6 30-80 0-100 90-100 @@ -90,7 +90,8 @@ window.HeightmapTemplates = (function () { Hill 3-4 3-5 5-95 80-100 Hill 1-2 3-5 5-95 40-60 Trough 5-6 10-25 5-95 5-95 - Smooth 3 0 0 0`; + Smooth 3 0 0 0 + Invert 0.4 both 0 0`; const pangea = `Hill 1-2 25-40 15-50 0-10 Hill 1-2 5-40 50-85 0-10 @@ -113,7 +114,8 @@ window.HeightmapTemplates = (function () { Trough 4-8 15-30 10-50 20-40 Trough 4-8 15-30 30-70 40-60 Trough 4-8 15-30 50-90 60-80 - Trough 4-8 15-30 70-100 80-100`; + Trough 4-8 15-30 70-100 80-100 + Invert 0.25 x 0 0`; const shattered = `Hill 8 35-40 15-85 30-70 Trough 10-20 40-50 5-95 5-95 diff --git a/modules/ui/heightmap-editor.js b/modules/ui/heightmap-editor.js index 14963745..12d8b283 100644 --- a/modules/ui/heightmap-editor.js +++ b/modules/ui/heightmap-editor.js @@ -613,9 +613,7 @@ function editHeightmap() { const power = brushPower.valueAsNumber; const interpolate = d3.interpolateRound(power, 1); const land = changeOnlyLand.checked; - function lim(v) { - return minmax(v, land ? 20 : 0, 100); - } + const lim = v => minmax(v, land ? 20 : 0, 100); const h = grid.cells.h; const brush = document.querySelector("#brushesButtons > button.pressed").id; @@ -674,15 +672,10 @@ function editHeightmap() { } function startFromScratch() { - if (changeOnlyLand.checked) { - tip("Not allowed when 'Change only land cells' mode is set", false, "error"); - return; - } + if (changeOnlyLand.checked) return tip("Not allowed when 'Change only land cells' mode is set", false, "error"); const someHeights = grid.cells.h.some(h => h); - if (!someHeights) { - tip("Heightmap is already cleared, please do not click twice if not required", false, "error"); - return; - } + if (!someHeights) return tip("Heightmap is already cleared, please do not click twice if not required", false, "error"); + grid.cells.h = new Uint8Array(grid.cells.i.length); viewbox.select("#heights").selectAll("*").remove(); updateHistory(); @@ -752,19 +745,21 @@ function editHeightmap() { } function addStep(type, count, dist, arg4, arg5) { - const body = byId("templateBody"); - body.insertAdjacentHTML("beforeend", getStepHTML(type, count, dist, arg4, arg5)); - const elDist = body.querySelector("div:last-child").querySelector(".templateDist"); - if (elDist) elDist.on("change", setRange); - if (dist && elDist && elDist.tagName === "SELECT") { - for (const o of elDist.options) { - if (o.value === dist) elDist.value = dist; + const $body = byId("templateBody"); + $body.insertAdjacentHTML("beforeend", getStepHTML(type, count, dist, arg4, arg5)); + + const $elDist = $body.querySelector("div:last-child > span > .templateDist"); + if ($elDist) $elDist.on("change", setRange); + + if (dist && $elDist && $elDist.tagName === "SELECT") { + for (const option of $elDist.options) { + if (option.value === dist) $elDist.value = dist; } - if (elDist.value !== dist) { + if ($elDist.value !== dist) { const opt = document.createElement("option"); opt.value = opt.innerHTML = dist; - elDist.add(opt); - elDist.value = dist; + $elDist.add(opt); + $elDist.value = dist; } } } @@ -775,52 +770,97 @@ function editHeightmap() { const Reorder = /* html */ ``; const common = /* html */ `
${Hide}
${type}
${Trash}${Reorder}`; - const TempY = /* html */ `y:`; + const TempY = /* html */ `y: + + `; - const TempX = /* html */ `x:`; + const TempX = /* html */ `x: + + `; - const Height = /* html */ `h:`; + const Height = /* html */ `h: + + `; - const Count = /* html */ `n:`; + const Count = /* html */ `n: + + `; if (type === "Hill" || type === "Pit" || type === "Range" || type === "Trough") return /* html */ `${common}${TempY}${TempX}${Height}${Count}
`; if (type === "Strait") - return /* html */ `${common}d: - w:`; + return /* html */ `${common} + d: + + + w: + + + `; + + if (type === "Invert") + return /* html */ `${common} + by: + + + n: + + + `; if (type === "Mask") - return /* html */ `${common}f:`; + return /* html */ `${common} + f: + + + `; if (type === "Add") - return /* html */ `${common}to: - v:`; + return /* html */ `${common} + to: + + + v: + + + `; if (type === "Multiply") - return /* html */ `${common}to: - v:`; + return /* html */ `${common} + to: + + + v: + + + `; if (type === "Smooth") - return /* html */ `${common}f:`; + return /* html */ `${common} + f: + + + `; } function setRange(event) { @@ -903,6 +943,7 @@ function editHeightmap() { else if (type === "Trough") HeightmapGenerator.addTrough(count, height, x, y); else if (type === "Strait") HeightmapGenerator.addStrait(count, dist); else if (type === "Mask") HeightmapGenerator.mask(+count); + else if (type === "Invert") HeightmapGenerator.invert(+count, dist); else if (type === "Add") HeightmapGenerator.modify(dist, +count, 1); else if (type === "Multiply") HeightmapGenerator.modify(dist, 0, +count); else if (type === "Smooth") HeightmapGenerator.smooth(+count);