mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
refactor: lake group detection and features rendering
This commit is contained in:
parent
4a15dc3243
commit
4b874246e3
10 changed files with 52 additions and 60 deletions
|
|
@ -5,7 +5,6 @@ import {heightmapTemplates} from "config/heightmap-templates";
|
||||||
import {ERROR, INFO, TIME} from "config/logging";
|
import {ERROR, INFO, TIME} from "config/logging";
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
import {layerIsOn, turnLayerButtonOff, turnLayerButtonOn, updatePresetInput, renderLayer} from "layers";
|
import {layerIsOn, turnLayerButtonOff, turnLayerButtonOn, updatePresetInput, renderLayer} from "layers";
|
||||||
import {drawCoastline} from "modules/coastline";
|
|
||||||
import {markupGridFeatures} from "modules/markup";
|
import {markupGridFeatures} from "modules/markup";
|
||||||
import {generatePrecipitation} from "modules/precipitation";
|
import {generatePrecipitation} from "modules/precipitation";
|
||||||
import {calculateTemperatures} from "modules/temperature";
|
import {calculateTemperatures} from "modules/temperature";
|
||||||
|
|
@ -225,7 +224,6 @@ export function open(options) {
|
||||||
generatePrecipitation(grid);
|
generatePrecipitation(grid);
|
||||||
repackGrid(grid);
|
repackGrid(grid);
|
||||||
markupPackFeatures(pack, newGrid);
|
markupPackFeatures(pack, newGrid);
|
||||||
drawCoastline(pack);
|
|
||||||
|
|
||||||
Rivers.generate(pack, grid, erosionAllowed);
|
Rivers.generate(pack, grid, erosionAllowed);
|
||||||
|
|
||||||
|
|
@ -344,7 +342,6 @@ export function open(options) {
|
||||||
calculateTemperatures(grid);
|
calculateTemperatures(grid);
|
||||||
generatePrecipitation(grid);
|
generatePrecipitation(grid);
|
||||||
reGraph(grid);
|
reGraph(grid);
|
||||||
drawCoastline(pack);
|
|
||||||
|
|
||||||
if (erosionAllowed) Rivers.generate(pack, grid, true);
|
if (erosionAllowed) Rivers.generate(pack, grid, true);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import {simplify} from "scripts/simplify";
|
||||||
import {filterOutOfCanvasPoints} from "utils/lineUtils";
|
import {filterOutOfCanvasPoints} from "utils/lineUtils";
|
||||||
import {round} from "utils/stringUtils";
|
import {round} from "utils/stringUtils";
|
||||||
|
|
||||||
export function drawCoastline(vertices: IGraphVertices, features: TPackFeatures) {
|
export function drawFeatures() {
|
||||||
|
/* uses */ const {vertices, features} = pack;
|
||||||
|
|
||||||
const landMask = defs.select("#land");
|
const landMask = defs.select("#land");
|
||||||
const waterMask = defs.select("#water");
|
const waterMask = defs.select("#water");
|
||||||
|
|
||||||
|
|
@ -12,8 +14,7 @@ export function drawCoastline(vertices: IGraphVertices, features: TPackFeatures)
|
||||||
const SIMPLIFICATION_TOLERANCE = 0.3; // px
|
const SIMPLIFICATION_TOLERANCE = 0.3; // px
|
||||||
|
|
||||||
for (const feature of features) {
|
for (const feature of features) {
|
||||||
if (!feature) continue;
|
if (!feature || feature.type === "ocean") continue;
|
||||||
if (feature.type === "ocean") continue;
|
|
||||||
|
|
||||||
const points = feature.vertices.map(vertex => vertices.p[vertex]);
|
const points = feature.vertices.map(vertex => vertices.p[vertex]);
|
||||||
const filteredPoints = filterOutOfCanvasPoints(points);
|
const filteredPoints = filterOutOfCanvasPoints(points);
|
||||||
|
|
@ -28,7 +29,7 @@ export function drawCoastline(vertices: IGraphVertices, features: TPackFeatures)
|
||||||
.attr("id", "land_" + feature.i);
|
.attr("id", "land_" + feature.i);
|
||||||
|
|
||||||
lakes
|
lakes
|
||||||
.select("#freshwater")
|
.select(`#${feature.group}`)
|
||||||
.append("path")
|
.append("path")
|
||||||
.attr("d", path)
|
.attr("d", path)
|
||||||
.attr("id", "lake_" + feature.i)
|
.attr("id", "lake_" + feature.i)
|
||||||
|
|
@ -46,9 +47,8 @@ export function drawCoastline(vertices: IGraphVertices, features: TPackFeatures)
|
||||||
.attr("fill", "black")
|
.attr("fill", "black")
|
||||||
.attr("id", "water_" + feature.i);
|
.attr("id", "water_" + feature.i);
|
||||||
|
|
||||||
const group = feature.group === "lake_island" ? "lake_island" : "sea_island";
|
|
||||||
coastline
|
coastline
|
||||||
.select("#" + group)
|
.select(`#${feature.group}`)
|
||||||
.append("path")
|
.append("path")
|
||||||
.attr("d", path)
|
.attr("d", path)
|
||||||
.attr("id", "island_" + feature.i)
|
.attr("id", "island_" + feature.i)
|
||||||
|
|
@ -3,7 +3,7 @@ import {TIME} from "config/logging";
|
||||||
import {drawBiomes} from "./drawBiomes";
|
import {drawBiomes} from "./drawBiomes";
|
||||||
import {drawBorders} from "./drawBorders";
|
import {drawBorders} from "./drawBorders";
|
||||||
import {drawCells} from "./drawCells";
|
import {drawCells} from "./drawCells";
|
||||||
import {drawCoastline} from "./drawCoastline";
|
import {drawFeatures} from "./drawFeatures";
|
||||||
import {drawCoordinates} from "./drawCoordinates";
|
import {drawCoordinates} from "./drawCoordinates";
|
||||||
import {drawCultures} from "./drawCultures";
|
import {drawCultures} from "./drawCultures";
|
||||||
import {drawEmblems} from "./drawEmblems";
|
import {drawEmblems} from "./drawEmblems";
|
||||||
|
|
@ -24,10 +24,10 @@ const layerRenderersMap = {
|
||||||
biomes: drawBiomes,
|
biomes: drawBiomes,
|
||||||
borders: drawBorders,
|
borders: drawBorders,
|
||||||
cells: drawCells,
|
cells: drawCells,
|
||||||
coastline: drawCoastline,
|
|
||||||
coordinates: drawCoordinates,
|
coordinates: drawCoordinates,
|
||||||
cultures: drawCultures,
|
cultures: drawCultures,
|
||||||
emblems: drawEmblems,
|
emblems: drawEmblems,
|
||||||
|
features: drawFeatures,
|
||||||
grid: drawGrid,
|
grid: drawGrid,
|
||||||
heightmap: drawHeightmap,
|
heightmap: drawHeightmap,
|
||||||
ice: drawIce,
|
ice: drawIce,
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,6 @@ export function resolveVersionConflicts(version) {
|
||||||
lakes.selectAll("path").remove();
|
lakes.selectAll("path").remove();
|
||||||
|
|
||||||
reMarkFeatures(pack, newGrid);
|
reMarkFeatures(pack, newGrid);
|
||||||
drawCoastline(pack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < 1.11) {
|
if (version < 1.11) {
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,6 @@ import {DISTANCE_FIELD, MIN_LAND_HEIGHT} from "config/generation";
|
||||||
import {byId} from "utils/shorthands";
|
import {byId} from "utils/shorthands";
|
||||||
|
|
||||||
window.Lakes = (function () {
|
window.Lakes = (function () {
|
||||||
const defineGroup = function (pack: IPack) {
|
|
||||||
for (const feature of pack.features) {
|
|
||||||
if (feature && feature.type === "lake") {
|
|
||||||
const lakeEl = lakes.select(`[data-f="${feature.i}"]`).node();
|
|
||||||
if (!lakeEl) continue;
|
|
||||||
|
|
||||||
feature.group = getGroup(feature);
|
|
||||||
byId(feature.group)?.appendChild(lakeEl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const generateName = function () {
|
const generateName = function () {
|
||||||
Math.random = aleaPRNG(seed);
|
Math.random = aleaPRNG(seed);
|
||||||
for (const feature of pack.features) {
|
for (const feature of pack.features) {
|
||||||
|
|
@ -34,20 +22,6 @@ window.Lakes = (function () {
|
||||||
return Names.getCulture(culture);
|
return Names.getCulture(culture);
|
||||||
};
|
};
|
||||||
|
|
||||||
function getGroup(feature) {
|
|
||||||
if (feature.temp < -3) return "frozen";
|
|
||||||
if (feature.height > 60 && feature.cells < 10 && feature.firstCell % 10 === 0) return "lava";
|
|
||||||
|
|
||||||
if (!feature.inlets && !feature.outlet) {
|
|
||||||
if (feature.evaporation > feature.flux * 4) return "dry";
|
|
||||||
if (feature.cells < 3 && feature.firstCell % 10 === 0) return "sinkhole";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!feature.outlet && feature.evaporation > feature.flux) return "salt";
|
|
||||||
|
|
||||||
return "freshwater";
|
|
||||||
}
|
|
||||||
|
|
||||||
const {LAND_COAST, WATER_COAST} = DISTANCE_FIELD;
|
const {LAND_COAST, WATER_COAST} = DISTANCE_FIELD;
|
||||||
|
|
||||||
function addLakesInDeepDepressions(grid: IGraph & Partial<IGrid>) {
|
function addLakesInDeepDepressions(grid: IGraph & Partial<IGrid>) {
|
||||||
|
|
@ -162,11 +136,5 @@ window.Lakes = (function () {
|
||||||
TIME && console.timeEnd("openLakes");
|
TIME && console.timeEnd("openLakes");
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {generateName, getName, addLakesInDeepDepressions, openNearSeaLakes};
|
||||||
defineGroup,
|
|
||||||
generateName,
|
|
||||||
getName,
|
|
||||||
addLakesInDeepDepressions,
|
|
||||||
openNearSeaLakes
|
|
||||||
};
|
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,6 @@ window.Submap = (function () {
|
||||||
// remove misclassified cells
|
// remove misclassified cells
|
||||||
stage("Define coastline.");
|
stage("Define coastline.");
|
||||||
reMarkFeatures(pack, newGrid);
|
reMarkFeatures(pack, newGrid);
|
||||||
drawCoastline(pack);
|
|
||||||
|
|
||||||
/****************************************************/
|
/****************************************************/
|
||||||
/* Packed Graph */
|
/* Packed Graph */
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@ import {closeDialogs} from "dialogs/utils";
|
||||||
import {openDialog} from "dialogs";
|
import {openDialog} from "dialogs";
|
||||||
import {initLayers, renderLayer, restoreLayers} from "layers";
|
import {initLayers, renderLayer, restoreLayers} from "layers";
|
||||||
// @ts-expect-error js module
|
// @ts-expect-error js module
|
||||||
import {drawCoastline} from "layers/renderers/drawCoastline";
|
|
||||||
// @ts-expect-error js module
|
|
||||||
import {drawScaleBar, Rulers} from "modules/measurers";
|
import {drawScaleBar, Rulers} from "modules/measurers";
|
||||||
// @ts-expect-error js module
|
// @ts-expect-error js module
|
||||||
import {unfog} from "modules/ui/editors";
|
import {unfog} from "modules/ui/editors";
|
||||||
|
|
@ -63,7 +61,7 @@ async function generate(options?: IGenerationOptions) {
|
||||||
|
|
||||||
// temp rendering for debug
|
// temp rendering for debug
|
||||||
renderLayer("cells");
|
renderLayer("cells");
|
||||||
renderLayer("coastline", pack.vertices, pack.features);
|
renderLayer("features");
|
||||||
renderLayer("heightmap");
|
renderLayer("heightmap");
|
||||||
renderLayer("rivers", pack);
|
renderLayer("rivers", pack);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ export const getClimateData = function (
|
||||||
return lakeData;
|
return lakeData;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mergeLakeData = function (
|
export const mergeLakeDataToFeatures = function (
|
||||||
features: TPackFeatures,
|
features: TPackFeatures,
|
||||||
lakeData: ILakeClimateData[],
|
lakeData: ILakeClimateData[],
|
||||||
rivers: Pick<IRiver, "i">[]
|
rivers: Pick<IRiver, "i">[]
|
||||||
|
|
@ -57,11 +57,12 @@ export const mergeLakeData = function (
|
||||||
const lake = lakeData.find(lake => lake.i === feature.i);
|
const lake = lakeData.find(lake => lake.i === feature.i);
|
||||||
if (!lake) return feature;
|
if (!lake) return feature;
|
||||||
|
|
||||||
const {flux, temp, evaporation} = lake;
|
const {firstCell, height, flux, temp, evaporation} = lake;
|
||||||
const inlets = lake.inlets?.filter(inlet => rivers.find(river => river.i === inlet));
|
const inlets = lake.inlets?.filter(inlet => rivers.find(river => river.i === inlet));
|
||||||
const outlet = rivers.find(river => river.i === lake.outlet)?.i;
|
const outlet = rivers.find(river => river.i === lake.outlet)?.i;
|
||||||
|
const group = defineLakeGroup({firstCell, height, flux, temp, evaporation, inlets, outlet});
|
||||||
|
|
||||||
const lakeFeature: IPackFeatureLake = {...feature, flux, temp, evaporation, inlets, outlet};
|
const lakeFeature: IPackFeatureLake = {...feature, flux, temp, evaporation, inlets, outlet, group};
|
||||||
if (!inlets || !inlets.length) delete lakeFeature.inlets;
|
if (!inlets || !inlets.length) delete lakeFeature.inlets;
|
||||||
if (!outlet) delete lakeFeature.outlet;
|
if (!outlet) delete lakeFeature.outlet;
|
||||||
|
|
||||||
|
|
@ -70,3 +71,33 @@ export const mergeLakeData = function (
|
||||||
|
|
||||||
return updatedFeatures as TPackFeatures;
|
return updatedFeatures as TPackFeatures;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function defineLakeGroup({
|
||||||
|
firstCell,
|
||||||
|
height,
|
||||||
|
flux,
|
||||||
|
temp,
|
||||||
|
evaporation,
|
||||||
|
inlets,
|
||||||
|
outlet
|
||||||
|
}: {
|
||||||
|
firstCell: number;
|
||||||
|
height: number;
|
||||||
|
flux: number;
|
||||||
|
temp: number;
|
||||||
|
evaporation: number;
|
||||||
|
inlets?: number[];
|
||||||
|
outlet?: number;
|
||||||
|
}): IPackFeatureLake["group"] {
|
||||||
|
if (temp < -3) return "frozen";
|
||||||
|
if (height > 60 && cells < 10 && firstCell % 10 === 0) return "lava";
|
||||||
|
|
||||||
|
if ((!inlets || !inlets.length) && !outlet) {
|
||||||
|
if (evaporation > flux * 4) return "dry";
|
||||||
|
if (cells < 3 && firstCell % 10 === 0) return "sinkhole";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!outlet && evaporation > flux) return "salt";
|
||||||
|
|
||||||
|
return "freshwater";
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
|
|
||||||
// @ts-expect-error js module
|
|
||||||
import {drawCoastline} from "layers/renderers/drawCoastline";
|
|
||||||
import {markupPackFeatures} from "modules/markup";
|
import {markupPackFeatures} from "modules/markup";
|
||||||
// @ts-expect-error js module
|
// @ts-expect-error js module
|
||||||
import {drawScaleBar} from "modules/measurers";
|
import {drawScaleBar} from "modules/measurers";
|
||||||
|
|
@ -22,17 +20,19 @@ const {LAND_COAST, WATER_COAST, DEEPER_WATER} = DISTANCE_FIELD;
|
||||||
export function createPack(grid: IGrid): IPack {
|
export function createPack(grid: IGrid): IPack {
|
||||||
const {vertices, cells} = repackGrid(grid);
|
const {vertices, cells} = repackGrid(grid);
|
||||||
|
|
||||||
const markup = markupPackFeatures(grid, vertices, pick(cells, "v", "c", "b", "p", "h"));
|
const {features, featureIds, distanceField, haven, harbor} = markupPackFeatures(
|
||||||
const {features, featureIds, distanceField, haven, harbor} = markup;
|
grid,
|
||||||
|
vertices,
|
||||||
|
pick(cells, "v", "c", "b", "p", "h")
|
||||||
|
);
|
||||||
|
|
||||||
const {heights, flux, r, conf, rivers, mergedFeatures} = generateRivers(
|
const {heights, flux, r, conf, rivers, mergedFeatures} = generateRivers(
|
||||||
grid.cells.prec,
|
grid.cells.prec,
|
||||||
grid.cells.temp,
|
grid.cells.temp,
|
||||||
pick({...cells, f: featureIds, t: distanceField, haven}, "i", "c", "b", "g", "t", "h", "f", "haven", "p"),
|
{...pick(cells, "i", "c", "b", "g", "h", "p"), f: featureIds, t: distanceField, haven},
|
||||||
features
|
features
|
||||||
);
|
);
|
||||||
|
|
||||||
// Lakes.defineGroup(newPack);
|
|
||||||
// Biomes.define(newPack, grid);
|
// Biomes.define(newPack, grid);
|
||||||
|
|
||||||
// const rankCellsData = pick(newPack.cells, "i", "f", "fl", "conf", "r", "h", "area", "biome", "haven", "harbor");
|
// const rankCellsData = pick(newPack.cells, "i", "f", "fl", "conf", "r", "h", "area", "biome", "haven", "harbor");
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import {DISTANCE_FIELD, MAX_HEIGHT, MIN_LAND_HEIGHT} from "config/generation";
|
||||||
import {getInputNumber} from "utils/nodeUtils";
|
import {getInputNumber} from "utils/nodeUtils";
|
||||||
import {pick} from "utils/functionUtils";
|
import {pick} from "utils/functionUtils";
|
||||||
import {byId} from "utils/shorthands";
|
import {byId} from "utils/shorthands";
|
||||||
import {mergeLakeData, getClimateData, ILakeClimateData} from "./lakes";
|
import {mergeLakeDataToFeatures, getClimateData, ILakeClimateData} from "./lakes";
|
||||||
import {drawArrow} from "utils/debugUtils";
|
import {drawArrow} from "utils/debugUtils";
|
||||||
|
|
||||||
const {Rivers} = window;
|
const {Rivers} = window;
|
||||||
|
|
@ -44,7 +44,7 @@ export function generateRivers(
|
||||||
const {r, conf, rivers} = defineRivers();
|
const {r, conf, rivers} = defineRivers();
|
||||||
const heights = downcutRivers(currentCellHeights);
|
const heights = downcutRivers(currentCellHeights);
|
||||||
|
|
||||||
const mergedFeatures = mergeLakeData(features, lakeData, rivers);
|
const mergedFeatures = mergeLakeDataToFeatures(features, lakeData, rivers);
|
||||||
|
|
||||||
TIME && console.timeEnd("generateRivers");
|
TIME && console.timeEnd("generateRivers");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue