Dynamically remove Mapbox 3D terrain in Mapbox-GL - mapbox

I'm using mapbox-3d-terrain with the new version of mapbox-gl. We want to give our users the option to switch back to 2D. I would like to be able to
unset Terrain
then remove the source
This is the function to switch it 'on'.
// manage 3D terrain
enable3DTerrain() {
try {
this.map.addSource('mapbox-dem-2', {
"type": "raster-dem",
"url": "mapbox://mapbox.mapbox-terrain-dem-v1",
"tileSize": 512,
});
this.map.setTerrain({ "source": "mapbox-dem-2", 'exaggeration': 1.5 });
} catch (e) {
console.log({ e });
}
},
Is there a map function for unsetting terrain? Currently I am restarting / rebuilding / reloading the map completely to remove the 3D terrain, which is not how I want to implement my solution.

I found a simple solution how to switch map back to 2D:
this.map.setTerrain();
It works without restarting or reloading.
Then you can remove the source, and add it again if necessary.

I was dealing with the same use case. After playing around,
I found that changing {'exaggeration': 0} value to 0 in
this.map.setTerrain({ "source": "mapbox-dem-2", 'exaggeration': 1.5 })
displays the 2D view of the map.
If elevation of the map exists, set maxPitch: 0 or pitch: 0 in your initialViewState or viewState of the map conditionally to toggle between 2D & 3D.

Related

Gizmos.DrawCube display bug when multiple cubes drawn near each other

When I draw multiple cubes using Gizmos.DrawCubeto visualize some 3D tiles, I end up with a bunch of cubes inside out. It's called from Editor Code.
Here is the code for the call:
private void OnDrawGizmos() {
foreach (Vector3Int position in positions) {
Gizmos.DrawCube(position * Const.tileSize, Const.tileVectorSize);
}
}
Here is the display bug:
But everything is ok when _position only contains 1 cube
Edit: It also happens with few cubes drawn :
Any idea what is going on and how to correct it ?
This is not actually a bug. The gizmos don't write to the depth buffer. What that means (and what you see in the image) is gizmos being drawn on top of each other regardless of whether they are behind another gizmo. Maybe there is some way to enable depth buffer write or zWrite on gizmos, now you know what to look for.
What you could do in the meantime is try the Painter's algorithm. This is just sorting the gizmos from furthest from the camera to closest before you draw them.
private void OnDrawGizmos()
{
var sorted = positions.OrderByDescending((x) => Vector3.Distance(Camera.current.transform.position, x));
foreach (Vector3Int position in sorted)
{
Gizmos.DrawCube(position * Const.tileSize, Const.tileVectorSize);
}
}
And this is what it looks like:

render of low poly model tris showing very hard/marked in three.js compared to sketchfab/unit3d/Iray

