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();
thokra
3
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 )
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);