lib/Models/AugmentedVirtuality.js
function(terria) {
  const that = this;

  this._terria = terria;

  // Note: We create a persistant object and define a transient property, since knockout needs a persistant variable
  //       to track, but for state we want a 'maybe' intervalId.
  this._eventLoopState = {};

  this._manualAlignment = false;

  this._maximumUpdatesPerSecond =
    AugmentedVirtuality.DEFAULT_MAXIMUM_UPDATES_PER_SECOND;

  this._orientationUpdated = false;
  this._alpha = 0;
  this._beta = 0;
  this._gamma = 0;
  this._realignAlpha = 0;
  this._realignHeading = 0;

  // Set the default height to be the last height so that when we first toggle (and increment) we cycle and go to the first height.
  this._hoverLevel = AugmentedVirtuality.PRESET_HEIGHTS.length - 1;

  // Always run the device orientation event, this way as soon as we enable we know where we are and set the
  // orientation rather then having to wait for the next update.
  // The following is disabled because chrome does not currently support deviceorientationabsolute correctly:
  // if ('ondeviceorientationabsolute' in window)
  // {
  //     window.addEventListener('deviceorientationabsolute', function(event) {that._orientationUpdate(event);} );
  // }
  // else
  if ("ondeviceorientation" in window) {
    window.addEventListener("deviceorientation", function(event) {
      that._storeOrientation(event);
    });
  }

  // Make the variables used by the object properties knockout observable so that changes in the state notify the UI
  // and cause a UI update. Note: These are all of the variables used just by the getters (not the setters), since
  // these unqiquely define what the current state is and are the only things that can effect/cause the state to change
  // (note: _eventLoopState is hidden behind ._eventLoopRunning() ).
  knockout.track(this, [
    "_eventLoopState",
    "_manualAlignment",
    "_maximumUpdatesPerSecond",
    "_realignAlpha",
    "_realignHeading",
    "_hoverLevel"
  ]);

  // Note: The following properties are defined as knockout properties so that they can be used to trigger updates on the UI.
  /**
   * Gets or sets whether Augmented Virtuality mode is currently enabled (true) or not (false).
   *
   * Note: If {@link AugmentedVirtuality#manualAlignment} is enabled and the state is changed it will be disabled.
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {Boolean} enabled
   */
  knockout.defineProperty(this, "enabled", {
    get: function() {
      return this._eventLoopRunning() || this._manualAlignment;
    },
    set: function(enable) {
      if (enable !== true) {
        enable = false;

        this.resetAlignment();
      }

      if (enable !== this.enabled) {
        // If we are changing the enabled state then disable manual alignment.
        // We only do this if we are changing the enabled state so that the client can repeatedly call the
        // setting without having any effect if they aren't changing the enabled state, but so that every time
        // that the state is changed that the manual alignment is turned back off initally.
        this._manualAlignment = false;

        this._startEventLoop(enable);
      }
    }
  });

  /**
   * Gets or sets whether manual realignment mode is currently enabled (true) or not (false).
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {Boolean} manualAlignment
   */
  knockout.defineProperty(this, "manualAlignment", {
    get: function() {
      return this._getManualAlignment();
    },
    set: function(startEnd) {
      this._setManualAlignment(startEnd);
    }
  });

  /**
   * Gets whether a manual realignment has been specified (true) or not (false).
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {Boolean} manualAlignmentSet
   */
  knockout.defineProperty(this, "manualAlignmentSet", {
    get: function() {
      return this._realignAlpha !== 0.0 || this._realignHeading !== 0.0;
    }
  });

  /**
   * Gets the index of the current hover level.
   *
   * Use <code>AugmentedVirtuality.PRESET_HEIGHTS.length</code> to find the total avaliable levels.
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {int} hoverLevel
   */
  knockout.defineProperty(this, "hoverLevel", {
    get: function() {
      return this._hoverLevel;
    }
  });

  /**
   * Gets or sets the the maximum number of times that the camera orientation will be updated per second. This is
   * the number of camera orientation updates per seconds is capped to (explicitly the number of times the
   * orientation is updated per second might be less but it won't be more then this number). We want the number of
   * times that the orientation is updated capped so that we don't consume to much battery life updating to
   * frequently, but responsiveness is still acceptable.
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {Float} maximumUpdatesPerSecond
   */
  knockout.defineProperty(this, "maximumUpdatesPerSecond", {
    get: function() {
      return this._maximumUpdatesPerSecond;
    },
    set: function(maximumUpdatesPerSecond) {
      this._maximumUpdatesPerSecond = maximumUpdatesPerSecond;

      // If we are currently enabled reset to update the timing interval used.
      if (this._eventLoopRunning()) {
        this._startEventLoop(false);
        this._startEventLoop(true);
      }
    }
  });

  this.enabled = false;
}
function(terria) {
  const that = this;

  this._terria = terria;

  // Note: We create a persistant object and define a transient property, since knockout needs a persistant variable
  //       to track, but for state we want a 'maybe' intervalId.
  this._eventLoopState = {};

  this._manualAlignment = false;

  this._maximumUpdatesPerSecond =
    AugmentedVirtuality.DEFAULT_MAXIMUM_UPDATES_PER_SECOND;

  this._orientationUpdated = false;
  this._alpha = 0;
  this._beta = 0;
  this._gamma = 0;
  this._realignAlpha = 0;
  this._realignHeading = 0;

  // Set the default height to be the last height so that when we first toggle (and increment) we cycle and go to the first height.
  this._hoverLevel = AugmentedVirtuality.PRESET_HEIGHTS.length - 1;

  // Always run the device orientation event, this way as soon as we enable we know where we are and set the
  // orientation rather then having to wait for the next update.
  // The following is disabled because chrome does not currently support deviceorientationabsolute correctly:
  // if ('ondeviceorientationabsolute' in window)
  // {
  //     window.addEventListener('deviceorientationabsolute', function(event) {that._orientationUpdate(event);} );
  // }
  // else
  if ("ondeviceorientation" in window) {
    window.addEventListener("deviceorientation", function(event) {
      that._storeOrientation(event);
    });
  }

  // Make the variables used by the object properties knockout observable so that changes in the state notify the UI
  // and cause a UI update. Note: These are all of the variables used just by the getters (not the setters), since
  // these unqiquely define what the current state is and are the only things that can effect/cause the state to change
  // (note: _eventLoopState is hidden behind ._eventLoopRunning() ).
  knockout.track(this, [
    "_eventLoopState",
    "_manualAlignment",
    "_maximumUpdatesPerSecond",
    "_realignAlpha",
    "_realignHeading",
    "_hoverLevel"
  ]);

  // Note: The following properties are defined as knockout properties so that they can be used to trigger updates on the UI.
  /**
   * Gets or sets whether Augmented Virtuality mode is currently enabled (true) or not (false).
   *
   * Note: If {@link AugmentedVirtuality#manualAlignment} is enabled and the state is changed it will be disabled.
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {Boolean} enabled
   */
  knockout.defineProperty(this, "enabled", {
    get: function() {
      return this._eventLoopRunning() || this._manualAlignment;
    },
    set: function(enable) {
      if (enable !== true) {
        enable = false;

        this.resetAlignment();
      }

      if (enable !== this.enabled) {
        // If we are changing the enabled state then disable manual alignment.
        // We only do this if we are changing the enabled state so that the client can repeatedly call the
        // setting without having any effect if they aren't changing the enabled state, but so that every time
        // that the state is changed that the manual alignment is turned back off initally.
        this._manualAlignment = false;

        this._startEventLoop(enable);
      }
    }
  });

  /**
   * Gets or sets whether manual realignment mode is currently enabled (true) or not (false).
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {Boolean} manualAlignment
   */
  knockout.defineProperty(this, "manualAlignment", {
    get: function() {
      return this._getManualAlignment();
    },
    set: function(startEnd) {
      this._setManualAlignment(startEnd);
    }
  });

  /**
   * Gets whether a manual realignment has been specified (true) or not (false).
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {Boolean} manualAlignmentSet
   */
  knockout.defineProperty(this, "manualAlignmentSet", {
    get: function() {
      return this._realignAlpha !== 0.0 || this._realignHeading !== 0.0;
    }
  });

  /**
   * Gets the index of the current hover level.
   *
   * Use <code>AugmentedVirtuality.PRESET_HEIGHTS.length</code> to find the total avaliable levels.
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {int} hoverLevel
   */
  knockout.defineProperty(this, "hoverLevel", {
    get: function() {
      return this._hoverLevel;
    }
  });

  /**
   * Gets or sets the the maximum number of times that the camera orientation will be updated per second. This is
   * the number of camera orientation updates per seconds is capped to (explicitly the number of times the
   * orientation is updated per second might be less but it won't be more then this number). We want the number of
   * times that the orientation is updated capped so that we don't consume to much battery life updating to
   * frequently, but responsiveness is still acceptable.
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {Float} maximumUpdatesPerSecond
   */
  knockout.defineProperty(this, "maximumUpdatesPerSecond", {
    get: function() {
      return this._maximumUpdatesPerSecond;
    },
    set: function(maximumUpdatesPerSecond) {
      this._maximumUpdatesPerSecond = maximumUpdatesPerSecond;

      // If we are currently enabled reset to update the timing interval used.
      if (this._eventLoopRunning()) {
        this._startEventLoop(false);
        this._startEventLoop(true);
      }
    }
  });

  this.enabled = false;
}
function ( terria ) { const that = this ; this . _terria = terria ; // Note: We create a persistant object and define a transient property, since knockout needs a persistant variable //       to track, but for state we want a 'maybe' intervalId. this . _eventLoopState = { } ; this . _manualAlignment = false ; this . _maximumUpdatesPerSecond = AugmentedVirtuality . DEFAULT_MAXIMUM_UPDATES_PER_SECOND ; this . _orientationUpdated = false ; this . _alpha = 0 ; this . _beta = 0 ; this . _gamma = 0 ; this . _realignAlpha = 0 ; this . _realignHeading = 0 ; // Set the default height to be the last height so that when we first toggle (and increment) we cycle and go to the first height. this . _hoverLevel = AugmentedVirtuality . PRESET_HEIGHTS . length - 1 ; // Always run the device orientation event, this way as soon as we enable we know where we are and set the // orientation rather then having to wait for the next update. // The following is disabled because chrome does not currently support deviceorientationabsolute correctly: // if ('ondeviceorientationabsolute' in window) // { //     window.addEventListener('deviceorientationabsolute', function(event) {that._orientationUpdate(event);} ); // } // else if ( "ondeviceorientation" in window ) { window . addEventListener ( "deviceorientation" , function ( event ) { that . _storeOrientation ( event ) ; } ) ; } // Make the variables used by the object properties knockout observable so that changes in the state notify the UI // and cause a UI update. Note: These are all of the variables used just by the getters (not the setters), since // these unqiquely define what the current state is and are the only things that can effect/cause the state to change // (note: _eventLoopState is hidden behind ._eventLoopRunning() ). knockout . track ( this , [ "_eventLoopState" , "_manualAlignment" , "_maximumUpdatesPerSecond" , "_realignAlpha" , "_realignHeading" , "_hoverLevel" ] ) ; // Note: The following properties are defined as knockout properties so that they can be used to trigger updates on the UI. /**
   * Gets or sets whether Augmented Virtuality mode is currently enabled (true) or not (false).
   *
   * Note: If {@link AugmentedVirtuality#manualAlignment} is enabled and the state is changed it will be disabled.
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {Boolean} enabled
   */ knockout . defineProperty ( this , "enabled" , { get : function ( ) { return this . _eventLoopRunning ( ) || this . _manualAlignment ; } , set : function ( enable ) { if ( enable !== true ) { enable = false ; this . resetAlignment ( ) ; } if ( enable !== this . enabled ) { // If we are changing the enabled state then disable manual alignment. // We only do this if we are changing the enabled state so that the client can repeatedly call the // setting without having any effect if they aren't changing the enabled state, but so that every time // that the state is changed that the manual alignment is turned back off initally. this . _manualAlignment = false ; this . _startEventLoop ( enable ) ; } } } ) ; /**
   * Gets or sets whether manual realignment mode is currently enabled (true) or not (false).
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {Boolean} manualAlignment
   */ knockout . defineProperty ( this , "manualAlignment" , { get : function ( ) { return this . _getManualAlignment ( ) ; } , set : function ( startEnd ) { this . _setManualAlignment ( startEnd ) ; } } ) ; /**
   * Gets whether a manual realignment has been specified (true) or not (false).
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {Boolean} manualAlignmentSet
   */ knockout . defineProperty ( this , "manualAlignmentSet" , { get : function ( ) { return this . _realignAlpha !== 0.0 || this . _realignHeading !== 0.0 ; } } ) ; /**
   * Gets the index of the current hover level.
   *
   * Use <code>AugmentedVirtuality.PRESET_HEIGHTS.length</code> to find the total avaliable levels.
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {int} hoverLevel
   */ knockout . defineProperty ( this , "hoverLevel" , { get : function ( ) { return this . _hoverLevel ; } } ) ; /**
   * Gets or sets the the maximum number of times that the camera orientation will be updated per second. This is
   * the number of camera orientation updates per seconds is capped to (explicitly the number of times the
   * orientation is updated per second might be less but it won't be more then this number). We want the number of
   * times that the orientation is updated capped so that we don't consume to much battery life updating to
   * frequently, but responsiveness is still acceptable.
   *
   * @memberOf AugmentedVirtuality.prototype
   * @member {Float} maximumUpdatesPerSecond
   */ knockout . defineProperty ( this , "maximumUpdatesPerSecond" , { get : function ( ) { return this . _maximumUpdatesPerSecond ; } , set : function ( maximumUpdatesPerSecond ) { this . _maximumUpdatesPerSecond = maximumUpdatesPerSecond ; // If we are currently enabled reset to update the timing interval used. if ( this . _eventLoopRunning ( ) ) { this . _startEventLoop ( false ) ; this . _startEventLoop ( true ) ; } } } ) ; this . enabled = false ; }
Manages state for Augmented Virtuality mode.

This mode uses the devices orientation sensors to change the viewers viewport to match the change in orientation.

Term Augmented Virtuality:
"The use of real-world sensor information (e.g., gyroscopes) to control a virtual environment is an additional form
of augmented virtuality, in which external inputs provide context for the virtual view."
{@link https://en.wikipedia.org/wiki/Mixed_reality}

@alias AugmentedVirtuality
@constructor
Manages state for Augmented Virtuality mode .