text: /**
   * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
   *
   * @author David Sehnal <david.sehnal@gmail.com>
   * @author Alexander Rose <alexander.rose@weirdbyte.de>
   *
   * Adapted from three.js, The MIT License, Copyright © 2010-2020 three.js authors
   */
  import { __assign } from "tslib";
  import { Mat4 } from '../../mol-math/linear-algebra';
  import { ParamDefinition as PD } from '../../mol-util/param-definition';
  import { Camera } from '../camera';
  import { Viewport } from './util';
  export var StereoCameraParams = {
      eyeSeparation: PD.Numeric(0.064, { min: 0.01, max: 0.5, step: 0.001 }),
      focus: PD.Numeric(10, { min: 1, max: 100, step: 0.01 }),
  };
  export var DefaultStereoCameraProps = PD.getDefaultValues(StereoCameraParams);
  export { StereoCamera };
  var StereoCamera = /** @class */ (function () {
      function StereoCamera(parent, props) {
          if (props === void 0) { props = {}; }
          this.parent = parent;
          this.left = new EyeCamera();
          this.right = new EyeCamera();
          this.props = __assign(__assign({}, DefaultStereoCameraProps), props);
      }
      Object.defineProperty(StereoCamera.prototype, "viewport", {
          get: function () {
              return this.parent.viewport;
          },
          enumerable: false,
          configurable: true
      });
      Object.defineProperty(StereoCamera.prototype, "viewOffset", {
          get: function () {
              return this.parent.viewOffset;
          },
          enumerable: false,
          configurable: true
      });
      StereoCamera.prototype.setProps = function (props) {
          Object.assign(this.props, props);
      };
      StereoCamera.prototype.update = function () {
          this.parent.update();
          update(this.parent, this.props, this.left, this.right);
      };
      return StereoCamera;
  }());
  (function (StereoCamera) {
      function is(camera) {
          return 'left' in camera && 'right' in camera;
      }
      StereoCamera.is = is;
  })(StereoCamera || (StereoCamera = {}));
  var EyeCamera = /** @class */ (function () {
      function EyeCamera() {
          this.viewport = Viewport.create(0, 0, 0, 0);
          this.view = Mat4();
          this.projection = Mat4();
          this.projectionView = Mat4();
          this.inverseProjectionView = Mat4();
          this.state = Camera.createDefaultSnapshot();
          this.viewOffset = Camera.ViewOffset();
          this.far = 0;
          this.near = 0;
          this.fogFar = 0;
          this.fogNear = 0;
      }
      return EyeCamera;
  }());
  var eyeLeft = Mat4.identity(), eyeRight = Mat4.identity();
  function update(camera, props, left, right) {
      // Copy the states
      Viewport.copy(left.viewport, camera.viewport);
      Mat4.copy(left.view, camera.view);
      Mat4.copy(left.projection, camera.projection);
      Camera.copySnapshot(left.state, camera.state);
      Camera.copyViewOffset(left.viewOffset, camera.viewOffset);
      left.far = camera.far;
      left.near = camera.near;
      left.fogFar = camera.fogFar;
      left.fogNear = camera.fogNear;
      Viewport.copy(right.viewport, camera.viewport);
      Mat4.copy(right.view, camera.view);
      Mat4.copy(right.projection, camera.projection);
      Camera.copySnapshot(right.state, camera.state);
      Camera.copyViewOffset(right.viewOffset, camera.viewOffset);
      right.far = camera.far;
      right.near = camera.near;
      right.fogFar = camera.fogFar;
      right.fogNear = camera.fogNear;
      // update the view offsets
      var w = Math.floor(camera.viewport.width / 2);
      var aspect = w / camera.viewport.height;
      left.viewport.width = w;
      right.viewport.x += w;
      right.viewport.width -= w;
      // update the projection and view matrices
      var eyeSepHalf = props.eyeSeparation / 2;
      var eyeSepOnProjection = eyeSepHalf * camera.near / props.focus;
      var ymax = camera.near * Math.tan(camera.state.fov * 0.5);
      var xmin, xmax;
      // translate xOffset
      eyeLeft[12] = -eyeSepHalf;
      eyeRight[12] = eyeSepHalf;
      // for left eye
      xmin = -ymax * aspect + eyeSepOnProjection;
      xmax = ymax * aspect + eyeSepOnProjection;
      left.projection[0] = 2 * camera.near / (xmax - xmin);
      left.projection[8] = (xmax + xmin) / (xmax - xmin);
      Mat4.mul(left.view, left.view, eyeLeft);
      Mat4.mul(left.projectionView, left.projection, left.view);
      Mat4.invert(left.inverseProjectionView, left.projectionView);
      // for right eye
      xmin = -ymax * aspect - eyeSepOnProjection;
      xmax = ymax * aspect - eyeSepOnProjection;
      right.projection[0] = 2 * camera.near / (xmax - xmin);
      right.projection[8] = (xmax + xmin) / (xmax - xmin);
      Mat4.mul(right.view, right.view, eyeRight);
      Mat4.mul(right.projectionView, right.projection, right.view);
      Mat4.invert(right.inverseProjectionView, right.projectionView);
  }
  //# sourceMappingURL=stereo.js.map