我正在创建一个小型演示游戏,您可以围绕地球旋转并将卫星发射到太空。但是我在计算上遇到了一些麻烦。
您可以将鼠标从平台拖动到某个方向。这是你射击卫星的方向。由于相机围绕行星旋转,因此向上与向前相同。对于卫星的方向,我需要一个Vector3(方向/速度)。
因此,我所拥有的数据是屏幕上的平台前方和mosue拖动方向。
因此,当用户将其拖动到(-0.7,0.7)时,这意味着satilatie发射方向应为(0,0,1)。全球/世界前进方向。
那么如何将这些2D屏幕位置和方向转换为世界方向呢?
答案 0 :(得分:1)
PlayCanvas有一个非常有用的功能我们可以使用。 implementation如下:
* @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.]
那么这给了我们什么?由这两个向量跨越的平面:
速度方向必须满足三个标准:
让:
最后,(非标准化)速度方向仅由
cross(N, cross(A, B))
给出。请注意,操作顺序很重要。
想象一下:
修改强>:
第二张图中的小错误:U×V
应为V×U
,但预期结果N×(U×V)
仍然正确。
请注意,UxV
不一定与N
垂直。当平行到N
时,蓝色平面"刮擦"表面,即绿线AB
与发射现场在屏幕上渲染的地球表面相切。