How to enable AR and Hit-test?
Similar to VR experience, you can add AR Button to enable AR experiences. Additionally, you can specify the required and optional AR features your experience will use.
1
import { ARButton } from "/jsm/webxr/ARButton";
2
​
3
document.body.appendChild(ARButton.createButton(renderer, { requiredFeatures: ["hit-test"] }));
Copied!
Add a controller: Returns a Group representing the so called target ray space of the controller. Use this space for visualizing 3D objects that support the user in pointing tasks like UI interaction.
1
controller = renderer.xr.getController(0);
2
controller.addEventListener("select", onSelect);
3
scene.add(controller);
Copied!
When we are hitting a surface, to indicate the surface, we will create a reticle to our scene.
1
//Hit-test indicator
2
reticle = new Mesh(new RingBufferGeometry(0.15, 0.2, 32).rotateX(-Math.PI / 2), new MeshBasicMaterial());
3
reticle.matrixAutoUpdate = false;
4
reticle.visible = false;
5
scene.add(reticle);
Copied!
Let's define the onSelect event that we attached to controller. When the select event happen, meaning user decides to place the object and we create it on the chosen location.
1
function onSelect() {
2
if (reticle.visible) {
3
const mesh = new Mesh(geometry, phongMaterial);
4
mesh.position.setFromMatrixPosition(reticle.matrix);
5
mesh.scale.y = Math.random() * 2 + 1;
6
scene.add(mesh);
7
}
8
}
Copied!
Finally in our render function, we will check in every XRFrame if we have an hit-test source to display the reticle on the surface.
1
function render(timestamp: number, frame: any) {
2
if (frame) {
3
earth.visible = false;
4
const referenceSpace = renderer.xr.getReferenceSpace();
5
const session = renderer.xr.getSession();
6
if (hitTestSourceRequested === false) {
7
session.requestReferenceSpace("viewer").then((referenceSpace) => {
8
session.requestHitTestSource({ space: referenceSpace }).then((source) => {
9
hitTestSource = source;
10
});
11
});
12
​
13
session.addEventListener("end", () => {
14
hitTestSourceRequested = false;
15
hitTestSource = null;
16
});
17
hitTestSourceRequested = true;
18
}
19
if (hitTestSource) {
20
const hitTestResults = frame.getHitTestResults(hitTestSource);
21
if (hitTestResults.length) {
22
const hit = hitTestResults[0];
23
reticle.visible = true;
24
reticle.matrix.fromArray(hit.getPose(referenceSpace).transform.matrix);
25
} else {
26
reticle.visible = false;
27
}
28
}
29
}
30
renderer.render(scene, camera);
31
}
32
​
Copied!
To run the code on your device, you have to give access to your camera when prompted.
Export as PDF
Copy link