Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 任何对象的OpenGL光线投射_C++_Opengl_Math_3d_Game Engine - Fatal编程技术网

C++ 任何对象的OpenGL光线投射

C++ 任何对象的OpenGL光线投射,c++,opengl,math,3d,game-engine,C++,Opengl,Math,3d,Game Engine,我只是想知道是否有任何方法可以对任何物体执行鼠标拾取检测。它是生成的对象还是导入的对象 [Idea]- 我的想法是,场景中的每个对象都会有迭代。检查鼠标光线是否与对象相交。为了检查交点,它将检查鼠标拾取的光线与构成对象的三角形 [Pros]- 我相信这种方法的好处是,每个对象都可以通过鼠标拾取来检测,因为它们都继承了检测方法 [Cons]- 我认为这种缺点主要是速度和方法非常昂贵。因此,需要对优化进行微调 [情况]- 在过去,我读过关于鼠标拾取的文章,我也实现了一些基本的鼠标拾取形式。但所有这些

我只是想知道是否有任何方法可以对任何物体执行鼠标拾取检测。它是生成的对象还是导入的对象

[Idea]- 我的想法是,场景中的每个对象都会有迭代。检查鼠标光线是否与对象相交。为了检查交点,它将检查鼠标拾取的光线与构成对象的三角形

[Pros]- 我相信这种方法的好处是,每个对象都可以通过鼠标拾取来检测,因为它们都继承了检测方法

[Cons]- 我认为这种缺点主要是速度和方法非常昂贵。因此,需要对优化进行微调

[情况]- 在过去,我读过关于鼠标拾取的文章,我也实现了一些基本的鼠标拾取形式。但所有这些都是糟糕的工作,我并不感到自豪。今天,我再次在网上重读了一些内容。现在我看到很多鼠标使用颜色ID和着色器进行拾取。我不太喜欢这种方法。我更喜欢数学方面

这是我的老鼠在抓雷·辛加马吉格

maths::Vector3 Camera::Raycast(s32 mouse_x, s32 mouse_y)
{
    // Normalized Device Coordinates
    maths::Vector2 window_size = Application::GetApplication().GetWindowSize();

    float x = (2.0f * mouse_x) / window_size.x - 1.0f;
    float y = 1.0f;
    float z = 1.0f;

    maths::Vector3 normalized_device_coordinates_ray = maths::Vector3(x, y, z);

    // Homogeneous Clip Coordinates
    maths::Vector4 homogeneous_clip_coordinates_ray = maths::Vector4(normalized_device_coordinates_ray.x, normalized_device_coordinates_ray.y, -1.0f, 1.0f);

    // 4D Eye (Camera) Coordinates
    maths::Vector4 camera_ray = maths::Matrix4x4::Invert(projection_matrix_) * homogeneous_clip_coordinates_ray;
    camera_ray = maths::Vector4(camera_ray.x, camera_ray.y, -1.0f, 0.0f);

    // 4D World Coordinates
    maths::Vector3 world_coordinates_ray = maths::Matrix4x4::Invert(view_matrix_) * camera_ray;
    world_coordinates_ray = world_coordinates_ray.Normalize();

    return world_coordinates_ray;
}
我有一个射线平面相交函数,它计算某条射线是否与某个平面相交。哼

这是代码

bool Camera::RayPlaneIntersection(const maths::Vector3& ray_origin, const maths::Vector3& ray_direction, const maths::Vector3& plane_origin, const maths::Vector3& plane_normal, float& distance)
{
    float denominator = plane_normal.Dot(ray_direction);

    if (denominator >= 1e-6) // 1e-6 = 0.000001
    {
        maths::Vector3 vector_subtraction = plane_origin - ray_origin;
        distance = vector_subtraction.Dot(plane_normal);

        return (distance >= 0);
    }

    return false;
}
还有很多。例如,平面-球体相交、平面-圆盘相交。这些事情都很具体。因此,在全球范围内用鼠标拾取交叉点是非常困难的。我这样想是因为,对于这个光线平面相交函数。我希望用它来做的是,检索场景中的对象,并检索该对象的所有法线(这是一件让人头疼的事)。现在我要再次强调我的问题

是否已经有一种我不知道的方法,可以用一种方式对所有对象进行鼠标拾取?或者我只是愚蠢,当我拥有一切的时候不知道该做什么


多谢各位。谢谢。

是的,可以使用OpenGL进行鼠标拾取:将所有几何体渲染到一个特殊的缓冲区中,该缓冲区存储对象的唯一id而不是其着色颜色,然后只需查看鼠标下方像素的值,并通过写入其中的id了解对象。然而,尽管它可能更简单,但如果您的相机或几何体不断移动,它并不是一个特别有效的解决方案

相反,执行分析光线对象相交是一种方法。但是,不需要检查每个对象的每个三角形与光线的交点。这确实是低效的。您应该通过边界框来剔除整个对象,甚至是整个场景的一部分。游戏引擎有自己的空间索引数据结构来加速光线对象的相交。他们不仅需要鼠标拾取,还需要碰撞检测、物理模拟、人工智能等等


还请注意,用于拾取的几何体可能与用于渲染的几何体不同。我想到的一个例子是半透明对象。

是的,可以使用OpenGL进行鼠标拾取:将所有几何体渲染到一个特殊的缓冲区中,该缓冲区存储对象的唯一id,而不是其着色颜色,然后你只需看看鼠标下方像素的值,就可以通过写在那里的id知道对象。然而,尽管它可能更简单,但如果您的相机或几何体不断移动,它并不是一个特别有效的解决方案

相反,执行分析光线对象相交是一种方法。但是,不需要检查每个对象的每个三角形与光线的交点。这确实是低效的。您应该通过边界框来剔除整个对象,甚至是整个场景的一部分。游戏引擎有自己的空间索引数据结构来加速光线对象的相交。他们不仅需要鼠标拾取,还需要碰撞检测、物理模拟、人工智能等等


还请注意,用于拾取的几何体可能与用于渲染的几何体不同。我想到的一个例子是半透明对象。

您好,您能更详细地介绍一下“您应该通过边界框剔除整个对象”吗?不完全清楚你的意思和如何接近它。@JekasG:首先计算对象的边界框,然后跟踪光线时,首先进行光线框相交。如果光线没有击中长方体,显然它无法击中物体。所以你不需要检查物体每个三角形的光线。如果它击中了长方体,你需要做更精细的光线三角形相交测试,以确保它确实击中了对象。边界球体会更好吗?@JekasG:它们也可以工作,但它们更难计算(因此它们很紧)。最后,这取决于你的品味。嗨,你能更详细地谈谈“你应该按边界框剔除整个对象”吗?不完全清楚你的意思和如何接近它。@JekasG:首先计算对象的边界框,然后跟踪光线时,首先进行光线框相交。如果光线没有击中长方体,显然它无法击中物体。所以你不需要检查物体每个三角形的光线。如果它击中了长方体,你需要做更精细的光线三角形相交测试,以确保它确实击中了对象。边界球体会更好吗?@JekasG:它们也可以工作,但它们更难计算(因此它们很紧)。最终,这取决于你的品味。