我正在尝试使用鼠标在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();
}
问题是:我在做什么在逻辑上是正确的?
答案 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函数)。所以我的鼠标指向的位置是不同的从屏幕上对象的位置开始。
如何实现这一结果?有人可以向我解释逻辑步骤吗?