我正在为我的opengl-es 2.0 3D应用程序使用GLKit和PowerVR库。 3D场景加载了几个网格,模拟车库环境。我在车库的中心有一辆车。我正在尝试为应用程序添加触摸处理,用户可以在其中旋转房间(例如,查看汽车周围的所有4个墙壁)。我还想允许在x轴上旋转,但限制在一个小范围内。基本上他们可以从汽车的顶部看到地板以上的高度。
我可以在X上的Y OR上旋转,但不能同时旋转。一旦我在两个轴上旋转,汽车就会被抛出轴外。汽车不再与相机齐平了。我希望我能更好地解释这一点,但希望你们能理解。
以下是我的实施内容:
- (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旋转矩阵加到一起,然后再乘以当前的旋转,但这也不起作用。我觉得我很接近,但此时我只是出于想法。
你能帮忙吗?谢谢。 -Valerie更新:为了解决这个问题,我正在尝试简化它。我已经更新了上面的代码,删除了Y旋转范围内的任何限制。基本上我根据用户在屏幕上滑动来计算X和Y旋转。
如果我理解正确的话,我想我想用_rotationX的计算旋转View矩阵(相机/眼睛)。
我认为我需要使用World矩阵(原点0,0,0)进行_rotationY计算。我会尝试拍摄一些我正在谈论的图像。
答案 0 :(得分:0)
Wahoo,让这个工作!我用X旋转矩阵旋转了视图矩阵(由LookAt方法创建)。我用Y旋转矩阵旋转了模型视图矩阵。
以下是修改后的Update方法:
- (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;
}