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

Generic VR controller. #10991

Closed
wants to merge 6 commits into from
Closed

Conversation

stewdio
Copy link
Contributor

@stewdio stewdio commented Mar 12, 2017

Handles gamepad discovery, emits event with controller (Object3D) instance. Handles controller updates for position, orientation (including 3DOF rigs). Watches for updates on axes and button states, emits corresponding events on the controller instance. Good for Vive, Rift, Daydream, and beyond. And all you need to do is include THREE.VRController.update() in your animation loop.

controller.dispatchEvent({ type: 'disconnected', controller: controller })
delete controller
}
window.addEventListener( 'gamepaddisconnected', function( event ){
Copy link
Owner

Choose a reason for hiding this comment

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

Hmm... This is sneaky...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For that particular bit I was aiming to follow Mozilla’s guidance here: https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API/Using_the_Gamepad_API

But instead of removing only the reference to the gamepad I deleted the whole controller. But what makes you say sneaky?

Copy link
Owner

Choose a reason for hiding this comment

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

What happens if someone includes VRController.js twice (by mistake)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh—are you talking about the window gamepaddisconnected event? I thought you were pointing out delete controller for some reason. As far as those events go I was (again) trying to follow the convention as seen here: https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API/Using_the_Gamepad_API

But I see what you mean—despite that feeling like a pretty obscure thing to troubleshoot 😉—it would indeed make those callbacks as many times as VRController.js was included in the document. Fortunately I’m not relying on those events (they’re not supported at all in Chrome right now) so I can strip them out without much fuss.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok. I’ve removed the 'ongamepadconnected' and 'ongamepaddisconnected' event listeners.

torus.rotation.y += 0.002;
if (torus.rotation.y > Math.PI) torus.rotation.y = torus.rotation.y - (Math.PI * 2);

controls.update();
Copy link
Owner

Choose a reason for hiding this comment

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

Can we add a requestAnimationFrame inside the controls so we don't have to call update from outside? We'll probably have to pass the vrdisplay to the VRController constructor so we can use the correct requestAnimationFrame.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is your comment about THREE.VRControls? Or about this proposed THREE.VRController? (Both follow the convention of requiring the developer to include a call to .update() in their animation loop.) I chose to follow the existing THREE.VRControls convention because I think this is the cleanest way to do it—rather than having independent rAF loops; makes the sequence of updates more predictable.

@mrdoob
Copy link
Owner

mrdoob commented Mar 17, 2017

Are let and const really needed? If someone includes this in a browser that doesn't support these yet things will break I think.

// Adapted from Boris’ code in a hurry -- many thanks!

const
HEAD_ELBOW_OFFSET = new THREE.Vector3( 0.155, -0.465, -0.15 ),
Copy link
Owner

Choose a reason for hiding this comment

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

You're defining these in global space. I think you should wrap all this code in a closure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are so correct here—I am embarrassed! It was a quick inclusion job. Will enclose those variables for sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Although it’s a bit verbose instead of wrapping it all in a closure, I made these formerly-global variables into properties of OrientationArmModel() because I felt it better expressed their purpose. But what do you think? (That change is in the latest commit around line 581.)

@stewdio
Copy link
Contributor Author

stewdio commented Mar 21, 2017

I think using let and const is the right way to go in this specific case. According to these feature support tables there is wider support for them than there is for the Web Gamepad API which we are relying on in this script.

Can I use let? http://caniuse.com/#feat=let
Can I use const? http://caniuse.com/#feat=const
Can I use the Gamepad API? http://caniuse.com/#feat=gamepad

ES6 is at least partially here and I think embracing it as it comes is not a terrible thing ;)

@mrdoob
Copy link
Owner

mrdoob commented Mar 21, 2017

My argument is that... If the user doesn't have navigator.getGamepads nothing breaks, the page still works. If the user doesn't have ES6 support, JavaScript will stop execution, right?

@stewdio
Copy link
Contributor Author

stewdio commented Mar 30, 2017

I see your point. I’ve removed const and let (ES6) in favor of var (ES5).

@stewdio
Copy link
Contributor Author

stewdio commented Apr 3, 2017

I think my latest commits have addressed your above concerns—aside from your comment about calling update() in the animation loop; I’d like to better understand your thoughts there.

Once you’re happy with the structure I imagine you’d like me to add semicolons and conform to your whitespace standards? 😉

@mrdoob
Copy link
Owner

mrdoob commented Apr 4, 2017

Looking good!

Once you’re happy with the structure I imagine you’d like me to add semicolons and conform to your whitespace standards? 😉

Yes, at least semicolons... Never trust the parser 😜

@stewdio
Copy link
Contributor Author

stewdio commented Apr 6, 2017

As much as it pained me to do it, I added semicolons just for you 😄

@stewdio
Copy link
Contributor Author

stewdio commented Apr 12, 2017

Howdy @mrdoob. Just checking if you had more thoughts on this VRController code 😉

@mflux
Copy link

mflux commented Apr 18, 2017

@mrdoob ricardo ;) bump

@stewdio
Copy link
Contributor Author

stewdio commented May 4, 2017

For the time being I’ve posted the code here, including a README:
https://github.com/stewdio/THREE.VRController

But of course I’d love to see this become an official part of r86 😉

@marclave
Copy link
Contributor

@mrdoob any updates with this PR? 😄

@alexozer
Copy link

