Custom Input Devices: How does it all work?
Moderator: PPS-Leaders
Custom Input Devices: How does it all work?
Greetings everyone,
I'm in this semester's Orxonox PPS and decided to try and implement a WiiMote interface. I'm now stuck trying to figure out how exactly input devices are managed, where data is collected, passed on and mapped to game actions. So far, I've gathered the following (please correct any mistaken impressions):
-Input is collected by (extended) InputDevice instances representing an input device each; these interface with X Window Manager directly
-The collected input is somehow passed to the InputManager, from where/bz which it is passed to the various components that can accept input.
(These are just the things I gathered from the Input Wiki page)
My questions now would be:
-Is there a clean way for me to define a custom InputDevice-inheriting class for my WiiMote that can interface with the InputManager as well as the WiiC library (OIS has rudimentary WiiMote support, but not enough for what I'm trying to do) and act as sort of a hybrid between the mouse and controller device classes (using the IR functionality to act like a mouse for steering the craft and the buttons for controlling things like weapons, speed etc)?
-How/where would I code the key mappings for the WiiMote?
-How is the input data actually passed between these classes, and what would I have to change to accomodate the WiiMote?
-Where/how does the game select between different input devices? I wouldn't want to have mouse input interfering with my WiiMote input, for example, so it would be nice to be able to have kind of a "WiiMote Option" where only WiiMote and keyboard commands are accepted. I've noticed that in the game, the only options in the input menu are regarding keyboard and mouse input...
-How do the standard OIS play into the whole thing? What parts are handled by them, and what's done by the original orxonox code?
The bottom line is really that I'm looking for a run-down of the whole input data flow, all these classes referencing each other and some macro magic to top it all off are really making my head spin.
Thanks in advance for your help,
Georg
I'm in this semester's Orxonox PPS and decided to try and implement a WiiMote interface. I'm now stuck trying to figure out how exactly input devices are managed, where data is collected, passed on and mapped to game actions. So far, I've gathered the following (please correct any mistaken impressions):
-Input is collected by (extended) InputDevice instances representing an input device each; these interface with X Window Manager directly
-The collected input is somehow passed to the InputManager, from where/bz which it is passed to the various components that can accept input.
(These are just the things I gathered from the Input Wiki page)
My questions now would be:
-Is there a clean way for me to define a custom InputDevice-inheriting class for my WiiMote that can interface with the InputManager as well as the WiiC library (OIS has rudimentary WiiMote support, but not enough for what I'm trying to do) and act as sort of a hybrid between the mouse and controller device classes (using the IR functionality to act like a mouse for steering the craft and the buttons for controlling things like weapons, speed etc)?
-How/where would I code the key mappings for the WiiMote?
-How is the input data actually passed between these classes, and what would I have to change to accomodate the WiiMote?
-Where/how does the game select between different input devices? I wouldn't want to have mouse input interfering with my WiiMote input, for example, so it would be nice to be able to have kind of a "WiiMote Option" where only WiiMote and keyboard commands are accepted. I've noticed that in the game, the only options in the input menu are regarding keyboard and mouse input...
-How do the standard OIS play into the whole thing? What parts are handled by them, and what's done by the original orxonox code?
The bottom line is really that I'm looking for a run-down of the whole input data flow, all these classes referencing each other and some macro magic to top it all off are really making my head spin.
Thanks in advance for your help,
Georg
Re: Custom Input Devices: How does it all work?
The input system was designed and implemented by Reto but I'm not sure if he's still reading this forum.
I cannot answer all your questions off the top of my head but I'll try to find some answers soon.
So far I can tell you only a few things:
I cannot answer all your questions off the top of my head but I'll try to find some answers soon.
So far I can tell you only a few things:
- We use OIS as an external library for input handling. OIS handles everything from the moment when you press a button up to the point where we (Orxonox) receive a callback with the input event. This includes all OS-dependent stuff and some abstraction layers (therefore all input devices behave the same from our point ov view).
- OIS is included in our source repository (src/external/ois). I don't know which version this is, but if you need a more recent version to work with the WiiMote you have to upgrade it and probably adjust some code in Orxonox.
- OIS has a list of keys. This includes keyboard keys but also mouse, joystick, gamepad and (virtual) wiimote keys.
- OIS/Orxonox knows different kinds of events. I'm not sure where to draw the line between OIS and Orxonox without looking into the code. There are different types of events, I think we distinguish between buttons and axes. A button has a binary state (pressed or not) and triggers events when pressed or released. An axis has a floating point state between 0 and 1 (or maybe -1 and 1) and triggers an event when moved. You can imagine a mouse or a joystick as two axes. A slider on a gamepad is one axis.
- Events (and the state of the corresponding button or axis) are sent via callbacks from OIS to Orxonox.
- Orxonox maintains a list of so called key-bindings. A key-binding is a console-command which is bound to a button or axis. If the button or axis triggers an event, the console command is executed.
- If a console command is bound to a button, you can bind it to different events: press, release, or hold. Depending on this, the console command is either executed when you press the button, release it, or when you hold it.
- If a console command is bound to an axis, every movement of the axis executes the command plus the state of the axis is passed to the command as an argument.
- I could tell you more about console commands (I implemented them) but I think it's out of scope of your project. All you have to know is that a console command executes a function in C++ with some arguments. Console commands can be typed into the console (hence the name) or bound to a key (key-binding).
- The input framework in Orxonox (located in src/libraries/core/input) acts as the "glue" between OIS and console-commands. It's responsibility is to recieve input events from OIS and pass them to the correct console command, based on a list of key-bindings.
Fabian 'x3n' Landau, Orxonox developer
Re: Custom Input Devices: How does it all work?
About the general goal:
Do you have an idea how to steer a spaceship with a wiimote as input device?
The Problem is, that we use two input devices to steer a spaceship.
The mouse to aim and select weapons (left click, right click and middle click) and a ton of keys on a keyboard.
E.g. W to accelerate to the front and A,S,D to accelerate to the left, back and right. The R and F keys accelerate up and down.
The space bar creates boost, and with Q/E you rotate to the left/ to the right. When pressing T a rocket is launched.
There are also special functions like changing the camera when pressing C, decoupling aim from flight direction, when pressing tab, free camera mode when pressing Control and the ESC key to call the menu.
Besides if you press the F1 to F5 some overlays/ in game menus appear.
Here the quest menu and probably the pickup menu are a must have.
-----------------------------------------------------------------
With this post I do not want you to give up, but try your best.
Besides the ESC key, all other special functions can be omitted.
The mouse input is replaced by the location the wiimote is pointing.
Accerlerating to the left/ right is not needed, up and down acceleration might also be omitted. I consider ESC, boost and the weapons as most important features.
Do you have an idea how to steer a spaceship with a wiimote as input device?
The Problem is, that we use two input devices to steer a spaceship.
The mouse to aim and select weapons (left click, right click and middle click) and a ton of keys on a keyboard.
E.g. W to accelerate to the front and A,S,D to accelerate to the left, back and right. The R and F keys accelerate up and down.
The space bar creates boost, and with Q/E you rotate to the left/ to the right. When pressing T a rocket is launched.
There are also special functions like changing the camera when pressing C, decoupling aim from flight direction, when pressing tab, free camera mode when pressing Control and the ESC key to call the menu.
Besides if you press the F1 to F5 some overlays/ in game menus appear.
Here the quest menu and probably the pickup menu are a must have.
-----------------------------------------------------------------
With this post I do not want you to give up, but try your best.
Besides the ESC key, all other special functions can be omitted.
The mouse input is replaced by the location the wiimote is pointing.
Accerlerating to the left/ right is not needed, up and down acceleration might also be omitted. I consider ESC, boost and the weapons as most important features.
Fail. Fail again. Fail better.
Re: Custom Input Devices: How does it all work?
An input device doesn't have to cover all features. You can play Orxonox with a gamepad which acts like a combination of mouse and keyboard, but with less buttons. If you need more buttons, you can still use the keyboard.
The same holds for the WiiMote. Just use the keyboard if necessary. After all, Orxonox is a PC game and not a Wii one. It's still cool if we can use the WiiMote though, but it will of course never be enough to use all features.
The same holds for the WiiMote. Just use the keyboard if necessary. After all, Orxonox is a PC game and not a Wii one. It's still cool if we can use the WiiMote though, but it will of course never be enough to use all features.
Fabian 'x3n' Landau, Orxonox developer
Re: Custom Input Devices: How does it all work?
Well, for the control scheme I've already thought of a few options:
-IR Tracking acts like a mouse for steering - this necesssitates an IR bar, but it's worth the trouble IMO since accelerometers are inherently unprecise.
-A and B fire primary and secondary weapons, respectively
-the accelerometer is used to control roll, but with a button-like behaviour instead of continuous measuring, e.g. a wiimote roll of more than X (a suitable value will have to be determined) has the same effect as pressing Q/W on the keyboard
-The boost button is the Z button of the Nunchuck
-For throttle control, you press C on the Nunchuck and move the joystick up/down to increase/decrease throttle
-For functions used in less stressful (i.e. non-combat) situations like the quest overlays etc, the plus/minus/1/2 buttons can be mapped
-Maybe fire rockets with D-pad down? This isn't very elegant, but it's either 2 easily accessible lasers or 1 laser and 1 rocket...
I'm just wondering how I can get the WiiCPP library to somehow interact with OIS meaningfully, seeing as OIS seems to be geared towards OS-generated input events (or am I wrong with this assumption? I could not for the life of me find any documentation on OIS...). I've already got the example program to run and register wiimotes on my laptop, so on that end, it's looking good.
-IR Tracking acts like a mouse for steering - this necesssitates an IR bar, but it's worth the trouble IMO since accelerometers are inherently unprecise.
-A and B fire primary and secondary weapons, respectively
-the accelerometer is used to control roll, but with a button-like behaviour instead of continuous measuring, e.g. a wiimote roll of more than X (a suitable value will have to be determined) has the same effect as pressing Q/W on the keyboard
-The boost button is the Z button of the Nunchuck
-For throttle control, you press C on the Nunchuck and move the joystick up/down to increase/decrease throttle
-For functions used in less stressful (i.e. non-combat) situations like the quest overlays etc, the plus/minus/1/2 buttons can be mapped
-Maybe fire rockets with D-pad down? This isn't very elegant, but it's either 2 easily accessible lasers or 1 laser and 1 rocket...
I'm just wondering how I can get the WiiCPP library to somehow interact with OIS meaningfully, seeing as OIS seems to be geared towards OS-generated input events (or am I wrong with this assumption? I could not for the life of me find any documentation on OIS...). I've already got the example program to run and register wiimotes on my laptop, so on that end, it's looking good.
Re: Custom Input Devices: How does it all work?
OIS is indeed designed to use input events on the OS-level. And I guess your WiiMote will produces those events if you install an appropriate driver. I don't know if you need WiiCpp for that...
The latest (well, it's from 2010) release of OIS (1.3) contains sources for the WiiMote on Windows. See the project homepage: http://sourceforge.net/projects/wgois/
Those sources are not included in Orxonox so far. You may have to update OIS to v1.3.
If your target plattform is not Windows, then however I don't know if you can achieve your goal with OIS...
The latest (well, it's from 2010) release of OIS (1.3) contains sources for the WiiMote on Windows. See the project homepage: http://sourceforge.net/projects/wgois/
Those sources are not included in Orxonox so far. You may have to update OIS to v1.3.
If your target plattform is not Windows, then however I don't know if you can achieve your goal with OIS...
Fabian 'x3n' Landau, Orxonox developer
Re: Custom Input Devices: How does it all work?
Well, the only reference to wiimotes I could find in OIS' (virtually non-existent) documentation stated that IR tracking wasn't implemented, and without that defining feature, the wiimote (IMO) doesn't have enough ways to input things to be a suitable controller for orxonox. Maybe bypassing OIS altogether and writing my own separate input module for the WiiMote would be the way to go? The WiiCpp library allows for some pretty easy no-fuss input handling (it's also RMS-approved, being licensed under the GNU GPL), so if there's a way to sort of emulate the events OIS generates and pass them to the orxonox input handler, hooking the wiimote up to Orxonox would not be too difficult. Going through OS layers seems unnecessarily tedious to me, considering most wiimote libraries I've seen are third-party projects that don't rely on any system calls apart from bluetooth communication, which it handles with libbluetooth-dev.
Also, I'm definitely not considering Windows as my target platform seeing as actually getting Orxonox to run on it seems to be a task few have accomplished yet - two of my colleagues who are in this semester's PPS tried it and they both gave up eventually. I think I'll just stick to Linux.
Also, I'm definitely not considering Windows as my target platform seeing as actually getting Orxonox to run on it seems to be a task few have accomplished yet - two of my colleagues who are in this semester's PPS tried it and they both gave up eventually. I think I'll just stick to Linux.
Re: Custom Input Devices: How does it all work?
In this case you're probably right, it's better to bypass OIS and use WiiCpp. It shouldn't be too hard to inject some events into Orxonox' input system. Just look at how OIS events are handled, then do the same with your WiiMote events. Just try to find the part of the code which "translates" OIS events into Orxonox events. If you need some hints, keep asking. But I'd have to look into the code as well.
Regarding Windows: If you or someone else has trouble building it on Windows, please post your problems in this forum. Even if you don't really care if you use Windows or Linux; but every feedback helps us improving the documentation.
Without feedback, I have no clue what the problems are... because I can build Orxonox with both MinGW and Visual Studio on every Windows machine I own (including virutal machines) without any issues. But maybe I simply forgot to add an important detail to the documentation or maybe I use an old version of some tool and the new versions don't work anymore...
Regarding Windows: If you or someone else has trouble building it on Windows, please post your problems in this forum. Even if you don't really care if you use Windows or Linux; but every feedback helps us improving the documentation.
Without feedback, I have no clue what the problems are... because I can build Orxonox with both MinGW and Visual Studio on every Windows machine I own (including virutal machines) without any issues. But maybe I simply forgot to add an important detail to the documentation or maybe I use an old version of some tool and the new versions don't work anymore...
Fabian 'x3n' Landau, Orxonox developer
Re: Custom Input Devices: How does it all work?
Yeah, that's what we figured in the last PPS session too. From the way it looks, I'm just gonna be pushing hacked together mouse events on the InputManager's stack and doing something similarly ugly with button events, although I haven't been able to find out exactly where/how those are handled yet.
About the Windows thing: I haven't tried it myself, but if I remember correctly, the people who had trouble already got stuck at the CMake part of the build process (as in, they couldn't get CMake on their machines)... I'll let them know to post their problems here, although I'm certain it was nothing that wouldn't be google-able. I'll also try your suggestions from here to get Orxonox to build on my Ubuntu machine tomorrow and report back with my results.
Thanks for all the help, I'll let you know if I need some more info!
About the Windows thing: I haven't tried it myself, but if I remember correctly, the people who had trouble already got stuck at the CMake part of the build process (as in, they couldn't get CMake on their machines)... I'll let them know to post their problems here, although I'm certain it was nothing that wouldn't be google-able. I'll also try your suggestions from here to get Orxonox to build on my Ubuntu machine tomorrow and report back with my results.
Thanks for all the help, I'll let you know if I need some more info!
Re: Custom Input Devices: How does it all work?
@ x3n: we wondered whether we can have a Singleton or something that simply sits
around and does the calls into orxonox's input system instead of the OIS code. I imagine something like a singleton that's being ticked/polled every x milliseconds and then calls the InputState's mouseMoved function to emulate something like OIS does.
Any thoughts on this approach?
around and does the calls into orxonox's input system instead of the OIS code. I imagine something like a singleton that's being ticked/polled every x milliseconds and then calls the InputState's mouseMoved function to emulate something like OIS does.
Any thoughts on this approach?
Re: Custom Input Devices: How does it all work?
Well, of course you can have a singleton, you can have anything, you're developers.
The question is more like "Is a singleton a suitable solution to our problem" and "does it fit into the existing design". On a side note: try to not use singletons if possible. But before you start thinking about the design, think about responsibilities and behavior.
What needs to be done to create input events from WiiMote actions?
Now look at it from the other side. What do we already have in our input system? For instance there's InputManager, a singleton. It has a list of InputDevice instances. When I look at InputDevice, I see this function:
Whoops. That reads a lot like your suggestions, doesn't it? InputDevice is the base class of Mouse, Keyboard and JoyStick. There can be multiple instances of each type.
Maybe all you have to do is to create a new subclass for the WiiMote and put it into the list of devices in InputManager? (That's not a rhetorical question by the way, I really don't know)
The question is more like "Is a singleton a suitable solution to our problem" and "does it fit into the existing design". On a side note: try to not use singletons if possible. But before you start thinking about the design, think about responsibilities and behavior.
What needs to be done to create input events from WiiMote actions?
- Do you need an instance which wraps the driver (or WiiCpp)? Is there only one driver? Maybe that could be a singleton. Maybe.
- Do you need an instance which represents the WiiMote device? Is there only one? Or maybe multiple? Can you guarantee that there's ever only one such device connected? Probably not. So that's not gona be a singleton.
- Anything else?
Now look at it from the other side. What do we already have in our input system? For instance there's InputManager, a singleton. It has a list of InputDevice instances. When I look at InputDevice, I see this function:
Code: Select all
//! Updates the device which should in turn distribute events
virtual void update(const Clock& time) = 0;
Maybe all you have to do is to create a new subclass for the WiiMote and put it into the list of devices in InputManager? (That's not a rhetorical question by the way, I really don't know)
Fabian 'x3n' Landau, Orxonox developer
Re: Custom Input Devices: How does it all work?
x3n is pretty much right. When you look at our input devices (Mouse, Keyboard etc.) they all inherit from InputDeviceTemplated. This is because this class has already OIS support built in. A call from the InputManager to the InputDevice's update method will call OIS. OIS will then spawn events that are handed back to the InputDeviceTemplated via mouseMoved and similar functions. The InputDevice will then create InputStates which are then again used by the InputManager.
So the call stack looks kind of like this:
... -> InputManager -> InputDeviceTemplated -> OIS -> InputDeviceTemplated (new InputState) -> InputManager -> ...
Since the WiiMote will not use OIS you will have to create the InputStates without the help of OIS events and use the class InputDevice instead of InputDeviceTemplated.
You will then get a call stack like this:
... -> InputManager -> InputDevice -> WiiMoteCode -> InputDevice (new InputState) -> InputManager -> ...
Obviously you will have a WiiMote class that inherits from InputDevice and implements the update method.
Also how about looking at this (Ogre Wiki article on how to use OIS)?
Or this (OIS wrapper to facilitate access to the library)?
OR, if you want to be very bold, have a look at this!
Later on you will need to map the InputStates to Keybindings. I don't know how WiiMote output looks like, but I guess looking at the code that binds the Joystick-Analog-Sticks to keys will help figuring out how WiiMote output will map to our ingame events.
So the call stack looks kind of like this:
... -> InputManager -> InputDeviceTemplated -> OIS -> InputDeviceTemplated (new InputState) -> InputManager -> ...
Since the WiiMote will not use OIS you will have to create the InputStates without the help of OIS events and use the class InputDevice instead of InputDeviceTemplated.
You will then get a call stack like this:
... -> InputManager -> InputDevice -> WiiMoteCode -> InputDevice (new InputState) -> InputManager -> ...
Obviously you will have a WiiMote class that inherits from InputDevice and implements the update method.
Also how about looking at this (Ogre Wiki article on how to use OIS)?
Or this (OIS wrapper to facilitate access to the library)?
OR, if you want to be very bold, have a look at this!
Later on you will need to map the InputStates to Keybindings. I don't know how WiiMote output looks like, but I guess looking at the code that binds the Joystick-Analog-Sticks to keys will help figuring out how WiiMote output will map to our ingame events.
"I'm Commander Shepard and this is my favorite forum on the internet."
Re: Custom Input Devices: How does it all work?
Thanks for all the help everyone! I have heeded your advice and have now managed to make a dummy WiiMote class (see my code branch) which inherits from InputDevice and doesn't yet interface with an actual wiimote, but is registered in the InputManager's device list and proceeds to output insulting messages to the console. Next week I'll give connecting it to the actual wiimote a try.
Re: Custom Input Devices: How does it all work?
You've made some good progress with the understanding of the InputSystem. I'm looking forward to see how the interfacing with the WiiMote will go next week.
If you're able to understand the Inputsystem better, it's definitely a good idea to document your fidings about the Inputsystem overall. Improving the documentation (rather in the Wiki than the code) will help others who will look at the Inputsystem later.
If you're able to understand the Inputsystem better, it's definitely a good idea to document your fidings about the Inputsystem overall. Improving the documentation (rather in the Wiki than the code) will help others who will look at the Inputsystem later.
"I'm Commander Shepard and this is my favorite forum on the internet."
Re: Custom Input Devices: How does it all work?
Actually I prefer to put documentation into the code instead of the wiki. It's less likely to get out of date if you put it in the code. It's also the first place where a real developer looks.
Nice to see that you're project makes some progress.
[x] created a class
[x] created insulting messages
[ ] working wiimote input
I'd say you're 67% done
Nice to see that you're project makes some progress.
[x] created a class
[x] created insulting messages
[ ] working wiimote input
I'd say you're 67% done
Fabian 'x3n' Landau, Orxonox developer
Who is online
Users browsing this forum: No registered users and 1 guest