1

我正在为我的 opengl-es 2.0 3D 应用程序使用 GLKit 和 PowerVR 库。3D 场景加载了几个模拟车库环境的网格。我在车库中央有一辆车。我正在尝试向应用程序添加触摸处理,用户可以在其中旋转房间(例如,查看汽车周围的所有 4 面墙)。我也想允许在 x 轴上旋转,尽管限制在一个很小的范围内。基本上,他们可以从车顶的一点点看到地板的上方。

我可以在 Y 或 X 上旋转,但不能同时旋​​转。一旦我在两个轴上旋转,汽车就会偏离轴。汽车不再与相机保持水平。我希望我能更好地解释这一点,但希望你们能理解。

这是我的触摸实现:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch * touch = [touches anyObject];
    CGPoint location = [touch locationInView:self.view];    
    CGPoint lastLoc = [touch previousLocationInView:self.view];
    CGPoint diff = CGPointMake(lastLoc.x - location.x, lastLoc.y - location.y);

    float rotX = -1 * GLKMathDegreesToRadians(diff.x / 4.0);
    float rotY = GLKMathDegreesToRadians(diff.y / 5.0);

    PVRTVec3 xAxis = PVRTVec3(1, 0, 0);
    PVRTVec3 yAxis = PVRTVec3(0,1,0);

    PVRTMat4 yRotMatrix, xRotMatrix;

    // create rotation matrices with angle
    PVRTMatrixRotationXF(yRotMatrix, rotY);
    PVRTMatrixRotationYF(xRotMatrix, -rotX);

    _rotationY = _rotationY * yRotMatrix;
    _rotationX = _rotationX * xRotMatrix;
}

这是我的更新方法:

- (void)update {

    // Use the loaded effect
    m_pEffect->Activate();


    PVRTVec3    vFrom, vTo, vUp;
    VERTTYPE    fFOV;
    vUp.x = 0.0f;
    vUp.y = 1.0f;
    vUp.z = 0.0f;

    // We can get the camera position, target and field of view (fov) with GetCameraPos()
    fFOV = m_Scene.GetCameraPos(vFrom, vTo, 0);

    /*
     We can build the world view matrix from the camera position, target and an up vector.
     For this we use PVRTMat4LookAtRH().
     */
    m_mView = PVRTMat4::LookAtRH(vFrom, vTo, vUp);

    // rotate the camera based on the users swipe in the X direction (THIS WORKS)
    m_mView = m_mView * _rotationX;

    // Calculates the projection matrix
    bool bRotate = false;
    m_mProjection = PVRTMat4::PerspectiveFovRH(fFOV, (float)1024.0/768.0, CAM_NEAR, CAM_FAR, PVRTMat4::OGL, bRotate);
}

我尝试先将新的 X 旋转矩阵与当前场景旋转相乘,然后再将新的 Y 旋转矩阵相乘。我尝试了相反的方法,认为乘法的顺序是我的问题。那没有帮助。然后我尝试在乘以当前旋转之前将新的 X 和 Y 旋转矩阵加在一起,但这也不起作用。我觉得我很接近,但在这一点上我只是没有想法。

你们能帮忙吗?谢谢。-瓦莱丽

更新:为了解决这个问题,我试图简化一点。我已经更新了上面的代码,删除了 Y 旋转范围内的任何限制。基本上,我根据用户在屏幕上的滑动来计算 X 和 Y 旋转。

如果我理解正确,我想我想用 _rotationX 的计算来旋转视图矩阵(相机/眼睛)。

我想我需要使用 World 矩阵(原点 0,0,0)进行 _rotationY 计算。我会试着得到一些我在说什么的图像。

4

1 回答 1

0

哇,搞定了!我用 X 旋转矩阵旋转了视图矩阵(由 LookAt 方法创建)。我用 Y 旋转矩阵旋转了模型视图矩阵。

这是修改后的更新方法:

- (void)update {

    PVRTVec3    vFrom, vTo, vUp;
    VERTTYPE    fFOV;

    // We can get the camera position, target and field of view (fov) with GetCameraPos()
    fFOV = m_Scene.GetCameraPos(vFrom, vTo, 0);

    /*
     We can build the world view matrix from the camera position, target and an up vector.
     For this we use PVRTMat4LookAtRH().
     */
    m_mView = PVRTMat4::LookAtRH(vFrom, vTo, PVRTVec3(0.0f, 1.0f, 0.0f));

    // rotate on the X axis (finger swipe Y direction)
    m_mView = m_mView * _rotationY;

    // Calculates the projection matrix
    m_mProjection = PVRTMat4::PerspectiveFovRH(fFOV, (float)1024.0/768.0, CAM_NEAR, CAM_FAR, PVRTMat4::OGL, false);

}

这是修改后的触摸移动方法:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch * touch = [touches anyObject];
    CGPoint location = [touch locationInView:self.view];    
    CGPoint lastLoc = [touch previousLocationInView:self.view];
    CGPoint diff = CGPointMake(lastLoc.x - location.x, lastLoc.y - location.y);

    float rotX = -1 * GLKMathDegreesToRadians(diff.x / 2.5);
    float rotY = GLKMathDegreesToRadians(diff.y / 2.5);

    PVRTMat4 rotMatrixX, rotMatrixY;

    // create rotation matrices with angle
    PVRTMatrixRotationYF(rotMatrixX, -rotX);
    PVRTMatrixRotationXF(rotMatrixY, rotY);

    _rotationX = _rotationX * rotMatrixX;
    _rotationY = _rotationY * rotMatrixY;

}
于 2012-12-29T18:45:17.603 回答