Do not move camera when setting trackedEntity

I want my camera to fly freely until an entity starts moving when I want to start tracking it. I use trackedEntity for this. If I don’t use viewFrom then the camera moves close to the object. I want to set viewFrom to look at the entity from the current position of the camera without moving (and then start moving).

To rephrase this problem: viewFrom is set in east-north-up reference frame but camera position is in Cartesian3. How can I compute east-north-up from two Cartesian3 (entity and camera)?

I did something similar in my app here to make the camera orbit around the mountain and stay pointing towards it: Projecting flags on Matterhorn mountain - behind the scenes

I did it by having an invisible entity on top of the mountain that the camera is tracking. It sounds like this is basically what you’d need, your entity is moving, the camera is changing direction to look at it but not position. The source code for that app is available in that forum thread if it helps.

I think ideally we could bring this into CesiumJS as a simple camera.lookAt(entity.position) and you’d run that every frame to turn the camera to the moving entity. We’d be happy to review that pull request if this is something you’re working on!

Thanks for the answer. My use-case is slightly different. I want to track the entity once it starts moving and stop tracking once it stops moving. The only thing I need is the camera to just rotate when the tracking starts instead of jumping and rotating.

I think that this could be easily done with some matrix operations but I don’t understand how they work. I need to compute a north-east-up vector from two cartesians.

BTW this is my use case: https://www.paragliding-mapa.cz/mapa/cesium/15
Try rotating or moving the camera and then start flying with the + button or key Up. The camera jumps. While moving, rotate the camera, then stop with button or key Down. Now start flying again and the camera jumps again.

I’ve decided to do something dumb but it works well: Manually compute the east-north-up difference by creating one position south from the entity and computing the distance to entity and one below the camera and computing the distance to camera:

/**
 * Computes the east-north-up difference between two points.
 * @param {Cartesian3} left
 * @param {Cartesian3} right
 * @returns {Cartesian3}
 */
function eastNorthUp(left, right) {
    var leftCartographic = Cesium.Cartographic.fromCartesian(left);
    var rightCartographic = Cesium.Cartographic.fromCartesian(right);
    var leftEast = Cesium.Cartesian3.fromRadians(rightCartographic.longitude, leftCartographic.latitude, leftCartographic.height);
    var rightDown = Cesium.Cartesian3.fromRadians(rightCartographic.longitude, rightCartographic.latitude, leftCartographic.height);
    return new Cesium.Cartesian3(
        Cesium.Cartesian3.distance(left, leftEast) * (rightCartographic.longitude > leftCartographic.longitude ? 1 : -1),
        Cesium.Cartesian3.distance(leftEast, rightDown) * (rightCartographic.latitude > leftCartographic.latitude ? 1 : -1),
        rightCartographic.height - leftCartographic.height
    );
};

Do you think it’s something worth creating a pull request for?

Created https://github.com/CesiumGS/cesium/pull/8838.

1 Like

Hey ,
Have you tried your solution in 2.5D/2D modes?
It seems to work only when using 3D mode.
Have you found out more by now?
Thank you