Start · Sprachen · JavaScript · Referenz · XRSession.requestHitTestSourceForTransientInput()

XRSession.requestHitTestSourceForTransientInput()

Methode

Fordert eine Hit-Test-Quelle für kurzlebige Eingaben wie Bildschirmberührungen an. Das Promise wird mit einer <code>XRTransientInputHitTestSource</code> erfüllt.

seit JavaScript WebXR Hit Test Module – experimentell; Chrome/Edge Kategorie: webapi

Signatur

XRSession.prototype.requestHitTestSourceForTransientInput(options)

Beschreibung

Mit requestHitTestSourceForTransientInput() legt eine immersive AR-Sitzung eine Hit-Test-Quelle an, die nicht an einen festen Referenzraum gebunden ist. Sie ist an kurzlebige (transiente) Eingabequellen gebunden. Ein typisches Beispiel ist das Antippen des Bildschirms auf einem Smartphone: Solange der Finger den Bildschirm berührt, gibt es eine Eingabequelle mit dem Profil "generic-touchscreen". Danach verschwindet sie wieder.

Der Vorteil gegenüber requestHitTestSource(): Sie müssen nicht bei jeder neuen Berührung eine neue Hit-Test-Quelle anfordern. Eine einzige Quelle liefert in jedem Frame über XRFrame.getHitTestResultsForTransientInput() Ergebnisse für alle gerade aktiven Eingaben, die zum angegebenen Profil passen. So bekommen Sie ohne asynchrone Verzögerung Treffer mit der realen Umgebung (Boden, Tischflächen), zum Beispiel um ein virtuelles Objekt genau dort zu platzieren, wo der Nutzer hintippt.

Voraussetzung ist eine Sitzung, die mit dem Feature "hit-test" angefordert wurde (in requiredFeatures oder optionalFeatures). Ohne dieses Feature wird das Promise abgelehnt. Geben Sie die Quelle mit XRTransientInputHitTestSource.cancel() wieder frei, sobald Sie sie nicht mehr brauchen.

Parameter

Name Typ Default Beschreibung
$options Pflicht Object Konfigurationsobjekt mit den unten aufgeführten Eigenschaften.
$options.profile Pflicht string Eingabeprofil, das zu den Einträgen in XRInputSource.profiles passen muss, z. B. "generic-touchscreen" für Berührungen auf Handheld-Geräten.
$options.entityTypes Array<"point"|"plane"|"mesh"> ["plane"] Arten von realen Objekten, die beim Hit-Test berücksichtigt werden: "point" (Merkmalspunkte), "plane" (erkannte Ebenen) und "mesh" (Geometrienetze).
$options.offsetRay XRRay new XRRay() Strahl, der relativ zum Ziel-Strahl (targetRaySpace) der Eingabequelle verschoben wird. Standardmäßig verläuft er vom Ursprung entlang der negativen Z-Achse.

Rückgabewert

Typ
Promise<XRTransientInputHitTestSource>
Beschreibung
Ein Promise, das mit einem XRTransientInputHitTestSource-Objekt erfüllt wird. Es wird mit einer DOMException abgelehnt: NotSupportedError, wenn das Feature "hit-test" nicht aktiviert ist; InvalidStateError, wenn die Sitzung bereits beendet ist; NotAllowedError, wenn die Anfrage nicht erlaubt ist (z. B. bei zu vielen gleichzeitigen Quellen).

Beispiele

AR-Sitzung starten und Hit-Test-Quelle für Touch-Eingaben anfordern

const startAR = async () => {
  if (!(await navigator.xr?.isSessionSupported('immersive-ar'))) {
    console.log('immersive-ar wird nicht unterstützt');
    return;
  }

  const session = await navigator.xr.requestSession('immersive-ar', {
    requiredFeatures: ['hit-test', 'local-floor']
  });

  const touchHitSource = await session.requestHitTestSourceForTransientInput({
    profile: 'generic-touchscreen',
    entityTypes: ['plane', 'point']
  });

  console.log('Hit-Test-Quelle bereit:', touchHitSource);
  return { session, touchHitSource };
};

