элементы управления arcball с помощью Qt и OpenGL

Я пытаюсь реализовать контроллер аркбола / трекбола, используя Open GL и Qt. Тем не менее, я новичок в OpenGL. У меня ужасно, ужасно, ужасно получается заставить работать вещи.

Я начал с этого видео: https://www.youtube.com/watch?v=3IQV65ApWGs

Я использую Qt для своего окна, используя их класс QtWidget.

По сути, у меня есть куб вокруг источника. Я хочу вращать камеру вокруг куба мышью. Прямо сейчас, когда я тащу, камера, кажется, остается на месте, пока куб вращается вокруг сферы. Вид противоположности того, что мне нужно.

Я надеюсь, что вы, ребята, можете помочь. Я чувствую, что я попробовал почти все здесь.

Сначала моя работа с мышью:

void GLWidget::wheelEvent(QWheelEvent *e){
scrollDelta +=  e->delta() / 120;
}

void GLWidget::mousePressEvent(QMouseEvent *e){
rotate=false;
if(e->button() == Qt::LeftButton){
oldX = e->x(); // Set this to the mouse position
oldY = e->y(); // Set this to the mouse position

newX = e->x();
newY = e->y();

qDebug() << oldX << oldY << newX << newY;

rotate = true;

useArcBall = true;
}
}

void GLWidget::mouseMoveEvent(QMouseEvent *e){
if(e->buttons() & Qt::LeftButton){
//qDebug() << QString::number(e->x());
if(rotate){
newX = e->x();
newY = e->y();
updateMouse();

}
oldX = e->x();
oldY = e->y();
}

}

void GLWidget::mouseReleaseEvent(QMouseEvent *e){
if(e->button() == Qt::LeftButton)
useArcBall = false;

}

void GLWidget::updateMouse()
{

QVector3D v = getArcBallVector(oldX,oldY); // from the mouse
QVector3D u = getArcBallVector(newX, newY);

float angle = std::acos(std::min(1.0f, QVector3D::dotProduct(u,v)));

QVector3D rotAxis = QVector3D::crossProduct(v,u);

QMatrix4x4 eye2ObjSpaceMat = rotationMat.inverted();

QVector3D objSpaceRotAxis = eye2ObjSpaceMat * rotAxis;

qDebug() << 4 * qRadiansToDegrees(angle);//modelview.rotate(4 * qRadiansToDegrees(angle), rotAxis);

//oldRot = newRot;

//oldX = newX;
//oldY = newY;

//qDebug() << objSpaceRotAxis.normalized();if(true){
rotationMat.rotate(4 * qRadiansToDegrees(angle), objSpaceRotAxis);
}

}

Теперь математика, связанная с аркболом:

QVector3D GLWidget::getArcBallVector(int x, int y)
{
QVector3D pt = QVector3D(2.0 * x / GLWidget::width() - 1.0, 2.0 * y / GLWidget::height() - 1.0 , 0);
pt.setY(pt.y() * -1);

// compute z-coordinates

float xySquared = pt.x() * pt.x() + pt.y() * pt.y();

if(xySquared <= 1.0)

pt.setZ(std::sqrt(1.0 - xySquared));
else
pt.normalize();

return pt;

}

И это та часть, где я отрисовываю все:

void GLWidget :: paintGL ()
{
QMatrix4x4 modelview;

QPainter painter;
painter.begin(this);

painter.beginNativePainting();

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glFrontFace(GL_CW);
glCullFace(GL_FRONT);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);modelview.perspective(90.0f, 4.0f / 3.0f, 0.1f, 3000.0f);

modelview.lookAt(QVector3D(eyeX,eyeY,eyeZ), QVector3D(0,0,0), QVector3D(0,1,0));// New Trackball code

modelview = rotationMat * modelview;

modelview.scale(1 - scrollDelta / 10);

Что я делаю неправильно?
Мой подход неоснователен?

Обновить Поэтому я исправил некоторые манипуляции с мышью. Теперь моя проблема в том, что куб вращается вокруг поверхности сферы, а не камеры. Это потому, что я использую команду lookat?

Кроме того, куб закрывается цветом фона, когда я его включаю. Это проблема проекции?

4

Решение

похоже, что ваши матрицы применяются в неправильном порядке

в paintGL ты должен сделать:

modelview *= rotationMat;

и в updateMouse вы должны сделать

QMatrix4x4 tmp;
tmp.rotate(4 * qRadiansToDegrees(angle), objSpaceRotAxis);
rotationMat = tmp * rotationMat;
0

Другие решения