Entity Primitive Model Camera Reference

I’m trying to set the camera to the modelMatrix of a model primitive
that was created from a loaded czml so that the camera will be fixed relative to the 3D model. I tried a bunch of things and tested the
concept with the following sandcastle example but this uses a model fromGltf and doesn’t seem to work when I use my czml.

Example of desired behavior:

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

var scene = viewer.scene;

var degreesToRadians = function(val) {

return val*Math.PI/180;


var lon = -60;

var lat = -52;

var alt = 100;

var heading = 0;

var pitch = 0;

var roll = 0;

var primitives = scene.primitives;

var ellipsoid = viewer.scene.globe.ellipsoid;

var positionModel = function(model, lon, lat, alt, heading, pitch, roll) {

var point = Cesium.Cartographic.fromDegrees(lon, lat, alt / 3);

var epoint = ellipsoid.cartographicToCartesian(point);

var heading = degreesToRadians((heading));

var pitch = degreesToRadians(pitch);

var roll = degreesToRadians(roll);

var currentTranslation = new Cesium.Cartesian3();

var currentRotation = new Cesium.Matrix3();

var eastNorthUp = Cesium.Transforms.eastNorthUpToFixedFrame(epoint);

var p = new Cesium.Cartesian3(lon, lat, alt);

Cesium.Matrix4.getRotation(eastNorthUp, currentRotation);

Cesium.Matrix4.getTranslation(eastNorthUp, currentTranslation);

var headingQuaternion = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, -heading);

var pitchQuaternion = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Y, -pitch);

var rollQuaternion = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_X, -roll);

var headingPitchQuaternion = Cesium.Quaternion.multiply(headingQuaternion, pitchQuaternion, new Cesium.Quaternion());

var finalQuaternion = new Cesium.Quaternion();

Cesium.Quaternion.multiply(headingPitchQuaternion, rollQuaternion, finalQuaternion);

var rM = new Cesium.Matrix3();

Cesium.Matrix3.fromQuaternion(finalQuaternion, rM);

Cesium.Matrix3.multiply(currentRotation, rM, currentRotation);

var modelMatrix = new Cesium.Matrix4();






model.modelMatrix = modelMatrix;


var positionCamera = function(model) {

var camera = scene.camera;

camera.lookAtTransform(model.modelMatrix, new Cesium.Cartesian3(-25,0,10))

var controller = scene.screenSpaceCameraController;

var r = 2.0 * Math.max(model.boundingSphere.radius, camera.frustum.near);

controller.minimumZoomDistance = r * 0.5;


var createModel = function(lon, lat, alt, heading, pitch, roll) {

var model = scene.primitives.add(Cesium.Model.fromGltf({

url : ‘…/…/SampleData/models/CesiumAir/Cesium_Air.gltf’


model.readyToRender.addEventListener(function(model) {


speedup : 1,

loop : Cesium.ModelAnimationLoop.REPEAT


viewer.clock.onTick.addEventListener(function() {

positionModel(model, lon, lat, alt, heading, pitch, roll);


heading += 0.01;

pitch += 0.05;

roll += 0.1;




createModel(lon, lat, alt, heading, pitch, roll);


Now, here is my attempt from the loaded czml which kind of works but as the
camera is tracking the moving entity there is a lot of jittering of the camera
about the entity. I also tried to use just the model.modelMatrix instead of the _modelMatrix but I kept ending up inside the Earth. Any ideas what I’m doing wrong? I can provide an actual sandcastle example if needed.


function findPrimitive(entity) {

var id = entity.id;

for (var i = 0; i < scene.primitives.length; i++) {

var primitive = scene.primitives.get(i);

if (primitive.hasOwnProperty(‘id’)){

if (primitive.id.id == id) {

return primitive;





function cameraBodyAxes(entity) {

var primitive = findPrimitive(entity);

viewer.clock.onTick.addEventListener(function() {

camera.lookAtTransform(primitive._modelMatrix, new Cesium.Cartesian3(-20, 0, 8));




Solved the issue. I was returning the first primitive in the list with the matching entity id but it turns out there are 2 primitives with the same id in the array (not sure why). When I select the second primitives modelMatrix it works as I would expect.