Map skips frames when mouse_move handler is used

Hi there,

I'm trying to implement a simple map with around 20 pins that you can hover on to change the style of the billboard and then click on which then zooms you in and more info is displayed (info is in a html overlay outside cesium). However when the user moves their mouse whilst the map is being zoomed in, it lags loads and skips a lot of frames.

I'm using a handler to test when a billboard is being hovered over:

       handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
        handler.setInputAction(function(movement) {
            var pickedObject = scene.pick(movement.endPosition);

        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

When I remove this part of the code the amp does not lag at all. Is there a more performant way of checking for mouse over on a billboard?

I'm using Chrome on a mac running High Sierra 10.13.2 but am also seeing it on other devices.

Many thanks

Just confirm, if you leave this code as is but comment out the scene.pick line, is the performance good?

What scene.pick does is it will render the scene to a small framebuffer, and then read those pixels back to figure out what the mouse clicked on. Both the rendering and the reading back of the pixels are expensive operations. I think a way to make this much faster, especially if the objects you’re picking are fairly rectangular/flat, is simply to convert the billboard’s 3D position to a 2D position on the screen using this function:

https://cesiumjs.org/Cesium/Build/Documentation/SceneTransforms.html#.wgs84ToWindowCoordinates

And similarly convert the 4 corners if you know the size of the billboard, and then compare those screen coordinates against the mouse coordinates. It’s a bit more work, and it won’t take into account if the billboard is occluded by something in front of it, but it might be a good solution in some cases.

Hi Omar,

Yes, removing the scene.pick line removes any obvious performance issues.

The objects are completely flat but triangle shaped so I guess I’ll need to do some sort of trigonometry to work out if they’re being hovered on.

I was also wondering if Cesium offers any easing for hover effects as the pins are red and I want them to turn green on hover. At the moment I’m just switching out the image but it would be much better if we could just change a property on a shape and add easing to that.

Thanks

David

For computations like that, Turfjs is a pretty good lightweight library. There’s a function that takes a point and a polygon and returns whether it’s inside:

http://turfjs.org/docs/#booleanPointInPolygon

So you could use that for mouse clicks and triangles.

For tweening, Cesium does actually embed the popular Tweenjs library:

https://github.com/AnalyticalGraphicsInc/cesium/issues/7597#issuecomment-482567503

Which is used for the camera flyTos. It’s a private class right now, but it can be accessed through viewer.scene.tweens:

https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Scene/TweenCollection.js

So I think what you’d have to do is set a callback property that just returns some stored value, and then you can use the tweening library (either this or your own) and have it change that stored value.

Let me know how it ends up working for you! I wonder if it’d be useful to have a code example for this on Sandcastle.