Skip to content

Commit 96a35d9

Browse files
committed
Better inputSources support
1 parent afa2da0 commit 96a35d9

File tree

11 files changed

+656
-302
lines changed

11 files changed

+656
-302
lines changed

Assets/WebGLTemplates/WebXR/webxr.js

Lines changed: 167 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,33 @@
88
this.rightViewMatrix = mat4.create();
99
this.sitStandMatrix = mat4.create();
1010
this.gamepads = [];
11+
this.controllerA = new XRControllerData();
12+
this.controllerB = new XRControllerData();
1113
this.xrData = null;
1214
}
15+
16+
function XRControllerData() {
17+
// TODO: set enabled 0 if controller was enable and then disable
18+
this.enabled = 0;
19+
this.hand = 0;
20+
this.positionX = 0;
21+
this.positionY = 0;
22+
this.positionZ = 0;
23+
this.rotationX = 0;
24+
this.rotationY = 0;
25+
this.rotationZ = 0;
26+
this.rotationW = 0;
27+
this.trigger = 0;
28+
this.squeeze = 0;
29+
this.thumbstick = 0;
30+
this.thumbstickX = 0;
31+
this.thumbstickY = 0;
32+
this.touchpad = 0;
33+
this.touchpadX = 0;
34+
this.touchpadY = 0;
35+
this.buttonA = 0;
36+
this.buttonB = 0;
37+
}
1338

1439
function XRManager() {
1540
this.arSession = null;
@@ -24,6 +49,7 @@
2449
this.isARSupported = false;
2550
this.isVRSupported = false;
2651
this.rAFCB = null;
52+
this.onInputEvent = null;
2753
this.init();
2854
}
2955

@@ -112,13 +138,65 @@
112138
XRManager.prototype.onEndSession = function (xrSessionEvent) {
113139
if (xrSessionEvent.session) {
114140
xrSessionEvent.session.isInSession = false;
141+
xrSessionEvent.session.removeEventListener('select', this.onInputEvent);
142+
xrSessionEvent.session.removeEventListener('selectstart', this.onInputEvent);
143+
xrSessionEvent.session.removeEventListener('selectend', this.onInputEvent);
144+
xrSessionEvent.session.removeEventListener('squeeze', this.onInputEvent);
145+
xrSessionEvent.session.removeEventListener('squeezestart', this.onInputEvent);
146+
xrSessionEvent.session.removeEventListener('squeezeend', this.onInputEvent);
115147
}
116148

117149
this.gameInstance.Module.WebXR.OnEndXR();
118150
this.didNotifyUnity = false;
119151
this.canvas.width = this.canvas.parentElement.clientWidth * window.devicePixelRatio;
120152
this.canvas.height = this.canvas.parentElement.clientHeight * window.devicePixelRatio;
121153
}
154+
155+
XRManager.prototype.onInputSourceEvent = function (xrInputSourceEvent) {
156+
if (xrInputSourceEvent.type && xrInputSourceEvent.inputSource
157+
&& xrInputSourceEvent.inputSource.handedness) {
158+
var hand = 0;
159+
var inputSource = xrInputSourceEvent.inputSource;
160+
var xrData = this.xrData;
161+
var controller = this.xrData.controllerA;
162+
if (inputSource.handedness == 'left') {
163+
hand = 1;
164+
controller = this.xrData.controllerB;
165+
} else if (inputSource.handedness == 'right') {
166+
hand = 2;
167+
}
168+
169+
controller.enabled = 1;
170+
controller.hand = hand;
171+
172+
switch (xrInputSourceEvent.type) {
173+
case "select":
174+
controller.trigger = 1;
175+
break;
176+
case "selectstart":
177+
controller.trigger = 1;
178+
break;
179+
case "selectend":
180+
controller.trigger = 0;
181+
break;
182+
case "squeeze":
183+
controller.squeeze = 1;
184+
break;
185+
case "squeezestart":
186+
controller.squeeze = 1;
187+
break;
188+
case "squeezeend":
189+
controller.squeeze = 0;
190+
break;
191+
}
192+
193+
if (hand == 0 || hand == 2) {
194+
xrData.controllerA = controller;
195+
} else {
196+
xrData.controllerB = controller;
197+
}
198+
}
199+
}
122200

