
Dans un article précédent, j'ai déjà expliqué ce qu'est ARCore et comment il aide les développeurs à créer d'incroyables applications de réalité augmentée sans avoir besoin de comprendre les mathématiques et OpenGL.
Si vous ne l'avez pas encore lu, je vous recommande vivement de le faire avant de passer à cet article et de commencer à développer des applications ARCore.
Pour commencer
Pour commencer à développer des applications ARCore, vous devez d'abord ajouter la prise en charge ARCore à votre projet. C'est très simple, car nous utiliserons le SDK Android Studio et Sceneform. Il existe deux opérations principales qui sont effectuées automatiquement par Sceneform:
- Vérifiez ARCore.
- Demandez l'autorisation d'utiliser l'appareil photo.
Vous n'avez pas à vous soucier de ces deux étapes lors de la création d'une application ARCore à l'aide du SDK Sceneform. Il vous suffit d'ajouter le SDK Sceneform à votre projet.
Créez un nouveau projet Android Studio avec une activité vide.
Ajoutez la dépendance suivante au fichier build.gradle
au niveau du projet:
dependencies { classpath 'com.google.ar.sceneform:plugin:1.5.0' }
Et ajoutez cette dépendance au fichier build.gradle
au niveau de l'application:
implementation "com.google.ar.sceneform.ux:sceneform-ux:1.5.0"
Synchronisez maintenant le projet avec les fichiers Gradle et attendez que la construction soit terminée. Ainsi, le SDK Sceneform et le plug-in Sceneform pour Android Studio seront ajoutés au projet. Cela vous permettra de visualiser les .sfb
, qui sont des modèles 3D qui seront rendus dans votre appareil photo, ainsi que de vous aider à importer, visualiser et créer des ressources 3D.
Création de votre première application ARCore
Maintenant que la configuration d'Android Studio est terminée et que le SDK Sceneform est installé, nous pouvons commencer à créer notre première application ARCore.
Tout d'abord, nous devons ajouter un fragment Sceneform à notre mise en page. C'est la soi-disant scène où tous nos modèles 3D seront placés. Le fragment se chargera d'initialiser la caméra et de traiter les autorisations par lui-même.
Accédez à votre fichier de mise en page principal. Dans mon cas, il s'agit du fichier activity_main.xml
. Et ajoutez-y le fragment Sceneform:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <fragment android:name="com.google.ar.sceneform.ux.ArFragment" android:id="@+id/ux_fragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
J'ai défini la largeur et la hauteur de match_parent
pour que la scène soit en plein écran. Vous pouvez choisir les tailles selon vos besoins.
Vérification de compatibilité
C'est tout ce que vous devez faire dans le fichier de mise en page. Nous passons maintenant Ă Activity, dans mon cas, c'est MainActivity
. Ajoutez une méthode à l'activité:
public static boolean checkIsSupportedDeviceOrFinish(final Activity activity) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { Log.e(TAG, "Sceneform requires Android N or later"); Toast.makeText(activity, "Sceneform requires Android N or later", Toast.LENGTH_LONG).show(); activity.finish(); return false; } String openGlVersionString = ((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE)) .getDeviceConfigurationInfo() .getGlEsVersion(); if (Double.parseDouble(openGlVersionString) < MIN_OPENGL_VERSION) { Log.e(TAG, "Sceneform requires OpenGL ES 3.0 later"); Toast.makeText(activity, "Sceneform requires OpenGL ES 3.0 or later", Toast.LENGTH_LONG) .show(); activity.finish(); return false; } return true; }
Cette méthode vérifie si votre appareil prend en charge le SDK Sceneform ou non. Le SDK nécessite Android API niveau 27 ou supérieur et OpenGL ES version 3.0 ou supérieure. Si l'appareil ne prend pas en charge ces deux paramètres, la scène ne sera pas chargée et votre application affichera un écran vierge.
Cependant, vous pouvez toujours implémenter toutes les autres fonctions de votre application qui ne nécessitent pas le SDK Sceneform.
Après avoir vérifié la compatibilité, nous pouvons créer notre modèle 3D et l'attacher à la scène.
Ajout d'actifs
Vous devez maintenant ajouter des modèles 3D au projet qui seront affichés sur votre écran. Vous pouvez créer ces modèles vous-même si vous connaissez le processus de création. Ou vous pouvez aller à Poly .
Vous y trouverez un vaste référentiel de ressources 3D à choisir. De plus, ils sont téléchargeables gratuitement.

