Cleaned up RotationVector example code to prepare for different fusion-providers.
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name="org.hitlabnz.sensor_fusion_demo.RotationVector"
|
||||
android:name="org.hitlabnz.sensor_fusion_demo.MainActivity"
|
||||
android:label="@string/title_main_activity"
|
||||
android:screenOrientation="nosensor" >
|
||||
<intent-filter>
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.nio.FloatBuffer;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
/**
|
||||
* A simple cube that is used for drawing the current rotation of the device
|
||||
* A simple colour-cube that is used for drawing the current rotation of the device
|
||||
*
|
||||
*/
|
||||
public class Cube {
|
||||
@@ -24,6 +24,9 @@ public class Cube {
|
||||
*/
|
||||
private ByteBuffer mIndexBuffer;
|
||||
|
||||
/**
|
||||
* Initialises a new instance of the cube
|
||||
*/
|
||||
public Cube() {
|
||||
final float vertices[] = { -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, };
|
||||
|
||||
@@ -50,6 +53,11 @@ public class Cube {
|
||||
mIndexBuffer.position(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws this cube of the given GL-Surface
|
||||
*
|
||||
* @param gl The GL-Surface this cube should be drawn upon.
|
||||
*/
|
||||
public void draw(GL10 gl) {
|
||||
gl.glEnable(GL10.GL_CULL_FACE);
|
||||
gl.glFrontFace(GL10.GL_CW);
|
||||
|
||||
96
src/org/hitlabnz/sensor_fusion_demo/CubeRenderer.java
Normal file
96
src/org/hitlabnz/sensor_fusion_demo/CubeRenderer.java
Normal file
@@ -0,0 +1,96 @@
|
||||
package org.hitlabnz.sensor_fusion_demo;
|
||||
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import org.hitlabnz.sensor_fusion_demo.orientationProvider.OrientationProvider;
|
||||
|
||||
import android.opengl.GLSurfaceView;
|
||||
|
||||
/**
|
||||
* Class that implements the rendering of a cube with the current rotation of the device that is provided by a
|
||||
* OrientationProvider
|
||||
*
|
||||
* @author Alexander Pacha
|
||||
*
|
||||
*/
|
||||
public class CubeRenderer implements GLSurfaceView.Renderer {
|
||||
/**
|
||||
* The colour-cube that is drawn repeatedly
|
||||
*/
|
||||
private Cube mCube;
|
||||
|
||||
/**
|
||||
* The current provider of the device orientation.
|
||||
*/
|
||||
private OrientationProvider orientationProvider = null;
|
||||
|
||||
/**
|
||||
* Initialises a new CubeRenderer
|
||||
*/
|
||||
public CubeRenderer() {
|
||||
mCube = new Cube();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the orientationProvider of this renderer. Use this method to change which sensor fusion should be currently
|
||||
* used for rendering the cube. Simply exchange it with another orientationProvider and the cube will be rendered
|
||||
* with another approach.
|
||||
*
|
||||
* @param orientationProvider The new orientation provider that delivers the current orientation of the device
|
||||
*/
|
||||
public void setOrientationProvider(OrientationProvider orientationProvider) {
|
||||
this.orientationProvider = orientationProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the actual rendering of the cube for each frame
|
||||
*
|
||||
* @param gl The surface on which the cube should be rendered
|
||||
*/
|
||||
public void onDrawFrame(GL10 gl) {
|
||||
// clear screen
|
||||
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// set-up modelview matrix
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glLoadIdentity();
|
||||
gl.glTranslatef(0, 0, -3.0f);
|
||||
|
||||
if (orientationProvider != null) {
|
||||
// Get the rotation from the current orientationProvider
|
||||
gl.glMultMatrixf(orientationProvider.getRotationMatrix(), 0);
|
||||
}
|
||||
|
||||
// draw our object
|
||||
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
|
||||
|
||||
mCube.draw(gl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update view-port with the new surface
|
||||
*
|
||||
* @param gl the surface
|
||||
* @param width new width
|
||||
* @param height new height
|
||||
*/
|
||||
public void onSurfaceChanged(GL10 gl, int width, int height) {
|
||||
// set view-port
|
||||
gl.glViewport(0, 0, width, height);
|
||||
// set projection matrix
|
||||
float ratio = (float) width / height;
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
// dither is enabled by default, we don't need it
|
||||
gl.glDisable(GL10.GL_DITHER);
|
||||
// clear screen in black
|
||||
gl.glClearColor(0, 0, 0, 1);
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,9 @@
|
||||
|
||||
package org.hitlabnz.sensor_fusion_demo;
|
||||
|
||||
import org.hitlabnz.sensor_fusion_demo.orientationProvider.OrientationProvider;
|
||||
import org.hitlabnz.sensor_fusion_demo.orientationProvider.RotationVectorProvider;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
@@ -27,16 +30,29 @@ import android.os.Bundle;
|
||||
* @see SensorManager
|
||||
*
|
||||
*/
|
||||
public class RotationVector extends Activity {
|
||||
public class MainActivity extends Activity {
|
||||
/**
|
||||
* The surface that will be drawn upon
|
||||
*/
|
||||
private GLSurfaceView mGLSurfaceView;
|
||||
private SensorFuser mRenderer;
|
||||
/**
|
||||
* The class that renders the cube
|
||||
*/
|
||||
private CubeRenderer mRenderer;
|
||||
/**
|
||||
* The current orientation provider that delivers device orientation.
|
||||
*/
|
||||
private OrientationProvider currentOrientationProvider;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Initialise the orientationProvider
|
||||
currentOrientationProvider = new RotationVectorProvider((SensorManager) getSystemService(SENSOR_SERVICE));
|
||||
// Create our Preview view and set it as the content of our Activity
|
||||
mRenderer = new SensorFuser((SensorManager) getSystemService(SENSOR_SERVICE));
|
||||
mRenderer = new CubeRenderer();
|
||||
mRenderer.setOrientationProvider(currentOrientationProvider);
|
||||
mGLSurfaceView = new GLSurfaceView(this);
|
||||
mGLSurfaceView.setRenderer(mRenderer);
|
||||
setContentView(mGLSurfaceView);
|
||||
@@ -47,7 +63,7 @@ public class RotationVector extends Activity {
|
||||
// Ideally a game should implement onResume() and onPause()
|
||||
// to take appropriate action when the activity looses focus
|
||||
super.onResume();
|
||||
mRenderer.start();
|
||||
currentOrientationProvider.start();
|
||||
mGLSurfaceView.onResume();
|
||||
}
|
||||
|
||||
@@ -56,7 +72,7 @@ public class RotationVector extends Activity {
|
||||
// Ideally a game should implement onResume() and onPause()
|
||||
// to take appropriate action when the activity looses focus
|
||||
super.onPause();
|
||||
mRenderer.stop();
|
||||
currentOrientationProvider.stop();
|
||||
mGLSurfaceView.onPause();
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
package org.hitlabnz.sensor_fusion_demo;
|
||||
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.opengl.GLSurfaceView;
|
||||
|
||||
public class SensorFuser implements GLSurfaceView.Renderer, SensorEventListener {
|
||||
private Cube mCube;
|
||||
private Sensor mRotationVectorSensor;
|
||||
private final float[] mRotationMatrix = new float[16];
|
||||
private SensorManager mSensorManager;
|
||||
|
||||
public SensorFuser(SensorManager sensorManager) {
|
||||
mSensorManager = sensorManager;
|
||||
|
||||
// find the rotation-vector sensor
|
||||
mRotationVectorSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
|
||||
|
||||
mCube = new Cube();
|
||||
// initialize the rotation matrix to identity
|
||||
mRotationMatrix[0] = 1;
|
||||
mRotationMatrix[4] = 1;
|
||||
mRotationMatrix[8] = 1;
|
||||
mRotationMatrix[12] = 1;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
// enable our sensor when the activity is resumed, ask for
|
||||
// 10 ms updates.
|
||||
mSensorManager.registerListener(this, mRotationVectorSensor, 10000);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
// make sure to turn our sensor off when the activity is paused
|
||||
mSensorManager.unregisterListener(this);
|
||||
}
|
||||
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
// we received a sensor event. it is a good practice to check
|
||||
// that we received the proper event
|
||||
if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
|
||||
// convert the rotation-vector to a 4x4 matrix. the matrix
|
||||
// is interpreted by Open GL as the inverse of the
|
||||
// rotation-vector, which is what we want.
|
||||
SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values);
|
||||
}
|
||||
}
|
||||
|
||||
public void onDrawFrame(GL10 gl) {
|
||||
// clear screen
|
||||
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// set-up modelview matrix
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glLoadIdentity();
|
||||
gl.glTranslatef(0, 0, -3.0f);
|
||||
gl.glMultMatrixf(mRotationMatrix, 0);
|
||||
|
||||
// draw our object
|
||||
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
|
||||
|
||||
mCube.draw(gl);
|
||||
}
|
||||
|
||||
public void onSurfaceChanged(GL10 gl, int width, int height) {
|
||||
// set view-port
|
||||
gl.glViewport(0, 0, width, height);
|
||||
// set projection matrix
|
||||
float ratio = (float) width / height;
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
// dither is enabled by default, we don't need it
|
||||
gl.glDisable(GL10.GL_DITHER);
|
||||
// clear screen in black
|
||||
gl.glClearColor(0, 0, 0, 1);
|
||||
}
|
||||
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.hitlabnz.sensor_fusion_demo.orientationProvider;
|
||||
|
||||
/**
|
||||
* Classes implementing this interface provide an orientation of the device either by directly accessing hardware, using
|
||||
* Android sensor fusion or fusing sensors itself.
|
||||
*
|
||||
* The orientation can be provided as rotation matrix or quaternion.
|
||||
*
|
||||
* @author Alexander Pacha
|
||||
*
|
||||
*/
|
||||
public interface OrientationProvider {
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Returns the current rotation of the device in the rotation matrix format
|
||||
*/
|
||||
public float[] getRotationMatrix();
|
||||
|
||||
/**
|
||||
* Starts the sensor fusion (e.g. when resuming the activity)
|
||||
*/
|
||||
public void start();
|
||||
|
||||
/**
|
||||
* Stops the sensor fusion (e.g. when pausing/suspending the activity)
|
||||
*/
|
||||
public void stop();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package org.hitlabnz.sensor_fusion_demo.orientationProvider;
|
||||
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
|
||||
/**
|
||||
* The orientation provider that delivers the current orientation from the {@link Sensor#TYPE_ROTATION_VECTOR Android
|
||||
* Rotation Vector sensor}.
|
||||
*
|
||||
* @author Alexander Pacha
|
||||
*
|
||||
*/
|
||||
public class RotationVectorProvider implements SensorEventListener, OrientationProvider {
|
||||
|
||||
/**
|
||||
* The rotation vector sensor that is being used for this provider to get device orientation
|
||||
*/
|
||||
private Sensor rotationVectorSensor;
|
||||
|
||||
/**
|
||||
* The matrix that holds the current rotation
|
||||
*/
|
||||
private final float[] currentOrientationRotationMatrix = new float[16];
|
||||
|
||||
/**
|
||||
* The sensor manager for accessing android sensors
|
||||
*/
|
||||
private SensorManager sensorManager;
|
||||
|
||||
/**
|
||||
* Initialises a new RotationVectorProvider
|
||||
*
|
||||
* @param sensorManager The android sensor manager
|
||||
*/
|
||||
public RotationVectorProvider(SensorManager sensorManager) {
|
||||
this.sensorManager = sensorManager;
|
||||
|
||||
// find the rotation-vector sensor
|
||||
rotationVectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
|
||||
|
||||
// initialize the rotation matrix to identity
|
||||
currentOrientationRotationMatrix[0] = 1;
|
||||
currentOrientationRotationMatrix[4] = 1;
|
||||
currentOrientationRotationMatrix[8] = 1;
|
||||
currentOrientationRotationMatrix[12] = 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
// enable our sensor when the activity is resumed, ask for
|
||||
// 10 ms updates.
|
||||
sensorManager.registerListener(this, rotationVectorSensor, 10000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
// make sure to turn our sensor off when the activity is paused
|
||||
sensorManager.unregisterListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
// we received a sensor event. it is a good practice to check
|
||||
// that we received the proper event
|
||||
if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
|
||||
// convert the rotation-vector to a 4x4 matrix. the matrix
|
||||
// is interpreted by Open GL as the inverse of the
|
||||
// rotation-vector, which is what we want.
|
||||
SensorManager.getRotationMatrixFromVector(currentOrientationRotationMatrix, event.values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getRotationMatrix() {
|
||||
return currentOrientationRotationMatrix;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user