123201
XRManager.prototype.toggleAr = function () {
124202
if (!this.gameInstance)
@@ -209,6 +287,8 @@
209287
document.dispatchEvent(new CustomEvent('onVRSupportedCheck', { detail:{supported:this.isVRSupported} }));
210288

211289
this.UpdateXRCapabilities();
290+
291+
this.onInputEvent = this.onInputSourceEvent.bind(this);
212292

213293
navigator.xr.isSessionSupported('inline').then((supported) => {
214294
if (supported) {
@@ -232,57 +312,90 @@
232312
})
233313
);
234314
}
235-
236-
XRManager.prototype.getGamepadAxes = function(gamepad) {
237-
var axes = [];
238-
for (var i = 0; i < gamepad.axes.length; i++) {
239-
axes.push(gamepad.axes[i]);
240-
}
241-
return axes;
242-
}
243-
244-
XRManager.prototype.getGamepadButtons = function(gamepad) {
245-
var buttons = [];
246-
for (var i = 0; i < gamepad.buttons.length; i++) {
247-
buttons.push({
248-
pressed: gamepad.buttons[i].pressed,
249-
touched: gamepad.buttons[i].touched,
250-
value: gamepad.buttons[i].value
251-
});
252-
}
253-
return buttons;
254-
}
255-
256-
XRManager.prototype.getXRGamepads = function(frame, inputSources, refSpace) {
257-
var vrGamepads = []
315+
316+
XRManager.prototype.getXRControllersData = function(frame, inputSources, refSpace, xrData) {
258317
if (!inputSources || !inputSources.length) {
259-
return vrGamepads;
318+
return;
260319
}
261320
for (var i = 0; i < inputSources.length; i++) {
262321
let inputSource = inputSources[i];
263322
// Show the input source if it has a grip space
264-
if (inputSource.gripSpace && inputSource.gamepad) {
323+
if (inputSource.gripSpace) {
265324
let inputPose = frame.getPose(inputSource.gripSpace, refSpace);
266325

267326
var position = inputPose.transform.position;
268327
var orientation = inputPose.transform.orientation;
269-
270-
vrGamepads.push({
271-
id: inputSource.gamepad.id,
272-
index: inputSource.gamepad.index,
273-
hand: inputSource.handedness,
274-
buttons: this.getGamepadButtons(inputSource.gamepad),
275-
axes: this.getGamepadAxes(inputSource.gamepad),
276-
hasOrientation: true,
277-
hasPosition: true,
278-
orientation: this.GLQuaternionToUnity([orientation.x, orientation.y, orientation.z, orientation.w]),
279-
position: this.GLVec3ToUnity([position.x, position.y, position.z]),
280-
linearAcceleration: [0, 0, 0],
281-
linearVelocity: [0, 0, 0]
282-
});
328+
var hand = 0;
329+
var controller = xrData.controllerA;
330+
if (inputSource.handedness == 'left') {
331+
hand = 1;
332+
controller = xrData.controllerB;
333+
} else if (inputSource.handedness == 'right') {
334+
hand = 2;
335+
}
336+
337+
controller.enabled = 1;
338+
controller.hand = hand;
339+
340+
controller.positionX = position.x;
341+
controller.positionY = position.y;
342+
controller.positionZ = -position.z;
343+
344+
controller.rotationX = -orientation.x;
345+
controller.rotationY = -orientation.y;
346+
controller.rotationZ = orientation.z;
347+
controller.rotationW = orientation.w;
348+
349+
// if there's gamepad, use the xr-standard mapping
350+
// TODO: check for profiles
351+
if (inputSource.gamepad) {
352+
for (var j = 0; j < inputSource.gamepad.buttons.length; j++) {
353+
switch (j) {
354+
case 0:
355+
controller.trigger = inputSource.gamepad.buttons[j].value;
356+
break;
357+
case 1:
358+
controller.squeeze = inputSource.gamepad.buttons[j].value;
359+
break;
360+
case 2:
361+
controller.touchpad = inputSource.gamepad.buttons[j].value;
362+
break;
363+
case 3:
364+
controller.thumbstick = inputSource.gamepad.buttons[j].value;
365+
break;
366+
case 4:
367+
controller.buttonA = inputSource.gamepad.buttons[j].value;
368+
break;
369+
case 5:
370+
controller.buttonB = inputSource.gamepad.buttons[j].value;
371+
break;
372+
}
373+
}
374+
for (var j = 0; j < inputSource.gamepad.axes.length; j++) {
375+
switch (j) {
376+
case 0:
377+
controller.touchpadX = inputSource.gamepad.axes[j].value;
378+
break;
379+
case 1:
380+
controller.touchpadY = inputSource.gamepad.axes[j].value;
381+
break;
382+
case 2:
383+
controller.thumbstickX = inputSource.gamepad.axes[j].value;
384+
break;
385+
case 3:
386+
controller.thumbstickY = inputSource.gamepad.axes[j].value;
387+
break;
388+
}
389+
}
390+
}
391+
392+
if (hand == 0 || hand == 2) {
393+
xrData.controllerA = controller;
394+
} else {
395+
xrData.controllerB = controller;
396+
}
283397
}
284398
}
285-
return vrGamepads;
286399
}
287400

288401
// Convert WebGL to Unity compatible Vector3
@@ -322,6 +435,8 @@
322435
let glLayer = new XRWebGLLayer(session, this.ctx);
323436
session.updateRenderState({ baseLayer: glLayer });
324437

438+
439+
325440
let refSpaceType = 'viewer';
326441
if (session.isImmersive) {
327442
refSpaceType = 'local-floor';
@@ -331,6 +446,13 @@
331446

332447
this.canvas.width = glLayer.framebufferWidth;
333448
this.canvas.height = glLayer.framebufferHeight;
449+
450+
session.addEventListener('select', this.onInputEvent);
451+
session.addEventListener('selectstart', this.onInputEvent);
452+
session.addEventListener('selectend', this.onInputEvent);
453+
session.addEventListener('squeeze', this.onInputEvent);
454+
session.addEventListener('squeezestart', this.onInputEvent);
455+
session.addEventListener('squeezeend', this.onInputEvent);
334456
}
335457

336458
session.requestReferenceSpace(refSpaceType).then((refSpace) => {
@@ -387,16 +509,17 @@
387509
}
388510
}
389511

390-
// Gamepads
391-
xrData.gamepads = this.getXRGamepads(frame, session.inputSources, session.refSpace);
392-
512+
this.getXRControllersData(frame, session.inputSources, session.refSpace, xrData);
513+
393514
// Dispatch event with headset data to be handled in webxr.jslib
394515
document.dispatchEvent(new CustomEvent('XRData', { detail: {
395516
leftProjectionMatrix: xrData.leftProjectionMatrix,
396517
rightProjectionMatrix: xrData.rightProjectionMatrix,
397518
leftViewMatrix: xrData.leftViewMatrix,
398519
rightViewMatrix: xrData.rightViewMatrix,
399-
sitStandMatrix: xrData.sitStandMatrix
520+
sitStandMatrix: xrData.sitStandMatrix,
521+
controllerA: xrData.controllerA,
522+
controllerB: xrData.controllerB
400523
}}));
401524

402525
if (!this.didNotifyUnity)
@@ -409,26 +532,6 @@
409532
}
410533
this.didNotifyUnity = true;
411534
}
412-
413-
this.gameInstance.Module.WebXR.OnWebXRData(
414-
JSON.stringify({
415-
controllers: xrData.gamepads
416-
}));
417-
}
418-
419-
// Show instruction dialogue for non-VR enabled browsers.
420-
XRManager.prototype.displayElement = function (el) {
421-
if (el.dataset.enabled) {
422-
return;
423-
}
424-
var confirmButton = el.querySelector('button');
425-
el.dataset.enabled = true;
426-
427-
function onConfirm () {
428-
el.dataset.enabled = false;
429-
confirmButton.removeEventListener('click', onConfirm);
430-
}
431-
confirmButton.addEventListener('click', onConfirm);
432535
}
433536

434537
function initWebXRManager () {

0 commit comments

Comments
 (0)