# Checking if the reticle is horizontal or vertical in webxr

I’m developing with webxr and three.js following the basic setup here.

I need to determine whether the reticle is on a horizontal surface or a vertical one. I assume in the render loop after the line `this.reticle.matrix.fromArray(hit.getPose(referenceSpace).transform.matrix);`.

What is the best way to do this please?

You can try the method getWorldDirection(v3) on the reticle where v3 is a target vector3 to be passed the world direction, normalising this vector should give you number values to determine if the reticle is facing upwards or sideways

Thank you. I had actually tried that, but the normalize function doesn’t seem to work in this instance. It’s really odd.

Two samples. The first one normalizes perfectly. The second normalize does nothing at all.

Sample 1:

``````var dir = new THREE.Vector3(-20, 0, 0);
dir.normalize();
console.log(dir);
``````

Output 1: `Vector3 {x: -1, y: 0, z: 0}`

Sample 2:

``````var dir = new THREE.Vector3(0, 0, 0);
this.reticle.getWorldDirection(dir);
dir.normalize();
console.log(dir);
``````

Output 2: `Vector3 {x: 0.2372211329375215, y: -8.289278695949982e-17, z: 0.9714556778813118}`

The `dir` values in output 2 here are exactly the same as the `dir` values immediately after the `this.reticle.getWorldDirection(dir);` command.

It’s like there is something different about the Vector3 returned by `getWorldDirection()` which makes the `normalize()` function fail.

OK so I found a solution. I couldn’t get past the `getWorldDirection()` `normalize()` issue, but I found a way.

I create an invisible plane within the reticle object, offset in the y direction so that it sits in front of the reticle. This is always in front of the reticle regardless of where the reticle is because it’s a child of the reticle.

``````    addReticle() {

let geom;
if(this.reticleType == 0){
geom = new THREE.RingGeometry(0.05, 0.07, 32);
}else if(this.reticleType == 1){
geom = new THREE.CircleGeometry( .01, 32 );
}

this.reticle = new THREE.Mesh(
geom.rotateX(- Math.PI / 2),
new THREE.MeshBasicMaterial()
);
this.reticle.matrixAutoUpdate = false;
this.reticle.visible = false;

let geomLookAt = new THREE.PlaneGeometry(.05, .05);
this.reticleLookAt = new THREE.Mesh(
geomLookAt.rotateX(- Math.PI / 2),
new THREE.MeshBasicMaterial({color: 0xff0000})
);
this.reticleLookAt.translateY(.3);
this.reticleLookAt.visible = false;

}
``````

I can now get the world position of the `reticle` and `reticleLookAt` and calculate the subvector between the two to get the direction between them. The y property will contain 1 if facing up, -1 if facing down and anything else if neither of those. So we can calculate floor, wall and ceiling placement with this function:

``````    getReticleSurface(){
this.reticleLookAt.getWorldPosition(this.reticleWorldPosition);
this.reticle.getWorldPosition(this.reticleLookAtWorldPosition);
this.reticleDirection.subVectors( this.reticleWorldPosition, this.reticleLookAtWorldPosition ).normalize();
if(this.reticleDirection.y == 1){
return 'floor';
}else if(this.reticleDirection.y == -1){
return 'ceiling';
}else{
return 'wall';
}
}
``````

`this.reticleWorldPosition`, `this.reticleLookAtWorldPosition`, and `this.reticleDirection` are all defined as class properties so that they are re-used rather than creating a new `Vector3()` each time.

Hope that helps someone out

1 Like