La realtà virtuale (virtual reality, VR) ha sempre affascinato il grande pubblico trovando applicazione in diversi ambiti, dai videogiochi al cinema, passando per settori quali l’archeologia e il settore militare. Grazie alla realtà simulata vissuta attraverso dispositivi ad-hoc come guanti, visori e auricolari, l’utilizzatore finale viene completamente immerso in un mondo artificialmente ricostruito dove tutto diventa possibile e i cui limiti sono imposti solo dalla fantasia dello sviluppatore. Oggigiorno, la VR è diventata accessibile a chiunque mediante il proprio smartphone e visori low-cost che l’hanno resa sempre più popolare.
In questo articolo, si focalizzerà l’attenzione sugli aspetti basilari per permettere ad un’applicazione Android di offrire contenuti VR. Per farlo, è necessario rispettare i seguenti prerequisiti:
Strumento | Versione | Descrizione |
---|---|---|
Android Studio | 2.2.2 o superiori | IDE di sviluppo ufficiale per sviluppare app Android, come illustrato qui |
Dispositivo Android | 4.4 o superiori | Dispositivo fisico su cui eseguire e testare l’applicazione |
Android SDK | 24 o superiori | API per lo sviluppo di applicazioni Android, per dettagli consultare la guida |
Gradle | 23.0.1 | strumento per la build automation. Qualora fosse installata una versione più vecchia del Gradle, Android Studio chiederà di aggiornarla |
Google VR SDK (GVRSDK) | 1.60.0 o superiori | Libreria open source (reperibile su GitHub |
Cardboard | - | Visore in cartone composto da lenti con una distanza focale di 40mm che può essere acquistato o costruito scaricando il modelli per la costruzione, come riportato sulla pagina ufficiale |
In particolare, la GVRSDK offre un set di API per semplificare lo sviluppo di tipiche funzionalità di VR, come la correzione della distorsione delle lenti e la calibrazione 3D. Inoltre, la GVRSDK è una libreria cross-platform (Androd e iOS) e offre pieno supporto ai framework Unity e Unreal per lo sviluppo di giochi e ambienti 3D interattivi.
Google VR SDK – codice d’esempio
Diversamente da molte librerie Android, la GVRSDK può essere importata all’interno di un progetto esclusivamente attraverso le dipendenze di Gradle. Ciò nonostante, essendo una libreria open source è possibile scaricare il repository e i relativi esempi tramite il seguente comando Git:
git clone https://github.com/googlevr/gvr-android-sdk.git
Aprendo il progetto in Android Studio (Figura 1), sarà possibile compilare ed eseguire sul proprio dispositivo i vari progetti d’esempio. Tra i template di progetto disponibili, selezioniamo quello per Daydream, un visore per la realtà virtuale munito di controller addizionale e supportato solo da un insieme limitato di dispositivi Android. Per questo motivo, non verrà trattato in questo articolo.
Nota Gradle.Script
Set-up GVRSDK
Creiamo un nuovo progetto Android con le seguenti impostazioni:
Nome Progetto | AndroidVRTutorial |
---|---|
Minimum SDK | API 19: Android 4.4 (KitKat) |
Una volta inizializzato il progetto, all’interno del build.gradle
jcenter()
allprojects {
repositories {
jcenter()
}
}
...
A questo punto, devono essere impostate le dipendenze alle API di interesse della libreria nel build.gradle
dependencies {
. . .
compile 'com.google.vr:sdk-panowidget:1.60.0'
}
In particolare, la GVRSDK è composta da sette package: uno come parte della NDK, mentre i restanti sei come parte della SDK. Si riporta una breve descrizione di questi:
Repository | Descrizione |
---|---|
com.google.vr.ndk.base | API per il core delle API GVR |
com.google.vr.sdk.base | API per il core delle API GVR |
com.google.vr.sdk.audio | API per la gestione dell’audio 3D |
com.google.vr.sdk.controller | API per la gestione del controller del Daydream |
com.google.vr.sdk.widgets.common | API condivise per le VR view (API sperimentali in sostituzione delle seguenti) |
com.google.vr.sdk.widgets.pano | API per la gestione delle VR view per le immagini Panorama |
com.google.vr.sdk.widgets.video | API per la gestione delle VR view per i video |
Le VR View decompilazione degli APK proguard-gvr.txt
android {
...
buildTypes {
release {
minifyEnabled true
proguardFiles.add(file('../../proguard-gvr.txt'))
}
}
}
Una volta salvato il file e sincronizzati i file del Gradle
VR View e immagini Panorama
Le VR View supportano due diverse tipologie di immagini panoramiche:
- Mono 360, unica foto panoramica (Figura 2.a);
- Stereo 360, due foto panoramiche impilate (Figura 2.b).
Entrambe le tipologie devono rispettare determinate specifiche per poter essere processate correttamente dalla VR View:
Formati supportati | jpg, png, o gif |
Proporzioni Mono 360 | 2:1 (es: 4096 x 2048) |
Proporzioni Stereo 360 | 1:1 (es: 4096 x 4096) |
Inoltre, è importante che le immagini rispettino la proiezione cilindrica equidistante
Tenendo presenti tali informazioni, integriamo nell’applicazione un widget per la visualizzazione di un’immagine sferica.
Nel progetto Android, aggiungiamo una nuova cartella, assets
All’interno del main_layout.xml
VrPanoramaView
RelativeLayout
<com.google.vr.sdk.widgets.pano.VrPanoramaView
android:id="@+id/vr_panorama"
android:layout_margin="5dip"
android:layout_width="match_parent"
android:layout_centerInParent="true"
android:scrollbars="none"
android:layout_height="250dip" />
In Java, apriamo la classe MainActivity
onCreate
private static final String TAG = "AndroidVRTutorial";
private VrPanoramaView vrPanoramaView;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
vrPanoramaView = (VrPanoramaView) findViewById(R.id.vr_panorama);
}
Implementiamo, adesso, un semplice metodo da richiamare all’interno dell’onCreate
private void loadPanoramaImage() {
VrPanoramaView.Options options = null;
InputStream inputStream = null;
AssetManager assetManager = getAssets();
try {
inputStream = assetManager.open("panorama.jpg");
options = new VrPanoramaView.Options();
options.inputType = VrPanoramaView.Options.TYPE_MONO;
vrPanoramaView.loadImageFromBitmap(BitmapFactory.decodeStream(inputStream), options);
try {
inputStream.close();
} catch (IOException e) {
Log.e(TAG, "Could not close input stream: " + e);
}
} catch (IOException e) {
Log.e(TAG, "Exception in loadPhotoSphere: " + e.getMessage());
}
}
In particolare, essendo l’immagine negli assets dell’applicazione, è necessario istanziare l’AssetManager
open
Successivamente, attraverso la proprietà Options
TYPE_MONO
TYPE_STEREO_OVER_UNDER
Infine, l’immagine panoramica viene caricata come un’immagine Bitmap
loadImageFromBitmap
vrPanoramaView
Non resta che gestire il ciclo di vita della VR Activity. Per farlo, è necessario gestire il rendering del VrPanoramaView
Metodo ciclo di vita | Metodo da richiamare | Descrizione |
onPause
|
pauseRendering()
|
Mette in pausa il rendering dell’immagine al sorpaggiungere di altri eventi |
onResume
|
resumeRendering()
|
Fa ripartire il rendering quando l’utente interagisce nuovamente con l’applicazione |
onDestroy
|
shutdown()
|
Distrugge il widget e libera la memoria |
Nota
AsyncTask
In Figura 4, è riportato il risultato finale dell’applicazione.
In alternativa, è possibile impiegare la modalità fullscreen (Figura 5.a) per una visione più immersiva dell’immagine o in modalità Cardboard che permette all’utente di visualizzare l’immagine panorama usando la Cardboard (Figura 5.b).
Il codice d’esempio è reperibile su GitHub