Signatur
Beschreibung
Die Eigenschaft angularVelocity eines XRPose-Objekts gibt an, wie schnell und um welche Achse sich ein verfolgtes Objekt (Headset, Controller, Hand) gerade dreht. Der Wert ist ein DOMPointReadOnly. Die Komponenten x, y und z bilden einen Vektor: Seine Richtung ist die Drehachse und seine Länge die Drehrate in Radiant pro Sekunde. Die Komponente w ist immer 0.
Der Vektor bezieht sich auf das Koordinatensystem des Basis-Raums, den du an XRFrame.getPose() oder XRFrame.getViewerPose() übergibst. Dieselbe physische Bewegung kann also je nach Referenzraum unterschiedliche Werte ergeben.
Typische Einsatzfälle sind physikalisch glaubwürdiges Werfen von Objekten (Drall beim Loslassen), Bewegungsvorhersage, Unschärfe-Effekte bei Bewegung oder Gesten wie schnelles Drehen des Handgelenks. Zusammen mit XRPose.linearVelocity lässt sich der komplette Bewegungszustand eines Controllers beschreiben.
Kann das Gerät oder der Browser die Winkelgeschwindigkeit nicht ermitteln, ist der Wert null. Prüfe das deshalb immer, bevor du auf die Werte zugreifst.
Rückgabewert
DOMPointReadOnly: x/y/z geben die Drehachse an, die Länge des Vektors ist die Drehrate in rad/s, und w ist 0. Ist keine Winkelgeschwindigkeit verfügbar, ist der Wert null.Beispiele
Drehrate des Headsets pro Frame auslesen
const session = await navigator.xr.requestSession('immersive-vr');
const refSpace = await session.requestReferenceSpace('local');
const onFrame = (time, frame) => {
const pose = frame.getViewerPose(refSpace);
const av = pose?.angularVelocity;
if (av) {
// Die Länge des Vektors ist die Drehrate in rad/s
const radPerSec = Math.hypot(av.x, av.y, av.z);
const degPerSec = radPerSec * 180 / Math.PI;
console.log(`Kopfdrehung: ${degPerSec.toFixed(1)} °/s`);
}
frame.session.requestAnimationFrame(onFrame);
};
session.requestAnimationFrame(onFrame);
Drall beim Werfen eines Objekts übernehmen
// Voraussetzung: session und refSpace aus einer laufenden XR-Sitzung
const thrownObject = { velocity: [0, 0, 0], spin: [0, 0, 0] };
session.addEventListener('selectend', (event) => {
const { frame, inputSource } = event;
if (!inputSource.gripSpace) return;
const pose = frame.getPose(inputSource.gripSpace, refSpace);
if (!pose) return;
const lv = pose.linearVelocity;
const av = pose.angularVelocity;
thrownObject.velocity = lv ? [lv.x, lv.y, lv.z] : [0, 0, 0];
thrownObject.spin = av ? [av.x, av.y, av.z] : [0, 0, 0];
console.log('Wurf mit Drall:', thrownObject.spin);
});
Drehachse normieren und schnelle Drehgeste erkennen
const SCHWELLE_RAD_S = 6; // ungefähr 344 °/s
const analyseDrehung = (pose) => {
const av = pose.angularVelocity;
if (!av) return null;
const rate = Math.hypot(av.x, av.y, av.z);
if (rate === 0) return { rate: 0, achse: null, schnell: false };
const achse = { x: av.x / rate, y: av.y / rate, z: av.z / rate };
return { rate, achse, schnell: rate > SCHWELLE_RAD_S };
};
// Nutzung innerhalb des Frame-Callbacks:
// const info = analyseDrehung(frame.getPose(inputSource.gripSpace, refSpace));
// if (info?.schnell) console.log('Schnelle Drehgeste!', info.achse);
// Wichtig · Fallstricke
- Kann
nullsein: Viele Geräte und Laufzeitumgebungen liefern keine Geschwindigkeitsdaten. Plane immer einen Ersatzweg ein, z. B. die Differenz der Orientierung zwischen zwei Frames geteilt durch die Zeitdifferenz. - Kein Quaternion: Obwohl
DOMPointReadOnlyeinew-Komponente hat, ist der Wert ein Achsen-Raten-Vektor und keine Orientierung.wist immer0. Nutze den Wert nicht als Rotation fürXRRigidTransform. - Bezugsraum beachten: Der Vektor gilt im Koordinatensystem des Basis-Raums, nicht im lokalen Raum des Objekts. Für eine Drehung um die eigene Achse musst du ihn mit der inversen Orientierung der Pose umrechnen.
- Einheit: Radiant pro Sekunde, nicht pro Frame. Für die Integration musst du mit der Zeit zwischen den Frames multiplizieren.
- Kompatibilität: Die Eigenschaft ist experimentell und bisher nur in Chromium-basierten Browsern verfügbar, nicht in Firefox und Safari. WebXR läuft zudem nur in sicheren Kontexten (HTTPS). Prüfe die Unterstützung mit
'angularVelocity' in XRPose.prototype.