简体   繁体   English

OpenGL 3D相机gluLookAt

[英]OpenGL 3D camera gluLookAt

I'm trying to set up a 3D camera with the gluLookAt method. 我正在尝试使用gluLookAt方法设置3D相机。 So I have got a 10x10x10 cube and now i want to move the camera inside that cube. 所以我有一个10x10x10的立方体,现在我想把相机移到那个立方体里面。 I have something like that: 我有类似的东西:

gluLookAt( camera->x,camera->y,camera->z, camera->eyeX, camera->eyeY, camera->eyeZ, 0, 1, 0 );

now I'm moving forward/backward: 现在我向前/向后移动:

if(GetKeyState(VK_UP) <0)
               {    
                    camera->x += sin(camera->angleX)*0.1f;
                    camera->eyeX += sin(camera->angleX)*0.1f;               
                    camera->z -= cos(camera->angleX)*0.1f;
                    camera->eyeZ -= cos(camera->angleX)*0.1f;
            }

now I'm rotating left/right: 现在我向左/向右旋转:

if(GetKeyState(VK_LEFT) <0)
            {   
                camera->angleX -=0.1f;
                camera->eyeX = sin(camera->angleX) +camera->x;
                camera->eyeZ = -cos(camera->angleX) + camera->z;
            }

So that all works perfectly but now i want to rotate up/down while the SHIFT button is pressed. 这样一切都完美无缺,但现在我想在按下SHIFT按钮的同时向上/向下旋转。 So i have something like that: 所以我有类似的东西:

if(GetKeyState(VK_SHIFT) <0)
            {   
                if(GetKeyState(VK_UP)<0)
                {
                    camera->angleY +=0.1f;                  
                    camera->eyeY = sin(camera->angleY) +camera->y;                  
                }

And actually something strange happens. 实际上发生了奇怪的事情。 The camera keeps bouncing up and down all the time and slowly moving forward. 相机一直在上下弹跳,慢慢向前移动。 Additionaly I want to add that when I look up and move forward the camera actually goes there where it looks. 另外我想补充一点,当我向上看并向前移动时,相机实际上会在那里看起来。 So basicaly the situation looks like that: I'm a ghost trapped in a 10x10x10 cube and can walk wherever I want. 所以情况看起来很基本:我是一个被困在10x10x10立方体中的幽灵,可以在任何我想要的地方行走。 I want to move to the upper right corner? 我想搬到右上角? I JUST GO THERE. 我只是去那儿。 So... any ideas what should I change/add? 那么......任何想法我应该改变/添加什么?

EDIT: I am starting my reply from scratch as I may have assumed too much familiarity with the subject. 编辑:我从头开始回复,因为我可能已经对这个主题过于熟悉了。

The problem you are facing is that your formulas are basically not correct : your formula for rotating left/right are correct under the assumption that the "up" vector (the vector pointing upward from the camera) is always [0 1 0]... which is not the case if you also want to rotate up/down. 您面临的问题是您的公式基本上不正确:在“向上”向量(从摄像机向上指向的向量)始终为[0 1 0]的假设下,左/右旋转的公式是正确的。如果你还想要向上/向下旋转,情况并非如此。 And your formula for rotating up down is not correct since it only modifies the Y component and rotations do not work that way. 而你向下旋转的公式是不正确的,因为它只修改Y分量,旋转不起作用。

The correct way to handle that is: 处理这个问题的正确方法是:

  • to store 3 variables that represent the camera position (as you did). 存储3个代表摄像机位置的变量(就像你一样)。 Let's call them Px , Py , Pz 我们称它们为PxPyPz
  • to store 3 variables that represent the camera view direction (instead of your eyeX/Y/Z that encode the point the camera is looking at). 存储3个表示摄像机视图方向的变量(而不是编码摄像机正在查看的点的eyeX / Y / Z)。 Let's call them Vx , Vy , Vz 我们称之为VxVyVz
  • to store 3 variables that represent the camera right vector (or up vector, as you wish). 存储3个代表摄像机右矢量的变量(或向上矢量,如你所愿)。 Let's take the right vector, and call it Rx , Ry , Rz . 让我们采用正确的向量,并称之为RxRyRz

Alternatively, you can have a nice "Vector" class that represent vectors instead of storing 3 variables each time. 或者,您可以使用一个很好的“Vector”类来表示向量,而不是每次存储3个变量。 This is a detail at this point. 这是一个细节。

Now, your method to move your camera forward just becomes: 现在,您向前移动相机的方法变为:

Px += Vx;
Py += Vy;
Pz += Vz;

You can use, for example, Rodrigues formula to rotate (hoping nobody will launch at you the "quaternion" magic word to express their cleverness ;) ). 你可以使用,例如, Rodrigues公式旋转(希望没有人会向你发射“四元数”魔术词来表达他们的聪明;))。 The general self-contained code to rotate around an arbitrary axis would then be: 围绕任意轴旋转的一般自包含代码将是:

// rotate the vector (vx, vy, vz) around (ax, ay, az) by an angle "angle"

void rotate(double &vx, double &vy, double &vz, double ax, double ay, double az, double angle) {
  double ca = cos(angle);
  double sa = sin(angle);
  double crossx = -vy*az + vz*ay;
  double crossy = -vz*ax + vx*az;
  double crossz = -vx*ay + vy*ax;
  double dot = ax*vx + ay*vy + az*vz;
  double rx = vx*ca + crossx*sa + dot*ax*(1-ca);
  double ry = vy*ca + crossy*sa + dot*ay*(1-ca);
  double rz = vz*ca + crossz*sa + dot*az*(1-ca);
  vx = rx; 
  vy = ry; 
  vz = rz;
}

And make sure to keep normalized coordinates for your camera vectors. 并确保为相机矢量保持标准化坐标。

Now, to specifically rotate your camera up/down when you press a button: 现在,要在按下按钮时专门上/下旋转相机:

// rotate up:
rotate(Vx, Vy, Vz, Rx, Ry, Rz, some_CONSTANT_angle);
// rotate down:
rotate(Vx, Vy, Vz, Rx, Ry, Rz, - some_CONSTANT_angle);

To rotate left/right, you first need to compute the "Up" vector that doesn't need to be stored (unless you want to, but it is redundant), and rotate both your view direction and right vectors: 要向左/向右旋转,首先需要计算不需要存储的“向上”向量(除非您想要,但它是多余的),并旋转视图方向和右向量:

// find up vector using a cross product:
  double Ux = Ry*Vz - Rz*Vy;
  double Uy = Rz*Vx - Rx*Vz;
  double Uz = Rx*Vy - Ry*Vx;

//rotate left
    rotate(Rx, Ry, Rz, Ux, Uy, Uz, some_CONSTANT_angle);
    rotate(Vx, Vy, Vz, Ux, Uy, Uz, some_CONSTANT_angle);
// rotate right
    rotate(Rx, Ry, Rz, Ux, Uy, Uz, - some_CONSTANT_angle);
    rotate(Vx, Vy, Vz, Ux, Uy, Uz, - some_CONSTANT_angle);

Setting up your camera matrix now becomes: 现在设置相机矩阵变为:

  gluLookAt( Px, Py, Pz, Px+Vx, Py+Vy, Pz+Vz, Rx, Ry, Rz); // or is it Ux, Uy, Uz at the end? don't remember.

Of course, I didn't test any of this code, and wrote it now. 当然,我没有测试任何代码,现在就写了。 Hope it works! 希望它有效!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM