对于在三维空间中移动的对象,使用gluUnProject的滞后和缺乏准确性

Lag and lacks of accuracy using gluUnProject for object moving in a 3D space

本文关键字:滞后 gluUnProject 准确性 使用 对象 三维空间 移动      更新时间:2023-10-16

我正试图在三维空间中使用鼠标移动三维对象。

因此,我检索实际的矩阵,并使用gluUnProject(将窗口坐标映射到对象坐标)从鼠标位置dx和dy获得实际的x,y,z。

根据设计,我的项目有3个转换对象的功能,每个轴一个。因此,每当发生类似"mouseMoveEvent"的事件时,它都会发出一个信号"mouseHasMoved(x,y,z)"(x,y,z从gluunproject获得并按比例缩小)。

这个信号(基于QT)被控制器捕获,它调用了我上面提到的三种方法。

事实上,它是有效的,但有很多滞后,运动也不精确。选择的对象往往离它应该停留的平行平面更远。

以下是"mouseMoveEvent"的示例代码:

if (event->buttons() & Qt::RightButton) {
    gluUnProject(event->x(), -event->y(), 0, model_matrix, proj_matrix, view_matrix, &newx, &newy, &newz);
    if (event->x()>lastPos.x()){
        emit SignalPreviewMouseXChanged((float)(newx/1000));
        emit SignalPreviewMouseZChanged((float)(-newz/1000));
    }
    else {
        emit SignalPreviewMouseXChanged((float)(-newx/1000));
        emit SignalPreviewMouseZChanged((float)(newz/1000));
    }

    if (event->y()<lastPos.y())
        emit SignalPreviewMouseYChanged((float)(newy/500));
    else {
        emit SignalPreviewMouseYChanged((float)(-newy/500));
    }
}
lastPos = event->pos();
updateGL();

其中objCamera->mPos是摄影机位置。

这为gluUnProject()设置矩阵

void setMatrixes()
{
  glGetDoublev(GL_MODELVIEW_MATRIX, model_matrix);
  glGetDoublev(GL_PROJECTION_MATRIX, proj_matrix);
  glGetIntegerv(GL_VIEWPORT, view_matrix);
}

相同的翻译函数与3个QSlider(x,y,z)相连,它们准确快速。所以这不是函数问题。下面是一个当信号被捕获时调用的方法的例子

void SlotZRotationValueChanged(float val){
  sceneRef->translate(0,0,tValue*10);
  facade->window->getPreview()->RebuildScene();
}

问题是:我所做的在逻辑上是正确的?

已解决部分(请阅读本文底部)从左\右分离上\下移动:将上述鼠标移动功能更改为

if (event->buttons() & Qt::RightButton) {
    setMatrixes();

    gluUnProject(event->x(), -event->y(), 0, model_matrix, proj_matrix, view_matrix, &newx, &newy, &newz);
    float acc=sqrt((int)dx^2+(int)dy^2);
    acc*=acc;

    qDebug()<< acc;
    if (dy<dx){
        if (event->x()>lastPos.x()){
            emit SignalPreviewMouseChanged((float)(newx/2500)*acc,0,(float)(-newz/2500)*acc);
        }
        else {
            emit SignalPreviewMouseChanged((float)(-newx/2500)*acc,0,(float)(newz/2500)*acc);
        }
    }
    else{
        if (event->y()<lastPos.y())
            emit SignalPreviewMouseChanged(0,(float)(newy/1750)*acc,0);
        else {
            emit SignalPreviewMouseChanged(0,(float)(-newy/1750)*acc,0);
        }
    }
    isPressed=true;
}
lastPos = event->pos();
updateGL();

在控制器中时:

void Controller::SlotMouseTranslationValueChanged(float val1, float val2, float val3){
if (val1!=0) sceneRef->translate(val1,0,0);
if (val2!=0) sceneRef->translate(0,val2,0);
if (val3!=0) sceneRef->translate(0,0,val3);
facade->window->getPreview()->RebuildScene();
}

现在它没有滞后,一切都很好。

考虑:

现在我不是拖动对象,而是使用gluUnproject来检索对象可以移动的平面(然后调用translate函数,将\sub值添加到对象位置)。因此,我的鼠标指向的位置与对象在屏幕上的位置不同

如何实现这一结果?有人能给我解释一下合乎逻辑的步骤吗?

您可以使用"拾取"技术。查看本教程http://www.lighthouse3d.com/opengl/picking/