Cesium Intermediate Course 3 - Camera - Camera (Camera)

Posted by Mucello on Thu, 05 Sep 2019 05:33:58 +0200

Camera

Camera controls the view of the scene in Cesium JS. There are many ways to manipulate Camera, such as rotate, zoom, pan and fly to destination. Cesium JS has mouse and touch events to handle interaction with Camrea, and APIs to operate cameras programmatically. Learn how to use the Camera API and Camera controls.

Default Camera behavior

Open Sandcastle Hello World The sample is used to experience the default camera control. The default mode of operation is as follows:

Mouse operation 3D 2D Columbus Perspective
Left click + drag Rotate around the globe Translate over the map Translate over the map
Right click + drag Zoom in and out Zoom in and out Zoom in and out
Middle wheel scrolling Zoom in and out Zoom in and out Zoom in and out
Middle click + drag Tilt the globe No action Tilt the map
Mouse operation 3D 2D Columbus Perspective
Left key + drag Rotating the Earth Moving on the map Moving on the map
Right-click + drag zoom zoom zoom
Medium key roller zoom zoom zoom
Middle key + drag Tilt the Earth No operation Tilt the Earth

Use the setView function to set the location and direction of Camera. destination can be Cartesian3 or Rectangle, orientation can be heading/pitch/roll or direction/up. The heading angle, pitch angle and roll angle are defined in radians. The heading angle is a local northward rotation which increases from the positive angle to the east. The pitch angle refers to the rotation starting from the local northeast plane. The positive pitch angle is above the plane. The negative pitch angle is below the plane. Very rolling is the first rotation around the local Eastern axis application.

camera.setView({
    destination : new Cesium.Cartesian3(x, y, z),
    orientation: {
        heading : headingAngle,
        pitch : pitchAngle,
        roll : rollAngle
    }
});
viewer.camera.setView({
    destination : Cesium.Rectangle.fromDegrees(west, south, east, north),
    orientation: {
        heading : headingAngle,
        pitch : pitchAngle,
        roll : rollAngle
    }
});

All of the above parameters are optional. If not specified, the parameter value will be set to the default user's current Camera location and direction.

Customize Camera Mouse or Keyboard Events

Create our own event control, according to the direction of the mouse to control the direction of Camera, keyboard keys to control Camera forward, left, right, up, and down. Start by disabling default event operations. After (javascript var viewe=...), add the following code:

var scene = viewer.scene;
var canvas = viewer.canvas;
canvas.setAttribute('tabindex', '0'); // needed to put focus on the canvas
canvas.onclick = function() {
    canvas.focus();
};
var ellipsoid = viewer.scene.globe.ellipsoid;

// disable the default event handlers
scene.screenSpaceCameraController.enableRotate = false;
scene.screenSpaceCameraController.enableTranslate = false;
scene.screenSpaceCameraController.enableZoom = false;
scene.screenSpaceCameraController.enableTilt = false;
scene.screenSpaceCameraController.enableLook = false;

Create variables to record the current mouse position, then mark and follow the Camera trajectory:

var startMousePosition;
var mousePosition;
var flags = {
    looking : false,
    moveForward : false,
    moveBackward : false,
    moveUp : false,
    moveDown : false,
    moveLeft : false,
    moveRight : false
};

Add an event control user settings tag to record the current mouse position when the left mouse button is clicked:

var handler = new Cesium.ScreenSpaceEventHandler(canvas);

