package com.asha.vrlib.strategy.interactive; import android.app.Activity; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.util.Log; import com.asha.vrlib.MD360Director; import com.asha.vrlib.common.MDMainHandler; import com.asha.vrlib.common.VRUtil; /** * Created by hzqiujiadi on 16/3/19. * hzqiujiadi ashqalcn@gmail.com */ public class MotionStrategy extends AbsInteractiveStrategy implements SensorEventListener { private static final String TAG = "MotionStrategy"; private int mDeviceRotation; private float[] mSensorMatrix = new float[16]; private float[] mTmpMatrix = new float[16]; private boolean mRegistered = false; private Boolean mIsSupport = null; private final Object mMatrixLock = new Object(); private boolean isOn; public MotionStrategy(InteractiveModeManager.Params params) { super(params); } @Override public void onResume(Context context) { registerSensor(context); } @Override public void onPause(Context context) { unregisterSensor(context); } @Override public boolean handleDrag(int distanceX, int distanceY) { return false; } @Override public void onOrientationChanged(Activity activity) { mDeviceRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); } @Override public void turnOnInGL(Activity activity) { isOn = true; mDeviceRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); for (MD360Director director : getDirectorList()){ director.reset(); } } @Override public void turnOffInGL(final Activity activity) { isOn = false; activity.runOnUiThread(new Runnable() { @Override public void run() { unregisterSensor(activity); } }); } @Override public boolean isSupport(Activity activity) { if (mIsSupport == null){ SensorManager mSensorManager = (SensorManager) activity .getSystemService(Context.SENSOR_SERVICE); Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR); mIsSupport = (sensor != null); } return mIsSupport; } protected void registerSensor(Context context){ if (mRegistered) return; SensorManager mSensorManager = (SensorManager) context .getSystemService(Context.SENSOR_SERVICE); Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR); if (sensor == null){ Log.e(TAG,"TYPE_ROTATION_VECTOR sensor not support!"); return; } mSensorManager.registerListener(this, sensor, getParams().mMotionDelay, MDMainHandler.sharedHandler()); mRegistered = true; } protected void unregisterSensor(Context context){ if (!mRegistered) return; SensorManager mSensorManager = (SensorManager) context .getSystemService(Context.SENSOR_SERVICE); mSensorManager.unregisterListener(this); mRegistered = false; } @Override public void onSensorChanged(final SensorEvent event) { if (isOn && event.accuracy != 0){ if (getParams().mSensorListener != null){ getParams().mSensorListener.onSensorChanged(event); } int type = event.sensor.getType(); switch (type){ case Sensor.TYPE_ROTATION_VECTOR: // post VRUtil.sensorRotationVector2Matrix(event, mDeviceRotation, mSensorMatrix); // mTmpMatrix will be used in multi thread. synchronized (mMatrixLock){ System.arraycopy(mSensorMatrix, 0, mTmpMatrix, 0, 16); } getParams().glHandler.post(updateSensorRunnable); break; } } } private Runnable updateSensorRunnable = new Runnable() { @Override public void run() { if (!mRegistered || !isOn) return; // mTmpMatrix will be used in multi thread. synchronized (mMatrixLock){ for (MD360Director director : getDirectorList()){ director.updateSensorMatrix(mTmpMatrix); } } } }; @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { if (getParams().mSensorListener != null){ getParams().mSensorListener.onAccuracyChanged(sensor,accuracy); } } }