0

マウスを使用して、3D 空間で 3D オブジェクトを移動しようとしています。

そこで、実際の行列を取得し、gluUnProject (ウィンドウ座標をオブジェクト座標にマップする) を使用して、マウス位置 dx と dy から実際の x、y、z を取得します。

設計上、私のプロジェクトには、オブジェクトを変換する 3 つの関数があり、各軸に 1 つずつあります。そのため、「mouseMoveEvent」のようなイベントが発生するたびに、「mouseHasMoved(x,y,z)」という信号を発します (x,y,z は gluunproject から取得され、スケーリングされます)。下)。

このシグナル (QT ベース) は、上で説明した 3 つのメソッドを呼び出すコントローラーによってキャッチされます。

そのままで動作しますが、ラグが多く、動きが正確ではありません。選択したオブジェクトは、本来あるべき平行計画から遠ざかる傾向があります。

「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();
}

問題は、私がしていることは論理的に正しいかということです。

4

2 に答える 2

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 を使用して、オブジェクトが移動できるプランを取得します (次に、\sub 値をオブジェクトの位置に追加する変換関数を呼び出します)。そのため、マウスが指す場所はオブジェクトの位置とは異なります。私の画面に。

この結果を達成するにはどうすればよいですか?論理的な手順を説明してもらえますか?

于 2013-07-01T23:19:46.850 に答える