使用gluUnProject在3D空间中移动物体时滞后且缺乏准确性

时间:2013-07-01 15:44:15

标签: c++ qt opengl

我正在尝试使用鼠标在3D空间中移动3D对象。

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

通过设计我的项目有3个函数来翻译对象,每个轴一个。所以每当发生像'mouseMoveEvent'这样的事件时它会发出一个信号'mouseHasMoved(x,y,z)'(x,y,z来自gluunproject and scale down)。

该信号(基于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-&gt; mPos是相机位置。

这为gluUnProject()

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

相同的翻译函数与3个QSliders(x,y,z)相关联,并且它们准确而快速。因此,这不是函数问题。这是一个在捕获信号时调用的方法的示例

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

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

2 个答案:

答案 0 :(得分:1)

您可以使用“拣货”技术。查看本教程 http://www.lighthouse3d.com/opengl/picking/

答案 1 :(得分:0)

解决了 部分 (请阅读此处的底部)将\ down向下移动从左\右:将上面的mousemove函数更改为< / p>

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来检索我的对象可以移动的计划(然后调用将\ sub值添加到对象位置的translate函数)。所以我的鼠标指向的位置是不同的从屏幕上对象的位置开始。

如何实现这一结果?有人可以向我解释逻辑步骤吗?