Start · Sprachen · JavaScript · Referenz · XRFrame.getPose()

XRFrame.getPose()

Methode

Gibt die Pose (Position und Orientierung) eines <code>XRSpace</code> relativ zu einem Basis-Raum als <code>XRPose</code> zurück, oder <code>null</code>, wenn sie nicht ermittelbar ist.

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

Signatur

XRFrame.prototype.getPose(space, baseSpace)

Beschreibung

getPose() berechnet für den Zeitpunkt des aktuellen XRFrame, wo sich ein Raum (XRSpace) im Verhältnis zu einem anderen Raum befindet. Das Ergebnis ist ein XRPose-Objekt mit einer transform (XRRigidTransform mit position, orientation und matrix) und dem Flag emulatedPosition.

Typische Einsatzfälle sind das Verfolgen von Eingabegeräten: Über inputSource.gripSpace ermittelt man, wo ein Controller in der Hand liegt (um z. B. ein 3D-Modell daran zu hängen), über inputSource.targetRaySpace den Zeigestrahl für Auswahl und Raycasting. Auch Anker (XRAnchor.anchorSpace) oder die Gelenke der Handverfolgung (dafür gibt es zusätzlich getJointPose()) werden so abgefragt.

Für die Pose des Betrachters selbst (Kopf bzw. Augen) nutzt man stattdessen XRFrame.getViewerPose(), das zusätzlich die einzelnen XRViews für das Rendern liefert. Als baseSpace übergibt man in der Regel den Referenzraum, der auch zum Rendern verwendet wird, etwa den von requestReferenceSpace("local-floor").

Die Methode darf nur mit einem aktiven Frame aufgerufen werden, also innerhalb des Callbacks von XRSession.requestAnimationFrame() oder eines Eingabe-Events wie select. Kann das Gerät die Beziehung zwischen den beiden Räumen gerade nicht bestimmen (z. B. weil der Controller die Verfolgung verloren hat), gibt sie null zurück.

Parameter

Name Typ Default Beschreibung
$space Pflicht XRSpace — Der Raum, dessen Pose gesucht ist – z. B. inputSource.gripSpace, inputSource.targetRaySpace oder anchor.anchorSpace.
$baseSpace Pflicht XRSpace — Der Bezugsraum, in dessen Koordinatensystem die Pose ausgedrückt wird, üblicherweise ein XRReferenceSpace.

Rückgabewert

Typ
XRPose | null
Beschreibung
Ein XRPose mit transform (Position in Metern, Orientierung als Quaternion, 4×4-matrix) und emulatedPosition; optional auch linearVelocity/angularVelocity. null, wenn die Pose aktuell nicht bestimmbar ist.

Beispiele

Controller-Position in jedem Frame auslesen

const session = await navigator.xr.requestSession('immersive-vr');
const refSpace = await session.requestReferenceSpace('local-floor');

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

  for (const source of frame.session.inputSources) {
    if (!source.gripSpace) continue; // z. B. Blick-Eingabe ohne Grip
    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);
right: 0.21, 1.05, -0.34 left: -0.18, 1.02, -0.30

Zeigestrahl beim select-Event auswerten

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

  const origin = rayPose.transform.position;
  // Blickrichtung: -Z-Achse der Transformationsmatrix
  const m = rayPose.transform.matrix;
  const direction = { x: -m[8], y: -m[9], z: -m[10] };
  console.log('Strahl von', origin, 'Richtung', direction);
});
Strahl von DOMPointReadOnly {x: 0.2, y: 1.1, z: -0.3, w: 1} Richtung {x: 0.01, y: -0.12, z: -0.99}

Matrix direkt an ein 3D-Modell übergeben (Three.js)

const controllerMesh = new THREE.Mesh(
  new THREE.BoxGeometry(0.05, 0.05, 0.15),
  new THREE.MeshStandardMaterial({ color: 0x3399ff })
);
controllerMesh.matrixAutoUpdate = false;
scene.add(controllerMesh);

const updateController = (frame, source) => {
  const pose = frame.getPose(source.gripSpace, refSpace);
  controllerMesh.visible = pose !== null;
  if (pose) {
    controllerMesh.matrix.fromArray(pose.transform.matrix);
    // Hinweis bei geschätzter Position anzeigen
    controllerMesh.material.opacity = pose.emulatedPosition ? 0.5 : 1;
  }
};

// Wichtig · Fallstricke

  • Immer auf null prüfen: Verliert das Gerät die Verfolgung, liefert getPose() null – ohne Prüfung folgt ein TypeError beim Zugriff auf transform.
  • Nur mit aktivem Frame: Wird ein XRFrame außerhalb seines Callbacks aufgerufen (z. B. in einem gespeicherten Verweis oder nach await), wird eine InvalidStateError-DOMException geworfen. Frames nicht zwischenspeichern.
  • Beide Räume müssen zur selben XRSession gehören, sonst wird ebenfalls eine InvalidStateError geworfen.
  • emulatedPosition === true bedeutet, dass die Position nur geschätzt ist (z. B. bei 3DoF-Controllern). Die Orientierung ist dann verlässlich, die Position nicht.
  • gripSpace kann undefined sein (z. B. bei Blick- oder Bildschirm-Eingabe); targetRaySpace ist immer vorhanden.
  • Für die Kopfpose getViewerPose() verwenden, für Handgelenke getJointPose().
  • Kompatibilität: WebXR erfordert einen sicheren Kontext (HTTPS) und wird von Chromium-basierten Browsern und dem Meta Quest Browser unterstützt; Firefox und Desktop-Safari unterstützen es nicht (Safari auf Apple Vision Pro dagegen schon). Zum Testen am Desktop eignet sich ein WebXR-Emulator.