'viewer.camera.lookAt' method change camera.heading and camera.pitch

1. A concise explanation of the problem you’re experiencing.

I’m trying to simply follow a billboard movement on its trajectory, and keep the original camera HeadingPitchRange.

To do so I use 'viewer.camera.lookAt(myBillboardposition, new Cesium.HeadingPitchRange(camera.heading, camera.pitch, camera.range));

The problem is that each time I call ‘viewer.camera.lookAt’ the heading and the pitch of the camera is a bit modified,

so during the time the camera change a lot, and it’s not what I’d like to have.

2. A minimal code example. If you’ve found a bug, this helps us reproduce and repair it.

viewer.camera.lookAt(myBillboardposition, new Cesium.HeadingPitchRange(camera.heading, camera.pitch, camera.range));

3. Context. Why do you need to do this? We might know a better way to accomplish your goal.

I’m trying to follow on the map a billboard that is moving

4. The Cesium version you’re using, your operating system and browser.

1.62

The best way I’ve found to make the camera look towards a specific point without changing its location is the following snippet:

// Given a Cartesian3 called "targetPosition"
// This snippet will turn the camera towards it, and keep it from turning/tilting
var camera = viewer.camera;
var cameraPosition = viewer.camera.position.clone();
var direction = Cesium.Cartesian3.subtract(
  targetPosition,
  cameraPosition,
  new Cesium.Cartesian3()
);
direction = Cesium.Cartesian3.normalize(direction, direction);
viewer.camera.direction = direction;

// get an "approximate" up vector, which in this case we want to be something like the geodetic surface normal.
var approxUp = Cesium.Cartesian3.normalize(
  cameraPosition,
  new Cesium.Cartesian3()
);

// cross viewdir with approxUp to get a right normal
var right = Cesium.Cartesian3.cross(
  direction,
  approxUp,
  new Cesium.Cartesian3()
);
right = Cesium.Cartesian3.normalize(right, right);
viewer.camera.right = right;

// cross right with view dir to get an orthonormal up
var up = Cesium.Cartesian3.cross(
  right,
  direction,
  new Cesium.Cartesian3()
);
up = Cesium.Cartesian3.normalize(up, up);
camera.up = up;

Hi Omar,

this is the function I’m looking for - do you have experiences if this calculations change heading/pitch and if the due to this calculations a camerachanged-event is fired ?

Rüdiger

@Ruediger_Brand

I am happy that you found the function that you are looking for. I just tested out Omar’s code. From my testing, it seems like the code does change the heading and pitch of the Camera. I also noticed that the changed event was fired. @Ruediger_Brand did you notice similar behavior when you tested the code?

-Sam

Hi Sam,

answer is yes, and it works for me.

Rüdiger

@Ruediger_Brand

I am happy to hear that. Let me know if anything else comes up!

-Sam

I’m using camera.lookAt(position, new Cesium.headingPitchRange()) at onTick function , and I need to handle speed of camera while lookAt.

Thank you

Hi @Yajur_Sood,

You can use Cartesian3.lerp to interpolate between two positions based on a time or other value.

For instance, each onTick, you can move the camera 1/10 of the way to target to create a smooth transition.