[Solved] Problems orienting camera with extreme P values

Hey everyone,

I’m writing a program where the user flies a camera and as such can point it any direction. My cameras are parented to render as otherwise my RoamingRalph forward-movement matrix hack refuses to work. To do my “rotations” (i.e. angling the camera upwards, downwards, leftwards and rightward) I’m setting the H and P of the camera. While the camera is orientated “normally” (i.e. with HPR of (0,0,0) ) this works as I expected: changing P rotates the camera to face upwards or downwards and changing H rotates the camera leftwards or rightwards.

However, if I change P this behavior changes. If I set P to 90 my upward and downward rotations remain functional but changes in H creates only a rotation in a circle, not towards the camera’s left and right as desired.

How do I fix this? I’ve discovered that if I set the camera’s R to 90 then change it’s P value I can do rotations to the left and right but for some reason I don’t seem to be able to implement this with tasks and this seems like quite a hack to do something so simple.

Here is the relevant bits of code, I’d appreciate any nudge in the right direction! It’s structured very much like the RoamingRalph demo as I thought that was quite a clean way to organise the code.


# Snippet from init
def __init__(self):
		self.camera = self.makeCamera(self.win)
		self.camera.reparentTo(render)

def move(self, task):
		"""
		A task that is continously called that moves the active camera in the 
		directions given by the states set with set_key.
		"""
		cam = self.camera
		# Left and Right rotation
		if self.key_map["left"] != 0: 
			cam.setH(cam.getH() +100 * globalClock.getDt())
		if self.key_map["right"] != 0:
			cam.setH(cam.getH() -100 * globalClock.getDt())
		
		# Upward and Downward rotation
		if self.key_map["up"] != 0:
			cam.setP(cam.getP() +100 * globalClock.getDt())
		if self.key_map["down"] != 0:
			cam.setP(cam.getP() -100 * globalClock.getDt())
			

Edit: fixing my embarrassing it’s/its mistake

You might be the victim of gimbal lock, which basically means the hpr math doesn’t work at extreme positions. Try using quaternions.

Another approach is to use relative transforms. Instead of using simple addition, use a rotation relative to yourself. Replace:

cam.setH(cam.getH() +100 * globalClock.getDt())

with:

cam.setH(cam, 100 * globalClock.getDt())

David

This worked perfectly, thanks again David!