C++ ';雷';光线拾取的创建未完全工作

C++ ';雷';光线拾取的创建未完全工作,c++,qt,opengl,glu,ray-picking,C++,Qt,Opengl,Glu,Ray Picking,我正在尝试实现一个“光线选择器”,用于在项目中选择对象。我不完全理解如何实现这一点,但我从概念上理解它应该如何工作。我一直在努力学习如何做到这一点,但我发现大多数教程都让我不知所措。我当前的代码基于我最近找到的一个教程 经过几个小时的修改,我相信我的光线采集器的问题实际上是光线的创建。如果我用一个无可争议地位于三角形区域内的坐标替换/硬编码我的近/远平面,选择器将正确识别它 我的问题是:我的光线创建似乎没有充分考虑我当前的“相机”或透视,因此相机旋转不会影响鼠标的位置。 我相信要解决这个问题,我

我正在尝试实现一个“光线选择器”,用于在项目中选择对象。我不完全理解如何实现这一点,但我从概念上理解它应该如何工作。我一直在努力学习如何做到这一点,但我发现大多数教程都让我不知所措。我当前的代码基于我最近找到的一个教程

经过几个小时的修改,我相信我的光线采集器的问题实际上是光线的创建。如果我用一个无可争议地位于三角形区域内的坐标替换/硬编码我的近/远平面,选择器将正确识别它

我的问题是:我的光线创建似乎没有充分考虑我当前的“相机”或透视,因此相机旋转不会影响鼠标的位置。 我相信要解决这个问题,我需要使用glunproject()之类的东西,但每当我使用它时,返回的x,y,z坐标都会非常小

我当前的光线创建非常混乱。我尝试使用其他人最初提出的方法,但似乎无论我尝试了什么方法,它都无法与我的选择器/交集函数一起工作

以下是我的光线创建代码:

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();
}
void oglWidget::mousePressEvent(QMouseEvent*event)
{   
QVector3D nearP=QVector3D(事件->x()+camX,-事件->y()-camY,-1.0);
QVector3D farP=QVector3D(事件->x()+凸轮轴,-event->y()-凸轮轴,1.0);
int i=-1;
对于(int x=0;x顶点);
如果(rayInter==true)
i=x;
}
如果(i!=-1)
{
tiles[i]->showSelection();
}
其他的
{
对于(int x=0;xhideSelection();
}
//tiles[0]->showSelection();
}
为了重复,我曾经加载视口、模型和投影矩阵,并取消投影鼠标坐标,但在1920x1080窗口中,对于每个鼠标事件,我得到的是-2到2范围内的x y&z值,这就是我尝试此方法的原因,但此方法不适用于相机旋转和缩放

我不想做像素颜色选择,因为谁知道我以后可能会需要这种技术,在我付出了这么多努力之后,我宁愿不放弃

在确定各种几何图形之间的交点方面有很多帮助


也有一些C++函数,其中一个为你的目的服务

,因为你似乎在构造光线方面存在问题,下面是我如何做的。这还没有直接测试过。你可以这样做,确保所有向量都在同一个空间。如果使用多个模型矩阵(或其堆栈),则需要对每个矩阵分别重复计算

  • 使用
    pos=glunproject(winx,winy,near,…)
    获取模型空间中近平面上鼠标坐标的位置
    near
    是指定给
    glFrustum()
    GLUPPERVICE()
  • 光线的原点是相机在模型空间中的位置:
    rayorig=inv(modelmat)*相机在世界空间中的位置
  • 光线的方向是从1开始的位置的归一化向量。到光线原点:
    raydir=normalize(pos-rayorig)

  • 在链接的网站上,他们使用两个点来表示光线,而且他们似乎没有规范化光线方向向量,因此这是可选的。

    好的,这是我的面包屑轨迹的开始

    不知何故,我对矩阵的QT数据类型以及与矩阵转换相关的逻辑有问题

    这个问题中的这个特殊问题是因为实际上没有执行任何转换。

    解决这个问题的步骤是:

    • 将鼠标坐标转换为NDC空间(在-1到1的范围内:x/屏幕宽度*2-1,y-高度/高度*2-1)
    • 为我的视图矩阵获取4x4矩阵(可以是渲染或重新计算时使用的矩阵)
    • 在新向量中,使其等于逆视图矩阵乘以逆投影矩阵
    为了构建光线,我必须执行以下操作:

    • 对于相乘的矩阵,取先前计算的值。这将乘以向量4(由4个点组成的数组),其中它将保存先前计算的x和y坐标,以及-1,然后+1
    • 然后该向量将除以整个向量的最后一个点值
    • 创建另一个向量4,它与上一个向量相同,但不是-1,而是放置“1”
    • 再次将其除以最后一个点的值
    现在,光线的坐标已在远平面和近平面上创建,因此它可以与场景中沿它的任何对象相交

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

    • ,我了解到在切换笛卡尔坐标系的y轴原点时需要考虑屏幕高度,因为windows的y轴从左上角开始。此外,检索矩阵是多余的,但也是错误的,因为它们从未被“正确”声明
    • ,我了解到unProject不起作用,因为我试图使用OpenGL函数提取模型和视图矩阵,但我从来没有真正设置它们,因为我是手工构建矩阵的。我用两种方法解决了这个问题:我手工计算,并且我制作了相同数据类型的所有矩阵(之前它们是混合数据类型,也导致了问题)
    • ,我了解到我的运算顺序有点偏离(需要将矩阵乘以向量,而不是相反),