mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
feat: improve 3d view
This commit is contained in:
parent
2fd58e9d35
commit
9ad08c80c6
4 changed files with 34 additions and 54 deletions
32
index.html
32
index.html
|
|
@ -5730,11 +5730,13 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-tip="Set sun position (x, y, z) to define shadows">
|
<div data-tip="Set sun position (x, y) and color" style="margin-top: 0.4em">
|
||||||
<div>Sun position:</div>
|
<label>Sun position and color:</label>
|
||||||
<input id="options3dSunX" type="number" min="-2500" max="2500" step="100" style="width: 4.7em" />
|
<div style="display: flex; gap: 0.2em">
|
||||||
<input id="options3dSunY" type="number" min="0" max="5000" step="100" style="width: 4.7em" />
|
<input id="options3dSunX" type="number" min="-2500" max="2500" step="100" style="width: 4.7em" />
|
||||||
<input id="options3dSunZ" type="number" min="-1500" max="1500" step="100" style="width: 4.7em" />
|
<input id="options3dSunY" type="number" min="0" max="5000" step="100" style="width: 4.7em" />
|
||||||
|
<input id="options3dSunColor" type="color" style="padding: 0; height: 1.5em; border: none" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-tip="Toggle 3d labels" style="margin: 0.6em 0 0.3em -0.2em">
|
<div data-tip="Toggle 3d labels" style="margin: 0.6em 0 0.3em -0.2em">
|
||||||
|
|
@ -5752,18 +5754,9 @@
|
||||||
style="margin: 0.6em 0 0.3em -0.2em"
|
style="margin: 0.6em 0 0.3em -0.2em"
|
||||||
>
|
>
|
||||||
<input id="options3dSubdivide" class="checkbox" type="checkbox" />
|
<input id="options3dSubdivide" class="checkbox" type="checkbox" />
|
||||||
<label for="options3dSubdivide" class="checkbox-label">
|
<label for="options3dSubdivide" class="checkbox-label"
|
||||||
<i>Smooth geometry <small style="color: darkred">[slow]</small></i>
|
><i>Smooth geometry <small style="color: darkred">[slow]</small></i></label
|
||||||
</label>
|
>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div data-tip="Set Sun Color" id="options3dSunColorSection">
|
|
||||||
<span>Sun Color:</span
|
|
||||||
><input
|
|
||||||
id="options3dSunColor"
|
|
||||||
type="color"
|
|
||||||
style="width: 4.4em; height: 1em; border: 0; padding: 0; margin: 0 0.2em"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-tip="Set sky and water color" id="options3dColorSection" style="display: none">
|
<div data-tip="Set sky and water color" id="options3dColorSection" style="display: none">
|
||||||
|
|
@ -5796,6 +5789,7 @@
|
||||||
<option value="1">1x</option>
|
<option value="1">1x</option>
|
||||||
<option value="2">2x</option>
|
<option value="2">2x</option>
|
||||||
<option value="4">4x</option>
|
<option value="4">4x</option>
|
||||||
|
<option value="8">8x</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -7989,7 +7983,7 @@
|
||||||
<script src="modules/ui/stylePresets.js?v=1.93.07"></script>
|
<script src="modules/ui/stylePresets.js?v=1.93.07"></script>
|
||||||
|
|
||||||
<script src="modules/ui/general.js?v=1.93.04"></script>
|
<script src="modules/ui/general.js?v=1.93.04"></script>
|
||||||
<script src="modules/ui/options.js?v=1.93.08"></script>
|
<script src="modules/ui/options.js?v=1.93.11"></script>
|
||||||
<script src="main.js?v=1.93.02"></script>
|
<script src="main.js?v=1.93.02"></script>
|
||||||
|
|
||||||
<script defer src="modules/relief-icons.js"></script>
|
<script defer src="modules/relief-icons.js"></script>
|
||||||
|
|
@ -8025,7 +8019,7 @@
|
||||||
<script defer src="modules/ui/battle-screen.js"></script>
|
<script defer src="modules/ui/battle-screen.js"></script>
|
||||||
<script defer src="modules/ui/emblems-editor.js?v=1.91.00"></script>
|
<script defer src="modules/ui/emblems-editor.js?v=1.91.00"></script>
|
||||||
<script defer src="modules/ui/markers-editor.js"></script>
|
<script defer src="modules/ui/markers-editor.js"></script>
|
||||||
<script defer src="modules/ui/3d.js?v=1.89.36"></script>
|
<script defer src="modules/ui/3d.js?v=1.93.11"></script>
|
||||||
<script defer src="modules/ui/submap.js?v=1.92.00"></script>
|
<script defer src="modules/ui/submap.js?v=1.92.00"></script>
|
||||||
<script defer src="modules/ui/hotkeys.js?v=1.93.00"></script>
|
<script defer src="modules/ui/hotkeys.js?v=1.93.00"></script>
|
||||||
<script defer src="modules/coa-renderer.js?v=1.91.00"></script>
|
<script defer src="modules/coa-renderer.js?v=1.91.00"></script>
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,19 @@
|
||||||
window.ThreeD = (function () {
|
window.ThreeD = (function () {
|
||||||
const options = {
|
const options = {
|
||||||
scale: 50,
|
scale: 50,
|
||||||
lightness: 0.7,
|
lightness: 0.6,
|
||||||
shadow: 0.5,
|
shadow: 0.5,
|
||||||
sun: {x: 100, y: 600, z: 1000},
|
sun: {x: 100, y: 800, z: 1000},
|
||||||
rotateMesh: 0,
|
rotateMesh: 0,
|
||||||
rotateGlobe: 0.5,
|
rotateGlobe: 0.5,
|
||||||
skyColor: "#9ecef5",
|
skyColor: "#9ecef5",
|
||||||
waterColor: "#466eab",
|
waterColor: "#466eab",
|
||||||
|
sunColor: "#cccccc",
|
||||||
extendedWater: 0,
|
extendedWater: 0,
|
||||||
labels3d: 0,
|
labels3d: 0,
|
||||||
wireframe: 0,
|
wireframe: 0,
|
||||||
resolution: 2,
|
resolution: 2,
|
||||||
resolutionScale: 2048,
|
resolutionScale: 2048,
|
||||||
sunColor: "#cccccc",
|
|
||||||
subdivide: 0
|
subdivide: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -202,16 +202,16 @@ window.ThreeD = (function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveOBJ = async function () {
|
const saveOBJ = async function () {
|
||||||
downloadFile(await getOBJ(), getFileName() + ".obj", "text/plain;charset=UTF-8");
|
const objexporter = await OBJExporter();
|
||||||
|
const obj = await objexporter.parse(mesh);
|
||||||
|
|
||||||
|
downloadFile(obj, getFileName() + ".obj", "text/plain;charset=UTF-8");
|
||||||
};
|
};
|
||||||
|
|
||||||
// start 3d view and heightmap edit preview
|
// start 3d view and heightmap edit preview
|
||||||
async function newMesh(canvas) {
|
async function newMesh(canvas) {
|
||||||
const loaded = await loadTHREE();
|
const loaded = await loadTHREE();
|
||||||
if (!loaded) {
|
if (!loaded) return tip("Cannot load 3d library", false, "error", 4000);
|
||||||
tip("Cannot load 3d library", false, "error", 4000);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
scene = new THREE.Scene();
|
scene = new THREE.Scene();
|
||||||
|
|
||||||
|
|
@ -221,17 +221,16 @@ window.ThreeD = (function () {
|
||||||
spotLight = new THREE.SpotLight(options.sunColor, 0.8, 2000, 0.8, 0, 0);
|
spotLight = new THREE.SpotLight(options.sunColor, 0.8, 2000, 0.8, 0, 0);
|
||||||
spotLight.position.set(options.sun.x, options.sun.y, options.sun.z);
|
spotLight.position.set(options.sun.x, options.sun.y, options.sun.z);
|
||||||
spotLight.castShadow = true;
|
spotLight.castShadow = true;
|
||||||
//maybe add a option for this. But changing the option will require to reinstance the spotLight.
|
|
||||||
spotLight.shadow.mapSize.width = 2048;
|
spotLight.shadow.mapSize.width = 2048;
|
||||||
spotLight.shadow.mapSize.height = 2048;
|
spotLight.shadow.mapSize.height = 2048;
|
||||||
scene.add(spotLight);
|
scene.add(spotLight);
|
||||||
//scene.add(new THREE.SpotLightHelper(spotLight));
|
// scene.add(new THREE.SpotLightHelper(spotLight));
|
||||||
|
|
||||||
// Renderer
|
// Renderer
|
||||||
Renderer = new THREE.WebGLRenderer({canvas, antialias: true, preserveDrawingBuffer: true});
|
Renderer = new THREE.WebGLRenderer({canvas, antialias: true, preserveDrawingBuffer: true});
|
||||||
Renderer.setSize(canvas.width, canvas.height);
|
Renderer.setSize(canvas.width, canvas.height);
|
||||||
Renderer.shadowMap.enabled = true;
|
Renderer.shadowMap.enabled = true;
|
||||||
// Renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
Renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
||||||
if (options.extendedWater) extendWater(graphWidth, graphHeight);
|
if (options.extendedWater) extendWater(graphWidth, graphHeight);
|
||||||
createMesh(graphWidth, graphHeight, grid.cellsX, grid.cellsY);
|
createMesh(graphWidth, graphHeight, grid.cellsX, grid.cellsY);
|
||||||
|
|
||||||
|
|
@ -241,8 +240,11 @@ window.ThreeD = (function () {
|
||||||
|
|
||||||
// controls
|
// controls
|
||||||
controls = await OrbitControls(camera, canvas);
|
controls = await OrbitControls(camera, canvas);
|
||||||
controls.enableKeys = false;
|
controls.listenToKeyEvents(window);
|
||||||
controls.minDistance = 10;
|
controls.zoomSpeed = 0.25;
|
||||||
|
|
||||||
|
controls.panSpeed = 0.5;
|
||||||
|
controls.minDistance = 100;
|
||||||
controls.maxDistance = 1000;
|
controls.maxDistance = 1000;
|
||||||
controls.maxPolarAngle = Math.PI / 2;
|
controls.maxPolarAngle = Math.PI / 2;
|
||||||
controls.autoRotate = Boolean(options.rotateMesh);
|
controls.autoRotate = Boolean(options.rotateMesh);
|
||||||
|
|
@ -250,7 +252,6 @@ window.ThreeD = (function () {
|
||||||
if (controls.autoRotate) animate();
|
if (controls.autoRotate) animate();
|
||||||
|
|
||||||
controls.addEventListener("change", render);
|
controls.addEventListener("change", render);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -440,12 +441,11 @@ window.ThreeD = (function () {
|
||||||
|
|
||||||
async function createMeshTextureUrl() {
|
async function createMeshTextureUrl() {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
const mapOptions = {
|
const url = await getMapURL("mesh", {
|
||||||
noLabels: options.labels3d,
|
noLabels: options.labels3d,
|
||||||
noWater: options.extendedWater,
|
noWater: options.extendedWater,
|
||||||
fullMap: true
|
fullMap: true
|
||||||
};
|
});
|
||||||
const url = await getMapURL("mesh", mapOptions);
|
|
||||||
const canvas = document.createElement("canvas");
|
const canvas = document.createElement("canvas");
|
||||||
const ctx = canvas.getContext("2d");
|
const ctx = canvas.getContext("2d");
|
||||||
canvas.width = options.resolutionScale;
|
canvas.width = options.resolutionScale;
|
||||||
|
|
@ -541,11 +541,6 @@ window.ThreeD = (function () {
|
||||||
|
|
||||||
async function update3dTexture() {
|
async function update3dTexture() {
|
||||||
if (texture) texture.dispose();
|
if (texture) texture.dispose();
|
||||||
const mapOptions = {
|
|
||||||
noLabels: options.labels3d,
|
|
||||||
noWater: options.extendedWater,
|
|
||||||
fullMap: true
|
|
||||||
};
|
|
||||||
const url = await createMeshTextureUrl();
|
const url = await createMeshTextureUrl();
|
||||||
window.setTimeout(() => window.URL.revokeObjectURL(url), 4000);
|
window.setTimeout(() => window.URL.revokeObjectURL(url), 4000);
|
||||||
texture = new THREE.TextureLoader().load(url, render);
|
texture = new THREE.TextureLoader().load(url, render);
|
||||||
|
|
@ -580,7 +575,7 @@ window.ThreeD = (function () {
|
||||||
|
|
||||||
// controls
|
// controls
|
||||||
controls = await OrbitControls(camera, Renderer.domElement);
|
controls = await OrbitControls(camera, Renderer.domElement);
|
||||||
controls.enableKeys = false;
|
controls.zoomSpeed = 0.25;
|
||||||
controls.minDistance = 1.8;
|
controls.minDistance = 1.8;
|
||||||
controls.maxDistance = 10;
|
controls.maxDistance = 10;
|
||||||
controls.autoRotate = Boolean(options.rotateGlobe);
|
controls.autoRotate = Boolean(options.rotateGlobe);
|
||||||
|
|
@ -631,12 +626,6 @@ window.ThreeD = (function () {
|
||||||
img2.src = await getMapURL("mesh", {globe: true, fullMap: true});
|
img2.src = await getMapURL("mesh", {globe: true, fullMap: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getOBJ() {
|
|
||||||
const objexporter = await OBJExporter();
|
|
||||||
const data = await objexporter.parse(mesh);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addGlobe3dMesh() {
|
function addGlobe3dMesh() {
|
||||||
geometry = new THREE.SphereBufferGeometry(1, 64, 64);
|
geometry = new THREE.SphereBufferGeometry(1, 64, 64);
|
||||||
mesh = new THREE.Mesh(geometry, material);
|
mesh = new THREE.Mesh(geometry, material);
|
||||||
|
|
|
||||||
|
|
@ -1002,7 +1002,7 @@ async function enter3dView(type) {
|
||||||
canvas.style.display = "block";
|
canvas.style.display = "block";
|
||||||
canvas.onmouseenter = () => {
|
canvas.onmouseenter = () => {
|
||||||
const help =
|
const help =
|
||||||
"Left mouse to change angle, middle mouse / mousewheel to zoom, right mouse to pan. <b>O</b> to toggle options";
|
"Left mouse to change angle, middle mouse. Mousewheel to zoom. Right mouse or hold Shift to pan. <b>O</b> to toggle options";
|
||||||
+canvas.dataset.hovered > 2 ? tip("") : tip(help);
|
+canvas.dataset.hovered > 2 ? tip("") : tip(help);
|
||||||
canvas.dataset.hovered = (+canvas.dataset.hovered | 0) + 1;
|
canvas.dataset.hovered = (+canvas.dataset.hovered | 0) + 1;
|
||||||
};
|
};
|
||||||
|
|
@ -1055,7 +1055,6 @@ function toggle3dOptions() {
|
||||||
document.getElementById("options3dLightnessNumber").addEventListener("change", changeLightness);
|
document.getElementById("options3dLightnessNumber").addEventListener("change", changeLightness);
|
||||||
document.getElementById("options3dSunX").addEventListener("change", changeSunPosition);
|
document.getElementById("options3dSunX").addEventListener("change", changeSunPosition);
|
||||||
document.getElementById("options3dSunY").addEventListener("change", changeSunPosition);
|
document.getElementById("options3dSunY").addEventListener("change", changeSunPosition);
|
||||||
document.getElementById("options3dSunZ").addEventListener("change", changeSunPosition);
|
|
||||||
document.getElementById("options3dMeshSkinResolution").addEventListener("change", changeResolutionScale);
|
document.getElementById("options3dMeshSkinResolution").addEventListener("change", changeResolutionScale);
|
||||||
document.getElementById("options3dMeshRotationRange").addEventListener("input", changeRotation);
|
document.getElementById("options3dMeshRotationRange").addEventListener("input", changeRotation);
|
||||||
document.getElementById("options3dMeshRotationNumber").addEventListener("change", changeRotation);
|
document.getElementById("options3dMeshRotationNumber").addEventListener("change", changeRotation);
|
||||||
|
|
@ -1079,7 +1078,6 @@ function toggle3dOptions() {
|
||||||
options3dLightnessRange.value = options3dLightnessNumber.value = ThreeD.options.lightness * 100;
|
options3dLightnessRange.value = options3dLightnessNumber.value = ThreeD.options.lightness * 100;
|
||||||
options3dSunX.value = ThreeD.options.sun.x;
|
options3dSunX.value = ThreeD.options.sun.x;
|
||||||
options3dSunY.value = ThreeD.options.sun.y;
|
options3dSunY.value = ThreeD.options.sun.y;
|
||||||
options3dSunZ.value = ThreeD.options.sun.z;
|
|
||||||
options3dMeshRotationRange.value = options3dMeshRotationNumber.value = ThreeD.options.rotateMesh;
|
options3dMeshRotationRange.value = options3dMeshRotationNumber.value = ThreeD.options.rotateMesh;
|
||||||
options3dMeshSkinResolution.value = ThreeD.options.resolutionScale;
|
options3dMeshSkinResolution.value = ThreeD.options.resolutionScale;
|
||||||
options3dGlobeRotationRange.value = options3dGlobeRotationNumber.value = ThreeD.options.rotateGlobe;
|
options3dGlobeRotationRange.value = options3dGlobeRotationNumber.value = ThreeD.options.rotateGlobe;
|
||||||
|
|
@ -1115,8 +1113,7 @@ function toggle3dOptions() {
|
||||||
function changeSunPosition() {
|
function changeSunPosition() {
|
||||||
const x = +options3dSunX.value;
|
const x = +options3dSunX.value;
|
||||||
const y = +options3dSunY.value;
|
const y = +options3dSunY.value;
|
||||||
const z = +options3dSunZ.value;
|
ThreeD.setSun(x, y);
|
||||||
ThreeD.setSun(x, y, z);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeRotation() {
|
function changeRotation() {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// version and caching control
|
// version and caching control
|
||||||
const version = "1.93.10"; // generator version, update each time
|
const version = "1.93.11"; // generator version, update each time
|
||||||
|
|
||||||
{
|
{
|
||||||
document.title += " v" + version;
|
document.title += " v" + version;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue