Skip to content

Commit 9d0a603

Browse files
authored
Add Reverb G2 Support (#4845)
* Start work on hp reverb g2 controller * Add hp-mixed-reality-controls to necessary locations * Align hp-mixed-reality-controls with actual controller orientation * Remove placeholders
1 parent b164623 commit 9d0a603

File tree

4 files changed

+192
-0
lines changed

4 files changed

+192
-0
lines changed

src/components/hand-controls.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ module.exports.Component = registerComponent('hand-controls', {
211211
el.setAttribute('vive-controls', controlConfiguration);
212212
el.setAttribute('oculus-touch-controls', controlConfiguration);
213213
el.setAttribute('windows-motion-controls', controlConfiguration);
214+
el.setAttribute('hp-mixed-reality-controls', controlConfiguration);
214215
});
215216
}
216217
},
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
var bind = require('../utils/bind');
2+
var registerComponent = require('../core/component').registerComponent;
3+
var THREE = require('../lib/three');
4+
5+
var trackedControlsUtils = require('../utils/tracked-controls');
6+
var checkControllerPresentAndSetup = trackedControlsUtils.checkControllerPresentAndSetup;
7+
var emitIfAxesChanged = trackedControlsUtils.emitIfAxesChanged;
8+
var onButtonEvent = trackedControlsUtils.onButtonEvent;
9+
10+
// See Profiles Registry:
11+
// https://github.com/immersive-web/webxr-input-profiles/tree/master/packages/registry
12+
// TODO: Add a more robust system for deriving gamepad name.
13+
var GAMEPAD_ID = 'hp-mixed-reality';
14+
15+
var HP_MIXEDL_REALITY_MODEL_GLB_BASE_URL = 'https://cdn.aframe.io/controllers/hp/mixed-reality/';
16+
17+
var HP_MIXED_REALITY_POSITION_OFFSET = {x: 0, y: 0, z: 0.06};
18+
var HP_MIXED_REALITY_ROTATION_OFFSET = {_x: Math.PI / 4, _y: 0, _z: 0, _order: 'XYZ'};
19+
20+
/**
21+
* Button IDs:
22+
* 0 - trigger
23+
* 1 - grip
24+
* 3 - X / A
25+
* 4 - Y / B
26+
*
27+
* Axis:
28+
* 2 - joystick x axis
29+
* 3 - joystick y axis
30+
*/
31+
var INPUT_MAPPING_WEBXR = {
32+
left: {
33+
axes: {touchpad: [2, 3]},
34+
buttons: ['trigger', 'grip', 'none', 'thumbstick', 'xbutton', 'ybutton']
35+
},
36+
right: {
37+
axes: {touchpad: [2, 3]},
38+
buttons: ['trigger', 'grip', 'none', 'thumbstick', 'abutton', 'bbutton']
39+
}
40+
};
41+
42+
/**
43+
* HP Mixed Reality Controls
44+
*/
45+
module.exports.Component = registerComponent('hp-mixed-reality-controls', {
46+
schema: {
47+
hand: {default: 'none'},
48+
model: {default: true},
49+
orientationOffset: {type: 'vec3'}
50+
},
51+
52+
mapping: INPUT_MAPPING_WEBXR,
53+
54+
init: function () {
55+
var self = this;
56+
this.controllerPresent = false;
57+
this.lastControllerCheck = 0;
58+
this.onButtonChanged = bind(this.onButtonChanged, this);
59+
this.onButtonDown = function (evt) { onButtonEvent(evt.detail.id, 'down', self, self.data.hand); };
60+
this.onButtonUp = function (evt) { onButtonEvent(evt.detail.id, 'up', self, self.data.hand); };
61+
this.onButtonTouchEnd = function (evt) { onButtonEvent(evt.detail.id, 'touchend', self, self.data.hand); };
62+
this.onButtonTouchStart = function (evt) { onButtonEvent(evt.detail.id, 'touchstart', self, self.data.hand); };
63+
this.previousButtonValues = {};
64+
this.rendererSystem = this.el.sceneEl.systems.renderer;
65+
66+
this.bindMethods();
67+
},
68+
69+
update: function () {
70+
var data = this.data;
71+
this.controllerIndex = data.hand === 'right' ? 0 : data.hand === 'left' ? 1 : 2;
72+
},
73+
74+
play: function () {
75+
this.checkIfControllerPresent();
76+
this.addControllersUpdateListener();
77+
},
78+
79+
pause: function () {
80+
this.removeEventListeners();
81+
this.removeControllersUpdateListener();
82+
},
83+
84+
bindMethods: function () {
85+
this.onModelLoaded = bind(this.onModelLoaded, this);
86+
this.onControllersUpdate = bind(this.onControllersUpdate, this);
87+
this.checkIfControllerPresent = bind(this.checkIfControllerPresent, this);
88+
this.removeControllersUpdateListener = bind(this.removeControllersUpdateListener, this);
89+
this.onAxisMoved = bind(this.onAxisMoved, this);
90+
},
91+
92+
addEventListeners: function () {
93+
var el = this.el;
94+
el.addEventListener('buttonchanged', this.onButtonChanged);
95+
el.addEventListener('buttondown', this.onButtonDown);
96+
el.addEventListener('buttonup', this.onButtonUp);
97+
el.addEventListener('touchstart', this.onButtonTouchStart);
98+
el.addEventListener('touchend', this.onButtonTouchEnd);
99+
el.addEventListener('axismove', this.onAxisMoved);
100+
el.addEventListener('model-loaded', this.onModelLoaded);
101+
this.controllerEventsActive = true;
102+
},
103+
104+
removeEventListeners: function () {
105+
var el = this.el;
106+
el.removeEventListener('buttonchanged', this.onButtonChanged);
107+
el.removeEventListener('buttondown', this.onButtonDown);
108+
el.removeEventListener('buttonup', this.onButtonUp);
109+
el.removeEventListener('touchstart', this.onButtonTouchStart);
110+
el.removeEventListener('touchend', this.onButtonTouchEnd);
111+
el.removeEventListener('axismove', this.onAxisMoved);
112+
el.removeEventListener('model-loaded', this.onModelLoaded);
113+
this.controllerEventsActive = false;
114+
},
115+
116+
checkIfControllerPresent: function () {
117+
var data = this.data;
118+
checkControllerPresentAndSetup(this, GAMEPAD_ID,
119+
{index: this.controllerIndex, hand: data.hand});
120+
},
121+
122+
injectTrackedControls: function () {
123+
var el = this.el;
124+
var data = this.data;
125+
126+
el.setAttribute('tracked-controls', {
127+
// TODO: verify expected behavior between reserved prefixes.
128+
idPrefix: GAMEPAD_ID,
129+
hand: data.hand,
130+
controller: this.controllerIndex,
131+
orientationOffset: data.orientationOffset
132+
});
133+
134+
// Load model.
135+
if (!this.data.model) { return; }
136+
this.el.setAttribute('gltf-model', HP_MIXEDL_REALITY_MODEL_GLB_BASE_URL + this.data.hand + '.glb');
137+
},
138+
139+
addControllersUpdateListener: function () {
140+
this.el.sceneEl.addEventListener('controllersupdated', this.onControllersUpdate, false);
141+
},
142+
143+
removeControllersUpdateListener: function () {
144+
this.el.sceneEl.removeEventListener('controllersupdated', this.onControllersUpdate, false);
145+
},
146+
147+
onControllersUpdate: function () {
148+
// Note that due to gamepadconnected event propagation issues, we don't rely on events.
149+
this.checkIfControllerPresent();
150+
},
151+
152+
onButtonChanged: function (evt) {
153+
var button = this.mapping[this.data.hand].buttons[evt.detail.id];
154+
var analogValue;
155+
156+
if (!button) { return; }
157+
if (button === 'trigger') {
158+
analogValue = evt.detail.state.value;
159+
console.log('analog value of trigger press: ' + analogValue);
160+
}
161+
162+
// Pass along changed event with button state, using button mapping for convenience.
163+
this.el.emit(button + 'changed', evt.detail.state);
164+
},
165+
166+
onModelLoaded: function (evt) {
167+
var controllerObject3D = evt.detail.model;
168+
169+
if (!this.data.model) { return; }
170+
171+
controllerObject3D.position.copy(HP_MIXED_REALITY_POSITION_OFFSET);
172+
controllerObject3D.rotation.copy(HP_MIXED_REALITY_ROTATION_OFFSET);
173+
174+
this.el.emit('controllermodelready', {
175+
name: 'hp-mixed-reality-controls',
176+
model: this.data.model,
177+
rayOrigin: new THREE.Vector3(0, 0, 0)
178+
});
179+
},
180+
181+
onAxisMoved: function (evt) {
182+
emitIfAxesChanged(this, this.mapping.axes, evt);
183+
}
184+
});

