Panda3D has mouse support built in.
In Python, the default action of the mouse is to control the camera. If you want to disable this functionality you can use the command:
base.disableMouse()
This function's name is slightly misleading. It only disables the task that drives the camera around, it doesn't disable the mouse itself. You can still get the position of the mouse, as well as the mouse clicks.
To get the position:
if base.mouseWatcherNode.hasMouse():
x=base.mouseWatcherNode.getMouseX()
y=base.mouseWatcherNode.getMouseY()
The mouse clicks generate "events." To understand what events are, and how to process them, you will need to read the Event Handling section. The names of the events generated are:
mouse1 | Mouse Button 1 Pressed |
mouse2 | Mouse Button 2 Pressed |
mouse3 | Mouse Button 3 Pressed |
mouse1-up | Mouse Button 1 Released |
mouse2-up | Mouse Button 2 Released |
mouse3-up | Mouse Button 3 Released |
wheel_up | Mouse Wheel rolled upwards |
wheel_down | Mouse Wheel rolled downwards |
If you want to hide the mouse cursor, you want the line: "cursor hidden #t" in your Config.prc or this section of code:
from pandac.PandaModules import WindowProperties
props = WindowProperties()
props.setCursorHidden(True)
base.win.requestProperties(props)
Re-enabling mouse control
If you need to re-enable the mouse control of the camera, you have to adjust mouseInterfaceNode to the current camera transformation :
mat=Mat4(camera.getMat())
mat.invertInPlace()
base.mouseInterfaceNode.setMat(mat)
base.enableMouse()
Otherwise the camera would be placed back to the last position when the mouse control was enabled.
Multiple Mice
If you have multiple mice connected to a single machine, it is possible to get mouse movements and buttons for each individual mouse. This is called raw mouse input. It is really only useful if you are building an arcade machine that has lots of trackballs or spinners.
In order to use raw mouse input, you first need to enable it. To do so, add the following line to your panda configuration file:
read-raw-mice #t
This causes the panda main window to be created with the "raw_mice" window property. That window property, in turn, causes the window to track and store the positions and buttons of the raw mice. Then, that data is extracted from the main window by objects of class MouseWatcher. The application program can fetch the mouse data from the MouseWatchers. The global variable base.pointerWatcherNodes
contains the MouseWatcher
s.
The first MouseWatcher on the list always represents the system mouse pointer - a virtual mouse that moves around whenever any of the physical mice do. Usually, you do not want to use this virtual mouse. If you're accessing raw mice, you usually want to access the real, physical mice. The list base.pointerWatcherNodes
always contains the virtual system mouse first, followed by all the physical mice.
So to print out the positions of the mice, use this:
for mouse in base.pointerWatcherNodes:
print "NAME=", mouse.getName()
print "X=", mouse.getMouseX()
print "Y=", mouse.getMouseY()
Each mouse will have a name-string, which might be something along the lines of "Micrologic High-Precision Gaming Mouse 2.0 #20245/405". The name is the only way to tell the various mice apart. If you have two different mice of different brands, you can easily tell them apart by the names. If you have two mice of the same make and manufacture, then their names will be very similar, but still unique. This is not because the mice contain serial numbers, but rather because they are uniquefied based on the USB port into which they are plugged. That means that if you move a mouse from one USB port to another, it will have a new name. For all practical purposes, that means that you will need to store a config file that maps mouse name to intended purpose.
Raw mouse buttons generate events. The event names are similar to the ones for the system mouse, except that they have a "mousedevX" prefix. Ie, an example event might be mousedev3-mouse1-up
. In this example, the "mousedev3" specifier means that the mouse sending the event is base.pointerWatcherNode[3]
.
Multiple Mice under Linux
To use raw mouse input under Linux, the panda program needs to open the device files /dev/input/event*. On many Linux distributions, the permission bits are set such that this is not possible. This is a flaw in these distributions.
It is not a good idea to just change the permission bits. Doing so introduces a huge security hole in which any logged in user can monitor the mice, the joysticks, and the keyboard --- including any passwords that may be typed. The correct solution is to change the ownership of the input devices whenever a user sits down at the console. There is a module, pam_console, that does this, but it is now obsoleted, and has been removed from several distros. The Fedora pam_console removal page states that ACLs set by the HAL should replace pam_console's functionality. Currently, since it does not seem that HAL provides this yet, the best course of action is to make an 'input' group as described on the Gizmod wiki.
If you are building a stand-alone arcade machine that does not allow remote login and probably doesn't even have a net connection, then changing the permission bits isn't going to hurt you.