Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update polyfill to use WebVR v1 API #33

Merged
merged 1 commit into from
Mar 2, 2016
Merged

Update polyfill to use WebVR v1 API #33

merged 1 commit into from
Mar 2, 2016

Conversation

toji
Copy link
Member

@toji toji commented Feb 24, 2016

Now includes distortion and querying of device parameters from DPDB. Old API
is still accessible when setting WebVRConfig.ENABLE_DEPRECATED_API to true.

@toji
Copy link
Member Author

toji commented Feb 24, 2016

Apologies for the large pull request. Happy to discuss any part of it you have questions about. Would like to try and get this merged before the release of the WebVR v1 spec/builds so that I can point developers to the official polyfill repo from day one instead of my fork.

self.isPresenting = fullscreenElement == layer.source;
self.fireVRDisplayPresentChange_();
if (self.isPresenting) {
if (screen.orientation && screen.orientation.lock)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jshint will complain; I would put /* global screen */ up top

@toji
Copy link
Member Author

toji commented Feb 25, 2016

Addressed @cvan's comments and fixed a bug or two.


if (!this.isWebVRAvailable()) {
if (!this.nativeWebVRAvailable) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, we should bail return early if this.nativeWebVRAvailable (would also prevent having to check WebVRConfig.ENABLE_DEPRECATED_API below if you wanted to).

@cvan
Copy link
Contributor

cvan commented Feb 26, 2016

I had to make these changes for this to work in Firefox and your older Chromium builds:

diff --git a/src/webvr-polyfill.js b/src/webvr-polyfill.js
index 0e8c237..a02952b 100644
--- a/src/webvr-polyfill.js
+++ b/src/webvr-polyfill.js
@@ -28,12 +28,15 @@ function WebVRPolyfill() {
   this.devices = []; // For deprecated objects
   this.devicesPopulated = false;
   this.nativeWebVRAvailable = this.isWebVRAvailable();
+  this.nativeLegacyWebVRAvailable = this.isDeprecatedWebVRAvailable();

-  if (!this.nativeWebVRAvailable) {
-    this.enablePolyfill();
-  }
-  if (WebVRConfig.ENABLE_DEPRECATED_API && !this.isDeprecatedWebVRAvailable()) {
-    this.enableDeprecatedPolyfill();
+  if (!this.nativeLegacyWebVRAvailable) {
+    if (!this.nativeWebVRAvailable) {
+      this.enablePolyfill();
+    }
+    if (WebVRConfig.ENABLE_DEPRECATED_API) {
+      this.enableDeprecatedPolyfill();
+    }
   }
 }

@@ -113,15 +116,30 @@ WebVRPolyfill.prototype.getVRDevices = function() {
   var self = this;
   return new Promise(function(resolve, reject) {
     try {
-      if (!self.devicesPopulated && self.nativeWebVRAvailable) {
-        navigator.getVRDisplays(function(displays) {
-          for (var i = 0; i < displays.length; ++i) {
-            self.devices.push(new VRDisplayHMDDevice(displays[i]));
-            self.devices.push(new VRDisplayPositionSensorDevice(displays[i]));
-          }
-          self.devicesPopulated = true;
-          resolve(self.devices);
-        }, reject);
+      if (!self.devicesPopulated) {
+        if (self.nativeWebVRAvailable) {
+          navigator.getVRDisplays(function(displays) {
+            for (var i = 0; i < displays.length; ++i) {
+              self.devices.push(new VRDisplayHMDDevice(displays[i]));
+              self.devices.push(new VRDisplayPositionSensorDevice(displays[i]));
+            }
+            self.devicesPopulated = true;
+            resolve(self.devices);
+          }, reject);
+        } else if (self.nativeLegacyWebVRAvailable) {
+          (navigator.getVRDDevices || navigator.mozGetVRDevices)(function(devices) {
+            for (var i = 0; i < devices.length; ++i) {
+              if (devices[i] instanceof HMDVRDevice) {
+                self.devices.push(displays[i]);
+              }
+              if (devices[i] instanceof PositionSensorVRDevice) {
+                self.devices.push(devices[i]);
+              }
+            }
+            self.devicesPopulated = true;
+            resolve(self.devices);
+          }, reject);
+        }
       } else {
         self.populateDevices();
         resolve(self.devices);

@@ -0,0 +1,2 @@

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend

*.log
*.pid
*.seed
*~
.DS_Store
.node_repl_history
.npm
logs
node_modules
npm-debug.log*
pids

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opened #34; this is fine for now

@cvan
Copy link
Contributor

cvan commented Mar 1, 2016

latest patch to fix Firefox/older Chromium experimental builds:

diff --git a/src/webvr-polyfill.js b/src/webvr-polyfill.js
index 0e8c237..20eac0d 100644
--- a/src/webvr-polyfill.js
+++ b/src/webvr-polyfill.js
@@ -28,12 +28,15 @@ function WebVRPolyfill() {
   this.devices = []; // For deprecated objects
   this.devicesPopulated = false;
   this.nativeWebVRAvailable = this.isWebVRAvailable();
+  this.nativeLegacyWebVRAvailable = this.isDeprecatedWebVRAvailable();

-  if (!this.nativeWebVRAvailable) {
-    this.enablePolyfill();
-  }
-  if (WebVRConfig.ENABLE_DEPRECATED_API && !this.isDeprecatedWebVRAvailable()) {
-    this.enableDeprecatedPolyfill();
+  if (!this.nativeLegacyWebVRAvailable) {
+    if (!this.nativeWebVRAvailable) {
+      this.enablePolyfill();
+    }
+    if (WebVRConfig.ENABLE_DEPRECATED_API) {
+      this.enableDeprecatedPolyfill();
+    }
   }
 }

@@ -113,19 +116,36 @@ WebVRPolyfill.prototype.getVRDevices = function() {
   var self = this;
   return new Promise(function(resolve, reject) {
     try {
-      if (!self.devicesPopulated && self.nativeWebVRAvailable) {
-        navigator.getVRDisplays(function(displays) {
-          for (var i = 0; i < displays.length; ++i) {
-            self.devices.push(new VRDisplayHMDDevice(displays[i]));
-            self.devices.push(new VRDisplayPositionSensorDevice(displays[i]));
-          }
-          self.devicesPopulated = true;
-          resolve(self.devices);
-        }, reject);
-      } else {
-        self.populateDevices();
-        resolve(self.devices);
+      if (!self.devicesPopulated) {
+        if (self.nativeWebVRAvailable) {
+          return navigator.getVRDisplays(function(displays) {
+            for (var i = 0; i < displays.length; ++i) {
+              self.devices.push(new VRDisplayHMDDevice(displays[i]));
+              self.devices.push(new VRDisplayPositionSensorDevice(displays[i]));
+            }
+            self.devicesPopulated = true;
+            resolve(self.devices);
+          }, reject);
+        }
+
+        if (self.nativeLegacyWebVRAvailable) {
+          return (navigator.getVRDDevices || navigator.mozGetVRDevices)(function(devices) {
+            for (var i = 0; i < devices.length; ++i) {
+              if (devices[i] instanceof HMDVRDevice) {
+                self.devices.push(displays[i]);
+              }
+              if (devices[i] instanceof PositionSensorVRDevice) {
+                self.devices.push(devices[i]);
+              }
+            }
+            self.devicesPopulated = true;
+            resolve(self.devices);
+          }, reject);
+        }
       }
+
+      self.populateDevices();
+      resolve(self.devices);
     } catch (e) {
       reject(e);
     }

// Initialize our virtual VR devices.
if (this.isCardboardCompatible()) {
this.devices.push(new CardboardHMDVRDevice());
var vrDisplay = new CardboardVRDisplay();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

variable already defined above. drop the var.

@toji
Copy link
Member Author

toji commented Mar 1, 2016

Implemented the patch @cvan pasted inline above as well as a couple of other fixes mentioned in this conversation. Also refactored the mouse and keyboard implementation as a VRDisplay and started exposing it on non-mobile. As always, you can see the latest version in action on http://toji.github.io/webvr-samples/03a-webvr-polyfill.html

@toji
Copy link
Member Author

toji commented Mar 2, 2016

Latest update fixes resetPose on CardboardVRDisplay and corrects non-black distortion background with backbuffers that have an alpha channel. (which is forced on iOS)

};

VRDisplay.prototype.fireVRDisplayPresentChange_ = function() {
var event = new CustomEvent('vrdisplaypresentchange', { 'vrdisplay': this });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@toji listeners to this event don't receive the vrdisplay value, it needs to be added to the event detail:

var event = new CustomEvent('vrdisplaypresentchange', { detail: { vrdisplay: this } });

which makes it available at e.details.vrdisplay

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to reply here, but I instead adding a comment to the issue filed in the spec repo. Feel free to drop a line there: MozillaReality/webvr-spec#15.

@toji
Copy link
Member Author

toji commented Mar 2, 2016

Added flag to defer initialization of the polyfill (now used with all the samples at https://toji.github.io/webvr-samples) and fixed the issue @ashconnell brought up.

//MOUSE_KEYBOARD_CONTROLS_DISABLED: true, // Default: false
// Prevent the polyfill from initializing immediately. Requiures the app
// to call InitializeWebVRPolyfill() before it can be used.
//DEFER_INITIALIZATION: true, // default: false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would also mention this in the commit message

@cvan
Copy link
Contributor

cvan commented Mar 2, 2016

build/webvr-polyfill.js needs to be rebuilt. or I guess you could undo those changes and wait until the PR is ready to be merged and @borismus could do it.

Now includes distortion and querying of device parameters from DPDB. Old API
is still accessible when setting WebVRConfig.ENABLE_DEPRECATED_API to true.
@toji
Copy link
Member Author

toji commented Mar 2, 2016

Latests patch now includes basic Cardboard UI with the alignment line and options button. Hooks are in for a button click listener but at the moment it only writes a "not implemented" error to the console.

screenshot_20160302-102041

Also made sure I rebuilt the build/ version this time. :)

As for the deferred load thing, I talked to @borismus about it offline yesterday and he seemed OK with the current form, but if he'd like me to refactor it I'm happy to.

borismus added a commit that referenced this pull request Mar 2, 2016
Update polyfill to use WebVR v1 API
@borismus borismus merged commit 4e10331 into immersive-web:master Mar 2, 2016
@borismus
Copy link
Contributor

borismus commented Mar 2, 2016

Thanks Brandon, this is huge. I've started a parallel webvr-boilerplate branch. Once everything is working (hopefully with compat), can branch both branches to masters.

@cvan
Copy link
Contributor

cvan commented Mar 2, 2016

woo! thanks, @borismus and @toji! 👍

@toji toji deleted the webvr_1 branch April 3, 2016 22:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants