XY limits on mouse control

Hi, I am trying to add xy-limits on the default mouse control so that my models won’t go out of the display region, i.e. drive the camera around xy axis within a preset x and y ranges. Is there a way to add limits to default control or do I have to build a custom camera control and add calculations using xy coordinates of mouse?

Also, i found that core base still tracks and store mouse position after base.disabledmouse(), so the cam pos does not stay still but move far away after base.enabledmouse() is called again. Is there a way to override or stop this behavior?

Thanks!

base.enabledmouse() # move camera around
base.disabledmouse() 
# and then continue dragging the mouse around
# camera stays fixed
base.enabledmouse()
# camera suddenly jumps to far away

The problem is that this function doesn’t have an exact name. This is actually a camera node, or rather an update function. This has nothing to do with the mouse. You need to do an additional check in the body of your function to update X Y or not.

Note that there are two different built-in camera controllers available: a “trackball” controller (the default) and a “drive” controller.
What seems to work is to take the (inverse) transformation of base.camera and apply its position and orientation to base.mouseInterfaceNode (which is apparently used by the built-in camera control system) just before re-enabling the built-in controller. For some reason that transformation needs to be inverted when in trackball mode, but not when in drive mode.

Here is some code that should hopefully do what you want:

from direct.showbase.ShowBase import ShowBase
from panda3d.core import *


class MyApp(ShowBase):

    def __init__(self):

        ShowBase.__init__(self)

        self.accept("escape", base.userExit)

        environment = loader.loadModel("../samples/Roaming-Ralph/models/world")
        environment.reparentTo(render)

        # uncomment the following line to go into drive mode
        # self.use_drive()

        self.accept("d", self.disable_mouse)
        self.accept("e", self.__enable_autocam)

    def __enable_autocam(self):

        # don't invert the camera transformation when in drive mode
        xform = self.camera.get_transform().get_inverse()
        pos = xform.get_pos()
        hpr = xform.get_hpr()
        self.mouseInterfaceNode.set_pos(pos)
        self.mouseInterfaceNode.set_hpr(hpr)
        self.enable_mouse()


app = MyApp()
app.run()

Press D to disable built-in camera control, E to re-enable it.

yes this works! thanks!

xform = self.camera.get_transform().get_inverse()
pos = xform.get_pos()
self.mouseInterfaceNode.set_pos(pos)

I wonder why torment the base camera, when you can write your implementation with the desired behavior.