La API Frappé Test le posibilita colocar ítems virtuales en una vista del mundo real.
Mise à jour
La API del dispositivo WebXR se envió el otoño pasado en Chrome 79. Como se dijo entonces, la implementación de la API en Chrome es un trabajo en progreso. Chrome se complace en anunciar que parte del trabajo está acabado. En Chrome 81, han llegado dos nuevas funciones:
est Publier cubre el API de test de visite WebXR, un moyen de placer des objets virtuels dans une vue caméra du monde réel.
En este post, supongo que ya sabe cómo crear una sesión de realidad aumentada y que sabe cómo ejecutar un frame loop. Si no está familiarizado con estos conceptos, debería leer los posts anteriores de esta serie.
L'échantillon de session de réalité augmentée immersive
El código de este post se basa, pero no es equivalente, al que se encuentra en la muestra de prueba de impacto del Immersive Web Working Group (manifestation,
Fontaine). Este ejemplo le posibilita colocar girasoles virtuales en superficies del mundo real.
Cuando abra la aplicación por primera vez, verá un círculo azul con un punto en el medio. El punto es la intersección entre una línea imaginaria desde su dispositivo hasta el punto en el entorno. Se mueve a medida que mueve el dispositivo. A medida que encuentra puntos de intersección, parece que se ajusta a superficies como suelos, mesas y paredes. Lo hace debido a que la prueba de impacto proporciona la posición y orientación del punto de intersección, pero nada sobre las superficies en sí.
Un recordatorio para aquellos de ustedes que son nuevos: en la API del dispositivo WebXR, «posición y orientación» están cubiertos por el término pose. Usaré ese término de ahora en más.
Ce cercle s'appelle réticule, que es una imagen temporal que ayuda a colocar un objeto en realidad aumentada. Si toca la pantalla, se coloca un girasol en la superficie en la ubicación de la retícula y la orientación del punto de la retícula, sin tener en cuenta dónde haya tocado la pantalla. La retícula continúa moviéndose con su dispositivo.

Le réticule est une image temporaire qui permet de positionner un objet en réalité augmentée.
Créer la grille
Debe crear la imagen de la retícula usted mismo, dado que no la proporciona el le navigateur ni la API. El método de carga y dibujo es específico del marco. Si no lo está dibujando de forma directa utilizando WebGL o WebGL2, consulte la documentación de su marco. Por esta razón, no entraré en detalles acerca de cómo se dibuja la retícula en la muestra. A continuación, muestro una línea por una sola razón: para que en ejemplos de código posteriores, sepa a qué me refiero cuando uso el réticule
variable.
laisser réticule = new Gltf2Node({dirección URL: 'media/gltf/reticle/reticle.gltf'});
Demander une séance
Lorsque vous demandez une session, vous devez demander 'hit-test'
dans le
requisCaractéristiques
matrice comme indiqué ci-dessous.
navigateur.xr.requestSession('immersif-ar', {
requisCaractéristiques: ['local', 'hit-test']
})
.then((session) => {
});
Ingresar en una sesión
En posts anteriores, presenté el código para entrar a una sesión XR. He mostrado una versión de esto a continuación con algunas adiciones. Primero agregué el sélectionner
oyente de eventos. Cuando el Nom d'utilisateur toca la pantalla, se colocará una flor en la vista de la cámara según la pose del retículo. Describiré ese oyente de eventos más tarde.
une fonction onSessionStarted(xrSession) {
xrSession.addEventListener('end', onSessionEnded);
xrSession.addEventListener('select', onSelect);
laisser canvas = document.createElement('canvas');
gl = canvas.getContext('webgl', { xrCompatible: vrai });
xrSession.updateRenderState({
baseLayer: new XRWebGLLayer(session, gl)
});
xrSession.requestReferenceSpace('viewer').then((refSpace) => {
xrViewerSpace = refSpace;
xrSession.requestHitTestSource({ space: xrViewerSpace })
.then((hitTestSource) => {
xrHitTestSource = hitTestSource;
});
});
xrSession.requestReferenceSpace('local').then((refSpace) => {
xrRefSpace = refSpace;
xrSession.requestAnimationFrame(onXRFrame);
});
}
Diversos espacios de referencia
Notez que le code en surbrillance appelle XRSession.requestReferenceSpace ()
deux fois. J'ai d'abord trouvé cela déroutant. J'ai demandé pourquoi le code de test de crash ne demande pas une image d'animation (démarrage de la boucle d'image) et pourquoi la boucle d'image ne semble pas impliquer de tests de collision. La source de la confusion était une mauvaise compréhension des espaces de référence. Les espaces de référence expriment les relations entre une origine et le monde.
Para saber lo que hace este código, imagina que estás viendo esta muestra con un equipo independiente y tienes tanto un auricular como un controlador. Para medir distancias desde el controlador, usaría un marco de referencia centrado en el controlador. Pero para dibujar algo en la pantalla, usaría coordenadas centradas en el usuario.
En esta muestra, el visor y el controlador son el mismo dispositivo. Pero tengo un obstáculo. Lo que dibujo debe ser estable con respecto al entorno, pero el ‘controlador’ con el que estoy dibujando se está moviendo.
Pour dessiner des images, j'utilise le local
espacio de referencia, lo que me da estabilidad en cuanto al entorno. Posteriormente de conseguir esto, comienzo el ciclo del marco llamando requestAnimationFrame ()
.
Para las pruebas de positionnement, utilizo el téléspectateur
espacio de referencia, que se basa en la pose del dispositivo en el momento de la prueba de impacto. La etiqueta «visor» es algo confusa en este contexto debido a que estoy hablando de un controlador. Tiene sentido si piensa en el controlador como un visor electrónico. Posteriormente de recibir esto, llamo xrSession.requestHitTestSource ()
, qui crée la source de données de test de déclenchement que j'utiliserai lors du dessin.
Exécution d'une boucle d'image
Les requestAnimationFrame ()
callback además obtiene un nuevo código para manejar las pruebas de visitas.
A medida que mueve su dispositivo, la retícula debe moverse con él mientras intenta hallar superficies. Para crear la ilusión de movimiento, vuelva a dibujar la retícula en cada fotograma. Pero no muestre la retícula si falla la prueba. Entonces, para la retícula que creé previamente, configuré su visible
propriété à faux
.
une fonction onXRFrame(hrTime, xrFrame) {
laisser xrSession = xrFrame.session;
xrSession.requestAnimationFrame(onXRFrame);
laisser xrViewerPose = xrFrame.getViewerPose(xrRefSpace);
réticule.visible = faux;
si (xrHitTestSource && xrViewerPose) {
laisser hitTestResults = xrFrame.getHitTestResults(xrHitTestSource);
si (hitTestResults.longueur > 0) {
laisser pose = hitTestResults[0].getPose(xrRefSpace);
réticule.visible = vrai;
réticule.matrix = pose.transformer.matrix;
}
}
}
Para dibujar cualquier cosa en AR, necesito saber dónde está el espectador y hacia dónde está mirando. Por lo tanto pruebo eso hitTestSource
et le xrViewerPose
sont toujours valables.
une fonction onXRFrame(hrTime, xrFrame) {
laisser xrSession = xrFrame.session;
xrSession.requestAnimationFrame(onXRFrame);
laisser xrViewerPose = xrFrame.getViewerPose(xrRefSpace);
réticule.visible = faux;
si (xrHitTestSource && xrViewerPose) {
laisser hitTestResults = xrFrame.getHitTestResults(xrHitTestSource);
si (hitTestResults.longueur > 0) {
laisser pose = hitTestResults[0].getPose(xrRefSpace);
réticule.visible = vrai;
réticule.matrix = pose.transformer.matrix;
}
}
}
Maintenant j'appelle getHitTestResults ()
. Se requiere el hitTestSource
comme argument et renvoie un tableau de HitTestResult
instancias. La prueba de impacto puede hallar diversos superficies. El primero de la matriz es el más cercano a la cámara. La mayoría de las veces lo usará, pero se devuelve una matriz para casos de uso avanzados. A modo de ejemplo, imagina que tu cámara apunta a una caja en una mesa en el piso. Es viable que la prueba de impacto devuelva las tres superficies de la matriz. En la mayoría de los casos, será la caja que me importa. Si la longitud de la matriz devuelta es 0, en otras palabras, si no se devuelve ninguna prueba, continúe hacia adelante. Vuelve a intentarlo en el siguiente cuadro.
une fonction onXRFrame(hrTime, xrFrame) {
laisser xrSession = xrFrame.session;
xrSession.requestAnimationFrame(onXRFrame);
laisser xrViewerPose = xrFrame.getViewerPose(xrRefSpace);
réticule.visible = faux;
si (xrHitTestSource && xrViewerPose) {
laisser hitTestResults = xrFrame.getHitTestResults(xrHitTestSource);
si (hitTestResults.longueur > 0) {
laisser pose = hitTestResults[0].getPose(xrRefSpace);
réticule.visible = vrai;
réticule.matrix = pose.transformer.matrix;
}
}
}
Para terminar, necesito procesar los resultados de la prueba de posicionamiento. El procedimiento básico es este. Obtenga una pose del resultado de la prueba de impacto, transforme (mueva) la imagen del retículo a la posición de la prueba de impacto, posteriormente configure su visible
propriété à vrai. La pose représente la pose d'un point sur une surface.
une fonction onXRFrame(hrTime, xrFrame) {
laisser xrSession = xrFrame.session;
xrSession.requestAnimationFrame(onXRFrame);
laisser xrViewerPose = xrFrame.getViewerPose(xrRefSpace);réticule.visible = faux;
si (xrHitTestSource && xrViewerPose) {
laisser hitTestResults = xrFrame.getHitTestResults(xrHitTestSource);
si (hitTestResults.longueur > 0) {
laisser pose = hitTestResults[0].getPose(xrRefSpace);
réticule.matrix = pose.transformer.matrix;
réticule.visible = vrai;
}
}
}
Placer un objet
Un objet est placé en RA lorsque l'utilisateur touche l'écran. J'ai déjà ajouté un
sélectionner
gestionnaire d'événements à la session. (Voir au dessus.)
Lo importante en este paso es saber dónde colocarlo. Puesto que la retícula en movimiento le brinda una fuente constante de pruebas de impacto, la forma más sencilla de colocar un objeto es dibujarlo en la ubicación de la retícula en la última prueba de impacto.
une fonction onSelect(un événement) {
si (réticule.visible) {
addARObjectAt(réticule.matrix);
}
}
conclusion
La meilleure façon de gérer cela est de passer par le Exemple de code ou essayez le
codelab. Espero haberte dado suficientes antecedentes para que ambos tengan sentido.
No hemos acabado de crear API web inmersivas, ni mucho menos. Publicaremos nuevos posts aquí a medida que avancemos.
photo par Daniel Frank au Unsplash