I am using the Entity API to display GLTF based models on my scene with terrain enabled. The models use I am trying to have an html overlay that will work like a video game health bar - hovering above the top of the model. The goal is to translate a position “above” my model to the screen space and display it there. I think problem I have is how to get the actual position of the rendered primitive and the primitive’s bounding sphere so I can find the top. I don’t seem to have access to the primitive through the entity api.
What are the best practices for getting:
-
the entities position with respect to the ground clamping?
-
the top of the model’s bounding sphere (top meaning - with respect to the viewport)
I’ve edited the 3D models Sandcastle demo to show a situation where placing the html overlay at position takes the position before the clamping.
HTML:
@import url(../templates/bucket.css);Loading...
JS:
var viewer = new Cesium.Viewer(‘cesiumContainer’, {
infoBox : false,
selectionIndicator : false,
shadows : true,
shouldAnimate : true
});
var htmlOverlay = document.getElementById(‘htmlOverlay’);
var longitude = -123.0744619;
var latitude = 44.0503706;
function createModel(url, height) {
viewer.entities.removeAll();
var position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height - 100);
var heading = Cesium.Math.toRadians(135);
var pitch = 0;
var roll = 0;
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
var entity = viewer.entities.add({
name : url,
position : position,
orientation : orientation,
model : {
uri : url,
minimumPixelSize : 128,
maximumScale : 20000,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
}
});
viewer.trackedEntity = entity;
viewer.scene.preRender.addEventListener(function() {
var canvasPosition = viewer.scene.cartesianToCanvasCoordinates(entity.position.getValue(viewer.clock.currentTime));
if (Cesium.defined(canvasPosition)) {
htmlOverlay.style.top = canvasPosition.y + ‘px’;
htmlOverlay.style.left = canvasPosition.x + ‘px’;
}
});
}
var options = [{
text : ‘Aircraft’,
onselect : function() {
createModel(’…/…/…/…/Apps/SampleData/models/CesiumAir/Cesium_Air.glb’, 5000.0);
}
}, {
text : ‘Ground Vehicle’,
onselect : function() {
createModel(’…/…/…/…/Apps/SampleData/models/GroundVehicle/GroundVehicle.glb’, 0);
}
}, {
text : ‘Hot Air Balloon’,
onselect : function() {
createModel(’…/…/…/…/Apps/SampleData/models/CesiumBalloon/CesiumBalloon.glb’, 1000.0);
}
}, {
text : ‘Milk Truck’,
onselect : function() {
createModel(’…/…/…/…/Apps/SampleData/models/CesiumMilkTruck/CesiumMilkTruck-kmc.glb’, 0);
}
}, {
text : ‘Skinned Character’,
onselect : function() {
createModel(’…/…/…/…/Apps/SampleData/models/CesiumMan/Cesium_Man.glb’, 0);
}
}, {
text : ‘Draco Compressed Model’,
onselect : function() {
createModel(’…/…/…/…/Apps/SampleData/models/DracoCompressed/CesiumMilkTruck.gltf’, 0);
}
}];
Sandcastle.addToolbarMenu(options);