Start · Sprachen · JavaScript · Referenz · VRPose.orientation

VRPose.orientation

Eigenschaft

Schreibgeschützte Eigenschaft, die die aktuelle Ausrichtung des VR-Sensors als Quaternion <code>[x, y, z, w]</code> in einem <code>Float32Array</code> liefert, oder <code>null</code>.

seit JavaScript Veraltet (WebVR 1.1). Nie Baseline, durch WebXR er deprecated seit ja Kategorie: webapi

Signatur

VRPose.orientation

Beschreibung

Die Eigenschaft orientation des Interfaces VRPose gibt die Ausrichtung eines VR-Geräts an, zum Beispiel die Kopfhaltung beim Tragen eines Headsets. Das Ergebnis ist ein Quaternion in der Form [x, y, z, w], also ein Float32Array mit vier Elementen. Das Quaternion beschreibt die Drehung gegenüber der Grundausrichtung. In der Grundausrichtung zeigt das Gerät entlang der negativen Z-Achse nach vorn, und die Y-Achse zeigt nach oben. Keine Drehung entspricht [0, 0, 0, 1].

Ein VRPose bekommt man in der Regel über VRFrameData.pose. Dafür ruft man in jedem Frame VRDisplay.getFrameData() auf. Die Ausrichtung wird vor allem gebraucht, um die Kamera einer 3D-Szene (z. B. in WebGL oder three.js) an die Kopfbewegung anzupassen. Man kann sie auch nutzen, um Blickrichtung oder Neigung auszuwerten, etwa für eine Auswahl per Blick.

Der Wert kann null sein, wenn das Gerät gerade keine Ausrichtung liefern kann. Das passiert z. B., wenn das Tracking verloren geht oder kein Orientierungssensor vorhanden ist. Ob ein Gerät seine Ausrichtung überhaupt melden kann, zeigt VRDisplay.capabilities.hasOrientation.

Rückgabewert

Typ
Float32Array | null
Beschreibung
Ein Float32Array mit vier Werten [x, y, z, w], die ein Einheitsquaternion bilden. Wenn keine Ausrichtung verfügbar ist, ist der Wert null.

Beispiele

Ausrichtung pro Frame auslesen

// Nur in Browsern mit WebVR 1.1 (z. B. altes Firefox oder Oculus Browser)
const frameData = new VRFrameData();

const start = async () => {
  const displays = await navigator.getVRDisplays();
  if (displays.length === 0) {
    console.log('Kein VR-Gerät gefunden');
    return;
  }
  const vrDisplay = displays[0];

  const loop = () => {
    vrDisplay.getFrameData(frameData);
    const { orientation } = frameData.pose;
    if (orientation) {
      const [x, y, z, w] = orientation;
      console.log(`Quaternion: x=${x.toFixed(3)} y=${y.toFixed(3)} z=${z.toFixed(3)} w=${w.toFixed(3)}`);
    }
    vrDisplay.requestAnimationFrame(loop);
  };
  vrDisplay.requestAnimationFrame(loop);
};

start();
Quaternion: x=0.012 y=-0.383 z=0.004 w=0.924

Quaternion in Gier- und Nickwinkel umrechnen

// Wandelt [x, y, z, w] in Grad um (Y nach oben, -Z nach vorn)
const quatToYawPitch = ([x, y, z, w]) => {
  const yaw = Math.atan2(2 * (w * y + x * z), 1 - 2 * (y * y + x * x));
  const sinPitch = Math.max(-1, Math.min(1, 2 * (w * x - y * z)));
  const pitch = Math.asin(sinPitch);
  const toDeg = (rad) => Math.round(rad * 180 / Math.PI);
  return { yaw: toDeg(yaw), pitch: toDeg(pitch) };
};

// Beispielwert: Kopf um 45° nach links gedreht
const orientation = new Float32Array([0, 0.3827, 0, 0.9239]);
console.log(quatToYawPitch(orientation));
{ yaw: 45, pitch: 0 }

Fallback bei null und Übergabe an eine three.js-Kamera

// Setzt voraus, dass three.js als THREE eingebunden ist
const camera = new THREE.PerspectiveCamera(75, innerWidth / innerHeight, 0.1, 100);
const frameData = new VRFrameData();

const updateCamera = (vrDisplay) => {
  vrDisplay.getFrameData(frameData);
  const o = frameData.pose.orientation;
  if (o === null) {
    // Tracking verloren: letzte bekannte Ausrichtung beibehalten
    return;
  }
  camera.quaternion.fromArray(o);
};

Moderner Ersatz mit WebXR

// WebXR: XRRigidTransform.orientation ist ein DOMPointReadOnly
const session = await navigator.xr.requestSession('immersive-vr');
const refSpace = await session.requestReferenceSpace('local');

session.requestAnimationFrame(function onFrame(time, frame) {
  const pose = frame.getViewerPose(refSpace);
  if (pose) {
    const { x, y, z, w } = pose.transform.orientation;
    console.log([x, y, z, w]);
  }
  session.requestAnimationFrame(onFrame);
});
[0, 0.3827, 0, 0.9239]

// Wichtig · Fallstricke

  • Veraltet: Die WebVR-API, zu der VRPose gehört, ist abgelöst. Aktuelle Browser unterstützen sie praktisch nicht mehr. Chrome hat sie nie standardmäßig aktiviert, und Firefox hat sie entfernt. Für neue Projekte ist WebXR vorgesehen. Dort übernimmt XRRigidTransform.orientation diese Aufgabe, und zwar als DOMPointReadOnly statt als Float32Array.
  • Auf null prüfen: Den Wert immer vor der Nutzung prüfen. Nach einem Trackingverlust oder bei Geräten ohne Orientierungssensor ist er null.
  • Reihenfolge der Werte: Die Werte stehen in der Reihenfolge [x, y, z, w], der Realteil w kommt also zuletzt. Manche Mathematik-Bibliotheken erwarten w an erster Stelle.
  • Werte kopieren: Das Array kann bei jedem getFrameData()-Aufruf neu befüllt werden. Wer einen Wert aufheben will, sollte ihn kopieren, z. B. mit Float32Array.from(orientation).
  • Nur sicherer Kontext: Die API setzt HTTPS und eine Nutzerinteraktion voraus, bevor die Darstellung gestartet werden kann.