【问题标题】:Rotation around camera's axis绕相机轴旋转
【发布时间】:2013-09-15 17:33:37
【问题描述】:

我想在 OpenGL 中构建适当的相机转换,但我有一个问题。

我在没有 OpenGL 的情况下构建了一个简单的 3D 引擎,只是为了看看将世界简单地投影到屏幕上是多么困难。

在这个引擎中,我将 wiewer 放在 (0,0,0) 上,同时打开视线 (1,0,0)。 ASDW 进行对象的翻译。 鼠标旋转 大约 (1,0,0),(0,1,0),(0,0,1)。

通过编写自己的 3D 引擎,我学到了很多东西。有了这些知识,我开始构建一个合适的基于 OpenGL 的 3D 引擎。

对于 OpenGL 中的相机转换,我编写了这段代码...

相机的轴定义了向上、向右、向前平移的位置。 围绕全局轴进行旋转(我想围绕相机的轴旋转对象):(

glRotatef(camera_rot[0],1,0,0)
glRotatef(camera_rot[1],0,1,0)
glRotatef(camera_rot[2],0,0,1)

camera_rot[0]=0
camera_rot[1]=0
camera_rot[2]=0

glGetFloatv(GL_MODELVIEW_MATRIX, matrix)

glTranslatef(
matrix[0]*camera_tra[0],
matrix[4]*camera_tra[0],
matrix[8]*camera_tra[0])

glTranslatef(
matrix[1]*camera_tra[1],
matrix[5]*camera_tra[1],
matrix[9]*camera_tra[1])

glTranslatef(
matrix[2]*camera_tra[2],
matrix[6]*camera_tra[2],
matrix[10]*camera_tra[2])

camera_tra[0]=0
camera_tra[1]=0
camera_tra[2]=0

为什么 OpenGL 设计者没有将相机放在 (0,0,0) 并在对象而不是相机上进行平移和旋转,这有点令人困惑。

我正在考虑在不使用 glTranslate 或 glRotation 的情况下手动应用转换,并将转换逻辑从我的 3D 引擎(我制作的)放入更改 glVertexe 坐标。 所以每次在绘制函数中我都会改变 glVertexes 坐标。但是如果我这样做,顶点将在我的转换后与相同的矩阵(ModelView 矩阵)相乘,并且我不希望在我的程序中进行无意义的计算。

那么我应该怎么做才能解决这个问题呢? 如何为围绕相机轴的旋转制定最佳解决方案?

【问题讨论】:

    标签: opengl pyopengl


    【解决方案1】:

    YEEEEEES 我为本地相机轴做了 YAW、ROLL、PITCH 旋转和平移:D

    Down 是我负责转换的代码部分。

    这是我的全局常量:

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

    在我绘制对象之前:

    if(camera_drot[0]!=0){    //ROTATE CAMERA_UP AND CAMERA_FORVARD AROUND CAMERA_RIGHT
        MYRotation(camera_right,camera_up,camera_drot[0]);
        MYRotation(camera_right,camera_forvard,camera_drot[0]);
        camera_drot[0]=0;}
    if(camera_drot[1]!=0){    //ROTATE CAMERA_RIGHT AND CAMERA_FORVARD AROUND CAMERA_UP
        MYRotation(camera_up,camera_right,camera_drot[1]);
        MYRotation(camera_up,camera_forvard,camera_drot[1]);
        camera_drot[1]=0;}
    if(camera_drot[2]!=0){    //ROTATE CAMERA_RIGHT AND CAMERA_UP AROUND CAMERA_FORWARD
        MYRotation(camera_forvard,camera_right,camera_drot[2]);
        MYRotation(camera_forvard,camera_up,camera_drot[2]);
        camera_drot[2]=0;}
    
    if(camera_dtra[0]!=0){MYTranslation(camera_right,camera_dtra[0]);camera_dtra[0]=0;}
    if(camera_dtra[1]!=0){MYTranslation(camera_up,camera_dtra[1]);camera_dtra[1]=0;}
    if(camera_dtra[2]!=0){MYTranslation(camera_forvard,camera_dtra[2]);camera_dtra[2]=0;}
    
    glLoadIdentity();
    gluLookAt(
    camera_place[0],camera_place[1],camera_place[2],
    camera_place[0]+camera_forvard[0],camera_place[1]+camera_forvard[1],camera_place[2]+camera_forvard[2],
    camera_up[0],camera_up[1],camera_up[2]);
    }
    

    这是我的函数 MYRotation 和 MYTranslation :)

    static void MYRotation(float vector[3],float point[3],float fi){
        //ROTATE POINT AROUND VECTOR
        float i = point[0]; 
        float j = point[1];
        float k = point[2];
        float x = vector[0];
        float y = vector[1];
        float z = vector[2];
    
        point[0] = i*(x*x + (y*y + z*z)*cos(fi)) + k*(-x*z*(-1 + cos(fi)) + y*sin(fi)) + j*(-x*y*(-1 + cos(fi)) - z*sin(fi));
        point[1] = j*(y*y + (x*x + z*z)*cos(fi)) + k*(-y*z*(-1 + cos(fi)) - x*sin(fi)) + i*(-x*y*(-1 + cos(fi)) + z*sin(fi)); 
        point[2] = k*(z*z + (x*x + y*y)*cos(fi)) + j*(-y*z*(-1 + cos(fi)) + x*sin(fi)) + i*(-    x*z*(-1 + cos(fi)) - y*sin(fi));
    
        float normalize = pow(pow(point[0],2)+pow(point[1],2)+pow(point[2],2),-0.5);
        point[0]=point[0]*normalize;
        point[1]=point[1]*normalize;
        point[2]=point[2]*normalize;    
    }
    static void MYTranslation(float camera_axe[3],float camera_dtra){
        camera_place[0]+=camera_axe[0]*camera_dtra;
        camera_place[1]+=camera_axe[1]*camera_dtra;
        camera_place[2]+=camera_axe[2]*camera_dtra;}
    

    【讨论】:

      【解决方案2】:

      哦,我忘记在 MYRotation 中进行标准化之前进行矢量校正。在程序中,计算错误不会给出正交向量。进行此更正至关重要!

      我会在我完成后发布代码:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-23
        • 2016-09-22
        • 2018-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多