In my Cardboard app for Android, I want to display an overlay in each eye that centers. Simply creating a LinearLayout with two centered views is fairly easy and works for most phones as the eyes are drawn to best fit:
When that's not the case, getting something to center in each eye becomes a problem. It's most clearly illustrated when using a tablet:
I'm trying to get the message "Buffering, 0%..." centered inside each eye view.
The size of the render boxes for the eyes has a fixed dimension (of course, because the distance between human eyes has a fairly fixed size). Unfortunately, CardboardView doesn't appear to provide information about the exact size and/or position of the eyes.
I've looked into obtaining the left and right Eye through cardboardView.getCurrentEyeParams()
(oddly undocumented), for which each Eye contains a Viewport. This appears to give a size and position, but its values don't appear to have an immediate relation with the size and placement on the screen.
On a LG G2 with a screen resolution of 1920×1080, the Viewports are:
Viewport left: {
x: 0,
y: 0,
width: 1150,
height: 1177,
}
Viewport right: {
x: 1150,
y: 0,
width: 1150,
height: 1177,
}
On a Nexus 9 with a screen resolution of 2048×1536, the Viewports are:
Viewport left: {
x: 0,
y: 0,
width: 802,
height: 802,
}
Viewport right: {
x: 802,
y: 0,
width: 802,
height: 802,
}
Both of these dimensions (if they're in pixels) are much larger than the actual image displayed, and in the case of the LG G2, the width and height indeed larger than the screen size of 1080px.
Looking into some decompiled code of the Cardboard SDK, it appears that the vignetted square around the eyes is drawn through an internal class called DistortionMesh, and is rendered through some somewhat complex code. (Note that some logic appears to be missing through decompilation, such as lines 195 and 199.)
The creation of the Viewport suggests that the values are indeed pixels (offset in meters, multiplied by pixels per meter). Perhaps that DistortionMesh or the EyeView matrix is applied to the Viewport before rendering? In any case, I get the feeling I'm not looking in the right place.
I've also taken a look at obtaining the ScreenParams, as it provides a width and height as well. Unfortunately, this returns the entire screen size on both devices and also doesn't appear to be relevant.
My current approach overlay is a custom ViewGroup that centers two children through calling child.layout()
using the ScreenParams' height and half of its width.
How can I figure out how large the Eyes are drawn into StereoRenderer? Can I find a different way to center a different view in the eyes?
cardboardView.getCurrentEyeParams(head, leftEye, rightEye, monocular, leftEyeNoDistortionCorrection, rightEyeNoDistortionCorrection)
. I then extract the Viewport fromleftEye
andrightEye
. – Effeminate