¿Cuál es la diferencia entre usar ARAnchor para insertar un nodo e insertar directamente un nodo?

En ARKit, he encontrado 2 formas de insertar un nodo después del hitTest

  1. Inserte un ARAnchor y luego cree el nodo en el renderizador (_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode?

    let anchor = ARAnchor(transform:hit.worldTransform) sceneView.session.add(anchor:anchor) 
  2. Inserta el nodo directamente

     node.position = SCNVector3(hit.worldTransform.columns.3.x, hit.worldTransform.columns.3.y, hit.worldTransform.columns.3.z) sceneView.scene.rootNode.addChildNode(node) 

Ambos parecen funcionar para mí, pero ¿por qué de una forma u otra?

Actualización: A partir de iOS 11.3 (también conocido como “ARKit 1.5”), existe una diferencia entre agregar un ARAnchor a la sesión (y luego asociar contenido de SceneKit a través de ARSCNViewDelegate llamada de ARSCNViewDelegate ) y simplemente colocar contenido en el espacio de SceneKit.

Cuando agrega un ancla a la sesión, le está diciendo a ARKit que un determinado punto en el espacio mundial es relevante para su aplicación. ARKit puede entonces hacer un trabajo extra para asegurarse de que su espacio de coordenadas del mundo se alinee con precisión con el mundo real, al menos en las cercanías de ese punto.

Por lo tanto, si intenta hacer que el contenido virtual aparezca “adjunto” a algún punto de interés del mundo real, como poner un objeto en una mesa o pared, debería ver menos “deriva” debido a la imprecisión del seguimiento mundial si le da ese objeto es un ancla que si simplemente lo colocas en el espacio de SceneKit. Y si ese objeto se mueve de una posición estática a otra, querrá quitar el anclaje original y agregar uno en la nueva posición después.

Además, en iOS 11.3 puede optar por la “relocalización”, un proceso que ayuda a ARKit a reanudar una sesión después de que se interrumpe (mediante una llamada telefónica, el cambio de aplicaciones, etc.). La sesión aún funciona mientras intenta averiguar cómo se realizó el mapa de dónde estaba antes y dónde se encuentra ahora, lo que podría hacer que las posiciones del espacio-mundo de los anclajes cambien una vez que la relocalización sea exitosa.

(Por otro lado, si solo estás haciendo invasores espaciales que flotan en el air, combinar el espacio mundial de forma perfecta no es tan importante, y por lo tanto no verás mucha diferencia entre basado en anclaje y no basado en anclaje posicionamiento)

Consulte el apartado “Usar anclajes para mejorar la calidad del seguimiento de objetos virtuales” en Manejo de 3D de Apple y Controles de IU en el artículo / código de muestra de Realidad Aumentada .

El rest de esta respuesta sigue siendo históricamente relevante para iOS 11.0-11.2.5 y explica algún contexto, así que lo dejo abajo …


Considere primero el uso de ARAnchor sin SceneKit.

  • Si está utilizando ARSKView , necesita una forma de referenciar posiciones / orientaciones en el espacio 3D (mundo real), porque SpriteKit no es 3D. Necesita ARAnchor para realizar un seguimiento de las posiciones en 3D para que puedan mapearse en 2D.

  • Si estás construyendo tu propio motor con Metal (o GL, por alguna extraña razón) … esa no es una API de descripción de escena 3D, es una API de progtwigción de GPU, por lo que realmente no tiene una noción de espacio mundial. Puedes usar ARAnchor como puente entre la noción de espacio mundial de ARKit y lo que sea que construyas.

Entonces, en algunos casos necesita ARAnchor porque esa es la única forma sensata de referirse a las posiciones 3D. (Y por supuesto, si está usando la detección de plano, necesita ARPlaneAnchor porque ARKit realmente moverá aquellos relativos al espacio de la escena mientras refina sus estimaciones de dónde están los aviones).


Con ARSCNView , SceneKit ya tiene un espacio de coordenadas del mundo 3D, y ARKit hace todo el trabajo de hacer que ese espacio coincida con el espacio del mundo real que ARKit traza. Entonces, dada una transformada float4x4 que describe una posición (y orientación, etc.) en el espacio mundial, puede:

  • Cree un ARAnchor , agréguelo a la sesión y responda a la callback ARSCNViewDelegate para proporcionar el contenido de SceneKit para cada delimitador, que ARKit agregará y posicionará en la escena por usted.
  • Cree un SCNNode , configure su simdTransform y agréguelo como hijo del rootNode de la escena.

Siempre que tenga una ARSession ejecutándose, no hay diferencia entre los dos enfoques: son formas equivalentes de decir lo mismo. Entonces, si te gusta hacer las cosas del modo SceneKit, no hay nada de malo en eso. (Incluso puede usar SCNVector3 y SCNMatrix4 lugar de los tipos SIMD si lo desea, pero deberá convertir de ida y vuelta si también obtiene tipos SIMD de las API ARKit).


La única vez que estos enfoques difieren es cuando la sesión se reinicia. Si falla el seguimiento mundial, reanuda una sesión interrumpida o inicia una sesión otra vez, es posible que el “espacio mundial” ya no se alinee con el mundo real de la misma manera que cuando colocó contenido en la escena.

En este caso, puede hacer que ARKit elimine anclas de la sesión; consulte el método run(_:options:) y ARSession.RunOptions . (Sí, todos ellos, porque en este punto ya no puede confiar en que ninguno de ellos sea válido). Si coloca contenido en la escena usando anclas y delega devoluciones de llamadas, ARKit nukeará todo el contenido. (Recibes devoluciones de llamada de delegates que se eliminan). Si colocó contenido con la API de SceneKit, permanece en la escena (pero probablemente en el lugar equivocado).

Por lo tanto, qué tipo de uso depende de cómo desea manejar las interrupciones y las interrupciones de la sesión (y fuera de eso no hay diferencia real).

SCNVector3 es solo “una representación de un vector de tres componentes”. SCNVector3 documentos .

Al utilizar ARAnchor, tiene acceso a un vector de tres componentes, pero también puede “seguir las posiciones y orientaciones de los objetos reales o virtuales relativos a la cámara” ARAnchor documentos . Y es por eso que usa la sesión para agregar el ancla en lugar de usar la escena.

Mira los documentos y puedes ver la diferencia en términos de la API 🙂

Espero eso ayude.

Intereting Posts