Made a simple demo of usage DualShock4 gamepad’s motion sensors. It uses the real DualShock4 gamepad’s rotation (from internal gyro) to rotate the 3D model.
The model downloaded from Dualshock 4 - Download Free 3D model by Saba.Lanchava [66a48c6] - Sketchfab
import sys
from direct.showbase.ShowBase import ShowBase
from panda3d.core import load_prc_file_data, InputDeviceManager, PandaNode
import simplepbr
class DS4Demo(ShowBase):
def __init__(self):
load_prc_file_data('', '''
win-size 1280 720
''')
super().__init__()
self.disable_mouse()
self.pipeline = simplepbr.init()
idm = InputDeviceManager.get_global_ptr()
self._devices = set()
for device in idm.get_devices():
self._connect_device(device)
self.accept('connect-device', self._connect_device)
self.accept('disconnect-device', self._disconnect_device)
self.accept('escape', sys.exit)
self._container = self.render.attach_new_node(PandaNode('Container'))
self._model = self.loader.load_model('scene.gltf')
self._model.reparent_to(self._container)
# self._model.set_p(90)
self._x = [0] * 10
self._y = [0] * 10
self.cam.set_y(-100)
self.task_mgr.add(self._update, '_update')
def _connect_device(self, device):
if device not in self._devices:
self.attach_input_device(device)
self._devices.add(device)
print('{manufacturer} {name} [{class}] [{vid:04x}:{pid:04x}]'.format(**{
'name': device.name,
'class': device.device_class.name,
'manufacturer': device.manufacturer,
'vid': device.vendor_id,
'pid': device.product_id,
}))
def _disconnect_device(self, device):
if device in self._devices:
self._devices.remove(device)
def _update(self, task):
x = 0
y = 0
for device in self._devices:
if device.name == 'Wireless Controller Motion Sensors':
for axis in device.axes:
# X axis: 0.25 (rotated left/CCW) to -0.25 (rotated right/CW)
if axis.axis.name == 'x':
x = axis.value * -4 # convert to range: -1 to 1
# elif axis.axis.name == 'y': # Y axis: 0.25 (flat on table) to -0.25 (upside down)
elif axis.axis.name == 'throttle': # Y axis: 0.25 (lightbar up) to -0.25 (lightbar down)
y = axis.value * -4 # convert to range: -1 to 1
# fixes wobble, but adds a delay
self._x.append(x)
self._x = self._x[1:]
self._y.append(y)
self._y = self._y[1:]
x_ave = sum(self._x) / len(self._x)
y_ave = sum(self._y) / len(self._y)
# print(x_ave, y_ave)
self._container.set_r(x_ave * 90)
self._container.set_p(y_ave * 90)
return task.again
if __name__ == '__main__':
demo = DS4Demo()
demo.run()