4

LibGDX を使用して構築されたアプリケーションで、カメラを回転させたり、ユーザーが移動したり、ズームしたりできるようにする必要がある状況になりました。カメラを移動およびズームするためのカメラ コントロールは美しく機能しますが、カメラを回転させると、その回転に基づいてカメラが移動します。たとえば、カメラが左に 45 度回転している場合、ユーザーがカメラを移動するために右にドラッグすると、カメラの右側が現在指している場所であるため、カメラは右上に向かって移動します。代わりに、回転に関係なく、カメラが画面/ユーザー入力に対して常に移動する必要があります。

この問題の解決策は 1 つあります。それは、現在使用しようとしている「ウィンドウ座標」に基づくのではなく、単純に「ワールド座標」を使用してカメラを配置することです。ただし、これにより、カメラがかなり途切れ途切れになり、ズームシステムに問題が発生するため、非常に不快なユーザーエクスペリエンスが作成されます. これらの問題は、多くの微調整で修正できると思いますが、ウィンドウ座標を使用すると非常にスムーズになるため、その方法を使用したいと思います。

この一見単純な問題に対するエレガントな解決策があると思います。行列またはそれらの線に沿った何かで簡単な計算を行うことができますが、OpenGL に関する私の知識はまだかなり不足しており、正確に何が必要なのかを理解できないようです。それを修正します。OpenGL とこのすべての行列に詳しい人からのアイデアは大歓迎です!

===編集===

ここで値を保持するために使用されるオブジェクトは、基本的に、アプリケーションの別の部分で必要とされた私自身のバージョンの Vector2 です。そこにある0.7fの正確な理由はよく覚えていませんが、おそらくムーブメントの感度を下げるためであり、それを削除しても問題は解決しません.

camera.position.set(cameraStartPosition.getX() - ((zoomCurrentPosition.getX() - zoomStartPosition.getX()) * 0.7f), cameraStartPosition.getY() + ((zoomCurrentPosition.getY() - zoomStartPosition.getY())  * 0.7f), 0);

cameraStartPosition - ユーザーがカメラを動かし始めたときのカメラの X 座標と Y 座標。

zoomStartPosition - ズームを開始する最初のタッチの X 座標と Y 座標

zoomCurrentPosition - ズームを制御するタッチが現在ある X 座標と Y 座標

これらの x 値と y 値は、 touchDown メソッドと touchDragged メソッドから直接取得されます。代わりに、次のコードの後に​​それらを設定するコードを配置すると、元の投稿で言及した問題が発生し、本来の方法で移動しますが、非常に途切れます。

    Vector3 vector = new Vector3(x, y, 0);
    camera.unproject(vector);
    x = (int) vector.x;
    y = CanvasAnywhereMain.HEIGHT - (int) vector.y;
4

1 に答える 1

2

今日、軌道カメラをプログラミングしていたときに、同様の問題に対処していました。私がこの問題にどのように対処したかを説明しようと思います。

軌道カメラが X 軸と Y 軸を同時に回転できるようにしたかったのですが、うまくいきませんでした。それぞれこの軸だけを中心に回転できました。

私にとってのトリックは次のとおりです。

Vector3 target = Vector3.zero
Vector3 right = new Vector().set(camera.direction).crs(camera.up).nor();

// This angles usualy comes from touchDragged event in your input processor
// class implementing the InputProcessor, where you do your calculations
deltaAngleX = 1.1f;
deltaAngleY = 1.9f;

// Rotate around X axis
camera.rotateAround(target, right, deltaAngleX);

// Rotate around Y
camera.updateRotation(Vector3.Y, deltaAngleY);

Y軸を中心に回転している場合、Y軸はX回転に応じて変化しないため、すべて問題ありません。ローカルの Y 軸ではなく、常にワールドの Y 軸を中心に回転する必要があります。

ただし、X を中心に回転している場合は、Vector3.X を使用できません。これは、この軸がカメラの位置と方向に関連していないためです。そのため、カメラの「ローカル Y」軸を計算する必要があります。そのためには、2 つのベクトルの外積が何であるかを知る必要があります。wiki の Cross productlibgdx クラス リファレンスの crs() を参照してください

次のコード フラグメントは、現在のカメラに対して右軸を指す新しい Vector3 を返します。そのベクトルを正規化したいので、nor() 呼び出しが存在することに注意してください。

簡単に言えば:

Vector3 right = new Vector().set(direction).crs(up).nor();

Crs は、2 つのベクトル (この場合は camera.direction と camera.up) から外積ベクトルを作成します。

Vector3 で正しいメンバー変数が公開されていない理由、または正しいベクトル計算方法が存在しない理由がわかりませんが、とにかくこれでうまくいきます

コードを少し編集するだけで、プレーヤー、カメラ、または必要な軸を中心に世界中のあらゆるものを移動できます。基本的なベクトル操作を理解する必要があるだけなので、それらを試してみることをお勧めします

最後のメモ:

Y を中心に回転するとローカル X 軸が変更され、再計算が必要になるため (正しいベクトル)、最初に X 軸を中心に回転する必要があります。

于 2013-02-07T09:34:26.917 に答える