init chapter 3
- add augmented images project
This commit is contained in:
parent
6b0b7f5624
commit
c893958326
135
src/chapter3.md
Normal file
135
src/chapter3.md
Normal file
@ -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.
|
Loading…
Reference in New Issue
Block a user