Signatur
Beschreibung
Die Eigenschaft orientation einer XRRigidTransform liefert die Rotationskomponente der Transformation als normalisiertes Quaternion (auch Einheitsquaternion oder Versor genannt). Der Wert ist ein DOMPointReadOnly: Die Felder x, y und z bilden den Vektoranteil, w ist der Skalaranteil. Die Länge des Quaternions ist immer 1.
Gebraucht wird die Eigenschaft vor allem, wenn du die Lage eines Headsets, eines Controllers oder eines Ankers in eine eigene 3D-Engine übernehmen willst, z. B. mit quaternion.set(x, y, z, w) in three.js oder in eine glMatrix-quat. Zusammen mit position beschreibt sie die komplette starre Transformation. Die vorberechnete 4×4-Matrix bekommst du über matrix.
Übergibst du beim Konstruktor new XRRigidTransform(position, orientation) ein Quaternion, das nicht normalisiert ist, normalisiert der Browser es automatisch. Lässt du den Parameter weg, gilt das Identitätsquaternion {x: 0, y: 0, z: 0, w: 1}, also „keine Drehung“. Die Eigenschaft ist schreibgeschützt. Für eine andere Rotation musst du eine neue XRRigidTransform erzeugen.
Rückgabewert
x, y, z (Vektoranteil) und w (Skalaranteil), das die Rotation der Transformation angibt.Beispiele
Transformation erzeugen und Orientierung auslesen
// 90° Drehung um die Y-Achse: q = (0, sin(45°), 0, cos(45°))
const half = Math.PI / 4;
const transform = new XRRigidTransform(
{ x: 0, y: 1.6, z: -2 },
{ x: 0, y: Math.sin(half), z: 0, w: Math.cos(half) }
);
const { x, y, z, w } = transform.orientation;
console.log(x, y.toFixed(4), z, w.toFixed(4));
Automatische Normalisierung
// Absichtlich nicht normalisiertes Quaternion
const t = new XRRigidTransform(undefined, { x: 0, y: 0, z: 2, w: 2 });
const o = t.orientation;
const length = Math.hypot(o.x, o.y, o.z, o.w);
console.log(o.z.toFixed(4), o.w.toFixed(4), length.toFixed(4));
Controller-Orientierung pro Frame in three.js übernehmen
const onXRFrame = (time, frame) => {
const session = frame.session;
session.requestAnimationFrame(onXRFrame);
for (const source of session.inputSources) {
if (!source.gripSpace) continue;
const pose = frame.getPose(source.gripSpace, refSpace);
if (!pose) continue;
const { position: p, orientation: q } = pose.transform;
controllerMesh.position.set(p.x, p.y, p.z);
controllerMesh.quaternion.set(q.x, q.y, q.z, q.w);
}
renderer.render(scene, camera);
};
session.requestAnimationFrame(onXRFrame);
Blickrichtung (Yaw) des Nutzers berechnen
// Yaw-Winkel aus Quaternion (Drehung um Y-Achse) in Grad
const yawFromQuaternion = ({ x, y, z, w }) =>
Math.atan2(2 * (w * y + x * z), 1 - 2 * (y * y + x * x)) * 180 / Math.PI;
const viewerPose = frame.getViewerPose(refSpace);
if (viewerPose) {
const yaw = yawFromQuaternion(viewerPose.transform.orientation);
console.log(`Blickrichtung: ${yaw.toFixed(1)}°`);
}
// Wichtig · Fallstricke
- Nur lesbar: Wenn du
transform.orientation.x = …setzt, hat das keine Wirkung. Das Objekt ist einDOMPointReadOnly. Für eine neue Rotation erzeugst du eine neueXRRigidTransform. - Reihenfolge der Komponenten: WebXR nutzt die Reihenfolge (x, y, z, w). Manche Bibliotheken erwarten w an erster Stelle, z. B. einige Mathematik- oder Physik-Engines. Prüfe die Reihenfolge beim Übergeben.
- Keine Euler-Winkel: Das Quaternion enthält keine Gradwerte. Für Winkel musst du selbst umrechnen, dabei ist die Achsenreihenfolge wichtig.
- Normalisierung: Der Konstruktor normalisiert übergebene Quaternionen. Ein Quaternion der Länge 0 führt zu einem
InvalidStateError. - q und −q: Beide beschreiben dieselbe Rotation. Deshalb können die Vorzeichen zwischen Frames springen. Beim Interpolieren (Slerp) solltest du das berücksichtigen.
- Kompatibilität: WebXR steht nur in einem sicheren Kontext (HTTPS) zur Verfügung. Unterstützt wird es vor allem von Chromium-basierten Browsern und XR-Browsern wie dem Meta Quest Browser. Firefox und Safari unterstützen WebXR auf dem Desktop nicht. Vorher mit
'xr' in navigatorprüfen.