0

我已经使用 Objective C++ 将我一直在使用的 arcball 类从 vb.net 移植到了 iPhone,但现在我遇到了问题。当我旋转我的对象时,一切都很好。平移视图后,我的旋转中心不再像以前那样位于对象原点的中心。理想情况下,我希望能够设置旋转点在对象参考框架中的位置。我不确定我需要在轨迹球例程中的哪个位置进行更改才能执行此操作。我基于我的实现可以在以下链接中找到:

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

编辑:

我几乎想出了如何做到这一点。我已经到了可以为我的 Arcball 设置旋转中心的地步,但现在我遇到了另一个问题。当我应用变换围绕指定的中心点进行旋转时,有两个问题:

  1. 模型跳转到不同的位置。我想将模型保持在完全相同的位置和方向。

  2. 该模型围绕新的中心点进行缩放,但我希望模型围绕用户用两根手指触摸的平均点进行缩放。

对于 2 号,我想我知道该怎么做,但我需要弄清楚 1 号才能使 2 号正常工作。对于数字 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 不久前编写了一个示例应用程序,它使用轨迹球在 Core Animation 上下文中旋转两个图像,可以很容易地修改它以在 OpenGL ES 中工作(Core Animation 和 OpenGL ES 使用相同的矩阵结构进行变换) .

我实现了另一种旋转模型的方法,即使用 X 和 Y 中的触摸移动来围绕屏幕的 Y 和 X 轴旋转,如用户所见。这可以在我的Molecules应用程序的源代码中找到,也可以在我编写的显示 3-D 立方体的示例应用程序中找到。我在这里稍微解释一下这是如何工作的。

这两种方法仍然设法使模型围绕其原点旋转,即使它在特定方向上移位。

于 2010-12-29T15:13:52.003 回答
0

好的,我终于弄清楚发生了什么。最糟糕的是,我一直都在正确地做这件事。我遇到的唯一问题是我的三角形射线相交算法返回了错误的点。我解决了这个问题,现在控件按预期执行,旋转中心永远不会在屏幕上移动,模型只是移动,因此原点保持在同一位置。进行转换的代码是我在原帖中提到的:

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 回答