I do not know how to do this using Panda3D APIs. But it can be done by raw calculations as follows:
def getHprFromTo( fromPt, toPt ):
"""
HPR to rotate *from* point to look at *to* point
"""
# Translate points so that fromPt is origin
pos2 = toPt - fromPt
# Find which XY-plane quadrant toPt lies in
# +Y
# ^
# 2 | 1
# ---o---> +X
# 3 | 4
quad = 0
if pos2.x < 0:
if pos2.y < 0:
quad = 3
else:
quad = 2
else:
if pos2.y < 0:
quad = 4
# Get heading angle
ax = abs( pos2.x )
ay = abs( pos2.y )
head = math.degrees( math.atan2( ay, ax ) )
# Adjust heading angle based on quadrant
if 2 == quad:
head = 180 - head
elif 3 == quad:
head = 180 + head
elif 4 == quad:
head = 360 - head
# Compute roll angle
v = Vec3( pos2.x, pos2.y, 0 )
vd = abs( v.length() )
az = abs( pos2.z )
roll = math.degrees( math.atan2( az, vd ) )
# Adjust if toPt lies below XY-plane
if pos2.z < 0:
roll = - roll
# Make HPR
return Vec3( head, 0, -roll )
The basic idea is imagine your head stationary at fromPoint in space. Your head (or eyes) is facing along +ve X axis, +ve Y axis comes out of your left ear and your up vector is +ve Z axis. Somewhere in the space around you is the toPoint.
To look at it, you first rotate your head (like in horror movies) in the global XY plane until toPoint is above or below you. This is the heading angle.
Now you lift your head up or down to finally to get the toPoint in your sight. This is the roll angle. Note that this is roll and not pitch, though it seems like that. This is because it is roll in the coordinate system of your head. And this gives you the HPR!