src/components/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require('./generic-tracked-controller-controls');
88
require('./gltf-model');
99
require('./hand-tracking-controls');
1010
require('./hand-controls');
11+
require('./hp-mixed-reality-controls');
1112
require('./layer');
1213
require('./laser-controls');
1314
require('./light');

src/components/laser-controls.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ registerComponent('laser-controls', {
1818
// Set all controller models.
1919
el.setAttribute('daydream-controls', controlsConfiguration);
2020
el.setAttribute('gearvr-controls', controlsConfiguration);
21+
el.setAttribute('hp-mixed-reality-controls', controlsConfiguration);
2122
el.setAttribute('magicleap-controls', controlsConfiguration);
2223
el.setAttribute('oculus-go-controls', controlsConfiguration);
2324
el.setAttribute('oculus-touch-controls', controlsConfiguration);
@@ -86,6 +87,11 @@ registerComponent('laser-controls', {
8687
cursor: {downEvents: ['triggerdown'], upEvents: ['triggerup']}
8788
},
8889

90+
'hp-mixed-reality-controls': {
91+
cursor: {downEvents: ['triggerdown'], upEvents: ['triggerup']},
92+
raycaster: {origin: {x: 0, y: 0, z: 0}}
93+
},
94+
8995
'magicleap-controls': {
9096
cursor: {downEvents: ['trackpaddown', 'triggerdown'], upEvents: ['trackpadup', 'triggerup']}
9197
},

0 commit comments

Comments
 (0)