correzioni errori
This commit is contained in:
parent
1576f7414f
commit
283d10568e
@ -22,7 +22,7 @@ Sempre nel file per il build del progetto è necessario aggiungere la dipendenza
|
||||
implementation 'com.google.ar.sceneform.ux:sceneform-ux:1.6.0'
|
||||
```
|
||||
|
||||
Inoltre per sfruttare al massimo le potenzialità offerte da Sceneform e ridurre al minimo il lavoro extra per la gestione delle view si deve aggiungere il fragment di Sceneform al file di layout dell'activity principale mediante il seguente codice xml.
|
||||
Inoltre per sfruttare al massimo le potenzialità offerte da Sceneform e ridurre al minimo il lavoro extra per la gestione delle view, si deve aggiungere il fragment di Sceneform al file di layout dell'activity principale mediante il seguente codice xml.
|
||||
|
||||
```xml
|
||||
<fragment
|
||||
@ -34,7 +34,7 @@ Inoltre per sfruttare al massimo le potenzialità offerte da Sceneform e ridurre
|
||||
|
||||
Infine 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.
|
||||
[^manifest]: File in cui vengono dichiarate tutte le 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.
|
||||
|
||||
|
@ -17,9 +17,8 @@ override fun onCreate(savedInstanceState: Bundle?) {
|
||||
}
|
||||
```
|
||||
|
||||
La verifica di una collisione può essere effettuata o attraverso il metodo `overlapTest`, che dato un nodo in input restituisce il primo nodo che entra in collisione con questo.
|
||||
Oppure mediante il metodo `overlapTestAll`, che dato un nodo in input restituisce una lista con tutti i nodi che collidono con esso.
|
||||
Nel caso in cui non sono state riscontrate collisioni i metodi restituiscono rispettivamente `null` e una lista vuota.
|
||||
La verifica di una collisione può essere effettuata o attraverso il metodo `overlapTest`, che dato un nodo in input restituisce il primo nodo che entra in collisione con questo, oppure mediante il metodo `overlapTestAll`, che dato un nodo in input restituisce una lista con tutti i nodi che collidono con esso.
|
||||
Nel caso in cui non siano state riscontrate collisioni, i metodi restituiscono rispettivamente `null` e una lista vuota.
|
||||
|
||||
La funzione `onUpdate` si occupa di verificare la presenza di collisioni.
|
||||
|
||||
@ -60,7 +59,7 @@ override fun onCreate(savedInstanceState: Bundle?) {
|
||||
}
|
||||
```
|
||||
|
||||
Con la funzione `addShape` che, utilizzando le funzioni `buildMaterial` e `buildShape` analizzate in precedenza, si occupa dell'effettiva aggiunta dell'aggetto alla scena.
|
||||
La funzione `addShape`, utilizzando le funzioni `buildMaterial` e `buildShape` analizzate in precedenza, si occupa dell'effettiva aggiunta dell'aggetto alla scena.
|
||||
|
||||
```kotlin
|
||||
private fun addShape(
|
||||
@ -82,6 +81,6 @@ private fun addShape(
|
||||
}
|
||||
```
|
||||
|
||||
Risulta importante notare che attraverso questa strategia l'aggiunta del modello alla scena avvenga incondizionatamente, ed è solo all'aggiornamento di quest'ultima che si effettua il controllo di collisione sull'ultimo nodo aggiunto.
|
||||
Risulta importante notare come attraverso questa strategia l'aggiunta del modello alla scena avvenga incondizionatamente, ed è solo all'aggiornamento di quest'ultima che si effettua il controllo di collisione sull'ultimo nodo aggiunto.
|
||||
|
||||
[^toast]: Oggetto nativo di Android mediante il quale è possibile informare l'utente in modo non invasivo.
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
Negli esempi discussi fino a questo momento sono stati usati unicamente asset tridimensionali statici.
|
||||
Gli oggetti virtuali che di volta in volta sono stati integrati nel mondo reale non erano né dotati di animazioni, né erano in grado di muoversi all'interno dell'ambiente reale circostante.
|
||||
La scelta di utilizzare modelli statici è stata dettata da un lato dalla filosofia *kiss*[^kiss], e quindi di concentrassi unicamente sull'aspetto rilevante del progetto, dall'altro da un supporto quasi inesistente alle animazioni e al movimento.
|
||||
La scelta di utilizzare modelli statici è stata dettata da un lato dalla filosofia *kiss*[^kiss], e quindi di concentrarsi unicamente sull'aspetto rilevante del progetto, dall'altro da un supporto quasi inesistente alle animazioni e al movimento.
|
||||
|
||||
Come abbiamo avuto modo di vedere nel secondo capitolo, queste lacune sono da imputare principalmente alla libreria grafica.
|
||||
Infatti sia per le animazioni, sia per la gestione del movimento, Sceneform non offre alcun supporto nativo o diretto.
|
||||
@ -15,14 +15,14 @@ Questo è ancora più vero nello sviluppo di applicazioni AR su smartphone che,
|
||||
Il mancato utilizzo di un'animazione potrebbe segnare in modo permanete l'esperienza utente e quindi determinare il fallimento del progetto.
|
||||
|
||||
Non a caso uno dei problemi più discussi nell'issues tracker di Sceneform su GitHub[@googlear:Animated3DObjects:2019], è proprio la totale mancanza di supporto alle animazioni.
|
||||
Sebbene ci siano stati dei lavori in questo senso ed una prima contabilità con i modelli animati FBX si stata aggiunta alla code base, ad oggi non è possibile utilizzare questa funzione, in quanto è in fase di testing per il solo personale interno.
|
||||
Sebbene ci siano stati dei lavori in questo senso ed una prima contabilità con i modelli animati FBX sia stata aggiunta alla code base, ad oggi non è possibile utilizzare questa funzione, in quanto è in fase di testing per il solo personale interno.
|
||||
|
||||
In attesa di un rilascio al pubblico, l'unica via percorribile è quella presentata dalla stessa Google durante un codelab[@googlear:ChromaKey:2019].
|
||||
La soluzione consiste nel renderizzare un schermo trasparente nel mondo reale e proiettare su di esso un video.
|
||||
Affinché l'*illusione* riesca è necessario usare un video che sfrutti il *chroma key*[^chroma-key], in questo modo l'integrazione con il mondo reale risulta migliore.
|
||||
Inoltre per impedire che l'utente possa guardare il retro dello schermo è consigliabile rendere quest'ultimo solidale con l'utente.
|
||||
|
||||
Non solo risultano evidenti le limitazioni di questo metodo, ma anche la natura più di *pezza* che soluzione al problema.
|
||||
Non solo risultano evidenti le limitazioni di questo metodo, ma anche la natura più di *pezza* che soluzione al problema, che non lo rendono adatto per un utilizzo commerciale.
|
||||
|
||||
[^kiss]: Acronimo di *Keep It Simple, Stupid*, è un principio di programmazione che consiglia di concentrarsi su un problema alla volta.
|
||||
|
||||
|
@ -10,8 +10,8 @@ Per mostrare il funzionamento degli animator è stato realizzato un progetto d'e
|
||||
#### Recupero e rendering dei modelli
|
||||
|
||||
Visto l'elevato numero di modelli con cui si deve operare si è scelto di recuperarli da un server a runtime.
|
||||
Il procedimento è simile a quello visto precedentemente, con la differenza che in questo caso si è scelto di non usare le callback, al fine di evitare il *callback hell*[^callback-hell], a favore delle *coroutines*, uno strumento messo a disposizione dal linguaggio Kotlin che permette di gestire codice asincrono come se fosse sequenziale.
|
||||
Inoltre sempre attraverso le *coroutines* è stato possibile eseguire più rendering in parallelo e quindi ottimizzare il tempo di CPU dell'applicazione.
|
||||
Il procedimento è simile a quello visto precedentemente, con la differenza che in questo caso non si è optato per l'utilizzo delle callback, al fine di evitare il *callback hell*[^callback-hell], a favore delle *coroutines*, uno strumento messo a disposizione dal linguaggio Kotlin che permette di gestire codice asincrono come se fosse sequenziale.
|
||||
Sempre attraverso le *coroutines* è stato possibile eseguire più rendering in parallelo e quindi ottimizzare il tempo di CPU dell'applicazione.
|
||||
|
||||
All'interno del metodo `onCreate` viene avviata una coroutine che richiama la funzione `loadPlanets`.
|
||||
Inoltre viene conservato un riferimento al `Job` della coroutine.
|
||||
@ -49,7 +49,7 @@ suspend fun loadPlanets(
|
||||
```
|
||||
|
||||
Nella funzione `loadPlanet` viene da prima recuperato il modello tridimensionale dal server e successivamente se ne effettua il rendering attraverso la funzione `buildFutureRenderable`.
|
||||
Quest'ultima, come abbiamo già visto, restituisce un `CompletableFuture` che per poter essere utilizzarlo tramite delle coroutines deve essere trasformarlo in un `Deferred`[^deferred].
|
||||
Quest'ultima, come abbiamo già visto, restituisce un `CompletableFuture` che per poter essere utilizzato tramite delle coroutines deve essere trasformarlo in un `Deferred`[^deferred].
|
||||
Questa operazione avviene attraverso il costruttore di coroutines `async`.
|
||||
Inoltre viene usato il dispatcher `IO` che ci consente di eseguire l'operazione in background.
|
||||
|
||||
@ -90,7 +90,7 @@ Per realizzare le orbite e i pianeti è stata implementata la classe `RotationNo
|
||||
|
||||
Componente principale di questa è la funzione `createAnimator` che si occupa della creazione dell'`ObjectAnimator` che permette di muovere i modelli.
|
||||
All'interno della funzione vengono definiti i punti da cui ottenere la rotazione attraverso l'interpolatore.
|
||||
Inoltre viene impostato l'`ObjectAnimator` affinché riproduca in loop l'animazione.
|
||||
Infine viene impostato l'`ObjectAnimator` affinché riproduca in loop l'animazione.
|
||||
|
||||
```kotlin
|
||||
private fun createAnimator(): ObjectAnimator {
|
||||
@ -127,7 +127,8 @@ override fun onDeactivate() {
|
||||
```
|
||||
|
||||
La creazione dei pianeti è gestita attraverso un ulteriore classe, `PlanetNode`, anch'essa estensione della classe `Node`.
|
||||
Questa classe altro non è che un nodo che come attributo ha un `RotationNode`.
|
||||
Quest'ultima viene definita come un nodo dotato di un `Renderable` ancorato ad un `RotationNode`.
|
||||
Come vedremo in seguito questa operazione si rende necessaria per garantire il moto di rivoluzione.
|
||||
|
||||
La creazione delle orbite e dei pianeti avviene mediante la funzione `createPlanetNode`.
|
||||
L'orbita del pianeta viene ancorata al nodo principale, nel caso specifico il sole, e il pianeta viene ancorato alla sua orbita.
|
||||
@ -160,7 +161,7 @@ private fun createPlanetNode(
|
||||
|
||||
#### Creazione e aggiunta del sistema solare
|
||||
|
||||
La creazione del nostro sistema solare avviene mediante la funzione `createSolarSystem` che riceve in ingresso la `Map` con tutti i modelli dei pianeti, li posizionare intorno al sole e infine restituisce quest'ultimo.
|
||||
La creazione del nostro sistema solare avviene mediante la funzione `createSolarSystem` che riceve in ingresso la `Map` con tutti i modelli dei pianeti, li posiziona intorno al sole e infine restituisce quest'ultimo.
|
||||
|
||||
```kotlin
|
||||
private fun createSolarSystem(
|
||||
|
Loading…
Reference in New Issue
Block a user