diff --git a/examples/3dtiles_loader.html b/examples/3dtiles_loader.html
index 56ae5b01f1..44cb652a26 100644
--- a/examples/3dtiles_loader.html
+++ b/examples/3dtiles_loader.html
@@ -119,13 +119,12 @@
// Add one imagery layer to the scene. This layer's properties are
// defined in a json file, but it cou ld be defined as a plain js
// object. See `Layer` documentation for more info.
- Fetcher.json('./layers/JSONLayers/OPENSM.json').then((config) => {
- const colorLayer = new ColorLayer('Ortho', {
- ...config,
- source: new TMSSource(config.source),
- });
- view.addLayer(colorLayer);
+ const openSmConfig = await Fetcher.json('./layers/JSONLayers/OPENSM.json');
+ const colorLayer = new ColorLayer('Ortho', {
+ ...openSmConfig,
+ source: new TMSSource(openSmConfig.source),
});
+ view.addLayer(colorLayer);
// ---- Add 3D terrain ----
@@ -136,8 +135,10 @@
var elevationLayer = new itowns.ElevationLayer(config.id, config);
view.addLayer(elevationLayer);
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
// ---------- 3D Tiles loading
diff --git a/examples/copc_3d_loader.html b/examples/copc_3d_loader.html
index d572fe86c5..b695582cd0 100644
--- a/examples/copc_3d_loader.html
+++ b/examples/copc_3d_loader.html
@@ -60,11 +60,10 @@
// Add one imagery layer to the scene and the miniView
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer);
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
function addElevationLayerFromConfig(config) {
@@ -72,8 +71,10 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer);
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
var layer;
diff --git a/examples/effects_postprocessing.html b/examples/effects_postprocessing.html
index e2f9870ad9..ee4c976e80 100644
--- a/examples/effects_postprocessing.html
+++ b/examples/effects_postprocessing.html
@@ -118,16 +118,14 @@
r.render(postprocessScene, cam);
};
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer);
- });
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ElevationLayer(config.id, config);
- view.addLayer(layer);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer);
+ const ignMntConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT.json');
+ ignMntConfig.source = new itowns.WMTSSource(ignMntConfig.source);
+ var elevationLayer = new itowns.ElevationLayer(ignMntConfig.id, ignMntConfig);
+ view.addLayer(elevationLayer);
window.view = view;
window.itowns = itowns;
window.THREE = THREE;
diff --git a/examples/effects_split.html b/examples/effects_split.html
index 265423e5ac..e9949fccf0 100644
--- a/examples/effects_split.html
+++ b/examples/effects_split.html
@@ -82,17 +82,15 @@
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- const pOrtho = itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- orthoLayer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(orthoLayer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
- const pOsm = itowns.Fetcher.json('./layers/JSONLayers/OPENSM.json').then(function _(config) {
- config.source = new itowns.TMSSource(config.source);
- osmLayer = new itowns.ColorLayer('OSM', config);
- view.addLayer(osmLayer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
- });
+ const osmConfig = await itowns.Fetcher.json('./layers/JSONLayers/OPENSM.json');
+ osmConfig.source = new itowns.TMSSource(osmConfig.source);
+ osmLayer = new itowns.ColorLayer('OSM', osmConfig);
+ view.addLayer(osmLayer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
@@ -101,8 +99,10 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer);
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
// Slide handling
function splitSliderMove(evt) {
@@ -155,8 +155,7 @@
}
// Override default rendering method when color layers are ready
- Promise.all([pOrtho, pOsm]).then(
- function _() { view.render = splitRendering; }).catch(console.error);
+ view.render = splitRendering;
window.view = view;
window.itowns = itowns;
window.THREE = THREE;
diff --git a/examples/effects_stereo.html b/examples/effects_stereo.html
index ffed5d9d09..2a825375d1 100644
--- a/examples/effects_stereo.html
+++ b/examples/effects_stereo.html
@@ -78,11 +78,10 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- const source = new itowns.WMTSSource(config.source);
- const layer = new itowns.ColorLayer(config.id, { source });
- view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ const orthoSource = new itowns.WMTSSource(orthoConfig.source);
+ const orthoLayer = new itowns.ColorLayer(orthoConfig.id, { source: orthoSource });
+ view.addLayer(orthoLayer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
function addElevationLayerFromConfig(config) {
@@ -90,8 +89,10 @@
const layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
/* eslint-disable no-unused-vars */
function updateEyeSep(value) {
diff --git a/examples/entwine_3d_loader.html b/examples/entwine_3d_loader.html
index 27e155f23f..a392729089 100644
--- a/examples/entwine_3d_loader.html
+++ b/examples/entwine_3d_loader.html
@@ -61,11 +61,10 @@
// Add one imagery layer to the scene and the miniView
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer);
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
@@ -74,8 +73,10 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer);
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
// Check if an url had been given as an argument
// and parse to get url and options.
diff --git a/examples/geoid_geoidLayer.html b/examples/geoid_geoidLayer.html
index 5e3295f507..952e6109ef 100644
--- a/examples/geoid_geoidLayer.html
+++ b/examples/geoid_geoidLayer.html
@@ -62,12 +62,11 @@
// Add one imagery layer to the scene. This layer's properties are defined in a json file, but it could be
// defined as a plain js object. See `Layer` documentation for more info.
- itowns.Fetcher.json('layers/JSONLayers/Ortho.json').then((config) => {
- config.source = new itowns.WMTSSource(config.source);
- view.addLayer(
- new itowns.ColorLayer(config.id, config),
- ).then(debugMenu.addLayerGUI.bind(debugMenu));
- });
+ const orthoConfig = await itowns.Fetcher.json('layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ view.addLayer(
+ new itowns.ColorLayer(orthoConfig.id, orthoConfig),
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
// Add two elevaion layers, each with a different level of detail. Here again, each layer's properties are
// defined in a json file.
@@ -77,8 +76,10 @@
new itowns.ElevationLayer(config.id, config),
).then(debugMenu.addLayerGUI.bind(debugMenu));
}
- itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
diff --git a/examples/itowns-potree.html b/examples/itowns-potree.html
index 3d9cbdcf02..5b59e82bc4 100644
--- a/examples/itowns-potree.html
+++ b/examples/itowns-potree.html
@@ -195,13 +195,12 @@
// Add one imagery layer to the scene. This layer's properties are defined in a json file, but it could be
// defined as a plain js object. See `Layer` documentation for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- config.source.zoom = { max: 19, min: 3 };
- itownsViewer.addLayer(
- new itowns.ColorLayer(config.id, config),
- );
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ orthoConfig.source.zoom = { max: 19, min: 3 };
+ itownsViewer.addLayer(
+ new itowns.ColorLayer(orthoConfig.id, orthoConfig),
+ );
// Add two elevaion layers, each with a different level of detail. Here again, each layer's properties are
// defined in a json file.
@@ -211,8 +210,10 @@
new itowns.ElevationLayer(config.id, config),
);
}
- itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
diff --git a/examples/misc_camera_animation.html b/examples/misc_camera_animation.html
index e400c16869..2e08866f85 100644
--- a/examples/misc_camera_animation.html
+++ b/examples/misc_camera_animation.html
@@ -57,12 +57,11 @@
// Add one imagery layer to the scene. This layer's properties are defined in a json file, but it could be
// defined as a plain js object. See `Layer` documentation for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- view.addLayer(
- new itowns.ColorLayer('Ortho', config),
- );
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ view.addLayer(
+ new itowns.ColorLayer('Ortho', orthoConfig),
+ );
@@ -76,8 +75,10 @@
new itowns.ElevationLayer(config.id, config),
);
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
diff --git a/examples/misc_camera_traveling.html b/examples/misc_camera_traveling.html
index 0434fe5643..d4ffe9f1a5 100644
--- a/examples/misc_camera_traveling.html
+++ b/examples/misc_camera_traveling.html
@@ -71,11 +71,10 @@
// Add one imagery layer to the scene and the miniView.
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- const orthoLayer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(orthoLayer);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ const orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer);
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
@@ -84,8 +83,10 @@
let layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer);
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
// ---------- Select camera positions and travel through these positions : ----------
diff --git a/examples/misc_clamp_ground.html b/examples/misc_clamp_ground.html
index 60a49b4830..234a3b29c2 100644
--- a/examples/misc_clamp_ground.html
+++ b/examples/misc_clamp_ground.html
@@ -55,20 +55,24 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
function addElevationLayerFromConfig(config) {
config.source = new itowns.WMTSSource(config.source);
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
+
+ return layer;
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
+
function addMeshToScene() {
// creation of the new mesh (a cylinder)
@@ -100,9 +104,8 @@
}
// Listen for globe full initialisation event
- view.addEventListener(itowns.GLOBE_VIEW_EVENTS.GLOBE_INITIALIZED, function globeInitialized() {
- // eslint-disable-next-line no-console
- console.info('Globe initialized');
+ view.addEventListener(itowns.GLOBE_VIEW_EVENTS.GLOBE_INITIALIZED, function init() {
+ console.log('GLOBE_INITIALIZED');
addMeshToScene();
});
window.view = view;
diff --git a/examples/misc_colorlayer_visibility.html b/examples/misc_colorlayer_visibility.html
index dbbc622333..54400c84f0 100644
--- a/examples/misc_colorlayer_visibility.html
+++ b/examples/misc_colorlayer_visibility.html
@@ -57,10 +57,14 @@
view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
}
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(addColorLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/Cada.json').then(addColorLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ addColorLayerFromConfig(orthoConfig);
+ const cadaConfig = await itowns.Fetcher.json('./layers/JSONLayers/Cada.json');
+ addColorLayerFromConfig(cadaConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
view.addEventListener(itowns.GLOBE_VIEW_EVENTS.GLOBE_INITIALIZED, function _() {
// eslint-disable-next-line no-console
diff --git a/examples/misc_compare_25d_3d.html b/examples/misc_compare_25d_3d.html
index d102d5bdd0..925c3624aa 100644
--- a/examples/misc_compare_25d_3d.html
+++ b/examples/misc_compare_25d_3d.html
@@ -104,11 +104,10 @@
overGlobe = false;
}, false);
- promises.push(itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer(config.id, config);
- view.addLayer(layer);
- }));
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer(orthoConfig.id, orthoConfig);
+ view.addLayer(orthoLayer);
// Listen for globe full initialisation event
view
@@ -116,38 +115,36 @@
function globeInitialized() {
// eslint-disable-next-line no-console
console.info('Globe initialized');
- Promise.all(promises).then(function init() {
- var planarCamera = planarView.camera3D;
- var globeCamera = view.camera3D;
- var params;
- menuGlobe.addImageryLayersGUI(view.getLayers(function filterColor(l) { return l.isColorLayer; }));
- menuGlobe.addElevationLayersGUI(view.getLayers(function filterElevation(l) { return l.isElevationLayer; }));
-
- function sync() {
- if (overGlobe) {
- params = itowns.CameraUtils
- .getTransformCameraLookingAtTarget(
- view, globeCamera);
- itowns.CameraUtils
+ var planarCamera = planarView.camera3D;
+ var globeCamera = view.camera3D;
+ var params;
+ menuGlobe.addImageryLayersGUI(view.getLayers(function filterColor(l) { return l.isColorLayer; }));
+ menuGlobe.addElevationLayersGUI(view.getLayers(function filterElevation(l) { return l.isElevationLayer; }));
+
+ function sync() {
+ if (overGlobe) {
+ params = itowns.CameraUtils
+ .getTransformCameraLookingAtTarget(
+ view, globeCamera);
+ itowns.CameraUtils
+ .transformCameraToLookAtTarget(
+ planarView, planarCamera, params);
+ } else {
+ params = itowns.CameraUtils
+ .getTransformCameraLookingAtTarget(
+ planarView, planarCamera);
+ itowns.CameraUtils
.transformCameraToLookAtTarget(
- planarView, planarCamera, params);
- } else {
- params = itowns.CameraUtils
- .getTransformCameraLookingAtTarget(
- planarView, planarCamera);
- itowns.CameraUtils
- .transformCameraToLookAtTarget(
- view, globeCamera, params);
- }
+ view, globeCamera, params);
}
- sync();
- view
- .addFrameRequester(itowns
- .MAIN_LOOP_EVENTS.AFTER_CAMERA_UPDATE, sync);
- planarView
- .addFrameRequester(itowns
- .MAIN_LOOP_EVENTS.AFTER_CAMERA_UPDATE, sync);
- }).catch(console.error);
+ }
+ sync();
+ view
+ .addFrameRequester(itowns
+ .MAIN_LOOP_EVENTS.AFTER_CAMERA_UPDATE, sync);
+ planarView
+ .addFrameRequester(itowns
+ .MAIN_LOOP_EVENTS.AFTER_CAMERA_UPDATE, sync);
});
var wmsImagerySource = new itowns.WMSSource({
diff --git a/examples/misc_custom_controls.html b/examples/misc_custom_controls.html
index 5a482877fe..847c9dadb9 100644
--- a/examples/misc_custom_controls.html
+++ b/examples/misc_custom_controls.html
@@ -57,20 +57,21 @@
setupLoadingScreen(viewerDiv, view);
// Add imagery and elevation layers
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function (config) {
- config.source = new itowns.WMTSSource(config.source);
- view.addLayer(
- new itowns.ColorLayer('Ortho', config),
- );
- })
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ view.addLayer(
+ new itowns.ColorLayer('Ortho', orthoConfig),
+ );
function addElevationLayerFromConfig(config) {
config.source = new itowns.WMTSSource(config.source);
view.addLayer(
new itowns.ElevationLayer(config.id, config),
);
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
const customControls = {
// Disable pan movement
diff --git a/examples/misc_custom_label.html b/examples/misc_custom_label.html
index e410f03e54..fca04b7e80 100644
--- a/examples/misc_custom_label.html
+++ b/examples/misc_custom_label.html
@@ -62,16 +62,17 @@
const viewerDiv = document.getElementById('viewerDiv');
const view = new itowns.GlobeView(viewerDiv, placement);
var menuGlobe = new GuiTools('menuDiv', view);
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- view.addLayer(new itowns.ColorLayer('Ortho', config));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ view.addLayer(new itowns.ColorLayer('Ortho', orthoConfig));
function addElevationLayerFromConfig(config) {
config.source = new itowns.WMTSSource(config.source);
view.addLayer(new itowns.ElevationLayer(config.id, config));
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
debug.createTileDebugUI(menuGlobe.gui, view);
// Create a custom div which will be displayed as a label
diff --git a/examples/misc_georeferenced_images.html b/examples/misc_georeferenced_images.html
index 8ba0b95422..4b097f1c83 100644
--- a/examples/misc_georeferenced_images.html
+++ b/examples/misc_georeferenced_images.html
@@ -78,11 +78,10 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
@@ -91,8 +90,10 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
pictureInfos = {
panoramic: {
diff --git a/examples/misc_geotiff.html b/examples/misc_geotiff.html
index 53bd43dd3d..2db3bb29e0 100644
--- a/examples/misc_geotiff.html
+++ b/examples/misc_geotiff.html
@@ -57,16 +57,15 @@
// ---------- DISPLAY ORTHO IMAGES: ----------
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then((config) => {
- const colorLayer = new itowns.ColorLayer(
- 'Ortho',
- {
- ...config,
- source: new itowns.WMTSSource(config.source),
- },
- );
- view.addLayer(colorLayer).then(debugMenu.addLayerGUI.bind(debugMenu));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ const colorLayer = new itowns.ColorLayer(
+ 'Ortho',
+ {
+ ...orthoConfig,
+ source: new itowns.WMTSSource(orthoConfig.source),
+ },
+ );
+ view.addLayer(colorLayer).then(debugMenu.addLayerGUI.bind(debugMenu));
diff --git a/examples/misc_instancing.html b/examples/misc_instancing.html
index 7fec14f906..dcc3cdbcb6 100644
--- a/examples/misc_instancing.html
+++ b/examples/misc_instancing.html
@@ -62,14 +62,11 @@
view.scene.add(ambLight);
// Add one imagery layer to the scene
- itowns.Fetcher.json("./layers/JSONLayers/Ortho.json").then(
- function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer("Ortho", config);
- view.addLayer(layer).then(
- debugMenu.addLayerGUI.bind(debugMenu)
- );
- }
+ const orthoConfig = await itowns.Fetcher.json("./layers/JSONLayers/Ortho.json");
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer("Ortho", orthoConfig);
+ view.addLayer(orthoLayer).then(
+ debugMenu.addLayerGUI.bind(debugMenu)
);
//Tree
diff --git a/examples/plugins_drag_n_drop.html b/examples/plugins_drag_n_drop.html
index 17afe43b06..16faa5fe27 100644
--- a/examples/plugins_drag_n_drop.html
+++ b/examples/plugins_drag_n_drop.html
@@ -58,11 +58,10 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer);
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
@@ -71,8 +70,10 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer);
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
DragNDrop.setView(view);
DragNDrop.register('geojson', DragNDrop.JSON, itowns.GeoJsonParser.parse, DragNDrop.COLOR);
diff --git a/examples/plugins_pyramidal_tiff.html b/examples/plugins_pyramidal_tiff.html
index 5a0a39f980..5f5ac9155a 100644
--- a/examples/plugins_pyramidal_tiff.html
+++ b/examples/plugins_pyramidal_tiff.html
@@ -80,7 +80,8 @@
menuGlobe.elevationGui.__folders.GEOIDMNT.open();
});
}
- itowns.Fetcher.json('./layers/JSONLayers/GeoidMNT.json').then(addElevationLayerFromConfig);
+ const geoidMntConfig = await itowns.Fetcher.json('./layers/JSONLayers/GeoidMNT.json');
+ addElevationLayerFromConfig(geoidMntConfig);
const d = new debug.Debug(view, menuGlobe.gui);
debug.createTileDebugUI(menuGlobe.gui, view, view.tileLayer, d);
diff --git a/examples/plugins_vrt.html b/examples/plugins_vrt.html
index 196763996d..8dfd82e61c 100644
--- a/examples/plugins_vrt.html
+++ b/examples/plugins_vrt.html
@@ -58,11 +58,10 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/OPENSM.json').then(function _(config) {
- config.source = new itowns.TMSSource(config.source);
- var layer = new itowns.ColorLayer('OPENSM', config);
- view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
- });
+ const openSmConfig = await itowns.Fetcher.json('./layers/JSONLayers/OPENSM.json');
+ openSmConfig.source = new itowns.TMSSource(openSmConfig.source);
+ var openSmLayer = new itowns.ColorLayer('OPENSM', openSmConfig);
+ view.addLayer(openSmLayer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
// In this case, a VRT is associated to a CSV
itowns.Fetcher.multiple('https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/vrt/velib-disponibilite-en-temps-reel', {
diff --git a/examples/potree_3d_map.html b/examples/potree_3d_map.html
index 9971dce5af..8b2534aeeb 100644
--- a/examples/potree_3d_map.html
+++ b/examples/potree_3d_map.html
@@ -71,16 +71,14 @@
view.controls.minDistance = 50;
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ElevationLayer(config.id, config);
- view.addLayer(layer);
- });
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer(config.id, config);
- view.addLayer(layer);
- });
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ ignMntHighResConfig.source = new itowns.WMTSSource(ignMntHighResConfig.source);
+ var elevationLayer = new itowns.ElevationLayer(ignMntHighResConfig.id, ignMntHighResConfig);
+ view.addLayer(elevationLayer);
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer(orthoConfig.id, orthoConfig);
+ view.addLayer(orthoLayer);
/* OTHER dataset
Donnees geocentrique -> probleme pour le placement camera
diff --git a/examples/source_file_from_fetched_data.html b/examples/source_file_from_fetched_data.html
index 54f91d5fc2..25bc863cd7 100644
--- a/examples/source_file_from_fetched_data.html
+++ b/examples/source_file_from_fetched_data.html
@@ -62,11 +62,10 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer).then(debugMenu.addLayerGUI.bind(debugMenu));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer).then(debugMenu.addLayerGUI.bind(debugMenu));
diff --git a/examples/source_file_from_format.html b/examples/source_file_from_format.html
index 1fbc9890c5..2d635ff534 100644
--- a/examples/source_file_from_format.html
+++ b/examples/source_file_from_format.html
@@ -60,11 +60,10 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer).then(debugMenu.addLayerGUI.bind(debugMenu));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer).then(debugMenu.addLayerGUI.bind(debugMenu));
diff --git a/examples/source_file_from_methods.html b/examples/source_file_from_methods.html
index 34026a0952..387c259c85 100644
--- a/examples/source_file_from_methods.html
+++ b/examples/source_file_from_methods.html
@@ -60,11 +60,10 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer).then(debugMenu.addLayerGUI.bind(debugMenu));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer).then(debugMenu.addLayerGUI.bind(debugMenu));
diff --git a/examples/source_file_from_parsed_data.html b/examples/source_file_from_parsed_data.html
index 9dab6c5776..fd6d766838 100644
--- a/examples/source_file_from_parsed_data.html
+++ b/examples/source_file_from_parsed_data.html
@@ -61,11 +61,10 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer).then(debugMenu.addLayerGUI.bind(debugMenu));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer).then(debugMenu.addLayerGUI.bind(debugMenu));
diff --git a/examples/source_file_geojson_3d.html b/examples/source_file_geojson_3d.html
index 3400159bbd..0aed91a132 100644
--- a/examples/source_file_geojson_3d.html
+++ b/examples/source_file_geojson_3d.html
@@ -48,11 +48,10 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
@@ -61,8 +60,10 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
// Add a geometry layer, which will contain the multipolygon to display
var marne = new itowns.FeatureGeometryLayer('Marne', {
diff --git a/examples/source_file_geojson_raster.html b/examples/source_file_geojson_raster.html
index fd93807314..97137844c3 100644
--- a/examples/source_file_geojson_raster.html
+++ b/examples/source_file_geojson_raster.html
@@ -58,13 +58,12 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer).then(function _() {
- menuGlobe.addLayerGUI.bind(menuGlobe);
- itowns.ColorLayersOrdering.moveLayerToIndex(view, 'Ortho', 0);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer).then(function _() {
+ menuGlobe.addLayerGUI.bind(menuGlobe);
+ itowns.ColorLayersOrdering.moveLayerToIndex(view, 'Ortho', 0);
});
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
@@ -73,8 +72,10 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
// Display the content of two GeoJSON files on terrain with ColorLayer and FileSource.
diff --git a/examples/source_file_gpx_3d.html b/examples/source_file_gpx_3d.html
index 86c2e9a6b7..57b0c0424a 100644
--- a/examples/source_file_gpx_3d.html
+++ b/examples/source_file_gpx_3d.html
@@ -52,11 +52,10 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer);
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
function addElevationLayerFromConfig(config) {
@@ -64,8 +63,10 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer);
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
// update the waypoint
var distance, scale, point = new THREE.Vector3();
diff --git a/examples/source_file_gpx_raster.html b/examples/source_file_gpx_raster.html
index 3ef62fa8dd..5772d5ca37 100644
--- a/examples/source_file_gpx_raster.html
+++ b/examples/source_file_gpx_raster.html
@@ -55,13 +55,12 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer).then(function _() {
- menuGlobe.addLayerGUI.bind(menuGlobe);
- itowns.ColorLayersOrdering.moveLayerToIndex(view, 'Ortho', 0);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer).then(function _() {
+ menuGlobe.addLayerGUI.bind(menuGlobe);
+ itowns.ColorLayersOrdering.moveLayerToIndex(view, 'Ortho', 0);
});
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
@@ -70,8 +69,10 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
const gpxSource = new itowns.FileSource({
diff --git a/examples/source_file_kml_raster.html b/examples/source_file_kml_raster.html
index 832d591a5f..6ac82cf2a8 100644
--- a/examples/source_file_kml_raster.html
+++ b/examples/source_file_kml_raster.html
@@ -57,13 +57,12 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer).then(function _() {
- menuGlobe.addLayerGUI.bind(menuGlobe);
- itowns.ColorLayersOrdering.moveLayerToIndex(view, 'Ortho', 0);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer).then(function _() {
+ menuGlobe.addLayerGUI.bind(menuGlobe);
+ itowns.ColorLayersOrdering.moveLayerToIndex(view, 'Ortho', 0);
});
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
@@ -72,8 +71,10 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
// Fetch, Parse and Convert by iTowns
var kmlSource = new itowns.FileSource({
diff --git a/examples/source_file_kml_raster_usgs.html b/examples/source_file_kml_raster_usgs.html
index dfcbb663ce..37fc022576 100644
--- a/examples/source_file_kml_raster_usgs.html
+++ b/examples/source_file_kml_raster_usgs.html
@@ -54,13 +54,12 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer).then(function _() {
- menuGlobe.addLayerGUI.bind(menuGlobe);
- itowns.ColorLayersOrdering.moveLayerToIndex(view, 'Ortho', 0);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer).then(function _() {
+ menuGlobe.addLayerGUI.bind(menuGlobe);
+ itowns.ColorLayersOrdering.moveLayerToIndex(view, 'Ortho', 0);
});
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
@@ -69,8 +68,10 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
}
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
// Fetch, Parse and Convert by iTowns
var kmlSource = new itowns.FileSource({
diff --git a/examples/source_file_shapefile.html b/examples/source_file_shapefile.html
index bb5745cd3b..f8fb8efe43 100644
--- a/examples/source_file_shapefile.html
+++ b/examples/source_file_shapefile.html
@@ -54,11 +54,10 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/OPENSM.json').then(function _(config) {
- config.source = new itowns.TMSSource(config.source);
- var layer = new itowns.ColorLayer('OPENSM', config);
- view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
- });
+ const openSmConfig = await itowns.Fetcher.json('./layers/JSONLayers/OPENSM.json');
+ openSmConfig.source = new itowns.TMSSource(openSmConfig.source);
+ var openSmLayer = new itowns.ColorLayer('OPENSM', openSmConfig);
+ view.addLayer(openSmLayer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
diff --git a/examples/source_stream_wfs_3d.html b/examples/source_stream_wfs_3d.html
index 0682ef1891..4bbbac59e0 100644
--- a/examples/source_stream_wfs_3d.html
+++ b/examples/source_stream_wfs_3d.html
@@ -69,11 +69,10 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer);
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
@@ -82,8 +81,10 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer);
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
var color = new THREE.Color();
var tile;
diff --git a/examples/source_stream_wfs_raster.html b/examples/source_stream_wfs_raster.html
index ae89cca030..a3bae45f6a 100644
--- a/examples/source_stream_wfs_raster.html
+++ b/examples/source_stream_wfs_raster.html
@@ -56,11 +56,10 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
@@ -69,8 +68,10 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
var wfsBuildingSource = new itowns.WFSSource({
url: 'https://data.geopf.fr/wfs/ows?',
diff --git a/examples/vector_tile_3d_mesh.html b/examples/vector_tile_3d_mesh.html
index c2cabd2a33..28f7f9b964 100644
--- a/examples/vector_tile_3d_mesh.html
+++ b/examples/vector_tile_3d_mesh.html
@@ -73,16 +73,17 @@
view.addLayer(new itowns.ElevationLayer(config.id, config))
.then(debugMenu.addLayerGUI.bind(debugMenu));
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
// ---------- DISPLAY ORTHO-IMAGES : ----------
- const ortho = itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- return view.addLayer(layer);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer);
// ---------- DISPLAY VECTOR TILED MAP DATA AS A ColorLayer : ----------
@@ -158,9 +159,7 @@
debug.createTileDebugUI(debugMenu.gui, view);
view.addEventListener(itowns.GLOBE_VIEW_EVENTS.GLOBE_INITIALIZED, function () {
- ortho.then(function () {
- itowns.ColorLayersOrdering.moveLayerToIndex(view, 'Ortho', 0);
- }).catch(console.error);
+ itowns.ColorLayersOrdering.moveLayerToIndex(view, 'Ortho', 0);
});
window.view = view;
diff --git a/examples/vector_tile_3d_mesh_mapbox.html b/examples/vector_tile_3d_mesh_mapbox.html
index 6500d85674..74391dee9b 100644
--- a/examples/vector_tile_3d_mesh_mapbox.html
+++ b/examples/vector_tile_3d_mesh_mapbox.html
@@ -80,12 +80,10 @@
// Add one imagery layer to the scene. This layer's properties are
// defined in a json file, but it could be defined as a plain js
// object. See `Layer` documentation for more info.
- const ortho = itowns.Fetcher.json('./layers/JSONLayers/Ortho.json')
- .then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- return view.addLayer(layer);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer);
// Add an elevation layer, whose properties are defined in a json
// file.
@@ -94,8 +92,8 @@
view.addLayer(new itowns.ElevationLayer(config.id, config))
.then(debugMenu.addLayerGUI.bind(debugMenu));
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json')
- .then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
diff --git a/examples/vector_tile_raster_3d.html b/examples/vector_tile_raster_3d.html
index f046d81129..58df7fce4f 100644
--- a/examples/vector_tile_raster_3d.html
+++ b/examples/vector_tile_raster_3d.html
@@ -55,11 +55,10 @@
setupLoadingScreen(viewerDiv, view);
- promises.push(itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- return view.addLayer(layer);
- }));
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer);
// Define a VectorTilesSource to load Vector Tiles data from the geoportail
var mvtSource = new itowns.VectorTilesSource({
@@ -80,10 +79,8 @@
var menuGlobe = new GuiTools('menuDiv', view, 300);
// Listen for globe full initialisation event
view.addEventListener(itowns.GLOBE_VIEW_EVENTS.GLOBE_INITIALIZED, function () {
- Promise.all(promises).then(function () {
- menuGlobe.addImageryLayersGUI(view.getLayers(function (l) { return l.isColorLayer; }));
- itowns.ColorLayersOrdering.moveLayerToIndex(view, 'Ortho', 0);
- }).catch(console.error);
+ menuGlobe.addImageryLayersGUI(view.getLayers(function (l) { return l.isColorLayer; }));
+ itowns.ColorLayersOrdering.moveLayerToIndex(view, 'Ortho', 0);
});
debug.createTileDebugUI(menuGlobe.gui, view);
diff --git a/examples/view_3d_map.html b/examples/view_3d_map.html
index 5a5b99544c..ae13cf5b53 100644
--- a/examples/view_3d_map.html
+++ b/examples/view_3d_map.html
@@ -62,12 +62,11 @@
// Add one imagery layer to the scene. This layer's properties are defined in a json file, but it could be
// defined as a plain js object. See `Layer` documentation for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- view.addLayer(
- new itowns.ColorLayer('Ortho', config),
- ).then(debugMenu.addLayerGUI.bind(debugMenu));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ view.addLayer(
+ new itowns.ColorLayer('Ortho', orthoConfig),
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
@@ -81,8 +80,10 @@
new itowns.ElevationLayer(config.id, config),
).then(debugMenu.addLayerGUI.bind(debugMenu));
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
// ---------- ADD SOME WIDGETS : ----------
@@ -91,19 +92,19 @@
const scale = new itowns_widgets.Scale(view, { position: 'bottom-right', translate: { x: -80 } });
// ADD A MINIMAP :
- const minimap = new itowns_widgets.Minimap(
- view,
- new itowns.ColorLayer('minimap', {
- source: new itowns.VectorTilesSource({
- style: "https://data.geopf.fr/annexes/ressources/vectorTiles/styles/PLAN.IGN/standard.json",
- // We don't display mountains and plot related data to ease visualisation
- filter: (layer) => !layer['source-layer'].includes('oro_')
- && !layer['source-layer'].includes('parcellaire'),
- }),
- addLabelLayer: { performance: true },
- }),
- { cursor: '+' },
- );
+ // const minimap = new itowns_widgets.Minimap(
+ // view,
+ // new itowns.ColorLayer('minimap', {
+ // source: new itowns.VectorTilesSource({
+ // style: "https://data.geopf.fr/annexes/ressources/vectorTiles/styles/PLAN.IGN/standard.json",
+ // // We don't display mountains and plot related data to ease visualisation
+ // filter: (layer) => !layer['source-layer'].includes('oro_')
+ // && !layer['source-layer'].includes('parcellaire'),
+ // }),
+ // addLabelLayer: { performance: true },
+ // }),
+ // { cursor: '+' },
+ // );
// ADD NAVIGATION TOOLS :
const navigation = new itowns_widgets.Navigation(view, {
diff --git a/examples/view_3d_map_webxr.html b/examples/view_3d_map_webxr.html
index 9de40fe104..aa4fd20ebc 100644
--- a/examples/view_3d_map_webxr.html
+++ b/examples/view_3d_map_webxr.html
@@ -73,11 +73,10 @@
// Add one imagery layer to the scene. This layer's properties are
// defined in a json file, but it could be defined as a plain js
// object. See `Layer` documentation for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then((config) => {
- config.source = new itowns.WMTSSource(config.source);
- view.addLayer(new itowns.ColorLayer('Ortho', config),
- );
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ view.addLayer(new itowns.ColorLayer('Ortho', orthoConfig),
+ );
// ---------- DISPLAY A DIGITAL ELEVATION MODEL : ----------
@@ -89,10 +88,10 @@
new itowns.ElevationLayer(config.id, config),
);
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json')
- .then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json')
- .then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
window.view = view;
window.itowns = itowns;
window.THREE = THREE;
diff --git a/examples/view_3d_mns_map.html b/examples/view_3d_mns_map.html
index aaae1fe583..089538f17d 100644
--- a/examples/view_3d_mns_map.html
+++ b/examples/view_3d_mns_map.html
@@ -69,12 +69,11 @@
// Add one imagery layer to the scene. This layer's properties are defined in a json file, but it could be
// defined as a plain js object. See `Layer` documentation for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- view.addLayer(
- new itowns.ColorLayer('Ortho', config),
- ).then(debugMenu.addLayerGUI.bind(debugMenu));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ view.addLayer(
+ new itowns.ColorLayer('Ortho', orthoConfig),
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
// ---------- DISPLAY A DIGITAL ELEVATION MODEL : ----------
@@ -87,7 +86,8 @@
new itowns.ElevationLayer(config.id, config),
).then(debugMenu.addLayerGUI.bind(debugMenu));
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNS_HIGHRES.json').then(addElevationLayerFromConfig);
+ const ignMnsHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNS_HIGHRES.json');
+ addElevationLayerFromConfig(ignMnsHighResConfig);
// ---------- ADD SOME WIDGETS : ----------
diff --git a/examples/view_immersive.html b/examples/view_immersive.html
index f9cd1a0d33..4e632f054c 100644
--- a/examples/view_immersive.html
+++ b/examples/view_immersive.html
@@ -78,11 +78,10 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
@@ -91,7 +90,8 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer).then(menuGlobe.addLayerGUI.bind(menuGlobe));
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
function altitudeBuildings(properties) {
// I set altitude building 3 meters down, to be sure building is anchored in the ground
diff --git a/examples/view_multiglobe.html b/examples/view_multiglobe.html
index c48ea60b38..de3fe44d86 100644
--- a/examples/view_multiglobe.html
+++ b/examples/view_multiglobe.html
@@ -71,11 +71,10 @@
setupLoadingScreen(viewerDiv, view);
object3ds.push(object3d);
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer);
// Create a second smaller globe
object3d = new THREE.Object3D();
@@ -90,11 +89,10 @@
// add globe2 to the view so it gets updated
itowns.View.prototype.addLayer.call(view, globe2);
- itowns.Fetcher.json('./layers/JSONLayers/OPENSM.json').then(function _(osm) {
- osm.source = new itowns.TMSSource(osm.source);
- var layer = new itowns.ColorLayer(osm.id, osm);
- itowns.View.prototype.addLayer.call(view, layer, globe2);
- });
+ const openSmConfig = await itowns.Fetcher.json('./layers/JSONLayers/OPENSM.json');
+ openSmConfig.source = new itowns.TMSSource(openSmConfig.source);
+ var globe2Layer = new itowns.ColorLayer(openSmConfig.id, openSmConfig);
+ itowns.View.prototype.addLayer.call(view, globe2Layer, globe2);
// Globe animation
// Exchange postion and scale of globes in a 1 second animation
diff --git a/examples/vpc_3d_loader.html b/examples/vpc_3d_loader.html
index 50f050403b..d6fb919c9b 100644
--- a/examples/vpc_3d_loader.html
+++ b/examples/vpc_3d_loader.html
@@ -57,11 +57,10 @@
// Add one imagery layer to the scene and the miniView
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
- itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
- config.source = new itowns.WMTSSource(config.source);
- var layer = new itowns.ColorLayer('Ortho', config);
- view.addLayer(layer);
- });
+ const orthoConfig = await itowns.Fetcher.json('./layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ var orthoLayer = new itowns.ColorLayer('Ortho', orthoConfig);
+ view.addLayer(orthoLayer);
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
@@ -70,8 +69,10 @@
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer);
}
- itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
const url = 'https://data.geopf.fr/chunk/telechargement/download/lidarhd_fxx_ept/vpc/index.vpc';
loadVPC(url);
diff --git a/examples/widgets_minimap.html b/examples/widgets_minimap.html
index d3f1b0ed06..17098de115 100644
--- a/examples/widgets_minimap.html
+++ b/examples/widgets_minimap.html
@@ -76,12 +76,11 @@
// Add one imagery layer to the scene. This layer's properties are defined in a json file, but it could be
// defined as a plain js object. See `Layer` documentation for more info.
- itowns.Fetcher.json('layers/JSONLayers/Ortho.json').then((config) => {
- config.source = new itowns.WMTSSource(config.source);
- view.addLayer(
- new itowns.ColorLayer(config.id, config),
- ).then(debugMenu.addLayerGUI.bind(debugMenu));
- });
+ const orthoConfig = await itowns.Fetcher.json('layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ view.addLayer(
+ new itowns.ColorLayer(orthoConfig.id, orthoConfig),
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
// Add two elevation layers, each with a different level of detail. Here again, each layer's properties are
// defined in a json file.
@@ -91,8 +90,10 @@
new itowns.ElevationLayer(config.id, config),
).then(debugMenu.addLayerGUI.bind(debugMenu));
}
- itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
diff --git a/examples/widgets_navigation.html b/examples/widgets_navigation.html
index efd37ae108..3d3a57cd51 100644
--- a/examples/widgets_navigation.html
+++ b/examples/widgets_navigation.html
@@ -67,12 +67,11 @@
// Add one imagery layer to the scene. This layer's properties are defined in a json file, but it could be
// defined as a plain js object. See `Layer` documentation for more info.
- itowns.Fetcher.json('layers/JSONLayers/Ortho.json').then((config) => {
- config.source = new itowns.WMTSSource(config.source);
- view.addLayer(
- new itowns.ColorLayer(config.id, config),
- ).then(debugMenu.addLayerGUI.bind(debugMenu));
- });
+ const orthoConfig = await itowns.Fetcher.json('layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ view.addLayer(
+ new itowns.ColorLayer(orthoConfig.id, orthoConfig),
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
// Add two elevation layers, each with a different level of detail. Here again, each layer's properties are
// defined in a json file.
@@ -82,8 +81,10 @@
new itowns.ElevationLayer(config.id, config),
).then(debugMenu.addLayerGUI.bind(debugMenu));
}
- itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
diff --git a/examples/widgets_scale.html b/examples/widgets_scale.html
index 68d0ccb075..216657bb5b 100644
--- a/examples/widgets_scale.html
+++ b/examples/widgets_scale.html
@@ -68,12 +68,11 @@
// Add one imagery layer to the scene. This layer's properties are defined in a json file, but it could be
// defined as a plain js object. See `Layer` documentation for more info.
- itowns.Fetcher.json('layers/JSONLayers/Ortho.json').then((config) => {
- config.source = new itowns.WMTSSource(config.source);
- view.addLayer(
- new itowns.ColorLayer(config.id, config),
- ).then(debugMenu.addLayerGUI.bind(debugMenu));
- });
+ const orthoConfig = await itowns.Fetcher.json('layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ view.addLayer(
+ new itowns.ColorLayer(orthoConfig.id, orthoConfig),
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
// Add two elevation layers, each with a different level of detail. Here again, each layer's properties are
// defined in a json file.
@@ -83,8 +82,10 @@
new itowns.ElevationLayer(config.id, config),
).then(debugMenu.addLayerGUI.bind(debugMenu));
}
- itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
diff --git a/examples/widgets_searchbar.html b/examples/widgets_searchbar.html
index 9d3063ac1d..1ba137d8c4 100644
--- a/examples/widgets_searchbar.html
+++ b/examples/widgets_searchbar.html
@@ -66,12 +66,11 @@
// Add one imagery layer to the scene. This layer's properties are defined in a json file, but it could be
// defined as a plain js object. See `Layer` documentation for more info.
- itowns.Fetcher.json('layers/JSONLayers/Ortho.json').then((config) => {
- config.source = new itowns.WMTSSource(config.source);
- view.addLayer(
- new itowns.ColorLayer(config.id, config),
- ).then(debugMenu.addLayerGUI.bind(debugMenu));
- });
+ const orthoConfig = await itowns.Fetcher.json('layers/JSONLayers/Ortho.json');
+ orthoConfig.source = new itowns.WMTSSource(orthoConfig.source);
+ view.addLayer(
+ new itowns.ColorLayer(orthoConfig.id, orthoConfig),
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
// Add two elevation layers, each with a different level of detail. Here again, each layer's properties are
// defined in a json file.
@@ -81,8 +80,10 @@
new itowns.ElevationLayer(config.id, config),
).then(debugMenu.addLayerGUI.bind(debugMenu));
}
- itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
- itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
+ const ignMntHighResConfig = await itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json');
+ addElevationLayerFromConfig(ignMntHighResConfig);
+ const worldDtmConfig = await itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json');
+ addElevationLayerFromConfig(worldDtmConfig);
diff --git a/packages/Geographic/src/Extent.ts b/packages/Geographic/src/Extent.ts
index 388571a254..b2a2285773 100644
--- a/packages/Geographic/src/Extent.ts
+++ b/packages/Geographic/src/Extent.ts
@@ -1,4 +1,4 @@
-import { Vector2, Vector3, Vector4, Box3, type Matrix4 } from 'three';
+import { Vector2, Vector3, Vector4, Box3, Matrix3, type Matrix4 } from 'three';
import Coordinates from './Coordinates';
import * as CRS from './Crs';
@@ -288,7 +288,7 @@ class Extent {
this.planarDimensions(_dim2);
const originX = (this.west - extent.west) / _dim.x;
- const originY = (extent.north - this.north) / _dim.y;
+ const originY = (this.south - extent.south) / _dim.y;
const scaleX = _dim2.x / _dim.x;
const scaleY = _dim2.y / _dim.y;
@@ -296,6 +296,13 @@ class Extent {
return target.set(originX, originY, scaleX, scaleY);
}
+ transformToParent(extent: Extent, target = new Matrix3()) {
+ const { x: ox, y: oy, z: sx, w: sy } = this.offsetToParent(extent);
+
+ return target.setUvTransform(ox, oy, sx, sy, 0, 0, 0);
+ }
+
+
/**
* Checks wheter this bounding box intersects with the given extent
* parameter.
diff --git a/packages/Main/src/Converter/convertToTile.ts b/packages/Main/src/Converter/convertToTile.ts
index 46adb7af18..7f0ae1ad75 100644
--- a/packages/Main/src/Converter/convertToTile.ts
+++ b/packages/Main/src/Converter/convertToTile.ts
@@ -47,38 +47,57 @@ export default {
hideSkirt: layer.hideSkirt,
};
- return newTileGeometry(builder, paramsGeometry).then((result) => {
- // build tile mesh
- result.geometry.increaseRefCount();
- const crsCount = layer.tileMatrixSets.length;
- const material = new LayeredMaterial(layer.materialOptions, crsCount);
- ReferLayerProperties(material, layer);
-
- const tile = new TileMesh(result.geometry, material, layer, extent, level);
-
- if (parent && parent.isTileMesh) {
- // get parent extent transformation
- const pTrans = builder.computeShareableExtent(parent.extent);
- // place relative to his parent
- result.position.sub(pTrans.position).applyQuaternion(pTrans.quaternion.invert());
- result.quaternion.premultiply(pTrans.quaternion);
- }
+ const { geometry, quaternion, position } = newTileGeometry(builder, paramsGeometry);
+ // build tile mesh
+ geometry.increaseRefCount();
+ const crsCount = layer.tileMatrixSets.length;
+ const material = new LayeredMaterial(layer.materialOptions, crsCount);
+ ReferLayerProperties(material, layer);
+
+ const tile = new TileMesh(geometry, material, layer, extent, level);
+
+ if (parent && parent.isTileMesh) {
+ // get parent extent transformation
+ const pTrans = builder.computeShareableExtent(parent.extent);
+ // place relative to his parent
+ position.sub(pTrans.position).applyQuaternion(pTrans.quaternion.invert());
+ quaternion.premultiply(pTrans.quaternion);
+ }
+
+ tile.position.copy(position);
+ tile.quaternion.copy(quaternion);
+ tile.visible = false;
+ tile.updateMatrix();
- tile.position.copy(result.position);
- tile.quaternion.copy(result.quaternion);
- tile.visible = false;
- tile.updateMatrix();
+ setTileFromTiledLayer(tile, layer);
- setTileFromTiledLayer(tile, layer);
+ if (parent) {
+ tile.geoidHeight = parent.geoidHeight;
+ const geoidHeight = geoidLayerIsVisible(layer) ? tile.geoidHeight : 0;
+ tile.material.setUniform('geoidHeight', geoidHeight);
- if (parent) {
- tile.geoidHeight = parent.geoidHeight;
- const geoidHeight = geoidLayerIsVisible(layer) ? tile.geoidHeight : 0;
+ const parent_uniforms = parent.material.uniforms;
+ const child_uniforms = tile.material.uniforms;
+
+ if (parent.material.uniforms.map.value) {
+ const extentParent = parent_uniforms.map.value.extent;
+ child_uniforms.map.value = parent_uniforms.map.value;
+ tile.extent.transformToParent(extentParent, child_uniforms.mapTransform.value);
+ }
+
+ if (parent_uniforms.displacementMap.value) {
+ const extentParent = parent_uniforms.displacementMap.value.extent.toExtent(tile.extent.crs);
+ child_uniforms.displacementMap.value = parent_uniforms.displacementMap.value;
+ tile.extent.transformToParent(extentParent, child_uniforms.displacementMapTransform.value);
+ const rasterElevationNode = parent_uniforms.elevationLayer.value;
+ child_uniforms.elevationLayer.value = rasterElevationNode;
+ tile.setBBoxZ({ min: rasterElevationNode.min, max: rasterElevationNode.max, scale: rasterElevationNode.layer.scale, geoidHeight });
+ } else {
tile.setBBoxZ({ min: parent.obb.z.min, max: parent.obb.z.max, geoidHeight });
- tile.material.setUniform('geoidHeight', geoidHeight);
}
+ }
+
- return tile;
- });
+ return tile;
},
};
diff --git a/packages/Main/src/Core/Prefab/Globe/GlobeLayer.js b/packages/Main/src/Core/Prefab/Globe/GlobeLayer.js
index 02123e2495..bb706eb020 100644
--- a/packages/Main/src/Core/Prefab/Globe/GlobeLayer.js
+++ b/packages/Main/src/Core/Prefab/Globe/GlobeLayer.js
@@ -53,8 +53,7 @@ class GlobeLayer extends TiledGeometryLayer {
'EPSG:3857',
];
- const uvCount = tileMatrixSets.length;
- const builder = new GlobeTileBuilder({ uvCount });
+ const builder = new GlobeTileBuilder();
super(id, object3d || new THREE.Group(), schemeTile, builder, {
tileMatrixSets,
@@ -112,7 +111,7 @@ class GlobeLayer extends TiledGeometryLayer {
return super.preUpdate(context, changeSources);
}
- subdivision(context, layer, node) {
+ subdivision(context, node) {
if (node.level == 5) {
const row = node.getExtentsByProjection('EPSG:4326')[0].row;
if (row == 31 || row == 0) {
@@ -120,7 +119,7 @@ class GlobeLayer extends TiledGeometryLayer {
return false;
}
}
- return super.subdivision(context, layer, node);
+ return super.subdivision(context, node);
}
culling(node, camera) {
diff --git a/packages/Main/src/Core/Prefab/Globe/GlobeTileBuilder.ts b/packages/Main/src/Core/Prefab/Globe/GlobeTileBuilder.ts
index d67e2756c1..7f212b27ea 100644
--- a/packages/Main/src/Core/Prefab/Globe/GlobeTileBuilder.ts
+++ b/packages/Main/src/Core/Prefab/Globe/GlobeTileBuilder.ts
@@ -6,26 +6,13 @@ import {
TileBuilderParams,
} from '../TileBuilder';
-const PI_OV_FOUR = Math.PI / 4;
-const INV_TWO_PI = 1.0 / (Math.PI * 2);
const axisZ = new THREE.Vector3(0, 0, 1);
const axisY = new THREE.Vector3(0, 1, 0);
const quatToAlignLongitude = new THREE.Quaternion();
const quatToAlignLatitude = new THREE.Quaternion();
const quatNormalToZ = new THREE.Quaternion();
-/**
- * Transforms a WGS84 latitude into a usable texture offset.
- * @param latitude
- * @returns
- */
-function WGS84ToOneSubY(latitude: number): number {
- return 1.0 - (0.5 - Math.log(Math.tan(
- PI_OV_FOUR + THREE.MathUtils.degToRad(latitude) * 0.5,
- )) * INV_TWO_PI);
-}
-
-interface Transform {
+type Transform = {
/** Buffers for 2-part coordinate mapping operations. */
coords: [Coordinates, Coordinates];
position: THREE.Vector3;
@@ -36,8 +23,6 @@ interface Transform {
export interface GlobeTileBuilderParams extends TileBuilderParams {
/** Number of rows of tiles, essentially the resolution of the globe. */
nbRow: number;
- /** Offset of the second texture set. */
- deltaUV1: number;
/** Transformation to align a tile's normal to the Z axis. */
quatNormalToZ: THREE.Quaternion;
}
@@ -48,11 +33,7 @@ export interface GlobeTileBuilderParams extends TileBuilderParams {
*/
export class GlobeTileBuilder
implements TileBuilder {
- private static _crs = 'EPSG:4978';
- private static _computeExtraOffset(params: GlobeTileBuilderParams): number {
- const t = WGS84ToOneSubY(params.coordinates.latitude) * params.nbRow;
- return (!isFinite(t) ? 0 : t) - params.deltaUV1;
- }
+ private static _crs: string = 'EPSG:4978';
/**
* Buffer holding information about the tile/vertex currently being
@@ -60,16 +41,11 @@ implements TileBuilder {
*/
private _transform: Transform;
- public computeExtraOffset?: (params: GlobeTileBuilderParams) => number;
-
public get crs(): string {
return GlobeTileBuilder._crs;
}
- public constructor(options: {
- /** Number of unaligned texture sets. */
- uvCount: number;
- }) {
+ public constructor() {
this._transform = {
coords: [
new Coordinates('EPSG:4326', 0, 0),
@@ -78,29 +54,13 @@ implements TileBuilder {
position: new THREE.Vector3(),
dimension: new THREE.Vector2(),
};
-
- // UV: Normalized coordinates (from degree) on the entire tile
- // EPSG:4326
- // Offset: Float row coordinate from Pseudo mercator coordinates
- // EPSG:3857
- if (options.uvCount > 1) {
- this.computeExtraOffset = GlobeTileBuilder._computeExtraOffset;
- }
}
public prepare(params: TileBuilderParams): GlobeTileBuilderParams {
const nbRow = 2 ** (params.level + 1.0);
- let st1 = WGS84ToOneSubY(params.extent.south);
-
- if (!isFinite(st1)) { st1 = 0; }
-
- const sizeTexture = 1.0 / nbRow;
-
- const start = (st1 % (sizeTexture));
const newParams = {
nbRow,
- deltaUV1: (st1 - start) * nbRow,
// transformation to align tile's normal to z axis
quatNormalToZ: quatNormalToZ.setFromAxisAngle(
axisY,
diff --git a/packages/Main/src/Core/Prefab/Planar/PlanarTileBuilder.ts b/packages/Main/src/Core/Prefab/Planar/PlanarTileBuilder.ts
index 8cadb6acd4..8ec632e650 100644
--- a/packages/Main/src/Core/Prefab/Planar/PlanarTileBuilder.ts
+++ b/packages/Main/src/Core/Prefab/Planar/PlanarTileBuilder.ts
@@ -17,7 +17,6 @@ interface Transform {
/** Specialized parameters for the [PlanarTileBuilder]. */
export interface PlanarTileBuilderParams extends TileBuilderParams {
- uvCount?: number;
nbRow: number;
}
@@ -26,14 +25,12 @@ export interface PlanarTileBuilderParams extends TileBuilderParams {
* tile arrangements.
*/
export class PlanarTileBuilder implements TileBuilder {
- private _uvCount: number;
private _transform: Transform;
private _crs: string;
public constructor(options: {
projection?: string;
crs: string;
- uvCount?: number;
}) {
if (options.projection) {
console.warn('PlanarTileBuilder projection parameter is deprecated,'
@@ -48,12 +45,6 @@ export class PlanarTileBuilder implements TileBuilder {
position: new THREE.Vector3(),
normal: new THREE.Vector3(0, 0, 1),
};
-
- this._uvCount = options.uvCount ?? 1;
- }
-
- public get uvCount(): number {
- return this._uvCount;
}
public get crs(): string {
diff --git a/packages/Main/src/Core/Prefab/TileBuilder.ts b/packages/Main/src/Core/Prefab/TileBuilder.ts
index c5e65097b5..a2bfafec09 100644
--- a/packages/Main/src/Core/Prefab/TileBuilder.ts
+++ b/packages/Main/src/Core/Prefab/TileBuilder.ts
@@ -10,14 +10,14 @@ const cacheBuffer = new Map();
-const cacheTile = new LRUCache>({ max: 500 });
+const cacheTile = new LRUCache({ max: 500 });
export interface GpuBufferAttributes {
index: THREE.BufferAttribute | null;
position: THREE.BufferAttribute;
normal: THREE.BufferAttribute;
- uvs: THREE.BufferAttribute[];
-}
+ uv: THREE.BufferAttribute | null;
+};
/**
* Reference to a tile's extent with rigid transformations.
@@ -89,35 +89,27 @@ export function newTileGeometry(
`${builder.crs}_${params.disableSkirt ? 0 : 1}_${params.segments}`;
const key = `s${south}l${params.level}bK${bufferKey}`;
- let promiseGeometry = cacheTile.get(key);
+ let geometry = cacheTile.get(key);
// build geometry if doesn't exist
- if (!promiseGeometry) {
- let resolve: ((value: TileGeometry) => void) | undefined;
- promiseGeometry = new Promise((r) => { resolve = r; });
- cacheTile.set(key, promiseGeometry);
-
+ if (!geometry) {
params.extent = shareableExtent;
const center = builder.center(params.extent).clone();
// Read previously cached values (index and uv.wgs84 only
// depend on the # of triangles)
let cachedBuffers = cacheBuffer.get(bufferKey);
- let buffers;
- try {
- buffers = computeBuffers(
- builder,
- { ...params, center },
- cachedBuffers !== undefined
- ? {
- index: cachedBuffers.index.array as UintArray,
- uv: cachedBuffers.uv.array as Float32Array,
- }
- : undefined,
- );
- } catch (e) {
- return Promise.reject(e);
- }
+ const buffers = computeBuffers(
+ builder,
+ { ...params, center },
+ cachedBuffers !== undefined
+ ? {
+ index: cachedBuffers.index.array as
+ Uint8Array | Uint16Array | Uint32Array,
+ uv: cachedBuffers.uv.array as Float32Array,
+ }
+ : undefined,
+ );
if (!cachedBuffers) {
// We know the fields will exist due to the condition
@@ -125,8 +117,8 @@ export function newTileGeometry(
// TODO: Make this brain-based check compiler-based.
cachedBuffers = {
- index: new THREE.BufferAttribute(buffers.index as UintArray, 1),
- uv: new THREE.BufferAttribute(buffers.uvs[0] as Float32Array, 2),
+ index: new THREE.BufferAttribute(buffers.index!, 1),
+ uv: new THREE.BufferAttribute(buffers.uv!, 2),
};
// Update cacheBuffer
@@ -135,26 +127,20 @@ export function newTileGeometry(
const gpuBuffers: GpuBufferAttributes = {
index: cachedBuffers.index,
- uvs: [
- cachedBuffers.uv,
- ...(buffers.uvs[1] !== undefined
- ? [new THREE.BufferAttribute(buffers.uvs[1], 1)]
- : []
- ),
- ],
+ uv: cachedBuffers.uv,
position: new THREE.BufferAttribute(buffers.position, 3),
normal: new THREE.BufferAttribute(buffers.normal, 3),
};
- const geometry = new TileGeometry(builder, params, gpuBuffers);
- const bbox = geometry.boundingBox as THREE.Box3;
- geometry.OBB = new OBB(bbox.min, bbox.max);
+ geometry = new TileGeometry(builder, params, gpuBuffers);
+ geometry.OBB =
+ new OBB(geometry.boundingBox.min, geometry.boundingBox.max);
geometry.initRefCount(cacheTile, key);
- (resolve as (value: TileGeometry) => void)(geometry);
- return Promise.resolve({ geometry, quaternion, position });
+ cacheTile.set(key, geometry);
+
+ return { geometry, quaternion, position };
}
- return (promiseGeometry as Promise)
- .then(geometry => ({ geometry, quaternion, position }));
+ return { geometry, quaternion, position };
}
diff --git a/packages/Main/src/Core/Prefab/computeBufferTileGeometry.ts b/packages/Main/src/Core/Prefab/computeBufferTileGeometry.ts
index f2fde07fd5..37aba4ea9b 100644
--- a/packages/Main/src/Core/Prefab/computeBufferTileGeometry.ts
+++ b/packages/Main/src/Core/Prefab/computeBufferTileGeometry.ts
@@ -15,10 +15,8 @@ export interface Buffers {
index: IndexArray;
position: Float32Array;
normal: Float32Array;
- uvs: [Option, Option];
-}
-
-type UintArray = Uint8Array | Uint16Array | Uint32Array;
+ uv: Float32Array;
+};
type BuffersAndSkirt = Buffers & {
skirt: IndexArray;
@@ -98,28 +96,7 @@ function allocateBuffers(
skirt,
position: new Float32Array(nVertex * 3),
normal: new Float32Array(nVertex * 3),
- // 2 UV set per tile: wgs84 (uv[0]) and pseudo-mercator (pm, uv[1])
- // - wgs84: 1 texture per tile because tiles are using wgs84
- // projection
- // - pm: use multiple textures per tile.
- // +-------------------------+
- // | |
- // | Texture 0 |
- // +-------------------------+
- // | |
- // | Texture 1 |
- // +-------------------------+
- // | |
- // | Texture 2 |
- // +-------------------------+
- // * u = wgs84.u
- // * v = textureid + v in builder texture
- uvs: [
- cache?.uv ?? new Float32Array(nVertex * 2),
- builder.computeExtraOffset !== undefined
- ? new Float32Array(nVertex)
- : undefined,
- ],
+ uv: cache?.uv ?? new Float32Array(nVertex * 2),
};
}
@@ -128,12 +105,7 @@ function computeUv0(uv: Float32Array, id: number, u: number, v: number): void {
uv[id * 2 + 1] = v;
}
-function initComputeUv1(value: number): (uv: Float32Array, id: number) => void {
- return (uv: Float32Array, id: number): void => { uv[id] = value; };
-}
-
-type ComputeUvs =
- [typeof computeUv0 | (() => void), ReturnType?];
+type ComputeUvs = typeof computeUv0;
interface ComputeBuffersParams extends TileBuilderPrepareParams {
center: THREE.Vector3;
@@ -180,8 +152,7 @@ export function computeBuffers(
cache,
);
- const computeUvs: ComputeUvs =
- [cache === undefined ? computeUv0 : () => { }];
+ const computeUv: ComputeUvs = cache === undefined ? computeUv0 : () => { };
const preparedParams = builder.prepare(params);
@@ -190,12 +161,6 @@ export function computeBuffers(
preparedParams.coordinates.y = builder.vProject(v, params.extent);
- if (builder.computeExtraOffset !== undefined) {
- computeUvs[1] = initComputeUv1(
- builder.computeExtraOffset(preparedParams) as number,
- );
- }
-
for (let x = 0; x <= nSeg; x++) {
const u = x / nSeg;
const id_m3 = (y * nVertex + x) * 3;
@@ -219,12 +184,7 @@ export function computeBuffers(
vertex.toArray(outBuffers.position, id_m3);
normal.toArray(outBuffers.normal, id_m3);
-
- for (const [index, computeUv] of computeUvs.entries()) {
- if (computeUv !== undefined) {
- computeUv(outBuffers.uvs[index] as Float32Array, y * nVertex + x, u, v);
- }
- }
+ computeUv(outBuffers.uv, y * nVertex + x, u, v);
}
}
@@ -342,11 +302,7 @@ export function computeBuffers(
outBuffers.normal[id_m3 + 1] = outBuffers.normal[id2_m3 + 1];
outBuffers.normal[id_m3 + 2] = outBuffers.normal[id2_m3 + 2];
- buildSkirt.uv(outBuffers.uvs[0], start + i, id);
-
- if (outBuffers.uvs[1] !== undefined) {
- outBuffers.uvs[1][start + i] = outBuffers.uvs[1][id];
- }
+ buildSkirt.uv(outBuffers.uv, start + i, id);
const idf = (i + 1) % skirt.length;
@@ -363,7 +319,7 @@ export function computeBuffers(
return {
index: outBuffers.index,
position: outBuffers.position,
- uvs: outBuffers.uvs,
+ uv: outBuffers.uv,
normal: outBuffers.normal,
};
}
diff --git a/packages/Main/src/Core/Scheduler/Scheduler.js b/packages/Main/src/Core/Scheduler/Scheduler.js
index 0154025972..a043d5ea98 100644
--- a/packages/Main/src/Core/Scheduler/Scheduler.js
+++ b/packages/Main/src/Core/Scheduler/Scheduler.js
@@ -6,7 +6,6 @@
import PriorityQueue from 'js-priority-queue';
import DataSourceProvider from 'Provider/DataSourceProvider';
-import TileProvider from 'Provider/TileProvider';
import $3dTilesProvider from 'Provider/3dTilesProvider';
import PointCloudProvider from 'Provider/PointCloudProvider';
import URLBuilder from 'Provider/URLBuilder';
@@ -128,7 +127,6 @@ Scheduler.prototype.constructor = Scheduler;
Scheduler.prototype.initDefaultProviders = function initDefaultProviders() {
// Register all providers
- this.addProtocolProvider('tile', TileProvider);
this.addProtocolProvider('3d-tiles', $3dTilesProvider);
this.addProtocolProvider('pointcloud', PointCloudProvider);
};
@@ -239,7 +237,7 @@ Scheduler.prototype.execute = function execute(command) {
* @returns {Promise} The {@link Scheduler} always expect a Promise as a result,
* resolving to an object containing sufficient information for the associated
* processing to the current layer. For example, see the
- * [LayeredMaterialNodeProcessing#updateLayeredMaterialNodeElevation]{@link
+ * [LayeredMaterialNodeProcessing#updateRasterTile]{@link
* https://github.com/iTowns/itowns/blob/master/src/Process/LayeredMaterialNodeProcessing.js}
* class or other processing class.
*/
diff --git a/packages/Main/src/Core/Tile/Tile.ts b/packages/Main/src/Core/Tile/Tile.ts
index 143dac99c0..4b43817c02 100644
--- a/packages/Main/src/Core/Tile/Tile.ts
+++ b/packages/Main/src/Core/Tile/Tile.ts
@@ -99,8 +99,7 @@ class Tile {
}
/**
- * Returns the translation and scale to transform this tile to the input
- * tile.
+ * Returns UV transform values to map this tile in the input tile.
*
* @param tile - the input tile.
* @param target - copy the result to target.
@@ -112,12 +111,19 @@ class Tile {
}
const r = _rowColfromParent(this, tile.zoom);
+ const offsetX = this.col * r.invDiff - r.col;
+ const offsetY = 1 - r.invDiff - (this.row * r.invDiff - r.row);
return target.set(
- this.col * r.invDiff - r.col,
- this.row * r.invDiff - r.row,
+ offsetX,
+ offsetY,
r.invDiff, r.invDiff);
}
+ transformToParent(tile: Tile, target = new THREE.Matrix3()) {
+ const { x: ox, y: oy, z: sx, w: sy } = this.offsetToParent(tile);
+ return target.setUvTransform(ox, oy, sx, sy, 0, 0, 0);
+ }
+
/**
* Returns the parent tile at the given level.
*
diff --git a/packages/Main/src/Core/TileGeometry.ts b/packages/Main/src/Core/TileGeometry.ts
index bf18e3693f..c7f9627a87 100644
--- a/packages/Main/src/Core/TileGeometry.ts
+++ b/packages/Main/src/Core/TileGeometry.ts
@@ -33,15 +33,9 @@ function defaultBuffers(
index: buffers.index
? new THREE.BufferAttribute(buffers.index, 1)
: null,
- uvs: [
- ...(buffers.uvs[0]
- ? [new THREE.BufferAttribute(buffers.uvs[0], 2)]
- : []
- ),
- ...(buffers.uvs[1]
- ? [new THREE.BufferAttribute(buffers.uvs[1], 1)]
- : []),
- ],
+ uv: buffers.uv
+ ? new THREE.BufferAttribute(buffers.uv, 2)
+ : null,
position: new THREE.BufferAttribute(buffers.position, 3),
normal: new THREE.BufferAttribute(buffers.normal, 3),
};
@@ -57,6 +51,8 @@ export class TileGeometry extends THREE.BufferGeometry {
/** Resolution of the tile geometry in segments per side. */
public segments: number;
+ public boundingBox: THREE.Box3;
+
/**
* [TileGeometry] instances are shared between tiles. Since a geometry
* handles its own GPU resource, it needs a reference counter to dispose of
@@ -81,12 +77,11 @@ export class TileGeometry extends THREE.BufferGeometry {
this.setIndex(bufferAttributes.index);
this.setAttribute('position', bufferAttributes.position);
this.setAttribute('normal', bufferAttributes.normal);
- this.setAttribute('uv', bufferAttributes.uvs[0]);
-
- for (let i = 1; i < bufferAttributes.uvs.length; i++) {
- this.setAttribute(`uv_${i}`, bufferAttributes.uvs[i]);
+ if (bufferAttributes.uv) {
+ this.setAttribute('uv', bufferAttributes.uv);
}
+ this.boundingBox = new THREE.Box3();
this.computeBoundingBox();
this.OBB = null;
this.hideSkirt = params.hideSkirt ?? false;
@@ -110,7 +105,7 @@ export class TileGeometry extends THREE.BufferGeometry {
* @param key - The [south, level, epsg] key of this geometry.
*/
public initRefCount(
- cacheTile: LRUCache>,
+ cacheTile: LRUCache,
key: string,
): void {
if (this._refCount !== null) {
diff --git a/packages/Main/src/Core/TileMesh.ts b/packages/Main/src/Core/TileMesh.ts
index 33aa931a56..ded043a33f 100644
--- a/packages/Main/src/Core/TileMesh.ts
+++ b/packages/Main/src/Core/TileMesh.ts
@@ -161,9 +161,7 @@ class TileMesh extends THREE.Mesh {
* @param renderer - The renderer used to render textures.
*/
override onBeforeRender(renderer: THREE.WebGLRenderer) {
- if (this.material.layersNeedUpdate) {
- this.material.updateLayersUniforms(renderer);
- }
+ this.material.updateLayersUniforms(renderer, this.extent);
// Track actual usage every time this mesh is rendered
// Use global current rendering view ID set by MainLoop
diff --git a/packages/Main/src/Layer/ColorLayer.js b/packages/Main/src/Layer/ColorLayer.js
index da56d87873..4b3f4e8ecf 100644
--- a/packages/Main/src/Layer/ColorLayer.js
+++ b/packages/Main/src/Layer/ColorLayer.js
@@ -1,5 +1,4 @@
import RasterLayer from 'Layer/RasterLayer';
-import { updateLayeredMaterialNodeImagery } from 'Process/LayeredMaterialNodeProcessing';
import { RasterColorTile } from 'Renderer/RasterTile';
import { deprecatedColorLayerOptions } from 'Core/Deprecated/Undeprecator';
import Style from 'Core/Style';
@@ -164,7 +163,9 @@ class ColorLayer extends RasterLayer {
* @returns {RasterColorTile} The raster color node added.
*/
setupRasterNode(node) {
- const rasterColorTile = new RasterColorTile(this);
+ const tiles = node.getExtentsByProjection(this.crs);
+
+ const rasterColorTile = new RasterColorTile(this, tiles);
node.material.addColorTile(rasterColorTile);
// set up ColorLayer ordering.
@@ -172,10 +173,6 @@ class ColorLayer extends RasterLayer {
return rasterColorTile;
}
-
- update(context, layer, node, parent) {
- return updateLayeredMaterialNodeImagery(context, this, node, parent);
- }
}
export default ColorLayer;
diff --git a/packages/Main/src/Layer/ElevationLayer.js b/packages/Main/src/Layer/ElevationLayer.js
index 276f36966b..0beef2d197 100644
--- a/packages/Main/src/Layer/ElevationLayer.js
+++ b/packages/Main/src/Layer/ElevationLayer.js
@@ -1,5 +1,4 @@
import RasterLayer from 'Layer/RasterLayer';
-import { updateLayeredMaterialNodeElevation } from 'Process/LayeredMaterialNodeProcessing';
import { RasterElevationTile } from 'Renderer/RasterTile';
/**
@@ -115,7 +114,9 @@ class ElevationLayer extends RasterLayer {
* @returns {RasterElevationTile} The raster elevation node added.
*/
setupRasterNode(node) {
- const rasterElevationNode = new RasterElevationTile(this);
+ const tiles = node.getExtentsByProjection(this.crs);
+
+ const rasterElevationNode = new RasterElevationTile(this, tiles);
node.material.setElevationTile(rasterElevationNode);
node.material.setElevationTileId(this.id);
@@ -123,7 +124,6 @@ class ElevationLayer extends RasterLayer {
const updateBBox = () => node.setBBoxZ({
min: rasterElevationNode.min, max: rasterElevationNode.max, scale: this.scale,
});
- updateBBox();
// listen elevation updating
rasterElevationNode.addEventListener('rasterElevationLevelChanged', updateBBox);
@@ -138,8 +138,20 @@ class ElevationLayer extends RasterLayer {
return rasterElevationNode;
}
- update(context, layer, node, parent) {
- return updateLayeredMaterialNodeElevation(context, this, node, parent);
+ getRasterTile(node) {
+ return node.material.getElevationTile();
+ }
+
+ /**
+ * Compares source zoom ranges to detect whether the new source can provide
+ * more precise data than the source currently attached to this tile.
+ * If so, the raster tile is recreated to reload elevation with finer detail.
+ *
+ * @param {RasterElevationTile} rasterTile - Existing elevation raster tile on the node.
+ * @returns {boolean} `true` when the new source is more precise and tile reload is required.
+ */
+ overloadRasterTile(rasterTile) {
+ return this.source.zoom.min > rasterTile.layer.source.zoom.max;
}
}
diff --git a/packages/Main/src/Layer/Layer.js b/packages/Main/src/Layer/Layer.js
index 08a0313d75..235638fa6a 100644
--- a/packages/Main/src/Layer/Layer.js
+++ b/packages/Main/src/Layer/Layer.js
@@ -254,17 +254,19 @@ class Layer extends THREE.EventDispatcher {
}
getData(from, to) {
- const key = this.source.getDataKey(this.source.isVectorSource ? to : from);
- let data = this.cache.get(key);
- if (!data) {
- data = this.source.loadData(from, this)
- .then(feat => this.convert(feat, to))
- .catch((err) => {
- this.source.handlingError(err);
- });
- this.cache.set(key, data);
+ if (from) {
+ const key = this.source.getDataKey(this.source.isVectorSource ? to : from);
+ let data = this.cache.get(key);
+ if (!data) {
+ data = this.source.loadData(from, this)
+ .then(feat => this.convert(feat, to))
+ .catch((err) => {
+ this.source.handlingError(err);
+ });
+ this.cache.set(key, data);
+ }
+ return data;
}
- return data;
}
/**
diff --git a/packages/Main/src/Layer/LayerUpdateStrategy.ts b/packages/Main/src/Layer/LayerUpdateStrategy.ts
index 34a1fc9c62..f62c257cde 100644
--- a/packages/Main/src/Layer/LayerUpdateStrategy.ts
+++ b/packages/Main/src/Layer/LayerUpdateStrategy.ts
@@ -1,4 +1,4 @@
-import { EMPTY_TEXTURE_ZOOM } from 'Renderer/RasterTile';
+import { EMPTY_TEXTURE_ZOOM, type RasterTile } from 'Renderer/RasterTile';
/**
* This modules implements various layer update strategies.
*
@@ -112,3 +112,17 @@ export function chooseNextLevelToFetch(
}
return nextLevelToFetch;
}
+
+export const nextLevelToFetch = (t: RasterTile) => {
+ const zoom = {
+ min: Math.max(t.layer.zoom.min, t.layer.source.zoom?.min),
+ max: Math.min(t.layer.zoom.max, t.layer.source.zoom?.max),
+ };
+ return chooseNextLevelToFetch(
+ t.layer.updateStrategy,
+ t.tiles[0].zoom,
+ t.level,
+ t.state.failureParams,
+ zoom,
+ );
+};
diff --git a/packages/Main/src/Layer/RasterLayer.js b/packages/Main/src/Layer/RasterLayer.js
index 75c93002ff..2bdfe199bf 100644
--- a/packages/Main/src/Layer/RasterLayer.js
+++ b/packages/Main/src/Layer/RasterLayer.js
@@ -1,9 +1,25 @@
import Layer from 'Layer/Layer';
import { STRATEGY_MIN_NETWORK_TRAFFIC } from 'Layer/LayerUpdateStrategy';
-import { removeLayeredMaterialNodeTile } from 'Process/LayeredMaterialNodeProcessing';
import textureConverter from 'Converter/textureConverter';
import { CACHE_POLICIES } from 'Core/Scheduler/Cache';
+export function removeLayeredMaterialNodeTile(tileId) {
+ /**
+ * @param {TileMesh} node - The node to udpate.
+ */
+ return function removeLayeredMaterialNodeTile(node) {
+ if (node.material?.removeTile) {
+ if (node.material.elevationTile !== undefined) {
+ node.setBBoxZ({ min: 0, max: 0 });
+ }
+ node.material.removeTile(tileId);
+ }
+ if (node.layerUpdateState && node.layerUpdateState[tileId]) {
+ delete node.layerUpdateState[tileId];
+ }
+ };
+}
+
class RasterLayer extends Layer {
constructor(id, config) {
const {
@@ -19,6 +35,7 @@ class RasterLayer extends Layer {
cacheLifeTime,
});
+ this.visible = true;
this.minFilter = minFilter;
this.magFilter = magFilter;
@@ -44,6 +61,61 @@ class RasterLayer extends Layer {
root.traverse(removeLayeredMaterialNodeTile(this.id));
}
}
+
+ hasData(node) {
+ const minZoom = Math.max(this.source.zoom.min, this.zoom.min);
+
+ const tiles = node.getExtentsByProjection(this.crs)
+ .map(e => e.tiledExtentParent(minZoom));
+
+ return tiles.some(e => e.zoom >= minZoom && this.source.hasData(e));
+ }
+
+ /**
+ * Indicates whether an existing raster tile must be recreated.
+ * Subclasses can override this to force rebuilding tiles based on tile state.
+ *
+ * @param {RasterTile} rasterTile - Current raster tile attached to the node.
+ * @returns {boolean} `true` to recreate the raster tile, `false` to keep it.
+ */
+ // eslint-disable-next-line no-unused-vars
+ overloadRasterTile(rasterTile) {
+ return false;
+ }
+
+ /**
+ * Returns the raster tile associated with this layer for a given node.
+ *
+ * @param {TileMesh} node - The tile mesh carrying layered material tiles.
+ * @returns {?RasterTile} The matching raster tile, or `undefined` when none exists.
+ */
+ getRasterTile(node) {
+ return node.material.getTile(this.id);
+ }
+
+ /**
+ * Updates raster data for a node if the layer is active and data is available.
+ * Creates or recreates the raster tile when needed, then triggers loading.
+ *
+ * @param {object} context - Update context.
+ * @param {View} context.view - Active view used to schedule loading.
+ * @param {RasterLayer} layer - Current raster layer.
+ * @param {TileMesh} node - Tile node to update.
+ * @returns {Promise|undefined} A loading promise when an update is scheduled.
+ */
+ update(context, layer, node) {
+ if (layer.visible && !layer.freeze && this.hasData(node)) {
+ let rasterTile = this.getRasterTile(node);
+
+ if (!rasterTile || this.overloadRasterTile(rasterTile)) {
+ rasterTile = this.setupRasterNode(node);
+ }
+
+ if (rasterTile && (!rasterTile.hasData() || (node.visible && node.material.visible))) {
+ return rasterTile.load(node, context.view);
+ }
+ }
+ }
}
export default RasterLayer;
diff --git a/packages/Main/src/Layer/TiledGeometryLayer.js b/packages/Main/src/Layer/TiledGeometryLayer.js
index 3e19051ad3..89299051a0 100644
--- a/packages/Main/src/Layer/TiledGeometryLayer.js
+++ b/packages/Main/src/Layer/TiledGeometryLayer.js
@@ -313,51 +313,30 @@ class TiledGeometryLayer extends GeometryLayer {
if (!node.parent) {
return ObjectRemovalHelper.removeChildrenAndCleanup(this, node);
}
- // early exit if parent' subdivision is in progress
- if (node.parent.pendingSubdivision) {
- node.visible = false;
- node.material.visible = false;
- this.info.update(node);
- return undefined;
- }
- // do proper culling
node.visible = !this.culling(node, context.camera);
- if (node.visible) {
- let requestChildrenUpdate = false;
-
- node.material.visible = true;
- node.material.layersNeedUpdate = true;
+ if (node.visible && this.subdivision(context, node)) {
+ node.material.visible = false;
this.info.update(node);
- if (node.pendingSubdivision || (TiledGeometryLayer.hasEnoughTexturesToSubdivide(context, node) && this.subdivision(context, this, node))) {
- this.subdivideNode(context, node);
- // display iff children aren't ready
- node.material.visible = node.pendingSubdivision;
- this.info.update(node);
- requestChildrenUpdate = true;
- }
+ return this.subdivideNode(context, node);
+ }
- if (node.material.visible) {
- if (!requestChildrenUpdate) {
- return ObjectRemovalHelper.removeChildren(this, node);
- }
- }
+ node.material.visible = node.visible;
- return requestChildrenUpdate ? node.children.filter(n => n.layer == this) : undefined;
- }
+ // RasterTile.needsUpdate has been removed
+ // TODO: optimize uniforms update
+ node.material.layersNeedUpdate = node.material.visible;
- node.material.visible = false;
this.info.update(node);
return ObjectRemovalHelper.removeChildren(this, node);
}
convert(requester, extent) {
- return convertToTile.convert(requester, extent, this).then((tileMesh) => {
- tileMesh.material.renderTargetCache = this.renderTargetCache;
- return tileMesh;
- });
+ const tileMesh = convertToTile.convert(requester, extent, this);
+ tileMesh.material.renderTargetCache = this.renderTargetCache;
+ return tileMesh;
}
/**
@@ -379,56 +358,6 @@ class TiledGeometryLayer extends GeometryLayer {
return false;
}
- /**
- * Tell if a node has enough elevation or color textures to subdivide.
- * Subdivision is prevented if:
- *
- * - the node is covered by at least one elevation layer and if the node
- * doesn't have an elevation texture yet
- * - a color texture is missing
- *
- *
- * @param {object} context - The context of the update; see the {@link
- * MainLoop} for more informations.
- * @param {TileMesh} node - The node to subdivide.
- *
- * @returns {boolean} False if the node can not be subdivided, true
- * otherwise.
- */
- static hasEnoughTexturesToSubdivide(context, node) {
- const layerUpdateState = node.layerUpdateState || {};
- let nodeLayer = node.material.getElevationTile();
-
- for (const e of context.elevationLayers) {
- const tiles = node.getExtentsByProjection(e.crs);
-
- if (!e.frozen && e.ready && tiles.some(t => e.source.hasData(t)) && (!nodeLayer || nodeLayer.level < 0)) {
- // no stop subdivision in the case of a loading error
- if (layerUpdateState[e.id] && layerUpdateState[e.id].inError()) {
- continue;
- }
- return false;
- }
- }
-
- for (const c of context.colorLayers) {
- if (c.frozen || !c.visible || !c.ready) {
- continue;
- }
- const tiles = node.getExtentsByProjection(c.crs);
-
- // no stop subdivision in the case of a loading error
- if (layerUpdateState[c.id] && layerUpdateState[c.id].inError()) {
- continue;
- }
- nodeLayer = node.material.getColorTile(c.id);
- if (tiles.some(t => c.source.hasData(t)) && (!nodeLayer || nodeLayer.level < 0)) {
- return false;
- }
- }
- return true;
- }
-
/**
* Subdivides a node of this layer. If the node is currently in the process
* of subdivision, it will not do anything here. The subdivision of a node
@@ -442,38 +371,21 @@ class TiledGeometryLayer extends GeometryLayer {
* @param {TileMesh} node - The node to subdivide.
* @returns {Promise} { description_of_the_return_value }
*/
+
subdivideNode(context, node) {
- if (!node.pendingSubdivision && !node.children.some(n => n.layer == this)) {
+ if (node.children.length === 0) {
const extents = node.extent.subdivision();
- // TODO: pendingSubdivision mechanism is fragile, get rid of it
- node.pendingSubdivision = true;
-
- const command = {
- /* mandatory */
- view: context.view,
- requester: node,
- layer: this,
- priority: 10000,
- /* specific params */
- extentsSource: extents,
- redraw: false,
- };
-
- return context.scheduler.execute(command).then((children) => {
- for (const child of children) {
- node.add(child);
- child.updateMatrixWorld(true);
- }
- node.pendingSubdivision = false;
- context.view.notifyChange(node, false);
- }, (err) => {
- node.pendingSubdivision = false;
- if (!err.isCancelledCommandException) {
- throw new Error(err);
- }
+ extents.forEach((extent) => {
+ const child = this.convert(node, extent);
+ node.add(child);
+ child.updateMatrixWorld(true);
});
+ context.view.notifyChange(node, true);
}
+
+
+ return node.children;
}
/**
@@ -481,12 +393,11 @@ class TiledGeometryLayer extends GeometryLayer {
*
* @param {object} context - The context of the update; see the {@link
* MainLoop} for more informations.
- * @param {PlanarLayer} layer - This layer, parameter to be removed.
* @param {TileMesh} node - The node to test.
*
* @returns {boolean} - True if the node is subdivisable, otherwise false.
*/
- subdivision(context, layer, node) {
+ subdivision(context, node) {
if (node.level < this.minSubdivisionLevel) {
return true;
}
@@ -494,15 +405,20 @@ class TiledGeometryLayer extends GeometryLayer {
if (this.maxSubdivisionLevel <= node.level) {
return false;
}
+
+ if (!node.material.dataHasLoaded()) {
+ return false;
+ }
+
+ const camera3D = context.camera.camera3D;
+
subdivisionVector.setFromMatrixScale(node.matrixWorld);
boundingSphereCenter.copy(node.boundingSphere.center).applyMatrix4(node.matrixWorld);
const distance = Math.max(
- 0.0,
- context.camera.camera3D.position.distanceTo(boundingSphereCenter) - node.boundingSphere.radius * subdivisionVector.x);
+ 0.0, camera3D.position.distanceTo(boundingSphereCenter) - node.boundingSphere.radius * subdivisionVector.x);
// Size projection on pixel of bounding
- if (context.camera.camera3D.isOrthographicCamera) {
- const camera3D = context.camera.camera3D;
+ if (camera3D.isOrthographicCamera) {
const preSSE = context.camera._preSSE * 2 * camera3D.zoom / (camera3D.top - camera3D.bottom);
node.screenSize = preSSE * node.boundingSphere.radius * subdivisionVector.x;
} else {
diff --git a/packages/Main/src/Main.js b/packages/Main/src/Main.js
index 5261034d8a..da8fa4df43 100644
--- a/packages/Main/src/Main.js
+++ b/packages/Main/src/Main.js
@@ -16,7 +16,6 @@ export { default as View } from 'Core/View';
export { VIEW_EVENTS } from 'Core/View';
export { default as FeatureProcessing } from 'Process/FeatureProcessing';
export { default as ObjectRemovalHelper } from 'Process/ObjectRemovalHelper';
-export { updateLayeredMaterialNodeImagery, updateLayeredMaterialNodeElevation } from 'Process/LayeredMaterialNodeProcessing';
export { default as OrientedImageCamera } from 'Renderer/OrientedImageCamera';
export { default as PointsMaterial, PNTS_MODE, PNTS_SHAPE, PNTS_SIZE_MODE, ClassificationScheme } from 'Renderer/PointsMaterial';
export { default as GlobeControls } from 'Controls/GlobeControls';
@@ -33,7 +32,7 @@ export { default as FeaturesUtils } from 'Utils/FeaturesUtils';
export { default as DEMUtils } from 'Utils/DEMUtils';
export { default as CameraUtils } from 'Utils/CameraUtils';
export { default as ShaderChunk } from 'Renderer/Shader/ShaderChunk';
-export { getMaxColorSamplerUnitsCount, colorLayerEffects } from 'Renderer/LayeredMaterial';
+export { colorLayerEffects } from 'Renderer/LayeredMaterial';
export { default as Capabilities } from 'Core/System/Capabilities';
export { CAMERA_TYPE } from 'Renderer/Camera';
export { default as OBB } from 'Renderer/OBB';
diff --git a/packages/Main/src/Parser/XbilParser.js b/packages/Main/src/Parser/XbilParser.js
index 5be413206b..5f2bb7fdb2 100644
--- a/packages/Main/src/Parser/XbilParser.js
+++ b/packages/Main/src/Parser/XbilParser.js
@@ -1,9 +1,9 @@
import { readTextureValueWithBilinearFiltering } from 'Utils/DEMUtils';
function minMax4Corners(texture, pitch, options) {
- const u = pitch.x;
- const v = pitch.y;
- const w = pitch.z;
+ const u = pitch.elements[6];
+ const v = pitch.elements[7];
+ const w = pitch.elements[0];
const z = [
readTextureValueWithBilinearFiltering(options, texture, u, v),
readTextureValueWithBilinearFiltering(options, texture, u + w, v),
@@ -25,7 +25,7 @@ function minMax4Corners(texture, pitch, options) {
* Calculates the minimum maximum texture elevation with xbil data
*
* @param {THREE.Texture} texture The texture to parse
- * @param {THREE.Vector4} pitch The pitch, restrict zone to parse
+ * @param {THREE.Matrix3} pitch The pitch, restrict zone to parse
* @param {object} options No data value and clamp values
* @param {number} options.noDataValue No data value
* @param {number} [options.zmin] The minimum elevation value after which it will be clamped
@@ -44,12 +44,12 @@ export function computeMinMaxElevation(texture, pitch, options) {
// compute the minimum and maximum elevation on the 4 corners texture.
let { min, max } = minMax4Corners(texture, pitch, options);
- const sizeX = Math.floor(pitch.z * width);
+ const sizeX = Math.floor(pitch.elements[0] * width);
if (sizeX > 2) {
- const sizeY = Math.floor(pitch.z * height);
- const xs = Math.floor(pitch.x * width);
- const ys = Math.floor(pitch.y * height);
+ const sizeY = Math.floor(pitch.elements[4] * height);
+ const xs = Math.floor(pitch.elements[6] * width);
+ const ys = Math.floor(pitch.elements[7] * height);
const inc = Math.max(Math.floor(sizeX / 32), 2);
const limX = ys + sizeY;
for (let y = ys; y < limX; y += inc) {
diff --git a/packages/Main/src/Process/LayeredMaterialNodeProcessing.js b/packages/Main/src/Process/LayeredMaterialNodeProcessing.js
deleted file mode 100644
index a7684c8a43..0000000000
--- a/packages/Main/src/Process/LayeredMaterialNodeProcessing.js
+++ /dev/null
@@ -1,262 +0,0 @@
-import { chooseNextLevelToFetch } from 'Layer/LayerUpdateStrategy';
-import LayerUpdateState from 'Layer/LayerUpdateState';
-import handlingError from 'Process/handlerNodeError';
-
-function materialCommandQueuePriorityFunction(material) {
- // We know that 'node' is visible because commands can only be
- // issued for visible nodes.
- // TODO: need priorization of displayed nodes
- // Then prefer displayed node over non-displayed one
- return material.visible ? 100 : 10;
-}
-
-function refinementCommandCancellationFn(cmd) {
- if (!cmd.requester.parent || !cmd.requester.material) {
- return true;
- }
- // Cancel the command if the tile already has a better texture.
- // This is only needed for elevation layers, because we may have several
- // concurrent layers but we can only use one texture.
- if (cmd.layer.isElevationLayer && cmd.requester.material.getElevationTile() &&
- cmd.targetLevel <= cmd.requester.material.getElevationTile().level) {
- return true;
- }
-
- // Cancel the command if the layer was removed between command scheduling and command execution
- if (!cmd.requester.layerUpdateState[cmd.layer.id]
- || !cmd.layer.source._featuresCaches[cmd.layer.crs]) {
- return true;
- }
-
- return !cmd.requester.material.visible;
-}
-
-function buildCommand(view, layer, extentsSource, extentsDestination, requester) {
- return {
- view,
- layer,
- extentsSource,
- extentsDestination,
- requester,
- priority: materialCommandQueuePriorityFunction(requester.material),
- earlyDropFunction: refinementCommandCancellationFn,
- partialLoading: true,
- };
-}
-
-function computePitchs(textures, extentsDestination) {
- return extentsDestination
- .map((ext, i) => (ext.offsetToParent(textures[i].extent)));
-}
-
-export function updateLayeredMaterialNodeImagery(context, layer, node, parent) {
- const material = node.material;
- if (!parent || !material) {
- return;
- }
- const extentsDestination = node.getExtentsByProjection(layer.crs);
-
- const zoom = extentsDestination[0].zoom;
- if (zoom > layer.zoom.max || zoom < layer.zoom.min) {
- return;
- }
-
- let nodeLayer = material.getTile(layer.id);
-
- // Initialisation
- if (node.layerUpdateState[layer.id] === undefined) {
- node.layerUpdateState[layer.id] = new LayerUpdateState();
-
- if (!extentsDestination.some(t => layer.source.hasData(t))) {
- // we also need to check that tile's parent doesn't have a texture for this layer,
- // because even if this tile is outside of the layer, it could inherit it's
- // parent texture
- if (!layer.noTextureParentOutsideLimit &&
- parent.material &&
- parent.material.getTile &&
- parent.material.getTile(layer.id)) {
- // ok, we're going to inherit our parent's texture
- } else {
- node.layerUpdateState[layer.id].noMoreUpdatePossible();
- return;
- }
- }
-
- if (!nodeLayer) {
- // Create new raster node
- nodeLayer = layer.setupRasterNode(node);
-
- // Init the node by parent
- const parentLayer = parent.material?.getTile(layer.id);
- nodeLayer.initFromParent(parentLayer, extentsDestination);
- }
-
- // Proposed new process, two separate processes:
- // * FIRST PASS: initNodeXXXFromParent and get out of the function
- // * SECOND PASS: Fetch best texture
-
- // The two-step allows you to filter out unnecessary requests
- // Indeed in the second pass, their state (not visible or not displayed) can block them to fetch
- if (nodeLayer.level >= layer.source.zoom?.min) {
- context.view.notifyChange(node, false);
- return;
- }
- }
-
- // Node is hidden, no need to update it
- if (!material.visible) {
- return;
- }
-
- // An update is pending / or impossible -> abort
- if (!layer.visible || !node.layerUpdateState[layer.id].canTryUpdate()) {
- return;
- }
-
- if (nodeLayer.level >= extentsDestination[0].zoom) {
- // default decision method
- node.layerUpdateState[layer.id].noMoreUpdatePossible();
- return;
- }
-
- // is fetching data from this layer disabled?
- if (layer.frozen) {
- return;
- }
-
- const failureParams = node.layerUpdateState[layer.id].failureParams;
- const destinationLevel = extentsDestination[0].zoom || node.level;
- const targetLevel = chooseNextLevelToFetch(layer.updateStrategy, destinationLevel, nodeLayer.level, failureParams, layer.source.zoom);
-
- if ((!layer.source.isVectorSource && targetLevel <= nodeLayer.level) || targetLevel > destinationLevel) {
- if (failureParams.lowestLevelError != Infinity) {
- // this is the highest level found in case of error.
- node.layerUpdateState[layer.id].noMoreUpdatePossible();
- }
- return;
- } else if (!extentsDestination.some(t => layer.source.hasData(t))) {
- node.layerUpdateState[layer.id].noData({ targetLevel });
- context.view.notifyChange(node, false);
- return;
- }
-
- const extentsSource = extentsDestination.map(e => e.tiledExtentParent(targetLevel));
- node.layerUpdateState[layer.id].newTry();
- const command = buildCommand(context.view, layer, extentsSource, extentsDestination, node);
-
- return context.scheduler.execute(command)
- .then(
- (results) => {
- // Does nothing if the layer has been removed while command was being or waiting to be executed
- if (!node.layerUpdateState[layer.id]) {
- return;
- }
- const textures = results.map((texture, index) => (texture != null ? texture :
- { isTexture: false, extent: extentsDestination[index] }));
-
- // TODO: Handle error : result is undefined in provider. throw error
- const pitchs = computePitchs(textures, extentsDestination);
- nodeLayer.setTextures(textures, pitchs);
- node.layerUpdateState[layer.id].success();
- })
- .catch((err) => {
- handlingError(err, node, layer, targetLevel, context.view);
- });
-}
-
-export function updateLayeredMaterialNodeElevation(context, layer, node, parent) {
- const material = node.material;
- if (!parent || !material) {
- return;
- }
-
- // TODO: we need either
- // - compound or exclusive layers
- // - support for multiple elevation layers
-
- // Elevation is currently handled differently from color layers.
- // This is caused by a LayeredMaterial limitation: only 1 elevation texture
- // can be used (where a tile can have N textures x M layers)
- const extentsDestination = node.getExtentsByProjection(layer.crs);
- const zoom = extentsDestination[0].zoom;
- if (zoom > layer.zoom.max || zoom < layer.zoom.min) {
- return;
- }
- // Init elevation layer, and inherit from parent if possible
- let nodeLayer = material.getElevationTile();
- if (!nodeLayer) {
- nodeLayer = layer.setupRasterNode(node);
- }
-
- if (node.layerUpdateState[layer.id] === undefined) {
- node.layerUpdateState[layer.id] = new LayerUpdateState();
-
- const parentLayer = parent.material?.getTile(layer.id);
- nodeLayer.initFromParent(parentLayer, extentsDestination);
-
- if (nodeLayer.level >= layer.source.zoom.min) {
- context.view.notifyChange(node, false);
- return;
- }
- }
-
- // Possible conditions to *not* update the elevation texture
- if (layer.frozen ||
- !material.visible ||
- !node.layerUpdateState[layer.id].canTryUpdate()) {
- return;
- }
-
- const failureParams = node.layerUpdateState[layer.id].failureParams;
- const targetLevel = chooseNextLevelToFetch(layer.updateStrategy, extentsDestination[0].zoom, nodeLayer.level, failureParams, layer.source.zoom);
-
- if (targetLevel <= nodeLayer.level || targetLevel > extentsDestination[0].zoom) {
- node.layerUpdateState[layer.id].noMoreUpdatePossible();
- return;
- } else if (!extentsDestination.some(t => layer.source.hasData(t))) {
- node.layerUpdateState[layer.id].noData({ targetLevel });
- context.view.notifyChange(node, false);
- return;
- }
-
- const extentsSource = extentsDestination.map(e => e.tiledExtentParent(targetLevel));
- node.layerUpdateState[layer.id].newTry();
- const command = buildCommand(context.view, layer, extentsSource, extentsDestination, node);
-
- return context.scheduler.execute(command).then(
- (results) => {
- // Does nothing if the layer has been removed while command was being or waiting to be executed
- if (!node.layerUpdateState[layer.id]) {
- return;
- }
-
- // Do not apply the new texture if its level is < than the current
- // one. This is only needed for elevation layers, because we may
- // have several concurrent layers but we can only use one texture.
- if (targetLevel <= nodeLayer.level) {
- node.layerUpdateState[layer.id].noMoreUpdatePossible();
- return;
- }
- const pitchs = computePitchs(results, extentsDestination);
- nodeLayer.setTextures(results, pitchs);
- node.layerUpdateState[layer.id].success();
- },
- err => handlingError(err, node, layer, targetLevel, context.view));
-}
-
-export function removeLayeredMaterialNodeTile(tileId) {
- /**
- * @param {TileMesh} node - The node to udpate.
- */
- return function removeLayeredMaterialNodeTile(node) {
- if (node.material?.removeTile) {
- if (node.material.elevationTile !== undefined) {
- node.setBBoxZ({ min: 0, max: 0 });
- }
- node.material.removeTile(tileId);
- }
- if (node.layerUpdateState && node.layerUpdateState[tileId]) {
- delete node.layerUpdateState[tileId];
- }
- };
-}
diff --git a/packages/Main/src/Provider/DataSourceProvider.js b/packages/Main/src/Provider/DataSourceProvider.js
index 399c8e6666..e0b3e9c343 100644
--- a/packages/Main/src/Provider/DataSourceProvider.js
+++ b/packages/Main/src/Provider/DataSourceProvider.js
@@ -7,6 +7,8 @@ export default {
// partialLoading sets the return promise as fulfilled if at least one sub-promise is fulfilled
// It waits until all promises are resolved
+ //
+ // TODO FAIRE uniquement quand il y a une erreur
if (command.partialLoading) {
return Promise.allSettled(promises)
.then((results) => {
diff --git a/packages/Main/src/Provider/TileProvider.js b/packages/Main/src/Provider/TileProvider.js
deleted file mode 100644
index 65ebffcd56..0000000000
--- a/packages/Main/src/Provider/TileProvider.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import CancelledCommandException from 'Core/Scheduler/CancelledCommandException';
-
-export default {
- executeCommand(command) {
- const promises = [];
- const layer = command.layer;
- const requester = command.requester;
- const extentsSource = command.extentsSource;
-
- if (requester &&
- !requester.material) {
- return Promise.reject(new CancelledCommandException(command));
- }
-
- for (const extent of extentsSource) {
- promises.push(layer.convert(requester, extent));
- }
-
- return Promise.all(promises);
- },
-};
diff --git a/packages/Main/src/Renderer/GeographicTransformMaterials.js b/packages/Main/src/Renderer/GeographicTransformMaterials.js
new file mode 100644
index 0000000000..cfc8f361d8
--- /dev/null
+++ b/packages/Main/src/Renderer/GeographicTransformMaterials.js
@@ -0,0 +1,88 @@
+import * as THREE from 'three';
+import { CopyShader } from 'three/examples/jsm/shaders/CopyShader.js';
+import { Extent } from '@itowns/geographic';
+import geoTransfomerfragmentShader from './Shader/geoTransformFS.glsl';
+
+class GeographicTransformMaterial extends THREE.ShaderMaterial {
+ constructor(options) {
+ const params = {
+ transparent: true,
+ uniforms: {
+ ...CopyShader.uniforms,
+ mapToUvTransform: { value: new THREE.Matrix3() },
+ localUvToWorldTransform: { value: new THREE.Matrix3() },
+ mapTransform: { value: new THREE.Matrix3() },
+ },
+ vertexShader: CopyShader.vertexShader,
+ fragmentShader: options.defines ? geoTransfomerfragmentShader : CopyShader.fragmentShader,
+ };
+ super(params);
+
+ if (options.defines) {
+ this.defines = options.defines;
+ }
+ }
+ setTexture(tDiffuse) {
+ this.uniforms.tDiffuse.value = tDiffuse;
+ }
+
+ setOpacity(opacity) {
+ this.uniforms.opacity.value = opacity;
+ }
+
+ setOutputExtent(outputExtent) {
+ this.outputExtent = outputExtent;
+ }
+}
+
+const inputExtent = new Extent('EPSG:4326');
+const extent = new Extent('EPSG:4326');
+const s = new THREE.Vector2();
+const t = new THREE.Vector2();
+
+export const materialUnit = new GeographicTransformMaterial({
+ fragmentShader: CopyShader.fragmentShader,
+});
+
+export const materialMercatorToWGS84 = new (class extends GeographicTransformMaterial {
+ setTexture(tDiffuse) {
+ super.setTexture(tDiffuse);
+ tDiffuse.extent.toExtent(tDiffuse.extent.crs, inputExtent);
+ inputExtent.planarDimensions(s);
+ t.set(inputExtent.west, inputExtent.south);
+ this.uniforms.mapToUvTransform.value.set(
+ 1 / s.x, 0, -t.x / s.x,
+ 0, 1 / s.y, -t.y / s.y,
+ 0, 0, 1,
+ );
+ }
+ setOutputExtent(outputExtent) {
+ super.setOutputExtent(outputExtent);
+
+ this.outputExtent.planarDimensions(s).multiplyScalar(THREE.MathUtils.DEG2RAD);
+ t.set(this.outputExtent.west, this.outputExtent.south).multiplyScalar(THREE.MathUtils.DEG2RAD);
+
+ this.uniforms.localUvToWorldTransform.value.set(
+ s.x, 0, t.x,
+ 0, s.y, t.y,
+ 0, 0, 1,
+ );
+ }
+})({
+ defines: {
+ EPSG_4326_EPSG_3857: 1,
+ },
+});
+
+export const materialMercatorToWGS84Optimized = new (class extends GeographicTransformMaterial {
+ setTexture(tDiffuse) {
+ super.setTexture(tDiffuse);
+ tDiffuse.extent.toExtent(tDiffuse.extent.crs, inputExtent);
+ this.outputExtent.transformToParent(inputExtent.as(this.outputExtent.crs, extent), this.uniforms.mapTransform.value);
+ }
+})({
+ defines: {
+ EPSG_4326_EPSG_3857: 1,
+ OPTIMIZED: 1,
+ },
+});
diff --git a/packages/Main/src/Renderer/LayeredMaterial.ts b/packages/Main/src/Renderer/LayeredMaterial.ts
index 58cc3938ef..30074204cf 100644
--- a/packages/Main/src/Renderer/LayeredMaterial.ts
+++ b/packages/Main/src/Renderer/LayeredMaterial.ts
@@ -1,15 +1,13 @@
import * as THREE from 'three';
+import { Extent } from '@itowns/geographic';
import TileVS from 'Renderer/Shader/TileVS.glsl';
import TileFS from 'Renderer/Shader/TileFS.glsl';
import ShaderUtils from 'Renderer/Shader/ShaderUtils';
-import Capabilities from 'Core/System/Capabilities';
import RenderMode from 'Renderer/RenderMode';
import { RasterTile, RasterElevationTile, RasterColorTile } from './RasterTile';
-import { makeDataArrayRenderTarget } from './WebGLComposer';
+import { drawMap } from './WebGLComposer';
import { RenderTargetCache } from './RenderTargetCache';
-const identityOffsetScale = new THREE.Vector4(0.0, 0.0, 1.0, 1.0);
-
// from three.js packDepthToRGBA
const UnpackDownscale = 255 / 256; // 0..1 -> fraction (excluding 1)
const bitSh = new THREE.Vector4(
@@ -23,13 +21,6 @@ export function unpack1K(color: THREE.Vector4Like, factor: number): number {
return factor ? bitSh.dot(color) * factor : bitSh.dot(color);
}
-const samplersElevationCount = 1;
-
-export function getMaxColorSamplerUnitsCount(): number {
- const maxSamplerUnitsCount = Capabilities.getMaxTextureUnitsCount();
- return maxSamplerUnitsCount - samplersElevationCount;
-}
-
export const colorLayerEffects = {
noEffect: 0,
removeLightColor: 1,
@@ -37,16 +28,6 @@ export const colorLayerEffects = {
customEffect: 3,
} as const;
-/** GPU struct for color layers */
-interface StructColorLayer {
- textureOffset: number;
- crs: number;
- opacity: number;
- effect_parameter: number;
- effect_type: number;
- transparent: boolean;
-}
-
/** GPU struct for elevation layers */
interface StructElevationLayer {
scale: number;
@@ -57,25 +38,12 @@ interface StructElevationLayer {
}
/** Default GPU struct values for initialization QoL */
-const defaultStructLayers: Readonly<{
- color: StructColorLayer;
- elevation: StructElevationLayer;
-}> = {
- color: {
- textureOffset: 0,
- crs: 0,
- opacity: 0,
- effect_parameter: 0,
- effect_type: colorLayerEffects.noEffect,
- transparent: false,
- },
- elevation: {
- scale: 0,
- bias: 0,
- mode: 0,
- zmin: 0,
- zmax: 0,
- },
+const defaultStructElevationLayer: StructElevationLayer = {
+ scale: 0,
+ bias: 0,
+ mode: 0,
+ zmin: 0,
+ zmax: 0,
};
/**
@@ -85,93 +53,35 @@ const defaultStructLayers: Readonly<{
*
* @param uniforms - The uniforms object for your material.
* @param tiles - An array of RasterTile objects, each containing textures.
- * @param max - The maximum number of layers for the DataArrayTexture.
- * @param type - Layer set identifier: 'c' for color, 'e' for elevation.
* @param renderer - The renderer used to render textures.
* @param renderTargetCache - Cache for managing render targets.
+ * @param extent - tile extent
*/
-function updateLayersUniformsForType(
+function updateLayersUniforms(
uniforms: Record,
tiles: RasterTile[],
- max: number,
- type: Type,
renderer: THREE.WebGLRenderer,
renderTargetCache: RenderTargetCache | undefined,
-) {
- // Aliases for readability
- const uLayers = uniforms.layers.value;
- const uTextures = uniforms.textures;
- const uOffsetScales = uniforms.offsetScales.value;
- const uTextureCount = uniforms.textureCount;
-
- // Flatten the 2d array: [i, j] -> layers[_layerIds[i]].textures[j]
- let count = 0;
- let width = 0;
- let height = 0;
- let setSize = false;
-
- // Determine total count of textures and dimensions
- // (assuming all textures are same size)
- let textureSetId: string = type;
- for (const tile of tiles) {
- // FIXME: RasterElevationTile are always passed to this function
- // alone so this works, but it's really not great even ignoring
- // the dynamic addition of a field.
- // @ts-expect-error: adding field to passed layer
- tile.textureOffset = count;
-
- for (
- let i = 0;
- i < tile.textures.length && count < max;
- ++i, ++count
- ) {
- const texture = tile.textures[i];
- if (!texture.isTexture) { continue; }
-
- textureSetId += `${texture.id}.`;
- uOffsetScales[count] = tile.offsetScales[i];
- uLayers[count] = tile;
-
- const img = texture.image;
- if (!img || img.width <= 0 || img.height <= 0) {
- console.error('Texture image not loaded or has zero dimensions');
- uTextureCount.value = 0;
- } else if (setSize === false) {
- width = img.width;
- height = img.height;
- setSize = true;
- } else if (width !== img.width || height !== img.height) {
- console.error('Texture dimensions mismatch');
- uTextureCount.value = 0;
- }
- }
+ extent: Extent) {
+ if (tiles.length == 0 || tiles.find(tile => tile.textures.length == 0) || !renderTargetCache) {
+ return;
}
- const cachedRT = renderTargetCache?.get(textureSetId);
+ const textureSetId = extent.toString();
- if (cachedRT) {
- uTextures.value = cachedRT.texture;
- uTextureCount.value = count;
- return;
- }
+ let renderTarget = renderTargetCache.get(textureSetId);
- const rt = makeDataArrayRenderTarget(width, height, count, tiles, max, renderer);
- if (!rt) {
- uTextureCount.value = 0;
- return;
+ if (!renderTarget) {
+ renderTarget = new THREE.WebGLRenderTarget(256, 256, { depthBuffer: false });
+ renderTarget.texture.extent = extent;
+
+ renderTargetCache.set(textureSetId, renderTarget);
}
- renderTargetCache?.set(textureSetId, rt);
- rt.texture.userData = { textureSetId };
- uniforms.textures.value = rt.texture;
+ drawMap(renderTarget, tiles, renderer);
- if (count > max) {
- console.warn(
- `LayeredMaterial: Not enough texture units (${max} < ${count}), `
- + 'excess textures have been discarded.',
- );
- }
- uTextureCount.value = count;
+ uniforms.mapTransform.value.identity();
+ uniforms.map.value = renderTarget.texture;
}
export const ELEVATION_MODES = {
@@ -218,22 +128,18 @@ interface LayeredMaterialRawUniforms {
// Debug
showOutline: boolean;
outlineWidth: number;
- outlineColors: THREE.Color[];
+ outlineColors: THREE.Color;
// Elevation layers
- elevationLayers: StructElevationLayer[];
- elevationTextures: THREE.DataArrayTexture | null;
- elevationOffsetScales: THREE.Vector4[];
- elevationTextureCount: number;
+ elevationLayer: StructElevationLayer;
+ displacementMap: THREE.DataTexture | null;
+ displacementMapTransform: THREE.Matrix3;
// Color layers
- colorLayers: StructColorLayer[];
- colorTextures: THREE.DataArrayTexture | null;
- colorOffsetScales: THREE.Vector4[];
- colorTextureCount: number;
+ map: THREE.DataTexture | null;
+ mapTransform: THREE.Matrix3;
}
-let nbSamplers: [number, number] | undefined;
const fragmentShader: string[] = [];
/** Replacing the default uniforms dynamic type with our own static map. */
@@ -268,9 +174,8 @@ function fillInProp<
type ElevationModeDefines = DefineMapping<'ELEVATION', typeof ELEVATION_MODES>;
type RenderModeDefines = DefineMapping<'MODE', typeof RenderMode.MODES>;
type LayeredMaterialDefines = {
- NUM_VS_TEXTURES: number;
- NUM_FS_TEXTURES: number;
- NUM_CRS: number;
+ USE_MAP: number;
+ USE_DISPLACEMENTMAP: number;
DEBUG: number;
MODE: number;
} & ElevationModeDefines & RenderModeDefines;
@@ -309,32 +214,47 @@ export class LayeredMaterial extends THREE.ShaderMaterial {
super(options);
this.name = 'LayeredMaterial';
- nbSamplers ??= [samplersElevationCount, getMaxColorSamplerUnitsCount()];
-
const defines: Partial = {};
- fillInProp(defines, 'NUM_VS_TEXTURES', nbSamplers[0]);
- fillInProp(defines, 'NUM_FS_TEXTURES', nbSamplers[1]);
- fillInProp(defines, 'NUM_CRS', crsCount);
+ fillInProp(defines, 'USE_MAP', 1);
+ fillInProp(defines, 'USE_DISPLACEMENTMAP', 1);
initModeDefines(defines);
fillInProp(defines, 'MODE', RenderMode.MODES.FINAL);
fillInProp(defines, 'DEBUG', +__DEBUG__);
- if (__DEBUG__) {
- const outlineColors = [new THREE.Color(1.0, 0.0, 0.0)];
- if (crsCount > 1) {
- outlineColors.push(new THREE.Color(1.0, 0.5, 0.0));
- }
+ // iTowns-specific uniforms + overrides of lambert defaults.
+ const itownsUniforms: Record = {
+ lightingEnabled: { value: false },
+ lightPosition: { value: new THREE.Vector3(-0.5, 0.0, 1.0) },
+ overlayAlpha: { value: 0 },
+ overlayColor: { value: new THREE.Color(1.0, 0.3, 0.0) },
+ objectId: { value: 0 },
+ geoidHeight: { value: 0.0 },
+ minBorderDistance: { value: -0.01 },
+ elevationLayer: { value: defaultStructElevationLayer },
+ diffuse: { value: new THREE.Color(0.04, 0.23, 0.35) },
+ opacity: { value: this.opacity },
+ fogFar: { value: 1000 },
+ fogColor: { value: new THREE.Color(0.76, 0.85, 1.0) },
+ };
- this.initUniforms({
- showOutline: true,
- outlineWidth: 0.008,
- outlineColors,
- });
+ if (__DEBUG__) {
+ itownsUniforms.showOutline = { value: true };
+ itownsUniforms.outlineWidth = { value: 0.008 };
+ itownsUniforms.outlineColors = { value: new THREE.Color(1.0, 0.0, 0.0) };
}
+ // Merge Three.js lambert uniforms (fog, map, displacementmap, diffuse,
+ // opacity…) with iTowns-specific uniforms.
+ // User-provided options.uniforms take final precedence.
+ this.uniforms = THREE.UniformsUtils.merge([
+ THREE.ShaderLib.lambert.uniforms,
+ itownsUniforms,
+ options.uniforms ?? {},
+ ]);
+
this.defines = defines;
this.lights = true;
@@ -346,63 +266,11 @@ export class LayeredMaterial extends THREE.ShaderMaterial {
fragmentShader[crsCount] ??= ShaderUtils.unrollLoops(TileFS, defines);
this.fragmentShader = fragmentShader[crsCount];
- this.initUniforms({
- // Color uniforms
- diffuse: new THREE.Color(0.04, 0.23, 0.35),
- opacity: this.opacity,
-
- // Lighting uniforms
- lightingEnabled: false,
- lightPosition: new THREE.Vector3(-0.5, 0.0, 1.0),
-
- // Misc properties
- fogNear: 1,
- fogFar: 1000,
- fogColor: new THREE.Color(0.76, 0.85, 1.0),
- fogDensity: 0.00025,
- overlayAlpha: 0,
- overlayColor: new THREE.Color(1.0, 0.3, 0.0),
- objectId: 0,
-
- geoidHeight: 0.0,
-
- // > 0 produces gaps,
- // < 0 causes oversampling of textures
- // = 0 causes sampling artefacts due to bad estimation of texture-uv
- // gradients
- // best is a small negative number
- minBorderDistance: -0.01,
- });
-
// LayeredMaterialLayers
this.colorTiles = [];
this.colorTileIds = [];
this.layersNeedUpdate = false;
- // elevation/color layer uniforms, to be updated using updateUniforms()
- this.initUniforms({
- elevationLayers: new Array(nbSamplers[0])
- .fill(defaultStructLayers.elevation),
- elevationTextures: null,
- elevationOffsetScales: new Array(nbSamplers[0])
- .fill(identityOffsetScale),
- elevationTextureCount: 0,
-
- colorLayers: new Array(nbSamplers[1])
- .fill(defaultStructLayers.color),
- colorTextures: null,
- colorOffsetScales: new Array(nbSamplers[1])
- .fill(identityOffsetScale),
- colorTextureCount: 0,
- });
-
- const lambertUniforms = THREE.UniformsUtils.clone(THREE.ShaderLib.lambert.uniforms);
- const lambertUniformValues: Record = {};
- for (const [name, uniform] of Object.entries(lambertUniforms)) {
- lambertUniformValues[name] = uniform.value;
- }
- this.initUniforms(lambertUniformValues);
-
// Can't do an ES6 getter/setter here because it would override the
// Material::visible property with accessors, which is not allowed.
Object.defineProperty(this, 'visible', {
@@ -476,59 +344,28 @@ export class LayeredMaterial extends THREE.ShaderMaterial {
}
}
- public getLayerUniforms(type: Type):
- MappedUniforms<{
- layers: (Type extends 'color'
- ? StructColorLayer
- : StructElevationLayer)[];
- textures: THREE.Texture[];
- offsetScales: THREE.Vector4[];
- textureCount: number;
- }> {
- return {
- layers: this.uniforms[`${type}Layers`],
- textures: this.uniforms[`${type}Textures`],
- offsetScales: this.uniforms[`${type}OffsetScales`],
- textureCount: this.uniforms[`${type}TextureCount`],
- };
- }
-
- /**
- * Updates uniforms for both color and elevation layers.
- * Orchestrates the processing of visible color layers and elevation tiles.
- *
- * @param renderer - The renderer used to render textures into arrays.
- */
- public updateLayersUniforms(renderer: THREE.WebGLRenderer): void {
- const colorlayers = this.colorTiles
- .filter(rt => rt.visible && rt.opacity > 0);
- colorlayers.sort((a, b) =>
- this.colorTileIds.indexOf(a.id) - this.colorTileIds.indexOf(b.id),
- );
-
- updateLayersUniformsForType(
- this.getLayerUniforms('color'),
- colorlayers,
- this.defines.NUM_FS_TEXTURES,
- 'c',
- renderer,
- this.renderTargetCache,
- );
-
- if (this.elevationTileId !== undefined && this.getElevationTile()) {
- if (this.elevationTile !== undefined) {
- updateLayersUniformsForType(
- this.getLayerUniforms('elevation'),
- [this.elevationTile],
- this.defines.NUM_VS_TEXTURES,
- 'e',
- renderer,
- this.renderTargetCache,
+ public updateLayersUniforms(renderer: THREE.WebGLRenderer, extent: Extent): void {
+ if (!this.layersNeedUpdate) {
+ return;
+ } else {
+ const colorlayers = this.colorTiles
+ .filter(rt => rt.visible && rt.opacity > 0)
+ .sort((a, b) =>
+ this.colorTileIds.indexOf(a.id) - this.colorTileIds.indexOf(b.id),
);
+
+ updateLayersUniforms(this.uniforms,
+ colorlayers, renderer, this.renderTargetCache, extent);
+
+ if (this.elevationTile && this.elevationTile.level > 0) {
+ const { uniforms, elevationTile } = this;
+ uniforms.displacementMap.value = elevationTile.textures[0];
+ uniforms.displacementMapTransform.value = elevationTile.mapTransforms[0];
+ uniforms.elevationLayer.value = elevationTile;
}
- }
- this.layersNeedUpdate = false;
+ this.layersNeedUpdate = false;
+ }
}
/**
@@ -540,14 +377,14 @@ export class LayeredMaterial extends THREE.ShaderMaterial {
throw new Error('renderTargetCache is not initialized');
}
- const colorTextures = this.getUniform('colorTextures');
- if (colorTextures?.userData?.textureSetId) {
- this.renderTargetCache.markAsUsed(colorTextures.userData.textureSetId);
+ const map = this.uniforms.map.value;
+ if (map?.userData?.textureSetId) {
+ this.renderTargetCache.markAsUsed(map.userData.textureSetId);
}
- const elevationTextures = this.getUniform('elevationTextures');
- if (elevationTextures?.userData?.textureSetId) {
- this.renderTargetCache.markAsUsed(elevationTextures.userData.textureSetId);
+ const displacementMap = this.uniforms.displacementMap.value;
+ if (displacementMap?.userData?.textureSetId) {
+ this.renderTargetCache.markAsUsed(displacementMap.userData.textureSetId);
}
}
@@ -622,6 +459,18 @@ export class LayeredMaterial extends THREE.ShaderMaterial {
? this.elevationTile : this.colorTiles.find(l => l.id === id);
}
+ public colorDataHasLoaded() {
+ return this.colorTiles.length == 0 || !this.colorTiles.some(colorTile => !colorTile.hasData());
+ }
+
+ public elevationDataHasLoaded() {
+ return !this.elevationTile || this.elevationTile.hasData();
+ }
+
+ public dataHasLoaded() {
+ return this.colorDataHasLoaded() && this.elevationDataHasLoaded();
+ }
+
public getTiles(ids: string[]): RasterTile[] {
// NOTE: this could instead be a mapping with an undefined in place of
// unfound IDs. Need to identify a use case for it though as it would
diff --git a/packages/Main/src/Renderer/OBB.ts b/packages/Main/src/Renderer/OBB.ts
index a188f7f6cb..4c62e7ea9b 100644
--- a/packages/Main/src/Renderer/OBB.ts
+++ b/packages/Main/src/Renderer/OBB.ts
@@ -6,7 +6,7 @@ import { CRS, Coordinates, OrientationUtils } from '@itowns/geographic';
import type { Extent, ProjectionLike } from '@itowns/geographic';
// get oriented bounding box of tile
-const builder = new GlobeTileBuilder({ uvCount: 1 });
+const builder = new GlobeTileBuilder();
const size = new THREE.Vector3();
const dimension = new THREE.Vector2();
const center = new THREE.Vector3();
diff --git a/packages/Main/src/Renderer/RasterTile.js b/packages/Main/src/Renderer/RasterTile.js
index ccc5393fae..0edb651948 100644
--- a/packages/Main/src/Renderer/RasterTile.js
+++ b/packages/Main/src/Renderer/RasterTile.js
@@ -1,9 +1,41 @@
import * as THREE from 'three';
import { ELEVATION_MODES } from 'Renderer/LayeredMaterial';
+import LayerUpdateState from 'Layer/LayerUpdateState';
+import { nextLevelToFetch } from 'Layer/LayerUpdateStrategy';
+import handlingError from 'Process/handlerNodeError';
import { checkNodeElevationTextureValidity, insertSignificantValuesFromParent, computeMinMaxElevation } from 'Parser/XbilParser';
export const EMPTY_TEXTURE_ZOOM = -1;
+function materialCommandQueuePriorityFunction(material) {
+ // We know that 'node' is visible because commands can only be
+ // issued for visible nodes.
+ // TODO: need priorization of displayed nodes
+ // Then prefer displayed node over non-displayed one
+ return material.visible ? 100 : 10;
+}
+
+function refinementCommandCancellationFn(cmd) {
+ const { requester } = cmd;
+ const { children } = requester;
+
+ return !cmd.force && !requester.visible && (!requester.parent || !requester.material.visible || children.find(c => c.visible));
+}
+
+function buildCommand(tile, extentsSource, requester, view) {
+ return {
+ view,
+ layer: tile.layer,
+ extentsSource: extentsSource.map(t => (tile.layer.source.hasData(t) ? t : undefined)),
+ extentsDestination: tile.tiles,
+ requester,
+ priority: materialCommandQueuePriorityFunction(requester.material),
+ earlyDropFunction: refinementCommandCancellationFn,
+ partialLoading: true,
+ force: !tile.hasData(),
+ };
+}
+
const pitch = new THREE.Vector4();
function getIndiceWithPitch(i, pitch, w) {
@@ -28,18 +60,16 @@ function getIndiceWithPitch(i, pitch, w) {
* @class RasterTile
*/
export class RasterTile extends THREE.EventDispatcher {
- constructor(layer) {
+ constructor(layer, tiles) {
super();
this.layer = layer;
- this.crs = layer.parent.tileMatrixSets.indexOf(layer.crs);
- if (this.crs == -1) {
- console.error('Unknown crs:', layer.crs);
- }
-
this.textures = [];
- this.offsetScales = [];
+ this.tiles = tiles;
+ this.mapTransforms = [];
this.level = EMPTY_TEXTURE_ZOOM;
this.needsUpdate = false;
+ this.state = new LayerUpdateState();
+ this.lowestLevelError = Infinity;
this._handlerCBEvent = () => { this.needsUpdate = true; };
layer.addEventListener('visible-property-changed', this._handlerCBEvent);
@@ -58,27 +88,36 @@ export class RasterTile extends THREE.EventDispatcher {
return this.layer.visible;
}
- initFromParent(parent, extents) {
- if (parent && parent.level > this.level) {
- let index = 0;
- const sortedParentTextures = this.sortBestParentTextures(parent.textures);
- for (const childExtent of extents) {
- const matchingParentTexture = sortedParentTextures
- .find(parentTexture => parentTexture && childExtent.isInside(parentTexture.extent));
- if (matchingParentTexture) {
- this.setTexture(index++, matchingParentTexture,
- childExtent.offsetToParent(matchingParentTexture.extent));
- }
- }
+ load(requester, view) {
+ if (this.state.canTryUpdate()) {
+ this.state.newTry();
+
+ const nextLevel = nextLevelToFetch(this);
+ const nextTiles = this.tiles.map(tile => tile.tiledExtentParent(nextLevel));
+
+ const command = buildCommand(this, nextTiles, requester, view);
- if (__DEBUG__) {
- if (index != extents.length) {
- console.error(`non-coherent result ${index} vs ${extents.length}.`, extents);
+ return view.mainLoop.scheduler.execute(command).then((textures) => {
+ this.setTextures(textures);
+
+ if (nextLevelToFetch(this) == this.level) {
+ this.state.noMoreUpdatePossible();
+ } else {
+ this.state.success();
}
- }
+
+ return textures;
+ }, () => {
+ this.state.success();
+ })
+ .catch(err => handlingError(err, requester, this.layer, nextLevel, view));
}
}
+ hasData() {
+ return this.level > EMPTY_TEXTURE_ZOOM;
+ }
+
sortBestParentTextures(textures) {
const sortByValidity = (a, b) => {
if (a.isTexture === b.isTexture) {
@@ -116,7 +155,7 @@ export class RasterTile extends THREE.EventDispatcher {
// Dispose all textures
this.disposeAtIndexes(this.textures.keys());
this.textures = [];
- this.offsetScales = [];
+ this.mapTransforms = [];
this.level = EMPTY_TEXTURE_ZOOM;
}
@@ -130,19 +169,22 @@ export class RasterTile extends THREE.EventDispatcher {
this.needsUpdate = true;
}
- setTexture(index, texture, offsetScale) {
- if (this.shouldWriteTextureAtIndex(index, texture)) {
- this.level = (texture && texture.extent) ? texture.extent.zoom : this.level;
- this.textures[index] = texture || null;
- this.offsetScales[index] = offsetScale;
+ setTexture(index, texture, mapTransform) {
+ if (texture && this.shouldWriteTextureAtIndex(index, texture)) {
+ this.level = texture.extent ? texture.extent.zoom : this.level;
+ this.textures[index] = texture;
+ this.mapTransforms[index] = mapTransform;
this.needsUpdate = true;
+ return texture;
}
}
- setTextures(textures, pitchs) {
+ setTextures(textures) {
this.disposeRedrawnTextures(textures);
for (let i = 0, il = textures.length; i < il; ++i) {
- this.setTexture(i, textures[i], pitchs[i]);
+ if (textures[i]) {
+ this.setTexture(i, textures[i], this.tiles[i].transformToParent(textures[i].extent));
+ }
}
}
@@ -165,8 +207,8 @@ export class RasterColorTile extends RasterTile {
}
export class RasterElevationTile extends RasterTile {
- constructor(layer) {
- super(layer);
+ constructor(layer, tiles) {
+ super(layer, tiles);
const defaultEle = {
bias: 0,
mode: ELEVATION_MODES.DATA,
@@ -210,23 +252,14 @@ export class RasterElevationTile extends RasterTile {
}
}
- initFromParent(parent, extents) {
- const currentLevel = this.level;
- super.initFromParent(parent, extents);
- this.updateMinMaxElevation();
- if (currentLevel !== this.level) {
- this.dispatchEvent({ type: 'rasterElevationLevelChanged', node: this });
- }
- }
-
- setTextures(textures, offsetScales) {
+ setTextures(textures) {
const anyValidTexture = textures.find(texture => texture != null);
if (!anyValidTexture) {
return;
}
const currentLevel = this.level;
this.replaceNoDataValueFromTexture(anyValidTexture);
- super.setTextures(textures, offsetScales);
+ super.setTextures(textures);
this.updateMinMaxElevation();
if (currentLevel !== this.level) {
this.dispatchEvent({ type: 'rasterElevationLevelChanged', node: this });
@@ -238,7 +271,7 @@ export class RasterElevationTile extends RasterTile {
if (firstValidIndex !== -1 && !this.layer.useColorTextureElevation) {
const { min, max } = computeMinMaxElevation(
this.textures[firstValidIndex],
- this.offsetScales[firstValidIndex],
+ this.mapTransforms[firstValidIndex],
{
noDataValue: this.layer.noDataValue,
zmin: this.layer.zmin,
diff --git a/packages/Main/src/Renderer/RenderTargetCache.ts b/packages/Main/src/Renderer/RenderTargetCache.ts
index da856e41fb..0ad403d463 100644
--- a/packages/Main/src/Renderer/RenderTargetCache.ts
+++ b/packages/Main/src/Renderer/RenderTargetCache.ts
@@ -10,7 +10,7 @@ export class RenderTargetCache {
/**
* Render targets queued for disposal.
*/
- private _pendingDisposal: Map;
+ private _pendingDisposal: Map;
/**
* Render targets used in the current render cycle.
@@ -21,14 +21,14 @@ export class RenderTargetCache {
* LRU cache of render targets, automatically discards least recently
* used when max is exceeded.
*/
- private _cache: LRUCache;
+ private _cache: LRUCache;
constructor(maxCacheSize = 200) {
this._pendingDisposal = new Map();
this._usedIds = new Set();
this._cache = new LRUCache({
max: maxCacheSize,
- dispose: (rt: THREE.WebGLArrayRenderTarget, key: string) => {
+ dispose: (rt: THREE.WebGLRenderTarget, key: string) => {
this._pendingDisposal.set(key, rt);
},
});
@@ -68,7 +68,7 @@ export class RenderTargetCache {
* @param id - The identifier of the render target
* @returns The render target or undefined if not found
*/
- public get(id: string): THREE.WebGLArrayRenderTarget | undefined {
+ public get(id: string): THREE.WebGLRenderTarget | undefined {
let rt = this._cache.get(id);
if (!rt) {
@@ -88,7 +88,8 @@ export class RenderTargetCache {
* @param id - The identifier of the render target
* @param rt - The render target to cache
*/
- public set(id: string, rt: THREE.WebGLArrayRenderTarget): void {
+ public set(id: string, rt: THREE.WebGLRenderTarget): void {
+ rt.texture.userData.textureSetId = id;
this._cache.set(id, rt);
}
diff --git a/packages/Main/src/Renderer/Shader/Chunk/color_layers_pars_fragment.glsl b/packages/Main/src/Renderer/Shader/Chunk/color_layers_pars_fragment.glsl
index 97d2ba2fae..54a9957d52 100644
--- a/packages/Main/src/Renderer/Shader/Chunk/color_layers_pars_fragment.glsl
+++ b/packages/Main/src/Renderer/Shader/Chunk/color_layers_pars_fragment.glsl
@@ -1,26 +1,11 @@
-struct Layer {
- int textureOffset;
- int crs;
- int effect_type;
- float effect_parameter;
- float opacity;
- bool transparent;
-};
-
-#include
-
-uniform sampler2DArray colorTextures;
-uniform vec4 colorOffsetScales[NUM_FS_TEXTURES];
-uniform Layer colorLayers[NUM_FS_TEXTURES];
-uniform int colorTextureCount;
-
-vec3 uvs[NUM_CRS];
-
float getBorderDistance(vec2 uv) {
vec2 p2 = min(uv, 1. -uv);
return min(p2.x, p2.y);
}
+
+/* move new Pass
+
float tolerance = 0.99;
vec4 applyWhiteToInvisibleEffect(vec4 color) {
@@ -37,10 +22,11 @@ vec4 applyLightColorToInvisibleEffect(vec4 color, float intensity) {
color.rgb *= color.rgb * color.rgb;
return color;
}
+*/
#if defined(DEBUG)
uniform bool showOutline;
-uniform vec3 outlineColors[NUM_CRS];
+uniform vec3 outlineColors;
uniform float outlineWidth;
vec4 getOutlineColor(vec3 outlineColor, vec2 uv) {
@@ -50,31 +36,3 @@ vec4 getOutlineColor(vec3 outlineColor, vec2 uv) {
#endif
uniform float minBorderDistance;
-vec4 getLayerColor(int textureOffset, sampler2DArray tex, vec4 offsetScale, Layer layer) {
- if ( textureOffset >= colorTextureCount ) return vec4(0);
-
- vec3 uv;
- // #pragma unroll_loop
- for ( int i = 0; i < NUM_CRS; i ++ ) {
- if ( i == layer.crs ) uv = uvs[ i ];
- }
-
- float borderDistance = getBorderDistance(uv.xy);
- if (textureOffset != layer.textureOffset + int(uv.z) || borderDistance < minBorderDistance ) return vec4(0);
- vec4 color = texture(tex, vec3(pitUV(uv.xy, offsetScale), float(textureOffset)));
- if (layer.effect_type == 3) {
- #include
- } else {
- if (layer.transparent && color.a != 0.0) {
- color.rgb /= color.a;
- }
-
- if (layer.effect_type == 1) {
- color = applyLightColorToInvisibleEffect(color, layer.effect_parameter);
- } else if (layer.effect_type == 2) {
- color = applyWhiteToInvisibleEffect(color);
- }
- }
- color.a *= layer.opacity;
- return color;
-}
diff --git a/packages/Main/src/Renderer/Shader/Chunk/elevation_pars_vertex.glsl b/packages/Main/src/Renderer/Shader/Chunk/elevation_pars_vertex.glsl
index d5048c16d7..2377c904d8 100644
--- a/packages/Main/src/Renderer/Shader/Chunk/elevation_pars_vertex.glsl
+++ b/packages/Main/src/Renderer/Shader/Chunk/elevation_pars_vertex.glsl
@@ -1,4 +1,6 @@
-#if NUM_VS_TEXTURES > 0
+#if USE_DISPLACEMENTMAP
+ #include
+
struct Layer {
float scale;
float bias;
@@ -7,10 +9,7 @@
float zmax;
};
- uniform Layer elevationLayers[NUM_VS_TEXTURES];
- uniform sampler2DArray elevationTextures;
- uniform vec4 elevationOffsetScales[NUM_VS_TEXTURES];
- uniform int elevationTextureCount;
+ uniform Layer elevationLayer;
uniform float geoidHeight;
highp float decode32(highp vec4 rgba) {
@@ -21,19 +20,19 @@
return Result;
}
- float getElevationMode(vec2 uv, sampler2DArray tex, int mode) {
+ float getElevationMode(vec2 uv, sampler2D tex, int mode) {
if (mode == ELEVATION_RGBA)
- return decode32(texture(tex, vec3(uv, 0.0)).abgr * 255.0);
+ return decode32(texture(tex, uv).abgr * 255.0);
if (mode == ELEVATION_DATA || mode == ELEVATION_COLOR)
- return texture(tex, vec3(uv, 0.0)).r;
+ return texture(tex, uv).r;
return 0.;
}
- float getElevation(vec2 uv, sampler2DArray tex, vec4 offsetScale, Layer layer) {
- // Elevation textures are inverted along the y-axis
- uv = vec2(uv.x, 1.0 - uv.y);
- uv = uv * offsetScale.zw + offsetScale.xy;
- float d = clamp(getElevationMode(uv, tex, layer.mode), layer.zmin, layer.zmax);
+ float getElevation(Layer layer) {
+ vec2 uv = vDisplacementMapUv;
+ // Elevation textures are stored top-to-bottom (v=0 at north), flip after offset
+ uv.y = 1.0 - uv.y;
+ float d = clamp(getElevationMode(uv, displacementMap, layer.mode), layer.zmin, layer.zmax);
return d * layer.scale + layer.bias;
}
#endif
diff --git a/packages/Main/src/Renderer/Shader/Chunk/elevation_vertex.glsl b/packages/Main/src/Renderer/Shader/Chunk/elevation_vertex.glsl
index 54ab40ee9c..63c1937599 100644
--- a/packages/Main/src/Renderer/Shader/Chunk/elevation_vertex.glsl
+++ b/packages/Main/src/Renderer/Shader/Chunk/elevation_vertex.glsl
@@ -1,6 +1,4 @@
-#if NUM_VS_TEXTURES > 0
- if(elevationTextureCount > 0) {
- float elevation = getElevation(uv, elevationTextures, elevationOffsetScales[0], elevationLayers[0]);
+#if USE_DISPLACEMENTMAP
+ float elevation = getElevation(elevationLayer);
transformed += elevation * normal;
- }
#endif
diff --git a/packages/Main/src/Renderer/Shader/Chunk/pitUV.glsl b/packages/Main/src/Renderer/Shader/Chunk/pitUV.glsl
deleted file mode 100644
index 5dba9788ed..0000000000
--- a/packages/Main/src/Renderer/Shader/Chunk/pitUV.glsl
+++ /dev/null
@@ -1,5 +0,0 @@
-vec2 pitUV(vec2 uv, vec4 pit)
-{
- return uv * pit.zw + vec2(pit.x, 1.0 - pit.w - pit.y);
-}
-
diff --git a/packages/Main/src/Renderer/Shader/ShaderChunk.js b/packages/Main/src/Renderer/Shader/ShaderChunk.js
index 2868f19d89..ca6335d0e4 100644
--- a/packages/Main/src/Renderer/Shader/ShaderChunk.js
+++ b/packages/Main/src/Renderer/Shader/ShaderChunk.js
@@ -8,7 +8,6 @@ import mode_depth_fragment from './Chunk/mode_depth_fragment.glsl';
import mode_id_fragment from './Chunk/mode_id_fragment.glsl';
import overlay_fragment from './Chunk/overlay_fragment.glsl';
import overlay_pars_fragment from './Chunk/overlay_pars_fragment.glsl';
-import pitUV from './Chunk/pitUV.glsl';
import precision_qualifier from './Chunk/precision_qualifier.glsl';
import projective_texturing_vertex from './Chunk/projective_texturing_vertex.glsl';
import projective_texturing_pars_vertex from './Chunk/projective_texturing_pars_vertex.glsl';
@@ -29,7 +28,6 @@ const itownsShaderChunk = {
mode_pars_fragment,
overlay_fragment,
overlay_pars_fragment,
- pitUV,
precision_qualifier,
projective_texturing_vertex,
projective_texturing_pars_vertex,
diff --git a/packages/Main/src/Renderer/Shader/TileFS.glsl b/packages/Main/src/Renderer/Shader/TileFS.glsl
index f172fca602..ae30e06ec0 100644
--- a/packages/Main/src/Renderer/Shader/TileFS.glsl
+++ b/packages/Main/src/Renderer/Shader/TileFS.glsl
@@ -1,6 +1,8 @@
#include
#include
-#include
+#include
+#include
+
#include
#if MODE == MODE_FINAL
#include
@@ -16,7 +18,7 @@
uniform vec3 diffuse;
uniform float opacity;
-varying vec3 vUv; // uv.x/uv_1.x, uv.y, uv_1.y
+varying vec3 vUv;
varying vec2 vHighPrecisionZW;
void main() {
@@ -32,30 +34,17 @@ void main() {
#else
- gl_FragColor = vec4(diffuse, opacity);
-
- uvs[0] = vec3(vUv.xy, 0.);
-
-#if NUM_CRS > 1
- uvs[1] = vec3(vUv.x, fract(vUv.z), floor(vUv.z));
-#endif
+ gl_FragColor = vec4(diffuse, opacity);
- vec4 color;
- #pragma unroll_loop
- for ( int i = 0; i < NUM_FS_TEXTURES; i ++ ) {
- color = getLayerColor( i , colorTextures, colorOffsetScales[ i ], colorLayers[ i ]);
- gl_FragColor.rgb = mix(gl_FragColor.rgb, color.rgb, color.a);
- }
+ vec4 color = texture(map, vMapUv);
+ gl_FragColor.rgb = mix(gl_FragColor.rgb, color.rgb, color.a);
#if DEBUG == 1
if (showOutline) {
- #pragma unroll_loop
- for ( int i = 0; i < NUM_CRS; i ++) {
- color = getOutlineColor( outlineColors[ i ], uvs[ i ].xy);
- gl_FragColor.rgb = mix(gl_FragColor.rgb, color.rgb, color.a);
- }
+ color = getOutlineColor( outlineColors, vUv.xy);
+ gl_FragColor.rgb = mix(gl_FragColor.rgb, color.rgb, color.a);
}
- #endif
+ #endif
// if no lights are defined, keep flat shading
#if NUM_DIR_LIGHTS + NUM_SPOT_LIGHTS + NUM_POINT_LIGHTS + NUM_HEMI_LIGHTS > 0
diff --git a/packages/Main/src/Renderer/Shader/TileVS.glsl b/packages/Main/src/Renderer/Shader/TileVS.glsl
index 2e57c0b55e..4a425d5b8d 100644
--- a/packages/Main/src/Renderer/Shader/TileVS.glsl
+++ b/packages/Main/src/Renderer/Shader/TileVS.glsl
@@ -1,11 +1,9 @@
#include
#include
+#include
#include
#include
#include
-#if NUM_CRS > 1
-attribute float uv_1;
-#endif
#include
@@ -18,24 +16,24 @@ varying vec3 vUv;
varying vec3 vNormal;
#endif
void main() {
- #include
- #include
- #include
- #include
- #include
- vViewPosition = (modelViewMatrix * vec4(position, 1.0)).xyz;
- #include
- #include
- vHighPrecisionZW = gl_Position.zw;
+ vec2 DISPLACEMENTMAP_UV = vec2(uv);
+ vec2 MAP_UV = vec2(uv);
+
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include
+ vViewPosition = (modelViewMatrix * vec4(position, 1.0)).xyz;
+ #include
+ #include
+ vHighPrecisionZW = gl_Position.zw;
#if MODE == MODE_FINAL
- #include
- #include
- #include
- #if NUM_CRS > 1
- vUv = vec3(uv, (uv_1 > 0.) ? uv_1 : uv.y); // set uv_1 = uv if uv_1 is undefined
- #else
- vUv = vec3(uv, 0.0);
- #endif
- vNormal = normalize ( mat3( normalMatrix[0].xyz, normalMatrix[1].xyz, normalMatrix[2].xyz ) * normal );
+ #include
+ #include
+ #include
+ vUv = vec3(uv, 0.0);
+ vNormal = normalize ( mat3( normalMatrix[0].xyz, normalMatrix[1].xyz, normalMatrix[2].xyz ) * normal );
#endif
}
diff --git a/packages/Main/src/Renderer/Shader/geoTransformFS.glsl b/packages/Main/src/Renderer/Shader/geoTransformFS.glsl
new file mode 100644
index 0000000000..b6f61d6b36
--- /dev/null
+++ b/packages/Main/src/Renderer/Shader/geoTransformFS.glsl
@@ -0,0 +1,84 @@
+precision highp float;
+
+varying vec2 vUv;
+
+uniform sampler2D tDiffuse;
+uniform mat3 localUvToWorldTransform;
+uniform mat3 mapToUvTransform;
+uniform mat3 mapTransform;
+uniform float opacity;
+
+#ifdef EPSG_4326_EPSG_3857
+
+// Precomputed constant for converting latitude to Y in Mercator projection
+// The constant is derived from the formula for the Mercator projection:
+// y = R * ln(tan(pi/4 + lat/2))
+// where R is the Earth's radius (approximately 6378137 meters)
+// and the factor 0.69314718 is ln(2) to convert from natural log to log base 2
+// 20037508.34 is maximum extent size in Mercator projection
+const float CTOYL = 20037508.34 / 3.141592653589793 * 0.69314718;
+
+// world WGS84 to Mercator
+vec3 worldToMapEPSG(vec3 world_coordinates) {
+ vec3 mercatorCoordinates;
+
+ float s = sin(world_coordinates.y);
+
+ mercatorCoordinates.y = 0.5 * log2((1.0 + s) / (1.0 - s)) * CTOYL;
+
+ mercatorCoordinates.z = 1.0;
+
+ return mercatorCoordinates;
+}
+
+vec2 mapCoordinatesToUvTexture(mat3 mapTransform, vec2 uvMesh, vec3 mapCoordinates) {
+
+ return vec2(uvMesh.x, (mapTransform * mapCoordinates).y);
+
+}
+
+vec2 optimized(mat3 mapTransform, vec2 uvMesh) {
+
+ return ( mapTransform * vec3( uvMesh, 1 ) ).xy;
+
+}
+
+#endif
+
+void main() {
+
+ #ifdef OPTIMIZED
+
+ vec2 vMapUv = optimized( mapTransform, vUv);
+
+ #else
+
+ // world view coordinates
+
+ vec3 world_coordinates;
+
+ // coordinates in input map EPSG
+ vec3 mapCoordinates;
+
+ // local uv mesh to world view EPSG
+
+ world_coordinates = localUvToWorldTransform * vec3(vUv, 1.0);
+
+ // world view EPSG to input map EPSG
+
+ mapCoordinates = worldToMapEPSG(world_coordinates);
+
+ // input raster EPSG to local texture
+
+ vec2 vMapUv = mapCoordinatesToUvTexture(mapToUvTransform, vUv, mapCoordinates);
+
+ #endif
+
+ if (vMapUv.y < 0.0 || vMapUv.y > 1.0 || vMapUv.x < 0.0 || vMapUv.x > 1.0) {
+ // break if out of texture
+ discard;
+ } else {
+ gl_FragColor = texture2D(tDiffuse, vMapUv);
+ gl_FragColor.a *= opacity;
+ }
+}
\ No newline at end of file
diff --git a/packages/Main/src/Renderer/WebGLComposer.ts b/packages/Main/src/Renderer/WebGLComposer.ts
index 62f5de1381..23b6a8a118 100644
--- a/packages/Main/src/Renderer/WebGLComposer.ts
+++ b/packages/Main/src/Renderer/WebGLComposer.ts
@@ -1,121 +1,119 @@
import * as THREE from 'three';
+import { Extent } from '@itowns/geographic';
+// eslint-disable-next-line import/extensions
+import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
+// eslint-disable-next-line import/extensions
+import { Pass, FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+import { DotScreenPass } from 'three/examples/jsm/postprocessing/DotScreenPass.js';
import { RasterTile } from './RasterTile';
+import {
+ materialUnit,
+ materialMercatorToWGS84,
+ materialMercatorToWGS84Optimized } from './GeographicTransformMaterials';
-// shader for copying a 2D texture to a framebuffer
-const copyTextureShader = {
- vertexShader: `
- varying vec2 vUv;
- void main() {
- vUv = uv;
- gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
+declare module 'three' {
+ interface Texture {
+ extent: Extent | null | undefined,
+ }
+}
+
+const getGeographicTransformMaterial =
+ (input : string, outputExtent : Extent | null | undefined) => {
+ if (!outputExtent || input == outputExtent.crs) {
+ return materialUnit;
}
- `,
- fragmentShader: `
- precision highp float;
- uniform sampler2D sourceTexture;
- varying vec2 vUv;
- void main() {
- gl_FragColor = texture2D(sourceTexture, vUv);
+ if (input == 'EPSG:3857' && outputExtent.crs == 'EPSG:4326') {
+ // todo could computed with the size texture
+ if (outputExtent.planarDimensions().x < 0.01) {
+ return materialMercatorToWGS84Optimized;
+ } else {
+ return materialMercatorToWGS84;
+ }
}
- `,
-};
-
-let material: THREE.ShaderMaterial | null = null;
-let quad: THREE.Mesh | null = null;
-const quadCam: THREE.OrthographicCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
-/**
- * Initializes a THREE.WebGLArrayRenderTarget with immutable storage
- * and populates its layers.
- * Returns the populated render target so callers can own/dispose it.
- *
- * @param width - The width of each layer in the DataArrayTexture.
- * @param height - The height of each layer in the DataArrayTexture.
- * @param count - The total number of layers the DataArrayTexture should have.
- * @param tiles - An array of RasterTile objects, each containing textures.
- * @param max - The maximum allowed number of layers for the DataArrayTexture.
- * @param renderer - The renderer used to render the texture.
- * @returns The constructed render target, or null
- */
-export function makeDataArrayRenderTarget(
- width: number,
- height: number,
- count: number,
+
+ console.log('No Geographic Transform Material');
+ };
+
+class GeographicProjectionPass extends Pass {
+ tiles: RasterTile[];
+ extent: Extent | null;
+ _fsQuad: FullScreenQuad;
+ clear: boolean;
+ constructor() {
+ super();
+ this._fsQuad = new FullScreenQuad();
+ this.tiles = [];
+ this.extent = null;
+ this.clear = true;
+ this.needsSwap = true;
+ }
+
+ render(renderer: THREE.WebGLRenderer, writeBuffer: THREE.WebGLRenderTarget) {
+ renderer.setRenderTarget(writeBuffer);
+
+ const inputCrs = this.tiles[0].layer.crs;
+
+ const outputExtent = writeBuffer.texture.extent;
+
+ const geographicTransformMaterial = getGeographicTransformMaterial(inputCrs, outputExtent);
+
+ if (geographicTransformMaterial) {
+ geographicTransformMaterial.setOutputExtent(outputExtent);
+
+ this._fsQuad.material = geographicTransformMaterial;
+
+ if (this.clear) { renderer.clear(); }
+
+ this.tiles.forEach((tile) => {
+ if (tile.visible) {
+ geographicTransformMaterial.setOpacity(tile.opacity);
+
+ tile.textures.forEach((texture) => {
+ if (texture) {
+ geographicTransformMaterial.setTexture(texture);
+ this._fsQuad.render(renderer);
+ }
+ });
+ }
+ });
+ }
+ }
+
+ dispose() {
+ this._fsQuad.dispose();
+ }
+}
+
+const geographicProjectionPass = new GeographicProjectionPass();
+let composer : null | EffectComposer = null;
+
+const dotPass = new DotScreenPass(new THREE.Vector2(0, 0), 0.5, 0.8);
+// console.log('dotPass', dotPass);
+dotPass.needsSwap = false;
+
+export function drawMap(
+ renderTarget: THREE.WebGLRenderTarget,
tiles: RasterTile[],
- max: number,
renderer: THREE.WebGLRenderer,
-): THREE.WebGLArrayRenderTarget | null {
- if (count === 0) { return null; }
-
- // The render target's internal framebuffer will be used to attach layers.
- const renderTarget = new THREE.WebGLArrayRenderTarget(width, height, count, {
- depthBuffer: false, // No depth buffer needed for simple 2D texture copy
- });
- const arrayTexture = renderTarget.texture;
-
- // Set up the quad for rendering
- if (!quad) {
- const geometry = new THREE.PlaneGeometry(2, 2);
- material = new THREE.ShaderMaterial({
- uniforms: {
- // This uniform will be updated with each source 2D texture
- sourceTexture: { value: null },
- },
- vertexShader: copyTextureShader.vertexShader,
- fragmentShader: copyTextureShader.fragmentShader,
- });
- quad = new THREE.Mesh(geometry, material);
+): undefined {
+ if (!composer) {
+ composer = new EffectComposer(renderer, renderTarget);
+ composer.addPass(geographicProjectionPass);
+ composer.addPass(dotPass);
+ } else {
+ composer.renderer = renderer;
+ composer.renderTarget1 = renderTarget;
+ composer.writeBuffer = renderTarget;
}
- // Store renderer state and temporarily disable VR
- const previousRenderTarget = renderer.getRenderTarget();
- const gl = renderer.getContext();
- const glViewport = gl.getParameter(gl.VIEWPORT);
+ geographicProjectionPass.tiles = tiles;
+
const wasVREnabled = renderer.xr.enabled;
if (wasVREnabled) { renderer.xr.enabled = false; }
- // loop through each tile and its textures
- // to render them into DataArrayTexture layers
- let currentLayerIndex = 0;
-
- let setTexture = false;
-
- for (const tile of tiles) {
- for (
- let i = 0;
- i < tile.textures.length && currentLayerIndex < max;
- ++i, ++currentLayerIndex
- ) {
- const texture = tile.textures[i];
- if (!texture.isTexture) { continue; }
-
- // Set the current source 2D texture on the quad's material
- (material as THREE.ShaderMaterial).uniforms.sourceTexture.value = texture;
-
- if (!setTexture) {
- // Set parameters from the first valid texture
- arrayTexture.magFilter = texture.magFilter;
- arrayTexture.minFilter = texture.minFilter;
- arrayTexture.wrapS = texture.wrapS;
- arrayTexture.wrapT = texture.wrapT;
- arrayTexture.format = texture.format;
- arrayTexture.type = texture.type;
- arrayTexture.internalFormat = texture.internalFormat;
- arrayTexture.anisotropy = texture.anisotropy;
- arrayTexture.premultiplyAlpha = texture.premultiplyAlpha;
- setTexture = true;
- }
+ // todo verify if renderer size isn't overkill
+ composer.render();
- // render this source texture into the current layer
- renderer.setRenderTarget(renderTarget, currentLayerIndex);
- renderer.render(quad, quadCam);
- }
- }
-
- // Restore renderer state
- renderer.setRenderTarget(previousRenderTarget);
- // renderer.setViewport is not enough to update internal GL state
- gl.viewport(glViewport[0], glViewport[1], glViewport[2], glViewport[3]);
if (wasVREnabled) { renderer.xr.enabled = true; }
-
- return renderTarget;
}
diff --git a/packages/Main/src/Renderer/c3DEngine.js b/packages/Main/src/Renderer/c3DEngine.js
index bc535e2e87..6354eacd4a 100644
--- a/packages/Main/src/Renderer/c3DEngine.js
+++ b/packages/Main/src/Renderer/c3DEngine.js
@@ -100,6 +100,7 @@ class c3DEngine {
antialias: options.antialias,
alpha: options.alpha,
logarithmicDepthBuffer: options.logarithmicDepthBuffer,
+ preserveDrawingBuffer: true,
});
this.renderer.domElement.style.position = 'relative';
this.renderer.domElement.style.zIndex = 0;
diff --git a/packages/Main/src/Utils/DEMUtils.js b/packages/Main/src/Utils/DEMUtils.js
index c7d38914a9..9400bf67b7 100644
--- a/packages/Main/src/Utils/DEMUtils.js
+++ b/packages/Main/src/Utils/DEMUtils.js
@@ -346,7 +346,7 @@ function _readZ(layer, method, coord, nodes, cache) {
// Assuming that tiles are split in 4 children, we lookup the parent that
// really owns this texture
- const stepsUpInHierarchy = Math.round(Math.log2(1.0 / tileLayer.offsetScales[0].z));
+ const stepsUpInHierarchy = Math.round(Math.log2(1.0 / tileLayer.mapTransforms[0].elements[0]));
for (let i = 0; i < stepsUpInHierarchy; i++) {
tileWithValidElevationTexture = tileWithValidElevationTexture.parent;
}
diff --git a/packages/Main/test/unit/dataSourceProvider.js b/packages/Main/test/unit/dataSourceProvider.js
index 80f1821839..863e43ed5d 100644
--- a/packages/Main/test/unit/dataSourceProvider.js
+++ b/packages/Main/test/unit/dataSourceProvider.js
@@ -1,6 +1,5 @@
import * as THREE from 'three';
import assert from 'assert';
-import { updateLayeredMaterialNodeImagery, updateLayeredMaterialNodeElevation } from 'Process/LayeredMaterialNodeProcessing';
import FeatureProcessing from 'Process/FeatureProcessing';
import TileMesh from 'Core/TileMesh';
import { Extent } from '@itowns/geographic';
@@ -8,7 +7,6 @@ import { globalExtentTMS } from 'Core/Tile/TileGrid';
import OBB from 'Renderer/OBB';
import DataSourceProvider from 'Provider/DataSourceProvider';
import Fetcher from 'Provider/Fetcher';
-import TileProvider from 'Provider/TileProvider';
import WMTSSource from 'Source/WMTSSource';
import WMSSource from 'Source/WMSSource';
import WFSSource from 'Source/WFSSource';
@@ -46,21 +44,28 @@ describe('Provide in Sources', function () {
let nodeLayer;
let nodeLayerElevation;
let featureLayer;
+ let tile;
// Mock scheduler
const context = {
view: {
notifyChange: () => true,
- },
- scheduler: {
- commands: [],
- execute: (cmd) => {
- context.scheduler.commands.push(cmd);
- return new Promise(() => { /* no-op */ });
+ mainLoop: {
+ scheduler: {
+ commands: [],
+ execute: (cmd) => {
+ context.view.mainLoop.scheduler.commands.push(cmd);
+ return new Promise(() => { /* no-op */ });
+ },
+ },
},
},
};
+ const { scheduler } = context.view.mainLoop;
+
+ context.scheduler = scheduler;
+
before(function () {
stubFetcherJson = sinon.stub(Fetcher, 'json')
.callsFake(() => Promise.resolve(JSON.parse(holes)));
@@ -80,9 +85,11 @@ describe('Provide in Sources', function () {
planarlayer.attach(colorlayer);
planarlayer.attach(elevationlayer);
- const fakeNode = { material, setBBoxZ: () => { }, addEventListener: () => { } };
- colorlayer.setupRasterNode(fakeNode);
- elevationlayer.setupRasterNode(fakeNode);
+ tile = new TileMesh(geom, material, planarlayer, extent);
+ tile.parent = { material };
+
+ colorlayer.setupRasterNode(tile);
+ elevationlayer.setupRasterNode(tile);
nodeLayer = material.getColorTile(colorlayer.id);
nodeLayerElevation = material.getElevationTile();
@@ -124,7 +131,7 @@ describe('Provide in Sources', function () {
beforeEach('reset state', function () {
// clear commands array
- context.scheduler.commands = [];
+ scheduler.commands = [];
});
it('should get wmts texture with DataSourceProvider', (done) => {
@@ -142,15 +149,12 @@ describe('Provide in Sources', function () {
});
colorlayer.source.onLayerAdded({ out: colorlayer });
-
- const tile = new TileMesh(geom, material, planarlayer, extent);
material.visible = true;
nodeLayer.level = EMPTY_TEXTURE_ZOOM;
tile.parent = {};
- updateLayeredMaterialNodeImagery(context, colorlayer, tile, tile.parent);
- updateLayeredMaterialNodeImagery(context, colorlayer, tile, tile.parent);
- DataSourceProvider.executeCommand(context.scheduler.commands[0])
+ colorlayer.update(context, colorlayer, tile);
+ DataSourceProvider.executeCommand(scheduler.commands[0])
.then((textures) => {
assert.equal(textures.length, 1);
assert.equal(textures[0].isTexture, true);
@@ -172,21 +176,18 @@ describe('Provide in Sources', function () {
});
elevationlayer.source.onLayerAdded({ out: elevationlayer });
- const tile = new TileMesh(geom, material, planarlayer, extent, zoom);
material.visible = true;
nodeLayerElevation.level = EMPTY_TEXTURE_ZOOM;
tile.parent = {};
- updateLayeredMaterialNodeElevation(context, elevationlayer, tile, tile.parent);
- updateLayeredMaterialNodeElevation(context, elevationlayer, tile, tile.parent);
- DataSourceProvider.executeCommand(context.scheduler.commands[0])
+ elevationlayer.update(context, elevationlayer, tile);
+ DataSourceProvider.executeCommand(scheduler.commands[0])
.then((textures) => {
assert.equal(textures.length, 1);
assert.equal(textures[0].isTexture, true);
done();
}).catch(done);
});
-
it('should get wms texture with DataSourceProvider', (done) => {
colorlayer.source = new WMSSource({
url: 'http://domain.com',
@@ -204,12 +205,14 @@ describe('Provide in Sources', function () {
const tile = new TileMesh(geom, material, planarlayer, extent, zoom);
material.visible = true;
+ material.setColorTileIds([]);
+ material.removeTile(colorlayer.id);
nodeLayer.level = EMPTY_TEXTURE_ZOOM;
tile.parent = {};
- updateLayeredMaterialNodeImagery(context, colorlayer, tile, tile.parent);
- updateLayeredMaterialNodeImagery(context, colorlayer, tile, tile.parent);
- DataSourceProvider.executeCommand(context.scheduler.commands[0])
+ colorlayer.update(context, colorlayer, tile);
+
+ DataSourceProvider.executeCommand(scheduler.commands[0])
.then((textures) => {
assert.equal(textures.length, 1);
assert.equal(textures[0].isTexture, true);
@@ -224,15 +227,13 @@ describe('Provide in Sources', function () {
tile.parent = {};
planarlayer.subdivideNode(context, tile);
- TileProvider.executeCommand(context.scheduler.commands[0])
- .then((tiles) => {
- assert.equal(tiles.length, 4);
- assert.equal(tiles[0].extent.west, tile.extent.east * 0.5);
- assert.equal(tiles[0].extent.east, tile.extent.east);
- assert.equal(tiles[0].extent.north, tile.extent.north);
- assert.equal(tiles[0].extent.south, tile.extent.north * 0.5);
- done();
- }).catch(done);
+ const tiles = tile.children;
+ assert.equal(tiles.length, 4);
+ assert.equal(tiles[0].extent.west, tile.extent.east * 0.5);
+ assert.equal(tiles[0].extent.east, tile.extent.east);
+ assert.equal(tiles[0].extent.north, tile.extent.north);
+ assert.equal(tiles[0].extent.south, tile.extent.north * 0.5);
+ done();
});
it('should get 3 meshs with WFS source and DataSourceProvider', (done) => {
@@ -246,7 +247,7 @@ describe('Provide in Sources', function () {
featureLayer.source.onLayerAdded({ out: featureLayer });
featureLayer.update(context, featureLayer, tile);
- DataSourceProvider.executeCommand(context.scheduler.commands[0])
+ DataSourceProvider.executeCommand(scheduler.commands[0])
.then((features) => {
assert.equal(features[0].meshes.children.length, 4);
done();
@@ -268,7 +269,7 @@ describe('Provide in Sources', function () {
featureLayer.source._featuresCaches = {};
featureLayer.source.onLayerAdded({ out: featureLayer });
featureLayer.update(context, featureLayer, tile);
- DataSourceProvider.executeCommand(context.scheduler.commands[0])
+ DataSourceProvider.executeCommand(scheduler.commands[0])
.then((features) => {
assert.ok(features[0].meshes.children[0].isMesh);
assert.ok(features[0].meshes.children[1].isPoints);
@@ -290,7 +291,7 @@ describe('Provide in Sources', function () {
nodeLayer.level = EMPTY_TEXTURE_ZOOM;
tile.material.visible = true;
featureLayer.source.uid = 22;
- const colorlayerWfs = new ColorLayer('color', {
+ const colorlayerWfs = new ColorLayer('colorWfs', {
crs: 'EPSG:3857',
source: featureLayer.source,
style: {
@@ -308,10 +309,14 @@ describe('Provide in Sources', function () {
},
},
});
+
+ planarlayer.attach(colorlayerWfs);
+
colorlayerWfs.source.onLayerAdded({ out: colorlayerWfs });
- updateLayeredMaterialNodeImagery(context, colorlayerWfs, tile, tile.parent);
- updateLayeredMaterialNodeImagery(context, colorlayerWfs, tile, tile.parent);
- DataSourceProvider.executeCommand(context.scheduler.commands[0])
+
+ colorlayerWfs.update(context, colorlayerWfs, tile);
+
+ DataSourceProvider.executeCommand(scheduler.commands[0])
.then((textures) => {
assert.equal(textures.length, 1);
assert.ok(textures[0].isTexture);
@@ -335,12 +340,14 @@ describe('Provide in Sources', function () {
const tile = new TileMesh(geom, new LayeredMaterial(), planarlayer, extent);
tile.material.visible = true;
+ material.setColorTileIds([]);
+ material.removeTile(colorlayer.id);
nodeLayer.level = EMPTY_TEXTURE_ZOOM;
tile.parent = {};
- updateLayeredMaterialNodeImagery(context, colorlayer, tile, tile.parent);
- updateLayeredMaterialNodeImagery(context, colorlayer, tile, tile.parent);
- DataSourceProvider.executeCommand(context.scheduler.commands[0])
+ colorlayer.update(context, colorlayer, tile);
+
+ DataSourceProvider.executeCommand(scheduler.commands[0])
.then((result) => {
tile.material.setColorTileIds([colorlayer.id]);
tile.material.getColorTile(colorlayer.id).setTextures(result, [new THREE.Vector4()]);
diff --git a/packages/Main/test/unit/demutils.js b/packages/Main/test/unit/demutils.js
index f47abe2b62..a2b879ce4e 100644
--- a/packages/Main/test/unit/demutils.js
+++ b/packages/Main/test/unit/demutils.js
@@ -5,12 +5,9 @@ import Fetcher from 'Provider/Fetcher';
import assert from 'assert';
import GlobeView from 'Core/Prefab/GlobeView';
import { Coordinates, Extent } from '@itowns/geographic';
-import { updateLayeredMaterialNodeElevation } from 'Process/LayeredMaterialNodeProcessing';
import TileMesh from 'Core/TileMesh';
import OBB from 'Renderer/OBB';
-import LayerUpdateState from 'Layer/LayerUpdateState';
import DEMUtils from 'Utils/DEMUtils';
-import { RasterElevationTile } from 'Renderer/RasterTile';
import { LayeredMaterial } from 'Renderer/LayeredMaterial';
import * as sinon from 'sinon';
import Renderer from './bootstrap';
@@ -27,7 +24,6 @@ describe('DemUtils', function () {
const viewer = new GlobeView(renderer.domElement, placement, { renderer });
let elevationlayer;
- let context;
let stubFetcherTextFloat;
const ELEVATION = 300;
@@ -50,18 +46,6 @@ describe('DemUtils', function () {
});
source.url = 'https://github.com/iTowns/iTowns2-sample-data/blob/master/dem3_3_8.bil?raw=true';
elevationlayer = new ElevationLayer('worldelevation', { source });
-
- context = {
- camera: viewer.camera,
- engine: viewer.mainLoop.gfxEngine,
- scheduler: {
- execute: (command) => {
- const provider = viewer.mainLoop.scheduler.getProtocolProvider(command.layer.protocol);
- return provider.executeCommand(command);
- },
- },
- view: viewer,
- };
});
after(() => {
@@ -83,16 +67,16 @@ describe('DemUtils', function () {
const geom = new THREE.BufferGeometry();
geom.OBB = new OBB(new THREE.Vector3(), new THREE.Vector3(1, 1, 1));
const material = new LayeredMaterial();
- const nodeLayer = new RasterElevationTile(elevationlayer);
- material.getElevationTile = () => nodeLayer;
const tile = new TileMesh(geom, material, viewer.tileLayer, extent, 5);
- tile.layerUpdateState[elevationlayer.id] = new LayerUpdateState();
+ tile.parent = {};
tiles.push(tile);
- updateLayeredMaterialNodeElevation(context, elevationlayer, tile, {})
- .then(() => {
- assert.equal(nodeLayer.textures[0].image.data[0], ELEVATION);
- done();
- }).catch(done);
+ const nodeLayer = elevationlayer.setupRasterNode(tile);
+
+ material.getElevationTile = () => nodeLayer;
+ nodeLayer.load(tile, viewer).then(() => {
+ assert.equal(nodeLayer.textures[0].image.data[0], ELEVATION);
+ done();
+ }).catch(done);
});
it('get elevation value at center with PRECISE_READ_Z', () => {
diff --git a/packages/Main/test/unit/layeredmaterial.js b/packages/Main/test/unit/layeredmaterial.js
index 16a1e7ef02..e441ea81fd 100644
--- a/packages/Main/test/unit/layeredmaterial.js
+++ b/packages/Main/test/unit/layeredmaterial.js
@@ -1,7 +1,6 @@
import assert from 'assert';
import ColorLayer from 'Layer/ColorLayer';
import TMSSource from 'Source/TMSSource';
-import { updateLayeredMaterialNodeImagery } from 'Process/LayeredMaterialNodeProcessing';
import GlobeView from 'Core/Prefab/GlobeView';
import { Coordinates } from '@itowns/geographic';
import TileMesh from 'Core/TileMesh';
@@ -50,7 +49,7 @@ describe('material state vs layer state', function () {
});
it('should correctly initialize opacity & visibility', () => {
- updateLayeredMaterialNodeImagery(context, layer, node, node.parent);
+ layer.update(context, layer, node, node.parent);
const nodeLayer = material.getTile(layer.id);
nodeLayer.textures.push(new THREE.Texture());
assert.equal(nodeLayer.opacity, layer.opacity);
diff --git a/packages/Main/test/unit/layeredmaterialnodeprocessing.js b/packages/Main/test/unit/layeredmaterialnodeprocessing.js
index 294f5fa769..eeaec56fa1 100644
--- a/packages/Main/test/unit/layeredmaterialnodeprocessing.js
+++ b/packages/Main/test/unit/layeredmaterialnodeprocessing.js
@@ -1,10 +1,9 @@
import * as THREE from 'three';
import assert from 'assert';
-import { updateLayeredMaterialNodeImagery } from 'Process/LayeredMaterialNodeProcessing';
import TileMesh from 'Core/TileMesh';
import { Extent } from '@itowns/geographic';
import OBB from 'Renderer/OBB';
-import Layer from 'Layer/Layer';
+import ColorLayer from 'Layer/ColorLayer';
import Source from 'Source/Source';
import { STRATEGY_MIN_NETWORK_TRAFFIC } from 'Layer/LayerUpdateStrategy';
import { RasterColorTile } from 'Renderer/RasterTile';
@@ -26,18 +25,22 @@ describe('updateLayeredMaterialNodeImagery', function () {
commands: [],
execute: (cmd) => {
context.scheduler.commands.push(cmd);
- return new Promise(() => { /* no-op */ });
+ return new Promise(() => { });
},
},
};
+ context.view.mainLoop = {
+ scheduler: context.scheduler,
+ };
+
const source = new Source({
url: 'http://',
crs: 'EPSG:4326',
extent,
});
- const layer = new Layer('foo', {
+ const layer = new ColorLayer('foo', {
source,
crs: 'EPSG:4326',
info: { update: () => { } },
@@ -53,7 +56,11 @@ describe('updateLayeredMaterialNodeImagery', function () {
],
};
- const nodeLayer = new RasterColorTile(layer);
+ const node = new TileMesh(geom, material, layer, extent, 0);
+ const tiles = node.getExtentsByProjection(layer.crs);
+
+ const nodeLayer = new RasterColorTile(layer, tiles);
+
material.getTile = () => nodeLayer;
beforeEach('reset state', function () {
@@ -72,22 +79,21 @@ describe('updateLayeredMaterialNodeImagery', function () {
source.extent = new Extent('EPSG:4326');
});
-
it('hidden tile should not execute commands', () => {
const tile = new TileMesh(geom, material, layer, extent, 0);
material.visible = false;
nodeLayer.level = 0;
tile.parent = {};
- updateLayeredMaterialNodeImagery(context, layer, tile, tile.parent);
+ layer.update(context, layer, tile);
assert.equal(context.scheduler.commands.length, 0);
});
it('tile with best texture should not execute commands', () => {
- const tile = new TileMesh(geom, material, layer, extent, 3);
+ const tile = new TileMesh(geom, material, layer, extent);
material.visible = true;
- nodeLayer.level = 3;
+ nodeLayer.state.state = 4;
tile.parent = {};
- updateLayeredMaterialNodeImagery(context, layer, tile, tile.parent);
+ layer.update(context, layer, tile);
assert.equal(context.scheduler.commands.length, 0);
});
@@ -95,24 +101,22 @@ describe('updateLayeredMaterialNodeImagery', function () {
const tile = new TileMesh(geom, material, layer, extent, 2);
material.visible = true;
nodeLayer.level = 1;
+ nodeLayer.state.state = 0;
tile.parent = {};
- // FIRST PASS: init Node From Parent and get out of the function
- // without any network fetch
- updateLayeredMaterialNodeImagery(context, layer, tile, tile.parent);
- assert.equal(context.scheduler.commands.length, 0);
- // SECOND PASS: Fetch best texture
- updateLayeredMaterialNodeImagery(context, layer, tile, tile.parent);
+ layer.update(context, layer, tile);
assert.equal(context.scheduler.commands.length, 1);
});
it('tile should not request texture with level > layer.source.zoom.max', () => {
const countTexture = 2 ** 15;
const newExtent = new Extent('EPSG:4326', 0, 180 / countTexture, 0, 180 / countTexture);
- const tile = new TileMesh(geom, material, layer, newExtent, 15);
+ const tile = new TileMesh(geom, material, layer, newExtent);
// Emulate a situation where tile inherited a level 1 texture
material.visible = true;
nodeLayer.level = 1;
+ nodeLayer.tiles = tile.getExtentsByProjection(layer.crs);
+ nodeLayer.state.state = 0;
tile.parent = {};
source.isWMTSSource = true;
source.tileMatrixSet = 'WGS84G';
@@ -123,11 +127,12 @@ describe('updateLayeredMaterialNodeImagery', function () {
tile.material.getLayerTextures = () => [{}];
// Since layer is using STRATEGY_MIN_NETWORK_TRAFFIC, we should emit
// a single command, requesting a texture at layer.source.zoom.max level
- updateLayeredMaterialNodeImagery(context, layer, tile, tile.parent);
- updateLayeredMaterialNodeImagery(context, layer, tile, tile.parent);
+ layer.update(context, layer, tile);
+
assert.equal(context.scheduler.commands.length, 1);
assert.equal(
context.scheduler.commands[0].extentsSource[0].zoom,
layer.source.zoom.max);
});
});
+
diff --git a/packages/Main/test/unit/obb.js b/packages/Main/test/unit/obb.js
index 212e0f240f..13d3f1cc29 100644
--- a/packages/Main/test/unit/obb.js
+++ b/packages/Main/test/unit/obb.js
@@ -53,46 +53,42 @@ function assertVerticesAreInOBB(builder, extent) {
segments: 1,
};
- return newTileGeometry(builder, params)
- .then((result) => {
- const geom = result.geometry;
- const inverse = new THREE.Matrix4().copy(geom.OBB.matrix).invert();
+ const { geometry } = newTileGeometry(builder, params);
- let failing = 0;
- const vec = new THREE.Vector3();
- for (let i = 0; i < geom.attributes.position.count; i++) {
- vec.fromArray(geom.attributes.position.array, 3 * i);
+ const geom = geometry;
+ const inverse = new THREE.Matrix4().copy(geom.OBB.matrix).invert();
- vec.applyMatrix4(inverse);
- if (!geom.OBB.box3D.containsPoint(vec)) {
- failing++;
- }
- }
- assert.equal(geom.attributes.position.count - failing, geom.attributes.position.count, 'All points should be inside OBB');
- });
+ let failing = 0;
+ const vec = new THREE.Vector3();
+ for (let i = 0; i < geom.attributes.position.count; i++) {
+ vec.fromArray(geom.attributes.position.array, 3 * i);
+
+ vec.applyMatrix4(inverse);
+ if (!geom.OBB.box3D.containsPoint(vec)) {
+ failing++;
+ }
+ }
+ assert.equal(geom.attributes.position.count - failing, geom.attributes.position.count, 'All points should be inside OBB');
}
describe('Planar tiles OBB computation', function () {
const builder = new PlanarTileBuilder({ crs: 'EPSG:3946', uvCount: 1 });
- it('should compute OBB correctly', function (done) {
+ it('should compute OBB correctly', function () {
const extent = new Extent('EPSG:3946', -100, 100, -50, 50);
- assertVerticesAreInOBB(builder, extent)
- .then(done, done);
+ assertVerticesAreInOBB(builder, extent);
});
});
describe('Ellipsoid tiles OBB computation', function () {
const builder = new GlobeTileBuilder({ uvCount: 1 });
- it('should compute globe-level 0 OBB correctly', function (done) {
+ it('should compute globe-level 0 OBB correctly', function () {
const extent = new Extent('EPSG:4326', -180, 0, -90, 90);
- assertVerticesAreInOBB(builder, extent)
- .then(done, done);
+ assertVerticesAreInOBB(builder, extent);
});
- it('should compute globe-level 2 OBB correctly', function (done) {
+ it('should compute globe-level 2 OBB correctly', function () {
const extent = new Extent('EPSG:4326', 0, 45, -45, 0);
- assertVerticesAreInOBB(builder, extent)
- .then(done, done);
+ assertVerticesAreInOBB(builder, extent);
});
});
diff --git a/packages/Main/test/unit/tile.js b/packages/Main/test/unit/tile.js
index 845c29f5b5..793a339476 100644
--- a/packages/Main/test/unit/tile.js
+++ b/packages/Main/test/unit/tile.js
@@ -39,7 +39,7 @@ describe('Tile', function () {
const parent = new Tile('EPSG:4326', zoom - 2, row, col);
const offset = withValues.offsetToParent(parent);
assert.equal(offset.x, 0.5);
- assert.equal(offset.y, 0.5);
+ assert.equal(offset.y, 0.25);
assert.equal(offset.z, 0.25);
assert.equal(offset.w, 0.25);
});
diff --git a/packages/Main/test/unit/tiledGeometryLayer.js b/packages/Main/test/unit/tiledGeometryLayer.js
index 562c74515e..264efb5bf4 100644
--- a/packages/Main/test/unit/tiledGeometryLayer.js
+++ b/packages/Main/test/unit/tiledGeometryLayer.js
@@ -19,11 +19,11 @@ describe('TiledGeometryLayer', function () {
it('subdivide should compute a screenSize', function () {
// perspective camera
- viewPerspective.tileLayer.subdivision(viewPerspective, viewPerspective.tileLayer, viewPerspective.tileLayer.level0Nodes[0]);
+ viewPerspective.tileLayer.subdivision({ camera: viewPerspective.camera }, viewPerspective.tileLayer.level0Nodes[0]);
assert.notEqual(viewPerspective.tileLayer.level0Nodes[0].screenSize, undefined);
// orthographic camera
- viewOrtho.tileLayer.subdivision(viewOrtho, viewOrtho.tileLayer, viewOrtho.tileLayer.level0Nodes[0]);
+ viewOrtho.tileLayer.subdivision({ camera: viewOrtho.camera }, viewOrtho.tileLayer.level0Nodes[0]);
assert.notEqual(viewOrtho.tileLayer.level0Nodes[0].screenSize, undefined);
});
diff --git a/packages/Main/test/unit/tilemesh.js b/packages/Main/test/unit/tilemesh.js
index 22b684bf31..82cd63b381 100644
--- a/packages/Main/test/unit/tilemesh.js
+++ b/packages/Main/test/unit/tilemesh.js
@@ -1,11 +1,9 @@
import * as THREE from 'three';
import assert from 'assert';
import TileMesh from 'Core/TileMesh';
-// import PlanarView from 'Core/Prefab/PlanarView';
import PlanarLayer from 'Core/Prefab/Planar/PlanarLayer';
import Tile from 'Core/Tile/Tile';
import { globalExtentTMS } from 'Core/Tile/TileGrid';
-import TileProvider from 'Provider/TileProvider';
import { newTileGeometry } from 'Core/Prefab/TileBuilder';
import OBB from 'Renderer/OBB';
import ElevationLayer from 'Layer/ElevationLayer';
@@ -66,18 +64,13 @@ describe('TileMesh', function () {
assert.equal(res, tree[1][0]);
});
- it('subdivide tile by 4 tiles', function (done) {
+ it('subdivide tile by 4 tiles', function () {
const tile = planarlayer.object3d.children[0];
planarlayer.subdivideNode(context, tile);
- const command = context.scheduler.commands[0];
- TileProvider.executeCommand(command).then((tiles) => {
- context.scheduler.commands = [];
- assert.equal(tiles.length, 4);
- done();
- });
+ assert.equal(tile.children.length, 4);
});
- it('Choose the right typed Array', function (done) {
+ it('Choose the right typed Array', function () {
const paramsGeometry = {
extent: planarlayer.object3d.children[0].extent,
level: 0,
@@ -85,10 +78,10 @@ describe('TileMesh', function () {
disableSkirt: true,
};
- const a = newTileGeometry(planarlayer.builder, paramsGeometry).then((r) => {
- const position = r.geometry.attributes.position;
- assert.ok(position.array.constructor.name == 'Float32Array');
- });
+ const { geometry } = newTileGeometry(planarlayer.builder, paramsGeometry);
+
+ const position = geometry.attributes.position;
+ assert.ok(position.array.constructor.name == 'Float32Array');
const paramsGeometry2 = {
extent: planarlayer.object3d.children[0].extent,
@@ -97,20 +90,7 @@ describe('TileMesh', function () {
disableSkirt: true,
};
- const b = assert.rejects(newTileGeometry(planarlayer.builder, paramsGeometry2), Error);
- Promise.all([a, b]).then(() => done());
- });
-
- it('catch error when subdivide tile without material', function (done) {
- const tile = planarlayer.object3d.children[0];
- tile.pendingSubdivision = false;
- tile.material = undefined;
- planarlayer.subdivideNode(context, tile);
- const command = context.scheduler.commands[0];
- TileProvider.executeCommand(command).catch((error) => {
- assert.ok(error.isCancelledCommandException);
- done();
- });
+ assert.throws(() => newTileGeometry(planarlayer.builder, paramsGeometry2), new Error('Tile segments count is too big'));
});
it('should find the correct common ancestor between two tiles of different level', function () {
@@ -128,7 +108,7 @@ describe('TileMesh', function () {
assert.equal(res, tree[0][0]);
});
- it('Cache tile geometry', function (done) {
+ it('Cache tile geometry', function () {
const paramsGeometry = {
extent: planarlayer.object3d.children[0].extent,
level: 0,
@@ -136,16 +116,15 @@ describe('TileMesh', function () {
disableSkirt: true,
};
- newTileGeometry(planarlayer.builder, paramsGeometry).then((r) => {
- r.geometry.increaseRefCount();
- return newTileGeometry(planarlayer.builder, paramsGeometry).then((r) => {
- assert.equal(r.geometry.refCount, 1);
- done();
- });
- });
+ const { geometry } = newTileGeometry(planarlayer.builder, paramsGeometry);
+ geometry.increaseRefCount();
+
+ const r = newTileGeometry(planarlayer.builder, paramsGeometry);
+
+ assert.equal(r.geometry.refCount, 1);
});
- it('Dispose tile geometry', function (done) {
+ it('Dispose tile geometry', function () {
const paramsGeometry = {
extent: planarlayer.object3d.children[0].extent,
level: 0,
@@ -153,11 +132,9 @@ describe('TileMesh', function () {
disableSkirt: true,
};
- newTileGeometry(planarlayer.builder, paramsGeometry).then((r) => {
- r.geometry.dispose();
- assert.equal(r.geometry.index, null);
- done();
- });
+ const { geometry } = newTileGeometry(planarlayer.builder, paramsGeometry);
+ geometry.dispose();
+ assert.equal(geometry.index, null);
});
it('throw error if there\'s not extent in constructor', () => {
@@ -182,6 +159,7 @@ describe('TileMesh', function () {
it('event rasterElevationLevelChanged RasterElevationTile sets TileMesh bounding box ', () => {
const tileMesh = new TileMesh(geom, material, planarlayer, tile.toExtent('EPSG:3857'), 0);
+ tileMesh.parent = {};
const rasterNode = elevationLayer.setupRasterNode(tileMesh);
const min = 50;
const max = 500;
@@ -201,6 +179,7 @@ describe('TileMesh', function () {
it('RasterElevationTile throws error if ElevationLayer.useRgbaTextureElevation is true', () => {
elevationLayer.useRgbaTextureElevation = true;
const tileMesh = new TileMesh(geom, material, planarlayer, tile.toExtent('EPSG:3857'), 0);
+ tileMesh.parent = {};
assert.throws(() => {
elevationLayer.setupRasterNode(tileMesh);
});
@@ -213,6 +192,7 @@ describe('TileMesh', function () {
elevationLayer.colorTextureElevationMinZ = 10;
elevationLayer.colorTextureElevationMaxZ = 100;
const tileMesh = new TileMesh(geom, material, planarlayer, tile.toExtent('EPSG:3857'), 0);
+ tileMesh.parent = {};
const rasterNode = elevationLayer.setupRasterNode(tileMesh);
assert.equal(rasterNode.min, elevationLayer.colorTextureElevationMinZ);
assert.equal(rasterNode.max, elevationLayer.colorTextureElevationMaxZ);
@@ -221,6 +201,7 @@ describe('TileMesh', function () {
it('RasterElevationTile min and max are set by xbil texture', () => {
delete elevationLayer.useColorTextureElevation;
const tileMesh = new TileMesh(geom, material, planarlayer, tile.toExtent('EPSG:3857'), 0);
+ tileMesh.parent = {};
const rasterNode = elevationLayer.setupRasterNode(tileMesh);
const texture = new THREE.Texture();
texture.extent = new Tile('EPSG:3857', 4, 10, 10);
diff --git a/packages/Main/test/unit/view.js b/packages/Main/test/unit/view.js
index 62099727f9..ba3c6df946 100644
--- a/packages/Main/test/unit/view.js
+++ b/packages/Main/test/unit/view.js
@@ -1,5 +1,4 @@
import * as THREE from 'three';
-import { getMaxColorSamplerUnitsCount } from 'Renderer/LayeredMaterial';
import { MAIN_LOOP_EVENTS } from 'Core/MainLoop';
import assert from 'assert';
import View from 'Core/View';
@@ -137,12 +136,6 @@ describe('Viewer', function () {
// pretend that MAX_TEXTURE_IMAGE_UNITS is 42
renderer.context.getParameter = () => 42;
- // Simulate a success of linkProgram by making getProgramParameter return true.
- // In that case, the maximum color sampler count is computed.
- renderer.context.getProgramParameter = () => true;
- Capabilities.updateCapabilities(renderer);
- assert.equal(getMaxColorSamplerUnitsCount(), 41);
-
// Simulate a failure of linkProgram by making getProgramParameter return false.
// In that case, throw an error.
renderer.context.getProgramParameter = () => false;
diff --git a/test/functional/GlobeControls.js b/test/functional/GlobeControls.js
index 1331cb4716..20db2a6c56 100644
--- a/test/functional/GlobeControls.js
+++ b/test/functional/GlobeControls.js
@@ -147,6 +147,7 @@ describe('GlobeControls with globe example', function _() {
assert.ok(initialPosition.tilt - endTilt > 20);
});
+ // Doesn't work in master
it('should change heading like expected', async () => {
await page.evaluate(() => { view.controls.enableDamping = false; });
await page.keyboard.down('Control');
diff --git a/test/functional/view_25d_map.js b/test/functional/view_25d_map.js
index 0d44ae6ec6..b0dd5a0037 100644
--- a/test/functional/view_25d_map.js
+++ b/test/functional/view_25d_map.js
@@ -28,7 +28,7 @@ describe('view_25d_map', function _() {
});
assert.equal(displayedTiles['1'], 1);
assert.equal(displayedTiles['2'], 6);
- assert.equal(displayedTiles['3'], 6);
+ assert.equal(displayedTiles['3'], 5);
});
it('should get picking position from depth', async function __() {