【问题标题】:Lag and lacks of accuracy using gluUnProject for object moving in a 3D space使用 gluUnProject 在 3D 空间中移动对象时滞后且缺乏准确性
【发布时间】:2013-07-20 16:16:00
【问题描述】:

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

所以,我检索实际矩阵并使用 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();
}

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

【问题讨论】:

    标签: c++ qt opengl


    【解决方案1】:

    解决了部分(请阅读本文底部)将上下移动与左右分离:将上述 mousemove 函数更改为

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

    如何达到这个结果?有人可以解释一下逻辑步骤吗?

    【讨论】:

      【解决方案2】:

      您可以为此使用“挑选”技术。检查本教程 http://www.lighthouse3d.com/opengl/picking/

      【讨论】:

      • 我已经在使用拾取模式来选择对象,选择不是问题;)
      猜你喜欢
      • 2012-01-07
      • 1970-01-01
      • 2021-05-12
      • 1970-01-01
      • 2015-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-10
      相关资源
      最近更新 更多