Start · Sprachen · JavaScript · Referenz · XRInputSource.targetRaySpace

XRInputSource.targetRaySpace

Eigenschaft

Schreibgeschützte Eigenschaft, die ein <code>XRSpace</code> liefert, dessen Ursprung und Ausrichtung den Zielstrahl (Zeigestrahl) der Eingabequelle beschreiben.

seit JavaScript WebXR Device API – Chromium-Browser (Chrome/Edge 7 Kategorie: webapi

Signatur

XRInputSource.targetRaySpace

Beschreibung

Die Eigenschaft targetRaySpace eines XRInputSource-Objekts liefert ein XRSpace. Dessen Ursprung liegt am Ausgangspunkt des Zielstrahls, also z. B. an der Spitze eines Controllers, am Kopf des Nutzers bei Blickeingabe oder am Berührungspunkt auf einem Bildschirm. Der Strahl zeigt entlang der negativen Z-Achse dieses Raums.

Diesen Raum braucht man, um herauszufinden, worauf der Nutzer zeigt, etwa für Raycasting, Laserpointer-Darstellung, Hit-Tests oder Auswahl-Interaktionen. Die eigentliche Pose holt man sich in jedem Frame mit XRFrame.getPose(inputSource.targetRaySpace, referenceSpace). Das Ergebnis ist ein XRPose, dessen transform Position und Orientierung des Strahls relativ zum gewählten Referenzraum enthält.

Wie der Strahl zu deuten ist, hängt von XRInputSource.targetRayMode ab:

  • "tracked-pointer": Der Strahl geht von einem getrackten Controller oder einer Hand aus.
  • "gaze": Der Strahl kommt aus der Blickrichtung des Betrachters.
  • "screen": Der Strahl entsteht durch eine Berührung auf einem 2D-Bildschirm (Handheld-AR).
  • "transient-pointer": Kurzlebige Eingaben, z. B. Blick plus Fingertipp auf der Apple Vision Pro.

Wo Controller-Modelle gezeichnet werden sollen, ist dagegen gripSpace zuständig.

Rückgabewert

Typ
XRSpace
Beschreibung
Ein XRSpace, dessen Ursprung am Startpunkt des Zielstrahls liegt und dessen negative Z-Achse in Zeigerichtung weist. Die Eigenschaft ist nie null. Eine konkrete Pose bekommt man erst über XRFrame.getPose().

Beispiele

Zielstrahl-Pose in jedem Frame auslesen

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

  for (const source of session.inputSources) {
    const pose = frame.getPose(source.targetRaySpace, refSpace);
    if (!pose) continue; // Tracking gerade verloren

    const { position, orientation } = pose.transform;
    console.log(
      `${source.handedness}-Strahl bei`,
      position.x.toFixed(2), position.y.toFixed(2), position.z.toFixed(2)
    );
  }
};

const session = await navigator.xr.requestSession('immersive-vr');
const refSpace = await session.requestReferenceSpace('local-floor');
session.requestAnimationFrame(onXRFrame);
right-Strahl bei 0.21 1.12 -0.35

Richtungsvektor des Strahls für Raycasting berechnen

// Die Strahlrichtung ist die -Z-Achse der Transformationsmatrix
const getRay = (frame, source, refSpace) => {
  const pose = frame.getPose(source.targetRaySpace, refSpace);
  if (!pose) return null;

  const m = pose.transform.matrix; // Float32Array(16), spaltenweise
  const origin = { x: m[12], y: m[13], z: m[14] };
  const direction = { x: -m[8], y: -m[9], z: -m[10] };
  return { origin, direction };
};

// Kürzer: XRRay direkt aus der Transformation erzeugen
const getXRRay = (frame, source, refSpace) => {
  const pose = frame.getPose(source.targetRaySpace, refSpace);
  return pose ? new XRRay(pose.transform) : null;
};

Auswahl per select-Event auswerten

session.addEventListener('select', (event) => {
  const { frame, inputSource } = event;
  const pose = frame.getPose(inputSource.targetRaySpace, refSpace);
  if (!pose) return;

  console.log(`Auswahl mit Modus "${inputSource.targetRayMode}"`);
  pickObjectAlongRay(pose.transform); // eigene Szenenfunktion
});
Auswahl mit Modus "tracked-pointer"

Hit-Test-Quelle für AR-Tipps anlegen

session.addEventListener('inputsourceschange', async ({ added }) => {
  for (const source of added) {
    if (source.targetRayMode !== 'screen') continue;
    // Hit-Test entlang des Berührungsstrahls
    const hitTestSource = await session.requestHitTestSourceForTransientInput({
      profile: 'generic-touchscreen'
    });
    console.log('Hit-Test für Bildschirm-Eingaben aktiv', hitTestSource);
  }
});
Hit-Test für Bildschirm-Eingaben aktiv XRTransientInputHitTestSource {…}

// Wichtig · Fallstricke

  • Keine direkten Koordinaten: targetRaySpace enthält selbst keine Position. Man muss immer frame.getPose() aufrufen, und das nur innerhalb eines requestAnimationFrame-Rückrufs oder eines Eingabe-Events mit gültigem frame.
  • getPose() kann null liefern, etwa wenn das Tracking verloren geht oder der Controller außer Sicht ist. Diesen Fall immer abfangen.
  • Richtung: Der Strahl zeigt entlang −Z, nicht +Z. Ein Vorzeichenfehler ist ein häufiger Grund für „rückwärts“ zeigende Laserpointer.
  • Nicht mit gripSpace verwechseln: Der Zielstrahl ist oft gegenüber dem Griff geneigt. Controller-Modelle gehören in den gripSpace, Zeigestrahlen in den targetRaySpace.
  • Bei "screen"- und "transient-pointer"-Quellen existiert die Eingabequelle nur während der Berührung bzw. Geste. Das Objekt nicht dauerhaft zwischenspeichern.
  • Kompatibilität: WebXR gibt es nur in sicheren Kontexten (HTTPS) und vor allem in Chromium-Browsern und XR-Headset-Browsern. Firefox und Safari auf dem Desktop unterstützen die API nicht. Vorher mit navigator.xr?.isSessionSupported() prüfen.