Obtener dispositivo de orientación en el iPhone para Opengl Es

Estoy tratando de convertir el geomagnético y el acelerómetro para rotar la cámara en opengl ES1, encontré un código de android y cambié este código para iPhone, en realidad está funcionando más o menos, pero hay algunos errores, no puedo para encontrar este error, pongo el código, también la llamada a Opengl Es1: glLoadMatrixf((GLfloat*)matrix);

- (void) GetAccelerometerMatrix:(GLfloat *) matrix headingX: (float)hx headingY:(float)hy headingZ:(float)hz;
{

    _geomagnetic[0] = hx * (FILTERINGFACTOR-0.05) + _geomagnetic[0] * (1.0 - FILTERINGFACTOR-0.5)+ _geomagnetic[3] * (0.55);
    _geomagnetic[1] = hy * (FILTERINGFACTOR-0.05) + _geomagnetic[1] * (1.0 - FILTERINGFACTOR-0.5)+ _geomagnetic[4] *  (0.55);
    _geomagnetic[2] = hz * (FILTERINGFACTOR-0.05) + _geomagnetic[2] * (1.0 - FILTERINGFACTOR-0.5)+ _geomagnetic[5] *  (0.55);

    _geomagnetic[3]=_geomagnetic[0] ;
    _geomagnetic[4]=_geomagnetic[1];
    _geomagnetic[5]=_geomagnetic[2];


        //Clear matrix to be used to rotate from the current referential to one based on the gravity vector
    bzero(matrix, sizeof(matrix));



    //MAGNETIC
    float Ex = -_geomagnetic[1];    
    float Ey =_geomagnetic[0];
    float Ez =_geomagnetic[2];

    //ACCELEROMETER
    float Ax=  -_accelerometer[0];
    float Ay=  _accelerometer[1] ;
    float Az=  _accelerometer[2] ;


    float Hx = Ey*Az - Ez*Ay;
    float Hy= Ez*Ax - Ex*Az;
    float Hz = Ex*Ay - Ey*Ax;

    float normH = (float)sqrt(Hx*Hx + Hy*Hy + Hz*Hz);


    float invH = 1.0f / normH;
    Hx *= invH;
    Hy *= invH;
    Hz *= invH;

    float invA = 1.0f / (float)sqrt(Ax*Ax + Ay*Ay + Az*Az);
    Ax *= invA;
    Ay *= invA;
    Az *= invA;

    float Mx = Ay*Hz - Az*Hy;
    float My = Az*Hx - Ax*Hz;
    float Mz = Ax*Hy - Ay*Hx;

    // if (mOut.f != null) {

    matrix[0]  = Hx;    matrix[1]  = Hy;    matrix[2]  = Hz;   matrix[3]  = 0;
    matrix[4]  = Mx;    matrix[5]  = My;    matrix[6]  = Mz;   matrix[7]  = 0;
    matrix[8]  = Ax;    matrix[9]  = Ay;    matrix[10] = Az;   matrix[11] = 0;
    matrix[12] = 0;     matrix[13] = 0;     matrix[14] = 0;    matrix[15] = 1;


}

Muchas gracias por la ayuda.

Editar: El iPhone está permanentemente en orientación horizontal y sé que algo anda mal porque el objeto pintado en Opengl Es aparece dos veces.

preguntado el 10 de mayo de 11 a las 13:05

Ojalá fuera lo suficientemente inteligente para saber qué significa todo eso. jajaja. -

2 Respuestas

No puedo encontrar ningún problema con el código publicado y sugeriría que el problema está en otra parte. Si ayuda, mi análisis del código publicado es que:

Las primeras seis líneas, que tratan con _geomagnetic 0–5, efectúan un filtro de baja frecuencia muy simple, que asume que usted llama al método a intervalos regulares. Así que terminas con una versión del vector del magnetómetro, con suerte sin la fluctuación de fase de alta frecuencia.

El bzero pone a cero el resultado, listo para la acumulación.

Las líneas hasta la declaración y asignación a Hz toman los vectores del magnetómetro y acelerómetro y realizan el producto cruzado. Entonces, H (x, y, z) ahora es un vector en ángulo recto con el acelerómetro (que se presume que está 'abajo') y el magnetómetro (que estará hacia adelante + algo hacia arriba). Llámalo vector lateral.

Los elementos invH e invA, hasta la multiplicación de Az por invA, garantizan que los vectores lateral y acelerómetro / descendente tengan una longitud unitaria.

Luego se crea M (x, y, z), como el producto cruzado de los vectores laterales y descendentes (es decir, un vector en ángulo recto con ambos). Entonces da el vector frontal.

Finalmente, los tres vectores se usan para poblar la matriz, aprovechando el hecho de que la inversa de una matriz ortonormal 3x3 es su transposición (aunque eso está un poco oculto por la forma en que se presentan las cosas; preste atención a los índices de la matriz). De hecho, estableció todo en la matriz directamente, por lo que el bzero no era necesario en términos de resultado puro.

glLoadMatrixf entonces es lo correcto porque así es como se multiplica por una matriz de columna principal arbitraria en OpenGL ES 1.x.

contestado el 10 de mayo de 11 a las 18:05

muchas gracias por la explicación, el problema estaba en el iPhone, ahora está funcionando bien. :D - Gustavo

¿Has mirado a Apple GLGravity ¿Código de muestra? Hace algo muy similar a lo que desea aquí, manipulando la matriz de vista del modelo en respuesta a los cambios en la entrada del acelerómetro.

contestado el 10 de mayo de 11 a las 19:05

Sí, mi código se basa más o menos en el ejemplo de GLGravity pero también necesito los datos geomagnéticos para modificar la orientación. - Gustavo

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.