所以这是我今天的第二个问题,我可能会推动我的运气 简而言之,制作一个3D第一人称,你可以在那里四处走动。
在我的OnDrawFrame中我正在使用
Matrix.setLookAtM(mViewMatrix, 0, eyeX , eyeY, eyeZ , lookX , lookY , lookZ , upX, upY, upZ);
向后移动,向后移动,向左移动等我使用类似的东西(列出前向代码)
float v[] = {mRenderer.lookX - mRenderer.eyeX,mRenderer.lookY - mRenderer.eyeY, mRenderer.lookZ - mRenderer.eyeZ};
mRenderer.eyeX += v[0] * SPEED_MOVE;
mRenderer.eyeZ += v[2] * SPEED_MOVE;
mRenderer.lookX += v[0] * SPEED_MOVE;
mRenderer.lookZ += v[2] * SPEED_MOVE;
这有效
现在我想环顾四周,尝试移植我的iPhone openGL 1.0代码。这是左/右
float v[] = {mRenderer.lookX - mRenderer.eyeX,mRenderer.lookY - mRenderer.eyeY, mRenderer.lookZ - mRenderer.eyeZ};
if (x > mPreviousX )
{
mRenderer.lookX += ((Math.cos(SPEED_TURN / 2) * v[0]) - (Math.sin(SPEED_TURN / 2) * v[2]));
mRenderer.lookZ += ((Math.sin(SPEED_TURN / 2) * v[0]) + (Math.cos(SPEED_TURN / 2) * v[2]));
}
else
{
mRenderer.lookX -= (Math.cos(SPEED_TURN / 2) *v[0] - Math.sin(SPEED_TURN / 2) * v[2]);
mRenderer.lookZ -= (Math.sin(SPEED_TURN / 2) *v[0] + Math.cos(SPEED_TURN / 2) * v[2]);
}
这适用于35度,然后是心理?
有什么想法吗?
答案 0 :(得分:5)
首先,我建议不要追踪look
向量,而是追踪forward
向量,然后在lookAt
方法中使用eye+forward
生成look
向量。这样,您可以在移动时完全取消look
上的更新,而无需计算v
向量(mRenderer.eyeX += forward.x * SPEED_MOVE;
...)
为了使事情变得更简单,我建议您在更改它们时对矢量forward
和up
进行规范化(我将按照您在以下方法中的方式进行考虑)。
现在轮换有两种方式。使用right
和up
向量来移动forward
(以及up
),这对于小转弯非常有用(我说最多10度并且上限为90度)或计算当前角度,添加任意角度并重新创建矢量。
首次提到的旋转方法非常简单:
vector forward = forward
vector up = up
vector right = cross(forward, up) //this one might be the other way around as up, forward :)
//going left or right:
forward = normalized(forward + right*rotationSpeedX)
//going up or down:
forward = normalized(forward + up*rotationSpeedY)
vector right = cross(forward, up) //this one might be the other way around
vector up = normalized(cross(forward, right)) //this one might be the other way around
//tilt left or right:
up = normalized(up + right*rotationZ)
第二种方法需要一点三角法:
通常要计算一个角度,你可以调用atan(forward.z/forward.x)
并添加一些if
语句,因为生成的结果只有180度角(我相信你能找到一些答案) web来从矢量获得旋转)。获取垂直旋转的up
向量也是如此。然后在获得角度后,您可以轻松地向角度添加一些度数,并使用sin
和cos
重新创建向量。但是有一个问题,如果你以这种方式旋转相机,那么前方面朝上(0,1,0),你需要从up
向量获得第一次旋转,从forward
获得第二次旋转。矢量,但你可以避免所有这一切,如果你将最大垂直角度限制在+ - 85度(并且有很多游戏实际上这样做)。第二件事是如果你使用这种方法,你的环境必须支持+ -infinitive,否则atan(forward.z/forward.x)
会在forward.x == 0
时生效。
还有一些关于第一种方法的补充。由于我看到你试图在2D空间中移动,因此使用移动速度的前向矢量应该是normalized(forward.x, 0, forward.z)
,重要的是将其标准化,否则如果相机向上或向下倾斜更多,则移动速度会变慢。
第二件事是当您向左/向右旋转时,您可能希望强制up
向量到(0,1,0)+标准化右向量,最后从向前和向右重新创建向上向量。那么你应该再对垂直旋转进行限制(up.z应该大于一些小值,如.01)
答案 1 :(得分:0)
原来我的轮换代码错了
if (x > mPreviousX )
{
mRenderer.lookX = (float) (mRenderer.eyeX + ((Math.cos(SPEED_TURN / 2) * v[0]) - (Math.sin(SPEED_TURN / 2) * v[2])));
mRenderer.lookZ = (float) (mRenderer.eyeZ + ((Math.sin(SPEED_TURN / 2) * v[0]) + (Math.cos(SPEED_TURN / 2) * v[2])));
}
else
{
mRenderer.lookX = (float) (mRenderer.eyeX + ((Math.cos(-SPEED_TURN / 2) * v[0]) - (Math.sin(-SPEED_TURN / 2) * v[2])));
mRenderer.lookZ = (float) (mRenderer.eyeZ + ((Math.sin(-SPEED_TURN / 2) * v[0]) + (Math.cos(-SPEED_TURN / 2) * v[2])));
}