Publié par
Il y a 2 semaines · 6 minutes · Mobile

ARKit en 5 étapes

Lors de la dernière WWDC, Apple a surpris les développeurs iOS en annonçant un nouveau framework dédié à un domaine inattendu : la réalité augmentée.
Le framework, appelé ARKit propose des API permettant d’ajouter, à un flux vidéo venant de l’appareil photo, des objets numériques (3D ou 2D) avec une efficacité visuelle et une fluidité remarquable.

Dans cet article nous verrons comment créer une première application de réalité augmentée en utilisant les API ARKit et SceneKit d’Apple.

 

ARKit opère une vraie reconnaissance de l’environnement autour de l’utilisateur et calcule correctement les distances (exprimées en mètres) entre le téléphone et les objets physiques qui l’entourent.

Aujourd’hui nous verrons comment utiliser le framework pour ajouter des objets simples (une sphère) à notre environnement réel.

Avant de commencer, vérifiez d’avoir le matériel nécessaire, notamment :

  • Xcode 9
  • Un device avec processeur A9 ou supérieur (iPad 2017, iPad Pro, iPhone SE, 6s ou plus récent) sous iOS 11

Étape 0

Avant de débuter, nous allons introduire le framework et ses composants principaux.

ARKit se compose de deux parties principales :

  • La détection de l’environnement, opérée avec des techniques de tracking de l’image et du mouvement fourni. On parle aussi de Visual-inertial odometry.
  • Le rendering, qui se fait à l’aide d’un framework de dessin de contenu. Plusieurs choix s’offrent à nous dans ce contexte:
    • SceneKit, introduit avec iOS 8, et utilisé dans le cadre d’un rendering 3D ;
    • SpriteKit, introduit à partir d’iOS 7, utilisé pour la création de contenus 2D ;
    • Ou bien un renderer custom, en utilisant Metal par exemple.

Dans cet article, nous allons ajouter du contenu 3D virtuel ; ceci sera donc réalisé à l’aide de SceneKit.

Étape 1

SceneKit étant un framework très spécifique au dessin 3D, nous allons introduire ici les notions fondamentales à son utilisation.

L’élément basique pour le rendering 3D est le Node (SCNNode). Le Node est un élément structurel qui n’a aucun contenu visible et sert à représenter une position et une orientation dans un espace tridimensionnel.

Afin d’ajouter des contenus visibles à une scène, il est nécessaire d’attacher des géométries à un node : celles-ci peuvent être une surface plane, une sphère, un texte ou, bien sûr, n’importe quelle forme ou modèle 3D. Ces derniers peuvent être chargés à partir d’une source de données compatible (par exemple, les fichiers de description 3D) et contenir des informations telles que textures, couleurs, etc.

Un node N peut être ajouté à n’importe quel autre node. Une fois ajouté, positions et orientations du sous-node deviennent relatives au node parent.

La scène de ARKit fournit un node principal, appelé Root Node. Afin de construire une hiérarchie de node et de créer son expérience de réalité augmentée, il faudra donc attacher au moins un node au rootNode.

Étape 2

Le point de départ d’un écran ARKit est la ARSCNView, une sous-classe de SCNView (la view de SceneKit, étant à son tour une sous-classe de UIView).

if ARWorldTrackingConfiguration.isSupported {
 let sceneView = ARSCNView()
 sceneView.session = ARSession()
  
 let configuration = ARWorldTrackingConfiguration()
 configuration.planeDetection = .horizontal
 sceneView.delegate = self
 sceneView.session.run(configuration)
}

Étape 3

Avant d’ajouter des éléments virtuels au monde réel, il est important de comprendre comment ARKit reconstruit et numérise la conformation tridimensionnelle de l’environnement de l’utilisateur.

La source de données de la plateforme est bien évidemment la caméra du device qui photographie la scène. À partir des mouvements détectés par gyroscope et accéléromètre, ARKit détecte un certain nombre de points particuliers appelés Feature Points. Il s’agit de points dans l’espace 3D qui restent constants et qu’on peut reconnaître dans les différents frames du flux vidéo. Les coordonnées des Features Points sont relatives à la position du device de l’utilisateur, pour lequel ARKit sait également tracer précisément la translation dans l’espace.

