3d view system upgrade.

This commit is contained in:
Efruz Yıldırır 2023-07-13 22:44:27 +03:00
parent 3a5e7e78ed
commit 96ddef834f
4 changed files with 159 additions and 21 deletions

View file

@ -5648,6 +5648,24 @@
<input id="options3dLightnessNumber" type="number" min="0" max="500" style="width: 4em" /> <input id="options3dLightnessNumber" type="number" min="0" max="500" style="width: 4em" />
</div> </div>
<!-- <div data-tip="Set map skin resolution scale">
<div>Skin resolution scale:</div>
<input id="options3dResolutionScaleRange" type="range" min="0" max="100" />
<input id="options3dResolutionScaleNumber" type="number" min="0" max="1000" style="width: 4em" />
</div> -->
<div data-tip="Set mesh texture resolution">
<div>Texture resolution:</div>
<select id="options3dMeshSkinResolution" style="width: 10em">
<option value="1">512x512px</option>
<option value="2">1024x1024px</option>
<option value="3">2048x2048px</option>
<option value="4">4096x4096px</option>
<option value="5">8192x8192px</option>
</select>
</div>
<div data-tip="Set sun position (x, y, z) to define shadows"> <div data-tip="Set sun position (x, y, z) to define shadows">
<div>Sun position:</div> <div>Sun position:</div>
<input id="options3dSunX" type="number" min="-2500" max="2500" step="100" style="width: 4.7em" /> <input id="options3dSunX" type="number" min="-2500" max="2500" step="100" style="width: 4.7em" />
@ -5655,6 +5673,15 @@
<input id="options3dSunZ" type="number" min="-1500" max="1500" step="100" style="width: 4.7em" /> <input id="options3dSunZ" type="number" min="-1500" max="1500" step="100" style="width: 4.7em" />
</div> </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 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">
<input id="options3dMeshLabels3d" class="checkbox" type="checkbox" /> <input id="options3dMeshLabels3d" class="checkbox" type="checkbox" />
<label for="options3dMeshLabels3d" class="checkbox-label"><i>Show 3D labels</i></label> <label for="options3dMeshLabels3d" class="checkbox-label"><i>Show 3D labels</i></label>
@ -5665,6 +5692,11 @@
<label for="options3dMeshSkyMode" class="checkbox-label"><i>Show sky and extend water</i></label> <label for="options3dMeshSkyMode" class="checkbox-label"><i>Show sky and extend water</i></label>
</div> </div>
<div data-tip="Toggle wireframe mode, generally used for debugging." style="margin: 0.6em 0 0.3em -0.2em">
<input id="options3dMeshWireframeMode" class="checkbox" type="checkbox" />
<label for="options3dMeshWireframeMode" class="checkbox-label"><i>Show mesh material as wireframe</i></label>
</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">
<span>Sky:</span <span>Sky:</span
><input ><input
@ -7881,7 +7913,7 @@
<script src="modules/ui/stylePresets.js?v=1.89.11"></script> <script src="modules/ui/stylePresets.js?v=1.89.11"></script>
<script src="modules/ui/general.js?v=1.87.03"></script> <script src="modules/ui/general.js?v=1.87.03"></script>
<script src="modules/ui/options.js?v=1.89.19"></script> <script src="modules/ui/options.js?v=1.89.20"></script>
<script src="main.js?v=1.89.32"></script> <script src="main.js?v=1.89.32"></script>
<script defer src="modules/relief-icons.js"></script> <script defer src="modules/relief-icons.js"></script>
@ -7927,7 +7959,7 @@
<script defer src="modules/io/save.js?v=1.89.29"></script> <script defer src="modules/io/save.js?v=1.89.29"></script>
<script defer src="modules/io/load.js?v=1.89.30"></script> <script defer src="modules/io/load.js?v=1.89.30"></script>
<script defer src="modules/io/cloud.js"></script> <script defer src="modules/io/cloud.js"></script>
<script defer src="modules/io/export.js?v=1.89.17"></script> <script defer src="modules/io/export.js?v=1.89.18"></script>
<script defer src="modules/io/formats.js"></script> <script defer src="modules/io/formats.js"></script>
<!-- Web Components --> <!-- Web Components -->

