0

我有一些代码可以在 opengl 中创建一个 3d 视图,然后使用设备运动在其中环顾四周。我知道这是可行的,因为我可以将 3d 立方体放置在我周围的空间中,并查看它们是否在正确的位置。(我只是用 x/y/z 坐标创建它们)。

该代码使用设备的旋转矩阵,然后将其应用于各个块。

CMRotationMatrix r = dm.attitude.rotationMatrix;
GLKMatrix4 baseModelViewMatrix = GLKMatrix4Make(r.m11, r.m21, r.m31, 0.0f,
                                                r.m12, r.m22, r.m32, 0.0f,
                                                r.m13, r.m23, r.m33, 0.0f,
                                                0.0f,  0.0f,  0.0f,  1.0f);


float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);

GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, kNearZ, kFarZ);

block.effect.transform.projectionMatrix = projectionMatrix;

我想要做的是弄清楚我在看哪里,然后在我面前创建一个街区。

通过在一个方向上创建一个向量,将旋转矩阵应用于它,然后读取它的新值,我取得了一些有限的成功。但它只适用于某些方向 - 当我旋转太远时它会搞砸。

GLKVector4 vect = GLKVector4Make(0.0f,0.0f,10.0f,1.0f);

GLKVector4 newVec = GLKMatrix4MultiplyVector4(baseModelViewMatrix,vect);

然后我读取 newVec.x,newVec.y,newVec.z 并使用它们来放置立方体。

有人可以告诉我我是否在正确的轨道上?有没有更简单的方法来实现这一点?

这一切的数学是相当艰巨的。

更新:

我已经取得了一些部分成功

 GLKVector3 newVec1 = GLKVector3Make(-r.m22, -r.m33, r.m21);

这仅适用于一个横向方向,也仅适用于我当前位置周围的圆柱体。上/下轴不太正确。

旋转矩阵的这些部分是否足以在我周围的任何地方得到一个点?

更新 2:

认为发布更多代码以使其真正清晰可能会有所帮助。

这就是所有内容的显示方式。

//1- get device position
CMDeviceMotion *dm = motionManager.deviceMotion;
CMRotationMatrix r = dm.attitude.rotationMatrix;

GLKMatrix4 baseModelViewMatrix = GLKMatrix4Make(r.m11, r.m21, r.m31, 0.0f,
                                    r.m12, r.m22, r.m32, 0.0f,
                                    r.m13, r.m23, r.m33, 0.0f,
                                    0.0f,  0.0f,  0.0f,  1.0f);

GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(45.0f), aspect, kNearZ, kFarZ);


//2- work out position ahead of current view
GLKVector3 newVector = GLKVector3Make(-r.m22, -r.m33, r.m21);

//place cube in 3d space- this works fine when just positioning with x,y,z co-ordinates
cube.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 modelViewMatrix = GLKMatrix4Identity;

modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, newVector.x*100, newVector.y*100, newVector.z*100);
modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);

cube.effect.transform.modelviewMatrix = modelViewMatrix;
4

1 回答 1

0

您查看的向量可能应该乘以倒矩阵。你没有写出你得到了什么结果,但这里有一些可能的解决方案:

  1. newVect1 = (r.m13, r.m23, r.m33)
  2. newVect2 = (-r.m13, -r.m23, r.m33)
  3. 将 (0,0,1) 与倒矩阵相乘

编辑:(添加一些解释)

如果您的 baseModelViewMatrix 负责旋转您周围的所有对象,那么面向前方(显示方式)的矢量应该由 baseModelViewMatrix 的倒置矩阵旋转。如果确实,如果 baseModelViewMatrix 是恒等式,则面向前方的正确向量是 (0,0,1),那么只需将 (0,0,1) 与倒矩阵相乘(您可以简单地尝试一下,甚至应该,只需将其设置为标识并将对象放置在(0,0,100)或其他位置)。如果不是,您应该找到朝前的那个并对其执行相同的操作。

关于我发布的第二种方法,newVect2 = (-r.m13, -r.m23, r.m33)它专门用于 (0,0,1) 是前向向量的情况。这个想法是旋转矩阵由 3 个基向量 x,y,z 组成,其中每一行分别代表其中一个(它始终适用于创建旋转矩阵,但可能不可逆)。如果第 3 行确实代表 z 基向量,则向量 (0,0,1) 将转换为 (r.m13, r.m23, r.m33) 并且您似乎面对的是镜像的向量通过它的正常(0,0,1)。该操作将是 R' = normal*(2*dot(normal, R)) - R 并且对于 normal 为 (0,0,1) 且 R 为 (r.m13, r.m23, r .m33),结果 R' 是 (-r.m13, -r.m23, r.m33)。就像这里的注释一样,它可能会被转过来,z 基向量是 (r.m31, r.m32, r.m33)。

在任何情况下,如果第 3 个选项不起作用,则第 2 个选项也不起作用,问题可能是 (0,0,1) 不是身份的前向向量。

于 2013-04-09T12:39:09.950 回答