1

私は、Open GL ES (および ulti lib) に付属するオイラーまたはクォータニオン ベースの関数を使用する代わりに、行列操作を使用して実験してきました。

私はほとんどのものを動作させることができますが、以下のスクリーンショットからわかるように、gluLookAt 関数を完全に再現することはできません:

正しい gluLookAt バージョン。

バスト、マトリックス バージョン。

スクリーンショットは実際の画面の一部に過ぎないことに注意してください。両方に表示されているボタンは、2D 正投影を使用して作成されたオーバーレイであり、両方の画像で同じ場所にあるため、違いを示すのに役立ちます。

ここから情報を取得しました: http://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml

以下のJavaコードで再作成しました(一部の詳細は省略されています):

class point3D {
    public double mX, mY, mZ;
}

double scaler(point3D pt){
    return Math.pow(
        Math.pow(pt.mX, 2.0) + Math.pow(pt.mY, 2.0) + Math.pow(pt.mZ, 2.0),
        1.0/3.0
    );
}

void cross(point3D A, point3D B, point3D output){
    output.mX = (A.mY*B.mZ) - (A.mZ*B.mY);
    output.mY = (A.mZ*B.mX) - (A.mX*B.mZ);
    output.mZ = (A.mX*B.mY) - (A.mY*B.mX);
}

void normalise(point3D normMe, point3D output){
    double s = scaler(normMe);
    output.mX = normMe.mX / s;
    output.mY = normMe.mY / s;
    output.mZ = normMe.mZ / s;
}

float mx, my, mz, mfx, mfy, mfz;
private FloatBuffer mLookatMx; //- All setup and stuff elsewhere

void myLookAt(){
    point3D ptTmpA, ptTmpB, ptTmpC, ptTmpD;

    //- 'forward' F part
    ptTmpA.mX = mfx - mx;
    ptTmpA.mY = mfy - my;
    ptTmpA.mZ = mfz - mz;
    normalise(ptTmpA, ptTmpA);

    //- 'up' part
    ptTmpB.mX = 0;
    ptTmpB.mY = 1.0;
    ptTmpB.mZ = 0;

    cross(ptTmpB, ptTmpA, ptTmpC);  //- S
    normalise(ptTmpC, ptTmpC);

    cross(ptTmpA, ptTmpC, ptTmpD);  //- U
    normalise(ptTmpD, ptTmpD);

    //- the 4x4 matrix. Not including the transformation this time for simplicity.
    //- m = {
    //-        s1,  s2,  s3, -x
    //-        u1,  u2,  u3, -y
    //-       -f1, -f2, -f3, -z
    //-         0,   0,   0,  1
    //- }

    //- 0
    mLookatMx.put((float)ptTmpC.mX);            
    mLookatMx.put((float)ptTmpC.mY);            
    mLookatMx.put((float)ptTmpC.mZ);            
    mLookatMx.put(0);

    //- 4
    mLookatMx.put((float)ptTmpD.mX);            
    mLookatMx.put((float)ptTmpD.mY);            
    mLookatMx.put((float)ptTmpD.mZ);            
    mLookatMx.put(0);

    //- 12
    mLookatMx.put((float)ptTmpA.mX *-1.0f); 
    mLookatMx.put((float)ptTmpA.mY *-1.0f); 
    mLookatMx.put((float)ptTmpA.mZ *-1.0f); 
    mLookatMx.put(0);

    //- 16
    mLookatMx.put(0);                           
    mLookatMx.put(0);                           
    mLookatMx.put(0);                           
    mLookatMx.put(1.0f);
    mLookatMx.position(0);
}

void myDraw(){
    glDisable(GL_DEPTH_BITS);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(mGL, 90.0, mScreen.mX / mScreen.mY, 0.01, 10.0);

    //- This works
    //gluLookAt(mGL, 
    //    mx, my, mz, 
    //    mfx, mfy, mfz,
    //    0.0f, 1.0f, 0.0f
    //);

    //- This is distorted
    glMultMatrixf(mLookatMx);
    glTranslatef(mx * -1.0f, my * -1.0f, mz * -1.0f)

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    //- draw models as seen in screen shot
}
4

1 に答える 1