Cabri Java Applet
It's from a german site but the important things about it don't require any spoken language.
As you already have the formula for the facing, this 3D problem becomes an easier 2D problem.
(that y should actually be a z meh..)
Now that it's 2 dimensional we can rotate our imaginary camera until we get this 'standard' 2d cartesian view. (jesus my math-english sucks even more than my nonmath-english)
there are several ways on how to get the specific angle we're looking for but a general attempt is to first get the length of all the sides. We know the coordinates of the point P (the player): P(xp,yp,zp), and we know the coordinates of our target T: T(xt,yt,zt).
Imagine you're standing behind a window in a tall building. You are P, and T might be a car parking outside. Then the base B would be the entrence of the building you're in (right beneath you).
As we don't care about the facing anymore, you, the car and the entrence form a triangle.
This leads to the coordinates of the base B: B(xp,yp,zt). It has the same x/y coordinates as you and shares the z coordinate with your target.
|BT| is the length of the 'line/side' from the point B to the point T.
|BT| = |(xt,yt,zt) - (xp,yp,zt)| = Sqrt([xt-xp]^2 + [yt-yp]^2 + [0]^2)
|BP| = |(xp,yp,zp) - (xp,yp,zt)| = Sqrt([0]^2 + [0]^2 + [zp-zt]^2)
90° -> pyth: |r| = |PT| = Sqrt(|BT|^2+|BP|^2) = Sqrt([xt-xp]^2 + [yt-yp]^2 +[zp-zt]^2)
Now the angle alpha = |_BPT:
cos(alpha) = |BP| / |PT| = Sqrt((zp-zt)^2) / Sqrt([xt-xp]^2 + [yt-yp]^2 +[zp-zt]^2)
sqrt(x^2) = x
-> alpha = arccos((zt-zp) / sqrt((xt-xp)^2 + (yt-yp)^2 + (zt-zp)^2)
and thats
taken from wikipedia (
Spherical coordinate system - Wikipedia, the free encyclopedia )
or much easier if you know the formula for a sphere:
(x-xm)^2 + (y-ym)^2 + (z-zm)^2 = r^2, solving for r gives again that ugly squareroot.
Finally, WoWs a bit 'special' -> pitch = pi/2 - pitch so that looking down results in -pi/2 and thats very close to your findings of the max. pitch values.
This post might very well contain lots of mistakes, I'm tired and have had a very long pause
. The applet I linked is really helpful though.