How do you get the position of quest 2 controllers and have a ray-cast search for buttons?

I have the controller controller1 = renderer.xr.getController( 0 ); and the controller data and have two buttons stored in button1 and button2, I’ve made it work for the mouse but the controllers just make the raycast very inacurate when I do

raycaster25= new THREE.Raycaster(controller1.position.clone(),controller1.rotation.clone())

and then

const intersects12=raycaster25.intersectObjects( [button1,button2] );

it’s very inaccurate. idk why.

(edit to add the whole function)

function getIntersections(controller){
	var raycaster25= {}
	if(controller==controller1){
		var zcorrect=controller1.rotation.clone()
		zcorrect.z=-zcorrect.z
		raycaster25= new THREE.Raycaster(controller1.position.clone(),zcorrect)
	}else if(controller==controller2){
		var zcorrect=controller2.rotation.clone()
		zcorrect.z=-zcorrect.z
		raycaster25= new THREE.Raycaster(controller2.position.clone(),zcorrect)
	}
	const intersects12=raycaster25.intersectObjects( [button1,button2] );
	
	return intersects12
}

Are you using a dolly like most webXR app?
(Controller/camera inside a group instead of directly in the scene)
If this is the case, you may obtain wrong positions or crashes.

I’m not looking to move the player, so no, although if that could help with getting them to detect the buttons I’ll do it, although it seams to be tracking everything, although everything is a bit off.

hmm so this is not a local/world position issue :thinking:
All I can do is pasting the functions I’m using for both cases. And hope it can help.

The first one is to be used with a dolly (local position get converted to world position)

const tempMatrix = new THREE.Matrix4();

//require a controller (origin) and x,y,z (direction)
function getIntersections( controller,x,y,z ) {
	tempMatrix.identity().extractRotation( controller.matrixWorld );
	raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld );
	raycaster.ray.direction.set( x, y, z).applyMatrix4( tempMatrix );
	return raycaster.intersectObjects( objectsArray );
	}

the second one is a world raycast (very basic, no rotation sorry)

function getIntersections(object, x, y, z) {
    let origin = new THREE.Vector3;
    origin.copy(object.position);
    let direction = new THREE.Vector3(x, y, z);
    direction.normalize();

    raycaster.set(origin, direction);
    return raycaster.intersectObjects( objectsArray );
}

it’s extracted from my own code. May require few adaptations.

1 Like

what do x,y,z represent in the first example? and how would I get them?

it shoot from your controller’s axis.
so if you want to cast forward from your hands positions (like firing a gun), use something like
getIntersections( controller, 0,0,-1 )
no need for higher value, it’s just a direction.

1 Like

ah makes sense

Your function only works when I look straight forward. idk why though. any idea how to fix it?

nm, it works now, thanks for the help!!!