【问题标题】:Rotation when flipping up vector from Y to Z将矢量从 Y 向上翻转到 Z 时的旋转
【发布时间】:2016-04-17 01:02:11
【问题描述】:

我有一个旋转问题。

我将相机设置为向上矢量是 Z,-X 是向前,右侧是 Y。我有在另一个坐标系中导出的模型,其中 Y 向上,-Z 向前,X 是正确的。

我的挑战/问题是轮换。在这种情况下如何在不更改我导入的对象的坐标系的情况下进行正确的旋转。规模和转型正在发挥应有的作用。

到目前为止,我已经尝试在旋转矩阵手册中交换 Y 和 Z 轴,分别做旋转矩阵,在我们读取控制文件时进行旋转,翻转 Z 和 Y 旋转轴,将矩阵更改为

| 1 0 0 |

| 0 0 1 |

| 0 1 0 |

等等。

PS。我不想更改我现在导入的对象文件的坐标系,当我在控制文件中写入 rotateY 时,它将在我的 Y 轴而不是对象 Y 轴上旋转对象。

这是我正在尝试转换的代码部分

// control file is where i store transform, rotate and scale in a text file and objects that i want to read. 
for(int i = 0; i< controls.size(); i++) {
        meshStruct tempMesh;

        int isMeshLoaded = loadObjFile((char*)controls[i].path, &tempMesh.objectInfo_, &tempMesh.numObjects_);
        if(isMeshLoaded)
        {
            cout<< "Mesh " << controls[i].path << " loaded sucesfully." << endl;
        } else {
            cout<< "Mesh " << controls[i].path << " loaded failed." << endl;
        }

        tempModelMatrix = mat4(1.0f, 0.0f, 0.0f, 0.0f,
                                0.0f, 1.0f, 0.0f, 0.0f,
                                0.0f, 0.0f, 1.0f, 0.0f,
                                0.0f, 0.0f, 0.0f, 1.0f);

        //mat4 tempModelMatrixFlip = mat4(1.0f, 0.0f, 0.0f, 0.0f,
        //                              0.0f, 0.0f, 1.0f, 0.0f,
        //                              0.0f, 1.0f, 0.0f, 0.0f,
        //                              0.0f, 0.0f, 0.0f, 1.0f);
        //tempModelMatrix *= tempModelMatrixFlip;

        tempModelMatrix = glm::translate(tempModelMatrix, controls[i].translate);

        tempModelMatrix = glm::rotate(tempModelMatrix, radians(controls[i].rotation.x), vec3(1.0, 0.0, 0.0));
        // I dont want to flip here Y and Z because some objects are in the correct coordinate system
        tempModelMatrix = glm::rotate(tempModelMatrix, radians(controls[i].rotation.y), vec3(0.0, 1.0, 0.0));
        tempModelMatrix = glm::rotate(tempModelMatrix, radians(controls[i].rotation.z), vec3(0.0, 0.0, 1.0)); 
        /*
        mat4 r  = mat4(1.0f);
        mat4 rx = mat4(1.0f); 
        mat4 ry = mat4(1.0f);
        mat4 rz = mat4(1.0f);
        rx = rotate(radians(controls[i].rotation.x), vec3(1.0, 0.0, 0.0));
        ry = rotate(radians(controls[i].rotation.y), vec3(0.0, 1.0, 0.0));
        rz = rotate(radians(controls[i].rotation.z), vec3(0.0, 0.0, 1.0));
        r = rx * ry * rz;       

        vec4 temp;

        temp = column(r, 1);
        cout << to_string(temp) << endl;
        r = column(r,1, column(r, 2));
        r = column(r,2, temp);

        temp = row(r,1);
        r = row(r, 1,row(r,2));
        r = row(r, 2, temp);
        //cout << to_string(column(tempModelMatrix, 1)) << endl;

        //tempModelMatrix *= r;
        float tempModelMatrix2[16];// = mat4(1.0f);

        tempModelMatrix2[0] =  controls[i].scale.x * column(r, 0).x;//controls[i].scale.x * controls[i].rotation.x;
        tempModelMatrix2[1] =  controls[i].scale.x * column(r, 0).y;//controls[i].scale.x * controls[i].rotation.x;
        tempModelMatrix2[2] =  controls[i].scale.x * column(r, 0).z;//controls[i].scale.x * controls[i].rotation.x;
        tempModelMatrix2[3] =  0.0f;
        tempModelMatrix2[4] =  controls[i].scale.y * column(r, 2).x;//controls[i].scale.y * controls[i].rotation.y;
        tempModelMatrix2[5] =  controls[i].scale.y * column(r, 2).y;//controls[i].scale.y * controls[i].rotation.y;
        tempModelMatrix2[6] =  controls[i].scale.y * column(r, 2).z;//controls[i].scale.y * controls[i].rotation.y;
        tempModelMatrix2[7] =  0.0f;
        tempModelMatrix2[8] =  controls[i].scale.z * column(r, 1).x;//controls[i].scale.z * controls[i].rotation.z;
        tempModelMatrix2[9] =  controls[i].scale.z * column(r, 1).y;//controls[i].scale.z * controls[i].rotation.z;
        tempModelMatrix2[10] = controls[i].scale.z * column(r, 1).z;//controls[i].scale.z * controls[i].rotation.z;
        tempModelMatrix2[11] = 0.0f;
        tempModelMatrix2[12] = controls[i].translate.x;
        tempModelMatrix2[13] = controls[i].translate.y;
        tempModelMatrix2[14] = controls[i].translate.z;
        tempModelMatrix2[15] = 1.0f;*/

        tempModelMatrix = glm::scale(tempModelMatrix, controls[i].scale);
        //cout << controls[i].path << " controls[i].translate " << to_string(controls[i].translate) << endl;
        //cout << controls[i].path << " controls[i].rotation.X " <<  controls[i].rotation.x << endl;
        //cout << controls[i].path << " controls[i].rotation.y " <<  controls[i].rotation.y << endl;
        //cout << controls[i].path << " controls[i].rotation.Z " <<  controls[i].rotation.z << endl;
        //cout << controls[i].path << " controls[i].scale " << to_string(controls[i].scale) << endl;

        string basedir = dirname(controls[i].path);
        for(int j = 0; j < tempMesh.numObjects_; j++){
            //tempMesh.objectInfo_[j].modelMatrix = controls[i].modelMatrix;
            tempMesh.objectInfo_[j].modelMatrix = tempModelMatrix;
            //tempMesh.objectInfo_[j].modelMatrix = make_mat4(tempModelMatrix2);

【问题讨论】:

    标签: opengl matrix rotation transform glm-math


    【解决方案1】:

    由于我无法确定您如何存储对象中的顶点数据,因此我将定义一些简单的东西:

    struct Vertex {
        glm::vec3 position;
    };
    
    struct Mesh {
        std::vector<Vertex> vertices;
    };
    

    现在遍历所有顶点位置并将它们转换为您的世界坐标:

    Mesh originalMesh = loadObjectFromFile("object.file");
    Mesh convertedMesh = Mesh();
    
    for (Vertex v : originalMesh.vertices) {
        convertedMesh.push_back(glm::vec3(v.y, v.z, v.x));
    }
    

    这里要注意的关键是我们正在执行以下映射:

    x = v.y
    y = v.z
    z = v.x
    

    如果您有其他顶点数据(例如法线、texcoords),请确保它们也被转换。

    【讨论】:

    • 我获得了“loadObjFile”功能,但现在无法更改。这就是为什么我需要一个解决方案的原因。我也不能用 Blender 或类似的东西转换对象。问题是我和我的教授争论这不是一个好的解决方案,因为有些物体旋转正确,有些不是由于不同的局部坐标系。我今天确实花了 10 多个小时试图找到解决方案。感谢您的帮助:D
    • 我的回答不需要修改loadObjFile或者原文件。您将其转换为您的世界坐标之后它已被加载。
    • 很少有对象可以正确旋转,因为它们位于正确的世界坐标中,并且 obj 加载器将顶点数据发送到 GPU。 :(
    【解决方案2】:

    在与教授通过一些电子邮件后修复了计算旋转矩阵时出现小错误的问题。我是用相反的方式做的

    tempModelMatrix = glm::rotate(tempModelMatrix, radians(controls[i].rotation.x), vec3(1.0, 0.0, 0.0));
    tempModelMatrix = glm::rotate(tempModelMatrix, radians(controls[i].rotation.y), vec3(0.0, 1.0, 0.0));
    tempModelMatrix = glm::rotate(tempModelMatrix, radians(controls[i].rotation.z), vec3(0.0, 0.0, 1.0)); 
    

    而不是

    tempModelMatrix = glm::rotate(tempModelMatrix, radians(controls[i].rotation.z), vec3(0.0, 0.0, 1.0));
    tempModelMatrix = glm::rotate(tempModelMatrix, radians(controls[i].rotation.y), vec3(0.0, 1.0, 0.0));
    tempModelMatrix = glm::rotate(tempModelMatrix, radians(controls[i].rotation.x), vec3(1.0, 0.0, 0.0));
    

    感谢@Exide 的建议

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-28
      • 1970-01-01
      • 1970-01-01
      • 2020-06-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多