This question is about Unity3D. I want to create a navigation similar to Google Earth where you click and drag on a sphere and let the camera orbit accordingly. It is important that the point that was grabbed is always under the mouse position while dragging. The navigation should also work if I zoom close to the sphere. I do not want to rotate the sphere itself. Just exactly like Google Earth does it.
My attempt is to project the mouse position to the sphere if I start to drag. On the next frame I do the same and calculate the angle between the start drag and end drag position.
private void RotateCamera(Vector3 dragStart, Vector3 dragEnd)
{
// calc the rotation of the drag
float angle = Vector3.Angle(dragStart, dragEnd);
// rotate the camera around the sphere
Camera.main.transform.RotateAround(sphere), Vector3.up, angle);
}
I thought of using Unitys RotateAround method to rotate the camera with the calculated angle. Unfortunately I do not have the rotation vector (using Vector3.up in the example is obviously wrong). Does somebody know how I can calculate this vector to apply it for the method? Am I on the right direction to implement the Google Earth navigation?
Thank You!
UPDATE I am very close with a new solution. I project the drag vectors to a down and a right plane to get the angles. Afterwards I rotate the camera around up and left. This works well until I reach the poles of the sphere. The camera rotates a lot around itself if I reach a pole.
private void RotateCamera(Vector3 dragStart, Vector3 dragEnd)
{
Vector3 plane = Vector3.down;
var a = Vector3.ProjectOnPlane(dragStart, plane);
var b = Vector3.ProjectOnPlane(dragEnd, plane);
float up = Vector3.SignedAngle(a, b, plane);
plane = Vector3.right;
a = Vector3.ProjectOnPlane(dragStart, plane);
b = Vector3.ProjectOnPlane(dragEnd, plane);
float left = Vector3.SignedAngle(a, b, plane);
Camera.main.transform.RotateAround(_sphere, Vector3.up, up);
Camera.main.transform.RotateAround(_sphere, Vector3.left, left);
}
