Virtual Reality with Android and Google Cardboard

0
1574

The virtual reality ( virtual reality, VR ) has always fascinated the general public finding application in various fields, from video games to movies, passing through areas such as archeology and the military. Thanks to the simulated reality experienced through ad-hoc devices such as gloves, viewers and earphones, the end user is completely immersed in an artificially reconstructed world where everything becomes possible and whose limits are imposed only by the imagination of the developer. Nowadays, VR has become accessible to anyone through its smartphone and low-cost viewers that have made it increasingly popular.

In this article, we will focus on the basic aspects of allowing an Android application to offer VR content. To do this, the following prerequisites must be met:

Tool Version Description
Android Studio 2.2.2 or higher IDE official development to develop an Android app, as shown here
Android device 4.4 or higher Physical device on which to run and test the application
Android SDK 24 or higher API for the development of Android applications, for details, see the guide
Gradle 23.0.1 tool for build automation. If an older version of the Gradle is installed, Android Studio will ask you to update it
Google VR SDK (GVRSDK) 1.60.0 or higher Open source library (available on GitHub ) developed by Google to make VR-friendly Android applications
cardboard Cardboard viewer composed of lenses with a focal length of 40mm that can be purchased or built by downloading the models for construction, as reported on the official page

In particular, the GVRSDK offers a set of APIs to simplify the development of typical VR features, such as lens distortion correction and 3D calibration. In addition, the GVRSDK is a cross-platform library (Android and iOS) and offers full support for Unity and Unreal frameworks for developing interactive 3D games and environments.

Google VR SDK – sample code

Unlike many Android libraries, the GVRSDK can be imported into a project exclusively through Gradle’s dependencies. Nevertheless, being an open source library it is possible to download the repository and its examples through the following Git command :

git clone https://github.com/googlevr/gvr-android-sdk.git

Opening the project in Android Studio (Figure 1), it will be possible to compile and run the various sample projects on your device. Among the available project templates, we select the one for Daydream, a virtual reality viewer equipped with an additional controller and supported only by a limited set of Android devices. For this reason, it will not be covered in this article.

GVRSDK Project on Android Studio
GVRSDK Project on Android Studio

Note: If filling out the Gradle fails, there may be problems with the version of the GVRSDK. To work around this, simply set up an older version of the SDK from Gradle. The script as shown below.

GVRSDK set-up

We create a new Android project with the following settings:

Project Name AndroidVRTutorial
Minimum SDK API 19: Android 4.4 (KitKat)

 

Once the project is initialized, within the build.gradle there will be the method jcenter()for integrating Android archives (Android Archive – AAR), including those for GVRSDK, within the application.

allprojects {
    repositories {
        jcenter ()
    }
}
...

At this point, dependencies on APIs of interest to the library must be set in the build.gradle of the app module. For example, the following code will add support for the panorama view widget.

dependencies {
    . . .
    compile 'com.google.vr: sdk-panowidget: 1.60.0'
}

In particular, the GVRSDK consists of seven packages: one as part of the NDK, while the remaining six as part of the SDK. A brief description of these is given:

In particular, the GVRSDK consists of seven packages: one as part of the NDK, while the remaining six as part of the SDK. A brief description of these is given:

Repository Description
com.google.vr.ndk.base API for the core of GVR APIs
com.google.vr.sdk.base API for the core of GVR APIs
com.google.vr.sdk.audio API for managing 3D audio
com.google.vr.sdk.controller API for managing the Daydream controller
com.google.vr.sdk.widgets.common Shared APIs for VR views (experimental APIs replacing the following)
com.google.vr.sdk.widgets.pano API for managing VR views for Panorama images
com.google.vr.sdk.widgets.video API for managing VR views for videos

 

The VR View are the SDK specialized components for the support and integration of the contents to 360 degrees that handle transactions for uploading and managing content. In addition, to remedy the problem of APK decompilation, it is recommended to set up Proguard using the proguard-gvr.txt file, replacing the existing code portion as follows:

