diff --git a/samples/gamepad/steeringWheel.py b/samples/gamepad/steeringWheel.py new file mode 100644 index 0000000000..6353f24188 --- /dev/null +++ b/samples/gamepad/steeringWheel.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python +''' +Demonstrate usage of steering wheels + +In this sample you can use a wheel type device to control the camera and +show some messages on screen. You can acclerate forward using the +accleration pedal and slow down using the break pedal. +''' + +from direct.showbase.ShowBase import ShowBase +from panda3d.core import TextNode, InputDevice, loadPrcFileData, Vec3 +from direct.gui.OnscreenText import OnscreenText + +loadPrcFileData("", "notify-level-device debug") + +class App(ShowBase): + def __init__(self): + ShowBase.__init__(self) + # print all events sent through the messenger + self.messenger.toggleVerbose() + + self.lblWarning = OnscreenText( + text = "No devices found", + fg=(1,0,0,1), + scale = .25) + self.lblWarning.hide() + + self.lblAction = OnscreenText( + text = "Action", + fg=(1,1,1,1), + scale = .15) + self.lblAction.hide() + + self.checkDevices() + + self.currentMoveSpeed = 0.0 + self.maxAccleration = 28.0 + self.deaccleration = 10.0 + self.deaclerationBreak = 37.0 + self.maxSpeed = 80.0 + + # Accept device dis-/connection events + # NOTE: catching the events here will overwrite the accept in showbase, hence + # we need to forward the event in the functions we set here! + self.accept("connect-device", self.connect) + self.accept("disconnect-device", self.disconnect) + + self.accept("escape", exit) + self.accept("flight_stick0-start", exit) + + # Accept button events of the first connected steering wheel + self.accept("steering_wheel0-action_a", self.doAction, extraArgs=[True, "Action"]) + self.accept("steering_wheel0-action_a-up", self.doAction, extraArgs=[False, "Release"]) + + self.environment = loader.loadModel("environment") + self.environment.reparentTo(render) + + self.wheelCenter = 0 + wheels = base.devices.getDevices(InputDevice.DC_steering_wheel) + if len(wheels) > 0: + for i in range(wheels[0].getNumControls()): + if wheels[0].getControlMap(i) == InputDevice.C_wheel: + self.wheelCenter = wheels[0].getControlState(i) + + # disable pandas default mouse-camera controls so we can handle the camera + # movements by ourself + self.disableMouse() + base.camera.setZ(2) + + self.taskMgr.add(self.moveTask, "movement update task") + + def connect(self, device): + # we need to forward the event to the connectDevice function of showbase + self.connectDevice(device) + # Now we can check for ourself + self.checkDevices() + + def disconnect(self, device): + # we need to forward the event to the disconnectDevice function of showbase + self.disconnectDevice(device) + # Now we can check for ourself + self.checkDevices() + + def checkDevices(self): + # check if we have wheel devices connected + if self.devices.get_devices(InputDevice.DC_steering_wheel): + # we have at least one steering wheel device + self.lblWarning.hide() + else: + # no devices connected + self.lblWarning.show() + + def doAction(self, showText, text): + if showText and self.lblAction.isHidden(): + self.lblAction.show() + else: + self.lblAction.hide() + + def moveTask(self, task): + dt = globalClock.getDt() + movementVec = Vec3() + + wheels = base.devices.getDevices(InputDevice.DC_steering_wheel) + if len(wheels) == 0: + # savety check + return task.cont + + if self.currentMoveSpeed > 0: + self.currentMoveSpeed -= dt * self.deaccleration + if self.currentMoveSpeed < 0: + self.currentMoveSpeed = 0 + + # we will use the first found wheel + for i in range(wheels[0].getNumControls()): + + if wheels[0].getControlMap(i) == InputDevice.C_accelerator: + accleration = wheels[0].getControlState(i) * self.maxAccleration + self.currentMoveSpeed += dt * accleration + + if self.currentMoveSpeed > wheels[0].getControlState(i) * self.maxSpeed: + self.currentMoveSpeed -= dt * self.deaccleration + elif wheels[0].getControlMap(i) == InputDevice.C_brake: + deacleration = wheels[0].getControlState(i) * self.deaclerationBreak + self.currentMoveSpeed -= dt * deacleration + + elif self.currentMoveSpeed < 0: + self.currentMoveSpeed = 0 + + if wheels[0].getControlMap(i) == InputDevice.C_wheel: + rotation = self.wheelCenter - wheels[0].getControlState(i) + base.camera.setH(base.camera, 100 * dt * rotation) + + # calculate movement + base.camera.setY(base.camera, dt * self.currentMoveSpeed) + + return task.cont + +app = App() +app.run()