2

これは、OpenGL でのカメラの変換に関係するかなり具体的な質問です。ビューが開くと、回転ポイントは原点の周りにあります。カメラを移動すると、最初に移動が行われ、次に回転が行われ、回転ポイントが原点の周りに維持されます。

カメラの位置が変わらないように見えることなく、回転ポイントを原点からクリックした六角形のタイルに変更したいと思います。これは非常に漠然としているように見えるので、説明するためにいくつかの写真を含めました。

私の担当者がここで十分に高くないため、写真を含めることはできませんが、flickrの写真へのリンクは次のとおりです

ビューが最初に開いたとき

現在、新しいタイルをクリックして回転ポイントを変更すると、カメラが移動してそのタイルが画面の中心に保たれます。表示するリンクを投稿しますが、これも 2 つのリンクに十分な担当者のみです。代わりに、回転ポイントの変更をどのように行うかの写真へのリンクを投稿します (回転ポイントが変更されてもカメラは移動しません)。 .

どのように実現したいか

さて、いくつかのコード - これはカメラ変換行列を取得するためのコードです

NSMatrix4Df rotateTransform = NSMatrix4Df::getRotationMatrix(-orientation.x,-orientation.y,-orientation.z);
NSMatrix4Df rotationTranslationTransform = NSMatrix4Df::getTranslationMatrix(rotationPoint.x,rotationPoint.y,rotationPoint.z);
NSMatrix4Df cameraTranslateTransform = NSMatrix4Df::getTranslationMatrix(position.x,position.y,position.z);
return cameraTranslateTransform * rotateTransform * rotateTransform;

ここで、方向、位置、および回転ポイントはすべてワールド空間にあります。実際の行列変換のコードは次のとおりです。

NSMatrix4Df NSMatrix4Df::getRotationMatrix(float xAxisAng, float yAxisAng, float zAxisAng)
{
    float xRad = DegreesToRadians(xAxisAng);
    float yRad = DegreesToRadians(yAxisAng);
    float zRad = DegreesToRadians(zAxisAng);

    NSMatrix4Df xRotMat;
    NSMatrix4Df yRotMat;
    NSMatrix4Df zRotMat;

    xRotMat.value(1,1) = cosf(xRad); xRotMat.value(1,2) = -sinf(xRad);
    xRotMat.value(2,1) = sinf(xRad); xRotMat.value(2,2) = cosf(xRad);

    yRotMat.value(0,0) = cosf(yRad); yRotMat.value(0,2) = -sinf(yRad);
    yRotMat.value(2,0) = sinf(yRad); yRotMat.value(2,2) = cosf(yRad);

    zRotMat.value(0,0) = cosf(zRad); zRotMat.value(0,1) = -sinf(zRad);
    zRotMat.value(1,0) = sinf(zRad); zRotMat.value(1,1) = cosf(zRad);

    return zRotMat * yRotMat * xRotMat;
}

NSMatrix4Df NSMatrix4Df::getTranslationMatrix(float xMove, float yMove, float zMove)
{
    NSMatrix4Df identity;
    // set the fourth column of the matrix to the translation amount
    // the rest of the matrix is the identity matrix
    identity.setColumn(NSVec4Df(xMove,yMove,zMove,1),3);
    return identity;
}

NSMatrix4Df は、単位行列で満たされた 4x4 行列 ([4][4]) を表す 2 次元配列を作成します。そのためのコードはこちらです。

NSMatrix4Df::NSMatrix4Df():rows(MATDIM4D), 
    columns(MATDIM4D)
{
    data[0][0] = 1; data[0][1] = 0; data[0][2] = 0; data[0][3] = 0;
    data[1][0] = 0; data[1][1] = 1; data[1][2] = 0; data[1][3] = 0;
    data[2][0] = 0; data[2][1] = 0; data[2][2] = 1; data[2][3] = 0;
    data[3][0] = 0; data[3][1] = 0; data[3][2] = 0; data[3][3] = 1;
}

基本的に私の質問はこれです-回転ポイントが移動したときにカメラが同じ場所にとどまるように、回転ポイントを移動した後にカメラの位置を変換する方法を知っている人はいますか? 回転ポイントの翻訳の後に翻訳を追加してみました...

NSMatrix4Df rotateTransform = NSMatrix4Df::getRotationMatrix(-orientation.x,-orientation.y,-orientation.z);
NSMatrix4Df rotationTranslationTransform = NSMatrix4Df::getTranslationMatrix(rotationPoint.x,rotationPoint.y,rotationPoint.z);
NSMatrix4Df cameraTranslateTransform = NSMatrix4Df::getTranslationMatrix(**position.x - rotationPoint.x,position.y - rotationPoint.y,position.z - rotationPoint.z**);
return cameraTranslateTransform * rotateTransform * rotateTransform;

これは、回転ポイントを変更する前にカメラがまったく回転していない場合を除いて機能し、その理由がわかりません。この場合 (回転ポイントを変更する前にカメラを回転させた場合)、カメラは回転量によって影響を受ける方法で移動します。たとえば、x 軸を中心に 45 度の回転がある場合、カメラは x 方向に余分に変形します。理由がわかりません。

原点以外の点を中心にカメラを回転させることは知っていますが、カメラが回転している場合、最終的な変換は正しくありません。翻訳コードまたは回転コードに何か問題があるに違いないと思いますが、何が原因かわかりません。

これは複雑な質問であることを知っています。誰かが洞察を持っていれば、助けていただければ幸いです。御時間ありがとうございます。

4

1 に答える 1

1

行列乗算の基本的なプロパティに遭遇しています。実数が 4*5 == 5*4 の場合。ただし、行列には​​当てはまりません。

私は少し酔ってこの答えを書いているので、おそらく間違っているでしょう。なぜなら、それは自然に感じるのとは正反対だからです。最も右の変換が最初に発生し、左の変換が最後に発生します。

これをテストする簡単な方法は、カメラ マトリックスを左右に試すことです。それらの 1 つは、あなたが望むことを行います :) 通常、右辺の行列の乗算を別の空間への変換と考えると非常に役立ちます。通常はモデル * カメラ * プロジェクションである 3D で。次に、カメラを変更します。その前または後に変換が必要です。マウス入力 INPUT からマトリックスで変更するとします。次に、INPUT * CAMERA または CAMERA * INPUT を実行できます。最初のケースでは、参照フレームはカメラのない世界であり、2 番目のケースではカメラから見た世界です。

翻訳の適用と取り消しで同様のことをしようとしていますが、それだけでは十分ではありません。

これが少し役立つことを願っています。お気軽にフォローしてください。しかし、マトリックス数学についても読んでください。それは急な学習曲線ですが、それだけの価値があり、あなたの質問から判断すると、あなたは非常に近いです:)

于 2013-03-28T07:21:44.173 に答える