Position Billboard

Hi,

I’m trying to load the billboard in top of the 3D model(gltf). But it is not rendering as expected. If the verticalOrigin is set to BOTTOM. The billboard is snapping with the model. If I change to TOP. The billboard position is changing with respect to the camera view.

Find the sandcastle code below.

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

var pinBuilder = new Cesium.PinBuilder();

function createModel1(url, lat, long, height, billboard) {

var position = Cesium.Cartesian3.fromDegrees(lat, long, height);

var billboardPosition = Cesium.Cartesian3.fromDegrees(lat, long, height + 10);

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 : “Cesium Milk Truck”,

position : position,

orientation : orientation,

model : {

uri : url,

minimumPixelSize : 0

},

billboard: {

image: billboard,

show: true,

verticalOrigin: Cesium.VerticalOrigin.BOTTOM,

position: billboardPosition

}

});

viewer.trackedEntity = entity;

}

function createModel2(url, lat, long, height, billboard) {

var position = Cesium.Cartesian3.fromDegrees(lat, long, 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 : “Cesium Ground”,

position : position,

orientation : orientation,

model : {

uri : url,

minimumPixelSize : 0

},

billboard: {

image: billboard,

show: true,

verticalOrigin: Cesium.VerticalOrigin.TOP

}

});

viewer.trackedEntity = entity;

}

var cesium_milk_truck = pinBuilder.fromText(“Cesium Milk Truck”, Cesium.Color.WHITE, 50).toDataURL();

createModel1(’…/…/SampleData/models/CesiumMilkTruck/CesiumMilkTruck.bgltf’,-123.0744619, 44.0503706, 0, cesium_milk_truck);

var cesium_ground_billboard = pinBuilder.fromColor(Cesium.Color.ROYALBLUE, 48).toDataURL();

createModel2(’…/…/SampleData/models/CesiumGround/Cesium_Ground.bgltf’, -123.0745619, 44.0503906, 0, cesium_ground_billboard);

var billboardPosition1 = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0504106, 5);
var position1 = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0504106);

viewer.entities.add({
name : ‘Blank blue pin’,
position: billboardPosition1,
billboard : {
image : pinBuilder.fromColor(Cesium.Color.ROYALBLUE, 48).toDataURL(),
verticalOrigin : Cesium.VerticalOrigin.TOP

},
    polyline: {
        positions: [position1, billboardPosition1],
        width: 1,
        followSurface: false,
        show: true,
        verticalOrigin: Cesium.VerticalOrigin.TOP,
        horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
        material: Cesium.Color.ROYALBLUE,
        eyeOffset: new Cesium.Cartesian3(0.0, 0.0, -10.0), // Negative Z will make it closer to the camera
        pixelOffset: new Cesium.Cartesian2(0.0, -150.0) // Optional offset in pixels relative to center
    }

});

``

``

Also, billboard is having a properties called “position”. When I try to set the value to that. It is not working. I suppose to load the billboard in top of the polyline. If I give the position on entity level it is working. i.e. taking model position as entity position.

var billboardPosition1 = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0504106, 5);

``
var position1 = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0504106);

viewer.entities.add({

name : ‘Blank blue pin’,

    position: billboardPosition1  

billboard : {

image : pinBuilder.fromColor(Cesium.Color.ROYALBLUE, 48).toDataURL(),

verticalOrigin : Cesium.VerticalOrigin.TOP,

    position: billboardPosition1  

},

polyline: {

positions: [position1, billboardPosition1],

width: 1,

followSurface: false,

show: true,

verticalOrigin: Cesium.VerticalOrigin.TOP,

horizontalOrigin: Cesium.HorizontalOrigin.CENTER,

material: Cesium.Color.ROYALBLUE,

eyeOffset: new Cesium.Cartesian3(0.0, 0.0, -10.0), // Negative Z will make it closer to the camera

pixelOffset: new Cesium.Cartesian2(0.0, -150.0) // Optional offset in pixels relative to center

}

});

In the sandcastle example, the Cesium Ground model billboard is not snapping with the model. Also trying to load the billboard in top of the model.

Is’t possible to load the billboard in top of the model or in top of the polyline?

Thanks in advance!

Hello,

The verticalOrigin property for the billboard determines which part of the billboard should be placed at the Cartesian3 position. For a pin, you almost always want VerticalOrigin.BOTTOM because that will place the pin point at the desired position.

To make the billboard appear above the model, you can use the eyeOffset property. This offsets the billboard relative to it’s position. Here’s an example:

    billboard: {
        image: billboard,
        show: true,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        eyeOffset: new Cesium.Cartesian3(0, modelHeight, 0)
    }

``

Setting the y value to the height of the model will place it above the model.

Best,

Hannah

Thanks Hannah. It worked perfectly!

I’m facing challenge to set the billboard exactly top of the model. i.e. finding the height of the model (Setting “y” value to modelHeight ?)

Can you help me with the below code?

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

var pinBuilder = new Cesium.PinBuilder();

function createModel(url, lat, long, height, billboard) {

var position = Cesium.Cartesian3.fromDegrees(lat, long, height);

var billboardPosition = Cesium.Cartesian3.fromDegrees(lat, long, height + 10);

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 : “Cesium Milk Truck”,

position : position,

orientation : orientation,

model : {

uri : url,

minimumPixelSize : 0

},

billboard: {

image: billboard,

show: true,

verticalOrigin: Cesium.VerticalOrigin.BOTTOM,

eyeOffset: new Cesium.Cartesian3(0, 3.0504106, 0)

}

});

viewer.trackedEntity = entity;

}

var cesium_milk_truck = pinBuilder.fromText(“Cesium Milk Truck”, Cesium.Color.WHITE, 50).toDataURL();

createModel(’…/…/SampleData/models/CesiumMilkTruck/CesiumMilkTruck.bgltf’,-123.0744619, 44.0503706, 0, cesium_milk_truck);

``

Sorry, I don’t know of a good way to do this programatically. Also, if the pin is exactly on top of the model it goes inside the model at certain camera angles. If you want to see what I mean, use y=2.58 for the eyeOffset this example with the milktruck.
For a better visualization, I think you’ll have to have the pin slightly above the model with a line going down to the model.

-Hannah