Polyline update at mouse position shutter

I’m trying to set up a system to allow a user to place objects in my scene.

Before I explain anything I’ll preface by pointing to the snippet of code that can be found below and run in the sandcastle to demonstrate the issue.

The first click will set the position and the second click will set the angle of rotation. To display the angle to the user, I have one polyline that goes from the selected position straight north, and another polyline that has one point on the selected position and the other attached to the mouse.

When I am moving the mouse around, the polyline attached to the mouse only updates when the mouse slows down or stops moving, giving it a shutter effect, yet the label updates constantly. What can I do to have the polyline update smoothly with the mouse?

I’m also curious why the angle measurement goes from -90 to 270 degrees and not 0 to 360?

var viewer = new Cesium.Viewer(‘cesiumContainer’);

var scene = viewer.scene;

var ellipsoid = scene.globe.ellipsoid;

var entity = viewer.entities.add({

label: {

show: false

}

});

var entitytwo = viewer.entities.add({

polyline: {

show: false,

width: 2,

material: Cesium.Color.YELLOW

}

});

var entitythree = viewer.entities.add({

polyline: {

show: false,

width: 1,

material: Cesium.Color.YELLOW

}

});

var lla = ,

stage = 0,

degree = 0,

cartesian,

cartographic,

cartographictwo;

var positionHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);

