• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps [SOLVED, was a bug] screen rotation and remapCoordinateSystem

werner291

Lurker
Hello,

I'm developing a game where you have to fly some kind of plane, and I'd like to use sensor-based controls. I've got it working on one device in one orientation, but it totally fails in any other situation. It must be related to this piece from the remapCoordinateSystem() documentation:

When the rotation matrix is used for drawing (for instance with OpenGL ES), it usually doesn't need to be transformed by this function, unless the screen is physically rotated, in which case you can use Display.getRotation() to retrieve the current rotation of the screen. Note that because the user is generally free to rotate their screen, you often should consider the rotation in deciding the parameters to use here.

In "remapCoordinateSystem (float[] inR, int X, int Y, float[] outR)", what are X and Y?

Here's my code so far:
Code:
public void onSensorChanged(SensorEvent event) {
        if (event.sensor == mAccelerometer) {
            System.arraycopy(event.values, 0, mLastAccelerometer, 0, event.values.length);
            mLastAccelerometerSet = true;
        } else if (event.sensor == mMagnetometer) {
            System.arraycopy(event.values, 0, mLastMagnetometer, 0, event.values.length);
            mLastMagnetometerSet = true;
        }
        if (mLastAccelerometerSet && mLastMagnetometerSet) {
            SensorManager.getRotationMatrix(mR, null, mLastAccelerometer, mLastMagnetometer);
            // Fix acellerometer behaving differently on diferent devices
            int rotation = ((WindowManager) getApplicationContext().getSystemService(this.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
            switch (rotation){
                case Surface.ROTATION_0:
                    SensorManager.remapCoordinateSystem(mR, SensorManager.AXIS_X, SensorManager.AXIS_Y, mR);
                    break;
                case Surface.ROTATION_90:
                    SensorManager.remapCoordinateSystem(mR, SensorManager.AXIS_Y, SensorManager.AXIS_X, mR);
                    break;
                case Surface.ROTATION_180:
                    SensorManager.remapCoordinateSystem(mR, SensorManager.AXIS_MINUS_X, SensorManager.AXIS_MINUS_Y, mR);
                    break;
                case Surface.ROTATION_270:
                    SensorManager.remapCoordinateSystem(mR, SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X, mR);
                    break;
                // Do not remap if ROTATION_0
            }
            SensorManager.getOrientation(mR, mOrientation);
            Log.i("", String.format("Pitch: %f %f", mOrientation[1] * 180 / Math.PI, mOrientation[2] * 180 / Math.PI));
        }

        float requestedPitch = -(mOrientation[1] - pitchReference) * 2f;
        if (requestedPitch > 1f) requestedPitch = 1f;
        else if (requestedPitch < -1f) requestedPitch = -1f;

        float requestedYaw = -(mOrientation[2]) * 2f;
        if (requestedYaw > 1f) requestedYaw = 1f;
        else if (requestedYaw < -1f) requestedYaw = -1f;

        mGameManager.setSteer(invertX?-requestedYaw:requestedYaw,invertY?-requestedPitch:requestedPitch);
	}

EDIT (modified code): I'm starting to get it... the controls work for both 0 and 180, but on the 90 and 270 rotations, the pitch and the roll seem to allways be exactly equal?
 
Solved. It appears that, contrary to the documentation, inR and outR CANNOT be the same array or it might cause data corruption.
I've just submitted a bug report.
 
Back
Top Bottom