All fonts working properly + Big memory optimization + Minor fixes

This commit is contained in:
Rayzeq 2021-07-02 10:59:09 +02:00
parent 143e1dfbd7
commit bd4deaac7e

View file

@ -11,7 +11,7 @@ const options = {scale: 50, lightness: .7, shadow: .5, sun: {x: 100, y: 600, z:
// set variables // set variables
let Renderer, scene, camera, controls, animationFrame, material, texture, let Renderer, scene, camera, controls, animationFrame, material, texture,
geometry, mesh, ambientLight, spotLight, waterPlane, waterMaterial, waterMesh, geometry, mesh, ambientLight, spotLight, waterPlane, waterMaterial, waterMesh,
objexporter; objexporter, square_geometry, texture_loader;
const drawSVG = document.createElementNS("http://www.w3.org/2000/svg", "svg"); const drawSVG = document.createElementNS("http://www.w3.org/2000/svg", "svg");
document.body.appendChild(drawSVG); document.body.appendChild(drawSVG);
let textMeshs = [], iconMeshs = []; let textMeshs = [], iconMeshs = [];
@ -116,14 +116,14 @@ const toggleSky = function() {
} }
const toggleLabels = function() { const toggleLabels = function() {
options.labels3d = !options.labels3d;
if (options.labels3d) { if (options.labels3d) {
createLabels().then(() => update());
} else {
deleteLabels(); deleteLabels();
update(); update();
} else {
createLabels().then(() => update());
} }
options.labels3d = !options.labels3d;
} }
const setColors = function(sky, water) { const setColors = function(sky, water) {
@ -207,14 +207,14 @@ function svg2mesh(svg, sx=1, sy=1) {
svg.setAttribute("width", bbox.width); svg.setAttribute("width", bbox.width);
svg.setAttribute("height", bbox.height); svg.setAttribute("height", bbox.height);
const texture = new THREE.TextureLoader().load(svg2base64(svg)); const texture = new texture_loader.load(svg2base64(svg));
texture.minFilter = THREE.LinearFilter; // remove `texture has been resized` warning texture.minFilter = THREE.LinearFilter; // remove `texture has been resized` warning
const material = new THREE.MeshBasicMaterial({map: texture, side: THREE.DoubleSide, depthWrite: false}); const material = new THREE.MeshBasicMaterial({map: texture, side: THREE.DoubleSide, depthWrite: false});
material.transparent = true; material.transparent = true;
const mesh = new THREE.Mesh( const mesh = new THREE.Mesh(
new THREE.PlaneGeometry(1, 1), square_geometry,
material material
); );
mesh.scale.x = bbox.width * (sx / 100); mesh.scale.x = bbox.width * (sx / 100);
@ -227,7 +227,7 @@ function svg2mesh(svg, sx=1, sy=1) {
async function createStateText(font, size, color, label) { async function createStateText(font, size, color, label) {
drawSVG.innerHTML = "<defs></defs>"; drawSVG.innerHTML = "<defs></defs>";
drawSVG.appendChild(label.cloneNode(true)); drawSVG.appendChild(label.cloneNode(true));
if (fontCache[font] == undefined) {fontCache[font] = await GFontToDataURI(`https://fonts.googleapis.com/css?family=${font}`)} if (fontCache[font] == undefined) {fontCache[font] = (await GFontToDataURI(`https://fonts.googleapis.com/css?family=${font}`)).join('\n');}
drawSVG.children[0].innerHTML = `<style type="text/css">${fontCache[font]}</style>`; drawSVG.children[0].innerHTML = `<style type="text/css">${fontCache[font]}</style>`;
drawSVG.children[0].appendChild(svg.select(label.childNodes[0].href.baseVal).node().cloneNode(true)); // href of path in defs drawSVG.children[0].appendChild(svg.select(label.childNodes[0].href.baseVal).node().cloneNode(true)); // href of path in defs
drawSVG.children[1].setAttribute("transform", `scale(${5} ${5})`) drawSVG.children[1].setAttribute("transform", `scale(${5} ${5})`)
@ -241,11 +241,11 @@ async function createStateText(font, size, color, label) {
return mesh; return mesh;
} }
async function createBurgText(text, font, size, color) { async function createBurgText(text, font, size, color, quality=1) { // for quality: lower value mean higher quality
if (fontCache[font] == undefined) {fontCache[font] = await GFontToDataURI(`https://fonts.googleapis.com/css?family=${font}`)} if (fontCache[font] == undefined) {fontCache[font] = (await GFontToDataURI(`https://fonts.googleapis.com/css?family=${font}`)).join("\n");}
drawSVG.innerHTML = `<text font-family="${font}" font-size="${size * (20 / 2)}" fill="${color}">${text}</text> drawSVG.innerHTML = `<text font-family="${font}" font-size="${size * (20 / quality)}" fill="${color}">${text}</text>
<defs><style type="text/css">${fontCache[font]}</style></defs>`; <defs><style type="text/css">${fontCache[font]}</style></defs>`;
return svg2mesh(drawSVG, 7*2, 7*2); return svg2mesh(drawSVG, 7*quality, 7*quality);
} }
function get3dCoords(base_x, base_y) { function get3dCoords(base_x, base_y) {
@ -256,12 +256,19 @@ function get3dCoords(base_x, base_y) {
} }
async function createLabels() { async function createLabels() {
square_geometry = new THREE.PlaneGeometry(1, 1);
texture_loader = new THREE.TextureLoader();
// Burg labels // Burg labels
const cities = svg.select("#viewbox #labels #burgLabels #cities"); const cities = svg.select("#viewbox #labels #burgLabels #cities");
const towns = svg.select('#viewbox #labels #burgLabels #towns'); const towns = svg.select('#viewbox #labels #burgLabels #towns');
const cities_icons = svg.select('#viewbox #icons #burgIcons #cities'); const cities_icons = svg.select('#viewbox #icons #burgIcons #cities');
const towns_icons = svg.select('#viewbox #icons #burgIcons #towns'); const towns_icons = svg.select('#viewbox #icons #burgIcons #towns');
const citie_icon_material = new THREE.MeshBasicMaterial({color: cities_icons.attr('fill')});
const town_icon_material = new THREE.MeshBasicMaterial({color: towns_icons.attr('fill')});
const citie_icon_geometry = new THREE.SphereGeometry(cities_icons.attr("size") * 2, 16, 16);
const town_icon_geometry = new THREE.SphereGeometry(towns_icons.attr("size") * 2, 16, 16);
for (const burg of pack.burgs) { for (const burg of pack.burgs) {
const [x, y, z] = get3dCoords(burg.x, burg.y) const [x, y, z] = get3dCoords(burg.x, burg.y)
@ -300,10 +307,9 @@ async function createLabels() {
// Icon // Icon
if(layerIsOn("toggleIcons")) { if(layerIsOn("toggleIcons")) {
const icon_material = new THREE.MeshBasicMaterial({color: burg.capital ? cities_icons.attr('fill') : towns_icons.attr('fill')});
const icon_mesh = new THREE.Mesh( const icon_mesh = new THREE.Mesh(
new THREE.SphereGeometry((burg.capital ? cities_icons.attr("size") : towns_icons.attr("size")) * 2, 16, 16), burg.capital ? citie_icon_geometry : town_icon_geometry,
icon_material burg.capital ? citie_icon_material : town_icon_material
); );
icon_mesh.position.set(x, y, z) icon_mesh.position.set(x, y, z)
icon_mesh.base_x = burg.x icon_mesh.base_x = burg.x
@ -332,18 +338,31 @@ async function createLabels() {
} }
function deleteLabels() { function deleteLabels() {
for (const mesh of textMeshs) { if (square_geometry) square_geometry.dispose();
square_geometry = undefined;
texture_loader = undefined;
for (const [i, mesh] of textMeshs.entries()) {
scene.remove(mesh);
mesh.material.map.dispose(); mesh.material.map.dispose();
mesh.material.dispose(); mesh.material.dispose();
mesh.geometry.dispose(); mesh.geometry.dispose();
scene.remove(mesh); delete mesh.material.map;
delete mesh.material;
delete mesh.geometry;
delete textMeshs[i];
} }
textMeshs = [];
for (const mesh of iconMeshs) { for (const [i, mesh] of iconMeshs.entries()) {
scene.remove(mesh);
mesh.material.dispose(); mesh.material.dispose();
mesh.geometry.dispose(); mesh.geometry.dispose();
scene.remove(mesh); delete mesh.material;
delete mesh.geometry;
delete iconMeshs[i];
} }
iconMeshs = [];
} }
// create a mesh from pixel data // create a mesh from pixel data
@ -376,8 +395,6 @@ async function createMesh(width, height, segmentsX, segmentsY) {
scene.add(mesh); scene.add(mesh);
deleteLabels(); deleteLabels();
textMeshs = [];
iconMeshs = [];
if (options.labels3d) { if (options.labels3d) {
await createLabels(); await createLabels();