positionHandler.setInputAction(function (movement) {

if (stage === 0) {

cartesian = scene.camera.pickEllipsoid(movement.endPosition, ellipsoid);

if (cartesian) {

cartographic = ellipsoid.cartesianToCartographic(cartesian);

var longitudeString = Cesium.Math.toDegrees(cartographic.longitude).toFixed(4);

var latitudeString = Cesium.Math.toDegrees(cartographic.latitude).toFixed(4);

entity.position = cartesian;

entity.label.show = true;

entity.label.text = ‘(’ + longitudeString + ', ’ + latitudeString + ‘)’;

} else {

entity.label.show = false;

}

}else if (stage === 1){

var cartesiantwo = scene.camera.pickEllipsoid(movement.endPosition, ellipsoid);

if (cartesiantwo) {

cartographictwo = ellipsoid.cartesianToCartographic(cartesiantwo);

var dlat = cartographictwo.latitude - cartographic.latitude;

var dlon = cartographictwo.longitude - cartographic.longitude;

degree = Cesium.Math.toDegrees(Math.PI / 2.0 - Math.atan2(dlat, dlon));

entity.position = cartesiantwo;

entity.label.show = true;

entity.label.text = '(Rotation: ’ + degree + ‘)’;

entitytwo.polyline.positions = [cartesian, cartesiantwo];

entitytwo.polyline.show = true;

entitythree.polyline.positions = Cesium.Cartesian3.fromDegreesArray([lla[0], lla[1], lla[0], 90]);

entitythree.polyline.show = true;

} else {

entity.label.show = false;

}

}

}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

positionHandler.setInputAction(function (click) {

if (stage === 0) {

cartesian = scene.camera.pickEllipsoid(click.position, ellipsoid);

if (cartesian) {

cartographic = ellipsoid.cartesianToCartographic(cartesian);

lla = [

Cesium.Math.toDegrees(cartographic.longitude),

Cesium.Math.toDegrees(cartographic.latitude),

Cesium.Math.toDegrees(cartographic.height)

];

var positions = [cartographic.longitude, cartographic.latitude];

stage = 1;

entity.label.show = false;

}

}else if (stage === 1) {

positionHandler = positionHandler && positionHandler.destroy();

}

}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

``

Dear Brent,

if I understanderstand your problem correctly, I would suggest looking up CallbackProperties, which seem to be meant for solving really dynamic updating of i.e. positions. I had a similar problem in the last days and ultimately found this post here from Mathew https://groups.google.com/d/msg/cesium-dev/BqhefLtPsLg/0tq7MD8HH98J.
It pretty much describes the idea behind different properties and should imho be made part of the official documentation.

For now - though I am still in the process of evaluating everything - this approach solved my problem with flickering and “hopping” behavior when changing position properties the way you did.
I.e. in your mouse handler, you can modify “your own” position variable and in the callback (which from my understanding gets called every frame) you just return the content of “your own” position variable.

Kind Regards,
Sebastian

That worked perfectly. Thank you!

Still haven’t figured out the angle issue but that’s likely just an error in my math.

Hi Brent,

I want to ask you something about your code.

This is my first time using Cesium and I want to make “on-click polyline drawing” code, and that’s how I found this grups.
So, I modified your code like this :

var viewer = new Cesium.Viewer(‘cesiumContainer’);

var scene = viewer.scene;

var ellipsoid = scene.globe.ellipsoid;

var entity1 = viewer.entities.add({

label: {

    show: false

}

});

var entity2 = viewer.entities.add({

polyline: {

    show: false,

    width: 2,

    material: Cesium.Color.YELLOW

}

});

var entity3 = viewer.entities.add({

polyline: {

    show: false,

    width: 2,

    material: Cesium.Color.YELLOW

}

});

var entity4 = viewer.entities.add({

polyline: {

    show: false,

    width: 2,

    material: Cesium.Color.YELLOW

}

});

var lla = ,

lla2 = [],

stage = 0,

degree = 0,

cartesian,

cartesiantwo,

cartesianthree,

cartographic,

cartographictwo,

cartographicthree;

var positionHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);

positionHandler.setInputAction(function (movement) {

if (stage === 0) {

    cartesian = scene.camera.pickEllipsoid(movement.endPosition, ellipsoid);

    if (cartesian) {

        cartographic = ellipsoid.cartesianToCartographic(cartesian);

        entity1.position = cartesian;

        entity1.label.show = true;

    } else {

        entity1.label.show = false;

    }

}else if (stage === 1){

    cartesiantwo = scene.camera.pickEllipsoid(movement.endPosition, ellipsoid);

    if (cartesiantwo) {

        cartographictwo = ellipsoid.cartesianToCartographic(cartesiantwo);

        entity1.position = cartesiantwo;

        entity1.label.show = true;

        entity2.polyline.positions = [cartesian, cartesiantwo];

        entity2.polyline.show = true;

        entity3.polyline.positions = Cesium.Cartesian3.fromDegreesArray([lla[0], lla[1], lla[0], 90]);

        entity3.polyline.show = true;

    } else {

        entity1.label.show = false;

    }

}else if (stage === 2){

    cartesianthree = scene.camera.pickEllipsoid(movement.endPosition, ellipsoid);

    if (cartesianthree) {

        cartographicthree = ellipsoid.cartesianToCartographic(cartesianthree);

        entity2.position = cartesianthree;

        entity2.polyline.positions = [cartesiantwo, cartesianthree];

        entity3.polyline.show = true;

        entity4.polyline.positions = Cesium.Cartesian3.fromDegreesArray([lla2[0], lla2[1], lla2[0], 90]);

        entity4.polyline.show = true;

    } else {

        entity1.label.show = false;

    }

}

}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

positionHandler.setInputAction(function (click) {

if (stage === 0) {

    cartesian = scene.camera.pickEllipsoid(click.position, ellipsoid);

    if (cartesian) {

        cartographic = ellipsoid.cartesianToCartographic(cartesian);

        lla = [

            Cesium.Math.toDegrees(cartographic.longitude),

            Cesium.Math.toDegrees(cartographic.latitude),

            Cesium.Math.toDegrees(cartographic.height)

        ];

        var positions1 = [cartographic.longitude, cartographic.latitude];

        stage = 1;

        entity1.label.show = false;

    }

}else if (stage === 1) {

    cartesiantwo = scene.camera.pickEllipsoid(click.position, ellipsoid);

    if (cartesiantwo) {

        cartographictwo = ellipsoid.cartesianToCartographic(cartesiantwo);

        lla2 = [

            Cesium.Math.toDegrees(cartographictwo.longitude),

            Cesium.Math.toDegrees(cartographictwo.latitude),

            Cesium.Math.toDegrees(cartographictwo.height)

        ];

        var positions2 = [cartographictwo.longitude, cartographictwo.latitude];

        stage = 2;



}else if (stage === 2) {

    positionHandler = positionHandler && positionHandler.destroy();

}}

}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

The idea is to draw continued polyline, but I got it always back to the north pole. Can you help me fix my problem?

Thank you

Regards,

Yuvita