4

I want to get the android sensors to work with opengl to rotate the opengl's camera to wherever the phone is pointing to.

To elaborate: if the player is looking at east, I'd like to the opengl's camera points east too on the game; if the player points to the sky, I'd like to point the opengl's camera to the sky and so on.

I've tried using getRotationMatrix and load the matrix on the opengl but it only works on the up-down direction, if I turn the cell to the sides, there is no difference. Here is what I've done so far (the app is in landscape mode):

    public void onSensorChanged(SensorEvent evt) {
    int type=evt.sensor.getType();
    float alpha = 0.8f;

    //Smoothing the sensor data a bit
    if (type == Sensor.TYPE_MAGNETIC_FIELD) {
      geomag[0]=geomag[0]*alpha+evt.values[0]*(1-alpha);
      geomag[1]=geomag[1]*alpha+evt.values[1]*(1-alpha);
      geomag[2]=geomag[2]*alpha+evt.values[2]*(1-alpha);
    } else if (type == Sensor.TYPE_ACCELEROMETER) {
      gravity[0]= gravity[0]*alpha+evt.values[0]*(1-alpha);
      gravity[1]= gravity[1]*alpha+evt.values[1]*(1-alpha);
      gravity[2]= gravity[2]*alpha+evt.values[2]*(1-alpha);
    }

    if ((type==Sensor.TYPE_MAGNETIC_FIELD) || (type==Sensor.TYPE_ACCELEROMETER)) {
      rotationMatrix = new float[16];
      SensorManager.getRotationMatrix(rotationMatrix, null, gravity, geomag);
      SensorManager.remapCoordinateSystem( 
        rotationMatrix, 
        SensorManager.AXIS_Y, 
        SensorManager.AXIS_MINUS_X, 
        rotationMatrix );
     if (AOGLRenderer.rotationmatrix==null) AOGLRenderer.rotationmatrix = new float[16];
     AOGLRenderer.rotationmatrix = rotationMatrix;
    }       
  }

and in the opengl code:

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | // OpenGL docs.
                       GL10.GL_DEPTH_BUFFER_BIT);
    gl.glLoadIdentity();
    if (rotationmatrix!=null) gl.glLoadMatrixf(rotationmatrix, 0);
    gl.glPushMatrix();
    gl.glTranslatef(0, 0, -70);
    g.draw(gl);
    gl.glPopMatrix();
    alpha+=2f;
    gl.glTranslatef(0, -15, 0);
    c.draw(gl);

I'd like that someone who actually did it could share their code! I'd really appreciate it! Thank you all!

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
rdnobrega
  • 721
  • 6
  • 16

2 Answers2

0

You're supplying null for the inclination matrix - that's not correct.

SensorManager.getRotationMatrix(rotationMatrix, null, gravity, geomag);

There are lots of examples on how to use the SensorManager's getRotationMatrix(...).

float[] R = new float[16];
float[] I = new float[16];

if (SensorManager.getRotationMatrix(R, I, accelerometerValues, geomagneticValues)) {
    float[] anglesInRadians = new float[3];
    SensorManager.getOrientation(R, anglesInRadians);
    ...
}

Also "rotate the opengl's camera to wherever the phone is pointing to" is rather ambiguous. For instance, if you meant some sort of a augmented reality approach, then you should be mapping AXIS_X to AXIS_Z. Note that remapping might not even be necessary, e.g. when you already fix your activity to landscape mode. More details here.

Some example codes involving sensor data and OpenGL ES:

Community
  • 1
  • 1
MH.
  • 45,303
  • 10
  • 103
  • 116
  • Thanks for the answer! but didn't really worked out. What i meant is to accomplish the same thing showed in this video: http://www.youtube.com/watch?v=wfRjZrnPBXY – rdnobrega Jan 04 '12 at 19:52
0

Here is the way I did the same thing (my App was also in landscape). First I get the orientation values (similar to the way you do):

final float pi = (float) Math.PI;
final float rad2deg = 180/pi;
public static float x; //pitch
public static float y; //roll
public static float z; //azimuth    
float[] gravity = new float[3];
float[] geomag = new float[3];
float[] inOrientMatrix = new float[16];
float[] outOrientMatrix= new float[16];
float orientation[] = new float[3]; 
public static GLSurfaceView glView;

//  (...)

public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()){  
        case Sensor.TYPE_ACCELEROMETER:  gravity = event.values.clone();
        break;
        case Sensor.TYPE_MAGNETIC_FIELD: geomag = event.values.clone();
        break;
        }
if (gravity != null && geomag != null){
if (SensorManager.getRotationMatrix(inOrientMatrix, null, gravity, geomag)){
        SensorManager.remapCoordinateSystem(inOrientMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, outOrientMatrix);
        SensorManager.getOrientation(outOrientMatrix, orientation);
        x = orientation[1]*rad2deg; //pitch
        y = orientation[0]*rad2deg; //azimuth
        z = orientation[2]*rad2deg; //roll
        glView.requestRender();
}

Then in my rendered, in the onDrawFrame(GL10 gl) I do:

 gl.glLoadIdentity();
 GLU.gluLookAt(gl, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);      
 gl.glRotatef(MainActivity.x, 1.0f, 0.0f, 0.0f);
 gl.glRotatef(MainActivity.y, 0.0f, 1.0f, 0.0f);
 gl.glRotatef(MainActivity.z, 0.0f, 0.0f, 1.0f);
 //in case you have transformation, eg. the position of the object, you can do them here 
 //gl.Translatef(0.0f, 0.0f, -DISTANCE NORTH); 
 //gl.Translatef(0.0f, DISTANCE EAST, 0.0f); 
 gl.glPushMatrix();
 //object draw

In other words, I rotate the whole world around me. A better way would be to change the direction of the camera using glLookAt, with the eye positioned at (0,0,0) and (0,1,0) being the up vector, but I simply couldn't get my center_view x,y,z values correctly.

Hope this helps...

superjos
  • 12,189
  • 6
  • 89
  • 134
ılǝ
  • 3,440
  • 2
  • 33
  • 47