Using a virtual screen

In virtual reality, the space you are looking into is bigger than what is on the screen at a given time. The screen is like a viewport into the virtual space. In this project, we're not calculating 3D views and clipping planes, and we're constraining the head motion to left/right yaw rotation.

You can think of the visible space as the inside surface of a cylinder, with your head at the center. As you rotate your head, a portion of the unraveled cylinder is displayed on the screen.

Using a virtual screen

The height of the virtual screen in pixels is the same as the physical device.

We need to calculate the virtual width. One way to do this, for example, would be to figure out the number of pixels in one degree of head rotation. Then, the width of a full rotation would be pixels per degree * 360.

We can easily find the physical width of the display in pixels. In fact, we already found it in onLayout as the viewWidth variable. Alternatively, it can be retrieved from the Cardboard SDK call:

    ScreenParams sp = cardboardView.getHeadMountedDisplay().getScreenParams();
    Log.d(TAG, "screen width: " + sp.getWidth());

From the SDK, we can also get the field of view (FOV) angle of the Cardboard headset (in degrees). This value will vary from one device to the next and is part of the Cardboard device configuration parameters:

    FieldOfView fov = cardboardView.getHeadMountedDisplay().getCardboardDeviceParams().getLeftEyeMaxFov();
    Log.d(TAG, "FOV: " + fov.getLeft());

Given this, we can calculate the number of pixels per degree and the total width in pixels of the virtual screen. For example, on my Nexus 4, the device width (landscape mode) is 1,280, and using a Homido viewer, the FOV is 40.0 degrees. Thus, the split screen view is 640 pixels, giving us 16.0 pixels per degree and a virtual screen width of 5,760 pixels.

While we're at it, we can also calculate and remember the pixelsPerRadian value, which will be useful to determine the head offset based on the current user's HeadTransform (given in radians).

Let's add it. At the top of the OverlayView class, add these variables:

    private int virtualWidth; 
    private float pixelsPerRadian;

Then, add the following method:

    public void calcVirtualWidth(CardboardView cardboard) {
        int screenWidth = cardboard.getHeadMountedDisplay().getScreenParams().getWidth() / 2;
        float fov = cardboard.getCardboardDeviceParams().getLeftEyeMaxFov().getLeft();
        float pixelsPerDegree = screenWidth / fov;
		pixelsPerRadian = (float) (pixelsPerDegree * 180.0 / Math.PI);
        virtualWidth = (int) (pixelsPerDegree * 360.0);
    }

In the onCreate method of MainActivity, add the following call:

        overlayView.calcVirtualWidth(cardboardView);

Note that the FOV value reported from the device parameters is a rough approximation defined by the headset manufacturer, and, in some devices, may be overestimated and padded. The actual FOV can be retrieved from the eye object passed to onDrawEye(), since that represents the actual frustum that should be rendered. Once the project is working, you might consider making this change to your own code.

Now, we can use these values to respond to the user's head look rotation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset