Fix for accelerometer reading in libgdx

I just got around fixing the longstanding issue of those funky new tablet devices with HC (and one Motorola Phone) that have a landscape native orientation. Here’s an image illustrating this super awesome situation (taken from NVIDIA’s accelerometer whitepaper):

As you can see, on phones, the native orientation is portrait. That means

  • The accelerometer x-axis coincides with the smaller side of the screen
  • The accelerometer y-axis coincides with the bigger side of the screen
  • The accelerometer z-axis comes out of the screen

On shiny new tablets like the Transformer the native orientation is landscape. That means:

  • The accelerometer x-axis coincides with the bigger side of the screen
  • The accelerometer y-axis coincides with the smaller side of the screen
  • The accelerometer z-axis comes out of the screen

Which is totally fucking awesome. Thankfully the Android API does not provide a direct method to detect the native orientation. With a bit of creativity (Display metrics + Display.getOrientation()/getRotation()) one can however reliably determine the native orientation.

I did just that, and we are now “correcting” the accelerometer readings for your convenience. No matter the device, the y-axis will always coincide with the bigger side of the screen, the x-axis will always coincide with the smaller side of the screen. Just as it was on phones for the last 3 years.

In addition to that i added two new methods to the Input interface:

The getRotation() method returns an angle in degrees (0, 90, 180, 270), indicating the rotation relative to the default orientation of the device. The getNativeOrientation() method returns, well, the native orientation.

If you “fixed” the above “issue” yourself so far, make sure you revert that when updating to the latest nightlies! All other methods to calculate the orientation on the three axes in angles and so on work as expected, with the same reference system on all devices.

edit: on the desktop these methods return 0 and Orientation.Landscape. Always. GdxRemote has to be adapted to report the correct values. I put that on my todo list.

  • Bach

    Thanks for this Mario. Sounds brilliant. I’ll check it out later :)

  • HAG

    Do I detect a hint of sarcasm? :P seriously though good stuff, thanks :)

  • Greystache

    I encountered this problem before and solved it with getRotation() as well.

    However in the Android API this method is only available for Android >= 2.2 so it crashes if you try to load a class calling this method on older devices. I ended up writing a wrapper that would check the Android version and load a class containing a call to this method if >=2.2, otherwise it just uses the default orientation..

    Hopefully this integrated in Libgdx will make it much more convenient, thanks Mario!

  • adeluiz

    OK, tested on Asus Transformer and SGS2. Very nice!!!!

  • http://www.theruins.ch Jonas

    Thanks Mario!
    How can I detect reverseLandscape/reversePortrait so I can flip my accelerometer movement accordingly? Could you add this too?

    Thanks and cheers!
    Jonas

  • http://badlogicgames.com Mario

    Check out gdx.input.getoerientation

  • Tiago

    That is weird, on my Galaxy W the getRotation always return 90, and I don’t have other phone to test.