Skip to content

Commit

Permalink
Cursor component: improve xrselect rayOrigin logic (#5606)
Browse files Browse the repository at this point in the history
* cursor: fix error when using ray origin xrselect and cursor not attached to scene

* Transform XRPose into world space in cursor when using xrselect ray origin

---------

Co-authored-by: Johan Leuenberger <[email protected]>
  • Loading branch information
mrxz and JL-Vidinoti authored Nov 15, 2024
1 parent caa5bce commit 655ab16
Showing 1 changed file with 52 additions and 16 deletions.
68 changes: 52 additions & 16 deletions src/components/cursor.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 () {
Expand Down Expand Up @@ -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 () {
Expand All @@ -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();
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand All @@ -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'
});
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 655ab16

Please sign in to comment.