Modifying absolute vs relative rotation

I’m trying to modify the mouse-modes demo so that the mouse rotates the box in a more intuitive manner.

Currently, moving the mouse rotates the box along it’s own heading and pitch, however I would like the mouse to rotate things along a global heading and pitch. Pretty much, moving the mouse up will always rotate the box upwards relative to the camera. Illustrative picture attached.

I mainly need help figuring out how to turn a delta in screen X and Y to the modified HPR values. The original code is :

self.rotateX += dx * 10 * self.mouseMagnitude
self.rotateY += dy * 10 * self.mouseMagnitude
self.model.setH(self.rotateX)
self.model.setP(self.rotateY)

Which I know I have to modify something to adjust for all three rotation angles. I’ve taken out a global rotation like this, but have no idea how to get the desired result:

hpr = self.model.getHpr()
self.model.setHpr(hpr[0] + dx*10*self.mouseMagnitude, hpr[1] + dy*10*self.mouseMagnitude, 0)

Any help with either translating to a correct dh,dp,dr, or using a panda API function would be great


To get the desired result, you can use quaternions.
The old model quaternion is multiplied by the quaternion representing the angle deltas, resulting in the new model quaternion:

...

        # rotate box by delta
        deltaHeading = dx * 10 * self.mouseMagnitude
        deltaPitch = -dy * 10 * self.mouseMagnitude
        deltaHpr = (deltaHeading, deltaPitch, 0.)

        # create quaternion representing delta values
        deltaQuat = Quat()
        deltaQuat.setHpr(deltaHpr)

        oldQuat = self.model.getQuat()
        newQuat = oldQuat * deltaQuat
        self.model.setQuat(newQuat)

        self.positionText.setText("Model rotation: {0}, {1}".format(
             int(self.model.getH()*1000)/1000., int(self.model.getP()*1000)/1000.))
        
        return Task.cont

app = App()
app.run()

Hope this helps.

That’s exactly what I was looking for, thanks!

I missed the -ve on dy the first time around, which is rather important for ensuring the X and Y coordinates behave in the same way.