1

我正在开发第一人称 3D 游戏。关卡完全基于立方体,墙壁/地板/等都只是平铺的立方体(1x1x1)。

我目前正在使用相机位置和相机的旋转来获取方向来创建射线。然后我想将光线投射到第一个不为空的立方体上(或者当光线从网格上掉下来时)。很多时候,这些是方向向量,例如 0,0,1 或 1,0,0。

我在找到适用于方向矢量而不是起点/终点的 Bresenham 线条绘制算法时运气不佳。特别是考虑到方向向量不仅仅包含整数。

所以,对于一个特定的问题,我想我想问是否有人可以解释我是否接近以正确的方式解决这个问题,以及是否有人可能会详细说明无论如何应该如何完成。

4

1 回答 1

1

Bresenham 在这里不会帮助你,我担心......你需要的是 Ray/Line-Plane 相交算法:

在非常粗糙的数学伪代码中:

(警告:我已经很久没有做 3d 图形了)

// Ray == origin point + some distance in a direction
myRay = Porg + t*Dir;

// Plane == Some point on cube face * normal of cube face (facing out),
// at some distance from origin
myPlane = Pcube * Ncubeface - d;

// Straight shot: from ray origin to point on cube direction
straightTo = (Pcube - Porg);

通过这两个等式,您可以推断出一些事情:

  • 如果 'straightTo' 和平面法线的点积为零(称为“angA”),则您的原点在立方体的面内。

  • 如果光线方向和平面法线的点积接近于 0(称为“angB”),则光线平行于立方体的面——也就是说,不相交(除非你计算原点是否在立方体面,上面)。

  • 如果 (-angA / angB) < 0,则您的光线指向远离立方体面。

还有其他的东西,但我已经在逼迫我微薄的记忆力了。:)

编辑:可能有一个“捷径”,现在我认为它有点......这一切都假设你正在为你的“地图”使用类似 3-d 数组的结构。

好的,请耐心等待,在我的手机上思考和打字——如果您使用标准的旧 Bresenham delta-error 算法,但将其“固定”为 2D 会怎样?

所以让我们说:

  • 我们在 (10x10x10) “盒子”中的位置 (5, 5, 5)
  • 我们指向 (1 0 0)(即 +X 轴)
  • 从我们视锥体左上角投射的光线仍然只是一条线;“x”和“y”的定义改变了,就是
  • 在这种情况下,“X”将是(心理可视化)......比如说沿着平行于眼线的轴,但与投射线齐平;也就是说,如果我们正在查看 (640x480) 的 2D 图像,“中心”是 (0,0),左上角是 (-320,-240),那么这条“X 轴线”将是一条线通过点 (-320,0) 投射到无穷远。
  • “Y”同样是正常“Y”轴的投影,所以......几乎相同,除非我们歪着头。
  • 现在,当试图弄清楚下一个 deltaX 值是多少时,数学会变得非常棘手,但是一旦你弄清楚了公式,它基本上就是常数时间计算(现在我想起来了, “X 轴”只是通过您的相机投影投影的矢量 <1 0 0>,对吗?

对不起,我在回家的火车上。;)

于 2012-11-28T21:54:49.390 回答