My camera’s position is static, while my hero may walk around. I want the camera to be always looking at my hero, to rotate with lerp effect, so I did this:
def lerp_quaternion(q1, q2, factor):
if q1.getAngle() < 180 and q2.getAngle() > 180:
# in this situation, there is a sudden change of rotation.
# how to handle this?
return q1 + (q2 - q1) * factor
Got any ideas about how to deal with the sudden change of quaternion?
Here is a spherical lerp function I was using a while back to interpolate rotations in ODE (I have since switched to Bullet physics which does this internally). You can try dropping it into your code (import math, obviously).
If you just want the camera “locked on” to a moving object you don’t really need to interpolate, as wezu suggested just call “look_at” every frame. But for example if you want to select things to look at and have the camera smoothly pan to them rather than instantly snap, I also wrote a little function to dynamically create LerpIntervals for a “targetting” system.
lookinterval = None
def turnToward(target, slave):
lerptarget = slave.find("lerptarget")
lerptarget = slave.attachNewNode("lerptarget")
bt = "easeInOut"
if lookinterval is not None:
bt = "easeOut"
lookinterval = slave.quatInterval(0.5, lerptarget.getHpr(slave.getParent()), blendType=bt)
Here “slave” can be the camera or any other node. It attaches a reference node “lerptarget” to slave, uses lookAt to point that node at target, then smoothly interpolates slave’s rotation to match lerptarget. This may leak memory…I’m not sure if paused unreferenced intervals are held by the engine forever. It was just an experiment but might give you a little idea of how to write your own version.