1

我正在为 OpenGL ES 2.0 编写 3D 应用程序,其中用户设置路径并飞过某些地形。它基本上是一个轨道上的飞行模拟器。

路径由从样条线创建的一系列点定义。每个时间片我使用插值推进当前位置,即我在 p0 到 p1 之间插值,然后当我到达 p1 时,我在 p1 和 p2 之间插值,最后从 pN 回到 p0。

我创建了一个类似于 gluLookAt 的视图矩阵。eye coord 是当前位置,look at 是路径上的下一个位置和一个 up (0, 0, 1)。所以相机看向它接下来要飞到的地方,Z指向天空。

但现在我想在转弯时“银行”。即向上矢量不一定是直接向上的,而是基于转弯率的变化。我知道我当前的方向和我最后的方向,所以我可以增加或减少银行的数量。点积会告诉我转弯的角度,叉积会告诉我它是向左还是向右。我可以保持倾斜角度并将其保持在 -/+70 度的范围内,适当地增加或减少。

我认为这是正确的方法,但我可能会花很长时间实施它来发现它不是。

我是否走在正确的轨道上,是否有样本可以证明我正在尝试做的事情?

4

3 回答 3

2

由于您似乎有一架在正常条件下飞行的平稳的飞机,因此您不需要太多……您的方法几乎是正确的,并且看起来很自然。您所需要的只是 3 个连续点 A、B、C: 之间的叉积cross = cross(A-B, C-B)。现在 cross 是您需要围绕“前向”矢量转动平面的矢量:自然,平面的向上矢量是(-gravitation)通常是(0,0,1),而 B 点的前向矢量是 CB(如果不需要插值) ) 现在“侧”向量在side = normalized(cross(forward, up))这里是您使用银行的地方:side = side + cross*planeCorrectionParameter然后up = cross(normalized(side), normalized(forward)). “planeCorrectionParameter”是您应该使用的参数,实际上它代表了一些参数的组合,例如机翼和船体的尺寸、空气密度、重力、速度、质量......

请注意,上面的某些交叉操作可能需要按参数顺序进行交换(cross(a,b) 应该是 cross(b,a)),所以请尝试一下。

于 2012-11-23T08:52:34.103 回答
0

您的方法听起来正确,但看起来不自然。以一条看起来像 sin 函数的路径为例:当飞机实际上向右移动时,它可能向左“移动”。

我可以提到您的问题的两种解决方案。首先,您可以取样条的导数。我假设您的样条曲线是一个f(t)返回点的函数(x, y, z)。参数曲线的导数是指向旋转中心的向量:它将指向圆形路径的中心。

使用上述方法需要注意几点:直线的导数是0,向量也将是0,因此您必须手动修复上向量。此外,您可能希望修复此向量,使其不会颠倒。

这很有效,而且看起来比你的方法更好。但对于某些曲线,它仍然看起来不自然。我能提到的最好的方法是四元数插值,例如Slerp。在曲线的每个点,您还有一个“右”向量:指向平面右侧的向量。从曲线和这个向量,你可以计算出此时的向上向量。然后,您使用四元数插值沿曲线插入向上向量。

于 2012-11-22T14:50:38.470 回答
0

如果位置和旋转仅取决于样条曲线曲率,最简单的方法将是3D 样条曲线的数值微分(您将有 2 个导数,一个用于垂直分量,一个用于水平分量)。您的 UP 和 side 将是切线的法线。

于 2012-11-22T15:06:21.917 回答