| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- #!/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("", """
- default-fov 60
- 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.lblAction = OnscreenText(
- text = "Action",
- fg=(1,1,1,1),
- scale = .15)
- self.lblAction.hide()
- # Is there a steering wheel connected?
- self.wheel = None
- devices = self.devices.getDevices(InputDevice.DeviceClass.steering_wheel)
- if devices:
- self.connect(devices[0])
- 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
- self.accept("connect-device", self.connect)
- self.accept("disconnect-device", self.disconnect)
- self.accept("escape", exit)
- # Accept button events of the first connected steering wheel
- self.accept("steering_wheel0-face_a", self.action, extraArgs=["Action"])
- self.accept("steering_wheel0-face_a-up", self.actionUp)
- self.accept("steering_wheel0-hat_up", self.center_wheel)
- self.environment = loader.loadModel("environment")
- self.environment.reparentTo(render)
- # save the center position of the wheel
- # NOTE: here we assume, that the wheel is centered when the application get started.
- # In real world applications, you should notice the user and give him enough time
- # to center the wheel until you store the center position of the controler!
- self.wheelCenter = 0
- if self.wheel is not None:
- self.wheelCenter = self.wheel.findAxis(InputDevice.Axis.wheel).value
- # disable pandas default mouse-camera controls so we can handle the camera
- # movements by ourself
- self.disableMouse()
- self.reset()
- self.taskMgr.add(self.moveTask, "movement update task")
- def connect(self, device):
- """Event handler that is called when a device is discovered."""
- # We're only interested if this is a steering wheel and we don't have a
- # wheel yet.
- if device.device_class == InputDevice.DeviceClass.steering_wheel and not self.wheel:
- print("Found %s" % (device))
- self.wheel = device
- # Enable this device to ShowBase so that we can receive events.
- # We set up the events with a prefix of "steering_wheel0-".
- self.attachInputDevice(device, prefix="steering_wheel0")
- # Hide the warning that we have no devices.
- self.lblWarning.hide()
- def disconnect(self, device):
- """Event handler that is called when a device is removed."""
- if self.wheel != device:
- # We don't care since it's not our wheel.
- return
- # Tell ShowBase that the device is no longer needed.
- print("Disconnected %s" % (device))
- self.detachInputDevice(device)
- self.wheel = None
- # Do we have any steering wheels? Attach the first other steering wheel.
- devices = self.devices.getDevices(InputDevice.DeviceClass.steering_wheel)
- if devices:
- self.connect(devices[0])
- else:
- # No devices. Show the warning.
- self.lblWarning.show()
- def reset(self):
- """Reset the camera to the initial position."""
- self.camera.setPosHpr(0, -200, 2, 0, 0, 0)
- def action(self, button):
- # Just show which button has been pressed.
- self.lblAction.text = "Pressed %s" % button
- self.lblAction.show()
- def actionUp(self):
- # Hide the label showing which button is pressed.
- self.lblAction.hide()
- def center_wheel(self):
- """Reset the wheels center rotation to the current rotation of the wheel"""
- self.wheelCenter = self.wheel.findAxis(InputDevice.Axis.wheel).value
- def moveTask(self, task):
- dt = base.clock.dt
- movementVec = Vec3()
- if not self.wheel:
- 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
- # Acclerate
- accleratorPedal = self.wheel.findAxis(InputDevice.Axis.accelerator).value
- accleration = accleratorPedal * self.maxAccleration
- if self.currentMoveSpeed > accleratorPedal * self.maxSpeed:
- self.currentMoveSpeed -= dt * self.deaccleration
- self.currentMoveSpeed += dt * accleration
- # Break
- breakPedal = self.wheel.findAxis(InputDevice.Axis.brake).value
- deacleration = breakPedal * self.deaclerationBreak
- self.currentMoveSpeed -= dt * deacleration
- if self.currentMoveSpeed < 0:
- self.currentMoveSpeed = 0
- # Steering
- rotation = self.wheelCenter - self.wheel.findAxis(InputDevice.Axis.wheel).value
- 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()
|