Search code examples
c++qtcoordinate-transformation

How to rotate this mesh correctly?


I draw cube with 6 calls of draw_plane. I generate flate XY plane, then i rotate it and create cube. I need to rotate all this cube correctly. Before rotation enter image description here

 planeXY.setupMesh();
    
    planeXY1.setupMesh();
    planeXY1.modelMatrix.translate(QVector3D(0.0, 0.0, 2.0));
    
    planeZY.setupMesh();
    planeZY.modelMatrix.rotate(-90.0f, QVector3D(0.0f, 1.0f, 0.0f));
    
    planeZY1.setupMesh();
    planeZY1.modelMatrix.translate(QVector3D(2.0, 0.0, 0.0));
    planeZY1.modelMatrix.rotate(-90.0f, QVector3D(0.0f, 1.0f, 0.0f));
    
    planeXZ.setupMesh();
    planeXZ.modelMatrix.rotate(90.0f, QVector3D(1.0f, 0.0f, 0.0f));
    
    planeXZ1.setupMesh();
    planeXZ1.modelMatrix.translate(QVector3D(0.0, 2.0, 0.0));
    planeXZ1.modelMatrix.rotate(90.0f, QVector3D(1.0f, 0.0f, 0.0f));

Plane generation

Mesh CreateMeshPlane(Vector3D bottomleft, size_t numvertices_x, 
                     size_t numvertices_y, size_t worldsize_x, 
                     size_t worldsize_y)
{
    Mesh mesh;
    int numVerts = numvertices_x * numvertices_y;
    int numFaces = (numvertices_x - 1) * (numvertices_y - 1);
    int numIndices = numFaces * 6;

    float xStep = (float)worldsize_x / (numvertices_x - 1);
    float yStep = (float)worldsize_y / (numvertices_y - 1);

    mesh.vertices.resize(numVerts);
    mesh.indices.resize(numIndices);
   
    
    
    for (size_t y = 0; y < numvertices_y; y++)
    {
        for (size_t x = 0; x < numvertices_x; x++)
        {
                mesh.vertices[x + (y * numvertices_x)] = QVector3D(bottomleft.x() + (xStep * x), bottomleft.y() + (yStep * y), bottomleft.z());
        }
    }

    int offset = 0;

    for (int i = 0; i < numIndices; i+=6)
    {
        unsigned int cornerIndex = i/6 + offset;

        if ((cornerIndex + 1)%numvertices_x == 0)
        {
            offset++;
            cornerIndex++;
        }

        // First triangle
        int idx = 0;
        Face face;
        face.FaceIndices.resize(6);

        face.Edges.push_back(Edge((unsigned int)cornerIndex, (unsigned int)cornerIndex + numvertices_x));

        face.FaceIndices[idx] = (unsigned int)cornerIndex;/*0*/
        idx++;
        face.FaceIndices[idx] = (unsigned int)cornerIndex + numvertices_x; /*3*/
        idx++;

        face.Edges.push_back(Edge((unsigned int)cornerIndex + numvertices_x, (unsigned int)cornerIndex + numvertices_x + 1));
        face.FaceIndices[idx] = (unsigned int)cornerIndex + numvertices_x + 1; /*4*/
        idx++;

        // Second triangle
        face.FaceIndices[idx] = (unsigned int)cornerIndex;
        face.Edges.push_back(Edge((unsigned int)cornerIndex, (unsigned int)cornerIndex + 1));
        idx++;
        face.FaceIndices[idx] = (unsigned int)cornerIndex + numvertices_x + 1;
        idx++;
        face.Edges.push_back(Edge((unsigned int)cornerIndex + numvertices_x + 1, (unsigned int)cornerIndex + 1));
        face.FaceIndices[idx] = (unsigned int)cornerIndex + 1;
        mesh.faces.push_back(face);
    }

    return mesh;
}

Creating planes

planeXZ = CreateMeshPlane({0.0, 0.0, 0.0}, ny, nx, 2, 2);
            planeXZ1 = CreateMeshPlane({0.0, 0.0, 0.0}, ny, nx, 2, 2);
            
            planeXY = CreateMeshPlane({0.0, 0.0, 0.0}, ny, nz, 2, 2);
            planeXY1 = CreateMeshPlane({0.0, 0.0, 0.0}, ny, nz, 2, 2);           
            
            planeZY = CreateMeshPlane({0.0,0.0,0.0}, nx, nz, 2, 2);
            planeZY1 = CreateMeshPlane({0.0, 0.0,0.0}, nx, nz, 2, 2);

Then i try to rotate all planes around X axis. My code

if(ev->key() == Qt::Key_R)
    {
          planeXY.modelMatrix.rotate(20.0f, QVector3D(1.0f, 0.0f, 0.0f));

    planeXY1.modelMatrix.rotate(20.0f, QVector3D(1.0f, 0.0f, 0.0f));

    planeZY.modelMatrix.rotate(20.0f, QVector3D(1.0f, 0.0f, 0.0f));

    planeZY1.modelMatrix.rotate(20.0f, QVector3D(1.0f, 0.0f, 0.0f));

    planeXZ.modelMatrix.rotate(20.0f, QVector3D(1.0f, 0.0f, 0.0f));

    planeXZ1.modelMatrix.rotate(20.0f, QVector3D(1.0f, 0.0f, 0.0f));
    
    }

Result:

enter image description here

We can see that each plane rotates around its own X axes, how to rotate all planes around global X axis


Solution

  • In your keyboard event you need to apply the rotation from the other side. So your code should look similar to this:

    if(ev->key() == Qt::Key_R)
    {
        QMatrix4x4  mat;
        //mat.translate(rotationCenter.x, rotationCenter.y, rotationCenter.z);
        mat.rotate(20.0f, QVector3D(1.0f, 0.0f, 0.0f));
        //mat.translate(-rotationCenter.x, -rotationCenter.y, -rotationCenter.z);        
    
        planeXY.modelMatrix = mat * planeXY.modelMatrix;
        planeXY1.modelMatrix = mat * planeXY1.modelMatrix;
        planeZY.modelMatrix = mat * planeZY.modelMatrix;
        planeZY1.modelMatrix = mat * planeZY1.modelMatrix;
        planeXZ.modelMatrix = mat * planeXZ.modelMatrix;
        planeXZ1.modelMatrix = mat * planeXZ1.modelMatrix;
    }
    

    (I never used Qt so far so there might be some typos inside.)

    When you do no want to rotate about the origin of world space you need the 2 translations which are commented out.