PlayCanvas has a very useful function we could make use of. The implementation is as follows:
* @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) {
...
We can use this function to convert the start and end points (A
and B
respectively in the diagram) of the mouse drag line to 3D lines in world space. After the conversion we must subtract the camera's world position from the two projected points, and normalize the resulting vectors.
[The z
parameter is irrelevant for this purpose because we are only interested in a direction vector and not an actual point, so just set it to e.g. 1. ]
So what does this give us? A plane spanned by these two vectors:

There are three criteria that the velocity direction must satisfy:
- Perpendicular to the surface normal (i.e. tangent to the surface) at the launch site.
- Parallel to the plane we just found.
- Have a component in the direction from A to B.
Let:
- Screen points
A
and B
project to directional vectors U
and V
respectively.
The surface normal at the launch site (the "up" direction as seen by a person standing there) be N
:

Where (ψ, φ) = (lat, long)
.
Finally, the (un-normalized) velocity direction is simply given by cross(N, cross(A, B))
. Note that the order of operations matters.
To visualize this:

EDIT:
Small mistake in the second diagram: U×V
should be V×U
, but the expected result N×(U×V)
is still correct.
Note that UxV
is not necessarily perpendicular to N
. When it is parallel to N
, the blue plane "scrapes" the surface, i.e. the green line AB
is tangent to the Earth's surface as per rendered on-screen, at the launch site.