2

好的,这是一个非常具体的问题,与我在 OpenGL 中的相机变换有关。当视图打开时,旋转点围绕原点 - 当您平移相机时,它首先进行平移,然后进行旋转以保持旋转点围绕原点。

好吧,我希望旋转点从原点更改为您单击的六边形图块,而相机位置不会出现变化。这似乎很模糊,所以我附上了一些图片来说明。

我不能包含图片,因为我的代表在这里不够高,但这里是 flickr 上照片的链接

首次打开视图时

现在,当我单击新图块以更改旋转点时,相机会移动以使该图块保持在屏幕中心。我会发布一个链接来显示,但同样只有两个链接的足够代表 - 所以我将发布一个链接到我希望如何改变旋转点的图片(旋转点改变时相机不会移动) .

我希望它如何发生

好的,现在一些代码 - 这是获取相机变换矩阵的代码

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])。代码在这里。

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 方向上变换额外的量。我不知道为什么。

我知道要围绕原点以外的点旋转相机,您可以平移 * 旋转 * -translate 这是我在最后一种情况下所拥有的,但如果旋转相机,最终的平移是不正确的。我认为我的翻译或旋转代码一定有问题,但我不知道是什么。

我知道这是一个复杂的问题,如果有人有任何见解,我将不胜感激。谢谢你的时间。

4

1 回答 1

1

您遇到了矩阵乘法的基本属性。如果你有实数 4*5 == 5*4。但是,矩阵并非如此。

我写这个答案有点醉,所以我可能会弄错,因为它与感觉自然相反:最右边的变换首先发生,左边的最后发生。

一个简单的测试方法是左右尝试你的相机矩阵。其中一个会做你想做的:) 将右侧的矩阵乘法视为对不同空间的转换通常很有帮助。在 3D 中,通常是模型 * 相机 * 投影。现在您要更改 CAMERA。您想要在它之前或之后进行转换。假设您通过鼠标输入 INPUT 的矩阵进行更改。然后你可以做 INPUT * CAMERA 或 CAMERA * INPUT。在第一种情况下,您的参考系是没有相机的世界,在第二种情况下,它是相机看到的世界。

您正在尝试通过应用和撤消翻译来做类似的事情,但这还不够。

我希望这能有所帮助。随时跟进。但也要阅读矩阵数学。这是一个陡峭的学习曲线,但非常值得,从你的问题来看,你非常接近:)

于 2013-03-28T07:21:44.173 回答