Signatur
Beschreibung
XRSpace ist eine abstrakte Schnittstelle der WebXR Device API. Sie steht für ein virtuelles Koordinatensystem, dessen Ursprung an einer physischen Position in der Umgebung festgemacht ist, die das XR-Gerät verfolgt. Eigene Eigenschaften oder Methoden hat sie nicht. Sie erbt nur von EventTarget und dient als gemeinsamer Typ für alle Räume, die man den Pose-Methoden von XRFrame übergeben kann.
Instanzen erzeugt man nie direkt. Man bekommt sie immer über andere APIs, etwa:
XRReferenceSpaceundXRBoundedReferenceSpace: überXRSession.requestReferenceSpace()inputSource.targetRaySpaceundinputSource.gripSpace: Räume der Eingabequellen, zum Beispiel für Zeigestrahl und Griffposition von ControllernXRJointSpace: Gelenke der Handverfolgung (Hand Input Module)XRAnchor.anchorSpace: räumliche Anker (Anchors Module)
Wofür man das braucht: Mit XRFrame.getPose(space, baseSpace) berechnet man in jedem Frame, wo sich ein Raum relativ zu einem anderen befindet. Das Ergebnis ist eine XRPose mit Position, Ausrichtung und Transformationsmatrix. So setzt man zum Beispiel ein 3D-Modell eines Controllers an die richtige Stelle der Szene oder schickt einen Zeigestrahl ins Hit-Testing.
Zu beachten: Posen gelten nur für den jeweiligen Frame und können null sein, wenn das Gerät die Verfolgung verloren hat. Deshalb fragt man Posen immer innerhalb des requestAnimationFrame-Callbacks der Sitzung ab und prüft das Ergebnis.
Rückgabewert
XRSession.requestReferenceSpace() oder XRInputSource.targetRaySpace/gripSpace.Beispiele
XRSpace über einen Referenzraum erhalten
// Muss aus einer Benutzeraktion heraus aufgerufen werden (z. B. Klick)
const startXR = async () => {
if (!navigator.xr || !(await navigator.xr.isSessionSupported('immersive-vr'))) {
console.log('WebXR (immersive-vr) wird nicht unterstützt');
return;
}
const session = await navigator.xr.requestSession('immersive-vr');
const refSpace = await session.requestReferenceSpace('local-floor');
console.log(refSpace instanceof XRSpace); // true
console.log(refSpace instanceof XRReferenceSpace); // true
return { session, refSpace };
};
document.querySelector('#enter-vr').addEventListener('click', startXR);
Controller-Position pro Frame über gripSpace ermitteln
const runLoop = (session, refSpace) => {
const onFrame = (time, frame) => {
session.requestAnimationFrame(onFrame);
for (const source of session.inputSources) {
// gripSpace ist ein XRSpace (kann bei reinen Blick-Eingaben fehlen)
if (!source.gripSpace) continue;
const pose = frame.getPose(source.gripSpace, refSpace);
if (pose) {
const { x, y, z } = pose.transform.position;
console.log(`${source.handedness}: ${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`);
}
}
};
session.requestAnimationFrame(onFrame);
};
Hilfsfunktion: beliebigen XRSpace relativ zu einem Basisraum abfragen
// Funktioniert mit jedem XRSpace: Referenzraum, targetRaySpace, XRJointSpace, anchorSpace …
const getMatrix = (frame, space, baseSpace) => {
const pose = frame.getPose(space, baseSpace);
if (!pose) return null; // Verfolgung verloren
return {
matrix: pose.transform.matrix, // Float32Array(16), spaltenweise
emulated: pose.emulatedPosition // true = Position nur geschätzt
};
};
// Im Frame-Callback:
// const result = getMatrix(frame, inputSource.targetRaySpace, refSpace);
// if (result) laserMesh.matrix.fromArray(result.matrix);
// Wichtig · Fallstricke
- Abstrakt:
new XRSpace()wirft einenTypeError. Instanzen bekommt man nur über die WebXR-APIs. - Posen können
nullsein:XRFrame.getPose()gibtnullzurück, wenn die Verfolgung verloren geht, etwa weil ein Controller verdeckt ist. Deshalb immer prüfen. - Nur im aktiven Frame gültig:
getPose()darf man nur imrequestAnimationFrame-Callback der Sitzung aufrufen, sonst gibt es einenInvalidStateError. Beide Räume müssen außerdem zu derselbenXRSessiongehören. gripSpaceist optional: Bei Eingaben ohne physisches Gerät (Blick- oder Bildschirm-Eingabe) istgripSpaceundefined. EinentargetRaySpacehat dagegen jede Eingabequelle.- Sicherer Kontext: WebXR gibt es nur über HTTPS. Immersive Sitzungen brauchen eine Benutzeraktion und werden über die Permissions Policy
xr-spatial-trackinggesteuert. - Browser-Kompatibilität: Unterstützt in Chromium-Browsern (Chrome/Edge ab 79, Android) und im Meta Quest Browser. Firefox und Desktop-Safari unterstützen WebXR nicht, visionOS-Safari nur teilweise. Vorher mit
navigator.xr?.isSessionSupported()prüfen, für die Entwicklung eignet sich der WebXR-Emulator oder ein Polyfill. - Datenschutz: Posedaten können Rückschlüsse auf Körpermaße und Bewegungen erlauben. Deshalb Posen nicht ungefragt an Server übertragen.