我正在为OpenGL ES 2.0编写3D应用程序,用户可在其中设置路径并飞越某些地形。它基本上是轨道上的飞行模拟器。
路径由样条曲线创建的一系列点定义。每次使用插值推进当前位置,即I在p0到p1之间插值,然后当我到达p1时,我在p1和p2之间插值,最后从pN返回到p0。
我创建了一个类似于gluLookAt的视图矩阵。眼睛坐标是当前位置,外观是沿着路径的下一个位置和向上(0,0,1)。因此,相机看向它飞向下一个的位置,Z指向天空。
但是现在我想转向“银行”。即,向上矢量不一定是直接向上,而是基于转弯率的变化。我知道我目前的方向和最后的方向,所以我可以增加或减少一定数量的银行。点积将告诉我转弯的角度,并且十字产品会告诉我它是向左还是向右。我可以保持倾斜角度并将其保持在-+ 70度范围内,适当增量或减量。
我认为这是正确的方法,但我可能花了很长时间来实现它,以发现它不是。
我是否在正确的轨道上,是否有样品证明我正在尝试做什么?
答案 0 :(得分:2)
因为你似乎在正常条件下有一架漂亮的平稳飞机,你不需要太多......你的方法几乎是正确的,看起来很自然。您所需要的只是3个连续点A,B,C:cross = cross(A-B, C-B)
之间的交叉积。现在十字架是你需要转动飞机前进"前进" vector:当然,平面向上的向量是( - 引力)通常是(0,0,1),B点的前向向量是C-B(如果不需要插值)现在" side"向量是side = normalized(cross(forward, up))
这里是您使用银行业务的地方:side = side + cross*planeCorrectionParameter
然后是up = cross(normalized(side), normalized(forward))
。 " planeCorrectionParameter"是你应该玩的参数,实际上它代表了一些参数的组合,如机翼和船体的尺寸,空气密度,重力,速度,质量...
请注意,上面的一些交叉操作可能需要按参数顺序进行交换(cross(a,b)应该是cross(b,a)),所以请稍微调整一下。
答案 1 :(得分:0)
您的方法听起来不错,但看起来不自然。例如,一条看似sin函数的路径:当它实际向右移动时,飞机可能会“向左”移动。
我可以提出两个问题的解决方案。首先,您可以采用样条的导数。我假设你的样条曲线是f(t)
函数,它返回一个点(x, y, z)
。参数曲线的导数是指向旋转中心的矢量:它将指向圆形路径的中心。
上述方法需要注意的几点:直线的导数为0
,向量也为0
,因此您必须手动修复向上矢量。此外,您可能希望修复此向量,使其不会颠倒过来。
这样做并且看起来比你的方法更好。但对某些曲线来说,它仍然看起来不自然。我能提到的最好的方法是四元数插值,例如Slerp。 在曲线的每个点,您还有一个“右”向量:指向平面右侧的向量。从曲线和此向量,您可以计算此时的向上矢量。然后,使用四元数插值沿曲线插入向上矢量。
答案 2 :(得分:0)
如果位置和旋转仅取决于样条曲率,最简单的方法是3D样条曲线的Numerical differentiation(对于垂直组件,您将有2个导数,对于水平组件,您将有一个导数)。你的UP和side将是切线的法线。