mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-18 18:11:24 +01:00
feat: render states - separate pole detection from layer render
This commit is contained in:
parent
093014088c
commit
c66e6e4645
5 changed files with 45 additions and 24 deletions
|
|
@ -13,6 +13,8 @@ window.BurgsAndStates = (() => {
|
||||||
placeTowns();
|
placeTowns();
|
||||||
expandStates();
|
expandStates();
|
||||||
normalizeStates();
|
normalizeStates();
|
||||||
|
getPoles();
|
||||||
|
|
||||||
specifyBurgs();
|
specifyBurgs();
|
||||||
|
|
||||||
collectStatistics();
|
collectStatistics();
|
||||||
|
|
@ -468,8 +470,7 @@ window.BurgsAndStates = (() => {
|
||||||
|
|
||||||
const normalizeStates = () => {
|
const normalizeStates = () => {
|
||||||
TIME && console.time("normalizeStates");
|
TIME && console.time("normalizeStates");
|
||||||
const cells = pack.cells,
|
const {cells, burgs} = pack;
|
||||||
burgs = pack.burgs;
|
|
||||||
|
|
||||||
for (const i of cells.i) {
|
for (const i of cells.i) {
|
||||||
if (cells.h[i] < 20 || cells.burg[i]) continue; // do not overwrite burgs
|
if (cells.h[i] < 20 || cells.burg[i]) continue; // do not overwrite burgs
|
||||||
|
|
@ -486,6 +487,17 @@ window.BurgsAndStates = (() => {
|
||||||
TIME && console.timeEnd("normalizeStates");
|
TIME && console.timeEnd("normalizeStates");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// calculate pole of inaccessibility for each state
|
||||||
|
const getPoles = () => {
|
||||||
|
const getType = cellId => pack.cells.state[cellId];
|
||||||
|
const poles = getPolesOfInaccessibility(getType);
|
||||||
|
|
||||||
|
pack.states.forEach(s => {
|
||||||
|
if (!s.i || s.removed) return;
|
||||||
|
s.pole = poles[s.i] || [0, 0];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Resets the cultures of all burgs and states to their
|
// Resets the cultures of all burgs and states to their
|
||||||
// cell or center cell's (respectively) culture.
|
// cell or center cell's (respectively) culture.
|
||||||
const updateCultures = () => {
|
const updateCultures = () => {
|
||||||
|
|
@ -1194,6 +1206,7 @@ window.BurgsAndStates = (() => {
|
||||||
generate,
|
generate,
|
||||||
expandStates,
|
expandStates,
|
||||||
normalizeStates,
|
normalizeStates,
|
||||||
|
getPoles,
|
||||||
assignColors,
|
assignColors,
|
||||||
drawBurgs,
|
drawBurgs,
|
||||||
specifyBurgs,
|
specifyBurgs,
|
||||||
|
|
|
||||||
|
|
@ -845,6 +845,7 @@ function recalculateStates(must) {
|
||||||
if (!layerIsOn("toggleBorders")) toggleBorders();
|
if (!layerIsOn("toggleBorders")) toggleBorders();
|
||||||
else drawBorders();
|
else drawBorders();
|
||||||
if (layerIsOn("toggleProvinces")) drawProvinces();
|
if (layerIsOn("toggleProvinces")) drawProvinces();
|
||||||
|
BurgsAndStates.getPoles();
|
||||||
if (adjustLabels.checked) drawStateLabels();
|
if (adjustLabels.checked) drawStateLabels();
|
||||||
refreshStatesEditor();
|
refreshStatesEditor();
|
||||||
}
|
}
|
||||||
|
|
@ -981,6 +982,7 @@ function applyStatesManualAssignent() {
|
||||||
|
|
||||||
if (affectedStates.length) {
|
if (affectedStates.length) {
|
||||||
refreshStatesEditor();
|
refreshStatesEditor();
|
||||||
|
BurgsAndStates.getPoles();
|
||||||
layerIsOn("toggleStates") ? drawStates() : toggleStates();
|
layerIsOn("toggleStates") ? drawStates() : toggleStates();
|
||||||
if (adjustLabels.checked) drawStateLabels([...new Set(affectedStates)]);
|
if (adjustLabels.checked) drawStateLabels([...new Set(affectedStates)]);
|
||||||
adjustProvinces([...new Set(affectedProvinces)]);
|
adjustProvinces([...new Set(affectedProvinces)]);
|
||||||
|
|
@ -1415,6 +1417,7 @@ function openStateMergeDialog() {
|
||||||
unfog();
|
unfog();
|
||||||
debug.selectAll(".highlight").remove();
|
debug.selectAll(".highlight").remove();
|
||||||
|
|
||||||
|
BurgsAndStates.getPoles();
|
||||||
layerIsOn("toggleStates") ? drawStates() : toggleStates();
|
layerIsOn("toggleStates") ? drawStates() : toggleStates();
|
||||||
layerIsOn("toggleBorders") ? drawBorders() : toggleBorders();
|
layerIsOn("toggleBorders") ? drawBorders() : toggleBorders();
|
||||||
layerIsOn("toggleProvinces") && drawProvinces();
|
layerIsOn("toggleProvinces") && drawProvinces();
|
||||||
|
|
|
||||||
|
|
@ -991,18 +991,14 @@ function drawStates() {
|
||||||
TIME && console.time("drawStates");
|
TIME && console.time("drawStates");
|
||||||
const {cells, states} = pack;
|
const {cells, states} = pack;
|
||||||
|
|
||||||
const renderHalo = shapeRendering.value === "geometricPrecision";
|
|
||||||
const paths = getVertexPaths({
|
|
||||||
getType: cellId => cells.state[cellId],
|
|
||||||
options: {fill: true, waterGap: true, halo: renderHalo}
|
|
||||||
});
|
|
||||||
|
|
||||||
const maxLength = states.length - 1;
|
const maxLength = states.length - 1;
|
||||||
const bodyPaths = new Array(maxLength);
|
const bodyPaths = new Array(maxLength);
|
||||||
const clipPaths = new Array(maxLength);
|
const clipPaths = new Array(maxLength);
|
||||||
const haloPaths = new Array(maxLength);
|
const haloPaths = new Array(maxLength);
|
||||||
|
|
||||||
for (const [index, {fill, waterGap, halo}] of paths) {
|
const renderHalo = shapeRendering.value === "geometricPrecision";
|
||||||
|
const isolines = getIsolines(cellId => cells.state[cellId], {fill: true, waterGap: true, halo: renderHalo});
|
||||||
|
for (const [index, {fill, waterGap, halo}] of isolines) {
|
||||||
const color = states[index].color;
|
const color = states[index].color;
|
||||||
|
|
||||||
bodyPaths.push(
|
bodyPaths.push(
|
||||||
|
|
@ -1022,11 +1018,6 @@ function drawStates() {
|
||||||
byId("statePaths").innerHTML = renderHalo ? clipPaths.join("") : "";
|
byId("statePaths").innerHTML = renderHalo ? clipPaths.join("") : "";
|
||||||
byId("statesHalo").innerHTML = renderHalo ? haloPaths.join("") : "";
|
byId("statesHalo").innerHTML = renderHalo ? haloPaths.join("") : "";
|
||||||
|
|
||||||
// vArray.forEach((ar, i) => {
|
|
||||||
// const sorted = ar.sort((a, b) => b.length - a.length); // sort by points number
|
|
||||||
// states[i].pole = polylabel(sorted, 1.0); // pole of inaccessibility
|
|
||||||
// });
|
|
||||||
|
|
||||||
TIME && console.timeEnd("drawStates");
|
TIME && console.timeEnd("drawStates");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ function regenerateStates() {
|
||||||
pack.states = newStates;
|
pack.states = newStates;
|
||||||
BurgsAndStates.expandStates();
|
BurgsAndStates.expandStates();
|
||||||
BurgsAndStates.normalizeStates();
|
BurgsAndStates.normalizeStates();
|
||||||
|
BurgsAndStates.getPoles();
|
||||||
BurgsAndStates.collectStatistics();
|
BurgsAndStates.collectStatistics();
|
||||||
BurgsAndStates.assignColors();
|
BurgsAndStates.assignColors();
|
||||||
BurgsAndStates.generateCampaigns();
|
BurgsAndStates.generateCampaigns();
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// get continuous paths for all cells at once based on getType(cellId) comparison
|
// get continuous paths (isolines) for all cells at once based on getType(cellId) comparison
|
||||||
function getVertexPaths({getType, options}) {
|
function getIsolines(getType, options = {polygons: false, fill: false, halo: false, waterGap: false}) {
|
||||||
const {cells, vertices} = pack;
|
const {cells, vertices} = pack;
|
||||||
const paths = {};
|
const isolines = {};
|
||||||
|
|
||||||
const checkedCells = new Uint8Array(cells.c.length);
|
const checkedCells = new Uint8Array(cells.c.length);
|
||||||
const addToChecked = cellId => (checkedCells[cellId] = 1);
|
const addToChecked = cellId => (checkedCells[cellId] = 1);
|
||||||
|
|
@ -32,10 +32,10 @@ function getVertexPaths({getType, options}) {
|
||||||
const vertexChain = connectVertices({startingVertex, ofSameType, addToChecked, closeRing: true});
|
const vertexChain = connectVertices({startingVertex, ofSameType, addToChecked, closeRing: true});
|
||||||
if (vertexChain.length < 3) continue;
|
if (vertexChain.length < 3) continue;
|
||||||
|
|
||||||
addPath(type, vertexChain);
|
addIsoline(type, vertexChain);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Object.entries(paths);
|
return Object.entries(isolines);
|
||||||
|
|
||||||
function getBorderPath(vertexChain, discontinue) {
|
function getBorderPath(vertexChain, discontinue) {
|
||||||
let discontinued = true;
|
let discontinued = true;
|
||||||
|
|
@ -68,11 +68,12 @@ function getVertexPaths({getType, options}) {
|
||||||
return adjacentCells.every(i => cells.h[i] >= 20);
|
return adjacentCells.every(i => cells.h[i] >= 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPath(index, vertexChain) {
|
function addIsoline(index, vertexChain) {
|
||||||
if (!paths[index]) paths[index] = {fill: "", waterGap: "", halo: ""};
|
if (!isolines[index]) isolines[index] = {polygons: [], fill: "", waterGap: "", halo: ""};
|
||||||
if (options.fill) paths[index].fill += getFillPath(vertexChain);
|
if (options.polygons) isolines[index].polygons.push(vertexChain.map(getVertexPoint));
|
||||||
if (options.halo) paths[index].halo += getBorderPath(vertexChain, isBorderVertex);
|
if (options.fill) isolines[index].fill += getFillPath(vertexChain);
|
||||||
if (options.waterGap) paths[index].waterGap += getBorderPath(vertexChain, isLandVertex);
|
if (options.halo) isolines[index].halo += getBorderPath(vertexChain, isBorderVertex);
|
||||||
|
if (options.waterGap) isolines[index].waterGap += getBorderPath(vertexChain, isLandVertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,6 +125,18 @@ function getVertexPath(cellsArray) {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPolesOfInaccessibility(getType) {
|
||||||
|
const isolines = getIsolines(getType, {polygons: true});
|
||||||
|
|
||||||
|
const poles = isolines.map(([id, isoline]) => {
|
||||||
|
const multiPolygon = isoline.polygons.sort((a, b) => b.length - a.length);
|
||||||
|
const [x, y] = polylabel(multiPolygon, 20);
|
||||||
|
return [id, [rn(x), rn(y)]];
|
||||||
|
});
|
||||||
|
|
||||||
|
return Object.fromEntries(poles);
|
||||||
|
}
|
||||||
|
|
||||||
function connectVertices({startingVertex, ofSameType, addToChecked, closeRing}) {
|
function connectVertices({startingVertex, ofSameType, addToChecked, closeRing}) {
|
||||||
const vertices = pack.vertices;
|
const vertices = pack.vertices;
|
||||||
const MAX_ITERATIONS = pack.cells.i.length;
|
const MAX_ITERATIONS = pack.cells.i.length;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue