0

I am using legacy OpenGL and trying to move vertices around with the mouse. To test whether a vertex is clicked on I loop through all vertices and multiply them by the model and projection matrix before dividing by the w value. This works fine and is shown below:

for (Vertex *vertex : context->getMesh().vertices) {
        QVector4D vert(vertex->xPos, vertex->yPos, vertex->zPos, 1.0f);
        QVector4D transformedVert = projectionMatrix * modelMatrix * vert;
        transformedVert /= transformedVert.w();
        if ((mappedX < (transformedVert.x() + 0.1) && mappedX > (transformedVert.x() - 0.1)) &&
            (mappedY < (transformedVert.y() + 0.1) && mappedY > (transformedVert.y() - 0.1))) {
            std::cout << "SUCCESS" << std::endl;
            vertexPicked = true;
            currentVertex = vertex;
        }
    }

Then when I move the mouse I try to work backwards by first multiplying the current mouse coordinates by the same W value as in the first step and then multiplying by the inverse of the projection and model matrices. This moves the vertex around but not to where the mouse is.

  float mouseX = ((2.0f * event->x()) / width() - 1.0f);
  float mouseY = -((2.0f * event->y()) / height() - 1.0f);
  float x = (modelMatrix.inverted() * projectionMatrix.inverted() *
                (QVector4D(mouseX, mouseY, 1, 1) * (projectionMatrix * modelMatrix * QVector4D(MousePicker::currentVertex->xPos, MousePicker::currentVertex->yPos, MousePicker::currentVertex->zPos, 1)).w())).x();

  MousePicker::currentVertex->xPos = x;

I am currently only trying to change the X coordinate.

  • Again you have do divide by `w`. Dived by the `w` component, after the transformation by the inverse model view and projection matrix (of course by the `w` component which is the result of the transformation be the inverse matrices). – Rabbid76 Jan 31 '19 at 14:12
  • @Rabbid76 I tried that and it didn't have any effect. Shoud I be multiplying by the w component before i multiply by the inverse matrices? – Callum Perks Jan 31 '19 at 14:17
  • No. The coordinate which is transformed by the inverse projection matrix has to be a normalized device coordinate (all components in range[-1, 1]). – Rabbid76 Jan 31 '19 at 14:19
  • This is the new code: – Callum Perks Jan 31 '19 at 14:21
  • @Rabbid76 I have done that. I am now multiplying the mouse Coordinates by the inverse matrices and dividing by the w comonent. The vertices are moving way further than the mouse – Callum Perks Jan 31 '19 at 14:22
  • You have a perspective projection. You have to know the depth of the vertex coordinate! `QVector4D(mouseX, mouseY, 1, 1)` is a point on the far plane, but not the vertex coordinate in normalized device space. The normalized device space z coordinate is important too, because at perspective projection the view space x and y coordinate depends on the depth. – Rabbid76 Jan 31 '19 at 14:32

0 Answers0