Signatur
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
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 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));
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);
});
// Wichtig · Fallstricke
- Veraltet: Die WebVR-API, zu der
VRPosegehö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 übernimmtXRRigidTransform.orientationdiese Aufgabe, und zwar alsDOMPointReadOnlystatt alsFloat32Array. - Auf
nullprüfen: Den Wert immer vor der Nutzung prüfen. Nach einem Trackingverlust oder bei Geräten ohne Orientierungssensor ist ernull. - Reihenfolge der Werte: Die Werte stehen in der Reihenfolge
[x, y, z, w], der Realteilwkommt also zuletzt. Manche Mathematik-Bibliotheken erwartenwan 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. mitFloat32Array.from(orientation). - Nur sicherer Kontext: Die API setzt HTTPS und eine Nutzerinteraktion voraus, bevor die Darstellung gestartet werden kann.