Skip to content

Commit

Permalink
feat(layer): add full support to scaling for elevation layers
Browse files Browse the repository at this point in the history
Changing the `scale` property of an `ElevationLayer` can changed the
aspect of the visual, allowing exageration of the elevation of the
globe, as in the tiff.html example.

This is an up-to-date version of #511
  • Loading branch information
zarov committed Jul 30, 2019
1 parent b9f3b77 commit e736d1f
Show file tree
Hide file tree
Showing 14 changed files with 130 additions and 23 deletions.
4 changes: 4 additions & 0 deletions examples/js/GUI/GuiTools.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ GuiTools.prototype.addElevationLayerGUI = function addElevationLayerGUI(layer) {
folder.add({ frozen: layer.frozen }, 'frozen').onChange(function refreshFrozenGui(value) {
layer.frozen = value;
});
folder.add({ scale: layer.scale }, 'scale').min(1.0).max(20000.0).onChange((function updateScale(value) {
layer.scale = value;
this.view.notifyChange(layer);
}).bind(this));
};

GuiTools.prototype.addImageryLayersGUI = function addImageryLayersGUI(layers) {
Expand Down
50 changes: 50 additions & 0 deletions examples/layers/JSONLayers/GeoidMNT.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"id": "GEOIDMNT",
"noDataValue" : -99999,
"updateStrategy": {
"type": 0
},
"source": {
"url": "https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/geoid/geoid/bil/%TILEMATRIX/geoid_%COL_%ROW.bil",
"format": "image/x-bil;bits=32",
"projection": "EPSG:4326",
"tileMatrixSet": "WGS84G",
"tileMatrixSetLimits": {
"0": {
"minTileRow": 0,
"maxTileRow": 0,
"minTileCol": 0,
"maxTileCol": 1
},
"1": {
"minTileRow": 0,
"maxTileRow": 1,
"minTileCol": 0,
"maxTileCol": 3
},
"2": {
"minTileRow": 0,
"maxTileRow": 3,
"minTileCol": 0,
"maxTileCol": 7
},
"3": {
"minTileRow": 0,
"maxTileRow": 7,
"minTileCol": 0,
"maxTileCol": 15
},
"4": {
"minTileRow": 0,
"maxTileRow": 15,
"minTileCol": 0,
"maxTileCol": 31
}
},
"zoom": {
"min": 0,
"max": 4
}
}
}

1 change: 1 addition & 0 deletions examples/planar.html
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
if (view.isDebugMode) {
menuGlobe = new GuiTools('menuDiv', view);
menuGlobe.addImageryLayersGUI(view.getLayers(function gui(l) { return l.isColorLayer; }));
menuGlobe.addElevationLayerGUI(wmsElevationLayer);
d = new debug.Debug(view, menuGlobe.gui);
debug.createTileDebugUI(menuGlobe.gui, view, view.tileLayer, d);
}
Expand Down
17 changes: 17 additions & 0 deletions examples/tiff.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<script src="js/GUI/GuiTools.js"></script>
<script src="https://cdn.jsdelivr.net/npm/utif@3.1.0/UTIF.js"></script>
<script src="../dist/itowns.js"></script>
<script src="../dist/debug.js"></script>
<script src="js/loading_screen.js"></script>
<script src="js/TIFFParser.js"></script>
<script type="text/javascript">
Expand Down Expand Up @@ -47,6 +48,22 @@
});

view.addLayer(tiffLayer).then(menuGlobe.addLayerGUI.bind(menuGlobe));

function addElevationLayerFromConfig(config) {
config.source = new itowns.TMSSource(config.source);
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer).then(function _(layer) {
layer.scale = 10000;
view.tileLayer.attachedLayers[0].visible = false;
menuGlobe.addLayerGUI(layer);
menuGlobe.elevationGui.open();
menuGlobe.elevationGui.__folders.GEOIDMNT.open();
});
}
itowns.Fetcher.json('./layers/JSONLayers/GeoidMNT.json').then(addElevationLayerFromConfig);

const d = new debug.Debug(view, menuGlobe.gui);
debug.createTileDebugUI(menuGlobe.gui, view, view.tileLayer, d);
</script>
</body>
</html>
9 changes: 5 additions & 4 deletions src/Converter/convertToTile.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ function setTileFromTiledLayer(tile, tileLayer) {
const alpha = dimensions.length();
const h = Math.abs(1.0 / Math.cos(alpha * 0.5));
tile.horizonCullingPoint.setLength(h * tile.horizonCullingPoint.length());
tile.horizonCullingPointElevationScaled = tile.horizonCullingPoint.clone();
}
}

