1

地磁気と加速度計を変換してopengl ES1でカメラを回転させようとしています.Androidからいくつかのコードを見つけて、このコードをiPhone用に変更しました.実際には多かれ少なかれ機能していますが、いくつかの間違いがあります,私はできませんこの間違いを見つけるために、コードと 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;


}

助けてくれてありがとう。

編集: iPhone は常に横向きになっています。OpenGL Es で描画されたオブジェクトが 2 回表示されるため、何か問題があることがわかります。

4

2 に答える 2

2

Apple のGLGravityサンプル コードを見たことがありますか? 加速度計入力の変化に応じてモデル ビュー マトリックスを操作することで、ここで必要なものと非常によく似た処理を行います。

于 2011-05-10T15:49:49.753 に答える
1

投稿されたコードに問題を見つけることができず、問題が別の場所にあることを示唆しています。それが役立つ場合、投稿されたコードの私の分析は次のとおりです。

_geomagnetic 0 ~ 5 を扱う最初の 6 行は、非常に単純な低周波フィルターに影響を与えます。これは、一定の間隔でメソッドを呼び出すことを前提としています。したがって、できれば高周波ジッターが除去されたバージョンの磁力計ベクトルが得られます。

bzero は結果をゼロにし、累積の準備をします。

宣言と Hz への代入までの行は、磁力計と加速度計のベクトルを取り、外積を実行します。したがって、H(x, y, z) は、加速度計 (「下」と推定される) と磁力計 (前方 + いくらか上) の両方に対して直角のベクトルになりました。それをサイドベクトルと呼びます。

invH と invA のものから、invA による Az の乗算まで、サイド ベクトルと加速度計/ダウン ベクトルが単位長であることを保証します。

M(x, y, z) は、サイド ベクトルとダウン ベクトル (つまり、これらの両方に直角なベクトル) の外積として作成されます。したがって、フロントベクトルが得られます。

最後に、正規直交 3x3 行列の逆行列がその転置であるという事実を利用して、3 つのベクトルを使用して行列にデータを入力します (ただし、これは配置方法によって隠されていますが、配列のインデックスに注意してください)。実際にはすべてをマトリックスに直接設定するため、純粋な結果に関しては bzero は必要ありませんでした。

glLoadMatrixfこれは、OpenGL ES 1.x で任意の列優先行列を乗算する方法であるため、正しい使用方法です。

于 2011-05-10T14:31:59.870 に答える