alexozer commented Aug 6, 2017

@mrdoob Any updates?

@stewdio
Copy link
Contributor Author

stewdio commented Aug 6, 2017

Now supports r86: https://github.com/stewdio/THREE.VRController

@danrossi
Copy link

danrossi commented Sep 9, 2017

How is this one going ? This seems to work well for me with the Oculus and game controllers.

I was only able to get the trigger buttons working not the top buttons or joystick controls.

However is there an object model that might reflect the game controllers ? I'd like to support the vive controller as well as the GearVR remote.

I was unable to get a laser pointer raycaster working on the object just the menu

The model available in the demo is for the vive controller but the textures are huge.

@stewdio
Copy link
Contributor Author

stewdio commented Sep 9, 2017

It’s going really well, but I’m maintaining it here instead:
https://github.com/stewdio/THREE.VRController

The visual models for the various controllers is outside the scope of VRController.

@mflux
Copy link

mflux commented Sep 9, 2017

I'm surprised @stewdio you didn't mention @djambo's https://github.com/djambo/VRControllerView

@stewdio
Copy link
Contributor Author

stewdio commented Sep 9, 2017

AAAAAAHHHH! I didn’t realize that was public yet! My apologies to you and @djambo! I’ll also update VRController’s README to point to VRControllerView. (In-transit right now, but will do it soon.)

EDIT: It’s not public. I emailed @djambo to see if he’d publish it but no response yet.

@stewdio
Copy link
Contributor Author

stewdio commented Sep 9, 2017

(And that’s part of why I said it was “out of scope” cause I knew VRControllerView was going to handle it!)

@mflux
Copy link

mflux commented Sep 9, 2017

To be fair it really needs some documentation on how to use it.

@danrossi
Copy link

I tried to look for models. aframe include them all but not public. I'm going to fork the project then if required to get Gear VR remote support working.

@danrossi
Copy link

That project is not live sadly.

@stewdio
Copy link
Contributor Author

stewdio commented Oct 15, 2017

Just FYI for whoever ends up in this pull-request thread after Googling... The latest version of VRController now also supports Windows Mixed Reality motion controllers and is available here:
https://github.com/stewdio/THREE.VRController

VR Controller

@mrdoob
Copy link
Owner

mrdoob commented Jan 3, 2018

Alright. So... how about updating this PR so it sits on top of the WebXR Controllers API? 😇

@stewdio
Copy link
Contributor Author

stewdio commented Jan 3, 2018

Yes yes yes!

@danrossi
Copy link

danrossi commented Jan 4, 2018

Is this api available yet ? I see it requires a new api to launch and handle vr devices also.

@toji
Copy link
Contributor

toji commented Jan 8, 2018

For the record we've had our immediate plans for WebXR input derailed by some compatibility concerns with OpenXR. We're working on a solution to that, but in the meantime the Gamepad API will continue to be the way that these devices are accessed.

@mrdoob mrdoob added this to the rXX milestone Oct 26, 2018
@mrdoob
Copy link
Owner

mrdoob commented Nov 30, 2019

Things have changed quite a bit in the last two years...

@mrdoob mrdoob closed this Nov 30, 2019
@mrdoob mrdoob removed this from the rXXX milestone Nov 30, 2019
@danrossi
Copy link

What are the latest updates ? I implemented my own repository with a working updated gamepad controller to include support for Gear. I'm still waiting for details about WebXR to update to that. Mine works as a laser pointer for virtual video controls.

@danrossi
Copy link

danrossi commented Dec 9, 2019

This has been integrated into the VR and XR manager itself. Ive updated a controls project here to handle those controller events and setup a connect and disconnect event.

https://github.com/danrossi/three-vr-controls

@stewdio
Copy link
Contributor Author

stewdio commented Jan 3, 2020

It’s true that things have changed quite a bit over the past ... three years?! (That’s crazy in itself—that it’s been 3 years since I started kicking the tires on this generic VR controller idea in late 2016 / early 2017!)

Looking back, I regret we couldn’t find a way to incorporate these generic VR hand controls in to Three when I offered it here initially. I think it would have benefited the community—and the code itself would have benefited from the community’s constructive input. And that could have driven the official API.

I’ll miss the simplicity and legibility of constructions like this:
controller.addEventListener( 'primary press began', fire )

But mostly I worry we’ve lost little gems like “Multi-channel haptic feedback”:
https://medium.com/@stew_rtsmith/space-rocks-technical-deep-dive-9bf67fb8a467#9a15

Constructions like this made haptics so easy, you’d wonder why anyone was even making a fuss over it in the first place:

controller.setVibe( 'cannon recoil' )
    .set( 0.8 )
    .wait( 20 )
    .set( 0.0 )

controller.setVibe( 'cannon rotation' )
    .set( 0.2 )

Lastly, I feel like I should apologize a bit. I didn’t keep up with VRController much after launching a few projects. I was navigating some personal hurdles that prevented me from giving it enough attention. And I was leaping from job to job chasing the dream of working on web-based virtual reality. (It really amazed me how one could demonstrate through actual launched / delivered projects that WebXR was both feasible and fun and yet time after time I saw support evaporate; groups disbanded. I feel incredibly lucky that I’ve managed to keep getting paychecks for playing with this stuff over the past few years. I don’t take that lightly.)

Anyway, as we roll in to the new decade...
Keep VR weird!

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.

7 participants