OpenGL ES - 相机查看触摸位置
OpenGL ES - camera look at touch position
我有一个摄像头(主视图、投影)。我在这里创建它:
-(void)setupProjection
{
// Generate a perspective matrix with a 60 degree FOV
float aspect = self.frame.size.width / self.frame.size.height;
ksMatrixLoadIdentity(&_projectionMatrix);
ksPerspective(&_projectionMatrix, 60.0, aspect, 0.01f, 50.0f);
ksTranslate(&_projectionMatrix, 0.0, -0.295, 0.0);
// Defaul value
mFloatScale = 0.5;
// Load projection matrix
glUniformMatrix4fv(_projectionSlot, 1, GL_FALSE, (GLfloat*)&_projectionMatrix.m[0][0]);
}
我还有手势识别器。所以我希望当我的用户移动手指时,他会像在第一人称射击游戏中那样旋转相机。如何更新我的投影矩阵?我想我必须创建类似 lookAt 函数的东西。
要么使用一种方法生成 lookAt
矩阵,要么创建自己的矩阵。这是一个在网上找到的简单方程式。
一旦你有了这个,我建议你将代表你的相机的 3 个向量存储为 position
、forward
、up
。这些将被插入到 lookAt
方法中 (center = position+forward
).
现在,您可以实现相当多的相机移动变体。全向情况是创建一个额外的向量 right
,它是 forward
和 up
的叉积。那么:
- 转left/right:
forward += right*someRotationSpeedFactor
- 转up/down:
forward += up*someRotationSpeedFactor
- 倾斜left/right:
up += right*someRotationSpeedFactor
- 移动forward/backwards:
position += forward*someSpeedFactor
- 移动up/down:
position += up*someSpeedFactor
- 横向移动:
position += right*someSpeedFactor
改变方向意味着负面因素。这些因素通常是从用户输入(两个触摸事件的距离)或当前速度接收的。使用这些等式中的任何一个后,您需要重新归一化 forward
和 up
的更改向量(将它们除以它们的距离)。您还需要通过再次使用叉积重新计算受影响的向量 forward
或 up
(如果有的话)。例如,如果您出现,您将更改 forward
向量,但 up
向量也会受到它的影响。这意味着您需要将 up
向量设置为 forward
和 right
向量的叉积。这在理论上听起来令人困惑,但在实践中它看起来像这样:
- (void)turnUp:(CGFloat)scale {
vector forward = self.forward;
vector up = self.up;
vector right = cross(self.forward, self.up);
self.forward = normalized(forward + up*scale);
self.up = cross(self.forward, right);
}
现在这个程序非常适合驾驶 space 飞船或喷气式飞机。但是第一人称射击游戏通常会受到更多限制,因为 up
矢量必须始终朝上显示。然后不会实现倾斜,并且在某些游戏中,您对最大向上角度有限制。这是由于本例中的数学问题。无论如何,一般来说,如果您只是简单地保持 up
向量不变,您应该没问题,但您可能需要在计算后对 right
向量进行归一化,因为它的长度不再为 1。
我有一个摄像头(主视图、投影)。我在这里创建它:
-(void)setupProjection
{
// Generate a perspective matrix with a 60 degree FOV
float aspect = self.frame.size.width / self.frame.size.height;
ksMatrixLoadIdentity(&_projectionMatrix);
ksPerspective(&_projectionMatrix, 60.0, aspect, 0.01f, 50.0f);
ksTranslate(&_projectionMatrix, 0.0, -0.295, 0.0);
// Defaul value
mFloatScale = 0.5;
// Load projection matrix
glUniformMatrix4fv(_projectionSlot, 1, GL_FALSE, (GLfloat*)&_projectionMatrix.m[0][0]);
}
我还有手势识别器。所以我希望当我的用户移动手指时,他会像在第一人称射击游戏中那样旋转相机。如何更新我的投影矩阵?我想我必须创建类似 lookAt 函数的东西。
要么使用一种方法生成 lookAt
矩阵,要么创建自己的矩阵。这是一个在网上找到的简单方程式。
一旦你有了这个,我建议你将代表你的相机的 3 个向量存储为 position
、forward
、up
。这些将被插入到 lookAt
方法中 (center = position+forward
).
现在,您可以实现相当多的相机移动变体。全向情况是创建一个额外的向量 right
,它是 forward
和 up
的叉积。那么:
- 转left/right:
forward += right*someRotationSpeedFactor
- 转up/down:
forward += up*someRotationSpeedFactor
- 倾斜left/right:
up += right*someRotationSpeedFactor
- 移动forward/backwards:
position += forward*someSpeedFactor
- 移动up/down:
position += up*someSpeedFactor
- 横向移动:
position += right*someSpeedFactor
改变方向意味着负面因素。这些因素通常是从用户输入(两个触摸事件的距离)或当前速度接收的。使用这些等式中的任何一个后,您需要重新归一化 forward
和 up
的更改向量(将它们除以它们的距离)。您还需要通过再次使用叉积重新计算受影响的向量 forward
或 up
(如果有的话)。例如,如果您出现,您将更改 forward
向量,但 up
向量也会受到它的影响。这意味着您需要将 up
向量设置为 forward
和 right
向量的叉积。这在理论上听起来令人困惑,但在实践中它看起来像这样:
- (void)turnUp:(CGFloat)scale {
vector forward = self.forward;
vector up = self.up;
vector right = cross(self.forward, self.up);
self.forward = normalized(forward + up*scale);
self.up = cross(self.forward, right);
}
现在这个程序非常适合驾驶 space 飞船或喷气式飞机。但是第一人称射击游戏通常会受到更多限制,因为 up
矢量必须始终朝上显示。然后不会实现倾斜,并且在某些游戏中,您对最大向上角度有限制。这是由于本例中的数学问题。无论如何,一般来说,如果您只是简单地保持 up
向量不变,您应该没问题,但您可能需要在计算后对 right
向量进行归一化,因为它的长度不再为 1。