Signatur
Beschreibung
Die Eigenschaft anchorSpace eines XRAnchor-Objekts gibt ein XRSpace zurück, das die Position und Ausrichtung des Ankers in der realen Welt darstellt. Anker sind Punkte, die das AR-System über die Zeit verfolgt und bei Bedarf nachjustiert, wenn sich sein Verständnis der Umgebung verbessert. Deshalb verschiebt sich ein virtuelles Objekt, das an einem Anker befestigt ist, nicht mit, wenn das System seine Weltkarte korrigiert.
Das XRSpace selbst enthält keine Koordinaten. Die eigentliche Pose bekommt man in jedem Animationsframe über XRFrame.getPose(anchor.anchorSpace, referenceSpace). Das Ergebnis ist ein XRPose, dessen transform (Position, Orientierung, Matrix) man direkt für das Rendering, z. B. in WebGL oder Three.js, verwenden kann.
Typischer Ablauf: Man fordert beim Sessionstart das Feature "anchors" an, erstellt über XRFrame.createAnchor() oder XRHitTestResult.createAnchor() einen Anker und liest danach in jedem Frame für alle verfolgten Anker (XRFrame.trackedAnchors) die Pose über anchorSpace aus.
Rückgabewert
XRSpace-Objekt, das den Koordinatenraum des Ankers darstellt. Man kann es an XRFrame.getPose() übergeben, um die Pose zu bestimmen.Beispiele
Anker per Hit-Test erzeugen und Pose pro Frame auslesen
const session = await navigator.xr.requestSession('immersive-ar', {
requiredFeatures: ['anchors', 'hit-test']
});
const refSpace = await session.requestReferenceSpace('local');
const viewerSpace = await session.requestReferenceSpace('viewer');
const hitSource = await session.requestHitTestSource({ space: viewerSpace });
let anchor = null;
const onFrame = async (time, frame) => {
session.requestAnimationFrame(onFrame);
if (!anchor) {
const hits = frame.getHitTestResults(hitSource);
if (hits.length > 0) {
anchor = await hits[0].createAnchor();
}
return;
}
// Pose des Ankers relativ zum Referenzraum
const pose = frame.getPose(anchor.anchorSpace, refSpace);
if (pose) {
const { x, y, z } = pose.transform.position;
console.log(`Anker bei ${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`);
}
};
session.requestAnimationFrame(onFrame);
Alle verfolgten Anker rendern
const models = new Map(); // XRAnchor -> 3D-Objekt (z. B. Three.js Mesh)
const renderAnchors = (frame, refSpace) => {
for (const anchor of frame.trackedAnchors) {
const pose = frame.getPose(anchor.anchorSpace, refSpace);
const model = models.get(anchor);
if (!pose || !model) continue;
// Matrix direkt auf das Modell übertragen
model.matrix.fromArray(pose.transform.matrix);
model.matrixAutoUpdate = false;
model.visible = true;
}
};
Anker an einer festen Position vor dem Nutzer anlegen
const placeAnchor = async (frame, refSpace) => {
// 1 m vor dem Ursprung des Referenzraums
const transform = new XRRigidTransform({ x: 0, y: 0, z: -1 });
const anchor = await frame.createAnchor(transform, refSpace);
console.log(anchor.anchorSpace instanceof XRSpace);
return anchor;
};
// Wichtig · Fallstricke
- Experimentell: Das WebXR Anchors Module ist kein fertiger Standard. Unterstützt wird es vor allem in Chromium-Browsern unter Android mit ARCore und im Meta Quest Browser. Firefox und Safari unterstützen es nicht. Es funktioniert nur in einem sicheren Kontext (HTTPS) und nur, wenn beim Sessionstart das Feature
"anchors"angefordert wurde. frame.getPose(anchor.anchorSpace, refSpace)kannnullliefern, etwa wenn das Tracking vorübergehend verloren geht. Diesen Fall immer abfangen.- Die Pose kann sich von Frame zu Frame ändern, weil das System den Anker nachjustiert. Sie muss deshalb in jedem Frame neu abgefragt und darf nicht einmalig zwischengespeichert werden.
- Nach
anchor.delete()wird der Anker nicht mehr verfolgt. Ein Zugriff aufanchorSpacelöst dann einenInvalidStateErroraus. getPose()darf nur innerhalb desrequestAnimationFrame-Callbacks mit dem aktivenXRFrameaufgerufen werden.