Start · Sprachen · JavaScript · Referenz · XRHitTestSource

XRHitTestSource

Schnittstelle

Steht für ein aktives Hit-Test-Abonnement in einer WebXR-AR-Sitzung. Die Ergebnisse liefert <code>XRFrame.getHitTestResults()</code> in jedem Frame.

seit JavaScript WebXR Hit Test Module; Chrome/Edge 81+ (Android, A Kategorie: webapi

Signatur

interface XRHitTestSource

Beschreibung

Wird von XRSession.requestHitTestSource() als Promise<XRHitTestSource> geliefert. cancel() gibt undefined zurück.

Parameter

Name Typ Default Beschreibung
$options.space Pflicht XRSpace Referenzraum, von dem der Strahl ausgeht, oft await session.requestReferenceSpace('viewer'). Gehört zu requestHitTestSource(options).
$options.offsetRay XRRay new XRRay() Strahl relativ zu space. Ohne Angabe beginnt er im Ursprung und zeigt in Richtung -Z, also nach vorne.
$options.entityTypes Array<'point'|'plane'|'mesh'> ['plane'] Arten von Umgebungsmerkmalen, die der Hit-Test berücksichtigen soll.

Beispiele

Hit-Test-Quelle anfordern (AR-Sitzung starten)

const startAR = async () => {
  if (!navigator.xr || !(await navigator.xr.isSessionSupported('immersive-ar'))) {
    console.log('AR wird nicht unterstützt');
    return;
  }
  // Muss durch eine Nutzeraktion ausgelöst werden (z. B. Button-Klick)
  const session = await navigator.xr.requestSession('immersive-ar', {
    requiredFeatures: ['hit-test', 'local']
  });
  const viewerSpace = await session.requestReferenceSpace('viewer');
  const localSpace = await session.requestReferenceSpace('local');

  const hitTestSource = await session.requestHitTestSource({ space: viewerSpace });
  console.log(hitTestSource instanceof XRHitTestSource);
  return { session, hitTestSource, localSpace };
};

document.querySelector('#ar-button').addEventListener('click', startAR);
true

Ergebnisse pro Frame auswerten (Reticle positionieren)

const runLoop = ({ session, hitTestSource, localSpace }, reticle) => {
  const onFrame = (time, frame) => {
    session.requestAnimationFrame(onFrame);
    const results = frame.getHitTestResults(hitTestSource);
    if (results.length > 0) {
      const pose = results[0].getPose(localSpace);
      reticle.visible = true;
      reticle.matrix = pose.transform.matrix; // Float32Array(16)
      const { x, y, z } = pose.transform.position;
      console.log(`Treffer bei ${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`);
    } else {
      reticle.visible = false;
    }
  };
  session.requestAnimationFrame(onFrame);
};
Treffer bei 0.12, -1.35, -0.87

Eigener Strahl mit offsetRay und Aufräumen per cancel()

const setupDownwardHitTest = async (session) => {
  const viewerSpace = await session.requestReferenceSpace('viewer');
  // Strahl schräg nach unten-vorne
  const ray = new XRRay({ x: 0, y: 0, z: 0 }, { x: 0, y: -0.5, z: -1 });
  const source = await session.requestHitTestSource({
    space: viewerSpace,
    offsetRay: ray,
    entityTypes: ['plane', 'point']
  });

  session.addEventListener('end', () => {
    source.cancel(); // Abonnement freigeben
    console.log('Hit-Test-Quelle beendet');
  });
  return source;
};
Hit-Test-Quelle beendet

// Wichtig · Fallstricke

  • Feature-Anforderung: 'hit-test' muss beim Aufruf von requestSession() in requiredFeatures oder optionalFeatures stehen. Sonst schlägt requestHitTestSource() mit einem NotSupportedError fehl.
  • Nur sichere Kontexte: WebXR funktioniert nur über HTTPS. Die Sitzung braucht eine Nutzeraktion. In iframes ist zusätzlich eine Permissions-Policy xr-spatial-tracking nötig.
  • Browser-Unterstützung: Chromium-Browser auf Android mit ARCore unterstützen die API, ebenso einige Headsets wie Meta Quest Browser. Firefox und Safari auf iOS unterstützen sie nicht. Prüfe deshalb vorher mit isSessionSupported('immersive-ar').
  • Leere Ergebnisse: Direkt nach dem Start hat das Gerät oft noch keine Flächen erkannt. getHitTestResults() gibt dann ein leeres Array zurück. Rechne damit und blende das Reticle aus.
  • Ressourcen: Beende nicht mehr benötigte Quellen mit cancel(). Nach cancel() oder dem Ende der Sitzung darf die Quelle nicht mehr an getHitTestResults() übergeben werden, sonst wird ein InvalidStateError geworfen.
  • Datenschutz: Hit-Tests verraten etwas über die Geometrie der Umgebung. Browser verlangen deshalb eine Zustimmung des Nutzers.