// Muss durch eine Nutzeraktion ausgelöst werden
document.querySelector('#ar-button').addEventListener('click', startAR);
Hit-Test-Quelle bereit: XRTransientInputHitTestSource {}

Treffer pro Frame auswerten und Objekt beim Antippen platzieren

const setupPlacement = async (session, placeObject) => {
  const refSpace = await session.requestReferenceSpace('local-floor');
  const hitSource = await session.requestHitTestSourceForTransientInput({
    profile: 'generic-touchscreen'
  });

  const onFrame = (time, frame) => {
    session.requestAnimationFrame(onFrame);

    // Ein Eintrag je aktiver transienter Eingabe (z. B. je Finger)
    const inputResults = frame.getHitTestResultsForTransientInput(hitSource);

    for (const { inputSource, results } of inputResults) {
      if (results.length === 0) continue;
      const pose = results[0].getPose(refSpace);
      if (pose) {
        const { x, y, z } = pose.transform.position;
        placeObject(pose.transform.matrix);
        console.log(`Treffer (${inputSource.handedness}): ${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`);
      }
    }
  };

  session.requestAnimationFrame(onFrame);
  return hitSource;
};
Treffer (none): 0.12, 0.00, -0.85

Fehlerbehandlung und Aufräumen beim Sitzungsende

const requestTouchHitTest = async (session) => {
  try {
    const source = await session.requestHitTestSourceForTransientInput({
      profile: 'generic-touchscreen',
      offsetRay: new XRRay({ x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: -1 })
    });

    session.addEventListener('end', () => {
      source.cancel(); // Ressourcen freigeben
      console.log('Hit-Test-Quelle freigegeben');
    }, { once: true });

    return source;
  } catch (err) {
    if (err.name === 'NotSupportedError') {
      console.warn('Feature "hit-test" wurde für die Sitzung nicht aktiviert.');
    } else {
      console.error('Hit-Test nicht möglich:', err.name, err.message);
    }
    return null;
  }
};
Feature "hit-test" wurde für die Sitzung nicht aktiviert.

// Wichtig · Fallstricke

  • Experimentell: Die Methode gehört zum WebXR Hit Test Module. Sie ist praktisch nur in Chromium-Browsern auf Android (ARCore) und im Meta Quest Browser verfügbar. Firefox und Safari unterstützen sie nicht. Prüfen Sie die Unterstützung vorher mit navigator.xr.isSessionSupported('immersive-ar').
  • Die Methode funktioniert nur in einem sicheren Kontext (HTTPS). Außerdem muss die Sitzung mit dem Feature "hit-test" angefordert worden sein. Sonst wird das Promise mit NotSupportedError abgelehnt.
  • Das Profil muss exakt passen. Passt keine Eingabequelle zu profile, liefert getHitTestResultsForTransientInput() einfach ein leeres Array. Es gibt keinen Fehler, deshalb bleibt ein Tippfehler leicht unbemerkt.
  • Die Ergebnisse gelten nur für den aktuellen Frame. Speichern Sie keine XRFrame-Objekte oder Posen über den Callback hinaus. Für dauerhaft verankerte Objekte eignen sich Anker (XRHitTestResult.createAnchor()).
  • Wie viele Hit-Test-Quellen gleichzeitig erlaubt sind, hängt vom Gerät ab. Rufen Sie cancel() auf, wenn Sie eine Quelle nicht mehr brauchen. Fordern Sie nicht pro Berührung eine neue Quelle an, denn das ist genau der Fall, für den diese Methode gedacht ist.
  • entityTypes: ["mesh"] wird nicht von allen Geräten unterstützt. Nicht unterstützte Typen werden ignoriert oder führen zu einer Ablehnung.