View file

@ -11,7 +11,7 @@ async function saveSVG() {
link.click(); link.click();
tip( tip(
`${link.download} is saved. Open "Downloads" screen (crtl + J) to check. You can set image scale in options`, `${link.download} is saved. Open "Downloads" screen (ctrl + J) to check. You can set image scale in options`,
true, true,
"success", "success",
5000 5000
@ -157,7 +157,8 @@ async function getMapURL(type, options = {}) {
noWater = false, noWater = false,
noScaleBar = false, noScaleBar = false,
noIce = false, noIce = false,
fullMap = false fullMap = false,
for3D = false
} = options; } = options;
if (fullMap) drawScaleBar(1); if (fullMap) drawScaleBar(1);

View file

@ -5,14 +5,17 @@ window.ThreeD = (function () {
scale: 50, scale: 50,
lightness: 0.7, lightness: 0.7,
shadow: 0.5, shadow: 0.5,
sun: {x: 100, y: 600, z: 1000}, sun: {x: 300, y: 1500, z: 800},
rotateMesh: 0, rotateMesh: 0,
rotateGlobe: 0.5, rotateGlobe: 0.5,
skyColor: "#9ecef5", skyColor: "#9ecef5",
waterColor: "#466eab", waterColor: "#466eab",
extendedWater: 0, extendedWater: 0,
labels3d: 0, labels3d: 0,
resolution: 2 wireframe: 0,
resolution: 2,
resolutionScale: 3,
sunColor: "#ffffff"
}; };
// set variables // set variables
@ -100,6 +103,18 @@ window.ThreeD = (function () {
redraw(); redraw();
}; };
const setSunColor = function(color){
options.sunColor = color;
spotLight.color = new THREE.Color(color);
render();
}
const setResolutionScale = function (scale) {
options.resolutionScale = scale;
console.log("New res:",scale);
redraw();
};
const setLightness = function (intensity) { const setLightness = function (intensity) {
options.lightness = intensity; options.lightness = intensity;
ambientLight.intensity = intensity; ambientLight.intensity = intensity;
@ -148,6 +163,11 @@ window.ThreeD = (function () {
} }
}; };
const toggleWireframe = function () {
options.wireframe = !options.wireframe;
redraw();
};
const setColors = function (sky, water) { const setColors = function (sky, water) {
options.skyColor = sky; options.skyColor = sky;
scene.background = scene.fog.color = new THREE.Color(sky); scene.background = scene.fog.color = new THREE.Color(sky);
@ -189,16 +209,20 @@ window.ThreeD = (function () {
// light // light
ambientLight = new THREE.AmbientLight(0xcccccc, options.lightness); ambientLight = new THREE.AmbientLight(0xcccccc, options.lightness);
scene.add(ambientLight); scene.add(ambientLight);
spotLight = new THREE.SpotLight(0xcccccc, 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.height = 2048;
scene.add(spotLight); scene.add(spotLight);
//scene.add(new THREE.SpotLightHelper(spotLight)); //scene.add(new THREE.SpotLightHelper(spotLight));
// Rendered // 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;
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);
@ -223,7 +247,7 @@ window.ThreeD = (function () {
function textureToSprite(texture, width, height) { function textureToSprite(texture, width, height) {
const map = new THREE.TextureLoader().load(texture); const map = new THREE.TextureLoader().load(texture);
map.anisotropy = Renderer.getMaxAnisotropy(); map.anisotropy = Renderer.capabilities.getMaxAnisotropy();
const material = new THREE.SpriteMaterial({map}); const material = new THREE.SpriteMaterial({map});
const sprite = new THREE.Sprite(material); const sprite = new THREE.Sprite(material);
@ -295,8 +319,13 @@ window.ThreeD = (function () {
line: 5 - towns.attr("data-size") / 2 line: 5 - towns.attr("data-size") / 2
}; };
//Look for a custom model for city and town geometry. If not found use these.
//Maybe serialize the models to the .map file.
const city_icon_material = new THREE.MeshPhongMaterial({color: cityOptions.iconColor}); const city_icon_material = new THREE.MeshPhongMaterial({color: cityOptions.iconColor});
city_icon_material.wireframe = options.wireframe;
const town_icon_material = new THREE.MeshPhongMaterial({color: townOptions.iconColor}); const town_icon_material = new THREE.MeshPhongMaterial({color: townOptions.iconColor});
town_icon_material.wireframe = options.wireframe;
const city_icon_geometry = new THREE.CylinderGeometry(cityOptions.iconSize * 2, cityOptions.iconSize * 2, cityOptions.iconSize, 16, 1); const city_icon_geometry = new THREE.CylinderGeometry(cityOptions.iconSize * 2, cityOptions.iconSize * 2, cityOptions.iconSize, 16, 1);
const town_icon_geometry = new THREE.CylinderGeometry(townOptions.iconSize * 2, townOptions.iconSize * 2, townOptions.iconSize, 16, 1); const town_icon_geometry = new THREE.CylinderGeometry(townOptions.iconSize * 2, townOptions.iconSize * 2, townOptions.iconSize, 16, 1);
const line_material = new THREE.LineBasicMaterial({color: cityOptions.iconColor}); const line_material = new THREE.LineBasicMaterial({color: cityOptions.iconColor});
@ -387,24 +416,76 @@ window.ThreeD = (function () {
lines = []; lines = [];
} }
// create a mesh from pixel data async function createMeshTextureUrl(){
async function createMesh(width, height, segmentsX, segmentsY) { return new Promise(async (resolve, reject)=>{
const mapOptions = { const mapOptions = {
noLabels: options.labels3d, noLabels: options.labels3d,
noWater: options.extendedWater, noWater: options.extendedWater,
fullMap: true fullMap: true,
for3D: true
}; };
const url = await getMapURL("mesh", mapOptions); let sizeOfSkin = 512;
window.setTimeout(() => window.URL.revokeObjectURL(url), 5000); switch(options.resolutionScale){
case 1:
sizeOfSkin = 512;
break;
case 2:
sizeOfSkin = 1024;
break;
case 3:
sizeOfSkin = 2048;
break;
case 4:
sizeOfSkin = 4096;
break;
case 5:
sizeOfSkin = 8192;
break;
}
const url = await getMapURL("mesh",mapOptions);
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = sizeOfSkin;
canvas.height = sizeOfSkin;
const img = new Image();
img.src = url;
img.onload = function(){
ctx.drawImage(img,0,0,canvas.width,canvas.height);
canvas.toBlob((blob)=>{
const blobObj = window.URL.createObjectURL(blob)
window.setTimeout(()=>{
canvas.remove();
window.URL.revokeObjectURL(blobObj);
}, 100);
resolve(blobObj);
})
}
})
}
// create a mesh from pixel data
async function createMesh(width, height, segmentsX, segmentsY) {
if (texture) texture.dispose(); if (texture) texture.dispose();
texture = new THREE.TextureLoader().load(url, render); if(!options.wireframe){
//Try loading skin texture.
texture = new THREE.TextureLoader().load(await createMeshTextureUrl(), render);
texture.needsUpdate = true; texture.needsUpdate = true;
}
if (material) material.dispose(); if (material) material.dispose();
if(options.wireframe){
material = new THREE.MeshLambertMaterial(); material = new THREE.MeshLambertMaterial();
material.wireframe = true;
}else{
material = new THREE.MeshStandardMaterial();
material.map = texture; material.map = texture;
material.roughness = 0.9;
material.transparent = true; material.transparent = true;
}
if (geometry) geometry.dispose(); if (geometry) geometry.dispose();
geometry = new THREE.PlaneGeometry(width, height, segmentsX - 1, segmentsY - 1); geometry = new THREE.PlaneGeometry(width, height, segmentsX - 1, segmentsY - 1);
@ -449,7 +530,7 @@ window.ThreeD = (function () {
noWater: options.extendedWater, noWater: options.extendedWater,
fullMap: true fullMap: true
}; };
const url = await getMapURL("mesh", mapOptions); 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);
material.map = texture; material.map = texture;
@ -609,11 +690,14 @@ window.ThreeD = (function () {
update, update,
stop, stop,
options, options,
setSunColor,
setScale, setScale,
setResolutionScale,
setLightness, setLightness,
setSun, setSun,
setRotation, setRotation,
toggleLabels, toggleLabels,
toggleWireframe,
toggleSky, toggleSky,
setResolution, setResolution,
setColors, setColors,

View file

@ -1060,6 +1060,7 @@ function toggle3dOptions() {
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("options3dSunZ").addEventListener("change", changeSunPosition);
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);
document.getElementById("options3dGlobeRotationRange").addEventListener("input", changeRotation); document.getElementById("options3dGlobeRotationRange").addEventListener("input", changeRotation);
@ -1069,6 +1070,9 @@ function toggle3dOptions() {
document.getElementById("options3dMeshSky").addEventListener("input", changeColors); document.getElementById("options3dMeshSky").addEventListener("input", changeColors);
document.getElementById("options3dMeshWater").addEventListener("input", changeColors); document.getElementById("options3dMeshWater").addEventListener("input", changeColors);
document.getElementById("options3dGlobeResolution").addEventListener("change", changeResolution); document.getElementById("options3dGlobeResolution").addEventListener("change", changeResolution);
document.getElementById("options3dMeshWireframeMode").addEventListener("change",toggleWireframe3d);
document.getElementById("options3dSunColor").addEventListener("input", changeSunColor);
function updateValues() { function updateValues() {
const globe = document.getElementById("canvas3d").dataset.type === "viewGlobe"; const globe = document.getElementById("canvas3d").dataset.type === "viewGlobe";
@ -1081,6 +1085,7 @@ function toggle3dOptions() {
options3dSunY.value = ThreeD.options.sun.y; options3dSunY.value = ThreeD.options.sun.y;
options3dSunZ.value = ThreeD.options.sun.z; 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;
options3dGlobeRotationRange.value = options3dGlobeRotationNumber.value = ThreeD.options.rotateGlobe; options3dGlobeRotationRange.value = options3dGlobeRotationNumber.value = ThreeD.options.rotateGlobe;
options3dMeshLabels3d.value = ThreeD.options.labels3d; options3dMeshLabels3d.value = ThreeD.options.labels3d;
options3dMeshSkyMode.value = ThreeD.options.extendedWater; options3dMeshSkyMode.value = ThreeD.options.extendedWater;
@ -1088,18 +1093,30 @@ function toggle3dOptions() {
options3dMeshSky.value = ThreeD.options.skyColor; options3dMeshSky.value = ThreeD.options.skyColor;
options3dMeshWater.value = ThreeD.options.waterColor; options3dMeshWater.value = ThreeD.options.waterColor;
options3dGlobeResolution.value = ThreeD.options.resolution; options3dGlobeResolution.value = ThreeD.options.resolution;
options3dSunColor.value = ThreeD.options.sunColor;
console.log("options3dSunColor.value =",ThreeD.options.sunColor);
} }
function changeHeightScale() { function changeHeightScale() {
options3dScaleRange.value = options3dScaleNumber.value = this.value; options3dScaleRange.value = options3dScaleNumber.value = this.value;
console.log(this);
ThreeD.setScale(+this.value); ThreeD.setScale(+this.value);
} }
function changeResolutionScale() {
options3dMeshSkinResolution.value = this.value;
ThreeD.setResolutionScale(+this.value);
}
function changeLightness() { function changeLightness() {
options3dLightnessRange.value = options3dLightnessNumber.value = this.value; options3dLightnessRange.value = options3dLightnessNumber.value = this.value;
ThreeD.setLightness(this.value / 100); ThreeD.setLightness(this.value / 100);
} }
function changeSunColor(){
ThreeD.setSunColor(options3dSunColor.value);
}
function changeSunPosition() { function changeSunPosition() {
const x = +options3dSunX.value; const x = +options3dSunX.value;
const y = +options3dSunY.value; const y = +options3dSunY.value;
@ -1117,6 +1134,10 @@ function toggle3dOptions() {
ThreeD.toggleLabels(); ThreeD.toggleLabels();
} }
function toggleWireframe3d() {
ThreeD.toggleWireframe();
}
function toggleSkyMode() { function toggleSkyMode() {
const hide = ThreeD.options.extendedWater; const hide = ThreeD.options.extendedWater;
options3dColorSection.style.display = hide ? "none" : "block"; options3dColorSection.style.display = hide ? "none" : "block";