OpenGL摄像机在摄像机本地轴上平移和旋转

时间:2013-09-15 00:07:15

标签: c++ c opengl 3d glut

问题(这里)&回答(我自己在下面)

如何在OpenGL中对局部相机轴进行旋转和平移?真令人沮丧!互联网提供的结果非常少。 我想制作像飞机相机一样的相机,具有俯仰偏航和滚动。 请我知道ewerything(GOOD EXPLANATION)。 解决方案可以与gluLookAt一起使用吗?

1 个答案:

答案 0 :(得分:3)

如果每一步都可以理解,请随时告诉我。如果不是,我会添加更多解释。

活动变量--------------------------------------- -------------------------------------------------- --------

  1. camera_drot = {旋转arou x(右)ax, - \ - y(向上)ax, - \ - z(向前)ax} [弧度]
  2. camera_dtra = {翻译x(右)ax, - \ - y(向上)ax, - \ - z(向前)ax}
  3. 代码:

    float camera_drot[3]={0,0,0};
    float camera_dtra[3]={0,0,0};
    
    float camera_place[3]={0,0,0};
    float camera_right[3]={1,0,0};
    float camera_up[3]={0,1,0};
    float camera_forward[3]={0,0,-1};
    

    变革的寓言-------------------------------------- ----------------------------------------------

    1. 我会删除camera_以获得更好的视野。 :)
    2. 如果围绕x ax旋转摄像机轴,则必须旋转y和z ax(示例)。
    3. 旋转后至关重要,以确保前进,上,右侧的长度为矩形,所有轴的长度必须为“1”!如果我们不做正交性(向前,向右,向上),计算机计算中的错误将总结得非常快!相信我!
    4. 在Orthonormality之后我们可以将相机放置在相机轴的本地系统中。
    5. 好老的gluLookAt()最简单的事情就是与OpenGL的摄像机属性进行交流。
    6. 代码:

      if(drot[0]!=0){
          MYRotation(right,up,drot[0]);      //#Rotate up axis oround right for drot[0] radians
          MYRotation(right,forward,drot[0]);
          drot[0]=0;}
      if(drot[1]!=0){
          MYRotation(up,right,drot[1]);
          MYRotation(up,forward,drot[1]);
          drot[1]=0;}
      if(drot[2]!=0){
          MYRotation(forward,right,drot[2]);
          MYRotation(forward,up,drot[2]);
          drot[2]=0;}
      
      Orthonormality(forward,right,up);
      
      if(dtra[0]!=0){
          MYTranslation(right,place,dtra[0]);
          dtra[0]=0;}
      if(dtra[1]!=0){
          MYTranslation(up,place,dtra[1]);
          dtra[1]=0;}
      if(dtra[2]!=0){
          MYTranslation(forward,place,dtra[2]);
          dtra[2]=0;}
      
      glLoadIdentity();
      gluLookAt(place[0],place[1],place[2],
                place[0]+forward[0],place[1]+forward[1],place[2]+forward[2],
                up[0],up[1],up[2]);
      

      MY Functions --------------------------------------- -------------------------------------------------- ---------------

      <强> 正交性

      1. 规范化vec0!如果我们将vec0标准化,我们会简化许多事情!
      2. vec0向量的正交空间上的投影vec1。orthogonal complement Visual what we do in number 2 ^^^^
      3. 投影后我们必须规范化新的vec1!
      4. 在此步骤中,我们找到了带有Gram–Schmidt process
      5. 的vec3
      6. 最后一步是规范化vec3。
      7. 代码:

        static void Orthonormality(float vec0[3],float vec1[3],float vec2[3]){
            //1
            float normalize = pow(vec0[0]*vec0[0]+vec0[1]*vec0[1]+vec0[2]*vec0[2],-0.5);
            if(normalize!=1){
                vec0[0]=vec0[0]*normalize;
                vec0[1]=vec0[1]*normalize;
                vec0[2]=vec0[2]*normalize;}
        
            //2
            float x1=vec1[0];
            float y1=vec1[1];
            float z1=vec1[2];
        
            vec1[0]=x1*(vec0[1]*vec0[1] + vec0[2]*vec0[2]) - vec0[0]*(vec0[1]*y1 + vec0[2]*z1);
            vec1[1]=-vec0[0]*x1*vec0[1] + vec0[0]*vec0[0]*y1 + vec0[2]*(y1*vec0[2] - vec0[1]*z1);
            vec1[2]=-(vec0[0]*x1 + vec0[1]*y1)*vec0[2] + (vec0[0]*vec0[0] + vec0[1]*vec0[1])*z1;
        
            //3
            normalize = pow(vec1[0]*vec1[0]+vec1[1]*vec1[1]+vec1[2]*vec1[2],-0.5);
            vec1[0]=vec1[0]*normalize;
            vec1[1]=vec1[1]*normalize;
            vec1[2]=vec1[2]*normalize;
        
            //4
            float x0x2_y0y2_z0z2=vec0[0]*vec2[0] + vec0[1]*vec2[1] + vec0[2]*vec2[2];
            float x1x2_y1y2_z1z2=vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2];
            vec2[0] = vec2[0] - vec0[0]*x0x2_y0y2_z0z2 - vec1[0]*x1x2_y1y2_z1z2; 
            vec2[1] = vec2[1] - vec0[1]*x0x2_y0y2_z0z2 - vec1[1]*x1x2_y1y2_z1z2; 
            vec2[2] = vec2[2] - vec0[2]*x0x2_y0y2_z0z2 - vec1[2]*x1x2_y1y2_z1z2;
        
            //5
            normalize = pow(vec2[0]*vec2[0]+vec2[1]*vec2[1]+vec2[2]*vec2[2],-0.5);
            vec2[0]=vec2[0]*normalize;
            vec2[1]=vec2[1]*normalize;
            vec2[2]=vec2[2]*normalize;
            }
        

        <强> MYRotation

        围绕线旋转vec以获得drot弧度。

        static void MYRotation(float line[3],float vec[3],float drot){
            float ux=line[0]*vec[0];    
            float vy=line[1]*vec[1];    
            float wz=line[2]*vec[2];    
            float uu=pow(line[0],2);    
            float vv=pow(line[1],2);    
            float ww=pow(line[2],2);    
            float uxvywz=ux+vy+wz;    
            float sa=sin(drot);    
            float ca=cos(drot);    
            vec[0]=line[0]*uxvywz+(vec[0]*(vv+ww)-line[0]*(vy+wz))*ca+(-line[2]*vec[1]+line[1]*vec[2])*sa;    
            vec[1]=line[1]*uxvywz+(vec[1]*(uu+ww)-line[1]*(ux+wz))*ca+( line[2]*vec[0]-line[0]*vec[2])*sa;    
            vec[2]=line[2]*uxvywz+(vec[2]*(uu+vv)-line[2]*(ux+vy))*ca+(-line[1]*vec[0]+line[0]*vec[1])*sa;
            }
        

        <强> MYTranslation

        翻译vec for line * dtra

        static void MYTranslation(float line[3],float vec[3],float dtra){
            vec[0]+=line[0]*dtra;
            vec[1]+=line[1]*dtra;
            vec[2]+=line[2]*dtra;}