Signatur
Beschreibung
Mit getHitTestResults() fragt man in einer AR-Sitzung (immersive-ar) ab, wo ein Strahl auf die reale Umgebung trifft, z. B. auf den Boden, einen Tisch oder eine Wand. Den Strahl legt vorher eine XRHitTestSource fest, die man mit XRSession.requestHitTestSource() erzeugt, meist ausgehend vom viewer-Referenzraum (Bildschirmmitte) oder von einem Eingabestrahl.
Die Methode ruft man bei jedem Frame im Callback von XRSession.requestAnimationFrame() auf. Sie liefert die Treffer nach Entfernung sortiert, der nächste steht also an Index 0. Aus einem XRHitTestResult holt man mit getPose(referenceSpace) die Position und Ausrichtung des Treffers. Damit platziert man zum Beispiel ein Fadenkreuz (Reticle) oder ein virtuelles Objekt.
Typischer Ablauf: Sitzung mit requiredFeatures: ['hit-test'] anfordern → Hit-Test-Quelle anlegen → in jedem Frame frame.getHitTestResults(source) abfragen → die Pose des ersten Treffers verwenden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $hitTestSource Pflicht | XRHitTestSource | Die Hit-Test-Quelle, die mit XRSession.requestHitTestSource() erzeugt wurde und den Strahl (Ursprung, Richtung, Entitätstypen) festlegt. |
Rückgabewert
Beispiele
AR-Sitzung mit Hit-Test starten und Quelle anlegen
const startAR = async () => {
if (!(await navigator.xr?.isSessionSupported('immersive-ar'))) {
console.log('AR wird nicht unterstützt');
return;
}
const session = await navigator.xr.requestSession('immersive-ar', {
requiredFeatures: ['hit-test', 'local']
});
const viewerSpace = await session.requestReferenceSpace('viewer');
const localSpace = await session.requestReferenceSpace('local');
// Strahl aus der Bildschirmmitte nach vorne
const hitTestSource = await session.requestHitTestSource({ space: viewerSpace });
const onFrame = (time, frame) => {
session.requestAnimationFrame(onFrame);
const results = frame.getHitTestResults(hitTestSource);
if (results.length > 0) {
const pose = results[0].getPose(localSpace);
const { x, y, z } = pose.transform.position;
console.log(`Treffer bei ${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`);
}
};
session.requestAnimationFrame(onFrame);
};
// Muss durch eine Nutzeraktion ausgelöst werden
document.querySelector('#ar-button').addEventListener('click', startAR);
Fadenkreuz (Reticle) auf erkannter Fläche platzieren
// reticle: z. B. ein three.js-Mesh mit matrixAutoUpdate = false
const updateReticle = (frame, hitTestSource, refSpace, reticle) => {
const [nearest] = frame.getHitTestResults(hitTestSource);
if (!nearest) {
reticle.visible = false;
return;
}
const pose = nearest.getPose(refSpace);
reticle.visible = true;
// 4x4-Matrix direkt übernehmen (Position + Ausrichtung der Fläche)
reticle.matrix.fromArray(pose.transform.matrix);
};
Objekt beim Tippen platzieren und Quelle aufräumen
let lastHit = null;
const onFrame = (time, frame) => {
frame.session.requestAnimationFrame(onFrame);
const results = frame.getHitTestResults(hitTestSource);
lastHit = results.length ? results[0].getPose(localSpace) : null;
};
session.addEventListener('select', () => {
if (lastHit) {
placeModelAt(lastHit.transform); // eigene Funktion
}
});
session.addEventListener('end', () => {
hitTestSource.cancel(); // Ressourcen freigeben
});
// Wichtig · Fallstricke
- Nur mit aktivem Frame: Die Methode funktioniert nur innerhalb des
requestAnimationFrame-Callbacks der Sitzung. Speichert man denXRFrameund ruft sie später auf, wird einInvalidStateErrorgeworfen. - Feature anfordern: Ohne
'hit-test'inrequiredFeaturesoderoptionalFeaturesschlägtrequestHitTestSource()fehl, weil das Feature nicht aktiviert ist. - Die Quelle muss zur Sitzung passen: Stammt die
XRHitTestSourceaus einer anderen Sitzung oder wurde sie mitcancel()beendet, führt der Aufruf zu einem Fehler. - Direkt nach dem Start ist das Array oft einige Frames lang leer, solange das Gerät die Umgebung noch erfasst. Den Fall
results.length === 0immer abfangen. - Für transiente Eingaben wie Bildschirm-Taps gibt es die eigene Methode
getHitTestResultsForTransientInput(). - Kompatibilität: Die Methode ist experimentell und vor allem in Chromium auf Android (ARCore) und im Meta Quest Browser verfügbar. Firefox und Safari unterstützen sie nicht. Sie braucht einen sicheren Kontext (HTTPS) und in iframes die Permissions Policy
xr-spatial-tracking.