As of version 1.10, Panda3D gained built-in support for various input devices including but not limited to joysticks, gamepads and steering wheels.
Note: For earlier versions of Panda, you can use pygame or pyglet to get gamepad support. There are various resources found in the forum that address this topic.
We’ll be starting with a little bit of theory to get you some knowledge of the underlaying system to be able to understand how gamepad support works. The support for devices is given through evdev, the joystick api or xinput dependent on the OS you are using. Hence all devices that are reccognized by your system will be available by the engine. Each connected device will be classified by one of the following device classes (DC)
# It is not known what type of device this is. unknown # This means that the device doesn't correspond to a physical # device, but rather to a dynamic source of input events. virtual_device # A physical, alphabetical keyboard. keyboard mouse touch # A gamepad with action buttons, a D-pad, and thumbsticks. gamepad flight_stick steering_wheel dance_pad # Head-mounted display. hmd # 3D mouse, such as produced by 3Dconnexion. spatial_mouse
These DC’s are stored within the
InputDevice.DeviceClass enum which can be
Note: Linux users may need to be in the “input” user group to get access to the full range of available device functionality.
The above mechanism works well for digital buttons, which can only be in an on or off state. Many game controllers also have analog controls, often referred to as “axes”, which can have a variable value. In Panda3D, these values will be 0.0 when the respective control is in its default or resting position, and 1.0 when it is in its maximum position. Some controls can move in two directions, and can have a value of down to -1.0.
This sample will show how to get the left analog stick of the first gamepad device
gamepad = base.devices.getDevices(InputDevice.DeviceClass.gamepad) left_x = gamepad.findAxis(InputDevice.Axis.left_x) # Access and use the value for whatever you need it left_x.value
findAxis command we
tell the device which axis we are interested in and finally get the axis value
value member. The
state member will give you a double precision representation of the controls
current position and should be called within a task method to get a constant
update of the controls position changes if desired. It sometimes is also
prudent to store the centered position of each control early in an application
to simplify the calculation of the distance the control has been moved in any
direction. Some applications and devices also do this automatically in a given
idle time or provide the user a dedicated re-calibrate action.
findAxis will return a
dummy object if the axis doesn’t exist. You can check for the boolean value of
the returned object (ie.
if left_x:) to see if the returned
axis has a known value.