The VR View is the SDK specialized components for the support and integration of the contents to 360 degrees that handle transactions for uploading and managing content. In addition, to remedy the problem of APK decompilation, it is recommended to set up Proguard using the proguard-gvr.txt file , replacing the existing code portion as follows:

android {
    ...
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles.add (file ( '../../ proguard-gvr.txt'))
        }
    }
}

Once the file is saved and the Gradle files are synchronized, we are finally ready to use the GVRSDK in our project.

VR View and Panorama images

VR Views support two different types of panoramic images:

  • Mono 360, unique panoramic photo (Figure 2.a);
  • Stereo 360, two stacked panoramic photos (Figure 2.b).
a) Mono 360, b) Stereo 360 (source: Google Developer )
a) Mono 360, b) Stereo 360 (source: Google Developer )

Both types must comply with certain specifications in order to be processed correctly by VR View:

Supported formats jpg, png, or gif
Mono 360 Proportions 2: 1 (ex: 4096 x 2048)
Proportions Stereo 360 1: 1 (ex: 4096 x 4096)

 

Furthermore, it is important that the images respect the equidistant cylindrical projection, and in the case of cubic images, these must be converted according to the aforementioned projection.

With this information in mind, we integrate a widget into the application for displaying a spherical image.

In the Android project, we add a new folder, assets, which will contain the Mono 360 image to show on the screen and shown in Figure 3.

Sample image (source: pixabay )

Inside the main_layout.xml we insert the widget of the VrPanoramaViewlocation in the middle of the RelativeLayout, as follows:

<pre class=”brush: php; html-script: true”>
<com.google.vr.sdk.widgets.pano.VrPanoramaView
android: id = “@ + id / vr_panorama”
Android: layout_margin = “5dip”
Android: layout_width = “match_parent”
Android: layout_centerInParent = “false”
android: scrollbars = “none”
android: layout_height = “250dip” />
</pre>

In Java, we open the class MainActivityand add onCreatethe reference to the widget within the method .

 

private static final String TAG = "AndroidVRTutorial";
private VrPanoramaView vrPanoramaView;
@Override
protected void onCreate (Bundle savedInstanceState) {
    ...
    vrPanoramaView = (VrPanoramaView) findViewById (R.id.vr_panorama);
}

We now implement a simple method to be called within onCreatefor loading the 360 ° image on the screen.

 

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 particular, since the image is in the assets of the application, it is necessary to instantiate the AssetManagerfile to load the file by calling the method open.

Subsequently, the Options image upload mode can be set using the widget property. In this case, the TYPE_MONOappropriate property for loading the Mono 360 image was defined. Alternatively, for the Stereo 360 images, it is necessary to use the type TYPE_STEREO_OVER_UNDER.

Finally, the panoramic image is loaded as an image Bitmappassed as a parameter to the loadImageFromBitmapobject’s method vrPanoramaView.

All that remains is to manage the lifecycle of VR Activity. To do this, you need to manage the rendering of the VrPanoramaViewfollowing:

Lifecycle method Method to recall Description
onPause pauseRendering() Pause the rendering of the image to overtake other events
onResume resumeRendering() Restores rendering when the user interacts with the application again
onDestroy shutdown() It destroys the widget and frees up memory

 

Note: to make the user experience more usable, it is advisable to load the panorama image in the background through, for example, a AsyncTask.

In Figure 4, the final result of the application is reported.

VR Panorama Activity

Alternatively, it is possible to use the fullscreen mode (Figure 5.a) for a more immersive view of the image or in Cardboard mode that allows the user to view the panorama image using the Cardboard (Figure 5.b).

VR Panorama Activity in a) fullscreen mode, b) Cardboard

The sample code can be found on GitHub.

LEAVE A REPLY

Please enter your comment!
Please enter your name here