World coordinates changes on camera rotation

Hi,

In my first topic I asked for help with gluUnproject.

My current code is almost finished, but it still have one bug, that’s camera rotation.

I tried it explain in following picture:
[ATTACH=CONFIG]486[/ATTACH]

By my words: On 0 degrees is corrupted world coordinate Z, on -90 degrees is Z fine but X coordinate became corrupted

Source code:

        QMatrix4x4 viewMatrix       = m_camera->viewMatrix();
        QMatrix4x4 modelViewMatrix  = viewMatrix * m_modelMatrix;
        QMatrix4x4 modelViewProject = m_camera->projectionMatrix() * modelViewMatrix;
        QMatrix4x4 inverted         = m_viewportMatrix * modelViewProject;

        inverted = inverted.inverted();

        float posZ;
        int   posY = (int)m_viewportSize.y() - (int)mouse_position.y() - 1;

        m_funcs->glReadPixels((int)mouse_position.x(), posY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &posZ);

        QVector4D clickedPointOnScreen(mouse_position.x(), (float)posY, posZ, 1.0f);
        QVector4D clickedPointIn3DOrgn = inverted * clickedPointOnScreen;

        clickedPointIn3DOrgn = clickedPointIn3DOrgn / clickedPointIn3DOrgn.w();

        terrain_pos = clickedPointIn3DOrgn.toVector3DAffine();

BUMP, any idea?

You don’t change any camera parameter in that code segment - all you do is query some matrices. The bug is probably somewhere else.

Yes, I don’t change, but it’s based on camera matrices, so it must somehow.

I will post here my mouse camera code, if it helps (i’m not really genius in matrices :confused: )

mouseMoveEvent(QMouseEvent* e) - parent QGLWidget

        m_pos = e->pos();

        float dx = 0.4f * (m_pos.x() - m_prevPos.x());
        float dy = -0.4f * (m_pos.y() - m_prevPos.y());

        m_prevPos = m_pos;

        pan(dx);
        tilt(dy);

pan + tilt functions : header QGLWidget

    // Camera orientation control
    void pan(float angle)  { m_panAngle = angle; }
    void tilt(float angle) { m_tiltAngle = angle; }

update : parent QGLWidget called every 16ms with paint

    if(!qFuzzyIsNull(m_panAngle))
    {
        m_camera->pan(m_panAngle, QVector3D(0.0f, 1.0f, 0.0f));
        panAngle  += m_panAngle;
        m_panAngle = 0.0f;
    }

    if(panAngle > 360.0f || panAngle < -360.0f)
        panAngle = 0.0f;

    if(!qFuzzyIsNull(m_tiltAngle))
    {
        if(tiltAngle + m_tiltAngle > 90.0f || tiltAngle + m_tiltAngle < -90.0f)
        {
            float copyTAngle = m_tiltAngle;

            if(tiltAngle + copyTAngle > 90.0f)
            {
                while(tiltAngle + copyTAngle - 0.1f > 90.0f)
                    copyTAngle -= 0.1f;
            }
            else if(tiltAngle + copyTAngle < -90.0f)
            {
                while(tiltAngle + copyTAngle + 0.1f < -90.0f)
                    copyTAngle += 0.1f;
            }

            m_tiltAngle = copyTAngle;
            copyTAngle  = 0.0f;
        }

        m_camera->tilt(m_tiltAngle);
        tiltAngle  += m_tiltAngle;
        m_tiltAngle = 0.0f;
    }

camera

void Camera::tilt(const float& angle)
{
    QQuaternion q = tiltRotation(angle);
    rotate(q);
}

void Camera::pan(const float& angle)
{
    QQuaternion q = panRotation(-angle);
    rotate(q);
}

void Camera::pan(const float& angle, const QVector3D& axis)
{
    QQuaternion q = panRotation(-angle, axis);
    rotate(q);
}

QQuaternion Camera::tiltRotation(const float& angle) const
{
    Q_D(const Camera);
    QVector3D xBasis = QVector3D::crossProduct(d->m_upVector, d->m_cameraToCenter.normalized()).normalized();

    return QQuaternion::fromAxisAndAngle(xBasis, -angle);
}

QQuaternion Camera::panRotation(const float& angle) const
{
    Q_D(const Camera);
    return QQuaternion::fromAxisAndAngle(d->m_upVector, angle);
}

QQuaternion Camera::panRotation(const float& angle, const QVector3D& axis) const
{
    return QQuaternion::fromAxisAndAngle(axis, angle);
}

void Camera::rotate(const QQuaternion& q)
{
    Q_D(Camera);
    d->m_upVector       = q.rotatedVector(d->m_upVector);
    d->m_cameraToCenter = q.rotatedVector(d->m_cameraToCenter);
    d->m_viewCenter     = d->m_position + d->m_cameraToCenter;
}

FIXED thanks to http://www.opengl.org/discussion_boards/showthread.php/171432-gluUnProject-How-to-use-it-in-a-proper-way?p=1204252&viewfull=1#post1204252

I didn’t use whole code but just screenPos Z.

So in my case

QVector4D clickedPointOnScreen(mouse_position.x(), (float)posY, posZ, 1.0f);

TO

QVector4D clickedPointOnScreen(mouse_position.x(), (float)posY, 2.0f * posZ - 1.0f, 1.0f);