googlevr / gvr-android-sdk

Google VR SDK for Android
http://developers.google.com/vr/android/
Other
3.28k stars 1.28k forks source link

HeadView matrix rotated 90° around Z axis #556

Closed Consti10 closed 6 years ago

Consti10 commented 6 years ago

Problem: I am using Vertex displacement distortion correction for undistortion and therefore not the gvr_api undistortion (initially). Only the head tracking via gvr_api->GetHeadSpaceFromStartSpaceRotation(target_time);

According to the documentation in "gvr_types.h" the Mat4f is in row-major form, so I convert it to a glm matrix (which is colum-major) by transposing once: e.g. headViewGLM=glm::transpose(headViewGVR);

This was working fine with some older version of gvr (unfortunately i dont know which), but since the update to 1.140.0 the resulting GLM matrix is rotated 90° around the Z axis.

Why did no one notice this (yet): I just recently added support for the "Daydream async video texture" to my app and therefore am now also using the gvr distortion. These 2 modes (vddc and gvr) are basically the same - only now I am using the gvr distortion correction. My rendering code now looks like: swap_chain->AcquireFrame(); calculateNewHeadPose(); draw( headViewGLM) frame.Submit(buffer_viewports, headViewGVR) (Note the use of the GLM and GVR headView)

Suddenly the scene is in the right rotation.

So I am assuming that the gvr_api distortion function internally rotates the picture 90° (maybe correcting for the "landscape mode" rotation in the headset) and the view matrix obtained from the gvr_api head tracker uses a rotation 90° the other way around.

Since this adds unnecessary compability issues when not using the gvr_api distortion please confirm or unconfirm this assumption and add a documentation about the coordinate system and orientation used internally by the gvr_api head tracker.

jdduke commented 6 years ago

Hi @Consti10, what device are you using when you observe the issue? And what orientation is your Activity? You mentioned that this behavior changed in 1.140.0; was it different in 1.130.0? Thanks.

jdduke commented 6 years ago

Actually, this sounds a lot like issue #536. Can you make sure you're calling GvrLayout.onResume() when the Activity is resumed (and onPause() when the Activity is paused)?

Consti10 commented 6 years ago

The description of "SPGD" matches perfectly my problem "the world shifts into what looks like portrait mode and Looking vertically around the world will move horizontally (and vice versa)." Though there is one big difference: I am not using (and cannot use) the GvrView api. instead, I am using GvrLayout and installing a custom OpenGL View via mGvrLayout.setPresentationView(mGLView14Stereo);

@1 I am using a ZTE Axon 7. Tested it on a Nexus 5X, too. Same problem (couldnt test the Daydream video texture on it though, of course)

@2 Activity orientation is set to SCREEN_ORIENTATION_LANDSCAPE both via XML and java in onResume.

@3 can't tell. But the sudden change in the orientation is already a while ago and possibly already occured in february (only now as I am using the same renderer in Daydream Timewarp mode- which suddenly rearranged the scene) I opened the issue.

May it be me installing a custom view in the GvrLayout ? Since that is the only other difference between Vertex displacement distortion correction mode and Daydream Timewarp mode.

OH MAN: calling mGvrLayout.onPause(); and "resume" actually re-inverted it. I was doing this: mGvrLayout.getGvrApi().pauseTracking(); and "resume"

This fixes it partially. Why partially ? Calling onPause() and onResume() on my gvr layout causes it to crash sometimes when using my custom OpenGL view (which is doing front buffer rendering with vertex displacement distortion correction, so definitely not common). I will have a look into that and maybe open a new issue on that.

But in conclusion: Thanks jdduke, calling onPause() and onResume() on the GvrLayout instance instead of on the gvrApi instance fixed this problem.

gcalero commented 6 years ago

Hi everyone, this may help anyone else. I'm working on an app that renders using a C++ engine so I get the GvrApi and pass it to C++. I DON'T use GvrLayout. The key to fix this issue in my case was forward onPause() and onResume to the DisplaySynchronizer object used to build the GvrApi.