From c8939583260b7a5193b544ab0d1f8e2d841f4051 Mon Sep 17 00:00:00 2001 From: norangebit Date: Thu, 3 Jan 2019 22:20:27 +0100 Subject: [PATCH 1/6] init chapter 3 - add augmented images project --- src/chapter3.md | 135 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 src/chapter3.md diff --git a/src/chapter3.md b/src/chapter3.md new file mode 100644 index 0000000..c69d82a --- /dev/null +++ b/src/chapter3.md @@ -0,0 +1,135 @@ +# Progetti di esempio + +Quando si vuole sviluppare un applicazione con ARCore e Sceneform è necessaria una configurazione iniziale. + +Per funzionare ARCore necessita di Android 7.0(API level 24) o superiore. +Inoltre se si sta lavorando con un progetto con API level minore di 26 è necessario esplicitare il supporto a Java 8 aggiungendo al file `app/build.gradle` le seguenti linee. + +```gradle +compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 +} +``` + +Un'altra modifica da fare al file è aggiunta della dipendenza di Sceneform. + +```gradle +implementation "com.google.ar.sceneform.ux:sceneform-ux:1.6.0" +``` + +Inoltre nell'AndroidManifest è necessario dichiarare l'utilizzo del permesso della fotocamera[^camera] e l'utilizzo di ARCore[^arcore]. + +## Augmented images + +Il primo progetto è un classico esempio di AR marker based e ha lo scopo di riconosce un immagine data e sovrapporre ad essa un oggetto virtuale. + +### Aggiunta del modello + +//TODO + +### Creazione del database + +La prima cosa da fare è creare un database con tutte le immagini che si desidera far riconosce all'applicazione. Questa operazione può essere svolta sia quando si sta sviluppando l'applicazione, sia runtime. Per questo progetto si è scelta la seconda opzione. + +L'aggiunta dell'immagine al database avviene mediante la funzione `setupAugmentedImageDb`. + +```kotlin +private fun setupAugmentedImageDb (config: Config): Boolean { + val image = loadImage(IMAGE_FILE_NAME) ?: return false + + val augmentedImageDb = AugmentedImageDatabase(session) + augmentedImageDb.addImage(IMAGE_NAME, image) + config.augmentedImageDatabase = augmentedImageDb + return true +} +``` + +### Riconoscimento dell'immagine + +Sfortunatamente ARCore non permette di gestire il riconoscimento dell'immagine mediante un listener, per cui sarà compito dello sviluppatore controllare quando si è verificato un match. +Per fare ciò si usa il metodo `addOnUpdateListener()` dell'oggetto `Scene`, che permette di eseguire del codice ogni qual volta che la scena viene aggiornata. + +```kotlin +override fun onCreate(savedInstanceState: Bundle?) { + //... + + arSceneView.scene.addOnUpdateListener(this::detectAndPlaceAugmentedImage) + + //... +} +``` + +Dove la funzione `detectAndPlaceAugmentedImage()` si occupa di verificare la presenza di un match e nel caso aggiungere l'oggetto virtuale alla scena. + +```kotlin +private fun detectAndPlaceAugmentedImage(frameTime: FrameTime) { + if (isModelAdded) + return + + val augmentedImage = arSceneView.arFrame + .getUpdatedTrackables(AugmentedImage::class.java) + .filter { isTrackig(it) } + .find { it.name.contains(IMAGE_NAME) } + ?: return + + val augmentedImageAnchor = augmentedImage.createAnchor(augmentedImage.centerPose) + + buildRenderable(this, Uri.parse(MODEL_NAME)) { + addTransformableNodeToScene( + arFragment, + augmentedImageAnchor, + it + ) + } + + isModelAdded = true +} +``` + +### Rendering del modello + +Il rendering del modello avviene attraverso la funzione `buildRenderable()`. +Poiché quest'ultima è un operazione dispendiosa viene restituito un `Future`[^future] che racchiude il `Renderable` vero e proprio. +L'interazione con quest'oggetto avviene attraverso una callback che è possibile specificare attraverso il metodo `thenAccept()`. + +```kotlin +fun buildRenderable( + context: Context, + model: Uri, + onSuccess: (renderable: Renderable) -> Unit +) { + ModelRenderable.builder() + .setSource(context, model) + .build() + .thenAccept(onSuccess) + .exceptionally { + Log.e("SCENEFORM", "unable to load model", it) + return@exceptionally null + } +} +``` + +### Aggiunta dell'oggetto virtuale nella scena + +L'ultima cosa da compiere è l'aggiunta del modello renderizzato alla scena. +Questa operazione avviene attraverso la funzione `addTrasformableNodeToScene()`. + +```kotlin +fun addTransformableNodeToScene( + arFragment: ArFragment, + anchor: Anchor, + renderable: Renderable +) { + val anchorNode = AnchorNode(anchor) + val transformableNode = TransformableNode(arFragment.transformationSystem) + transformableNode.renderable = renderable + transformableNode.setParent(anchorNode) + arFragment.arSceneView.scene.addChild(anchorNode) + transformableNode.select() +} +``` + +[^camera]: Lo sviluppatore deve solo dichiarare l'utilizzo del permesso, la richiesta di concessione è gestita in automatico da Sceneform. +[^arcore]: L'utilizzo di ARCore deve essere dichiarata in quanto non tutti i dispositivi supportano ARCore. +[^future]: In informatica con il termine *future*, o *promise*, *delay* e *deferred*, si indica un tecnica che permette di sincronizzare l'esecuzione di un programma concorrente. From 73abd0b8dd867c21694b6da4e2b761ac9d85636b Mon Sep 17 00:00:00 2001 From: norangebit Date: Fri, 4 Jan 2019 12:17:49 +0100 Subject: [PATCH 2/6] various fixs --- src/chapter3.md | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/chapter3.md b/src/chapter3.md index c69d82a..4db8474 100644 --- a/src/chapter3.md +++ b/src/chapter3.md @@ -1,18 +1,22 @@ # Progetti di esempio -Quando si vuole sviluppare un applicazione con ARCore e Sceneform è necessaria una configurazione iniziale. +Prima di procedere allo sviluppo di applicazioni mediante ARCore e Sceneform sono necessarie alcune configurazioni iniziali. Per funzionare ARCore necessita di Android 7.0(API level 24) o superiore. -Inoltre se si sta lavorando con un progetto con API level minore di 26 è necessario esplicitare il supporto a Java 8 aggiungendo al file `app/build.gradle` le seguenti linee. +Inoltre se si sta lavorando con un progetto con API level minore di 26 è necessario esplicitare il supporto a Java 8 andando a modificare file `app/build.gradle`. ```gradle -compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 +android { + ... + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + ... } ``` -Un'altra modifica da fare al file è aggiunta della dipendenza di Sceneform. +Un'altra modifica da fare al file è l'aggiunta della dipendenza di Sceneform. ```gradle implementation "com.google.ar.sceneform.ux:sceneform-ux:1.6.0" @@ -23,14 +27,16 @@ Inoltre nell'AndroidManifest è necessario dichiarare l'utilizzo del permesso de ## Augmented images Il primo progetto è un classico esempio di AR marker based e ha lo scopo di riconosce un immagine data e sovrapporre ad essa un oggetto virtuale. +Nel caso specifico si vuole riconoscere una foto del pianeta terra e sostituirvi un modello tridimensionale di essa. ### Aggiunta del modello -//TODO +Prima di tutto dobbiamo la cartella *"sampledata"*, il cui contenuto sarà usato solo in fase di progettazione, e aggiungere ad essa il modello tridimensionale[^format] che vogliamo usare. +Per facilitare l'importazione del modello 3D usiamo il plug-in *Google Sceneform Tools*. ### Creazione del database -La prima cosa da fare è creare un database con tutte le immagini che si desidera far riconosce all'applicazione. Questa operazione può essere svolta sia quando si sta sviluppando l'applicazione, sia runtime. Per questo progetto si è scelta la seconda opzione. +La prima cosa da fare è la creazione di un database con tutte le immagini che si desidera far riconosce all'applicazione. Questa operazione può essere svolta sia quando si sta sviluppando l'applicazione, sia runtime. Per questo progetto si è scelta la seconda opzione. L'aggiunta dell'immagine al database avviene mediante la funzione `setupAugmentedImageDb`. @@ -90,7 +96,7 @@ private fun detectAndPlaceAugmentedImage(frameTime: FrameTime) { ### Rendering del modello Il rendering del modello avviene attraverso la funzione `buildRenderable()`. -Poiché quest'ultima è un operazione dispendiosa viene restituito un `Future`[^future] che racchiude il `Renderable` vero e proprio. +Poiché quest'ultima è un operazione onerosa viene restituito un `Future`[^future] che racchiude il `Renderable` vero e proprio. L'interazione con quest'oggetto avviene attraverso una callback che è possibile specificare attraverso il metodo `thenAccept()`. ```kotlin @@ -112,7 +118,7 @@ fun buildRenderable( ### Aggiunta dell'oggetto virtuale nella scena -L'ultima cosa da compiere è l'aggiunta del modello renderizzato alla scena. +L'ultima operazione da compiere è l'aggiunta del modello renderizzato alla scena. Questa operazione avviene attraverso la funzione `addTrasformableNodeToScene()`. ```kotlin @@ -130,6 +136,7 @@ fun addTransformableNodeToScene( } ``` +[^format]: Attualmente sono supportati solo modelli OBJ, FBX e gLTF. [^camera]: Lo sviluppatore deve solo dichiarare l'utilizzo del permesso, la richiesta di concessione è gestita in automatico da Sceneform. [^arcore]: L'utilizzo di ARCore deve essere dichiarata in quanto non tutti i dispositivi supportano ARCore. [^future]: In informatica con il termine *future*, o *promise*, *delay* e *deferred*, si indica un tecnica che permette di sincronizzare l'esecuzione di un programma concorrente. From a1d0be372316c9d073ba412d6ddca49e2e838e89 Mon Sep 17 00:00:00 2001 From: norangebit Date: Fri, 4 Jan 2019 21:03:08 +0100 Subject: [PATCH 3/6] rename chapter3 to chapter3.1 --- src/{chapter3.md => chapter3.1.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{chapter3.md => chapter3.1.md} (100%) diff --git a/src/chapter3.md b/src/chapter3.1.md similarity index 100% rename from src/chapter3.md rename to src/chapter3.1.md From 81ebc85722783f3f1b746b5ae113417e8b7ab6bb Mon Sep 17 00:00:00 2001 From: norangebit Date: Fri, 4 Jan 2019 21:06:25 +0100 Subject: [PATCH 4/6] init chapter3.2 --- src/chapter3.2.md | 92 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/chapter3.2.md diff --git a/src/chapter3.2.md b/src/chapter3.2.md new file mode 100644 index 0000000..97b8b9e --- /dev/null +++ b/src/chapter3.2.md @@ -0,0 +1,92 @@ +## Runtime fetching models + +Lo scopo di questa seconda applicazione è mostrare come sia possibile recuperare i modelli da renderizzare durante l'esecuzione dell'applicazione. +Questa funzione risulta particolarmente utile quando si deve rilasciare un'applicazione che sfrutta un numero elevato di modelli e non si vuole appesantire il volume del file *apk*[^apk]. +Inoltre è possibile aggiungere nuovi modelli, o aggiornare quelli vecchi, senza dover aggiornare l'applicazione, ma lavorando esclusivamente lato server. + +Per quest'applicazione oltre alle configurazioni già viste in precedenza dobbiamo aggiungere una nuova dipendenza che include le funzioni necessarie per il fetching del modello. + +```gradle + implementation 'com.google.ar.sceneform:assets:1.6.0' +``` + +Inoltre nell'AndroidManifest bisogna aggiungere il permesso per accedere alla rete. + +### Interazione con l'utente + +L'interazione con l'utente avviene mediante un tocco sul display. +Sceneform ci permette di personalizzare il comportamento al verificarsi di questo evento tramite un listener. + +```kotlin +override fun onCreate(savedInstanceState: Bundle?) { + //... + arFragment.setOnTapArPlaneListener(this::fetchAndPlaceModel) + //... +} +``` + +Dove la funzione `fetchAndPlaceModel` si occupa di recuperare il modello e renderizzarlo. + +```kotlin +private fun fetchAndPlaceModel( + hitResult: HitResult, + plane: Plane, + motionEvent: MotionEvent +) { + val modelUri = Uri.parse(MODEL_SOURCE) + val fetchedModel = fetchModel(this, modelUri) + buildRenderable(this, fetchedModel, modelUri) { + addTransformableNodeToScene( + arFragment, + hitResult.createAnchor(), + it + ) + } +} +``` + +### Fetching del model + +Il recupero del modello avviene attraverso la funzione `fetchModel`. + +```kotlin +fun fetchModel( + context: Context, + source: Uri +) : RenderableSource { + return RenderableSource.builder() + .setSource(context, source, RenderableSource.SourceType.GLTF2) + .setRecenterMode(RenderableSource.RecenterMode.ROOT) + .build() +} +``` + +Attualmente[^sceneform-1.6] Sceneform supporta unicamente il fetching di modelli gLTF. + +### Rendering e aggiunta del modello + +Il rendering del modello avviene tramite la funzione `buildRenderable`, che è molto simile a quella utilizzata nel progetto precedente, con la differenza che in questo caso deve essere passato anche il modello che si è recuperato in precedenza. + +```kotlin +fun buildRenderable( + context: Context, + model: RenderableSource, + modelUri: Uri, + onSuccess: (renderable: Renderable) -> Unit +) { + ModelRenderable.builder() + .setRegistryId(modelUri) + .setSource(context, model) + .build() + .thenAccept(onSuccess) + .exceptionally { + Log.e("SCENEFORM", "unable to load model", it) + return@exceptionally null + } +} +``` + +L'aggiunta del modello renderizzato alla scena avviene mediante la medesima funzione `addTransformableNodeToScene` vista in precedenza. + +[^sceneform-1.6]: Sceneform 1.6.0. +[^apk]: Formato delle applicazioni android. From a9db63e0558bd15a2c516a304d3bbdd4c0707c0d Mon Sep 17 00:00:00 2001 From: norangebit Date: Sat, 5 Jan 2019 16:34:51 +0100 Subject: [PATCH 5/6] bugs fix - mv introduzione to chapter3.0 - edit chapter3.1 and chapter3.2 --- src/chapter3.0.md | 31 ++++++++++++++++++++ src/chapter3.1.md | 74 +++++++++++++++++++---------------------------- src/chapter3.2.md | 23 ++++++++------- 3 files changed, 73 insertions(+), 55 deletions(-) create mode 100644 src/chapter3.0.md diff --git a/src/chapter3.0.md b/src/chapter3.0.md new file mode 100644 index 0000000..32b2184 --- /dev/null +++ b/src/chapter3.0.md @@ -0,0 +1,31 @@ +# Progetti d'esempio + +Per poter realizzare delle applicazioni mediante ARCore e Sceneform sono necessarie una serie di configurazioni iniziali. + +Requisito necessario al funzionamento di ARCore è una versione di Android uguale o superiore ad Android 7.0 Nougat(API level 24). +Inoltre se si sta lavorando su un progetto con API level minore di 26 è necessario esplicitare il supporto a Java 8 andando a modificare file `app/build.gradle`. + +```gradle +android { + ... + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + ... +} +``` + +Sempre nel file per il build del progetto è necessario aggiungere la dipendenza di Sceneform. + +```gradle +implementation "com.google.ar.sceneform.ux:sceneform-ux:1.6.0" +``` + +Inoltre nell'Android Manifest[^manifest] va dichiarato l'utilizzo del permesso della fotocamera[^camera] e l'utilizzo di ARCore[^arcore]. + +[^manifest]: File in cui vengono dichiarate tutte caratteristiche di un'applicazione Android, tra cui anche i permessi. + +[^camera]: Lo sviluppatore deve solo dichiarare l'utilizzo del permesso, la richiesta di concessione è gestita in automatico da Sceneform. + +[^arcore]: L'utilizzo di ARCore deve essere dichiarata in quanto non tutti i dispositivi lo supportano. diff --git a/src/chapter3.1.md b/src/chapter3.1.md index 4db8474..91c37b4 100644 --- a/src/chapter3.1.md +++ b/src/chapter3.1.md @@ -1,60 +1,41 @@ -# Progetti di esempio - -Prima di procedere allo sviluppo di applicazioni mediante ARCore e Sceneform sono necessarie alcune configurazioni iniziali. - -Per funzionare ARCore necessita di Android 7.0(API level 24) o superiore. -Inoltre se si sta lavorando con un progetto con API level minore di 26 è necessario esplicitare il supporto a Java 8 andando a modificare file `app/build.gradle`. - -```gradle -android { - ... - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - ... -} -``` - -Un'altra modifica da fare al file è l'aggiunta della dipendenza di Sceneform. - -```gradle -implementation "com.google.ar.sceneform.ux:sceneform-ux:1.6.0" -``` - -Inoltre nell'AndroidManifest è necessario dichiarare l'utilizzo del permesso della fotocamera[^camera] e l'utilizzo di ARCore[^arcore]. - ## Augmented images -Il primo progetto è un classico esempio di AR marker based e ha lo scopo di riconosce un immagine data e sovrapporre ad essa un oggetto virtuale. +Nel primo progetto d'esempio si è affrontato un classico problema di AR marker based, ovvero il riconoscimento di un'immagine preimpostata e il conseguente sovrapponimento di un oggetto virtuale. Nel caso specifico si vuole riconoscere una foto del pianeta terra e sostituirvi un modello tridimensionale di essa. ### Aggiunta del modello -Prima di tutto dobbiamo la cartella *"sampledata"*, il cui contenuto sarà usato solo in fase di progettazione, e aggiungere ad essa il modello tridimensionale[^format] che vogliamo usare. -Per facilitare l'importazione del modello 3D usiamo il plug-in *Google Sceneform Tools*. +Il modello tridimensionale della terra è stato recuperato dal sito `poly.google.com`, che funge da repository per modelli 3D. +La scelta del modello è stata dettata sia del formato[^format] in cui era disponibile, sia dalla licenza con cui veniva distribuito. +Una volta ottenuto il modello è stato salvato nella cartella *"sampledata"*, il cui contenuto sarà usato solo in fase di progettazione. + +L'importazione del modello all'interno del progetto di Android Studio è stato effettuato mediante l'utilizzo del plug-in *Google Sceneform Tools*, che si occupa sia di convertire il modello nel formato di Sceneform, sia di aggiornare il file `build.gradle` affinché sia incluso nell'APK[^apk] finale. ### Creazione del database -La prima cosa da fare è la creazione di un database con tutte le immagini che si desidera far riconosce all'applicazione. Questa operazione può essere svolta sia quando si sta sviluppando l'applicazione, sia runtime. Per questo progetto si è scelta la seconda opzione. +Il database contenete tutte le immagini che si desidera far riconosce all'applicazione, può essere creato sia a priori, sia a tempo di esecuzione. +Per la prima soluzione Google mette a disposizione *The arcoreimag tool*, un software a linea di comando, che oltre a creare il database si occupa anche di valutare l'immagine. -L'aggiunta dell'immagine al database avviene mediante la funzione `setupAugmentedImageDb`. +Dato che nel caso specifico si vuole far riconoscere un'unica immagine si è optato per la generazione del database a runtime. +In particolare quest'operazione avviene mediante la funzione `setupAugmentedImageDb`. ```kotlin private fun setupAugmentedImageDb (config: Config): Boolean { - val image = loadImage(IMAGE_FILE_NAME) ?: return false + val image = loadImage(IMAGE_FILE_NAME) ?: return false - val augmentedImageDb = AugmentedImageDatabase(session) - augmentedImageDb.addImage(IMAGE_NAME, image) - config.augmentedImageDatabase = augmentedImageDb - return true + val augmentedImageDb = AugmentedImageDatabase(session) + augmentedImageDb.addImage(IMAGE_NAME, image) + config.augmentedImageDatabase = augmentedImageDb + return true } ``` ### Riconoscimento dell'immagine -Sfortunatamente ARCore non permette di gestire il riconoscimento dell'immagine mediante un listener, per cui sarà compito dello sviluppatore controllare quando si è verificato un match. -Per fare ciò si usa il metodo `addOnUpdateListener()` dell'oggetto `Scene`, che permette di eseguire del codice ogni qual volta che la scena viene aggiornata. +Il riconoscimento dell'immagine non può avvenire mediate l'utilizzo di una callback in quanto ARCore non permette di registrare un listener all'evento. +Risulta dunque evidente che la verifica dell'avvenuto match sarà delegata allo sviluppatore. + +Per fare ciò si è usato il metodo `addOnUpdateListener` dell'oggetto `Scene`, che permette di eseguire del codice ogni qual volta la scena viene aggiornata. ```kotlin override fun onCreate(savedInstanceState: Bundle?) { @@ -66,7 +47,7 @@ override fun onCreate(savedInstanceState: Bundle?) { } ``` -Dove la funzione `detectAndPlaceAugmentedImage()` si occupa di verificare la presenza di un match e nel caso aggiungere l'oggetto virtuale alla scena. +Dove la funzione `detectAndPlaceAugmentedImage` si occupa di verificare la presenza di un match e nel caso di un riscontro positivo, dell'aggiunta dell'oggetto virtuale alla scena. ```kotlin private fun detectAndPlaceAugmentedImage(frameTime: FrameTime) { @@ -93,11 +74,13 @@ private fun detectAndPlaceAugmentedImage(frameTime: FrameTime) { } ``` +Il settaggio del flag `isModelAdded` al valore booleano di vero, si rende necessario al fine di evitare l'aggiunta incontrollata di nuovi modelli alla medesima immagine. + ### Rendering del modello -Il rendering del modello avviene attraverso la funzione `buildRenderable()`. +Il rendering del modello avviene attraverso la funzione `buildRenderable` che a sua volta chiama la funzione di libreria `ModelRenderable.builder()`. Poiché quest'ultima è un operazione onerosa viene restituito un `Future`[^future] che racchiude il `Renderable` vero e proprio. -L'interazione con quest'oggetto avviene attraverso una callback che è possibile specificare attraverso il metodo `thenAccept()`. +L'interazione con l'oggetto concreto avviene mediante una callback che è possibile specificare attraverso il metodo `thenAccept`. ```kotlin fun buildRenderable( @@ -119,7 +102,9 @@ fun buildRenderable( ### Aggiunta dell'oggetto virtuale nella scena L'ultima operazione da compiere è l'aggiunta del modello renderizzato alla scena. -Questa operazione avviene attraverso la funzione `addTrasformableNodeToScene()`. +Questa operazione avviene attraverso la funzione `addTrasformableNodeToScene()` che si occupa di creare un ancora in corrispondenza del punto reale d'interesse. +A partire da quest'ancora viene creato un nodo che racchiude l'oggetto renderizzato. +Inoltre nel caso specifico si è usato un `TransformabelNode`, in modo da concedere all'utente la possibilità di ridimensionare o ruotare il modello. ```kotlin fun addTransformableNodeToScene( @@ -137,6 +122,7 @@ fun addTransformableNodeToScene( ``` [^format]: Attualmente sono supportati solo modelli OBJ, FBX e gLTF. -[^camera]: Lo sviluppatore deve solo dichiarare l'utilizzo del permesso, la richiesta di concessione è gestita in automatico da Sceneform. -[^arcore]: L'utilizzo di ARCore deve essere dichiarata in quanto non tutti i dispositivi supportano ARCore. + +[^apk]: Formato delle applicazioni Android. + [^future]: In informatica con il termine *future*, o *promise*, *delay* e *deferred*, si indica un tecnica che permette di sincronizzare l'esecuzione di un programma concorrente. diff --git a/src/chapter3.2.md b/src/chapter3.2.md index 97b8b9e..822af0c 100644 --- a/src/chapter3.2.md +++ b/src/chapter3.2.md @@ -1,21 +1,23 @@ ## Runtime fetching models -Lo scopo di questa seconda applicazione è mostrare come sia possibile recuperare i modelli da renderizzare durante l'esecuzione dell'applicazione. -Questa funzione risulta particolarmente utile quando si deve rilasciare un'applicazione che sfrutta un numero elevato di modelli e non si vuole appesantire il volume del file *apk*[^apk]. -Inoltre è possibile aggiungere nuovi modelli, o aggiornare quelli vecchi, senza dover aggiornare l'applicazione, ma lavorando esclusivamente lato server. +Nella seconda applicazione d'esempio viene mostrato come sia possibile recuperare i modelli da renderizzare anche durante l'esecuzione dell'applicazione. +Questa funzione risulta particolarmente utile quando si deve rilasciare un'applicazione che sfrutta numerosi modelli e non si vuole appesantire eccessivamente il volume del file *APK*. +Inoltre concede maggiore libertà allo sviluppatore in quanto è possibile aggiungere nuovi modelli, o aggiornare quelli vecchi, senza dover operare sull'applicazione, ma lavorando esclusivamente lato server. -Per quest'applicazione oltre alle configurazioni già viste in precedenza dobbiamo aggiungere una nuova dipendenza che include le funzioni necessarie per il fetching del modello. +In questo caso specifico l'applicazione dovrà riconosce uno o più piani e in seguito ad un tocco dell'utente su di essi, mostrare un modello di *Andy*, la mascotte di Android. + +Per quest'applicazione oltre alle configurazioni già viste in precedenza è necessario aggiungere una nuova dipendenza che include le funzioni necessarie per il fetching del modello. ```gradle implementation 'com.google.ar.sceneform:assets:1.6.0' ``` -Inoltre nell'AndroidManifest bisogna aggiungere il permesso per accedere alla rete. +Inoltre nell'Android Manifest bisogna aggiungere il permesso per accedere alla rete. ### Interazione con l'utente -L'interazione con l'utente avviene mediante un tocco sul display. -Sceneform ci permette di personalizzare il comportamento al verificarsi di questo evento tramite un listener. +L'interazione con l'utente avviene mediante un tocco sul display in corrispondenza di un piano. +Sceneform ci permette di personalizzare il comportamento al verificarsi di questo evento tramite il metodo `setOnTapArPlaneListener`. ```kotlin override fun onCreate(savedInstanceState: Bundle?) { @@ -47,7 +49,7 @@ private fun fetchAndPlaceModel( ### Fetching del model -Il recupero del modello avviene attraverso la funzione `fetchModel`. +Il recupero del modello avviene attraverso la funzione `fetchModel`, che a sua volta chiama la funzione di libreria `RenderableSource.builder()`. ```kotlin fun fetchModel( @@ -65,7 +67,7 @@ Attualmente[^sceneform-1.6] Sceneform supporta unicamente il fetching di modelli ### Rendering e aggiunta del modello -Il rendering del modello avviene tramite la funzione `buildRenderable`, che è molto simile a quella utilizzata nel progetto precedente, con la differenza che in questo caso deve essere passato anche il modello che si è recuperato in precedenza. +Il rendering del modello avviene tramite la funzione `buildRenderable`, che riprende in buona parte quella vista precedentemente, con la differenza che in questo caso deve essere passato anche il modello recuperato. ```kotlin fun buildRenderable( @@ -86,7 +88,6 @@ fun buildRenderable( } ``` -L'aggiunta del modello renderizzato alla scena avviene mediante la medesima funzione `addTransformableNodeToScene` vista in precedenza. +Infine l'aggiunta del modello renderizzato alla scena avviene mediante la medesima funzione `addTransformableNodeToScene` vista in precedenza. [^sceneform-1.6]: Sceneform 1.6.0. -[^apk]: Formato delle applicazioni android. From ee79030a57accb7ec4fc6e7ecc0ea42f5b88aefd Mon Sep 17 00:00:00 2001 From: norangebit Date: Wed, 9 Jan 2019 19:15:52 +0100 Subject: [PATCH 6/6] correzione errori --- src/chapter3.1.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/chapter3.1.md b/src/chapter3.1.md index 91c37b4..cc89b41 100644 --- a/src/chapter3.1.md +++ b/src/chapter3.1.md @@ -13,10 +13,10 @@ L'importazione del modello all'interno del progetto di Android Studio è stato e ### Creazione del database -Il database contenete tutte le immagini che si desidera far riconosce all'applicazione, può essere creato sia a priori, sia a tempo di esecuzione. -Per la prima soluzione Google mette a disposizione *The arcoreimag tool*, un software a linea di comando, che oltre a creare il database si occupa anche di valutare l'immagine. +Il database contenente tutte le immagini che si desidera far riconosce all'applicazione, può essere creato sia a priori, sia a tempo di esecuzione. +Per la prima soluzione Google mette a disposizione *The arcoreimag tool*, un software a linea di comando, che oltre a creare il database, si occupa anche di valutare l'immagine. -Dato che nel caso specifico si vuole far riconoscere un'unica immagine si è optato per la generazione del database a runtime. +Dato che nel caso specifico si vuole far riconoscere un'unica immagine, si è optato per la generazione del database a runtime. In particolare quest'operazione avviene mediante la funzione `setupAugmentedImageDb`. ```kotlin @@ -35,7 +35,7 @@ private fun setupAugmentedImageDb (config: Config): Boolean { Il riconoscimento dell'immagine non può avvenire mediate l'utilizzo di una callback in quanto ARCore non permette di registrare un listener all'evento. Risulta dunque evidente che la verifica dell'avvenuto match sarà delegata allo sviluppatore. -Per fare ciò si è usato il metodo `addOnUpdateListener` dell'oggetto `Scene`, che permette di eseguire del codice ogni qual volta la scena viene aggiornata. +Per fare ciò si è usato il metodo `addOnUpdateListener` dell'oggetto `Scene`, che permette di eseguire un pezzo di codice ogni qual volta la scena viene aggiornata. ```kotlin override fun onCreate(savedInstanceState: Bundle?) { @@ -102,7 +102,7 @@ fun buildRenderable( ### Aggiunta dell'oggetto virtuale nella scena L'ultima operazione da compiere è l'aggiunta del modello renderizzato alla scena. -Questa operazione avviene attraverso la funzione `addTrasformableNodeToScene()` che si occupa di creare un ancora in corrispondenza del punto reale d'interesse. +Questa operazione avviene attraverso la funzione `addTrasformableNodeToScene` che si occupa di creare un'ancora in corrispondenza del punto reale d'interesse. A partire da quest'ancora viene creato un nodo che racchiude l'oggetto renderizzato. Inoltre nel caso specifico si è usato un `TransformabelNode`, in modo da concedere all'utente la possibilità di ridimensionare o ruotare il modello.