package com.marshalchen.common.uimodule.motion; import android.content.Context; import android.hardware.SensorEvent; import android.view.Surface; import android.view.WindowManager; /* * Copyright 2014 Nathan VanBenschoten * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ public class SensorInterpreter { private static final String TAG = SensorInterpreter.class.getName(); /** * The standardized vectors corresponding to yaw, pitch, and roll. */ private float[] mVectors; /** * The sensitivity the parallax effect has towards tilting. */ private float mTiltSensitivity = 2.0f; /** * The forward tilt offset adjustment to counteract a natural forward phone tilt. */ private float mForwardTiltOffset = 0.3f; public SensorInterpreter() { mVectors = new float[3]; } /** * Converts sensor data to yaw, pitch, and roll * * @param context the context of the * @param event the event to interpret * @return and interpreted array of yaw, pitch, and roll vectors */ public final float[] interpretSensorEvent(Context context, SensorEvent event) { if (event == null || event.values.length < 3 || event.values[0] == 0 || event.values[1] == 0 || event.values[2] == 0) return null; // Acquire rotation of screen final int rotation = ((WindowManager) context .getSystemService(Context.WINDOW_SERVICE)) .getDefaultDisplay() .getRotation(); // Adjust for forward tilt based on screen orientation switch (rotation) { case Surface.ROTATION_90: mVectors[0] = event.values[0]; mVectors[1] = event.values[2]; mVectors[2] = -event.values[1]; break; case Surface.ROTATION_180: mVectors[0] = event.values[0]; mVectors[1] = event.values[1]; mVectors[2] = event.values[2]; break; case Surface.ROTATION_270: mVectors[0] = event.values[0]; mVectors[1] = -event.values[2]; mVectors[2] = event.values[1]; break; default: mVectors[0] = event.values[0]; mVectors[1] = -event.values[1]; mVectors[2] = -event.values[2]; break; } // Adjust roll for sensitivity differences based on pitch // double tiltScale = 1/Math.cos(mVectors[1] * Math.PI/180); // if (tiltScale > 12) tiltScale = 12; // if (tiltScale < -12) tiltScale = -12; // mVectors[2] *= tiltScale; // Make roll and pitch percentages out of 1 mVectors[1] /= 90; mVectors[2] /= 90; // Add in forward tilt offset mVectors[1] -= mForwardTiltOffset; if (mVectors[1] < -1) mVectors[1] += 2; // Adjust for tilt sensitivity mVectors[1] *= mTiltSensitivity; mVectors[2] *= mTiltSensitivity; // Clamp values to image bounds if (mVectors[1] > 1) mVectors[1] = 1f; if (mVectors[1] < -1) mVectors[1] = -1f; if (mVectors[2] > 1) mVectors[2] = 1f; if (mVectors[2] < -1) mVectors[2] = -1f; return mVectors; } public float getForwardTiltOffset() { return mForwardTiltOffset; } public void setForwardTiltOffset(float forwardTiltOffset) { mForwardTiltOffset = forwardTiltOffset; } public float getTiltSensitivity() { return mTiltSensitivity; } public void setTiltSensitivity(float tiltSensitivity) { mTiltSensitivity = tiltSensitivity; } }