B2G/gecko/browser/devtools/tilt/TiltVisualizer.jsm
/**
   * Call this function whenever you need the updated rotation quaternion
   * and the zoom amount. These values will be returned as "rotation" and
   * "translation" properties inside an object.
   *
   * @param {Number} aDelta
   *                 the current animation frame delta
   *
   * @return {Object} the rotation quaternion and the translation amount
   */
Call this function whenever you need the updated rotation quaternion
and the zoom amount. These values will be returned as "rotation" and
"translation" properties inside an object.

@param {Number} aDelta
the current animation frame delta

@return {Object} the rotation quaternion and the translation amount
Call this function whenever you need the updated rotation quaternion and the zoom amount . These values will be returned as " rotation " and " translation " properties inside an object . @param { Number } aDelta the current animation frame delta @return { Object } the rotation quaternion and the translation amount
function TVA_update(aDelta)
  {
    let mousePress = this._mousePress;
    let mouseRelease = this._mouseRelease;
    let mouseMove = this._mouseMove;
    let mouseLerp = this._mouseLerp;
    let mouseButton = this._mouseButton;
    mouseLerp[0] += (mouseMove[0] - mouseLerp[0]) * ARCBALL_SENSITIVITY;
    mouseLerp[1] += (mouseMove[1] - mouseLerp[1]) * ARCBALL_SENSITIVITY;
    let x = mouseLerp[0];
    let y = mouseLerp[1];
    if (mouseButton === 3 || x === mouseRelease[0] && y === mouseRelease[1]) {
      this._rotating = false;
    }
    let startVec = this._startVec;
    let endVec = this._endVec;
    let pVec = this._pVec;
    let lastRot = this._lastRot;
    let deltaRot = this._deltaRot;
    let currentRot = this._currentRot;
    if (mouseButton === 1 || this._rotating) {
      this._rotating = true;
      this._pointToSphere(x, y, this.width, this.height, this.radius, endVec);
      vec3.cross(startVec, endVec, pVec);
      if (vec3.length(pVec) > 0) {
        deltaRot[0] = pVec[0];
        deltaRot[1] = pVec[1];
        deltaRot[2] = pVec[2];
        deltaRot[3] = -vec3.dot(startVec, endVec);
      } else {
        deltaRot[0] = 0;
        deltaRot[1] = 0;
        deltaRot[2] = 0;
        deltaRot[3] = 1;
      }
      quat4.multiply(lastRot, deltaRot, currentRot);
    } else {
      quat4.set(currentRot, lastRot);
    }
    let lastTrans = this._lastTrans;
    let deltaTrans = this._deltaTrans;
    let currentTrans = this._currentTrans;
    if (mouseButton === 3) {
      deltaTrans[0] = mouseMove[0] - mousePress[0];
      deltaTrans[1] = mouseMove[1] - mousePress[1];
      currentTrans[0] = lastTrans[0] + deltaTrans[0];
      currentTrans[1] = lastTrans[1] + deltaTrans[1];
    } else {
      lastTrans[0] = currentTrans[0];
      lastTrans[1] = currentTrans[1];
    }
    let zoomAmount = this._zoomAmount;
    let keyCode = this._keyCode;
    deltaTrans[2] = (zoomAmount - currentTrans[2]) * ARCBALL_ZOOM_STEP;
    currentTrans[2] += deltaTrans[2];
    let additionalRot = this._additionalRot;
    let additionalTrans = this._additionalTrans;
    let deltaAdditionalRot = this._deltaAdditionalRot;
    let deltaAdditionalTrans = this._deltaAdditionalTrans;
    let rotateKeys = this.rotateKeys;
    let panKeys = this.panKeys;
    let zoomKeys = this.zoomKeys;
    let resetKey = this.resetKey;
    if (keyCode[rotateKeys.left]) {
      additionalRot[0] -= ARCBALL_SENSITIVITY * ARCBALL_ROTATION_STEP;
    }
    if (keyCode[rotateKeys.right]) {
      additionalRot[0] += ARCBALL_SENSITIVITY * ARCBALL_ROTATION_STEP;
    }
    if (keyCode[rotateKeys.up]) {
      additionalRot[1] += ARCBALL_SENSITIVITY * ARCBALL_ROTATION_STEP;
    }
    if (keyCode[rotateKeys.down]) {
      additionalRot[1] -= ARCBALL_SENSITIVITY * ARCBALL_ROTATION_STEP;
    }
    if (keyCode[panKeys.left]) {
      additionalTrans[0] -= ARCBALL_SENSITIVITY * ARCBALL_TRANSLATION_STEP;
    }
    if (keyCode[panKeys.right]) {
      additionalTrans[0] += ARCBALL_SENSITIVITY * ARCBALL_TRANSLATION_STEP;
    }
    if (keyCode[panKeys.up]) {
      additionalTrans[1] -= ARCBALL_SENSITIVITY * ARCBALL_TRANSLATION_STEP;
    }
    if (keyCode[panKeys.down]) {
      additionalTrans[1] += ARCBALL_SENSITIVITY * ARCBALL_TRANSLATION_STEP;
    }
    if (keyCode[zoomKeys["in"][0]] ||
        keyCode[zoomKeys["in"][1]] ||
        keyCode[zoomKeys["in"][2]]) {
      this.zoom(-ARCBALL_TRANSLATION_STEP);
    }
    if (keyCode[zoomKeys["out"][0]] ||
        keyCode[zoomKeys["out"][1]]) {
      this.zoom(ARCBALL_TRANSLATION_STEP);
    }
    if (keyCode[zoomKeys["unzoom"]]) {
      this._zoomAmount = 0;
    }
    if (keyCode[resetKey]) {
      this.reset();
    }
    deltaAdditionalRot[0] +=
      (additionalRot[0] - deltaAdditionalRot[0]) * ARCBALL_SENSITIVITY;
    deltaAdditionalRot[1] +=
      (additionalRot[1] - deltaAdditionalRot[1]) * ARCBALL_SENSITIVITY;
    deltaAdditionalRot[2] +=
      (additionalRot[2] - deltaAdditionalRot[2]) * ARCBALL_SENSITIVITY;
    deltaAdditionalTrans[0] +=
      (additionalTrans[0] - deltaAdditionalTrans[0]) * ARCBALL_SENSITIVITY;
    deltaAdditionalTrans[1] +=
      (additionalTrans[1] - deltaAdditionalTrans[1]) * ARCBALL_SENSITIVITY;
    quat4.fromEuler(
      deltaAdditionalRot[0],
      deltaAdditionalRot[1],
      deltaAdditionalRot[2], deltaRot);
    vec3.set([deltaAdditionalTrans[0], deltaAdditionalTrans[1], 0], deltaTrans);
    if (this._resetInProgress) {
      this._nextResetStep(aDelta || 1);
    }
    return {
      rotation: quat4.multiply(deltaRot, currentRot),
      translation: vec3.add(deltaTrans, currentTrans)
    };
  }
