function Camera(scene) {
  //>>includeStart('debug', pragmas.debug);
  if (!defined(scene)) {
    throw new DeveloperError("scene is required.");
  }
  //>>includeEnd('debug');
  this._scene = scene;

  this._transform = Matrix4.clone(Matrix4.IDENTITY);
  this._invTransform = Matrix4.clone(Matrix4.IDENTITY);
  this._actualTransform = Matrix4.clone(Matrix4.IDENTITY);
  this._actualInvTransform = Matrix4.clone(Matrix4.IDENTITY);
  this._transformChanged = false;

  /**
   * The position of the camera.
   *
   * @type {Cartesian3}
   */
  this.position = new Cartesian3();
  this._position = new Cartesian3();
  this._positionWC = new Cartesian3();
  this._positionCartographic = new Cartographic();
  this._oldPositionWC = undefined;

  /**
   * The position delta magnitude.
   *
   * @private
   */
  this.positionWCDeltaMagnitude = 0.0;

  /**
   * The position delta magnitude last frame.
   *
   * @private
   */
  this.positionWCDeltaMagnitudeLastFrame = 0.0;

  /**
   * How long in seconds since the camera has stopped moving
   *
   * @private
   */
  this.timeSinceMoved = 0.0;
  this._lastMovedTimestamp = 0.0;

  /**
   * The view direction of the camera.
   *
   * @type {Cartesian3}
   */
  this.direction = new Cartesian3();
  this._direction = new Cartesian3();
  this._directionWC = new Cartesian3();

  /**
   * The up direction of the camera.
   *
   * @type {Cartesian3}
   */
  this.up = new Cartesian3();
  this._up = new Cartesian3();
  this._upWC = new Cartesian3();

  /**
   * The right direction of the camera.
   *
   * @type {Cartesian3}
   */
  this.right = new Cartesian3();
  this._right = new Cartesian3();
  this._rightWC = new Cartesian3();

  /**
   * The region of space in view.
   *
   * @type {PerspectiveFrustum|PerspectiveOffCenterFrustum|OrthographicFrustum}
   * @default PerspectiveFrustum()
   *
   * @see PerspectiveFrustum
   * @see PerspectiveOffCenterFrustum
   * @see OrthographicFrustum
   */
  this.frustum = new PerspectiveFrustum();
  this.frustum.aspectRatio =
    scene.drawingBufferWidth / scene.drawingBufferHeight;
  this.frustum.fov = CesiumMath.toRadians(60.0);

  /**
   * The default amount to move the camera when an argument is not
   * provided to the move methods.
   * @type {number}
   * @default 100000.0;
   */
  this.defaultMoveAmount = 100000.0;
  /**
   * The default amount to rotate the camera when an argument is not
   * provided to the look methods.
   * @type {number}
   * @default Math.PI / 60.0
   */
  this.defaultLookAmount = Math.PI / 60.0;
  /**
   * The default amount to rotate the camera when an argument is not
   * provided to the rotate methods.
   * @type {number}
   * @default Math.PI / 3600.0
   */
  this.defaultRotateAmount = Math.PI / 3600.0;
  /**
   * The default amount to move the camera when an argument is not
   * provided to the zoom methods.
   * @type {number}
   * @default 100000.0;
   */
  this.defaultZoomAmount = 100000.0;
  /**
   * If set, the camera will not be able to rotate past this axis in either direction.
   * @type {Cartesian3 | undefined}
   * @default undefined
   */
  this.constrainedAxis = undefined;
  /**
   * The factor multiplied by the the map size used to determine where to clamp the camera position
   * when zooming out from the surface. The default is 1.5. Only valid for 2D and the map is rotatable.
   * @type {number}
   * @default 1.5
   */
  this.maximumZoomFactor = 1.5;

  this._moveStart = new Event();
  this._moveEnd = new Event();

  this._changed = new Event();
  this._changedPosition = undefined;
  this._changedDirection = undefined;
  this._changedFrustum = undefined;
  this._changedHeading = undefined;
  this._changedRoll = undefined;

  /**
   * The amount the camera has to change before the <code>changed</code> event is raised. The value is a percentage in the [0, 1] range.
   * @type {number}
   * @default 0.5
   */
  this.percentageChanged = 0.5;

  this._viewMatrix = new Matrix4();
  this._invViewMatrix = new Matrix4();
  updateViewMatrix(this);

  this._mode = SceneMode.SCENE3D;
  this._modeChanged = true;
  const projection = scene.mapProjection;
  this._projection = projection;
  this._maxCoord = projection.project(
    new Cartographic(Math.PI, CesiumMath.PI_OVER_TWO),
  );
  this._max2Dfrustum = undefined;

  // set default view
  rectangleCameraPosition3D(
    this,
    Camera.DEFAULT_VIEW_RECTANGLE,
    this.position,
    true,
  );

  let mag = Cartesian3.magnitude(this.position);
  mag += mag * Camera.DEFAULT_VIEW_FACTOR;
  Cartesian3.normalize(this.position, this.position);
  Cartesian3.multiplyByScalar(this.position, mag, this.position);
}
The camera is defined by a position, orientation, and view frustum.
<br /><br />
The orientation forms an orthonormal basis with a view, up and right = view x up unit vectors.
<br /><br />
The viewing frustum is defined by 6 planes.
Each plane is represented by a {@link Cartesian4} object, where the x, y, and z components
define the unit vector normal to the plane, and the w component is the distance of the
plane from the origin/camera position.

@alias Camera

@constructor

@param {Scene} scene The scene.

@demo {@link https://sandcastle.cesium.com/index.html?src=Camera.html|Cesium Sandcastle Camera Demo}
@demo {@link https://sandcastle.cesium.com/index.html?src=Camera%20Tutorial.html|Cesium Sandcastle Camera Tutorial Example}
@demo {@link https://cesium.com/learn/cesiumjs-learn/cesiumjs-camera|Camera Tutorial}

@example
// Create a camera looking down the negative z-axis, positioned at the origin,
// with a field of view of 60 degrees, and 1:1 aspect ratio.
const camera = new Cesium.Camera(scene);
camera.position = new Cesium.Cartesian3();
camera.direction = Cesium.Cartesian3.negate(Cesium.Cartesian3.UNIT_Z, new Cesium.Cartesian3());
camera.up = Cesium.Cartesian3.clone(Cesium.Cartesian3.UNIT_Y);
camera.frustum.fov = Cesium.Math.PI_OVER_THREE;
camera.frustum.near = 1.0;
camera.frustum.far = 2.0;