mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-18 18:11:24 +01:00
added topography
This commit is contained in:
parent
21df872ca2
commit
2c3692f000
5 changed files with 151 additions and 1 deletions
|
|
@ -494,6 +494,14 @@
|
||||||
>
|
>
|
||||||
<u>H</u>eightmap
|
<u>H</u>eightmap
|
||||||
</li>
|
</li>
|
||||||
|
<li
|
||||||
|
id="toggleTopography"
|
||||||
|
data-tip="Topographic contours: click to toggle, drag to raise or lower the layer"
|
||||||
|
data-shortcut="Q"
|
||||||
|
onclick="toggleTopography(event)"
|
||||||
|
>
|
||||||
|
Topo<u>g</u>raphy
|
||||||
|
</li>
|
||||||
<li
|
<li
|
||||||
id="toggleBiomes"
|
id="toggleBiomes"
|
||||||
data-tip="Biomes: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style"
|
data-tip="Biomes: click to toggle, drag to raise or lower the layer. Ctrl + click to edit layer style"
|
||||||
|
|
@ -8205,5 +8213,6 @@
|
||||||
<script defer src="modules/renderers/draw-burg-labels.js?v=1.108.1"></script>
|
<script defer src="modules/renderers/draw-burg-labels.js?v=1.108.1"></script>
|
||||||
<script defer src="modules/renderers/draw-burg-icons.js?v=1.104.0"></script>
|
<script defer src="modules/renderers/draw-burg-icons.js?v=1.104.0"></script>
|
||||||
<script defer src="modules/renderers/draw-relief-icons.js?v=1.108.4"></script>
|
<script defer src="modules/renderers/draw-relief-icons.js?v=1.108.4"></script>
|
||||||
|
<script defer src="modules/renderers/draw-topography.js?v=1.108.4"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
3
main.js
3
main.js
|
|
@ -50,6 +50,7 @@ let lakes = viewbox.append("g").attr("id", "lakes");
|
||||||
let landmass = viewbox.append("g").attr("id", "landmass");
|
let landmass = viewbox.append("g").attr("id", "landmass");
|
||||||
let texture = viewbox.append("g").attr("id", "texture");
|
let texture = viewbox.append("g").attr("id", "texture");
|
||||||
let terrs = viewbox.append("g").attr("id", "terrs");
|
let terrs = viewbox.append("g").attr("id", "terrs");
|
||||||
|
let topography = viewbox.append("g").attr("id", "topography");
|
||||||
let biomes = viewbox.append("g").attr("id", "biomes");
|
let biomes = viewbox.append("g").attr("id", "biomes");
|
||||||
let cells = viewbox.append("g").attr("id", "cells");
|
let cells = viewbox.append("g").attr("id", "cells");
|
||||||
let gridOverlay = viewbox.append("g").attr("id", "gridOverlay");
|
let gridOverlay = viewbox.append("g").attr("id", "gridOverlay");
|
||||||
|
|
@ -249,7 +250,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||||
hideLoading();
|
hideLoading();
|
||||||
await checkLoadParameters();
|
await checkLoadParameters();
|
||||||
}
|
}
|
||||||
restoreDefaultEvents; // apply default viewbox events
|
restoreDefaultEvents(); // apply default viewbox events
|
||||||
initiateAutosave();
|
initiateAutosave();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
125
modules/renderers/draw-topography.js
Normal file
125
modules/renderers/draw-topography.js
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Draw topographic hillshade-style fill per grid cell
|
||||||
|
function drawTopography() {
|
||||||
|
TIME && console.time("drawTopography");
|
||||||
|
|
||||||
|
const group = d3.select("#topography");
|
||||||
|
group.selectAll("*").remove();
|
||||||
|
|
||||||
|
const {cells, points, features: gridFeatures} = grid;
|
||||||
|
|
||||||
|
// Colorimetry from user (positive altitudes, depressions, negative altitudes)
|
||||||
|
// Start positive ramp at #BAAE9A as requested
|
||||||
|
const POSITIVE_COLORS = [
|
||||||
|
"#BAAE9A",
|
||||||
|
"#AC9A7C",
|
||||||
|
"#AA8753",
|
||||||
|
"#B9985A",
|
||||||
|
"#C3A76B",
|
||||||
|
"#CAB982",
|
||||||
|
"#D3CA9D",
|
||||||
|
"#DED6A3",
|
||||||
|
"#E8E1B6",
|
||||||
|
"#EFEBC0",
|
||||||
|
"#E1E4B5",
|
||||||
|
"#D1D7AB",
|
||||||
|
"#BDCC96",
|
||||||
|
"#A8C68F",
|
||||||
|
"#94BF8B",
|
||||||
|
"#ACD0A5"
|
||||||
|
];
|
||||||
|
const NEGATIVE_COLORS = [
|
||||||
|
"#D8F2FE",
|
||||||
|
"#C6ECFF",
|
||||||
|
"#B9E3FF",
|
||||||
|
"#ACDBFB",
|
||||||
|
"#A1D2F7",
|
||||||
|
"#96C9F0",
|
||||||
|
"#8DC1EA",
|
||||||
|
"#84B9E3",
|
||||||
|
"#79B2DE",
|
||||||
|
"#71ABD8"
|
||||||
|
];
|
||||||
|
const DEPRESSIONS_COLOR = "#0978AB"; // lakes / inland depressions: Rivers, coasts, hydronyms color
|
||||||
|
|
||||||
|
const posInterp = d3.interpolateRgbBasis(POSITIVE_COLORS);
|
||||||
|
const negInterp = d3.interpolateRgbBasis(NEGATIVE_COLORS);
|
||||||
|
|
||||||
|
// Base color scheme mirrors heightmap scheme
|
||||||
|
// not used now; we fully replace with provided palette
|
||||||
|
|
||||||
|
// Lighting settings (can be overridden by attributes)
|
||||||
|
const azimuth = (+group.attr("azimuth") || 315) * (Math.PI / 180); // degrees → radians
|
||||||
|
const altitude = (+group.attr("altitude") || 45) * (Math.PI / 180);
|
||||||
|
const light = [Math.cos(azimuth) * Math.cos(altitude), Math.sin(azimuth) * Math.cos(altitude), Math.sin(altitude)];
|
||||||
|
const zScale = +group.attr("zscale") || 0.8; // vertical exaggeration for normals
|
||||||
|
|
||||||
|
let html = "";
|
||||||
|
|
||||||
|
for (const i of cells.i) {
|
||||||
|
const h = cells.h[i];
|
||||||
|
const isWater = h < 20;
|
||||||
|
const featureType = isWater && gridFeatures ? gridFeatures[cells.f[i]]?.type : null;
|
||||||
|
const isLake = isWater && featureType === "lake";
|
||||||
|
|
||||||
|
// Estimate gradient from neighbors
|
||||||
|
const [cx, cy] = points[i];
|
||||||
|
let gx = 0,
|
||||||
|
gy = 0,
|
||||||
|
wsum = 0;
|
||||||
|
for (const n of cells.c[i]) {
|
||||||
|
if (n < 0) continue;
|
||||||
|
const [nx, ny] = points[n];
|
||||||
|
const dx = nx - cx;
|
||||||
|
const dy = ny - cy;
|
||||||
|
const dist = Math.hypot(dx, dy) || 1;
|
||||||
|
const dh = (cells.h[n] - h) / 100; // normalize height difference
|
||||||
|
const w = 1 / dist; // weight close neighbors higher
|
||||||
|
gx += w * dh * (dx / dist);
|
||||||
|
gy += w * dh * (dy / dist);
|
||||||
|
wsum += w;
|
||||||
|
}
|
||||||
|
if (wsum) {
|
||||||
|
gx /= wsum;
|
||||||
|
gy /= wsum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build surface normal and compute light intensity
|
||||||
|
const nx = -gx * zScale;
|
||||||
|
const ny = -gy * zScale;
|
||||||
|
const nz = 1;
|
||||||
|
const invLen = 1 / Math.hypot(nx, ny, nz);
|
||||||
|
const n0 = [nx * invLen, ny * invLen, nz * invLen];
|
||||||
|
const intensity = minmax(n0[0] * light[0] + n0[1] * light[1] + n0[2] * light[2], 0, 1);
|
||||||
|
|
||||||
|
// Base color from provided palettes
|
||||||
|
let baseColor;
|
||||||
|
if (isWater) {
|
||||||
|
if (isLake) baseColor = d3.color(DEPRESSIONS_COLOR);
|
||||||
|
else {
|
||||||
|
const t = minmax((20 - h) / 20, 0, 1); // shallow 0 → deep 1
|
||||||
|
baseColor = d3.color(negInterp(t));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const t = minmax((h - 20) / 80, 0, 1); // lowland 0 → highland 1
|
||||||
|
baseColor = d3.color(posInterp(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modulate lightness by intensity (weaker effect on water)
|
||||||
|
const hsl = d3.hsl(baseColor);
|
||||||
|
const k = isWater ? 0.4 : 0.8;
|
||||||
|
hsl.l = minmax(hsl.l * (0.6 + k * intensity), 0, 1);
|
||||||
|
const color = hsl.toString();
|
||||||
|
|
||||||
|
// Cell polygon
|
||||||
|
const poly = getGridPolygon(i)
|
||||||
|
.map(p => `${rn(p[0], 2)},${rn(p[1], 2)}`)
|
||||||
|
.join(" ");
|
||||||
|
html += `<polygon points="${poly}" fill="${color}" opacity="${(terrs.attr("opacity") || 1) * 1}" />`;
|
||||||
|
}
|
||||||
|
|
||||||
|
group.html(html);
|
||||||
|
|
||||||
|
TIME && console.timeEnd("drawTopography");
|
||||||
|
}
|
||||||
|
|
@ -61,6 +61,7 @@ function handleKeyup(event) {
|
||||||
else if (key === "%") toggleAddMarker();
|
else if (key === "%") toggleAddMarker();
|
||||||
else if (code === "KeyX") toggleTexture();
|
else if (code === "KeyX") toggleTexture();
|
||||||
else if (code === "KeyH") toggleHeight();
|
else if (code === "KeyH") toggleHeight();
|
||||||
|
else if (code === "KeyQ") toggleTopography();
|
||||||
else if (code === "KeyB") toggleBiomes();
|
else if (code === "KeyB") toggleBiomes();
|
||||||
else if (code === "KeyE") toggleCells();
|
else if (code === "KeyE") toggleCells();
|
||||||
else if (code === "KeyG") toggleGrid();
|
else if (code === "KeyG") toggleGrid();
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,7 @@ function drawLayers() {
|
||||||
drawFeatures();
|
drawFeatures();
|
||||||
if (layerIsOn("toggleTexture")) drawTexture();
|
if (layerIsOn("toggleTexture")) drawTexture();
|
||||||
if (layerIsOn("toggleHeight")) drawHeightmap();
|
if (layerIsOn("toggleHeight")) drawHeightmap();
|
||||||
|
if (layerIsOn("toggleTopography")) drawTopography();
|
||||||
if (layerIsOn("toggleBiomes")) drawBiomes();
|
if (layerIsOn("toggleBiomes")) drawBiomes();
|
||||||
if (layerIsOn("toggleCells")) drawCells();
|
if (layerIsOn("toggleCells")) drawCells();
|
||||||
if (layerIsOn("toggleGrid")) drawGrid();
|
if (layerIsOn("toggleGrid")) drawGrid();
|
||||||
|
|
@ -229,6 +230,18 @@ function toggleHeight(event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleTopography(event) {
|
||||||
|
const group = d3.select('#topography');
|
||||||
|
const hasContent = group.selectAll('*').size() > 0;
|
||||||
|
if (!hasContent) {
|
||||||
|
turnButtonOn('toggleTopography');
|
||||||
|
drawTopography();
|
||||||
|
} else {
|
||||||
|
turnButtonOff('toggleTopography');
|
||||||
|
group.selectAll('*').remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function toggleTemperature(event) {
|
function toggleTemperature(event) {
|
||||||
if (!temperature.selectAll("*").size()) {
|
if (!temperature.selectAll("*").size()) {
|
||||||
turnButtonOn("toggleTemperature");
|
turnButtonOn("toggleTemperature");
|
||||||
|
|
@ -1015,6 +1028,7 @@ function moveLayer(event, ui) {
|
||||||
// define connection between option layer buttons and actual svg groups to move the element
|
// define connection between option layer buttons and actual svg groups to move the element
|
||||||
function getLayer(id) {
|
function getLayer(id) {
|
||||||
if (id === "toggleHeight") return $("#terrs");
|
if (id === "toggleHeight") return $("#terrs");
|
||||||
|
if (id === "toggleTopography") return $("#topography");
|
||||||
if (id === "toggleBiomes") return $("#biomes");
|
if (id === "toggleBiomes") return $("#biomes");
|
||||||
if (id === "toggleCells") return $("#cells");
|
if (id === "toggleCells") return $("#cells");
|
||||||
if (id === "toggleGrid") return $("#gridOverlay");
|
if (id === "toggleGrid") return $("#gridOverlay");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue