Signatur
Beschreibung
Die schreibgeschützte Eigenschaft matrix eines XRRay-Objekts gibt eine 4×4-Transformationsmatrix zurück. Sie ist als Float32Array mit 16 Elementen in spaltenweiser Anordnung (column-major) gespeichert, genau wie es WebGL und Bibliotheken wie three.js oder gl-matrix erwarten.
Die Matrix beschreibt die Transformation eines Standardstrahls, der im Koordinatenursprung (0, 0, 0) beginnt und entlang der negativen Z-Achse (0, 0, -1) zeigt, auf den tatsächlichen Strahl, der durch XRRay.origin und XRRay.direction festgelegt ist. Die Matrix enthält also eine Rotation und eine Translation, aber keine Skalierung.
In der Praxis braucht man die Matrix vor allem, um geometrische Objekte an einem Strahl auszurichten. Typische Fälle sind ein „Laserpointer“ vom Controller aus, ein Zielkreuz entlang der Blickrichtung oder die Darstellung des Strahls einer Treffertest-Quelle (XRSession.requestHitTestSource()). Ein Modell, das in seinem lokalen Koordinatensystem entlang -Z modelliert ist, übernimmt mit dieser Matrix direkt Lage und Richtung des Strahls.
Rückgabewert
Float32Array mit 16 Werten in spaltenweiser Anordnung. Es beschreibt die Transformation vom Standardstrahl (Ursprung (0,0,0), Richtung -Z) auf den durch origin und direction festgelegten Strahl.Beispiele
Matrix eines einfachen Strahls auslesen
// Strahl ab (0, 1, 0), der geradeaus entlang -Z zeigt
const ray = new XRRay(
{ x: 0, y: 1, z: 0, w: 1 },
{ x: 0, y: 0, z: -1, w: 0 }
);
const m = ray.matrix;
console.log(m.length);
// Translationsanteil steht in den Elementen 12–14
console.log(m[12], m[13], m[14]);
Laserpointer-Mesh mit three.js ausrichten
import * as THREE from 'three';
// Zylinder, der entlang -Z zeigt (Länge 5 m)
const geometry = new THREE.CylinderGeometry(0.005, 0.005, 5, 8);
geometry.rotateX(-Math.PI / 2);
geometry.translate(0, 0, -2.5);
const laser = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ color: 0x00ffcc }));
laser.matrixAutoUpdate = false;
scene.add(laser);
const updateLaser = (origin, direction) => {
const ray = new XRRay(origin, direction);
// Spaltenweise Matrix direkt übernehmen
laser.matrix.fromArray(ray.matrix);
laser.matrixWorldNeedsUpdate = true;
};
updateLaser({ x: 0.2, y: 1.2, z: -0.3 }, { x: 0, y: -0.2, z: -1 });
Strahl aus einer Controller-Pose erzeugen und als WebGL-Uniform nutzen
const onXRFrame = (time, frame) => {
const session = frame.session;
session.requestAnimationFrame(onXRFrame);
for (const source of session.inputSources) {
const pose = frame.getPose(source.targetRaySpace, refSpace);
if (!pose) continue;
// XRRay aus einer XRRigidTransform erzeugen
const ray = new XRRay(pose.transform);
gl.useProgram(rayProgram);
// Float32Array kann direkt als mat4 übergeben werden
gl.uniformMatrix4fv(uModelMatrix, false, ray.matrix);
drawRayGeometry();
}
};
// Wichtig · Fallstricke
- Spaltenweise Anordnung: Die Translation steht in den Elementen
12,13und14, nicht in der letzten Zeile. Wer die Werte zeilenweise liest, erhält eine transponierte und damit falsche Matrix. - Nur lesen: Die Eigenschaft ist schreibgeschützt. Browser können dasselbe Array-Objekt zwischenspeichern und erneut zurückgeben. Das Array deshalb nicht verändern, sondern bei Bedarf mit
new Float32Array(ray.matrix)kopieren. - Normierte Richtung: Der Konstruktor normiert
directionautomatisch. Ein Richtungsvektor der Länge 0 oder einwungleich 0 beidirectionbzw. ungleich 1 beioriginlöst einenTypeErroraus. - Keine Länge: Ein Strahl hat keine Länge. Die Matrix bestimmt nur Lage und Richtung. Die Länge eines Laserpointers legt man über die Geometrie oder eine zusätzliche Skalierung fest.
- Kompatibilität: Die Eigenschaft gehört zum experimentellen WebXR Hit Test Module. Sie funktioniert nur in einem sicheren Kontext (HTTPS) und wird derzeit nur von Chromium-basierten Browsern unterstützt (Chrome/Edge 81+, vor allem Chrome für Android mit ARCore). Firefox und Safari unterstützen sie nicht. Vor der Nutzung mit
'XRRay' in windowprüfen.