Signatur
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
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);
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
});
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);
}
});
// Wichtig · Fallstricke
- Keine direkten Koordinaten:
targetRaySpaceenthält selbst keine Position. Man muss immerframe.getPose()aufrufen, und das nur innerhalb einesrequestAnimationFrame-Rückrufs oder eines Eingabe-Events mit gültigemframe. getPose()kannnullliefern, 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
gripSpaceverwechseln: Der Zielstrahl ist oft gegenüber dem Griff geneigt. Controller-Modelle gehören in dengripSpace, Zeigestrahlen in dentargetRaySpace. - 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.