Signatur
Beschreibung
Das Interface XRTransientInputHitTestResult gehört zum WebXR Hit Test Module. Es fasst die Ergebnisse eines Hit-Tests für transiente Eingaben zusammen. Transiente Eingaben sind Eingabequellen, die nur kurz existieren, etwa ein Finger-Tipp auf dem Touchscreen eines Smartphones in einer AR-Sitzung (Profil "generic-touchscreen"). Weil diese Quellen beim Anfordern des Hit-Tests noch gar nicht existieren, wird der Hit-Test über ein Profil statt über eine konkrete Quelle registriert.
Instanzen werden nie direkt erzeugt. Man erhält sie in jedem Frame als Array über XRFrame.getHitTestResultsForTransientInput(hitTestSource), wobei hitTestSource eine XRTransientInputHitTestSource ist, die zuvor mit XRSession.requestHitTestSourceForTransientInput() angefordert wurde. Für jede aktuell aktive transiente Eingabequelle liefert das Array genau ein XRTransientInputHitTestResult.
Das Interface besitzt zwei schreibgeschützte Eigenschaften:
inputSource– dieXRInputSource, zu der die Ergebnisse gehören (z. B. der aktuelle Finger).results– ein eingefrorenes Array vonXRHitTestResult-Objekten, sortiert nach Entfernung (nächster Treffer zuerst). MitXRHitTestResult.getPose(referenceSpace)erhält man daraus Position und Ausrichtung des Treffers auf einer realen Oberfläche.
Typischer Einsatz: Nutzer tippt auf den Bildschirm, und an der Stelle, an der der „Strahl“ des Tipps eine erkannte Ebene (Boden, Tisch) trifft, wird ein virtuelles Objekt platziert oder ein Fadenkreuz angezeigt.
Rückgabewert
XRFrame.getHitTestResultsForTransientInput() geliefert. Eigenschaften: inputSource (XRInputSource) und results (FrozenArray<XRHitTestResult>).Beispiele
AR-Sitzung starten und transiente Hit-Test-Quelle anfordern
const startAR = async () => {
if (!navigator.xr || !(await navigator.xr.isSessionSupported('immersive-ar'))) {
console.log('immersive-ar wird nicht unterstützt');
return;
}
// 'hit-test' muss als Feature angefordert werden
const session = await navigator.xr.requestSession('immersive-ar', {
requiredFeatures: ['hit-test', 'local-floor']
});
const refSpace = await session.requestReferenceSpace('local-floor');
// Hit-Test für alle künftigen Touchscreen-Tipps registrieren
const transientSource = await session.requestHitTestSourceForTransientInput({
profile: 'generic-touchscreen'
});
console.log('Transiente Hit-Test-Quelle bereit:', transientSource);
return { session, refSpace, transientSource };
};
// Muss aus einer Nutzer-Geste heraus aufgerufen werden
document.querySelector('#ar-button').addEventListener('click', startAR);
Ergebnisse pro Frame auswerten
const onXRFrame = (time, frame) => {
const session = frame.session;
session.requestAnimationFrame(onXRFrame);
// Array von XRTransientInputHitTestResult – eines pro aktivem Finger
const perInput = frame.getHitTestResultsForTransientInput(transientSource);
for (const inputResult of perInput) {
const { inputSource, results } = inputResult;
if (results.length === 0) continue;
// Nächster Treffer steht an erster Stelle
const pose = results[0].getPose(refSpace);
if (!pose) continue;
const { x, y, z } = pose.transform.position;
console.log(`${inputSource.profiles[0]} trifft bei`, x.toFixed(2), y.toFixed(2), z.toFixed(2));
}
};
session.requestAnimationFrame(onXRFrame);
Objekt beim Tipp platzieren (select-Event) und Quelle aufräumen
let lastHitPose = null;
const onXRFrame = (time, frame) => {
frame.session.requestAnimationFrame(onXRFrame);
const perInput = frame.getHitTestResultsForTransientInput(transientSource);
lastHitPose = perInput[0]?.results[0]?.getPose(refSpace) ?? null;
};
const onSelect = () => {
if (!lastHitPose) return;
// Hier z. B. ein 3D-Modell an lastHitPose.transform setzen
console.log('Objekt platziert:', lastHitPose.transform.position);
};
session.addEventListener('select', onSelect);
session.requestAnimationFrame(onXRFrame);
session.addEventListener('end', () => {
session.removeEventListener('select', onSelect);
transientSource.cancel(); // Ressourcen freigeben
});
// Wichtig · Fallstricke
- Experimentell: Nur in Chromium-basierten Browsern auf Android mit ARCore verfügbar; Firefox und Safari unterstützen das Hit Test Module nicht. Immer per Feature-Erkennung (
navigator.xr,isSessionSupported(),'requestHitTestSourceForTransientInput' in session) absichern. - Nur in sicheren Kontexten (HTTPS) und nur, wenn
'hit-test'inrequiredFeaturesbzw.optionalFeaturesangefordert wurde – sonst wird das Promise mitNotSupportedErrorabgelehnt. - Das Array von
getHitTestResultsForTransientInput()ist leer, solange kein Finger den Bildschirm berührt. Auchresultskann leer sein, wenn keine Oberfläche erkannt wurde – immer auf Länge prüfen. getPose()kannnullliefern, wenn die Pose im gewählten Referenzraum nicht bestimmbar ist.- Ergebnisse gelten nur für den aktuellen Frame; Objekte nicht über Frames hinweg zwischenspeichern, sondern die Pose kopieren. Für dauerhaft stabile Positionen besser
XRHitTestResult.createAnchor()nutzen. - Nicht mehr benötigte Quellen mit
XRTransientInputHitTestSource.cancel()freigeben, um Rechenleistung zu sparen.