immersive-web / webvr-polyfill

Use WebVR today, without requiring a special browser build.
http://immersive-web.github.io/webvr-polyfill/examples/
Apache License 2.0
1.4k stars 324 forks source link

calcDeviceParams_() running twice when using custom dpdb.json #313

Open j0hnm4r5 opened 6 years ago

j0hnm4r5 commented 6 years ago
Description:

A little background first

I'm creating a custom VR setup, using a small display and running content on it in Three.js on a PC.

Since it's not a real mobile device, I have to spoof the User Agent to make webvr think it is real, and I do so by setting it before I initialize the polyfill:

Object.defineProperty(navigator, "userAgent", {
    value:
        "Mozilla/5.0 (Linux; Android 0; CUSTOM-VR Build/0) AppleWebKit/0 (KHTML, like Gecko) Chrome/0 Mobile Safari/0",
        configurable: true,
    });

Additionally, since this device is definitely not in the official dpdb.json, I have to create my own version:

{
    "format": 1,
    "devices": [{
        "type": "android",
        "rules": [{
            "ua": "CUSTOM-VR"
        }],
        "res": [1920, 1080],
        "dpi": 441,
        "bw": 2,
        "ac": 1000
    }]
}

And pass it into the polyfill:

setUA(); // set the UA
webvr = new WebVRPolyfill({ // create the polyfill
    DPDB_URL: "./data/dpdb.json",
});

Herein lies the issue

On initialization of the polyfill, I immediately get:

webvr-polyfill.js?1970 No DPDB device match.
webvr-polyfill.js?1922 Failed to recalculate device parameters.
webvr-polyfill.js?1706 Using fallback Android device measurements.

But when looking at the returned devices, it does seem like the CardboardVRDisplay has correctly initialized, as config.DPDB_URL is "./data/dpdb.json", and deviceInfo_.device.bevelMeters is 0.002.

After throwing some additional logs in webvr-polyfill.js, it seems like calcDeviceParams_() is running twice, once for the DPDB_CACHE, and then once for my special dpdb.json. The first call throws the errors, and the second call overwrites the fallback device with the custom one.

Additional Information:
jsantell commented 6 years ago

Looking at the dpdb logic in cardboard-vr-display, it looks like, yes, the device is initially searched for in the local DPDB copy, and then falls back to fetching the URL for an up-to-date value. Are the expectations here that the data/data.json should be calculated first before the local cache?

I wonder for local values, if it'd make more sense to pass them into the constructor rather than requiring an XHR call for values, as this is more for sites out in the wild to be able to pull in the latest device values without needing to update the polyfill, rather than supplying your own local device values.

j0hnm4r5 commented 6 years ago

I guess my expectations are that the local copy would be appended to the url or cached copy, so looking through the devices array only happens once. But if that’s not feasible, checking the local one first would make more sense, at least in my use-case.

jsantell commented 6 years ago

The DPDB_URL is for referencing remote data that may contain updated content, and not considered "local", as a fallback, which is a different connotation than appending extra data locally. Otherwise, all experiences would first require the URL data fetch, which leads me to think that maybe there should be a different mechanism for local data

j0hnm4r5 commented 6 years ago

Oh, I see.

That would certainly help my use case, which I admit is pretty rare in the grand scheme of things. If there was an additional DPDB_LOCAL option in the config, that took a javascript object and appended it to the existing cache before anything initialized, that would help. As it stands right now, though, this is just an annoying visual bug, and not anything game-breaking.

To clear up my understanding, there's three potential sources of the DPDB, right? The hardcoded DPDB_CACHE, the one at https://dpdb.webvr.rocks/dpdb.json (which is defined in the default config), and then the ability to replace that url with a custom one? I guess I'm confused as to why this issue doesn't happen all the time if the DPDB_URL is already defined (which it looks to be from the default config) and all I'm doing is replacing that URL.

jsantell commented 6 years ago

Your understanding matches mine I believe; however the fetch for the DPDB_URL should only occur if the device wasn't found in the local DPDB_CACHE. Does this have a visual effect on distortion? The remote DPDB should be available usually by the time a user enters VR.

And yes, I think a DPDB_LOCAL option is a good idea, since I've seen users do what your describing to add their specific device for testing

devasur commented 6 years ago

Was there any progress on this? DPDB_LOCAL seems like a good option to add.

bryantAXS commented 5 years ago

I'm running into this as well. As anyone come across a solution?