I have a unit sphere that Is centered at the origin and my camera is also centered at the origin. The camera is facing z=-1.
I change my view point by rotating the camera first about the x axis and then about the z axis. This is done in opengl es 1.1 using
glrotate(phi,1,0,0);
glrotate(theta,0,0,1)
This esentially gives me a camera viewpoint where z=(0,0,1) is always the up vector.
Using gluLookAt would give me the same result if I was specifying what point to look at.
I have also previously defined a projection matrix.
Now for the real question:
I click on the screen and the first point i click on is converted back through the projection matrix and modelview matrix and stored. i.e.
pl=pixel location on screen, P=projection matrix, M=modelview matrix, ps=point on sphere in 3d
P*M*ps=pl
so ps=inv(M)*inv(P)*pl
Doing this step is trivial. The next part isnt.
Now I want to click anywhere else on the screen so therefore i get a plnew and I want to find out what matrix Mnew will cause a rotation such that the point ps will now appear at plnew on the screen i.e
P*Mnew*ps=plnew
This is obviously underconstrained and so I need to find the correct constraints. The constraints are based on the fact that I can only rotate using phi and theta as described in the intro to the question. So how do I solve for Mnew? or in other words phiNew and thetaNew.
By the way, the end “effect” im going for is that if a user clicks somewhere on the sphere and then drags the sphere then the point the user clicked on stays under the mouse during dragging AND the sphere stays upright.
I managed to solve it quite easily after I posted the question despite having wasted an entire day banging my head yesterday.
let psnew=inv(M)*inv(P)*pl
I.e. psnew is just the location of the point plnew on the sphere.
v=psnew-ps
so (theta,phi)=convertToPolarCoordinates(v)
where the conversion is standard and can be found in wikipedia or anywhere else