handler.setInputAction(function(movement) {
    flags.looking = true;
    mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);

handler.setInputAction(function(movement) {
    mousePosition = movement.endPosition;
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

handler.setInputAction(function(position) {
    flags.looking = false;
}, Cesium.ScreenSpaceEventType.LEFT_UP);

Create keyboard events to control user switching Camera mobile tags. We set up tags for the following keys and actions:

  1. w Camera forward.
  2. s Camera backwards.
  3. a Camera to the left.
  4. d Camera to the right.
  5. q Camera up.
  6. e Camera down.
function getFlagForKeyCode(keyCode) {
    switch (keyCode) {
    case 'W'.charCodeAt(0):
        return 'moveForward';
    case 'S'.charCodeAt(0):
        return 'moveBackward';
    case 'Q'.charCodeAt(0):
        return 'moveUp';
    case 'E'.charCodeAt(0):
        return 'moveDown';
    case 'D'.charCodeAt(0):
        return 'moveRight';
    case 'A'.charCodeAt(0):
        return 'moveLeft';
    default:
        return undefined;
    }
}

document.addEventListener('keydown', function(e) {
    var flagName = getFlagForKeyCode(e.keyCode);
    if (typeof flagName !== 'undefined') {
        flags[flagName] = true;
    }
}, false);

document.addEventListener('keyup', function(e) {
    var flagName = getFlagForKeyCode(e.keyCode);
    if (typeof flagName !== 'undefined') {
        flags[flagName] = false;
    }
}, false);

Now when the tag indicates that the event is true, we update the camera. We added * onTick * listening events in clock:

viewer.clock.onTick.addEventListener(function(clock) {
    var camera = viewer.camera;
});

Next, we let Camera point in the direction of the mouse. After the variable declaration, add the following code to the event listener function:

if (flags.looking) {
    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 lookFactor = 0.05;
    camera.lookRight(x * lookFactor);
    camera.lookUp(y * lookFactor);
}

lookRight and lookUp require only one angle parameter to represent the rotation angle. We convert mouse coordinates to ranges (-1.0, 1.0), and coordinates (0.0, 0.0) are located in the center of the canvas. The distance between the mouse and the center determines the speed of rotation. Camera moves slowly near the center, while Camera moves faster away from the center.

Finally, add code to move Camera's location. Then add the following code to the event response function:

// Change movement speed based on the distance of the camera to the surface of the ellipsoid.
var cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;
var moveRate = cameraHeight / 100.0;

if (flags.moveForward) {
    camera.moveForward(moveRate);
}
if (flags.moveBackward) {
    camera.moveBackward(moveRate);
}
if (flags.moveUp) {
    camera.moveUp(moveRate);
}
if (flags.moveDown) {
    camera.moveDown(moveRate);
}
if (flags.moveLeft) {
    camera.moveLeft(moveRate);
}
if (flags.moveRight) {
    camera.moveRight(moveRate);
}

The moveForward, moveBackward, moveUp, moveDown, moveLeft and moveRight methods only need a distance parameter (m) to move Camera. When each button is pressed, Camera moves a fixed distance on the surface of the sphere. The closer Camera is to the ground, the slower it moves.

The complete code is as follows:

var viewer = new Cesium.Viewer('cesiumContainer');

var scene = viewer.scene;
var canvas = viewer.canvas;
canvas.setAttribute('tabindex', '0'); // needed to put focus on the canvas
canvas.onclick = function() {
    canvas.focus();
};
var ellipsoid = viewer.scene.globe.ellipsoid;

// disable the default event handlers
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 flags = {
    looking : false,
    moveForward : false,
    moveBackward : false,
    moveUp : false,
    moveDown : false,
    moveLeft : false,
    moveRight : false
};

var handler = new Cesium.ScreenSpaceEventHandler(canvas);

handler.setInputAction(function(movement) {
    flags.looking = true;
    mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);

handler.setInputAction(function(movement) {
    mousePosition = movement.endPosition;
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

handler.setInputAction(function(position) {
    flags.looking = false;
}, Cesium.ScreenSpaceEventType.LEFT_UP);

function getFlagForKeyCode(keyCode) {
    switch (keyCode) {
    case 'W'.charCodeAt(0):
        return 'moveForward';
    case 'S'.charCodeAt(0):
        return 'moveBackward';
    case 'Q'.charCodeAt(0):
        return 'moveUp';
    case 'E'.charCodeAt(0):
        return 'moveDown';
    case 'D'.charCodeAt(0):
        return 'moveRight';
    case 'A'.charCodeAt(0):
        return 'moveLeft';
    default:
        return undefined;
    }
}

document.addEventListener('keydown', function(e) {
    var flagName = getFlagForKeyCode(e.keyCode);
    if (typeof flagName !== 'undefined') {
        flags[flagName] = true;
    }
}, false);

document.addEventListener('keyup', function(e) {
    var flagName = getFlagForKeyCode(e.keyCode);
    if (typeof flagName !== 'undefined') {
        flags[flagName] = false;
    }
}, false);

viewer.clock.onTick.addEventListener(function(clock) {
    var camera = viewer.camera;

    if (flags.looking) {
        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 lookFactor = 0.05;
        camera.lookRight(x * lookFactor);
        camera.lookUp(y * lookFactor);
    }

    // Change movement speed based on the distance of the camera to the surface of the ellipsoid.
    var cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;
    var moveRate = cameraHeight / 100.0;

    if (flags.moveForward) {
        camera.moveForward(moveRate);
    }
    if (flags.moveBackward) {
        camera.moveBackward(moveRate);
    }
    if (flags.moveUp) {
        camera.moveUp(moveRate);
    }
    if (flags.moveDown) {
        camera.moveDown(moveRate);
    }
    if (flags.moveLeft) {
        camera.moveLeft(moveRate);
    }
    if (flags.moveRight) {
        camera.moveRight(moveRate);
    }
});

Visit the complete code)

Camera

Camera represents the current position, direction, reference frame and the status of the view truncation cone of Camera. The Camera vectors above are orthogonal in each frame.
move and zoom functions translate Camera's position according to its direction or specified direction vector. The direction remains fixed.

The look and twist functions rotate Camera in directions such as up or right vectors. The position remains fixed.

The mysterious position and direction of rotate* function are based on a given vector.

Function sets Camera's location and direction for a given range or location and target. For example:

var west = Cesium.Math.toRadians(-77.0);
var south = Cesium.Math.toRadians(38.0);
var east = Cesium.Math.toRadians(-72.0);
var north = Cesium.Math.toRadians(42.0);
var extent = new Cesium.Extent(west, south, east, north);
camera.viewExtent(extent, Cesium.Ellipsoid.WGS84);

Create the variable ray and pick up the location of Camera through the pixels. The method can be used for picking up, for example:

// find intersection of the pixel picked and an ellipsoid
var ray = camera.getPickRay(mousePosition);
var intersection = Cesium.IntersectionTests.rayEllipsoid(ray, Cesium.Ellipsoid.WGS84);

Screen space camera controller

ScreenSpace Camera Controller converts user input (such as mouse and touch) from window coordinates to Camera motion. It contains attributes for enabling and disabling different types of input, modifying inertia, and minimal and maximum zoom distances.

Resources

camera sample code can be viewed in Sandcastle:

  1. Camera Tutorial
  2. Camera

API documentation:

  1. Camera
  2. ScreenSpaceCameraController

Cesium Chinese Communication QQ Group: 807482793

This article is based on admin Creation, adoption Knowledge Sharing Signature 3.0 Mainland China Licensing Agreement License.
It can be reproduced and quoted freely, but the author should be signed and the source of the article should be indicated.

Topics: Javascript Mobile