diff --git a/src/components/vive-controls.js b/src/components/vive-controls.js index 8fccc5f0301..e3f1842a629 100644 --- a/src/components/vive-controls.js +++ b/src/components/vive-controls.js @@ -14,7 +14,7 @@ var isWebXRAvailable = require('../utils/').device.isWebXRAvailable; var GAMEPAD_ID_WEBXR = 'htc-vive'; var GAMEPAD_ID_WEBVR = 'OpenVR '; -// Prefix for Gen1 and Gen2 Oculus Touch Controllers. +// Prefix for HTC Vive Controllers. var GAMEPAD_ID_PREFIX = isWebXRAvailable ? GAMEPAD_ID_WEBXR : GAMEPAD_ID_WEBVR; /** @@ -44,8 +44,8 @@ var INPUT_MAPPING_WEBVR = { * Reference: https://github.com/immersive-web/webxr-input-profiles/blob/master/packages/registry/profiles/htc/htc-vive.json */ var INPUT_MAPPING_WEBXR = { - axes: {thumbstick: [0, 1]}, - buttons: ['trigger', 'grip', 'trackpad', 'none', 'menu'] + axes: {touchpad: [0, 1]}, + buttons: ['trigger', 'grip', 'touchpad', 'none'] }; var INPUT_MAPPING = isWebXRAvailable ? INPUT_MAPPING_WEBXR : INPUT_MAPPING_WEBVR; @@ -53,7 +53,7 @@ var INPUT_MAPPING = isWebXRAvailable ? INPUT_MAPPING_WEBXR : INPUT_MAPPING_WEBVR /** * Vive controls. * Interface with Vive controllers and map Gamepad events to controller buttons: - * trackpad, trigger, grip, menu, system + * touchpad, trigger, grip, menu, system * Load a controller model and highlight the pressed buttons. */ module.exports.Component = registerComponent('vive-controls', { @@ -209,6 +209,7 @@ module.exports.Component = registerComponent('vive-controls', { buttonMeshes.menu = controllerObject3D.getObjectByName('menubutton'); buttonMeshes.system = controllerObject3D.getObjectByName('systembutton'); buttonMeshes.trackpad = controllerObject3D.getObjectByName('touchpad'); + buttonMeshes.touchpad = controllerObject3D.getObjectByName('touchpad'); buttonMeshes.trigger = controllerObject3D.getObjectByName('trigger'); // Set default colors. diff --git a/src/components/vive-focus-controls.js b/src/components/vive-focus-controls.js index a9ac1031d6e..ec574de9070 100644 --- a/src/components/vive-focus-controls.js +++ b/src/components/vive-focus-controls.js @@ -5,11 +5,40 @@ var checkControllerPresentAndSetup = trackedControlsUtils.checkControllerPresent var emitIfAxesChanged = trackedControlsUtils.emitIfAxesChanged; var onButtonEvent = trackedControlsUtils.onButtonEvent; -var GAMEPAD_ID_PREFIX = 'HTC Vive Focus'; - var AFRAME_CDN_ROOT = require('../constants').AFRAME_CDN_ROOT; var VIVE_FOCUS_CONTROLLER_MODEL_URL = AFRAME_CDN_ROOT + 'controllers/vive/focus-controller/focus-controller.gltf'; +var isWebXRAvailable = require('../utils/').device.isWebXRAvailable; + +var GAMEPAD_ID_WEBXR = 'htc-vive-focus'; +var GAMEPAD_ID_WEBVR = 'HTC Vive Focus '; + +// Prefix for HTC Vive Focus Controllers. +var GAMEPAD_ID_PREFIX = isWebXRAvailable ? GAMEPAD_ID_WEBXR : GAMEPAD_ID_WEBVR; + +/** + * Button IDs: + * 0 - trackpad + * 1 - trigger + */ +var INPUT_MAPPING_WEBVR = { + axes: {trackpad: [0, 1]}, + buttons: ['trackpad', 'trigger'] +}; + +/** + * Button IDs: + * 0 - trigger + * 2 - touchpad + * 4 - menu + */ +var INPUT_MAPPING_WEBXR = { + axes: {touchpad: [0, 1]}, + buttons: ['trigger', 'none', 'touchpad', 'none', 'menu'] +}; + +var INPUT_MAPPING = isWebXRAvailable ? INPUT_MAPPING_WEBXR : INPUT_MAPPING_WEBVR; + /** * Vive Focus controls. * Interface with Vive Focus controller and map Gamepad events to @@ -26,15 +55,7 @@ module.exports.Component = registerComponent('vive-focus-controls', { armModel: {default: true} }, - /** - * Button IDs: - * 0 - trackpad - * 1 - trigger - */ - mapping: { - axes: {trackpad: [0, 1]}, - buttons: ['trackpad', 'trigger'] - }, + mapping: INPUT_MAPPING, bindMethods: function () { this.onModelLoaded = this.onModelLoaded.bind(this); diff --git a/src/utils/device.js b/src/utils/device.js index a7c9c8ae428..0e134a2947d 100644 --- a/src/utils/device.js +++ b/src/utils/device.js @@ -8,7 +8,7 @@ var supportsARSession = false; * Oculus Browser 7 doesn't support the WebXR gamepads module. * We fallback to WebVR API and will hotfix when implementation is complete. */ -var isWebXRAvailable = module.exports.isWebXRAvailable = !window.debug && navigator.xr !== undefined; +var isWebXRAvailable = module.exports.isWebXRAvailable = navigator.xr !== undefined; // Catch vrdisplayactivate early to ensure we can enter VR mode after the scene loads. window.addEventListener('vrdisplayactivate', function (evt) { diff --git a/tests/__init.test.js b/tests/__init.test.js index c187b787efb..8cd133cd3ae 100644 --- a/tests/__init.test.js +++ b/tests/__init.test.js @@ -1,10 +1,11 @@ -/* global sinon, setup, teardown */ +/* global EventTarget, sinon, setup, teardown */ /** * __init.test.js is run before every test case. */ window.debug = true; +/* WebVR Stub */ navigator.getVRDisplays = function () { var resolvePromise = Promise.resolve(); var mockVRDisplay = { @@ -19,6 +20,16 @@ navigator.getVRDisplays = function () { return Promise.resolve([mockVRDisplay]); }; +/* WebXR Stub */ +navigator.xr = navigator.xr || {}; +navigator.xr.isSessionSupported = function (_sessionType) { return Promise.resolve(true); }; +navigator.xr.requestSession = function (_mode) { + const xrSession = new EventTarget(); + xrSession.supportedFrameRates = [90]; + xrSession.requestReferenceSpace = function () { return Promise.resolve(); }; + return Promise.resolve(xrSession); +}; + const AFRAME = require('index'); var AScene = require('core/scene/a-scene').AScene; // Make sure WebGL context is not created since CI runs headless. @@ -28,7 +39,7 @@ AScene.prototype.setupRenderer = function () {}; setup(function () { window.AFRAME = AFRAME; this.sinon = sinon.createSandbox(); - // Stubs to not create a WebGL context since Travis CI runs headless. + // Stubs to not create a WebGL context since CI runs headless. this.sinon.stub(AScene.prototype, 'render'); this.sinon.stub(AScene.prototype, 'setupRenderer'); // Mock renderer. diff --git a/tests/components/oculus-go-controls.test.js b/tests/components/oculus-go-controls.test.js index 897e87c540f..d5c1a9d09a4 100644 --- a/tests/components/oculus-go-controls.test.js +++ b/tests/components/oculus-go-controls.test.js @@ -11,17 +11,9 @@ suite('oculus-go-controls', function () { component.controllers = []; // Our Mock data for enabling the controllers. component.controllersWhenPresent = [{ - id: 'Oculus Go Controller', - index: 0, - hand: 'right', - axes: [0, 0], - buttons: [ - {value: 0, pressed: false, touched: false}, - {value: 0, pressed: false, touched: false} - ], - pose: {orientation: [1, 0, 0, 0], position: null} + profiles: ['oculus-go'], + handedness: 'right' }]; - el.parentEl.renderer.xr.getStandingMatrix = function () {}; done(); }; if (el.hasLoaded) { callback(); } @@ -37,7 +29,7 @@ suite('oculus-go-controls', function () { setup(function (done) { component = this.el.components['oculus-go-controls']; - controllerSystem = this.el.sceneEl.systems['tracked-controls-webvr']; + controllerSystem = this.el.sceneEl.systems['tracked-controls-webxr']; addEventListenersSpy = sinon.spy(component, 'addEventListeners'); injectTrackedControlsSpy = sinon.spy(component, 'injectTrackedControls'); removeEventListenersSpy = sinon.spy(component, 'removeEventListeners'); @@ -117,14 +109,14 @@ suite('oculus-go-controls', function () { }); suite('axismove', function () { - test('emits trackpadmoved on axismove', function (done) { + test('emits touchpadmoved on axismove', function (done) { var el = this.el; setupTestControllers(el); // Configure the event state for which we'll use the axis state for verification. const eventState = {axis: [0.1, 0.2], changed: [true, false]}; - el.addEventListener('trackpadmoved', function (evt) { + el.addEventListener('touchpadmoved', function (evt) { assert.equal(evt.detail.x, eventState.axis[0]); assert.equal(evt.detail.y, eventState.axis[1]); done(); @@ -133,13 +125,13 @@ suite('oculus-go-controls', function () { el.emit('axismove', eventState); }); - test('does not emit trackpadmoved on axismove with no changes', function (done) { + test('does not emit touchpadmoved on axismove with no changes', function (done) { var el = this.el; setupTestControllers(el); // Fail purposely. - el.addEventListener('trackpadmoved', function (evt) { - assert.fail('trackpadmoved was called when there was no change.'); + el.addEventListener('touchpadmoved', function (evt) { + assert.fail('touchpadmoved was called when there was no change.'); }); el.emit('axismove', {axis: [0.1, 0.2], changed: [false, false]}); @@ -148,8 +140,8 @@ suite('oculus-go-controls', function () { }); suite('buttonchanged', function () { - [{ button: 'trackpad', id: 0 }, - { button: 'trigger', id: 1 } + [{ button: 'trigger', id: 0 }, + { button: 'touchpad', id: 2 } ].forEach(function (buttonDescription) { test('if we get buttonchanged for button ' + buttonDescription.id + ', emit ' + buttonDescription.button + 'changed', function (done) { var el = this.el; @@ -190,61 +182,6 @@ suite('oculus-go-controls', function () { }); }); - suite('armModel', function () { - test('does not apply armModel if armModel disabled', function () { - var el = this.el; - el.setAttribute('oculus-go-controls', 'armModel', false); - setupTestControllers(el); - - var trackedControls = el.components['tracked-controls-webvr']; - var applyArmModelSpy = sinon.spy(trackedControls, 'applyArmModel'); - trackedControls.tick(); - - // Verify that the function which applies arm model is not called when disabled. - sinon.assert.notCalled(applyArmModelSpy); - - // Additionally verify that no other offsets have been applied. - assert.strictEqual(el.object3D.position.x, 0); - assert.strictEqual(el.object3D.position.y, 0); - assert.strictEqual(el.object3D.position.z, 0); - }); - - test('applies armModel if armModel enabled', function () { - var el = this.el; - el.setAttribute('oculus-go-controls', 'armModel', true); - setupTestControllers(el); - - var trackedControls = el.components['tracked-controls-webvr']; - var applyArmModelSpy = sinon.spy(trackedControls, 'applyArmModel'); - trackedControls.tick(); - - // Verify that the function which applies arm model is called. - sinon.assert.calledOnce(applyArmModelSpy); - }); - - test('verifies armModel position is applied for the right hand', function () { - var el = this.el; - el.setAttribute('oculus-go-controls', 'armModel', true); - setupTestControllers(el); - - var trackedControls = el.components['tracked-controls-webvr']; - trackedControls.tick(); - assert.ok(el.object3D.position.x > 0); - }); - - test('verifies armModel position is applied for the left hand', function () { - var el = this.el; - el.setAttribute('oculus-go-controls', 'armModel', true); - el.setAttribute('oculus-go-controls', 'hand', 'left'); - el.components['oculus-go-controls'].controllersWhenPresent[0].hand = 'left'; - setupTestControllers(el); - - var trackedControls = el.components['tracked-controls-webvr']; - trackedControls.tick(); - assert.ok(el.object3D.position.x < 0); - }); - }); - /** * Establishes the baseline set of controllers needed for the tests to run. * @@ -252,7 +189,7 @@ suite('oculus-go-controls', function () { */ function setupTestControllers (el) { var component = el.components['oculus-go-controls']; - el.sceneEl.systems['tracked-controls-webvr'].controllers = component.controllersWhenPresent; + el.sceneEl.systems['tracked-controls-webxr'].controllers = component.controllersWhenPresent; component.checkIfControllerPresent(); } }); diff --git a/tests/components/oculus-touch-controls.test.js b/tests/components/oculus-touch-controls.test.js index 7f98b8dac5f..df0a9ad955f 100644 --- a/tests/components/oculus-touch-controls.test.js +++ b/tests/components/oculus-touch-controls.test.js @@ -14,10 +14,8 @@ suite('oculus-touch-controls', function () { component.controllers = []; // Our Mock data for enabling the controllers. component.controllersWhenPresent = [{ - id: 'Oculus Touch', - index: 0, - hand: 'left', - pose: {} + profiles: ['oculus-touch'], + handedness: 'left' }]; done(); }; @@ -34,7 +32,7 @@ suite('oculus-touch-controls', function () { setup(function (done) { component = this.el.components['oculus-touch-controls']; - controllerSystem = this.el.sceneEl.systems['tracked-controls-webvr']; + controllerSystem = this.el.sceneEl.systems['tracked-controls-webxr']; controllerSystem.vrDisplay = true; addEventListenersSpy = sinon.spy(component, 'addEventListeners'); injectTrackedControlsSpy = sinon.spy(component, 'injectTrackedControls'); @@ -118,7 +116,7 @@ suite('oculus-touch-controls', function () { var controllerSystem; setup(function (done) { - controllerSystem = this.el.sceneEl.systems['tracked-controls-webvr']; + controllerSystem = this.el.sceneEl.systems['tracked-controls-webxr']; controllerSystem.controllers = component.controllersWhenPresent; controllerSystem.vrDisplay = true; done(); @@ -128,11 +126,11 @@ suite('oculus-touch-controls', function () { // Do the check. component.checkIfControllerPresent(); // Set up the event details. - const eventDetails = {axis: [0.1, 0.2], changed: [true, false]}; + const eventDetails = {axis: [0.1, 0.2, 0.3, 0.4], changed: [false, false, true, false]}; // Install event handler listening for thumbstickmoved. this.el.addEventListener('thumbstickmoved', function (evt) { - assert.equal(evt.detail.x, eventDetails.axis[0]); - assert.equal(evt.detail.y, eventDetails.axis[1]); + assert.equal(evt.detail.x, eventDetails.axis[2]); + assert.equal(evt.detail.y, eventDetails.axis[3]); done(); }); // Emit axismove. @@ -147,15 +145,14 @@ suite('oculus-touch-controls', function () { assert.fail('thumbstickmoved should not be called'); }); // Emit axismove with no changes. - this.el.emit('axismove', {axis: [0.1, 0.2], changed: [false, false]}); + this.el.emit('axismove', {axis: [0.1, 0.2, 0.3, 0.4], changed: [false, false, false, false]}); setTimeout(() => { done(); }); }); }); suite('buttonchanged', function () { test('can emit triggerchanged', function (done) { - el.sceneEl.systems['tracked-controls-webvr'].controllers = component.controllersWhenPresent; - el.sceneEl.systems['tracked-controls-webvr'].vrDisplay = true; + el.sceneEl.systems['tracked-controls-webxr'].controllers = component.controllersWhenPresent; // Do the check. component.checkIfControllerPresent(); // Prepare the event details @@ -166,7 +163,7 @@ suite('oculus-touch-controls', function () { done(); }); // Emit buttonchanged. - el.emit('buttonchanged', {id: 1, state: eventState}); + el.emit('buttonchanged', {id: 0, state: eventState}); }); }); }); diff --git a/tests/components/scene/xr-mode-ui.test.js b/tests/components/scene/xr-mode-ui.test.js index 938f24d6fec..caf05b3232c 100644 --- a/tests/components/scene/xr-mode-ui.test.js +++ b/tests/components/scene/xr-mode-ui.test.js @@ -1,6 +1,5 @@ /* global assert, process, setup, suite, test */ var entityFactory = require('../../helpers').entityFactory; -var utils = require('index').utils; var UI_CLASSES = ['.a-orientation-modal', '.a-enter-vr-button']; @@ -8,11 +7,6 @@ suite('xr-mode-ui', function () { setup(function (done) { this.entityEl = entityFactory(); var el = this.el = this.entityEl.parentNode; - this.sinon.stub(utils.device, 'getVRDisplay').returns({ - requestPresent: function () { - return Promise.resolve(); - } - }); el.addEventListener('loaded', function () { done(); }); }); @@ -38,7 +32,6 @@ suite('xr-mode-ui', function () { el: {object3D: {}}, updateProjectionMatrix: function () {} }; - window.hasNativeWebVRImplementation = false; scene.enterVR(); UI_CLASSES.forEach(function (uiClass) { assert.ok(scene.querySelector(uiClass).className.indexOf('a-hidden')); @@ -52,7 +45,6 @@ suite('xr-mode-ui', function () { el: {object3D: {}, getAttribute: function () { return {spectator: false}; }}, updateProjectionMatrix: function () {} }; - window.hasNativeWebVRImplementation = false; scene.enterVR(); scene.exitVR(); diff --git a/tests/components/tracked-controls-webvr.test.js b/tests/components/tracked-controls-webvr.test.js index b82eb4429cf..a78ef8e0c51 100644 --- a/tests/components/tracked-controls-webvr.test.js +++ b/tests/components/tracked-controls-webvr.test.js @@ -13,6 +13,7 @@ suite('tracked-controls-webvr', function () { setup(function (done) { standingMatrix.identity(); el = entityFactory(); + el.sceneEl.hasWebXR = false; setTimeout(() => { el.setAttribute('position', ''); el.setAttribute('tracked-controls', ''); diff --git a/tests/components/vive-controls.test.js b/tests/components/vive-controls.test.js index 39955c93575..c7d80abae42 100644 --- a/tests/components/vive-controls.test.js +++ b/tests/components/vive-controls.test.js @@ -12,9 +12,9 @@ suite('vive-controls', function () { if (evt.detail.name !== 'vive-controls') { return; } component = el.components['vive-controls']; component.controllersWhenPresent = [ - {id: 'OpenVR Gamepad', index: 0, hand: 'right', pose: {}} + {profiles: ['htc-vive'], handedness: 'right'} ]; - controlsSystem = el.sceneEl.systems['tracked-controls-webvr']; + controlsSystem = el.sceneEl.systems['tracked-controls-webxr']; done(); }); el.setAttribute('vive-controls', 'hand: right; model: true'); // To ensure index = 0. @@ -108,13 +108,13 @@ suite('vive-controls', function () { }); suite('axismove', function () { - test('emits trackpadmoved on axismove', function (done) { + test('emits touchpadmoved on axismove', function (done) { controlsSystem.controllers = component.controllersWhenPresent; component.checkIfControllerPresent(); - // Install event handler listening for trackpad. - el.addEventListener('trackpadmoved', function (evt) { + // Install event handler listening for touchpad. + el.addEventListener('touchpadmoved', function (evt) { assert.equal(evt.detail.x, 0.1); assert.equal(evt.detail.y, 0.2); assert.ok(evt.detail); @@ -125,12 +125,12 @@ suite('vive-controls', function () { el.emit('axismove', {axis: [0.1, 0.2], changed: [true, false]}); }); - test('does not emit trackpadmoved on axismove with no changes', function (done) { + test('does not emit touchpadmoved on axismove with no changes', function (done) { controlsSystem.controllers = component.controllersWhenPresent; component.checkIfControllerPresent(); - // Install event handler listening for trackpadmoved. - el.addEventListener('trackpadmoved', function (evt) { + // Install event handler listening for touchpadmoved. + el.addEventListener('touchpadmoved', function (evt) { assert.notOk(evt.detail); }); @@ -143,11 +143,9 @@ suite('vive-controls', function () { suite('buttonchanged', function () { // Generate 3 tests for each button. Verify that it fires up/down/changed for all remapped buttons. - [{ button: 'trackpad', id: 0 }, - { button: 'trigger', id: 1 }, - { button: 'grip', id: 2 }, - { button: 'menu', id: 3 }, - { button: 'system', id: 4 } + [{ button: 'trigger', id: 0 }, + { button: 'grip', id: 1 }, + { button: 'touchpad', id: 2 } ].forEach(function (buttonDescription) { test('emits ' + buttonDescription.button + 'changed on buttonchanged', function (done) { controlsSystem.controllers = component.controllersWhenPresent; @@ -205,10 +203,10 @@ suite('vive-controls', function () { component.injectTrackedControls(); }); - test('has trackpad at default color', function (done) { + test('has touchpad at default color', function (done) { component.addEventListeners(); el.addEventListener('model-loaded', function (evt) { - var color = component.buttonMeshes.trackpad.material.color; + var color = component.buttonMeshes.touchpad.material.color; assert.equal(new THREE.Color(color).getHexString(), 'fafafa'); done(); }); @@ -232,7 +230,7 @@ suite('vive-controls', function () { test('sets trigger to highlight color when down', function (done) { component.addEventListeners(); el.addEventListener('model-loaded', function (evt) { - el.emit('buttondown', {id: 1, state: {}}); + el.emit('buttondown', {id: 0, state: {}}); setTimeout(() => { var color = component.buttonMeshes.trigger.material.color; assert.equal(new THREE.Color(color).getHexString(), '22d1ee'); @@ -247,7 +245,7 @@ suite('vive-controls', function () { component.addEventListeners(); el.addEventListener('model-loaded', function (evt) { component.buttonMeshes.trigger.material.color.set('#22d1ee'); - el.emit('buttonup', {id: 1, state: {}}); + el.emit('buttonup', {id: 0, state: {}}); setTimeout(() => { var color = component.buttonMeshes.trigger.material.color; assert.equal(new THREE.Color(color).getHexString(), 'fafafa'); @@ -258,12 +256,12 @@ suite('vive-controls', function () { component.injectTrackedControls(); }); - test('sets trackpad to highlight color when down', function (done) { + test('sets touchpad to highlight color when down', function (done) { component.addEventListeners(); el.addEventListener('model-loaded', function (evt) { - el.emit('buttondown', {id: 0, state: {}}); + el.emit('buttondown', {id: 2, state: {}}); setTimeout(() => { - var color = component.buttonMeshes.trackpad.material.color; + var color = component.buttonMeshes.touchpad.material.color; assert.equal(new THREE.Color(color).getHexString(), '22d1ee'); done(); }); @@ -286,12 +284,12 @@ suite('vive-controls', function () { component.injectTrackedControls(); }); - test('does not change color for trackpad touch', function (done) { + test('does not change color for touchpad touch', function (done) { component.addEventListeners(); el.addEventListener('model-loaded', function (evt) { - el.emit('touchstart', {id: 0, state: {}}); + el.emit('touchstart', {id: 2, state: {}}); setTimeout(() => { - var color = component.buttonMeshes.trackpad.material.color; + var color = component.buttonMeshes.touchpad.material.color; assert.equal(new THREE.Color(color).getHexString(), 'fafafa'); done(); }); diff --git a/tests/components/vive-focus-controls.test.js b/tests/components/vive-focus-controls.test.js index fc2a01ba233..0474019fde5 100644 --- a/tests/components/vive-focus-controls.test.js +++ b/tests/components/vive-focus-controls.test.js @@ -8,17 +8,9 @@ suite('vive-focus-controls', function () { el.addEventListener('loaded', function () { var component = el.components['vive-focus-controls']; component.controllersWhenPresent = [{ - id: 'HTC Vive Focus Controller', - index: 0, - hand: 'right', - axes: [0, 0], - buttons: [ - {value: 0, pressed: false, touched: false}, - {value: 0, pressed: false, touched: false} - ], - pose: {orientation: [1, 0, 0, 0], position: null} + profiles: ['htc-vive-focus'], + handedness: 'right' }]; - el.parentEl.renderer.xr.getStandingMatrix = function () {}; done(); }); }); @@ -30,7 +22,7 @@ suite('vive-focus-controls', function () { var addEventListenersSpy = sinon.spy(component, 'addEventListeners'); var injectTrackedControlsSpy = sinon.spy(component, 'injectTrackedControls'); - el.sceneEl.systems['tracked-controls-webvr'].controllers = []; + el.sceneEl.systems['tracked-controls-webxr'].controllers = []; component.controllerPresent = false; @@ -48,7 +40,7 @@ suite('vive-focus-controls', function () { var injectTrackedControlsSpy = sinon.spy(component, 'injectTrackedControls'); var removeEventListenersSpy = sinon.spy(component, 'removeEventListeners'); - el.sceneEl.systems['tracked-controls-webvr'].controllers = []; + el.sceneEl.systems['tracked-controls-webxr'].controllers = []; component.controllerEventsActive = false; component.controllerPresent = false; @@ -68,7 +60,7 @@ suite('vive-focus-controls', function () { var injectTrackedControlsSpy = sinon.spy(component, 'injectTrackedControls'); var removeEventListenersSpy = sinon.spy(component, 'removeEventListeners'); - el.sceneEl.systems['tracked-controls-webvr'].controllers = component.controllersWhenPresent; + el.sceneEl.systems['tracked-controls-webxr'].controllers = component.controllersWhenPresent; component.controllerPresent = false; @@ -87,7 +79,7 @@ suite('vive-focus-controls', function () { var injectTrackedControlsSpy = sinon.spy(component, 'injectTrackedControls'); var removeEventListenersSpy = sinon.spy(component, 'removeEventListeners'); - el.sceneEl.systems['tracked-controls-webvr'].controllers = component.controllersWhenPresent; + el.sceneEl.systems['tracked-controls-webxr'].controllers = component.controllersWhenPresent; component.controllerEventsActive = true; component.controllerPresent = true; @@ -107,7 +99,7 @@ suite('vive-focus-controls', function () { var injectTrackedControlsSpy = sinon.spy(component, 'injectTrackedControls'); var removeEventListenersSpy = sinon.spy(component, 'removeEventListeners'); - el.sceneEl.systems['tracked-controls-webvr'].controllers = []; + el.sceneEl.systems['tracked-controls-webxr'].controllers = []; component.controllerEventsActive = true; component.controllerPresent = true; @@ -122,14 +114,14 @@ suite('vive-focus-controls', function () { }); suite('axismove', function () { - test('emits trackpadmoved on axismove', function (done) { + test('emits touchpadmoved on axismove', function (done) { var el = this.el; setupTestControllers(el); // Configure the event state for which we'll use the axis state for verification. const eventState = {axis: [0.1, 0.2], changed: [true, false]}; - el.addEventListener('trackpadmoved', function (evt) { + el.addEventListener('touchpadmoved', function (evt) { assert.equal(evt.detail.x, eventState.axis[0]); assert.equal(evt.detail.y, eventState.axis[1]); done(); @@ -138,13 +130,13 @@ suite('vive-focus-controls', function () { el.emit('axismove', eventState); }); - test('does not emit trackpadmoved on axismove with no changes', function (done) { + test('does not emit touchpadmoved on axismove with no changes', function (done) { var el = this.el; setupTestControllers(el); // Fail purposely. - el.addEventListener('trackpadmoved', function (evt) { - assert.fail('trackpadmoved was called when there was no change.'); + el.addEventListener('touchpadmoved', function (evt) { + assert.fail('touchpadmoved was called when there was no change.'); }); el.emit('axismove', {axis: [0.1, 0.2], changed: [false, false]}); @@ -153,8 +145,9 @@ suite('vive-focus-controls', function () { }); suite('buttonchanged', function () { - [{ button: 'trackpad', id: 0 }, - { button: 'trigger', id: 1 } + [{ button: 'trigger', id: 0 }, + { button: 'touchpad', id: 2 }, + { button: 'menu', id: 4 } ].forEach(function (buttonDescription) { test('if we get buttonchanged for button ' + buttonDescription.id + ', emit ' + buttonDescription.button + 'changed', function (done) { var el = this.el; @@ -195,61 +188,6 @@ suite('vive-focus-controls', function () { }); }); - suite('armModel', function () { - test('does not apply armModel if armModel disabled', function () { - var el = this.el; - el.setAttribute('vive-focus-controls', 'armModel', false); - setupTestControllers(el); - - var trackedControls = el.components['tracked-controls-webvr']; - var applyArmModelSpy = sinon.spy(trackedControls, 'applyArmModel'); - trackedControls.tick(); - - // Verify that the function which applies arm model is not called when disabled. - sinon.assert.notCalled(applyArmModelSpy); - - // Additionally verify that no other offsets have been applied. - assert.strictEqual(el.object3D.position.x, 0); - assert.strictEqual(el.object3D.position.y, 0); - assert.strictEqual(el.object3D.position.z, 0); - }); - - test('applies armModel if armModel enabled', function () { - var el = this.el; - el.setAttribute('vive-focus-controls', 'armModel', true); - setupTestControllers(el); - - var trackedControls = el.components['tracked-controls-webvr']; - var applyArmModelSpy = sinon.spy(trackedControls, 'applyArmModel'); - trackedControls.tick(); - - // Verify that the function which applies arm model is called. - sinon.assert.calledOnce(applyArmModelSpy); - }); - - test('verifies armModel position is applied for the right hand', function () { - var el = this.el; - el.setAttribute('vive-focus-controls', 'armModel', true); - setupTestControllers(el); - - var trackedControls = el.components['tracked-controls-webvr']; - trackedControls.tick(); - assert.ok(el.object3D.position.x > 0); - }); - - test('verifies armModel position is applied for the left hand', function () { - var el = this.el; - el.setAttribute('vive-focus-controls', 'armModel', true); - el.setAttribute('vive-focus-controls', 'hand', 'left'); - el.components['vive-focus-controls'].controllersWhenPresent[0].hand = 'left'; - setupTestControllers(el); - - var trackedControls = el.components['tracked-controls-webvr']; - trackedControls.tick(); - assert.ok(el.object3D.position.x < 0); - }); - }); - /** * Establishes the baseline set of controllers needed for the tests to run. * @@ -257,7 +195,7 @@ suite('vive-focus-controls', function () { */ function setupTestControllers (el) { var component = el.components['vive-focus-controls']; - el.sceneEl.systems['tracked-controls-webvr'].controllers = component.controllersWhenPresent; + el.sceneEl.systems['tracked-controls-webxr'].controllers = component.controllersWhenPresent; component.checkIfControllerPresent(); } }); diff --git a/tests/components/windows-motion-controls.test.js b/tests/components/windows-motion-controls.test.js index 5601854c6a8..ac29b27c3a5 100644 --- a/tests/components/windows-motion-controls.test.js +++ b/tests/components/windows-motion-controls.test.js @@ -7,14 +7,14 @@ suite('windows-motion-controls', function () { var MOCKS = { AXIS_VALUES_VALID: [0.1, 0.2, 0.3, 0.4], - AXIS_THUMBSTICK_X: 0, - AXIS_THUMBSTICK_Y: 1, - AXIS_TRACKPAD_X: 2, - AXIS_TRACKPAD_Y: 3, + AXIS_TOUCHPAD_X: 0, + AXIS_TOUCHPAD_Y: 1, + AXIS_THUMBSTICK_X: 2, + AXIS_THUMBSTICK_Y: 3, HAND_LEFT: 'left', HAND_RIGHT: 'right', HAND_DEFAULT: 'right', - HAND_UNHANDED: '' + HAND_UNHANDED: 'none' }; setup(function (done) { @@ -73,7 +73,7 @@ suite('windows-motion-controls', function () { var removeEventListenersSpy = this.sinon.spy(component, 'removeEventListeners'); // Mock isControllerPresent to return true. - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); // delete our previously created mock, so component behaves as if it's never // checked for controller presence previously. @@ -87,25 +87,10 @@ suite('windows-motion-controls', function () { assert.ok(component.controllerPresent, 'controllers present'); }); - test('does not detect presence of controller with missing id suffix', function () { - // Mock isControllerPresent to return true. - el.sceneEl.systems['tracked-controls-webvr'].controllers = [ - {id: 'Spatial Controller (Spatial Interaction Source)', index: 0, hand: MOCKS.HAND_LEFT, pose: {}} - ]; - - // delete our previously created mock, so component behaves as if it's never - // checked for controller presence previously. - delete component.controllerPresent; - - component.checkIfControllerPresent(); - - assert.notOk(component.controllerPresent, 'controllers present'); - }); - test('does not detect presence of controller with unknown device ID', function () { // Mock isControllerPresent to return true. - el.sceneEl.systems['tracked-controls-webvr'].controllers = [ - {id: 'unknown', index: 0, hand: MOCKS.HAND_LEFT, pose: {}} + el.sceneEl.systems['tracked-controls-webxr'].controllers = [ + {profiles: ['unknown'], handedness: MOCKS.HAND_LEFT} ]; // delete our previously created mock, so component behaves as if it's never @@ -120,7 +105,7 @@ suite('windows-motion-controls', function () { test('does not detect presence of controller with wrong hand', function () { // Mock isControllerPresent to return false. component.data.hand = MOCKS.HAND_RIGHT; - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_LEFT); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_LEFT); // delete our previously created mock, so component behaves as if it's never // checked for controller presence previously. @@ -131,88 +116,11 @@ suite('windows-motion-controls', function () { assert.notOk(component.controllerPresent, 'controllers present'); }); - test('detects presence of controller in third pair', function () { - // Mock isControllerPresent to return true. - component.data.pair = 2; - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_LEFT, MOCKS.HAND_RIGHT, MOCKS.HAND_LEFT, MOCKS.HAND_RIGHT, MOCKS.HAND_LEFT, MOCKS.HAND_RIGHT); - - // delete our previously created mock, so component behaves as if it's never - // checked for controller presence previously. - delete component.controllerPresent; - - component.checkIfControllerPresent(); - - assert.ok(component.controllerPresent, 'controllers present'); - }); - - test('detects presence of controller in second pair', function () { - // Mock isControllerPresent to return true. - component.data.pair = 1; - - detect('right'); - detect('left'); - - function detect (hand) { - component.data.hand = hand; - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(hand, hand); - - // delete our previously created mock, so component behaves as if it's never - // checked for controller presence previously. - delete component.controllerPresent; - - component.checkIfControllerPresent(); - - assert.ok(component.controllerPresent, hand + ' controllers present'); - } - }); - - test('detects presence of controller in second pair of unhanded', function () { - // Mock isControllerPresent to return true. - component.data.pair = 1; - - detect('right'); - detect('left'); - - function detect (hand) { - component.data.hand = hand; - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList('', '', '', ''); - - // delete our previously created mock, so component behaves as if it's never - // checked for controller presence previously. - delete component.controllerPresent; - - component.checkIfControllerPresent(); - - assert.ok(component.controllerPresent, hand + ' controllers present'); - } - }); - - test('does not detect presence of controller in second pair of unhanded with too few connected', function () { - // Mock isControllerPresent to return true. - component.data.pair = 1; - - detect('right'); - detect('left'); - - function detect (hand) { - component.data.hand = hand; - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList('', ''); - - // delete our previously created mock, so component behaves as if it's never - // checked for controller presence previously. - delete component.controllerPresent; - - component.checkIfControllerPresent(); - - assert.notOk(component.controllerPresent, hand + ' controllers present'); - } - }); - test('detects presence of controller with right hand', function () { component.data.hand = MOCKS.HAND_RIGHT; // Mock isControllerPresent to return false. - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); // delete our previously created mock, so component behaves as if it's never // checked for controller presence previously. @@ -227,7 +135,7 @@ suite('windows-motion-controls', function () { component.data.hand = MOCKS.HAND_RIGHT; // Mock isControllerPresent to return false. - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_UNHANDED); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_UNHANDED); // delete our previously created mock, so component behaves as if it's never // checked for controller presence previously. @@ -238,26 +146,11 @@ suite('windows-motion-controls', function () { assert.ok(component.controllerPresent, 'controllers present'); }); - test('does not detect presence of left controller with single unhanded', function () { + test('detects presence of left controller with unhanded based on index (fallback)', function () { component.data.hand = MOCKS.HAND_LEFT; // Mock isControllerPresent to return false. - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_UNHANDED); - - // delete our previously created mock, so component behaves as if it's never - // checked for controller presence previously. - delete component.controllerPresent; - - component.checkIfControllerPresent(); - - assert.notOk(component.controllerPresent, 'controllers present'); - }); - - test('detects presence of left controller with two unhanded', function () { - component.data.hand = MOCKS.HAND_LEFT; - - // Mock isControllerPresent to return false. - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_UNHANDED, MOCKS.HAND_UNHANDED); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_UNHANDED, MOCKS.HAND_UNHANDED); // delete our previously created mock, so component behaves as if it's never // checked for controller presence previously. @@ -274,7 +167,7 @@ suite('windows-motion-controls', function () { var removeEventListenersSpy = this.sinon.spy(component, 'removeEventListeners'); // Mock isControllerPresent to return true. - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); // Mock to the state that a gamepad is present. component.controllerEventsActive = true; @@ -306,7 +199,7 @@ suite('windows-motion-controls', function () { suite('axismove', function () { test('emits thumbstick moved on X', function (done) { - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); // Do the check. component.checkIfControllerPresent(); // Install event handler listening for thumbstickmoved. @@ -321,7 +214,7 @@ suite('windows-motion-controls', function () { }); test('emits thumbstick moved on Y', function (done) { - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); // Do the check. component.checkIfControllerPresent(); // Install event handler listening for thumbstickmoved. @@ -335,38 +228,38 @@ suite('windows-motion-controls', function () { this.el.emit('axismove', createAxisMovedFromChanged(MOCKS.AXIS_THUMBSTICK_Y)); }); - test('emits trackpad moved on X', function (done) { - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); + test('emits touchpad moved on X', function (done) { + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); // Do the check. component.checkIfControllerPresent(); - // Install event handler listening for trackpadmoved. - this.el.addEventListener('trackpadmoved', function (evt) { + // Install event handler listening for touchpadmoved. + this.el.addEventListener('touchpadmoved', function (evt) { assert.ok(evt.detail, 'event.detail not null'); - assert.equal(evt.detail.x, MOCKS.AXIS_VALUES_VALID[MOCKS.AXIS_TRACKPAD_X], 'trackpad axis X value'); - assert.equal(evt.detail.y, MOCKS.AXIS_VALUES_VALID[MOCKS.AXIS_TRACKPAD_Y], 'trackpad axis Y value'); + assert.equal(evt.detail.x, MOCKS.AXIS_VALUES_VALID[MOCKS.AXIS_TOUCHPAD_X], 'touchpad axis X value'); + assert.equal(evt.detail.y, MOCKS.AXIS_VALUES_VALID[MOCKS.AXIS_TOUCHPAD_Y], 'touchpad axis Y value'); done(); }); // Emit axismove. - this.el.emit('axismove', createAxisMovedFromChanged(MOCKS.AXIS_TRACKPAD_X)); + this.el.emit('axismove', createAxisMovedFromChanged(MOCKS.AXIS_TOUCHPAD_X)); }); - test('emits trackpad moved on Y', function (done) { - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); + test('emits touchpad moved on Y', function (done) { + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); // Do the check. component.checkIfControllerPresent(); - // Install event handler listening for trackpadmoved. - this.el.addEventListener('trackpadmoved', function (evt) { + // Install event handler listening for touchpadmoved. + this.el.addEventListener('touchpadmoved', function (evt) { assert.ok(evt.detail, 'event.detail not null'); - assert.equal(evt.detail.x, MOCKS.AXIS_VALUES_VALID[MOCKS.AXIS_TRACKPAD_X], 'trackpad axis X value'); - assert.equal(evt.detail.y, MOCKS.AXIS_VALUES_VALID[MOCKS.AXIS_TRACKPAD_Y], 'trackpad axis Y value'); + assert.equal(evt.detail.x, MOCKS.AXIS_VALUES_VALID[MOCKS.AXIS_TOUCHPAD_X], 'touchpad axis X value'); + assert.equal(evt.detail.y, MOCKS.AXIS_VALUES_VALID[MOCKS.AXIS_TOUCHPAD_Y], 'touchpad axis Y value'); done(); }); // Emit axismove. - this.el.emit('axismove', createAxisMovedFromChanged(MOCKS.AXIS_TRACKPAD_Y)); + this.el.emit('axismove', createAxisMovedFromChanged(MOCKS.AXIS_TOUCHPAD_Y)); }); test('does not emit thumbstickmoved if axismove has no changes', function (done) { - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); // Do the check. component.checkIfControllerPresent(); // Fail purposely. @@ -390,7 +283,7 @@ suite('windows-motion-controls', function () { component.createControllerModelUrl = function () { return TEST_URL_MODEL; }; // Mock isControllerPresent to return true. - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); // Perform the test component.checkIfControllerPresent(); @@ -403,7 +296,7 @@ suite('windows-motion-controls', function () { var loadModelSpy = this.sinon.spy(component, 'loadModel'); // Mock isControllerPresent to return true. - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_DEFAULT); // Perform the test component.checkIfControllerPresent(); @@ -420,7 +313,7 @@ suite('windows-motion-controls', function () { component.data.hand = MOCKS.HAND_RIGHT; // Mock isControllerPresent to return true. - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_RIGHT); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_RIGHT); // Perform the test component.checkIfControllerPresent(); @@ -437,7 +330,7 @@ suite('windows-motion-controls', function () { component.data.hand = MOCKS.HAND_RIGHT; // Mock isControllerPresent to return true. - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_UNHANDED); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_UNHANDED); // Perform the test component.checkIfControllerPresent(); @@ -461,7 +354,7 @@ suite('windows-motion-controls', function () { }; // Mock isControllerPresent to return true. - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_RIGHT); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_RIGHT); // Perform the test component.checkIfControllerPresent(); @@ -475,25 +368,22 @@ suite('windows-motion-controls', function () { }); suite('buttonchanged', function () { - test('can emit thumbstickchanged event', function (done) { - buttonTestHelper(done, 0, 'thumbstick'); - }); test('can emit triggerchanged event', function (done) { - buttonTestHelper(done, 1, 'trigger'); + buttonTestHelper(done, 0, 'trigger'); }); - test('can emit gripchanged event', function (done) { - buttonTestHelper(done, 2, 'grip'); + test('can emit squeezechanged event', function (done) { + buttonTestHelper(done, 1, 'squeeze'); }); - test('can emit menuchanged event', function (done) { - buttonTestHelper(done, 3, 'menu'); + test('can emit touchpadchanged event', function (done) { + buttonTestHelper(done, 2, 'touchpad'); }); - test('can emit trackpadchanged event', function (done) { - buttonTestHelper(done, 4, 'trackpad'); + test('can emit thumbstickchanged event', function (done) { + buttonTestHelper(done, 3, 'thumbstick'); }); function buttonTestHelper (done, buttonIndex, buttonName) { var state = {value: 0.5, pressed: true, touched: true}; - el.sceneEl.systems['tracked-controls-webvr'].controllers = createMotionControllersList(MOCKS.HAND_RIGHT); + el.sceneEl.systems['tracked-controls-webxr'].controllers = createMotionControllersList(MOCKS.HAND_RIGHT); // Do the check. component.checkIfControllerPresent(); // Install event handler listening for changed event. @@ -555,7 +445,7 @@ suite('windows-motion-controls', function () { for (var i = 0; i < arguments.length; i++) { controllersList.push( - {id: 'Spatial Controller (Spatial Interaction Source) 045E-065A', index: i, hand: arguments[i], pose: {}} + { profiles: ['windows-mixed-reality'], handedness: arguments[i] } ); } diff --git a/tests/core/scene/a-scene.test.js b/tests/core/scene/a-scene.test.js index 2a2ef14c219..1ec67bae63d 100644 --- a/tests/core/scene/a-scene.test.js +++ b/tests/core/scene/a-scene.test.js @@ -511,6 +511,7 @@ suite('a-scene (without renderer) - WebXR', function () { suite('a-scene (without renderer) - WebVR', function () { setup(function (done) { var el = this.el = document.createElement('a-scene'); + el.hasWebXR = false; el.addEventListener('nodeready', function () { done(); }); this.sinon.stub(utils.device, 'getVRDisplay').returns({ requestPresent: function () {