Camera.SetView() gives inaccurate orientation using direction and up vectors
- Dominant language
- JavaScript
- Stars
- 15.7k
- Forks
- 3.9k
- Avg merge
- 4d 6h
- Merged PRs (30d)
- 34
Description
### Description
The view can be set with the method Camera.SetView() using direction and up vectors. Most of the time the behavior is correct. But in some angles, setView() does not behave as expected. The issue has been identified to occur when using a direction vector near to Cartesian3.UNIT_Y. In fact, this occurs when pointing a little under the middle of the earth (between 0 and ~-2.56radians). In the range of 0 to -2.56, the view is exactly the same as if the angle was positive. (a pitch rotation of -2.56 radians down gives a pitch rotation of 2.56 radians up). As soon as the rotation go to ~-2.565radians, the rotation goes down as expected.
### Expected behavior
Using Camera.SetView with direction and up vectors points to the direction vector and the up vector is directly up.
### Steps to reproduce
The issue is a little obscure. Here is a small sandcastle project to demonstrate the issue.
Use keys 1, 2, 3, 4 to switch from views
key 1 : set direction vector to vector a
key 2 : set direction vector to vector aPrime
key 3 : set direction vector to vector b
key 4 : set direction vector to vector bPrime
1. Alternate view by using key 1 and 2.
2. Notice that the view changes as expected and the view is mirrored since both vectors have only the z component opposite
3. Alternate view by using key 3 and 4.
4. Notice that the view does not change even if vectors b and bPrime have their z component opposed
```javascript
//Start of example
var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;
var canvas = viewer.canvas;
canvas.setAttribute('tabindex', '0');
canvas.onclick = function() {
canvas.focus();
};
var direction = Cesium.Cartesian3.UNIT_Y.clone();
var up = Cesium.Cartesian3.UNIT_Z.clone();
// initial position and orientation
viewer.camera.position = new Cesium.Cartesian3(0, -20000000, 0);
viewer.camera.setView(
{
orientation:
{
direction: direction,
up: up
}});
// setting view by switching from a to aPrime as direction changes view as expected
var a = new Cesium.Cartesian3(0, 0.9989980940754456, 0.044752743308394995);
var aPrime = new Cesium.Cartesian3(0, 0.9989980940754456, -0.044752743308394995);
// setting view by switching from b to bPrime does not change the view
var b = new Cesium.Cartesian3(0, 0.9993908270190958, 0.03489949670250097);
var bPrime = new Cesium.Cartesian3(0, 0.9993908270190958, -0.03489949670250097);
var ninetyDegreeRotation = Cesium.Matrix3.fromRotationX(Math.PI/2);
document.addEventListener('keydown', function(e) {
var camera = viewer.camera;
// setting direction vector to use
switch (e.keyCode)
{
case '1'.charCodeAt(0):
direction = a;
console.log("direction = a : " + direction);
break;
case '2'.charCodeAt(0):
direction = aPrime;
console.log("direction = aPrime : " + direction);
break;
case '3'.charCodeAt(0):
direction = b;
console.log("direction = b : " + direction);
break;
case '4'.charCodeAt(0):
direction = bPrime;
console.log("direction = bPrime : " + direction); // when using bPrime as direction, the view is the same as b.
break;
default:
break;
}
up = Cesium.Matrix3.multiplyByVector(ninetyDegreeRotation, direction, up);
camera.setView(
{orientation:
{
direction: direction,
up: up
}});
}, false);
// End of example
```
Contributor guide
Research direction
Start at Camera.setView and reproduce the behavior with the supplied sandcastle example, especially the direction vectors near Cesium.Cartesian3.UNIT_Y. Compare the views for vectors a/aPrime and b/bPrime, then verify that direction and up produce the expected distinct orientations near the reported pitch range.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100