【问题标题】:Simple OpenTK Raycasting简单的 OpenTK 光线投射
【发布时间】:2018-06-30 16:16:27
【问题描述】:

好吧,我不知道你是否可以完全考虑它是光线投射,但我基本上是想找到我的 2d 网格上的哪个图块被悬停在上面,这样我就可以在那里放置一个对象。

解决方案应该只选择网格而不是网格上的建筑物。建筑物突出显示将基于建筑物占用的任何瓷砖是否被悬停。

我想要实现的一个很好的例子是像异星工厂一样的建筑系统。

编辑: 网格是一个包含所有图块信息的二维数组。世界中的瓦片都是 2 个三角形(由顶点数组和索引数组组成)。相机是透视相机(如果 Factorio 使用 Orthographic,如果它使事情变得更简单,我可以切换到它)。

编辑 2: 该数组包含一个名为 TileInformation 的类,它有一些与 tile 包含的内容等相关的内容。瓦片大小为 1x1,阵列为 256x256。 (会有多个可以单独更新的网格块。)所有瓦片都在一个网格中,位置表示为 int 的(坐标系是正的和负的。)

【问题讨论】:

  • 这个问题有点含糊。请添加必要的详细信息,例如,您的网格是如何表示的以及您有什么相机型号?
  • @NicoSchertler 我改进了这个问题,我希望我的编辑有助于描述设置。 (OpenTK 和一般图形编程的新手)
  • 还是不够清楚。二维数组包含什么信息?瓷砖的尺寸是多少?它们位于哪里?
  • @NicoSchertler 这能回答你所有的问题吗?

标签: c# opengl grid opentk raycasting


【解决方案1】:

你的问题还不够清楚,但我会做一些假设,希望它们符合你的情况。

首先,我们需要一个代表 3D 空间中 2D 鼠标位置的拾取射线。为此,我们首先将鼠标位置从像素坐标转换为介于 -1 和 1 之间的标准化设备坐标:

mouseNDCX = 2 * mousePixelX / viewportWidth - 1
mouseNDCY = 1 - 2 * mousePixelY / viewportHeight

然后,我们找到了射线。为此,我们需要您的相机的视图投影矩阵。那么:

mouseNear = inverse(viewProjection) * (mouseNDCX, mouseNDCY, 0, 1)
mouseFar  = inverse(viewProjection) * (mouseNDCX, mouseNDCY, 1, 1)

这将为您提供拾取射线上的两个位置。一个在 z-near 平面上,一个在 z-far 平面上。不要忘记做透视划分:

mouseNear = (1 / mouseNear.w) * mouseNear
mouseFar = (1 / mouseFar.w) * mouseFar

下一步是计算与网格的交点。这是您的问题严重低估的地方。我假设网格位于与其中一个主平面平行的平面上。在下文中,这将是 xy 平面。如果您有不同的平面,则需要更换相应的组件。我将进一步假设网格位于高度z

现在,我们要找到交点,即:

          ((1 - t) * mouseNear + t * mouseFar).z = z
<=> mouseNear.z + t * (mouseFar.z - mouseNear.z) = z
<=>                                            t = (z - mouseNear.z) / (mouseFar.z - mouseNear.z)

这让我们可以计算交点:

intersection = (1 - t) * mouseNear + t * mouseFar

此交点位于网格平面上。最后,我们需要找到图块索引。为此,我们只需要考虑 x 和 y 分量。假设您的网格原点位于 o 并且图块的大小为 s,那么图块索引为:

i = floor((intersection.x - o.x) / s)
j = floor((intersection.y - o.y) / s)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    • 2016-08-09
    相关资源
    最近更新 更多