0

使用していたアークボール クラスを vb.net から iPhone に客観的な C++ を使用して移植しましたが、現在問題が発生しています。オブジェクトを回転させると、すべて問題ありません。ビューをパンするとすぐに、以前のように回転の中心がオブジェクトの原点の中心になくなりました。理想的には、オブジェクトの参照フレームのどこに回転ポイントがあるかを設定できるようにしたいと考えています。これを行うには、アークボール ルーチンのどこを変更する必要があるかわかりません。私がベースにした実装は、以下のリンクにあります。

http://www.codeproject.com/KB/openGL/Tao_Arcball.aspx

動作を少し変更してタッチ インターフェイスに変換しましたが、問題に関する限り、動作はこの実装と同じです。

これらのリンクは、四元数と行列の回転の背後にある数学の詳細を説明しています。

http://www.j3d.org/matrix_faq/matrfaq_latest.html http://www.gamedev.net/reference/articles/article1095.asp http://en.wikipedia.org/wiki/Quaternion_rotation

変更する必要があると思われるコードの主要部分は以下のとおりです (vb.net 内):

        Public WriteOnly Property Rotation() As Quat4f
            Set(ByVal value As Quat4f)
                Dim n, s As Single
                Dim xs, ys, zs As Single
                Dim wx, wy, wz As Single
                Dim xx, xy, xz As Single
                Dim yy, yz, zz As Single

                M = New Single(3, 3) {}

                n = (value.x * value.x) + (value.y * value.y) + (value.z * value.z) + (value.w * value.w)
                s = If((n > 0.0f), 2.0f / n, 0.0f)

                xs = value.x * s
                ys = value.y * s
                zs = value.z * s
                wx = value.w * xs
                wy = value.w * ys
                wz = value.w * zs
                xx = value.x * xs
                xy = value.x * ys
                xz = value.x * zs
                yy = value.y * ys
                yz = value.y * zs
                zz = value.z * zs

                ' rotation
                M(0, 0) = 1.0f - (yy + zz)
                M(0, 1) = xy - wz
                M(0, 2) = xz + wy

                M(1, 0) = xy + wz
                M(1, 1) = 1.0f - (xx + zz)
                M(1, 2) = yz - wx

                M(2, 0) = xz - wy
                M(2, 1) = yz + wx
                M(2, 2) = 1.0f - (xx + yy)

                M(3, 3) = 1.0f

                ' translation (pan)
                M(0, 3) = pan_Renamed.x
                M(1, 3) = pan_Renamed.y

                ' scale (zoom)
                For i As Integer = 0 To 2
                    For j As Integer = 0 To 2
                        M(i, j) *= scl
                    Next j
                Next i
            End Set
        End Property

編集:

私はこれを行う方法をほとんど理解しました。アークボールの回転中心を設定できるようになったのですが、別の問題が発生しました。指定した中心点を中心に回転する変換を適用すると、次の 2 つの問題があります。

  1. モデルが別の場所にジャンプします。モデルをまったく同じ位置と向きに保ちたいと思います。

  2. モデルは新しい中心点を中心にスケーリングしますが、ユーザーが 2 本の指で触れた場所の平均であるポイントを中心にモデルをスケーリングしたいと考えています。

2 番については、やり方はわかったと思いますが、2 番を正しく機能させるには 1 番を理解する必要があります。番号 2 については、平均的なタッチ ポイントをニア プレーンに平行であるがパーツの原点を通過するプレーンに投影し、ユーザーが指を離すまでそれを回転の中心にします。1番のアイデアはありますか?回転の中心を変更するために使用するコードは次のとおりです。

glTranslatef(panVector.x, panVector.y, 0); //panVector is a variable that keeps track of the user panning the model
glMultMatrixf(arcballMatrix); //arcball matrix is the 16 element rotation/scale matrix that controls the model orientation
glTranslatef(-centerOfRotation.x, -centerOfRotation.y, -centerOfRotation.z); //centerOfRotation is a point that is set where I want the center of rotation to be

参考までに、OpenGL は、そのスタックがどのように機能するかにより、マトリックス変換を逆の順序で適用します。したがって、私のコードでは、一番下の行が最初に実行され、次にそこから実行されます。効果的にモデルを移動して、回転の中心が原点にあるようにし、回転/スケーリングしてから、モデルをパンに移動する必要がある場所に移動します。

私が遭遇していると私が信じている問題は、パンを行うときに centerOfRotation を追加する必要があることですが、問題は、モデルが回転すると、centerOfRotation ポイントを何らかの方法で変換して別のモデル空間に配置する必要があることです。モデルを回転する前は正常に動作しますが、回転が導入されると、すべてが爆発します。

4

2 に答える 2

0

VB.NET アークボールに移植するのではなく、既存の iPhone トラックボールの実装を調べることができます。たとえば、Bill Dudney は少し前に、コア アニメーション コンテキスト内でトラックボールを使用して 2 つの画像を回転させるサンプル アプリケーションを作成しました。これは、OpenGL ES 内で動作するように簡単に変更できます (コア アニメーションと OpenGL ES は、変換に同一のマトリックス構造を使用します)。 .

ユーザーから見たように、X と Y のタッチ移動を使用して画面の Y 軸と X 軸を中心に回転させることで、モデルを回転させる別の方法を実装しました。これは、私のMoleculesアプリケーションのソース コード内と、3D 立方体を表示する私が作成したサンプル アプリケーション内にあります。ここで、これがどのように機能するかについて少し説明します。

これらのアプローチはどちらも、モデルが特定の方向に変位した場合でも、モデルをその原点を中心に回転させることができます。

于 2010-12-29T15:13:52.003 に答える
0

OK、ようやく何が起こっているのか理解できました。最悪の部分は、私がずっと正しくやっていたことです。私が抱えていた唯一の問題は、トライアングル レイ交差アルゴリズムが間違ったポイントを返すことでした。その問題を修正したところ、コントロールが期待どおりに動作するようになりました。回転の中心が画面上で移動することはなく、モデルが移動するだけなので、原点は同じ場所に留まります。変換を行うコードは、元の投稿で言及したものです。

glTranslatef(panVector.x, panVector.y, 0); //panVector is a variable that keeps track of the user panning the model
glMultMatrixf(arcballMatrix); //arcball matrix is the 16 element rotation/scale matrix that controls the model orientation
glTranslatef(-centerOfRotation.x, -centerOfRotation.y, -centerOfRotation.z); //centerOfRotation is a point that is set where I want the center of rotation to be
于 2011-02-01T15:56:25.430 に答える