Étape 4

Dans notre exercice, nous souhaitons ajouter un modèle 3D en correspondance d’une région de la scène réelle sélectionnée par l’utilisateur sur son écran. Pour se faire, il est nécessaire de pouvoir transformer les coordonnées 2D (celles du point de l’écran touché) en coordonnées 3D (celles de l’environnement entourant le device). Cette transformation demande l’application d’une procédure dite de « hit test ».

Le hit test consiste en la projection d’une multitude de rayons virtuels se propageant du device de l’utilisateur vers toutes les directions de l’espace 3D. Ou dit plus simplement, le hit test permet de convertir un point sur l’écran en une multitudes de positions, triées par distance à la caméra, définissant l’intersection avec un objet ou une surface dans le monde réel. Lorsqu’un rayon intersecte un feature point, les coordonnées de ce dernier seront sélectionnées en tant que résultat du hit test. Nous connaissons désormais où le modèle sera placé à l’intérieur de l’environnement 3D.

func addTapGestureRecognizer() {
    let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(placeObject))
    view.addGestureRecognizer(gestureRecognizer)
}
 
@objc private func placeObject(from recognizer: UITapGestureRecognizer) {
    let location = recognizer.location(in: view)
    let hitTestResults = sceneView.hitTest(location, types: .featurePoint)
    
    if let realWorldTransform = hitTestResults.first?.worldTransform {
        let node = SCNNode()
        node.transform = SCNMatrix4(realWorldTransform)
        sceneView.scene.rootNode.addChildNode(node)
    }
}

Étape 5

Il ne nous reste plus qu’à ajouter finalement le modèle à notre scène.
Pour se faire, nous chargeons les géomètres du modèle à partir d’un fichier spécifique.
Les formats supportés sont :

  • .scn (of course)
  • .obj
  • .dae

Dans le cas d’un fichier SCN, c’est très simple :

let scene = SCNScene(named: "art.scnassets/ship.scn")!
sceneView.scene = scene

Sinon, si l’on veut travailler avec un autre format, l’obj par exemple, il faut écrire un peu plus de code (ne pas oublier l’import) :

import SceneKit.ModelIO
 
let path = Bundle.main.path(forResource: "test", ofType: "obj")
let url = URL(fileURLWithPath: path!)
let asset = MDLAsset(url: url)
let node = SCNNode(mdlObject: asset.object(at: 0))

L’objet node pourra être ainsi utilisé dans la méthode placeObject impléméntée auparavant.

À l’exécution du programme, donc, la scène pourra se peupler de modèles 3D en correspondance des points sélectionnés par l’utilisateur.

Conclusion

À l’aide de cet article nous ne venons que d’effleurer la surface. En effet, le framework ARKit permet d’aller beaucoup plus loin, en identifiant, par exemple, des surfaces horizontales sur lesquels nos objets pourront se poser. Aussi, ARKit se prête particulièrement à l’usage avec des frameworks d’analyse d’image tels que Vision, qui permettent une reconnaissance avancée des objets et des symboles qui composent la scène, et à l’aide, si nécessaire, de techniques de Machine Learning.

À titre d’exemple, nous vous renvoyons vers notre vidéo FrenchKit Upgrade your Reality with Vision and ARKit, où Julien Datour présente comment se servir des deux frameworks Apple afin d’enrichir et rendre dynamiques des informations statiques issues de l’environnement réel.

Les derniers frameworks introduits par iOS introduisent des cas d’usage qui promettent d’enrichir les opportunités fournies par les terminaux mobiles. Vous avez des idées et vous cherchez un partenaire pour les mettre en pratique, ou bien vous cherchez des cas d’usages innovants et pertinents pour votre activité ? Parlons-en sur info+arkit@xebia.fr

Simone Civetta
Simone est responsable technique des équipes mobilités chez Xebia. Il est également formateur au sein de Xebia Training .

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *