diff --git a/src/components/cursor.js b/src/components/cursor.js index 523ff6785ab..0ac5f249bb0 100644 --- a/src/components/cursor.js +++ b/src/components/cursor.js @@ -87,6 +87,13 @@ module.exports.Component = registerComponent('cursor', { update: function (oldData) { if (this.data.rayOrigin === oldData.rayOrigin) { return; } this.updateMouseEventListeners(); + // Update the WebXR event listeners if needed + if (this.data.rayOrigin === 'xrselect') { + this.addWebXREventListeners(); + } + if (oldData.rayOrigin === 'xrselect') { + this.removeWebXREventListeners(); + } }, tick: function () { @@ -194,6 +201,8 @@ module.exports.Component = registerComponent('cursor', { el.sceneEl.removeEventListener('enter-vr', this.onEnterVR); window.removeEventListener('resize', this.updateCanvasBounds); window.removeEventListener('scroll', this.updateCanvasBounds); + + this.removeWebXREventListeners(); }, updateMouseEventListeners: function () { @@ -211,6 +220,32 @@ module.exports.Component = registerComponent('cursor', { this.updateCanvasBounds(); }, + addWebXREventListeners: function () { + var self = this; + var xrSession = this.el.sceneEl.xrSession; + if (xrSession) { + WEBXR_EVENTS.DOWN.forEach(function (downEvent) { + xrSession.addEventListener(downEvent, self.onCursorDown); + }); + WEBXR_EVENTS.UP.forEach(function (upEvent) { + xrSession.addEventListener(upEvent, self.onCursorUp); + }); + } + }, + + removeWebXREventListeners: function () { + var self = this; + var xrSession = this.el.sceneEl.xrSession; + if (xrSession) { + WEBXR_EVENTS.DOWN.forEach(function (downEvent) { + xrSession.removeEventListener(downEvent, self.onCursorDown); + }); + WEBXR_EVENTS.UP.forEach(function (upEvent) { + xrSession.removeEventListener(upEvent, self.onCursorUp); + }); + } + }, + onMouseMove: (function () { var direction = new THREE.Vector3(); var mouse = new THREE.Vector2(); @@ -220,6 +255,7 @@ module.exports.Component = registerComponent('cursor', { return function (evt) { var bounds = this.canvasBounds; var camera = this.el.sceneEl.camera; + var cameraElParent = camera.el.object3D.parent; var left; var point; var top; @@ -248,12 +284,18 @@ module.exports.Component = registerComponent('cursor', { if (this.data.rayOrigin === 'xrselect' && (evt.type === 'selectstart' || evt.type === 'fakeselectevent')) { frame = evt.frame; inputSource = evt.inputSource; - referenceSpace = this.el.renderer.xr.getReferenceSpace(); + referenceSpace = this.el.sceneEl.renderer.xr.getReferenceSpace(); pose = frame.getPose(inputSource.targetRaySpace, referenceSpace); - transform = pose.transform; - direction.set(0, 0, -1); - direction.applyQuaternion(transform.orientation); - origin.copy(transform.position); + if (pose) { + transform = pose.transform; + direction.set(0, 0, -1); + direction.applyQuaternion(transform.orientation); + origin.copy(transform.position); + + // Transform XRPose into world space + cameraElParent.localToWorld(origin); + direction.transformDirection(cameraElParent.matrixWorld); + } } else if (evt.type === 'fakeselectout') { direction.set(0, 1, 0); origin.set(0, 9999, 0); @@ -314,6 +356,7 @@ module.exports.Component = registerComponent('cursor', { */ onCursorUp: function (evt) { if (!this.isCursorDown) { return; } + if (this.data.rayOrigin === 'xrselect' && this.activeXRInput !== evt.inputSource) { return; } this.isCursorDown = false; @@ -338,7 +381,7 @@ module.exports.Component = registerComponent('cursor', { } // if the current xr input stops selecting then make the ray caster point somewhere else - if (data.rayOrigin === 'xrselect' && this.activeXRInput === evt.inputSource) { + if (data.rayOrigin === 'xrselect') { this.onMouseMove({ type: 'fakeselectout' }); @@ -394,16 +437,9 @@ module.exports.Component = registerComponent('cursor', { onEnterVR: function () { this.clearCurrentIntersection(true); - var xrSession = this.el.sceneEl.xrSession; - var self = this; - if (!xrSession) { return; } - if (this.data.rayOrigin === 'mouse') { return; } - WEBXR_EVENTS.DOWN.forEach(function (downEvent) { - xrSession.addEventListener(downEvent, self.onCursorDown); - }); - WEBXR_EVENTS.UP.forEach(function (upEvent) { - xrSession.addEventListener(upEvent, self.onCursorUp); - }); + if (this.data.rayOrigin === 'xrselect') { + this.addWebXREventListeners(); + } }, setIntersection: function (intersectedEl, intersection) {