web-dev-qa-db-fra.com

Quelle est la différence entre utiliser ARAnchor pour insérer un nœud et insérer directement un nœud?

Dans ARKit, j'ai trouvé 2 façons d'insérer un nœud après le hitTest

  1. Insérez un ARAnchor puis créez le nœud dans le moteur de rendu (_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode?

    let anchor = ARAnchor(transform:hit.worldTransform)
    sceneView.session.add(anchor:anchor)
    
  2. Insérez le nœud directement

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

Les deux cherchent à travailler pour moi, mais pourquoi d'une manière ou d'une autre?

31
Lim Thye Chean

Mise à jour: Depuis iOS 11.3 (aka "ARKit 1.5"), il y a est une différence entre l'ajout d'un ARAnchor à la session (puis en y associant le contenu SceneKit via des rappels ARSCNViewDelegate) et en plaçant simplement le contenu dans l'espace SceneKit.

Lorsque vous ajoutez une ancre à la session, vous dites à ARKit qu'un certain point de l'espace mondial est pertinent pour votre application. ARKit peut alors faire un travail supplémentaire pour s'assurer que son espace mondial de coordonnées s'aligne avec précision sur le monde réel, au moins à proximité de ce point.

Donc, si vous essayez de faire apparaître un contenu virtuel "attaché" à un point d'intérêt du monde réel, comme mettre un objet sur une table ou un mur, vous devriez voir moins de "dérive" en raison de l'inexactitude du suivi du monde si vous donnez cet objet une ancre que si vous venez de le placer dans l'espace SceneKit. Et si cet objet se déplace d'une position statique à une autre, vous souhaiterez supprimer l'ancre d'origine et en ajouter une à la nouvelle position par la suite.

De plus, dans iOS 11.3, vous pouvez activer pour "relocalisation", un processus qui aide ARKit à reprendre une session après son interruption (par un appel téléphonique, le changement d'application, etc.). La session fonctionne toujours pendant qu'elle essaie de comprendre comment mapper où vous étiez avant et où vous êtes maintenant, ce qui pourrait entraîner la modification des positions des ancres dans le monde une fois la relocalisation réussie.

(D'un autre côté, si vous faites juste des envahisseurs spatiaux qui flottent dans l'air, il n'est pas aussi important de faire correspondre parfaitement l'espace mondial, et donc vous ne verrez pas vraiment beaucoup de différence entre basé sur une ancre et non basé sur une ancre positionnement.)

Voir l'article sur "Utiliser des ancres pour améliorer la qualité du suivi autour des objets virtuels" dans Apple Gestion des interactions 3D et des contrôles d'interface utilisateur en réalité augmentée article/exemple de code.

Le reste de cette réponse reste historiquement pertinent pour iOS 11.0-11.2.5 et explique un certain contexte, donc je vais le laisser ci-dessous ...


Considérez d'abord l'utilisation de ARAnchor sans SceneKit.

  • Si vous utilisez ARSKView, vous avez besoin d'un moyen de référencer des positions/orientations dans un espace 3D (réel), car SpriteKit n'est pas 3D. Vous avez besoin de ARAnchor pour garder une trace des positions en 3D afin qu'elles puissent être mappées en 2D.

  • Si vous construisez votre propre moteur avec Metal (ou GL, pour une raison étrange) ... ce n'est pas une API de description de scène 3D - c'est une API de programmation GPU - donc elle n'a pas vraiment une notion d'espace mondial. Vous pouvez utiliser ARAnchor comme un pont entre la notion d'ARKit de l'espace mondial et tout ce que vous construisez.

Donc, dans certains cas, vous avez besoin de ARAnchor parce que c'est la seule façon raisonnable de se référer à des positions 3D. (Et bien sûr, si vous utilisez la détection des avions, vous avez besoin de ARPlaneAnchor car ARKit déplacera ceux-ci par rapport à l'espace de la scène tout en affinant ses estimations de l'emplacement des avions.)


Avec ARSCNView, SceneKit dispose déjà d'un espace de coordonnées universelles 3D, et ARKit fait tout le travail pour faire correspondre cet espace à l'espace réel qu'ARKit cartographie. Donc, étant donné une transformation float4x4 Qui décrit une position (et une orientation, etc.) dans l'espace mondial, vous pouvez soit:

  • Créez un ARAnchor, ajoutez-le à la session et répondez au rappel ARSCNViewDelegate pour fournir le contenu SceneKit pour chaque ancre, qu'ARKit ajoutera et positionnera dans la scène pour vous.
  • Créez un SCNNode, définissez son simdTransform et ajoutez-le en tant qu'enfant du rootNode de la scène.

Tant que vous avez un ARSession en cours d'exécution, il n'y a pas de différence entre les deux approches - ce sont des façons équivalentes de dire la même chose. Donc, si vous aimez faire les choses à la manière de SceneKit, il n'y a rien de mal à cela. (Vous pouvez même utiliser SCNVector3 Et SCNMatrix4 Au lieu des types SIMD si vous le souhaitez, mais vous devrez effectuer des conversions avant et en arrière si vous obtenez également des types SIMD à partir des API ARKit.)


La seule fois où ces approches diffèrent, c'est lorsque la session est réinitialisée. Si le suivi du monde échoue, vous reprenez une session interrompue et/ou vous recommencez une session, "l'espace du monde" peut ne plus s'aligner sur le monde réel de la même manière que lorsque vous avez placé du contenu dans la scène.

Dans ce cas, vous pouvez demander à ARKit de supprimer les ancres de la session - voir la méthode run(_:options:) et ARSession.RunOptions . (Oui, tous, car à ce stade, vous ne pouvez plus faire confiance à aucun d'entre eux pour être valide.) Si vous avez placé du contenu dans la scène à l'aide d'ancres et de rappels délégués, ARKit nuke tout le contenu. (Vous obtenez des rappels des délégués selon lesquels il est supprimé.) Si vous avez placé du contenu avec SceneKit API, il reste dans la scène (mais très probablement au mauvais endroit).

Donc, lequel utiliser dépend de la façon dont vous souhaitez gérer les échecs et les interruptions de session (et en dehors de cela, il n'y a pas de réelle différence).

46
rickster

SCNVector3 est juste "une représentation d'un vecteur à trois composants". documents SCNVector .

Lorsque vous utilisez ARAnchor, vous avez accès à un vecteur à trois composants, mais vous pouvez également "suivre les positions et orientations des objets réels ou virtuels par rapport à la caméra" ARAnchor docs . Et c'est pourquoi vous utilisez la session pour ajouter l'ancre au lieu d'utiliser la scène.

Voir les documents et vous pouvez voir la différence en termes d'API :)

J'espère que ça aide.

0
Fernando López