Dans Android Studio, ouvrez votre dossier d'application dans le volet gauche. Vous avez besoin d'un dossier de données d' échantillonnage . Ce dossier contiendra tous vos modèles 3D. Dans ce dossier, créez un dossier avec le nom de votre modèle.
Dans l'archive que vous téléchargez depuis Poly, vous trouverez très probablement 3 fichiers:
- fichier
.mtl
- Fichier
.obj
- fichier
.png
Le plus important de ces trois fichiers est le fichier .obj
. Ceci est votre modèle. Mettez les 3 fichiers dans sampledata -> "votre dossier modèle" .

Maintenant, .obj
clic droit sur le fichier .obj
. La première option serait Importer un élément Sceneform . Cliquez dessus, ne modifiez pas les paramètres par défaut, cliquez simplement sur Terminer dans la fenêtre suivante. Après cela, synchronisez le projet avec les fichiers Gradle.
L'importation de la ressource 3D qui sera utilisée dans votre projet est terminée. Ensuite, utilisons le modèle 3D dans notre code et incluons-le dans la scène.
Création de modèle
Ajoutez le code suivant à votre activité et je l'expliquerai ligne par ligne:
private static final String TAG = MainActivity.class.getSimpleName(); private static final double MIN_OPENGL_VERSION = 3.0; ArFragment arFragment; ModelRenderable lampPostRenderable; @Override @SuppressWarnings({"AndroidApiChecker", "FutureReturnValueIgnored"}) protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!checkIsSupportedDeviceOrFinish(this)) { return; } setContentView(R.layout.activity_main); arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment); ModelRenderable.builder() .setSource(this, Uri.parse("LampPost.sfb")) .build() .thenAccept(renderable -> lampPostRenderable = renderable) .exceptionally(throwable -> { Toast toast = Toast.makeText(this, "Unable to load andy renderable", Toast.LENGTH_LONG); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); return null; }); }
Nous trouvons d'abord arFragment
, que nous avons précédemment ajouté à la disposition. Ce fragment est responsable du stockage et du fonctionnement de la scène. Vous pouvez l'imaginer comme un conteneur pour notre scène.
Ensuite, nous utilisons la classe ModelRenderable
pour construire notre modèle. À l'aide de la méthode setSource
nous chargeons notre modèle à partir du fichier .sfb
qui a été généré lors de l'importation des ressources. La méthode thenAccept
obtient le modèle après sa création et nous définissons le modèle chargé sur notre variable lampPostRenderable
.
Pour la gestion des erreurs, nous avons une méthode exceptionally
, qui est appelée si une exception se produit.
Tout cela se produit de manière asynchrone, vous n'avez donc pas à vous soucier du multithreading.
Maintenant que le modèle est chargé et enregistré dans la variable lampPostRenderable
, nous allons l'ajouter à notre scène.
Ajout d'un modèle à la scène
Notre scène est en arFragment
et recevra des événements tactiles utilisateur. Par conséquent, nous devons installer un écouteur onTap
pour notre fragment afin de traiter les touches et de placer les objets là où cela est nécessaire. Ajoutez le code suivant à la méthode onCreate
:
arFragment.setOnTapArPlaneListener( (HitResult hitresult, Plane plane, MotionEvent motionevent) -> { if (lampPostRenderable == null){ return; } Anchor anchor = hitresult.createAnchor(); AnchorNode anchorNode = new AnchorNode(anchor); anchorNode.setParent(arFragment.getArSceneView().getScene()); TransformableNode lamp = new TransformableNode(arFragment.getTransformationSystem()); lamp.setParent(anchorNode); lamp.setRenderable(lampPostRenderable); lamp.select(); } );
Nous définissons l'écouteur onTapArPlaneListener
pour notre fragment AR. La syntaxe suivante est utilisée pour les expressions lambda. Si vous ne le connaissez pas, consultez ce petit guide sur ce sujet.
Tout d'abord, nous créons une ancre à partir de HitResult
utilisant hitresult.createAnchor()
et l'enregistrons dans l'objet Anchor
.
Ensuite, nous créons un nœud à partir de cette ancre. Il s'appellera AnchorNode
et sera attaché à la scène à l'aide de la méthode setParent
.
Ensuite, nous créons un TransformableNode
, qui sera notre modèle, et le lions à notre nœud. TransformableNode
n'a toujours aucune information sur l'objet qu'il doit afficher. Nous allons lui passer cet objet en utilisant la méthode setRenderable
, qui prend un objet de type ModelRenderable comme paramètre (rappelez-vous, nous avons obtenu un tel objet et l' lampPostRenderable
nommé lampPostRenderable
?). Et enfin, nous appelons la méthode lamp.select()
;
Ooh! Trop de terminologie. Ne vous inquiétez pas, je vais tout vous expliquer maintenant:
Scène : c'est l'endroit où tous vos objets 3D seront affichés. Cette scène se trouve dans le fragment AR que nous avons ajouté à la mise en page.
HitResult : c'est une ligne (ou rayon) imaginaire venant de l'infini, qui donne le point d'intersection de lui-même avec un objet du monde réel.
Ancre : Il s'agit d'un emplacement et d'une orientation fixes dans le monde réel. Il peut être compris comme les coordonnées (x, y, z) dans un espace tridimensionnel. La pose est la position et l'orientation d'un objet sur la scène. Il est utilisé pour convertir l'espace de coordonnées local d'un objet en un espace de coordonnées réel.
Noeud d'ancrage : il s'agit d'un noeud qui se positionne automatiquement dans le monde réel. Il s'agit du premier nœud installé lorsqu'un avion est détecté.
TransformableNode : c'est le nœud avec lequel vous pouvez interagir. Il peut être déplacé, mis à l'échelle, pivoté, etc. Dans cet exemple, nous pouvons mettre à l'échelle notre objet et le faire pivoter. D'où le nom Transformable.
Il n'y a pas de science sorcière. C'est vraiment relativement simple. La scène entière peut être visualisée sous la forme d'un graphique dans lequel le parent est la scène et les enfants sont des nœuds d'ancrage, qui se ramifient ensuite en divers autres nœuds et objets qui seront affichés à l'écran.
Par conséquent, votre activité devrait ressembler à ceci:
package com.ayusch.arcorefirst; import android.app.Activity; import android.app.ActivityManager; import android.content.Context; import android.net.Uri; import android.os.Build; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.widget.Toast; import com.google.ar.core.Anchor; import com.google.ar.core.HitResult; import com.google.ar.core.Plane; import com.google.ar.sceneform.AnchorNode; import com.google.ar.sceneform.rendering.ModelRenderable; import com.google.ar.sceneform.ux.ArFragment; import com.google.ar.sceneform.ux.TransformableNode; public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); private static final double MIN_OPENGL_VERSION = 3.0; ArFragment arFragment; ModelRenderable lampPostRenderable; @Override @SuppressWarnings({"AndroidApiChecker", "FutureReturnValueIgnored"}) protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!checkIsSupportedDeviceOrFinish(this)) { return; } setContentView(R.layout.activity_main); arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment); ModelRenderable.builder() .setSource(this, Uri.parse("LampPost.sfb")) .build() .thenAccept(renderable -> lampPostRenderable = renderable) .exceptionally(throwable -> { Toast toast = Toast.makeText(this, "Unable to load andy renderable", Toast.LENGTH_LONG); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); return null; }); arFragment.setOnTapArPlaneListener( (HitResult hitresult, Plane plane, MotionEvent motionevent) -> { if (lampPostRenderable == null){ return; } Anchor anchor = hitresult.createAnchor(); AnchorNode anchorNode = new AnchorNode(anchor); anchorNode.setParent(arFragment.getArSceneView().getScene()); TransformableNode lamp = new TransformableNode(arFragment.getTransformationSystem()); lamp.setParent(anchorNode); lamp.setRenderable(lampPostRenderable); lamp.select(); } ); } public static boolean checkIsSupportedDeviceOrFinish(final Activity activity) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { Log.e(TAG, "Sceneform requires Android N or later"); Toast.makeText(activity, "Sceneform requires Android N or later", Toast.LENGTH_LONG).show(); activity.finish(); return false; } String openGlVersionString = ((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE)) .getDeviceConfigurationInfo() .getGlEsVersion(); if (Double.parseDouble(openGlVersionString) < MIN_OPENGL_VERSION) { Log.e(TAG, "Sceneform requires OpenGL ES 3.0 later"); Toast.makeText(activity, "Sceneform requires OpenGL ES 3.0 or later", Toast.LENGTH_LONG) .show(); activity.finish(); return false; } return true; } }
Félicitations! Vous venez de terminer la création de votre première application ARCore. Commencez à y ajouter des objets et vous verrez comment ils commencent à prendre vie dans le monde réel.
C'était votre premier regard sur la façon de créer une application ARCore simple à partir de zéro dans Android Studio. Dans la prochaine leçon, je vais approfondir ARCore et ajouter plus de fonctionnalités à l'application.