First step for v6 biome rendering mode
This commit is contained in:
parent
ddb8914e5a
commit
eec2e94ce1
28
index.html
28
index.html
@ -19,14 +19,22 @@ ERROR: This tool requires JavaScript to work, but JavaScript is disabled in your
|
||||
</div>
|
||||
</noscript>
|
||||
</div>
|
||||
|
||||
<!-- The main content container starts hidden so it doesn't clutter
|
||||
the page in noscript mode. It will be unhidden once the JavaScript loads -->
|
||||
<div id="mainContentContainer" class="contentContainer" hidden>
|
||||
|
||||
<div id="modeContainer">
|
||||
<button id="modernModeButton" type="button">Modern biomes</button>
|
||||
<button id="v6ModeButton" type="button">v6 biomes</button>
|
||||
</div>
|
||||
|
||||
<div id="canvasContainer">
|
||||
<canvas id="voronoiCanvas" width="500" height="500">
|
||||
A Voronoi diagram is supposed to be here but for some reason it cannot be displayed. This tool is useless without this functionality.
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
<div id="diagramInfoContainer" class="borderedSection">
|
||||
<span id="errorMessage" hidden></span>
|
||||
<span id="altitudeDisplay"></span>
|
||||
@ -36,7 +44,8 @@ A Voronoi diagram is supposed to be here but for some reason it cannot be displa
|
||||
<span id="coordinateDisplay"> </span>
|
||||
<br>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<div id="biomeConfigContainerOuter">
|
||||
<h2 class="configHeader"><span class="collapser" id="biomeConfigHeaderLink">▼</span> Biome configuration</h2>
|
||||
<div id="biomeConfigContainer" class="configFrame">
|
||||
<form id="biomeForm">
|
||||
@ -78,7 +87,9 @@ A Voronoi diagram is supposed to be here but for some reason it cannot be displa
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
</div>
|
||||
|
||||
<div id="viewConfigContainerOuter">
|
||||
<h2 class="configHeader"><span class="collapser" id="viewConfigHeaderLink">▼</span> Diagram view settings</h2>
|
||||
<div id="viewConfigContainer" class="configFrame">
|
||||
<form id="viewForm">
|
||||
@ -104,11 +115,12 @@ A Voronoi diagram is supposed to be here but for some reason it cannot be displa
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<div id="noiseConfigContainerOuter">
|
||||
<h2 class="configHeader"><span class="collapser" id="noiseConfigHeaderLink">▼</span> Noise parameters</h2>
|
||||
<div class="configFrame" id="noiseConfigContainer">
|
||||
<form id="noiseForm">
|
||||
<h3>Heat (<code>mg_biome_np_heat</code>)</h3>
|
||||
<h3>Heat (<code id="noiseSettingNameHeat">mg_biome_np_heat</code>)</h3>
|
||||
<label for="inputNoiseHeatOffset">Offset: </label>
|
||||
<input id="inputNoiseHeatOffset" type="number" value="50" size="10">
|
||||
|
||||
@ -121,7 +133,7 @@ A Voronoi diagram is supposed to be here but for some reason it cannot be displa
|
||||
<label for="inputNoiseHeatPersistence">Persistence: </label>
|
||||
<input id="inputNoiseHeatPersistence" type="number" value="0.5" step=0.01 size="10">
|
||||
|
||||
<h3>Humidity (<code>mg_biome_np_humidity</code>)</h3>
|
||||
<h3>Humidity (<code id="noiseSettingNameHumidity">mg_biome_np_humidity</code>)</h3>
|
||||
<label for="inputNoiseHumidityOffset">Offset: </label>
|
||||
<input id="inputNoiseHumidityOffset" type="number" value="50" size="10">
|
||||
|
||||
@ -139,9 +151,8 @@ A Voronoi diagram is supposed to be here but for some reason it cannot be displa
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="importContainerOuter">
|
||||
<h2 class="configHeader"><span class="collapser" id="importHeaderLink">▶</span> Import</h2>
|
||||
<div class="configFrame" id="importContainer" style="display:none">
|
||||
<form id="importForm">
|
||||
@ -156,7 +167,7 @@ A Voronoi diagram is supposed to be here but for some reason it cannot be displa
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="exportContainerOuter">
|
||||
<h2 class="configHeader"><span class="collapser" id="exportHeaderLink">▶</span> Export</h2>
|
||||
<div class="configFrame" id="exportContainer" style="display:none">
|
||||
<form id="exportForm">
|
||||
@ -172,6 +183,7 @@ A Voronoi diagram is supposed to be here but for some reason it cannot be displa
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
197
mibpov.js
197
mibpov.js
@ -6,6 +6,7 @@ const MAX_Y_DEFAULT = 31000
|
||||
|
||||
// Draw a grid line every GRID_STEP units
|
||||
const GRID_STEP = 10
|
||||
const GRID_STEP_V6 = 0.2
|
||||
|
||||
// Size of the resizing corner
|
||||
const RESIZE_CORNER = 14;
|
||||
@ -116,25 +117,45 @@ const NOISE_SCALE_DEFAULT = 50;
|
||||
const NOISE_PERSISTENCE_DEFAULT = 0.5;
|
||||
const NOISE_OCTAVES_DEFAULT = 3;
|
||||
const NOISE_ABSVALUE_DEFAULT = false;
|
||||
const NOISE_V6_OFFSET_DEFAULT = 0;
|
||||
const NOISE_V6_SCALE_DEFAULT = 1;
|
||||
const NOISE_V6_PERSISTENCE_DEFAULT = 0.5;
|
||||
const NOISE_V6_OCTAVES_DEFAULT = 3;
|
||||
const NOISE_V6_ABSVALUE_DEFAULT = false;
|
||||
|
||||
// Current noise values
|
||||
let noises = {
|
||||
heat: {
|
||||
heat_modern: {
|
||||
offset: NOISE_OFFSET_DEFAULT,
|
||||
scale: NOISE_SCALE_DEFAULT,
|
||||
octaves: NOISE_OCTAVES_DEFAULT,
|
||||
persistence: NOISE_PERSISTENCE_DEFAULT,
|
||||
absvalue: NOISE_ABSVALUE_DEFAULT,
|
||||
},
|
||||
humidity: {
|
||||
humidity_modern: {
|
||||
offset: NOISE_OFFSET_DEFAULT,
|
||||
scale: NOISE_SCALE_DEFAULT,
|
||||
octaves: NOISE_OCTAVES_DEFAULT,
|
||||
persistence: NOISE_PERSISTENCE_DEFAULT,
|
||||
absvalue: NOISE_ABSVALUE_DEFAULT,
|
||||
},
|
||||
|
||||
heat_v6: {
|
||||
offset: NOISE_V6_OFFSET_DEFAULT,
|
||||
scale: NOISE_V6_SCALE_DEFAULT,
|
||||
octaves: NOISE_V6_OCTAVES_DEFAULT,
|
||||
persistence: NOISE_V6_PERSISTENCE_DEFAULT,
|
||||
absvalue: NOISE_V6_ABSVALUE_DEFAULT,
|
||||
},
|
||||
humidity_v6: {
|
||||
offset: NOISE_V6_OFFSET_DEFAULT,
|
||||
scale: NOISE_V6_SCALE_DEFAULT,
|
||||
octaves: NOISE_V6_OCTAVES_DEFAULT,
|
||||
persistence: NOISE_V6_PERSISTENCE_DEFAULT,
|
||||
absvalue: NOISE_V6_ABSVALUE_DEFAULT,
|
||||
},
|
||||
};
|
||||
noises.heat = noises.heat_modern;
|
||||
noises.humidity = noises.humidity_modern;
|
||||
|
||||
function updateAreaVarsFor(noiseType) {
|
||||
let noise = noises[noiseType];
|
||||
@ -442,7 +463,7 @@ function putPoint(context, point) {
|
||||
};
|
||||
|
||||
/* Put the grid on the draw context */
|
||||
function putGrid(context) {
|
||||
function putGrid(context, gridStep) {
|
||||
let [limit_x_min, limit_y_min] = biomeCoordsToCanvasPixelCoords(limit_heat_min, limit_humidity_min);
|
||||
let [limit_x_max, limit_y_max] = biomeCoordsToCanvasPixelCoords(limit_heat_max, limit_humidity_max);
|
||||
|
||||
@ -457,8 +478,8 @@ function putGrid(context) {
|
||||
// on the canvas.
|
||||
// This code will effectively trigger if the value range
|
||||
// is very high.
|
||||
let xGridLinesPerPixel = (limit_heat_max-limit_heat_min) / voronoiCanvas.width / GRID_STEP;
|
||||
let yGridLinesPerPixel = (limit_humidity_max-limit_humidity_min) / voronoiCanvas.height/ GRID_STEP;
|
||||
let xGridLinesPerPixel = (limit_heat_max-limit_heat_min) / voronoiCanvas.width / gridStep;
|
||||
let yGridLinesPerPixel = (limit_humidity_max-limit_humidity_min) / voronoiCanvas.height/ gridStep;
|
||||
let xWidth = GRID_WIDTH_LEVEL_3;
|
||||
let yWidth = GRID_WIDTH_LEVEL_3;
|
||||
if (xGridLinesPerPixel > GRID_THRESHOLD_LEVEL_0) {
|
||||
@ -484,13 +505,13 @@ function putGrid(context) {
|
||||
context.beginPath();
|
||||
let x = -xWidth*2;
|
||||
let [heat, _] = canvasPixelCoordsToBiomeCoords(x, 0);
|
||||
heat = heat - (heat % GRID_STEP);
|
||||
heat = heat - (heat % gridStep);
|
||||
steps = 0;
|
||||
while (x < voronoiCanvas.width + xWidth*2) {
|
||||
[x, _] = biomeCoordsToCanvasPixelCoords(heat, 0);
|
||||
context.moveTo(x, limit_y_min);
|
||||
context.lineTo(x, limit_y_max);
|
||||
heat += GRID_STEP;
|
||||
heat += gridStep;
|
||||
steps++;
|
||||
if (steps > 10000) {
|
||||
console.error("Over 10000 grid lines on the X axis!");
|
||||
@ -505,13 +526,13 @@ function putGrid(context) {
|
||||
context.beginPath();
|
||||
let y = -yWidth*2;
|
||||
let [_, humidity] = canvasPixelCoordsToBiomeCoords(0, y);
|
||||
humidity = humidity - (humidity % GRID_STEP);
|
||||
humidity = humidity - (humidity % gridStep);
|
||||
steps = 0;
|
||||
while (y < voronoiCanvas.height + yWidth*2) {
|
||||
[_, y] = biomeCoordsToCanvasPixelCoords(0, humidity);
|
||||
context.moveTo(limit_x_min, y);
|
||||
context.lineTo(limit_x_max, y);
|
||||
humidity -= GRID_STEP;
|
||||
humidity -= gridStep;
|
||||
steps++;
|
||||
if (steps > 10000) {
|
||||
console.error("Over 10000 grid lines on the Y axis!");
|
||||
@ -802,7 +823,7 @@ function getSelectedBiomeIDAndElement() {
|
||||
/* Draws the diagram on the voronoiCanvas.
|
||||
Will (re-)calculate the Voronoi diagram if recalculate is true;
|
||||
otherwise it may re-use a previous diagram for performance reasons. */
|
||||
function draw(recalculate) {
|
||||
function drawModern(recalculate) {
|
||||
let context = getDrawContext();
|
||||
let w = voronoiCanvas.width;
|
||||
let h = voronoiCanvas.height;
|
||||
@ -996,7 +1017,7 @@ function draw(recalculate) {
|
||||
|
||||
if (points.length > 0) {
|
||||
if (showGrid) {
|
||||
putGrid(context);
|
||||
putGrid(context, GRID_STEP);
|
||||
}
|
||||
if (showAxes) {
|
||||
putAxes(context);
|
||||
@ -1055,6 +1076,90 @@ function draw(recalculate) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function drawV6() {
|
||||
let context = getDrawContext();
|
||||
let w = voronoiCanvas.width;
|
||||
let h = voronoiCanvas.height;
|
||||
let y = getViewY();
|
||||
|
||||
clear();
|
||||
|
||||
if (!context) {
|
||||
if (!voronoiCanvas.hidden) {
|
||||
voronoiCanvas.hidden = true;
|
||||
coordinateDisplay.hidden = true;
|
||||
altitudeDisplay.hidden = true;
|
||||
rangeDisplay.hidden = true;
|
||||
configDiv.hidden = true;
|
||||
|
||||
errorMessage.innerText = "ERROR: Could not get the canvas context which means this tool won't work for you. Maybe your browser does not support the HTML canvas element properly.";
|
||||
console.error("Could not get the canvas context!");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
clear(context);
|
||||
|
||||
let showDiagramMessage = function(context, text) {
|
||||
context.textAlign = "center";
|
||||
context.fillStyle = "black";
|
||||
context.textBaseline = "middle";
|
||||
if (voronoiCanvas.width < 300) {
|
||||
context.font = "100% sans-serif";
|
||||
} else if (voronoiCanvas.width < 450) {
|
||||
context.font = "150% sans-serif";
|
||||
} else {
|
||||
context.font = "200% sans-serif";
|
||||
}
|
||||
context.fillText(text, voronoiCanvas.width/2, voronoiCanvas.height/2);
|
||||
updateAltitudeText();
|
||||
}
|
||||
|
||||
// Fail and render a special message if the value range is tiny
|
||||
if ((limit_heat_max - limit_heat_min < 0.01) || (limit_humidity_max - limit_humidity_min < 0.01)) {
|
||||
showDiagramMessage(context, "Value range is too small.");
|
||||
drawError = true;
|
||||
putResizeCorner(context);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fail and render a special message if the value range is huge
|
||||
if ((limit_heat_max - limit_heat_min > MAX_HEAT_HUMIDITY_VALUE) || (limit_humidity_max - limit_humidity_min > MAX_HEAT_HUMIDITY_VALUE)) {
|
||||
showDiagramMessage(context, "Value range is too large.");
|
||||
drawError = true;
|
||||
putResizeCorner(context);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fail and render a special message if value limit is out of permissible bounds
|
||||
if ((limit_heat_max > MAX_HEAT_HUMIDITY_VALUE) || (limit_humidity_max > MAX_HEAT_HUMIDITY_VALUE)) {
|
||||
showDiagramMessage(context, "Maximum value is too large.");
|
||||
drawError = true;
|
||||
putResizeCorner(context);
|
||||
return true;
|
||||
}
|
||||
if ((limit_heat_min < MIN_HEAT_HUMIDITY_VALUE) || (limit_humidity_min < MIN_HEAT_HUMIDITY_VALUE)) {
|
||||
showDiagramMessage(context, "Minimum value is too small.");
|
||||
drawError = true;
|
||||
putResizeCorner(context);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (showGrid) {
|
||||
putGrid(context, GRID_STEP_V6);
|
||||
}
|
||||
if (showAxes) {
|
||||
putAxes(context);
|
||||
}
|
||||
}
|
||||
|
||||
function draw(recalculate) {
|
||||
if (biomeMode === "v6") {
|
||||
drawV6(recalculate);
|
||||
} else {
|
||||
drawModern(recalculate);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clears the biome list widget and (re-adds) the list elements
|
||||
for the biomes from scratch. */
|
||||
function repopulateBiomeSelector() {
|
||||
@ -1711,22 +1816,39 @@ inputNoiseHumidityPersistence.oninput = function() {
|
||||
inputNoiseHumidityOctaves.oninput = function() {
|
||||
updateNoiseParam("humidity", "octaves", this);
|
||||
}
|
||||
|
||||
inputNoiseReset.onclick = function() {
|
||||
noises.heat.offset = NOISE_OFFSET_DEFAULT;
|
||||
noises.heat.scale = NOISE_SCALE_DEFAULT;
|
||||
noises.heat.octaves = NOISE_OCTAVES_DEFAULT;
|
||||
noises.heat.persistence = NOISE_PERSISTENCE_DEFAULT;
|
||||
noises.heat.absvalue = NOISE_ABSVALUE_DEFAULT;
|
||||
if (biomeMode === "v6") {
|
||||
noises.heat.offset = NOISE_V6_OFFSET_DEFAULT;
|
||||
noises.heat.scale = NOISE_V6_SCALE_DEFAULT;
|
||||
noises.heat.octaves = NOISE_V6_OCTAVES_DEFAULT;
|
||||
noises.heat.persistence = NOISE_V6_PERSISTENCE_DEFAULT;
|
||||
noises.heat.absvalue = NOISE_V6_ABSVALUE_DEFAULT;
|
||||
|
||||
noises.humidity.offset = NOISE_V6_OFFSET_DEFAULT;
|
||||
noises.humidity.scale = NOISE_V6_SCALE_DEFAULT;
|
||||
noises.humidity.octaves = NOISE_V6_OCTAVES_DEFAULT;
|
||||
noises.humidity.persistence = NOISE_V6_PERSISTENCE_DEFAULT;
|
||||
noises.humidity.absvalue = NOISE_V6_ABSVALUE_DEFAULT;
|
||||
} else {
|
||||
noises.heat.offset = NOISE_OFFSET_DEFAULT;
|
||||
noises.heat.scale = NOISE_SCALE_DEFAULT;
|
||||
noises.heat.octaves = NOISE_OCTAVES_DEFAULT;
|
||||
noises.heat.persistence = NOISE_PERSISTENCE_DEFAULT;
|
||||
noises.heat.absvalue = NOISE_ABSVALUE_DEFAULT;
|
||||
|
||||
noises.humidity.offset = NOISE_OFFSET_DEFAULT;
|
||||
noises.humidity.scale = NOISE_SCALE_DEFAULT;
|
||||
noises.humidity.octaves = NOISE_OCTAVES_DEFAULT;
|
||||
noises.humidity.persistence = NOISE_PERSISTENCE_DEFAULT;
|
||||
noises.humidity.absvalue = NOISE_ABSVALUE_DEFAULT;
|
||||
}
|
||||
|
||||
inputNoiseHeatOffset.value = noises.heat.offset;
|
||||
inputNoiseHeatScale.value = noises.heat.scale;
|
||||
inputNoiseHeatOctaves.value = noises.heat.octaves;
|
||||
inputNoiseHeatPersistence.value = noises.heat.persistence;
|
||||
|
||||
noises.humidity.offset = NOISE_OFFSET_DEFAULT;
|
||||
noises.humidity.scale = NOISE_SCALE_DEFAULT;
|
||||
noises.humidity.octaves = NOISE_OCTAVES_DEFAULT;
|
||||
noises.humidity.persistence = NOISE_PERSISTENCE_DEFAULT;
|
||||
noises.humidity.absvalue = NOISE_ABSVALUE_DEFAULT;
|
||||
inputNoiseHumidityOffset.value = noises.humidity.offset;
|
||||
inputNoiseHumidityScale.value = noises.humidity.scale;
|
||||
inputNoiseHumidityOctaves.value = noises.humidity.octaves;
|
||||
@ -1956,6 +2078,37 @@ inputImportSubmit.onclick = function() {
|
||||
}
|
||||
}
|
||||
|
||||
/* Mode events */
|
||||
let biomeMode = "modern";
|
||||
modernModeButton.onclick = function() {
|
||||
biomeMode = "modern";
|
||||
biomeConfigContainerOuter.hidden = false;
|
||||
importContainerOuter.hidden = false;
|
||||
exportContainerOuter.hidden = false;
|
||||
inputCheckboxPoints.disabled = false;
|
||||
noises.heat = noises.heat_modern;
|
||||
noises.humidity = noises.humidity_modern;
|
||||
noiseSettingNameHeat.innerText = "mg_biome_np_heat";
|
||||
noiseSettingNameHumidity.innerText = "mg_biome_np_humidity";
|
||||
updateAreaVars();
|
||||
updateWidgetStates();
|
||||
draw(true);
|
||||
}
|
||||
v6ModeButton.onclick = function() {
|
||||
biomeMode = "v6";
|
||||
biomeConfigContainerOuter.hidden = true;
|
||||
importContainerOuter.hidden = true;
|
||||
exportContainerOuter.hidden = true;
|
||||
inputCheckboxPoints.disabled = true;
|
||||
noises.heat = noises.heat_v6;
|
||||
noises.humidity = noises.humidity_v6;
|
||||
noiseSettingNameHeat.innerText = "mgv6_np_biome";
|
||||
noiseSettingNameHumidity.innerText = "mgv6_np_humidity";
|
||||
updateAreaVars();
|
||||
updateWidgetStates();
|
||||
draw();
|
||||
}
|
||||
|
||||
/* Events for collapsing/extending config section with the arrow thingie */
|
||||
|
||||
biomeConfigHeaderLink.onclick = function() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user