AR-js-org / AR.js

Image tracking, Location Based AR, Marker tracking. All on the Web.
MIT License
5.3k stars 909 forks source link

Location based ar with aframe requires different FOV values for chrome than it does for firefox #572

Open Platform-Group opened 9 months ago

Platform-Group commented 9 months ago

Do you want to request a feature or report a bug? Bug

What is the current behavior? The samsung tablet I'm using requires an FOV of 52.75 on firefox and an fov of 87 on chrome. This of course screws up the scale of everything but it's needed to ensure the "pins" stay on their given latitude and longitude when turning the tablet.

If the current behavior is a bug, please provide the steps to reproduce. Set up a simple location based aframe example, place a location about a km away, correct the fov on chrome or firefox until it's staying on target while you turn the device, change to the other browser and observe that the fov is now screwed up.

Please mention other relevant information such as the browser version, Operating System and Device Name Android samsung galaxy s8

What is the expected behavior? That FOV doesn't need to be changed between browsers

Platform-Group commented 9 months ago

It seems that the firefox camera is zoomed in which accounts for this discrepancy, I'm just unsure of why the firefox camera is zoomed.

Platform-Group commented 9 months ago

I noticed from arjs-webcam-texture.js that if I look at the stream's settings firefox doesn't have the "zoom" parameter while chrome does. And changing the deviceId seems to break it or have no effect. However chrome allows for the zoom parameter. So rather than trying to zoom firefox out which seems to be impossible, I decided to just zoom chrome in to match it for now

So I added zoom to the constraints

video: {
          facingMode: "environment",
          zoom: 2
        },

Added zoom to the 3d environment via the camera

<a-camera
        fov-change
        id="camera"
        gps-new-camera="gpsMinDistance: 5; simulateLatitude: 1; simulateLongitude: 1; simulateAltitude: 400;"
        far="1000000"
        look-controls-enabled="true"
        look-controls="enabled: true; magicWindowTrackingEnabled: true; touchEnabled: true; mouseEnabled: true"
        zoom="2"
      >

And set the fov to be dependent on the browser

AFRAME.registerComponent("fov-change", {
        init: function () {
          // grab the camera
          const cam = document.querySelector("[camera]");
          // this.el should also work for this as long as your fov-change component is on the camera
          // grab the current FOV, this will be 80 as that's the default for aframe
          const fov = cam.getAttribute("camera").fov;
          console.log("Wow, fov is ", fov);
          // update the camera with the new FOV
          // if holding portrait use 61:
          // cam.setAttribute("camera", "fov", 61)

          // For whatever weird reason it seems that chrome and firefox use different fov values?
          if (navigator.userAgent.indexOf("Chrome") != -1) {
            cam.setAttribute("camera", "fov", 87);
          } else if (navigator.userAgent.indexOf("Firefox") != -1) {
            // For landscape, 45 on the ipad, 52.75 for the samsung
            cam.setAttribute("camera", "fov", 52.75);
          } else {
            // Don't really know what other browsers use, but most will be chromium I suppose?
            cam.setAttribute("camera", "fov", 87);
          }

          console.log("Wow, fov is now", document.querySelector("[camera]").getAttribute("camera").fov);
        },
      });

It's an ugly workaround but I don't think there's another option as I can't seem to get a better stream from firefox at all.