Expand Down Expand Up @@ -74,14 +75,14 @@ export default {
tile.visible = false;
tile.updateMatrix();

if (parent) {
tile.setBBoxZ(parent.obb.z.min, parent.obb.z.max);
}

tile.add(tile.obb);

setTileFromTiledLayer(tile, layer);

if (parent) {
tile.setBBoxZ(parent.obb.z.min, parent.obb.z.max);
}

return tile;
});
},
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Prefab/Globe/GlobeLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class GlobeLayer extends TiledGeometryLayer {
}

// see https://cesiumjs.org/2013/04/25/Horizon-culling/
scaledHorizonCullingPoint.copy(node.horizonCullingPoint).applyMatrix4(worldToScaledEllipsoid);
scaledHorizonCullingPoint.copy(node.horizonCullingPointElevationScaled).applyMatrix4(worldToScaledEllipsoid);
scaledHorizonCullingPoint.sub(cameraPosition);

const vtMagnitudeSquared = scaledHorizonCullingPoint.lengthSq();
Expand Down
8 changes: 6 additions & 2 deletions src/Core/TileMesh.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,18 @@ class TileMesh extends THREE.Mesh {
*
* @param {?number} min
* @param {?number} max
* @param {?number} scale
*/
setBBoxZ(min, max) {
setBBoxZ(min, max, scale) {
if (min == undefined && max == undefined) {
return;
}
// FIXME: Why the floors ? This is not conservative : the obb may be too short by almost 1m !
if (Math.floor(min) !== Math.floor(this.obb.z.min) || Math.floor(max) !== Math.floor(this.obb.z.max)) {
this.obb.updateZ(min, max);
this.obb.updateZ(min, max, scale);
if (this.horizonCullingPointElevationScaled) {
this.horizonCullingPointElevationScaled.setLength(this.obb.z.delta + this.horizonCullingPoint.length());
}
this.obb.box3D.getBoundingSphere(this.boundingSphere);
}
}
Expand Down
18 changes: 18 additions & 0 deletions src/Layer/ElevationLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import textureConverter from 'Converter/textureConverter';
* @property {boolean} isElevationLayer - Used to checkout whether this layer is
* an ElevationLayer. Default is true. You should not change this, as it is used
* internally for optimisation.
* @property {number} scale - Used to apply a scale on the elevation value. It
* can be used for exageration of the elevation, like in [this
* example](https://www.itowns-project.org/itowns/examples/tiff.html).
*/
class ElevationLayer extends Layer {
/**
Expand Down Expand Up @@ -41,6 +44,21 @@ class ElevationLayer extends Layer {
constructor(id, config = {}) {
super(id, config);
this.isElevationLayer = true;

// This is used to add a factor needed to color texture
let baseScale = 1.0;
if (this.useColorTextureElevation) {
baseScale = this.colorTextureElevationMaxZ - this.colorTextureElevationMinZ;
}

this.defineLayerProperty('scale', this.scale || 1.0, (self) => {
self.parent.object3d.traverse((obj) => {
if (obj.layer == self.parent && obj.material) {
obj.material.setElevationScale(self.scale * baseScale);
obj.obb.updateScaleZ(self.scale);
}
});
});
}

update(context, layer, node, parent) {
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/XbilParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function computeMinMaxElevation(buffer, width, height, pitch) {
const pit = y * (width || 0);
for (let x = xs; x < xs + sizeX; x += inc) {
const val = buffer[pit + x];
if (val > -10.0) {
if (val > -10) {
max = Math.max(max, val);
min = Math.min(min, val);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Process/LayeredMaterialNodeProcessing.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,11 @@ export function updateLayeredMaterialNodeElevation(context, layer, node, parent)
const useMinMaxFromParent = extentsDestination[0].zoom - nodeLayer.zoom > 6;
if (nodeLayer.textures[0]) {
if (!useMinMaxFromParent) {
const { min, max } = computeMinMaxElevation(
const { min, max } = computeMinMaxElevation(
nodeLayer.textures[0].image.data,
SIZE_TEXTURE_TILE, SIZE_TEXTURE_TILE,
nodeLayer.offsetScales[0]);
node.setBBoxZ(min, max);
node.setBBoxZ(min, max, layer.scale);
} else {
// TODO: to verify we don't pass here,
// To follow issue, see #1011 https://github.com/iTowns/itowns/issues/1011
Expand Down Expand Up @@ -266,7 +266,7 @@ export function updateLayeredMaterialNodeElevation(context, layer, node, parent)
}
}

node.setBBoxZ(elevation.min, elevation.max);
node.setBBoxZ(elevation.min, elevation.max, layer.scale);
nodeLayer.setTexture(0, elevation.texture, elevation.pitch);
const nodeParent = parent.material && parent.material.getElevationLayer();
nodeLayer.replaceNoDataValueFromParent(nodeParent, layer.noDataValue);
Expand Down
6 changes: 6 additions & 0 deletions src/Renderer/LayeredMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,12 @@ class LayeredMaterial extends THREE.RawShaderMaterial {
getElevationLayer() {
return this.layers.find(l => l.id === this.elevationLayerIds[0]);
}

setElevationScale(scale) {
if (this.elevationLayerIds.length) {
this.getElevationLayer().scale = scale;
}
}
}

export default LayeredMaterial;
11 changes: 5 additions & 6 deletions src/Renderer/MaterialLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,21 @@ class MaterialLayer {
zmax: Infinity,
};

let scaleFactor = 1.0;

// Define elevation properties
if (layer.useRgbaTextureElevation) {
defaultEle.mode = ELEVATION_MODES.RGBA;
defaultEle.zmax = 5000;
throw new Error('Restore this feature');
} else if (layer.useColorTextureElevation) {
scaleFactor = layer.colorTextureElevationMaxZ - layer.colorTextureElevationMinZ;
defaultEle.mode = ELEVATION_MODES.COLOR;
// ?? pourquoi defaultEle.zmin et zmax ne sont pas
const zmin = layer.colorTextureElevationMinZ;
const zmax = layer.colorTextureElevationMaxZ;
defaultEle.scale = zmax - zmin;
defaultEle.bias = zmin;
defaultEle.bias = layer.colorTextureElevationMinZ;
}

defineLayerProperty(this, 'bias', layer.bias, defaultEle.bias);
defineLayerProperty(this, 'scale', layer.scale, defaultEle.scale);
defineLayerProperty(this, 'scale', layer.scale * scaleFactor, defaultEle.scale * scaleFactor);
defineLayerProperty(this, 'mode', layer.mode, defaultEle.mode);
defineLayerProperty(this, 'zmin', layer.zmin, defaultEle.zmin);
defineLayerProperty(this, 'zmax', layer.zmax, defaultEle.zmax);
Expand Down
18 changes: 13 additions & 5 deletions src/Renderer/OBB.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class OBB extends THREE.Object3D {
super();
this.box3D = new THREE.Box3(min.clone(), max.clone());
this.natBox = this.box3D.clone();
this.z = { min: 0, max: 0 };
this.z = { min: 0, max: 0, scale: 1.0 };
return this;
}

Expand All @@ -48,6 +48,7 @@ class OBB extends THREE.Object3D {
this.natBox.copy(cOBB.natBox);
this.z.min = cOBB.z.min;
this.z.max = cOBB.z.max;
this.z.scale = cOBB.z.scale;
return this;
}

Expand All @@ -64,11 +65,18 @@ class OBB extends THREE.Object3D {
*
* @param {number} min The minimum of oriented bounding box
* @param {number} max The maximum of oriented bounding box
* @param {number} scale
*/
updateZ(min, max) {
this.z = { min, max };
this.box3D.min.z = this.natBox.min.z + min;
this.box3D.max.z = this.natBox.max.z + max;
updateZ(min, max, scale = this.z.scale) {
this.z = { min, max, scale, delta: Math.abs(max - min) * scale };
this.box3D.min.z = this.natBox.min.z + min * scale;
this.box3D.max.z = this.natBox.max.z + max * scale;
}

updateScaleZ(scale) {
if (scale > 0) {
this.updateZ(this.z.min, this.z.max, scale);
}
}

/**
Expand Down
1 change: 0 additions & 1 deletion src/Renderer/Shader/Chunk/elevation_pars_vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
float getElevation(vec2 uv, sampler2D texture, vec4 offsetScale, Layer layer) {
uv = uv * offsetScale.zw + offsetScale.xy;
float d = getElevationMode(uv, texture, layer.mode);
if (d < layer.zmin || d > layer.zmax) d = 0.;
return d * layer.scale + layer.bias;
}
#endif

0 comments on commit e736d1f

Please sign in to comment.