package actions; import gl.GLCamRotationController; import gl.GLUtilityClass; import system.EventManager; import system.Setup; import util.Calculus; import worldData.Updateable; import actions.algos.Algo; import android.hardware.SensorManager; import android.view.MotionEvent; import android.view.Surface; public abstract class ActionWithSensorProcessing extends Action { private static final String LOG_TAG = "ActionWithSensorProcessing"; private final GLCamRotationController myTargetCamera; public Algo magnetAlgo; public Algo accelAlgo; public Algo orientAlgo; public Algo accelBufferAlgo; public Algo magnetBufferAlgo; public Algo orientationBufferAlgo; private float[] myAccelValues = new float[3]; private float[] myMagnetValues = new float[3]; private float[] myOrientValues = new float[3]; private boolean accelChanged; private float[] myNewAccelValues; private boolean magnetoChanged; private float[] myNewMagnetValues; private boolean orientationDataChanged; private float[] myNewOrientValues; private final float[] unrotatedMatrix = Calculus.createIdentityMatrix(); private float[] rotationMatrix = Calculus.createIdentityMatrix(); private final int screenRotation; public ActionWithSensorProcessing(GLCamRotationController targetCamera) { myTargetCamera = targetCamera; initAlgos(); screenRotation = Setup.getScreenOrientation(); } protected abstract void initAlgos(); @Override public boolean onTouchMove(MotionEvent e1, MotionEvent e2, float screenDeltaX, float screenDeltaY) { myTargetCamera.changeZAngleBuffered(screenDeltaY); return true; } @Override public synchronized boolean onAccelChanged(float[] values) { if (accelAlgo != null) { myNewAccelValues = accelAlgo.execute(values); } else { myNewAccelValues = values; } accelChanged = true; return true; } @Override public synchronized boolean onMagnetChanged(float[] values) { if (magnetAlgo != null) { myNewMagnetValues = magnetAlgo.execute(values); } else { myNewMagnetValues = values; } magnetoChanged = true; return true; } @Override public synchronized boolean onOrientationChanged(float[] values) { if (orientAlgo != null) { myNewOrientValues = orientAlgo.execute(values); } else { myNewOrientValues = values; } orientationDataChanged = true; return true; } @Override public synchronized boolean update(float timeDelta, Updateable parent) { if (magnetoChanged || accelChanged || orientationDataChanged) { if (magnetoChanged || accelChanged) { // if accel or magnet changed: if (accelChanged) { accelChanged = false; if (accelBufferAlgo != null) { accelBufferAlgo.execute(myAccelValues, myNewAccelValues, timeDelta); } else { myAccelValues = myNewAccelValues; } } if (magnetoChanged) { magnetoChanged = false; if (magnetBufferAlgo != null) { magnetBufferAlgo.execute(myMagnetValues, myNewMagnetValues, timeDelta); } else { myMagnetValues = myNewMagnetValues; } } // first calc the unrotated matrix: SensorManager.getRotationMatrix(unrotatedMatrix, null, myAccelValues, myMagnetValues); } else if (orientationDataChanged) { orientationDataChanged = false; if (orientationBufferAlgo != null) { orientationBufferAlgo.execute(myOrientValues, myNewOrientValues, timeDelta); } else { myOrientValues = myNewOrientValues; } GLUtilityClass.getRotationMatrixFromVector(unrotatedMatrix, myOrientValues); } /* * Then in addition the values have to be remapped of the device is * used in landscape mode or if it is a tablet etc */ if (EventManager.isTabletDevice) { /* * change accel sensor data according to * http://code.google.com/p * /libgdx/source/browse/trunk/backends/gdx * -backend-android/src/com * /badlogic/gdx/backends/android/AndroidInput.java */ SensorManager.remapCoordinateSystem(unrotatedMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Y, rotationMatrix); } else { /* * TODO do this for all 4 rotation possibilities! */ if (screenRotation == Surface.ROTATION_90) { // then rotate it according to the screen rotation: SensorManager.remapCoordinateSystem(unrotatedMatrix, SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X, rotationMatrix); } else { /* * else its in portrait mode so no remapping needed */ rotationMatrix = unrotatedMatrix; } } myTargetCamera.setRotationMatrix(rotationMatrix, 0); } return true; } @Override public boolean onReleaseTouchMove() { myTargetCamera.resetBufferedAngle(); return true; } }