function TVA_update ( aDelta ) { let mousePress = this . _mousePress ; let mouseRelease = this . _mouseRelease ; let mouseMove = this . _mouseMove ; let mouseLerp = this . _mouseLerp ; let mouseButton = this . _mouseButton ; mouseLerp [ 0 ] += ( mouseMove [ 0 ] - mouseLerp [ 0 ] ) * ARCBALL_SENSITIVITY ; mouseLerp [ 1 ] += ( mouseMove [ 1 ] - mouseLerp [ 1 ] ) * ARCBALL_SENSITIVITY ; let x = mouseLerp [ 0 ] ; let y = mouseLerp [ 1 ] ; if ( mouseButton === 3 || x === mouseRelease [ 0 ] && y === mouseRelease [ 1 ] ) { this . _rotating = false ; } let startVec = this . _startVec ; let endVec = this . _endVec ; let pVec = this . _pVec ; let lastRot = this . _lastRot ; let deltaRot = this . _deltaRot ; let currentRot = this . _currentRot ; if ( mouseButton === 1 || this . _rotating ) { this . _rotating = true ; this . _pointToSphere ( x , y , this . width , this . height , this . radius , endVec ) ; vec3 . cross ( startVec , endVec , pVec ) ; if ( vec3 . length ( pVec ) > 0 ) { deltaRot [ 0 ] = pVec [ 0 ] ; deltaRot [ 1 ] = pVec [ 1 ] ; deltaRot [ 2 ] = pVec [ 2 ] ; deltaRot [ 3 ] = - vec3 . dot ( startVec , endVec ) ; } else { deltaRot [ 0 ] = 0 ; deltaRot [ 1 ] = 0 ; deltaRot [ 2 ] = 0 ; deltaRot [ 3 ] = 1 ; } quat4 . multiply ( lastRot , deltaRot , currentRot ) ; } else { quat4 . set ( currentRot , lastRot ) ; } let lastTrans = this . _lastTrans ; let deltaTrans = this . _deltaTrans ; let currentTrans = this . _currentTrans ; if ( mouseButton === 3 ) { deltaTrans [ 0 ] = mouseMove [ 0 ] - mousePress [ 0 ] ; deltaTrans [ 1 ] = mouseMove [ 1 ] - mousePress [ 1 ] ; currentTrans [ 0 ] = lastTrans [ 0 ] + deltaTrans [ 0 ] ; currentTrans [ 1 ] = lastTrans [ 1 ] + deltaTrans [ 1 ] ; } else { lastTrans [ 0 ] = currentTrans [ 0 ] ; lastTrans [ 1 ] = currentTrans [ 1 ] ; } let zoomAmount = this . _zoomAmount ; let keyCode = this . _keyCode ; deltaTrans [ 2 ] = ( zoomAmount - currentTrans [ 2 ] ) * ARCBALL_ZOOM_STEP ; currentTrans [ 2 ] += deltaTrans [ 2 ] ; let additionalRot = this . _additionalRot ; let additionalTrans = this . _additionalTrans ; let deltaAdditionalRot = this . _deltaAdditionalRot ; let deltaAdditionalTrans = this . _deltaAdditionalTrans ; let rotateKeys = this . rotateKeys ; let panKeys = this . panKeys ; let zoomKeys = this . zoomKeys ; let resetKey = this . resetKey ; if ( keyCode [ rotateKeys . left ] ) { additionalRot [ 0 ] -= ARCBALL_SENSITIVITY * ARCBALL_ROTATION_STEP ; } if ( keyCode [ rotateKeys . right ] ) { additionalRot [ 0 ] += ARCBALL_SENSITIVITY * ARCBALL_ROTATION_STEP ; } if ( keyCode [ rotateKeys . up ] ) { additionalRot [ 1 ] += ARCBALL_SENSITIVITY * ARCBALL_ROTATION_STEP ; } if ( keyCode [ rotateKeys . down ] ) { additionalRot [ 1 ] -= ARCBALL_SENSITIVITY * ARCBALL_ROTATION_STEP ; } if ( keyCode [ panKeys . left ] ) { additionalTrans [ 0 ] -= ARCBALL_SENSITIVITY * ARCBALL_TRANSLATION_STEP ; } if ( keyCode [ panKeys . right ] ) { additionalTrans [ 0 ] += ARCBALL_SENSITIVITY * ARCBALL_TRANSLATION_STEP ; } if ( keyCode [ panKeys . up ] ) { additionalTrans [ 1 ] -= ARCBALL_SENSITIVITY * ARCBALL_TRANSLATION_STEP ; } if ( keyCode [ panKeys . down ] ) { additionalTrans [ 1 ] += ARCBALL_SENSITIVITY * ARCBALL_TRANSLATION_STEP ; } if ( keyCode [ zoomKeys [ "in" ] [ 0 ] ] || keyCode [ zoomKeys [ "in" ] [ 1 ] ] || keyCode [ zoomKeys [ "in" ] [ 2 ] ] ) { this . zoom ( - ARCBALL_TRANSLATION_STEP ) ; } if ( keyCode [ zoomKeys [ "out" ] [ 0 ] ] || keyCode [ zoomKeys [ "out" ] [ 1 ] ] ) { this . zoom ( ARCBALL_TRANSLATION_STEP ) ; } if ( keyCode [ zoomKeys [ "unzoom" ] ] ) { this . _zoomAmount = 0 ; } if ( keyCode [ resetKey ] ) { this . reset ( ) ; } deltaAdditionalRot [ 0 ] += ( additionalRot [ 0 ] - deltaAdditionalRot [ 0 ] ) * ARCBALL_SENSITIVITY ; deltaAdditionalRot [ 1 ] += ( additionalRot [ 1 ] - deltaAdditionalRot [ 1 ] ) * ARCBALL_SENSITIVITY ; deltaAdditionalRot [ 2 ] += ( additionalRot [ 2 ] - deltaAdditionalRot [ 2 ] ) * ARCBALL_SENSITIVITY ; deltaAdditionalTrans [ 0 ] += ( additionalTrans [ 0 ] - deltaAdditionalTrans [ 0 ] ) * ARCBALL_SENSITIVITY ; deltaAdditionalTrans [ 1 ] += ( additionalTrans [ 1 ] - deltaAdditionalTrans [ 1 ] ) * ARCBALL_SENSITIVITY ; quat4 . fromEuler ( deltaAdditionalRot [ 0 ] , deltaAdditionalRot [ 1 ] , deltaAdditionalRot [ 2 ] , deltaRot ) ; vec3 . set ( [ deltaAdditionalTrans [ 0 ] , deltaAdditionalTrans [ 1 ] , 0 ] , deltaTrans ) ; if ( this . _resetInProgress ) { this . _nextResetStep ( aDelta || 1 ) ; } return { rotation : quat4 . multiply ( deltaRot , currentRot ) , translation : vec3 . add ( deltaTrans , currentTrans ) } ; }
Call this function whenever you need the updated rotation quaternion
 and the zoom amount.
Call this function whenever you need the updated rotation quaternion and the zoom amount .
// smoothly update the mouse coordinates // cache the interpolated mouse coordinates // the smoothed arcball rotation may not be finished when the mouse is // pressed again, so cancel the rotation if other events occur or the // animation finishes // left mouse button handles rotation // the rotation doesn't stop immediately after the left mouse button is // released, so add a flag to smoothly continue it until it ends // find the sphere coordinates of the mouse positions // compute the vector perpendicular to the start & end vectors // if the begin and end vectors don't coincide // in the quaternion values, w is cosine (theta / 2), // where theta is the rotation angle // return an identity rotation quaternion // calculate the current rotation based on the mouse click events // save the current quaternion to stack rotations // right mouse button handles panning // calculate a delta translation between the new and old mouse position // and save it to the current translation // save the current panning to stack translations // mouse wheel handles zooming // handle additional rotation and translation by the keyboard // update the delta key rotations and translations // create an additional rotation based on the key events // create an additional translation based on the key events // handle the reset animation steps if necessary // return the current rotation and translation