I've edited this post with a clean edge flow model and maps you can access if that helps in getting feedback. I can replicate the hard marked edges issue for this case too:
I'm finding the rendering result in three.js shows very hard marked polygons of the low poly object, I'm comparing this to sketchfab , unity3d and Iray render results.
Here's a snapshot of the edge flow shown in maya : https://drive.google.com/open?id=1qNA4VoZf-rSyq3_MQdeZqdFC6BxsE3un
Here's what the model looks in maya's view panel (not subdivided): https://drive.google.com/open?id=1US-fv5-v2ygReqjRPgcsQSusrAXTxVG5
Here's a snapshot of the three.js render (marked in red box more noticeable)
https://drive.google.com/open?id=1K3CIBLvA7skVUPWL0qInLcFrK74DtriK
here sketchfabs without shadows/post-processing filters
https://drive.google.com/open?id=1rozZyBSU1HwPPk4EnKFyc7SVvFNXQBwz
here Iray render in substance painter:
https://drive.google.com/open?id=1cXJzw780-kWH0nANy5ekM0HjRKAdaVQ2
Here's Unity render: https://drive.google.com/open?id=1lLFLd8UT48OSvxJcp7arwygZZISsaHkS
Here is the fbx if you'd need to inspect mesh / edge flow: https://drive.google.com/open?id=1BwljZNKL3dWJSSca6WYlqSK7os1Hp4pT
I'm also adding the normal map as I thought the problem may relate to my three.js setup for this(?): https://drive.google.com/open?id=149r3n9JGnb9xEJkf9Eh7ELK2bM83bJX_
albedo map: https://drive.google.com/open?id=1rGgDUOKbbeE6mrAlTG_6C7b8LgqQ1DF0
I'm reusing envmap hdr example and hdr setting.
Can someone please share some thoughts on what I can try differently?
Thank you for your help, Sergio.
I tried the following:
I softened edges in maya.
I also tried the lines below separately and combined but there was not result.
//vaseMesh.geometry.mergeVertices(); and //vaseMesh.geometry.computeVertexNormals();
normalScale appears to be best at material.normalScale.x = -1;
I also tried but had same result without hdr or tonemapping settings as per displacement three.js example https://threejs.org/examples/?q=displ#webgl_materials_displacementmap
renderer = new THREE.WebGLRenderer();
renderer.toneMapping = THREE.LinearToneMapping;
//load vase material textures once loaded
manager.onLoad=function () {
material = new THREE.MeshStandardMaterial( {
color: 0xffffff,
roughness: params.roughness,
metalness: params.metalness,
map: albedoM,
normalMap: normalMap,
normalScale: new THREE.Vector2( 1, -1 ),
aoMap: aoMap,
aoMapIntensity: 1,
flatShading: true,
side: THREE.DoubleSide
} );
var myObjectLoader = new THREE.FBXLoader( );
myObjectLoader.load( "Piece1.fbx", function ( group ) {
console.log("On object loading");
var geometry = group.children[ 0 ].geometry;
geometry.attributes.uv2 = geometry.attributes.uv;
geometry.center();
vaseMesh = new THREE.Mesh( geometry, material );
vaseMesh.material=material;
//vaseMesh.geometry.mergeVertices();
//vaseMesh.geometry.computeVertexNormals();
material.normalScale.x = -1;
scene.add( vaseMesh );
console.log("Finished adding to scene");
vaseMesh.position.set(0,0,0);
animate();
} );
}
var textureLoader = new THREE.TextureLoader(manager);
var albedoM = textureLoader.load( "vaseTextures/albedo.png");
var normalMap = textureLoader.load( "vaseTextures/normal.png");
var aoMap = textureLoader.load( "vaseTextures/ao.png");
Giving credit to #Mugen87 for the answer, removing the setting flatShading to true did it!
https://discourse.threejs.org/t/render-of-low-poly-model-tris-showing-very-hard-marked-in-three-js-compared-to-sketchfab-unit3d-iray/6829/2?u=mugen87
Cheers, Sergio

Error when using Circle getBounds() and contains()

I'm getting the error below when trying to run getBounds() and contains() with a Circle shape.
leaflet.js:7 Uncaught TypeError: Cannot read property 'layerPointToLatLng' of undefined
I'm able to use it with the other shapes, but the circle is being stubborn. I tried this solution from another question, but no success.
Here's the code I have for the polygon and rectangle shapes:
drawnLayers.eachLayer(function(l) {
if (type == 'circle') {
// console.log(l.getBounds().contains(layer.getBounds()));
} else {
if (l.getBounds().contains(layer.getBounds())) {
isDonut = true;
l._latlngs.push(layer.getLatLngs());
l.redraw();
$('#map-info').append("<br>New Polygon: <pre>" +
JSON.stringify(l.getLatLngs(), null, 2) + '</pre>');
}
}
});
l.getBounds().contains(layer.getBounds())
getBounds() is a method specific only to polyline/polygon/rectangle in leaflet 0.7.x
It was added to circle shapes as of version 1.0.0 - see leaflet reference versions
To solve the problem you have 2 options
use some other methods for circles like getRadius() and compute by yourself if the shape contains your other shape
upgrade your leaflet library
Personally I would upgrade the leaflet library to 1.0.3 (which I did very easy and without any compatibility issues on my project)

easeljs create painting tools updateCache('destination-out')

