How to change billboard content dynamically?

1,860 views
Skip to first unread message

Premkumar Jayaseelan

unread,
Jul 30, 2015, 10:01:01 AM7/30/15
to cesium-dev
Hi,

I want to change the billboard content dynamically. Meaning, without re-render the billboard; I should able to render the content inside the billboard.

E.g. Changing the color of the context to "red".

context.fillStyle = color;

var viewer = new Cesium.Viewer('cesiumContainer', {
    infoBox : false,
    selectionIndicator : false
});

function createModel(url, height) {
    viewer.entities.removeAll();

    var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, height);
    var heading = Cesium.Math.toRadians(135);
    var pitch = 0;
    var roll = 0;
    var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, heading, pitch, roll);

    var entity = viewer.entities.add({
        name : url,
        position : position,
        orientation : orientation,
        model : {
            uri : url,
            minimumPixelSize : 128
        }, billboard: {
           image: drawImage("blue")
        }
    });
    viewer.trackedEntity = entity;
}

 function drawImage(color) {
                // create and draw an image using a canvas
                var canvas = document.createElement('canvas');
                var context = canvas.getContext('2d');

                context.fillStyle = color;
                context.fillRect(10, 20, 100, 50);

                context.strokeStyle = '#fa00ff';
                context.lineWidth = 5;
                context.lineCap = 'round';
                context.arc(50, 50, 20, 0, Math.PI, false);
                context.stroke();
                // ... draw image
                return canvas;
            }

 var handle = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

 handle.setInputAction(function (movement) {
  handle.setInputAction((movement) => {
                    var pick = scene.pick(movement.position);
                    if (Cesium.defined(pick) && Cesium.defined(pick.node) && Cesium.defined(pick.mesh)) {
                        selectedMesh = pick;

                       // Change the model color alone....
                        //selectedMesh.id.billboard.image......
                    } else {
                        selectedMesh = null;
                    }
                }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

var options = [{
    text : 'Aircraft',
    onselect : function() {
        createModel('../../SampleData/models/CesiumAir/Cesium_Air.bgltf', 5000.0);
    }
}, {
    text : 'Ground vehicle',
    onselect : function() {
        createModel('../../SampleData/models/CesiumGround/Cesium_Ground.bgltf', 0);
    }
}, {
    text : 'Milk truck',
    onselect : function() {
        createModel('../../SampleData/models/CesiumMilkTruck/CesiumMilkTruck.bgltf', 0);
    }
}, {
    text : 'Skinned character',
    onselect : function() {
        createModel('../../SampleData/models/CesiumMan/Cesium_Man.bgltf', 0);
    }
}];

Sandcastle.addToolbarMenu(options);


I can re-render the content dynamically from the below line on mouse_left_down. It will re draw the billboard :(

selectedMesh.id.billboard.image = drawImage("white");

But, I don't want to re-render the entire canvas. I should only change the partial content.

Can anyone give some lights on to this thread.

Premkumar Jayaseelan

unread,
Jul 30, 2015, 10:37:03 AM7/30/15
to cesium-dev, vlrp...@gmail.com
I want to achieve similar to this demo. They are changing the speed dynamically... Any idea how it is working?

Mark Erikson

unread,
Jul 30, 2015, 11:53:54 AM7/30/15
to cesium-dev, vlrp...@gmail.com
If you're talking about the section in the upper-left with "Speed", "Distance", "Gradient", and "Time", that appears to be a canvas that's part of the DOM, not one that's being uploaded to Cesium for use with a billboard.

As for dynamically updating a billboard... re-uploading the image is the only way I know of, because Cesium has to copy the image to the internal TextureAtlas that the BillboardCollection is using.  There's also no way currently to have the new billboard image "replace" the old one in the TextureAtlas, so doing lots of updates can eventually cause the TextureAtlas to resize itself too big and run out of memory.  There's a couple existing threads discussing this limitation.

Premkumar Jayaseelan

unread,
Aug 1, 2015, 4:56:59 AM8/1/15
to cesium-dev, vlrp...@gmail.com
Thank you Mark! I shall go with re-uploading the billboard image dynamically. 

Let me know, if you have any better solution or any other way to show a popup information as shown in the demo.

Thank you again!

Matthew Amato

unread,
Aug 17, 2015, 4:18:20 PM8/17/15
to cesiu...@googlegroups.com
As Mark alluded too, depending on your requirements, it might be better to use a pop-up HTML overlay instead of a billboard to do what you want.  Check out this example I posted a few days ago: https://groups.google.com/d/msg/cesium-dev/hP5wjNeOWzo/dq7frk-_AwAJ  This can be used to render any kind of HTML overlay, such as the stats your reference image was showing.

--
You received this message because you are subscribed to the Google Groups "cesium-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cesium-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages