Rogue hand rays in 0.127.0

Hello, I noticed that ray lines created for the controllers moved to the hands yesterday, 3/31/21, in Oculus Quest 2. After checking for code changes, I saw that the current version I’m using, from, just upgraded to 0.127.0, and tried reverting manually to 0.126.1, which removed the extra rays and allowed the hands, and the controller rays, to work normally. Prior to that, I tested a few code changes, to no effect (code below). Not sure if this is a bug or a new feature. Rays from hands could be useful, though they are harder to control and, for this particular project, we generally don’t want rays in the hands, and are instead using index finger tip intersection to push buttons, type and draw. If the ray is needed, the user picks up the controller to access it.
Is there a way to keep the controller rays out of the hands in 0.127.0, or should I just continue to use the previous version? Also, would it be a better practice in general to download a known-working version and supply that from our own server, or should the latest version from, or another source be used to keep up to date?
Thank you in advance for your help.

Here is the code to set up the hands and controllers, note:

  • several window vars utilized
  • “rig” keeps the camera, hands and controllers together
  • called functions “rayClick”, “onPinch…” etc. defined elsewhere
  • all working OK as shown prior to version 0.127.0, and now OK in 0.126.1:
var controller1 = window.renderer.xr.getController( 0 );
controller1.addEventListener( "selectend", rayClick);
controller1.addEventListener( "selectstart", rayDown);  
window.controller1 = controller1;
rig.add( controller1 );
controller2 = window.renderer.xr.getController( 1 );
rig.add( controller2 );
var controllerModelFactory = new window.XRControllerModelFactory();
var handModelFactory = new window.XRHandModelFactory().setPath( "/images/fbx/" );  
controllerGrip1 = window.renderer.xr.getControllerGrip( 0 );
controllerGrip1.add( controllerModelFactory.createControllerModel( controllerGrip1 ) );
rig.add( controllerGrip1 );
hand1 = window.renderer.xr.getHand( 0 ); = "right-hand";
rig.add( hand1 );
hand1.addEventListener( "pinchstart", onPinchStartRight ); 
hand1.addEventListener( "pinchend", () => { = false;
} );
hand1.add(handModelFactory.createHandModel( hand1, "oculus" )); 
window.hand1 = hand1;
controllerGrip2 = window.renderer.xr.getControllerGrip( 1 );
controllerGrip2.add( controllerModelFactory.createControllerModel( controllerGrip2 ) );
rig.add( controllerGrip2 );
hand2 = window.renderer.xr.getHand( 1 );
hand2.addEventListener( "pinchstart", onPinchStartLeft );
hand2.addEventListener( "pinchend", onPinchEndLeft );
hand2.add(handModelFactory.createHandModel( hand2, "oculus" )); = "left-hand";
rig.add( hand2 );
window.hand2 = hand2;
// following defines line for controllers; moving above hands in code sequence had no effect
var geometry = new window.THREE.BufferGeometry().setFromPoints( [ new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, - 1 ) ] );
var material = new window.THREE.LineBasicMaterial({	color: 0xff0000, opacity:.5, transparent:true});
var line = new window.THREE.Line( geometry, material ); = "line";
line.scale.z = 25;
controller1.add( line.clone() );
controller2.add( line.clone() );  // disabling fixes rogue ray -- if enabled and using 0.127.0, line shows from hand

// also, an earlier, possibly related version of this effect caused the controller ray to fire on the first hand pinch just after the controller was set down, even though the controller ray was no longer visible; this was fixed by monitoring the controller y, within an existing loop:
// try, stop ray if hand
var controller1 = window.controller1;
if (controller1)
if (position3.y && position3.y != controllerY) {
controllerY = position3.y;
window.indexTip1 = false;  
} else
window.indexTip1 = true;

// this is similar to the observed behavior of the oculus controller, that it switches to hand-mode (if enabled) when the controller is set down (y unchanging)

// the rayClick and rayDown functions are then disabled internally if hands are being used:
if(window.indexTip1)return false;

In the new problem, however, this no longer works, since apparently the controller is attached to the hand, and showing as being moved, therefore active and looking for clicks or pinches

// if you’re still reading, further testing showed the controller is indeed moving with the hand:
position3.y: 1.1276463270187378
position3.y: 1.004975438117981
position3.y: 1.0196633338928223
position3.y: 0.9368172287940979
position3.y: 0.8119852542877197
position3.y: 0.7701883316040039

// however, a simple attempt to remove the controller from the hand under this condition failed:
// no errors were reported, though it didn't work, either

Is there a correct way to remove the controller from the hand, or keep it from being attached to it in the first place?
Reverting to 0.126.1 for now, pending more information or updates.
Thank you again for your patience if you’ve read this far and for any help you can offer!

Just for reference, I think your topic refers to this change:

AFAIK, this was the only change in context of WebXR in r127. In any event, this change definitely makes sense in order to add support for hands interaction.

It’s not good to always use the latest version since sometimes migration tasks are required in order to keep things working.

Thank you very much for your answer. Any idea if there is a way to toggle on/off or remove rays from hands? It’s great to have them available, and fun to play with, though it can be distracting and produce unintended results when using hands for touch-based interactions, like typing, pushing buttons, or pinching to select or resize elements.
Thanks again for all your help!

Um, I’m not sure I understand this. three.js itself does not add visual helpers to the controllers. This all happens in example/app level code.

Hello and thanks again for all your help!
Here is the closest public example I could find to partially illustrate the problem:
When switching to hands while using a headset in VR, the controller rays now jump to and extend through the hands. In this example, there are no controls anywhere, however, if there were buttons or other controls on the front wall, for example, they could accidentally be triggered while attempting to pinch a cube.
In my project, there are several such controls, activated by ray intersect selectstart or selectend when the controller is being used. However, when hands are being used, for typing, drawing or pushing buttons, having the ray shoot past or through the hand and intended object and activating whatever it hits if the fingers reach a “pinch” position, which is not uncommon when using hands normally, is a problem. If the controller rays will now jump to the hands by default, is there a way to optionally disable or remove them from the hands? If not, is there a better way to detect when hands as being used? My previous method was to assume hands are being used if the controller stops moving - that no longer works now that the controller follows the hands.