0

我正在创建一个小型演示游戏,您可以在其中绕地球旋转并将卫星发射到太空。但是我在计算上遇到了一些麻烦。

您可以将鼠标从平台拖动到一个方向。这是你发射卫星的方向。因为相机围绕地球旋转,所以向上与向前不同。对于卫星的方向,我需要一个 Vector3(方向/速度)。

所以我拥有的数据是屏幕上平台的前方和鼠标拖动方向。

在此处输入图像描述 所以当用户将它拖到(-0.7, 0.7)时,这意味着饱和发射方向应该是(0, 0, 1)。全球/世界前进方向。

那么如何将那些 2d 屏幕位置和方向转换为世界方向呢?

4

1 回答 1

1

PlayCanvas 有一个我们可以利用的非常有用的功能。实现如下:

 * @description Convert a point from 2D canvas pixel space to 3D world space.
 * @param {Number} x x coordinate on PlayCanvas' canvas element.
 * @param {Number} y y coordinate on PlayCanvas' canvas element.
 * @param {Number} z The distance from the camera in world space to create the new point.
 * @param {Number} cw The width of PlayCanvas' canvas element.
 * @param {Number} ch The height of PlayCanvas' canvas element.
 * @param {pc.Vec3} [worldCoord] 3D vector to receive world coordinate result.
 * @returns {pc.Vec3} The world space coordinate.
 */
screenToWorld: function (x, y, z, cw, ch, worldCoord) {
  ...

A我们可以使用该函数将鼠标拖动线的起点和终点(B分别在图中)转换为世界空间中的 3D 线。转换后,我们必须从两个投影点中减去相机的世界位置,并对结果向量进行归一化。

[该z参数与此目的无关,因为我们只对方向向量感兴趣而不是实际点,因此只需将其设置为例如 1。]

那么这给了我们什么?由这两个向量跨越的平面

在此处输入图像描述

速度方向必须满足三个标准:

  • 垂直于发射场的表面法线(即与表面相切)。
  • 平行于我们刚刚找到的飞机。
  • 在从 A 到 B 的方向上有一个分量。

让:

  • 屏幕点AB投影到方向向量UV分别。
  • 发射场的表面法线(站在那里的人看到的“向上”方向)为N

    在此处输入图像描述

    哪里(ψ, φ) = (lat, long)

最后,(未归一化的)速度方向由 简单给出cross(N, cross(A, B))。请注意,操作顺序很重要。

可视化这一点:

在此处输入图像描述

编辑

  1. 第二张图中的小错误:U×V应该是V×U,但预期的结果N×(U×V)仍然是正确的。

  2. 注意UxV不一定垂直于N。当它与 平行N,蓝色平面“刮擦”表面,即根据AB屏幕上的渲染,在发射场,绿线与地球表面相切。

于 2018-03-03T02:50:30.997 回答