Signatur
Beschreibung
Die Eigenschaft emulatedPosition eines XRPose-Objekts (und damit auch von XRViewerPose) zeigt, ob der Positionsanteil von transform – also transform.position – echt gemessen wurde. Bei false kommt die Position direkt vom Positions-Tracking des Geräts, etwa durch Inside-out-Kameras oder externe Basisstationen. Bei true ist sie simuliert oder geschätzt, zum Beispiel über ein Nackenmodell, eine angenommene Armlänge oder mithilfe von Beschleunigungssensoren.
Typische Fälle für true sind Geräte mit 3DoF (drei Freiheitsgrade, nur Drehung), etwa einfache Smartphone-Halterungen oder 3DoF-Controller. Es kann aber auch vorübergehend passieren, wenn ein 6DoF-System das Tracking verliert, weil es zu dunkel ist, eine Kamera verdeckt ist oder ein Controller das Sichtfeld verlässt. Dann meldet der Browser oft die letzte bekannte Position oder eine Schätzung und setzt emulatedPosition auf true.
Die Eigenschaft sagt nur etwas über die Position aus. Die Ausrichtung (transform.orientation) gilt grundsätzlich als echt gemessen. Nützlich ist der Wert, um die Oberfläche anzupassen: Man kann einen Hinweis „Tracking verloren“ anzeigen, Raum-Interaktionen wie Teleport oder Greifen abschalten oder auf eine Steuerung ausweichen, die nur die Blickrichtung braucht.
Rückgabewert
true, wenn die Position simuliert oder geschätzt ist. false, wenn sie direkt vom Positions-Tracking des Geräts stammt.Beispiele
Tracking-Verlust im Render-Loop erkennen
const session = await navigator.xr.requestSession('immersive-vr');
const refSpace = await session.requestReferenceSpace('local');
const hinweis = document.querySelector('#tracking-hinweis');
const onFrame = (time, frame) => {
session.requestAnimationFrame(onFrame);
const viewerPose = frame.getViewerPose(refSpace);
if (!viewerPose) return; // noch keine Pose verfügbar
// Hinweis nur zeigen, wenn die Kopfposition geschätzt ist
hinweis.hidden = !viewerPose.emulatedPosition;
// ... Szene mit viewerPose.views rendern
};
session.requestAnimationFrame(onFrame);
Controller-Interaktion bei geschätzter Position einschränken
const updateControllers = (frame, refSpace) => {
for (const source of frame.session.inputSources) {
if (!source.gripSpace) continue;
const gripPose = frame.getPose(source.gripSpace, refSpace);
if (!gripPose) continue;
if (gripPose.emulatedPosition) {
// 3DoF-Controller oder Tracking verloren: nur Zeigestrahl erlauben
console.log(`${source.handedness}: Position geschätzt – Greifen deaktiviert`);
} else {
const { x, y, z } = gripPose.transform.position;
console.log(`${source.handedness}: echte Position`, x.toFixed(2), y.toFixed(2), z.toFixed(2));
}
}
};
Wechsel des Tracking-Status protokollieren
let letzterStatus = null;
const pruefeTracking = (pose) => {
if (!pose || pose.emulatedPosition === letzterStatus) return;
letzterStatus = pose.emulatedPosition;
console.log(letzterStatus
? 'Positions-Tracking verloren – Position wird geschätzt'
: 'Positions-Tracking wiederhergestellt');
};
// Aufruf im Frame-Callback: pruefeTracking(frame.getViewerPose(refSpace));
// Wichtig · Fallstricke
- Nur die Position:
emulatedPositionsagt nichts über die Qualität der Ausrichtung aus.transform.orientationgilt immer als gemessen. - Kann sich pro Frame ändern: Der Wert ist nicht fest pro Gerät. Er kann während einer Sitzung zwischen
trueundfalsewechseln und sollte deshalb bei jedem Frame neu geprüft werden. Wenn du ihn nur einmal zwischenspeicherst, übersiehst du Tracking-Verluste. null-Posen:XRFrame.getPose()undgetViewerPose()könnennullliefern, wenn gar keine Pose bestimmt werden kann. Prüfe das vorher, sonst gibt es einenTypeError.- Kein Ersatz für die Wahl des Referenzraums: Ein 3DoF-Gerät kann
'local'anbieten, meldet aber eine geschätzte Position. Für Raum-Anwendungen fordere zusätzlich'local-floor'oder'bounded-floor'an. - Kompatibilität: WebXR gibt es nur in sicheren Kontexten (HTTPS). Es wird von Chromium-Browsern und XR-Headset-Browsern unterstützt, nicht von Firefox und nicht von Safari auf dem Desktop. Prüfe die Verfügbarkeit mit
navigator.xr?.isSessionSupported().