I am working on a painting tools with eraser.
I don't know why when i click eraser and start to clear up.
The whole stage will become lighter.After i set updateCache('destination-out').
wrapper.addEventListener("pressup", function(event) {
console.log("up");
dragging = false;
// real_wrapper.updateCache();
if (erase == true) {
drawStroke(real_draw);
real_wrapper.updateCache('destination-out');
} else {
drawStroke(real_draw);
real_wrapper.updateCache();
tmp_draw.graphics.clear();
wrapper.updateCache();
}
ppts = [];
});
My Code: https://jsfiddle.net/steven_wong/mnfupy5o/6/
Sorry for my bad english.
You need to clear your graphics between draws. Right now your code is redrawing all of the old strokes each time, so when you're using the pencil, all the old shapes are made darker, when you're using the eraser, they become lighter.
graphics.clear();
Here's a fixed version:
https://jsfiddle.net/mnfupy5o/7/

Plot sometimes does not react to mouse input in windows forms

I'm using an ILPlotcube with line- and point-plots inside a windows forms window. Somehow the mouse control of the PlotCube, like zooming and dragging does not work anymore. For example: i can't zoom into the plot by drawing a rectangle over the region i want to see. The mouse doesn't seem to be recognized anymore.
Basically the code looks like this:
public void init() {
Thread backgroundThread = new Thread(
new ThreadStart(() =>
{
makePlot();
}));
backgroundThread.Start();
}
makePlot() looks like this:
public void makePlot()
{
ILPlotCube plotCube = _ilPanel.Scene.First<ILPlotCube>();
if (plotCube == null) {
plotCube = new ILPlotCube {
new ILLinePlot(tosingle(_data1), "plot1", lineColor: Color.Blue),
new ILLinePlot(tosingle(_data2), "plot2", lineColor: Color.Red),
new ILLegend("data1","data2")
};
_ilPanel.Scene = new ILScene { plotCube };
}
else
{
plotCube.First<ILLinePlot>(tag: "plot1").Line.Positions.Update(tosingle(_data1);
plotCube.First<ILLinePlot>(tag: "plot2").Line.Positions.Update(tosingle(_data2);
}
_ilPanel.Scene.Configure();
_ilPanel.Invoke((MethodInvoker)delegate { _ilPanel.Refresh(); });
}
I call init() in Form1_Load() not in ilPanel1_Load()
Actually there is an other thing. The Class Reference says ILLinePlot has a Method "Update" to update the positions of the plotted line. But Visual Studio tells me ILLinePlot doesn't have such a member Function. Instead i'm using
linePlot.Line.Positions.Update
Also if i don't call Configure() on the Scene Element it won't plot the legend but if i do, the whole Plotting takes much more time.
It is hard to guess without some code. But I suppose there are multiple plot cubes in your scene. And they probably use the same screen area (probably the whole panel area?). Mouse events will fire on the topmost camera object or one of its children, if configured that way. Possibly the plot cube lays "behind" some other camera object which catches all the events. You can find out by registering an event handler on the root node and print out all mouse down events:
ilPanel1.Scene.MouseDown += (_s, _e) => { Debug.WriteLine(_e.Target); };
This will give the node below the mouse which was selected as target for the mouse event during the mouse down action. In order for the (correct) plotcube to properly receive the mouse events for zoom / rotate/ pan operations there should be either the plotcube node (plotcube derives from ILCamera) or one of its children found as target.
Another easy way to inspect the scene and detect all camera nodes contained is to create a breakpoint at the very end of your setup method (mostly this will be ilPanel1_Load(..). Once you stopped in the debugger, execute the following code in the Immediate window:
ilPanel1.Scene.Find<ILCamera>()
Count = 2
[0]: "Camera: #2 - Polar r:10 φ:0° ρ:0° - Pos X:0 Y:0 Z:10 - Lookat X:0 Y:0 Z:0 - Top X:0 Y:1 Z:0"
[1]: "ILPlotCube #30 'PlotCube' Children:[2]"
How many plot cubes do you count?
I got it to work after i switched
ilpanel.Scene = new ILScene { plotCube }
to
ilpanel.Scene.Add( plotCube )