射线拾取的“射线"创建无法完全正常工作 [英] 'Ray' creation for raypicking not fully working

查看:132
本文介绍了射线拾取的“射线"创建无法完全正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现一个射线拾取器"以选择项目中的对象.我不完全了解如何实现此功能,但是我从概念上了解它应该如何工作.我一直在尝试学习如何执行此操作,但是我发现大多数教程都超出了我的理解范围.我当前的代码基于我发现的最新教程之一,此处.

I'm trying to implement a 'raypicker' for selecting objects within my project. I do not fully understand how to implement this, but I understand conceptually how it should work. I've been trying to learn how to do this, but most tutorials I find go way over my head. My current code is based on one of the recent tutorials I found, here.

经过几个小时的修改,我相信我的raypicker遇到的问题实际上是首先创建了ray.如果我用无可争议地位于三角形区域内的坐标替换/硬编码我的近/远平面,则选择器可以正确识别它.

After several hours of revisions, I believe the problem I'm having with my raypicker is actually the creation of the ray in the first place. If I substitute/hardcode my near/far planes with a coordinate that would undisputably be located within the region of a triangle, the picker identifies it correctly.

我的问题是:我的射线创建似乎没有完全考虑到当前的相机"或透视图,因此相机旋转不会影响鼠标的位置. 我相信要解决这个问题,我需要使用gluUnProject()之类的东西,但是每当使用此方法时,返回的x,y,z坐标都将非常小,

My problem is this: my ray creation doesn't seem to fully take my current "camera" or perspective into account, so camera rotation won't affect where my mouse is. I believe to remedy this I need something like using gluUnProject() or something, but whenever I used this the x,y,z coordinates returned would be incredibly small,

我目前的射线创作是一团糟.我尝试使用其他人最初提出的方法,但是无论我尝试使用哪种方法,它似乎都无法与我的选择器/交叉点函数一起使用.

My current ray creation is a mess. I tried to use methods that others proposed initially, but it seemed like whatever method I tried it never worked with my picker/intersection function.

这是我创建光线的代码:

Here's the code for my ray creation:

void oglWidget::mousePressEvent(QMouseEvent *event)
{   

    QVector3D nearP = QVector3D(event->x()+camX, -event->y()-camY, -1.0);
    QVector3D farP = QVector3D(event->x()+camX, -event->y()-camY, 1.0);

    int i = -1;
    for (int x = 0; x < tileCount; x++)
    {
        bool rayInter = intersect(nearP, farP, tiles[x]->vertices);
        if (rayInter == true)
            i = x;
    }
    if (i != -1)
    {
        tiles[i]->showSelection();
    }
    else
    {
        for (int x = 0; x < tileCount; x++)
            tiles[x]->hideSelection();
    }
    //tiles[0]->showSelection();
}

要重复,我曾经加载过视口,模型和投影矩阵,并取消投影鼠标坐标,但是在1920x1080的窗口内,我得到的值是x y& amp;在2到2的范围内.每个鼠标事件的z值,这就是我尝试使用此方法的原因,但是该方法不适用于相机旋转和缩放.

To repeat, I used to load up the viewport, model & projection matrices, and unproject the mouse coordinates, but within a 1920x1080 window, all I get is values in the range of -2 to 2 for x y & z for each mouse event, which is why I'm trying this method, but this method doesn't work with camera rotation and zoom.

我不想进行像素颜色选择,因为谁知道以后我可能需要这种技术,而我宁愿在到目前为止付出的努力之后也不要放弃

I don't want to do pixel color picking, because who knows I may need this technique later on, and I'd rather not give up after the amount of effort I put in so far

推荐答案

好的,所以这是我面包屑追踪的开始.

Ok, so this is the beginning of my trail of breadcrumbs.

我在某种程度上遇到了矩阵的QT数据类型以及与矩阵转换有关的逻辑问题.

I was somehow having issues with the QT datatypes for the matrices, and the logic pertaining to matrix transformations.

此问题中的这个特殊问题是由于实际上未执行任何转换所致.

This particular problem in this question resulted from not actually performing any transformations whatsoever.

解决此问题的步骤是:

  • 将鼠标坐标转换为NDC空间(在-1到1的范围内:x/屏幕宽度* 2-1,y-高度/高度* 2-1)
  • 将4x4矩阵用作我的视图矩阵(可以是渲染或重新计算时使用的矩阵)
  • 在新矢量中,使它等于反视图矩阵乘以反投影矩阵.

为了构建射线,我必须执行以下操作:

In order to build the ray, I had to do the following:

  • 取先前相乘的矩阵的计算值.这将乘以向量4(4个点的阵列),其中将保存先前计算的x和y坐标,以及 -1 ,然后+1.
  • 然后将这个矢量除以整个矢量的最后一个点值
  • 创建另一个向量4,该向量与最后一个相似,但不是-1,而是放置"1" .
  • 再次将其除以其最后一个现货值.
  • Take the previously calculated value for the matrices that were multiplied together. This will be multiplied by a vector 4 (array of 4 spots), where it will hold the previously calculated x and y coordinates, as well as -1, then +1.
  • Then this vector will be divided by the last spot value of the entire vector
  • Create another vector 4 which was just like the last, but instead of -1, put "1" .
  • Once again divide that by its last spot value.

现在,射线的坐标已在远近平面上创建,因此它可以与场景中沿它的任何东西相交.

Now the coordinates for the ray have been created at the far and near planes, so it can intersect with anything along it in the scene.

我提出了一系列问题(由于我的一系列问题存在很大的不确定性),所以我的部分问题也在其中重叠.

I opened a series of questions (because of great uncertainty with my series of problems), so parts of my problem overlap in them too.

  • 在这里,我了解到我需要考虑屏幕高度用于切换笛卡尔系统的y轴的原点,因为窗口的y轴从左上方开始.另外,矩阵的检索是多余的,但由于从未被正确地声明过,因此也是错误的.
  • 在这里,我了解到unProject无法正常工作因为我试图使用OpenGL函数提取模型并查看矩阵,但是我从来没有真正设置它们,因为我是手动构建矩阵的.我分两步解决了这个问题:我手动进行了数学运算,并制作了所有相同数据类型的矩阵(它们之前是混合数据类型,也导致了问题).
  • 最后,在这里,我了解到我的操作顺序略有偏离(需要将矩阵乘以矢量,而不是反向矩阵),我的近平面需要为-1,而不是0,并且矢量的最后一个值将与矩阵相乘(值"w" )必须为1.
  • In here, I learned that I needed to take the screen height into consideration for switching the origin of the y axis for a Cartesian system, since windows has the y axis start at the top left. Additionally, retrieval of matrices was redundant, but also wrong since they were never declared "properly".
  • In here, I learned that unProject wasn't working because I was trying to pull the model and view matrices using OpenGL functions, but I never actually set them in the first place, because I built the matrices by hand. I solved that problem in 2 fold: I did the math manually, and I made all the matrices of the same data type (they were mixed data types earlier, leading to issues as well).
  • And lastly, in here, I learned that my order of operations was slightly off (need to multiply matrices by a vector, not the reverse), that my near plane needs to be -1, not 0, and that the last value of the vector which would be multiplied with the matrices (value "w") needed to be 1.

对那些帮助我解决这些问题的个人提供信贷:

Credits goes to those individuals who helped me solve these problems:

  • srobins of facepunch, in this thread
  • derhass from here, in this question, and this discussion

这篇关于射线拾取的“射线"创建无法完全正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