refactor: openNearSeaLakes - remove as not required

This commit is contained in:
max 2022-07-24 17:56:25 +03:00
parent 3c6da6585e
commit fe4d4eac86
2 changed files with 52 additions and 39 deletions

View file

@ -9,7 +9,7 @@ import {byId} from "utils/shorthands";
import {ERROR} from "../config/logging";
import {lim, minmax} from "../utils/numberUtils";
import {aleaPRNG} from "scripts/aleaPRNG";
import {addLakesInDeepDepressions} from "scripts/generation/grid/lakes";
import {openNearSeaLakes, addLakesInDeepDepressions} from "scripts/generation/grid/lakes";
window.HeightmapGenerator = (function () {
let grid = null;
@ -75,19 +75,24 @@ window.HeightmapGenerator = (function () {
const generate = async function (graph) {
TIME && console.time("defineHeightmap");
const id = byId("templateInput").value;
Math.random = aleaPRNG(seed);
const isTemplate = id in heightmapTemplates;
const rawHeights = isTemplate ? fromTemplate(graph, id) : await fromPrecreated(graph, id);
const heights = addLakesInDeepDepressions(rawHeights, graph.cells.c, graph.cells.v, graph.vertices, graph.cells.i);
const rawHeights = id in heightmapTemplates ? fromTemplate(graph, id) : await fromPrecreated(graph, id);
const removedLakesHeights = openNearSeaLakes(rawHeights, graph.cells.c, graph.cells.i, graph.cells.b);
const addedLakesHeights = addLakesInDeepDepressions(
removedLakesHeights,
graph.cells.c,
graph.cells.v,
graph.vertices,
graph.cells.i
);
TIME && console.timeEnd("defineHeightmap");
clearData();
return heights;
return addedLakesHeights;
};
3;
function addStep(tool, a2, a3, a4, a5) {
if (tool === "Hill") return addHill(a2, a3, a4, a5);
if (tool === "Pit") return addPit(a2, a3, a4, a5);

View file

@ -8,51 +8,59 @@ const {LAND_COAST, WATER_COAST} = DISTANCE_FIELD;
// near sea lakes usually get a lot of water inflow
// most of them would brake threshold and flow out to sea (see Ancylus Lake)
// connect these type of lakes to the main water body to improve the heightmap
export function openNearSeaLakes(grid: IGraph & Partial<IGrid>) {
export function openNearSeaLakes(
heights: Uint8Array,
neighbours: number[][],
indexes: UintArray,
borderCells: IGraphCells["b"]
) {
if (getInputValue("templateInput") === "Atoll") return; // no need for Atolls
const {cells, features} = grid;
if (!features?.find(f => f && f.type === "lake")) return; // no lakes
TIME && console.time("openNearSeaLakes");
const LIMIT = 22; // max height that can be breached by water
const MAX_BREACHABLE_HEIGHT = 22; // max height that can be breached by water
const isLake = (featureId: number) => featureId && (features[featureId] as IGridFeature).type === "lake";
const isOcean = (featureId: number) => featureId && (features[featureId] as IGridFeature).type === "ocean";
const features: Dict<"ocean" | "lake"> = {};
const featureIds: Dict<number> = {};
let featureId = 0;
for (const cellId of cells.i) {
const featureId = cells.f[cellId];
if (!isLake(featureId)) continue; // not a lake cell
const lakeCoastalCells: Dict<number[]> = {};
check_neighbours: for (const neibCellId of cells.c[cellId]) {
// water cannot brake the barrier
if (cells.t[neibCellId] !== WATER_COAST || cells.h[neibCellId] > LIMIT) continue;
for (const cellId of indexes) {
if (featureIds[cellId]) continue;
if (heights[cellId] >= MIN_LAND_HEIGHT) continue;
for (const neibOfNeibCellId of cells.c[neibCellId]) {
const neibOfNeibFeatureId = cells.f[neibOfNeibCellId];
if (!isOcean(neibOfNeibFeatureId)) continue; // not an ocean
removeLake(neibCellId, featureId, neibOfNeibFeatureId);
break check_neighbours;
featureId += 1;
const breachableCoastalCells: number[] = [];
let isLake = true; // lakes are features surrounded by land cells
const queue = [cellId];
featureIds[cellId] = featureId;
while (queue.length) {
const nextCellId = queue.pop()!;
for (const neighborId of neighbours[nextCellId]) {
if (isLake && borderCells[neighborId]) isLake = false;
if (featureIds[neighborId]) continue;
const height = heights[neighborId];
if (height < MIN_LAND_HEIGHT) {
featureIds[neighborId] = featureId;
queue.push(neighborId);
} else if (isLake && height <= MAX_BREACHABLE_HEIGHT) {
breachableCoastalCells.push(neighborId);
}
}
}
features[featureId] = isLake ? "lake" : "ocean";
if (isLake) lakeCoastalCells[featureId] = breachableCoastalCells;
}
function removeLake(barrierCellId: number, lakeFeatureId: number, oceanFeatureId: number) {
cells.h[barrierCellId] = MIN_LAND_HEIGHT - 1;
cells.t[barrierCellId] = WATER_COAST;
cells.f[barrierCellId] = oceanFeatureId;
for (const neibCellId of cells.c[barrierCellId]) {
if (cells.h[neibCellId] >= MIN_LAND_HEIGHT) cells.t[neibCellId] = LAND_COAST;
}
if (features && lakeFeatureId) {
// mark former lake as ocean
(features[lakeFeatureId] as IGridFeature).type = "ocean";
}
}
console.log(featureIds, features, lakeCoastalCells);
TIME && console.timeEnd("openNearSeaLakes");
return heights;
}
// some deeply depressed areas may not be resolved on river generation