Device orientation and camera target

Not really a question but an answer I was not able to found on the forum.

Related questions:

etc

Now, I’m not using DeviceOrientationCamera but UniversalCamera with FreeCameraDeviceOrientationInput, but it’s the same story - Camera.setTarget() doesn’t do anything with device input attached.

To make it work, I had to

  • override FreeCameraDeviceOrientationInput._deviceOrientation to store initial camera rotation
  • override TargetCamera.setTarget to store the target angle
  • override FreeCameraDeviceOrientationInput.checkInputs to take these two into account

Actual code:

      // see https://github.com/BabylonJS/Babylon.js/blob/master/packages/dev/core/src/Cameras/Inputs/freeCameraDeviceOrientationInput.ts
      let deviceOrientation = new BABYLON.FreeCameraDeviceOrientationInput();
      deviceOrientation.angleOffset = 0;
      deviceOrientation.angleInitial = 0;
      deviceOrientation._deviceOrientation_original = deviceOrientation._deviceOrientation;

      deviceOrientation._deviceOrientation = (evt) => {
        if (!deviceOrientation.angleInitial && evt.alpha) {
          deviceOrientation.angleInitial = evt.alpha;
          console.log("Initial device orientation: "+evt.alpha+" "+evt.beta+" "+evt.gamma);
        }
        deviceOrientation._deviceOrientation_original(evt);
      }

      // see https://github.com/BabylonJS/Babylon.js/blob/master/packages/dev/core/src/Cameras/targetCamera.ts#L260
      camera.setTarget_original = camera.setTarget;
      camera.setTarget = (vector) => {
        camera.setTarget_original(vector);
        deviceOrientation.angleOffset = camera.rotation.y/2/Math.PI*360;
      }

      deviceOrientation.checkInputs_original = deviceOrientation.checkInputs;
      deviceOrientation.checkInputs = () => {
        // https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent
        // touch screen does not necessarily mean orientation info is available - do not mess up camera for these
        if ( deviceOrientation.angleInitial ) {
          deviceOrientation._alpha -= (deviceOrientation.angleInitial + deviceOrientation.angleOffset);
          deviceOrientation.checkInputs_original();
          deviceOrientation._alpha += (deviceOrientation.angleInitial + deviceOrientation.angleOffset);
        } else {
          deviceOrientation.checkInputs_original();
        }
      }

Snippet comes from vrspace/babylon/js/world/world.js at master · jalmasi/vrspace · GitHub and you can try it any time at vrspace.org. At the moment missing part is turning that on and off as desired, I may do it eventually.

Now I’m going to cast my vote for that RFE, not that I need it any longer :wink: But it’s reasonably simple to implement, as you can see above.

5 Likes