-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 8c50f8a
Showing
7 changed files
with
436 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "vendor/wiiuse"] | ||
path = vendor/wiiuse | ||
url = https://github.com/rpavlik/wiiuse.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
cmake_minimum_required(VERSION 2.8.12) | ||
project(WiimotePlugin) | ||
|
||
# in the CMake GUI or command line. | ||
find_package(osvr REQUIRED) | ||
|
||
set(BUILD_WIIUSE_SHARED_LIB OFF CACHE BOOL "Should we build as a shared library (dll/so)?") | ||
add_definitions("-DWIIUSE_STATIC") | ||
set(BUILD_EXAMPLE OFF CACHE BOOL "Should we build the example app?") | ||
set(BUILD_EXAMPLE_SDL OFF CACHE BOOL "Should we build the SDL-based example app?") | ||
set(INSTALL_EXAMPLES OFF CACHE BOOL "Should we install the example apps?") | ||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/vendor/wiiuse/cmake") | ||
|
||
add_subdirectory("vendor/wiiuse") | ||
|
||
osvr_convert_json(je_nourish_wiimote_json | ||
je_nourish_wiimote.json | ||
"${CMAKE_CURRENT_BINARY_DIR}/je_nourish_wiimote_json.h") | ||
|
||
include_directories("${CMAKE_CURRENT_BINARY_DIR}") | ||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/vendor/wiiuse/src") | ||
|
||
osvr_add_plugin(NAME je_nourish_wiimote | ||
CPP # indicates we'd like to use the C++ wrapper | ||
SOURCES | ||
je_nourish_wiimote.cpp | ||
"${CMAKE_CURRENT_BINARY_DIR}/je_nourish_wiimote_json.h") | ||
|
||
# If you use other libraries, find them and add a line like: | ||
target_link_libraries(je_nourish_wiimote wiiuse) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
OSVR-Wiimote | ||
Copyright (C) 2016 Steve Le Roy Harris | ||
|
||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
|
||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
|
||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# OSVR Wiimote Plugin {#WiimotePluginReadme} | ||
|
||
An OSVR plugin providing up to four Wii Remote + Nuncuk devices via the wiiuse library. There's one orientation only tracker per wiimote or nunchuk, although yaw is only available if using the sensor bar. | ||
|
||
Default mappings are for one wiimote in the right hand and nunchuk in the left, but it's more fun with a nunchuk in each hand! | ||
|
||
git clone https://github.com/simlrh/OSVR-Wiimote | ||
cd OSVR-Wiimote | ||
git submodule init | ||
git submoule update | ||
|
||
Then follow the [standard OSVR plugin build instructions](http://resource.osvr.com/docs/OSVR-Core/TopicWritingDevicePlugin.html). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
// Internal Includes | ||
#include <osvr/PluginKit/PluginKit.h> | ||
#include <osvr/PluginKit/TrackerInterfaceC.h> | ||
#include <osvr/PluginKit/AnalogInterfaceC.h> | ||
#include <osvr/PluginKit/ButtonInterfaceC.h> | ||
|
||
// Generated JSON header file | ||
#include "je_nourish_wiimote_json.h" | ||
|
||
// Library/third-party includes | ||
#include "wiiuse.h" | ||
|
||
// Standard includes | ||
#include <iostream> | ||
#define _USE_MATH_DEFINES | ||
#include <Math.h> | ||
|
||
#define MAX_WIIMOTES 4 | ||
#define TRACKERS_PER_WIIMOTE 2 | ||
#define BUTTONS_PER_WIIMOTE 13 | ||
#define ANALOG_PER_WIIMOTE 5 | ||
|
||
// Anonymous namespace to avoid symbol collision | ||
namespace { | ||
|
||
class WiimoteDevice { | ||
public: | ||
WiimoteDevice(OSVR_PluginRegContext ctx) { | ||
int found, connected; | ||
|
||
m_wiimotes = wiiuse_init(MAX_WIIMOTES); | ||
found = wiiuse_find(m_wiimotes, MAX_WIIMOTES, 5); | ||
connected = wiiuse_connect(m_wiimotes, MAX_WIIMOTES); | ||
|
||
wiiuse_set_leds(m_wiimotes[0], WIIMOTE_LED_1); | ||
wiiuse_set_leds(m_wiimotes[1], WIIMOTE_LED_2); | ||
wiiuse_set_leds(m_wiimotes[2], WIIMOTE_LED_3); | ||
wiiuse_set_leds(m_wiimotes[3], WIIMOTE_LED_4); | ||
|
||
wiiuse_motion_sensing(m_wiimotes[0], 1); | ||
wiiuse_motion_sensing(m_wiimotes[1], 1); | ||
wiiuse_motion_sensing(m_wiimotes[2], 1); | ||
wiiuse_motion_sensing(m_wiimotes[3], 1); | ||
|
||
/// Create the initialization options | ||
OSVR_DeviceInitOptions opts = osvrDeviceCreateInitOptions(ctx); | ||
|
||
osvrDeviceTrackerConfigure(opts, &m_tracker); | ||
osvrDeviceAnalogConfigure(opts, &m_analog, 20); | ||
osvrDeviceButtonConfigure(opts, &m_button, 52); | ||
|
||
/// Create the device token with the options | ||
m_dev.initAsync(ctx, "WiimoteDevice", opts); | ||
|
||
/// Send JSON descriptor | ||
m_dev.sendJsonDescriptor(je_nourish_wiimote_json); | ||
|
||
/// Register update callback | ||
m_dev.registerUpdateCallback(this); | ||
} | ||
|
||
~WiimoteDevice() { | ||
wiiuse_cleanup(m_wiimotes, MAX_WIIMOTES); | ||
} | ||
|
||
OSVR_ReturnCode update() { | ||
struct wiimote_t* wm; | ||
OSVR_Vec3 wm_rpy; | ||
OSVR_Quaternion wm_quaternion; | ||
OSVR_Vec3 nc_rpy; | ||
OSVR_Quaternion nc_quaternion; | ||
|
||
osvrVec3Zero(&wm_rpy); | ||
osvrQuatSetIdentity(&wm_quaternion); | ||
osvrVec3Zero(&nc_rpy); | ||
osvrQuatSetIdentity(&nc_quaternion); | ||
|
||
if (wiimote_connected()) { | ||
wiiuse_poll(m_wiimotes, MAX_WIIMOTES); | ||
|
||
OSVR_ButtonState buttons[BUTTONS_PER_WIIMOTE * MAX_WIIMOTES]; | ||
OSVR_AnalogState analog[ANALOG_PER_WIIMOTE * MAX_WIIMOTES]; | ||
|
||
for (int i = 0; i < MAX_WIIMOTES; i++) { | ||
wm = m_wiimotes[i]; | ||
|
||
if (wm->event == WIIUSE_EVENT) { | ||
buttons[BUTTONS_PER_WIIMOTE*i + 0] = IS_PRESSED(wm, WIIMOTE_BUTTON_A); | ||
buttons[BUTTONS_PER_WIIMOTE*i + 1] = IS_PRESSED(wm, WIIMOTE_BUTTON_B); | ||
buttons[BUTTONS_PER_WIIMOTE*i + 2] = IS_PRESSED(wm, WIIMOTE_BUTTON_UP); | ||
buttons[BUTTONS_PER_WIIMOTE*i + 3] = IS_PRESSED(wm, WIIMOTE_BUTTON_DOWN); | ||
buttons[BUTTONS_PER_WIIMOTE*i + 4] = IS_PRESSED(wm, WIIMOTE_BUTTON_LEFT); | ||
buttons[BUTTONS_PER_WIIMOTE*i + 5] = IS_PRESSED(wm, WIIMOTE_BUTTON_RIGHT); | ||
buttons[BUTTONS_PER_WIIMOTE*i + 6] = IS_PRESSED(wm, WIIMOTE_BUTTON_ONE); | ||
buttons[BUTTONS_PER_WIIMOTE*i + 7] = IS_PRESSED(wm, WIIMOTE_BUTTON_TWO); | ||
buttons[BUTTONS_PER_WIIMOTE*i + 8] = IS_PRESSED(wm, WIIMOTE_BUTTON_MINUS); | ||
buttons[BUTTONS_PER_WIIMOTE*i + 9] = IS_PRESSED(wm, WIIMOTE_BUTTON_PLUS); | ||
buttons[BUTTONS_PER_WIIMOTE*i + 10] = IS_PRESSED(wm, WIIMOTE_BUTTON_HOME); | ||
|
||
if (WIIUSE_USING_ACC(wm)) { | ||
|
||
osvrVec3SetX(&wm_rpy, -wm->orient.roll * M_PI / 180); | ||
osvrVec3SetY(&wm_rpy, -wm->orient.pitch * M_PI / 180); | ||
osvrVec3SetZ(&wm_rpy, -wm->orient.yaw * M_PI / 180); | ||
|
||
WiimoteDevice::quaternionFromRPY(&wm_rpy, &wm_quaternion); | ||
|
||
osvrDeviceTrackerSendOrientation(m_dev, m_tracker, &wm_quaternion, (TRACKERS_PER_WIIMOTE * i)); | ||
} | ||
|
||
if (WIIUSE_USING_IR(wm)) { | ||
analog[ANALOG_PER_WIIMOTE*i + 0] = wm->ir.x; | ||
analog[ANALOG_PER_WIIMOTE*i + 1] = wm->ir.y; | ||
analog[ANALOG_PER_WIIMOTE*i + 2] = wm->ir.z; | ||
} | ||
else { | ||
analog[ANALOG_PER_WIIMOTE*i + 0] = 0; | ||
analog[ANALOG_PER_WIIMOTE*i + 1] = 0; | ||
analog[ANALOG_PER_WIIMOTE*i + 2] = 0; | ||
} | ||
|
||
if (wm->exp.type == EXP_NUNCHUK || wm->exp.type == EXP_MOTION_PLUS_NUNCHUK) { | ||
struct nunchuk_t* nc = (nunchuk_t*)&wm->exp.nunchuk; | ||
|
||
buttons[BUTTONS_PER_WIIMOTE*i + 11] = IS_PRESSED(wm, NUNCHUK_BUTTON_C); | ||
buttons[BUTTONS_PER_WIIMOTE*i + 12] = IS_PRESSED(wm, NUNCHUK_BUTTON_Z); | ||
|
||
analog[ANALOG_PER_WIIMOTE*i + 3] = nc->js.x; | ||
analog[ANALOG_PER_WIIMOTE*i + 4] = nc->js.y; | ||
|
||
osvrVec3SetX(&nc_rpy, -nc->orient.roll * M_PI / 180); | ||
osvrVec3SetY(&nc_rpy, -nc->orient.pitch * M_PI / 180); | ||
osvrVec3SetZ(&nc_rpy, -nc->orient.yaw * M_PI / 180); | ||
|
||
WiimoteDevice::quaternionFromRPY(&nc_rpy, &nc_quaternion); | ||
|
||
osvrDeviceTrackerSendOrientation(m_dev, m_tracker, &nc_quaternion, (TRACKERS_PER_WIIMOTE * i) + 1); | ||
} | ||
else { | ||
buttons[BUTTONS_PER_WIIMOTE*i + 11] = false; | ||
buttons[BUTTONS_PER_WIIMOTE*i + 12] = false; | ||
analog[ANALOG_PER_WIIMOTE*i + 3] = 0; | ||
analog[ANALOG_PER_WIIMOTE*i + 4] = 0; | ||
} | ||
} | ||
else { | ||
buttons[BUTTONS_PER_WIIMOTE*i + 0] = false; | ||
buttons[BUTTONS_PER_WIIMOTE*i + 1] = false; | ||
buttons[BUTTONS_PER_WIIMOTE*i + 2] = false; | ||
buttons[BUTTONS_PER_WIIMOTE*i + 3] = false; | ||
buttons[BUTTONS_PER_WIIMOTE*i + 4] = false; | ||
buttons[BUTTONS_PER_WIIMOTE*i + 5] = false; | ||
buttons[BUTTONS_PER_WIIMOTE*i + 6] = false; | ||
buttons[BUTTONS_PER_WIIMOTE*i + 7] = false; | ||
buttons[BUTTONS_PER_WIIMOTE*i + 8] = false; | ||
buttons[BUTTONS_PER_WIIMOTE*i + 9] = false; | ||
buttons[BUTTONS_PER_WIIMOTE*i + 10] = false; | ||
buttons[BUTTONS_PER_WIIMOTE*i + 11] = false; | ||
buttons[BUTTONS_PER_WIIMOTE*i + 12] = false; | ||
} | ||
} | ||
|
||
osvrDeviceAnalogSetValues(m_dev, m_analog, analog, 20); | ||
osvrDeviceButtonSetValues(m_dev, m_button, buttons, 52); | ||
} | ||
|
||
return OSVR_RETURN_SUCCESS; | ||
} | ||
|
||
private: | ||
bool wiimote_connected() { | ||
for (int i = 0; i < MAX_WIIMOTES; i++) { | ||
if (m_wiimotes[i] && WIIMOTE_IS_CONNECTED(m_wiimotes[i])) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
static void quaternionFromRPY(OSVR_Vec3* rpy, OSVR_Quaternion* quaternion) { | ||
double r = osvrVec3GetX(rpy); | ||
double p = osvrVec3GetY(rpy); | ||
double y = osvrVec3GetZ(rpy); | ||
|
||
osvrQuatSetZ(quaternion, sin(r / 2) * cos(p / 2) * cos(y / 2) - cos(r / 2) * sin(p / 2) * sin(y / 2)); | ||
osvrQuatSetX(quaternion, cos(r / 2) * sin(p / 2) * cos(y / 2) + sin(r / 2) * cos(p / 2) * sin(y / 2)); | ||
osvrQuatSetY(quaternion, cos(r / 2) * cos(p / 2) * sin(y / 2) - sin(r / 2) * sin(p / 2) * cos(y / 2)); | ||
osvrQuatSetW(quaternion, cos(r / 2) * cos(p / 2) * cos(y / 2) + sin(r / 2) * sin(p / 2) * sin(y / 2)); | ||
} | ||
|
||
wiimote** m_wiimotes; | ||
osvr::pluginkit::DeviceToken m_dev; | ||
OSVR_TrackerDeviceInterface m_tracker; | ||
OSVR_AnalogDeviceInterface m_analog; | ||
OSVR_ButtonDeviceInterface m_button; | ||
}; | ||
|
||
class HardwareDetection { | ||
public: | ||
HardwareDetection() : m_found(false) {} | ||
OSVR_ReturnCode operator()(OSVR_PluginRegContext ctx) { | ||
|
||
if (!m_found) { | ||
m_found = true; | ||
|
||
osvr::pluginkit::registerObjectForDeletion( | ||
ctx, new WiimoteDevice(ctx)); | ||
} | ||
return OSVR_RETURN_SUCCESS; | ||
} | ||
|
||
private: | ||
bool m_found; | ||
|
||
}; | ||
} // namespace | ||
|
||
OSVR_PLUGIN(je_nourish_wiimote) { | ||
osvr::pluginkit::PluginContext context(ctx); | ||
|
||
/// Register a detection callback function object. | ||
context.registerHardwareDetectCallback(new HardwareDetection()); | ||
|
||
return OSVR_RETURN_SUCCESS; | ||
} |
Oops, something went wrong.