-
-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Added support for windows mixed reality controllers #3013
Changes from 6 commits
89e0fa4
638c6a2
35243a5
b391904
a654c50
6043da3
c57dfe9
c5df51e
6c9468f
028ad77
922797a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
--- | ||
title: windows-motion-controls | ||
type: components | ||
layout: docs | ||
parent_section: components | ||
source_code: src/components/windows-motion-controls.js | ||
examples: [] | ||
--- | ||
|
||
[trackedcontrols]: ./tracked-controls.md | ||
|
||
The windows-motion-controls component interfaces with any spatial controllers exposed through | ||
Windows Mixed Reality as Spatial Input Sources (such as Motion Controllers). | ||
It wraps the [tracked-controls component][trackedcontrols] while adding button | ||
mappings, events, and a controller model that highlights applies position/rotation transforms | ||
to the pressed buttons (trigger, grip, menu, thumbstick, trackpad) and moved axes (thumbstick and trackpad.) | ||
|
||
## Example | ||
|
||
```html | ||
<a-entity windows-motion-controls="hand: left"></a-entity> | ||
<a-entity windows-motion-controls="hand: right"></a-entity> | ||
``` | ||
|
||
## Value | ||
|
||
| Property | Description | Default Value | | ||
|----------------------|---------------------------------------------------------------------------------------------------|----------------| | ||
| hand | The hand that will be tracked (i.e., right, left). | right | | ||
| pair | Which pair of controllers, if > 2 are connected. | 0 | | ||
| model | Whether the controller model is loaded. | true | | ||
| hideDisconnected | Disable rendering of controller model when no matching gamepad (based on ID & hand) is connected. | true | | ||
|
||
|
||
## Events | ||
|
||
| Event Name | Description | | ||
| ---------- | ----------- | | ||
| thumbstickdown | Thumbstick button pressed. | | ||
| thumbstickup | Thumbstick button released. | | ||
| thumbstickchanged | Thumbstick button changed. | | ||
| thumbstickmoved | Thumbstick axis moved. | | ||
| triggerdown | Trigger pressed. | | ||
| triggerup | Trigger released. | | ||
| triggerchanged | Trigger changed. | | ||
| gripdown | Grip button pressed. | | ||
| gripup | Grip button released. | | ||
| gripchanged | Grip button changed. | | ||
| menudown | Menu button pressed. | | ||
| menuup | Menu button released. | | ||
| menuchanged | Menu button changed. | | ||
| trackpaddown | Trackpad pressed. | | ||
| trackpadup | Trackpad released. | | ||
| trackpadchanged | Trackpad button changed. | | ||
| trackpadmoved | Trackpad axis moved. | | ||
| controllerdisplayready | The model file is loaded and completed parsing. | | ||
|
||
## Assets | ||
|
||
TBC. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
var registerComponent = require('../core/component').registerComponent; | ||
var THREE = require('../lib/three'); | ||
var utils = require('../utils/'); | ||
var warn = utils.debug('components:windows-motion-controls:warn'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be: var warn = utils.debug('components:gltf-model:warn'); ...since the warning will appear for any glTF model. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch, copy-paste error. Will fix! |
||
|
||
/** | ||
* glTF model loader. | ||
|
@@ -26,6 +28,9 @@ module.exports.Component = registerComponent('gltf-model', { | |
self.model.animations = gltfModel.animations; | ||
el.setObject3D('mesh', self.model); | ||
el.emit('model-loaded', {format: 'gltf', model: self.model}); | ||
}, undefined /* onProgress */, function gltfFailed () { | ||
warn('Failed to glTF-model: ' + src); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The gltfFailed callback will receive an argument, var message = error ? error.message : 'Failed to load glTF model';
warn(message);
el.emit('model-error', {format: 'gltf', message: message}); |
||
el.emit('model-error', {format: 'gltf', src: src}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we throw an error instead of an event? A similar scenario can be found in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could do both? I listen to the error message to try loading a different (fallback) asset file, I think it could be useful in other contexts for the caller to know that the file load failed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, we could have both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 for both. The errors should be helpful for developers debugging, who may not know to listen for the event. But my inclination would be to log an error or warning, through the debug util, rather than throwing something that can't be caught. See There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool! Let's add both then 👌 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do both, thanks! |
||
}); | ||
}, | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,21 +16,33 @@ registerComponent('laser-controls', { | |
el.setAttribute('gearvr-controls', {hand: data.hand}); | ||
el.setAttribute('oculus-touch-controls', {hand: data.hand}); | ||
el.setAttribute('vive-controls', {hand: data.hand}); | ||
el.setAttribute('windows-motion-controls', {hand: data.hand}); | ||
|
||
// Wait for controller to connect before | ||
el.addEventListener('controllerconnected', function (evt) { | ||
// Wait for controller to connect, or have a valid pointing pose, before creating ray | ||
el.addEventListener('controllerconnected', function (evt) { createRay(evt); }); | ||
el.addEventListener('controllerdisplayready', createRay); | ||
|
||
function createRay (evt) { | ||
var controllerConfig = config[evt.detail.name]; | ||
|
||
if (!controllerConfig) { return; } | ||
|
||
el.setAttribute('raycaster', utils.extend({ | ||
var raycasterConfig = utils.extend({ | ||
showLine: true | ||
}, controllerConfig.raycaster || {})); | ||
}, controllerConfig.raycaster || {}); | ||
|
||
if (evt.detail.name === 'windows-motion-controls') { | ||
var motionControls = el.components['windows-motion-controls']; | ||
raycasterConfig = utils.extend(raycasterConfig, motionControls.rayOrigin); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we pass the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the pattern of passing the ray details in the event, will modify to follow that pattern. Happy to also modify the others, just let me know if you would prefer that in a separate PR once this is completed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! We can do it in a separate PR so we move things along. |
||
raycasterConfig.showLine = motionControls.rayOriginInitialized; | ||
} | ||
|
||
el.setAttribute('raycaster', raycasterConfig); | ||
|
||
el.setAttribute('cursor', utils.extend({ | ||
fuse: false | ||
}, controllerConfig.cursor)); | ||
}); | ||
} | ||
}, | ||
|
||
config: { | ||
|
@@ -50,6 +62,11 @@ registerComponent('laser-controls', { | |
|
||
'vive-controls': { | ||
cursor: {downEvents: ['triggerdown'], upEvents: ['triggerup']} | ||
}, | ||
|
||
'windows-motion-controls': { | ||
cursor: {downEvents: ['triggerdown'], upEvents: ['triggerup']}, | ||
raycaster: {showLine: false} | ||
} | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe
controllermodelready
is a better name?