Pan using right mouse

I have a tileset. I want to pan up/down using right mouse click+drag on tileset model. I want to pan object with relation to mouse movement. Object should be there where the mouse pointer is (similar to when panning is done using left mouse by default) My code moves camera but model goes way to far from pointer.

Here is my code:

scene.screenSpaceCameraController.enableRotate = false;

scene.screenSpaceCameraController.enableTranslate = false;

scene.screenSpaceCameraController.enableZoom = false;

scene.screenSpaceCameraController.enableTilt = false;

scene.screenSpaceCameraController.enableLook = false;

var startMousePosition;

var mousePosition;

var pan = false;

var pickedCenter;

var handler = new Cesium.ScreenSpaceEventHandler(canvas);

var timeout = null;

handler.setInputAction(function(movement) {

if (pan) {

//Check if mouse is not moving

clearTimeout(timeout);

timeout = setTimeout(function() {

mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.startPosition);

}, 100);

mousePosition = movement.endPosition;

var camera = viewer.camera;

var width = canvas.clientWidth;

var height = canvas.clientHeight;

// Coordinate (0.0, 0.0) will be where the mouse was clicked.

var x = (mousePosition.x - startMousePosition.x)// / width;

var y = -(mousePosition.y - startMousePosition.y)// / height;

var moveFactor = 0.005;

camera.moveRight(x * moveFactor * -1);

camera.moveUp(y * moveFactor * -1);

}

}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

//-----Right Mouse

handler.setInputAction(function(movement) {

pan = true;

mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.position);

}, Cesium.ScreenSpaceEventType.RIGHT_DOWN);

handler.setInputAction(function(position) {

pan = false;

}, Cesium.ScreenSpaceEventType.RIGHT_UP);

I’m having trouble running your example in Sandcastle, holding right click and moving doesn’t seem to do anything. Do you have to be zoomed into a model somewhere? Sharing a Sandcastle (https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/) example by clicking “Share” and pasting the link here is always going to be the easiest way to share something that others can run and edit.

It’s hard to tell what the issue is, but if this is specifically a problem of panning when you’re trying to keep a model in view, it might be worth taking into account the position of the model to the camera during this pan? Or perhaps simply decrease the moveFactor when the camera is closer to Earth. I believe the default CesiumJS camera does something similar.

Thanks for looking into it. Here is the complete and updated code:

//scene.screenSpaceCameraController.enableRotate = false;

scene.screenSpaceCameraController.enableTranslate = false;

scene.screenSpaceCameraController.enableZoom = false;

scene.screenSpaceCameraController.enableTilt = false;

scene.screenSpaceCameraController.enableLook = false;

var startMousePosition;

var endMousePosition;

var pan = false;

var pickedCenter;

var cameraPickDistance;

var handler = new Cesium.ScreenSpaceEventHandler(canvas);

handler.setInputAction(function(movement) {

if (pan) {

startMousePosition = movement.startPosition;

endMousePosition = movement.endPosition;

var camera = viewer.camera;

//var width = canvas.clientWidth;

//var height = canvas.clientHeight;

// Coordinate (0.0, 0.0) will be where the mouse was clicked.

var x = (endMousePosition.x - startMousePosition.x)// / width;

var y = -(endMousePosition.y - startMousePosition.y)// / height;

var moveFactor = cameraPickDistance/1000000;

camera.moveRight(x * moveFactor * -1);

camera.moveUp(y * moveFactor * -1);

}

}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

//-----Right Mouse

handler.setInputAction(function(click) {

var cartesian = scene.pickPosition(click.position);

if (scene.pickPositionSupported && Cesium.defined(cartesian)) {

var cartographic = Cesium.Cartographic.fromCartesian(cartesian);

var groundAltitude = getGroundAltitude(viewer, cartographic);

cartesian = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, groundAltitude);

var cameraPos = viewer.camera.position;

cameraPickDistance = Cesium.Cartesian3.distance(cameraPos, cartesian);

pan = true;

}

}, Cesium.ScreenSpaceEventType.RIGHT_DOWN);

handler.setInputAction(function(click) {

pan = false;

viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);

}, Cesium.ScreenSpaceEventType.RIGHT_UP);

I think this is still missing a piece. The getGroundAltitude function is not defined in that code snippet.

Thats not necessary, not even tileset model. I am just trying to get pan up/down/left/right with relation to mouse movement. When we pan using left mouse, clicked area moved with mouse, it stays with mouse.

function getGroundAltitude(viewer, cartographic) {

// Get a reference to the ellipsoid, with terrain on it. (This API may change soon)

var ellipsoid = viewer.scene.globe.ellipsoid;

// Specify our point of interest.

//var pointOfInterest = Cesium.Cartographic.fromRadians(

// -1.7344121076640773, 0.3363412538555782, 5000, new Cesium.Cartographic());

var pointOfInterest = cartographic;

// [OPTIONAL] Fly the camera there, to see if we got the right point.

/*viewer.camera.flyTo({

destination: ellipsoid.cartographicToCartesian(pointOfInterest,

new Cesium.Cartesian3())

});*/

// Sample the terrain (async) and write the answer to the console.

Cesium.sampleTerrain(viewer.terrainProvider, 9, [ pointOfInterest ])

.then(function(samples) {

//console.log('Height in meters is: ’ + samples[0].height);

return samples[0].height;

});

}

Thanks for providing the Sandcastle link. I think I see what you’re saying now. You mean when you pan in this way, the point you started at shifts away as you move and is no longer under the mouse, correct?

I think to do that you might need to get the actual 3D position at that mouse location so you can figure out exactly the right real world distance to move the camera by. I mentioned this in a previous thread you made but this is where you can find the implementation for the default CesiumJS camera:

https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Scene/ScreenSpaceCameraController.js#L1833-L1865

Notice the ray picking functions that get the 3D position from a 2d screen location. Another way to do this conversion is to use the Scene transforms function:

https://cesiumjs.org/Cesium/Build/Documentation/SceneTransforms.html?classFilter=Tran#.wgs84ToDrawingBufferCoordinates