From b8b61e7c62a8ad6dd891111064cdedc9cb432502 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Thu, 11 Jun 2015 15:51:21 -0700 Subject: [PATCH 01/12] integrated joysticks with userinputmapper, enabling plug-in-and-play controllers and input mapping with js --- interface/src/Application.cpp | 6 +- interface/src/devices/Joystick.cpp | 177 ++++++++++++++++-- interface/src/devices/Joystick.h | 51 +++-- .../SDL2Manager.cpp} | 101 +++++----- .../SDL2Manager.h} | 82 +++----- interface/src/ui/UserInputMapper.cpp | 5 + interface/src/ui/UserInputMapper.h | 1 + 7 files changed, 278 insertions(+), 145 deletions(-) rename interface/src/{scripting/JoystickScriptingInterface.cpp => devices/SDL2Manager.cpp} (62%) rename interface/src/{scripting/JoystickScriptingInterface.h => devices/SDL2Manager.h} (53%) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 750955dc6a..e126882004 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -113,6 +113,7 @@ #include "devices/Faceshift.h" #include "devices/Leapmotion.h" #include "devices/RealSense.h" +#include "devices/SDL2Manager.h" #include "devices/MIDIManager.h" #include "devices/OculusManager.h" #include "devices/TV3DManager.h" @@ -127,7 +128,6 @@ #include "scripting/AudioDeviceScriptingInterface.h" #include "scripting/ClipboardScriptingInterface.h" #include "scripting/HMDScriptingInterface.h" -#include "scripting/JoystickScriptingInterface.h" #include "scripting/GlobalServicesScriptingInterface.h" #include "scripting/LocationScriptingInterface.h" #include "scripting/MenuScriptingInterface.h" @@ -1455,6 +1455,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) { void Application::focusOutEvent(QFocusEvent* event) { _keyboardMouseDevice.focusOutEvent(event); + SDL2Manager::getInstance()->focusOutEvent(); // synthesize events for keys currently pressed, since we may not get their release events foreach (int key, _keysPressed) { @@ -2450,7 +2451,7 @@ void Application::update(float deltaTime) { } SixenseManager::getInstance().update(deltaTime); - JoystickScriptingInterface::getInstance().update(); + SDL2Manager::getInstance()->update(); } _userInputMapper.update(deltaTime); @@ -4045,7 +4046,6 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("AvatarManager", DependencyManager::get().data()); - scriptEngine->registerGlobalObject("Joysticks", &JoystickScriptingInterface::getInstance()); qScriptRegisterMetaType(scriptEngine, joystickToScriptValue, joystickFromScriptValue); scriptEngine->registerGlobalObject("UndoStack", &_undoStackScriptingInterface); diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index 8b225437c2..659e5fa175 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -13,8 +13,11 @@ #include +#include "Application.h" + #include "Joystick.h" +const float CONTROLLER_THRESHOLD = .25f; #ifdef HAVE_SDL2 const float MAX_AXIS = 32768.0f; @@ -22,10 +25,7 @@ const float MAX_AXIS = 32768.0f; Joystick::Joystick(SDL_JoystickID instanceId, const QString& name, SDL_GameController* sdlGameController) : _sdlGameController(sdlGameController), _sdlJoystick(SDL_GameControllerGetJoystick(_sdlGameController)), - _instanceId(instanceId), - _name(name), - _axes(QVector(SDL_JoystickNumAxes(_sdlJoystick))), - _buttons(QVector(SDL_JoystickNumButtons(_sdlJoystick))) + _instanceId(instanceId) { } @@ -42,24 +42,171 @@ void Joystick::closeJoystick() { #endif } +void Joystick::update() { + for (auto axisState : _axisStateMap) { + if (axisState.second < CONTROLLER_THRESHOLD && axisState.second > -CONTROLLER_THRESHOLD) { + _axisStateMap[axisState.first] = 0; + } + } +} + +void Joystick::focusOutEvent() { + _axisStateMap.clear(); + _buttonPressedMap.clear(); +}; #ifdef HAVE_SDL2 void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) { - if (_axes.size() <= event.axis) { - _axes.resize(event.axis + 1); + SDL_GameControllerAxis axis = (SDL_GameControllerAxis) event.axis; + + if (axis == SDL_CONTROLLER_AXIS_LEFTX) { + _axisStateMap[makeInput(LEFT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + } else if (axis == SDL_CONTROLLER_AXIS_LEFTY) { + _axisStateMap[makeInput(LEFT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + } else if (axis == SDL_CONTROLLER_AXIS_RIGHTX) { + _axisStateMap[makeInput(RIGHT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + } else if (axis == SDL_CONTROLLER_AXIS_RIGHTY) { + _axisStateMap[makeInput(RIGHT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; } - - float oldValue = _axes[event.axis]; - float newValue = event.value / MAX_AXIS; - _axes[event.axis] = newValue; - - emit axisValueChanged(event.axis, newValue, oldValue); + } void Joystick::handleButtonEvent(const SDL_ControllerButtonEvent& event) { - bool oldValue = _buttons[event.button]; + auto input = makeInput((SDL_GameControllerButton) event.button); bool newValue = event.state == SDL_PRESSED; - _buttons[event.button] = newValue; - emit buttonStateChanged(event.button, newValue, oldValue); + if (newValue) { + _buttonPressedMap.insert(input.getChannel()); + } else { + _buttonPressedMap.erase(input.getChannel()); + } } #endif + + +void Joystick::registerToUserInputMapper(UserInputMapper& mapper) { + // Grab the current free device ID + _deviceID = mapper.getFreeDeviceID(); + + auto proxy = UserInputMapper::DeviceProxy::Pointer(new UserInputMapper::DeviceProxy(_name)); + proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input._channel); }; + proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input._channel); }; + proxy->getAvailabeInputs = [this] () -> QVector { + QVector availableInputs; +#ifdef HAVE_SDL2 + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_A), "Bottom Button")); + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_B), "Right Button")); + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_X), "Left Button")); + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_Y), "Top Button")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_DPAD_UP), "DPad Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_DPAD_DOWN), "DPad Down")); + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_DPAD_LEFT), "DPad Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_DPAD_RIGHT), "DPad Right")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_LEFTSHOULDER), "L1")); + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), "R1")); +#endif + return availableInputs; + }; + proxy->resetDeviceBindings = [this, &mapper] () -> bool { + mapper.removeAllInputChannelsForDevice(_deviceID); + this->assignDefaultInputMapping(mapper); + return true; + }; + mapper.registerDevice(_deviceID, proxy); +} + +void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) { +#ifdef HAVE_SDL2 + const float JOYSTICK_MOVE_SPEED = 1.0f; + const float DPAD_MOVE_SPEED = .5f; + const float JOYSTICK_YAW_SPEED = 0.5f; + const float JOYSTICK_PITCH_SPEED = 0.25f; + + // Y axes are flipped (up is negative) + // Left Joystick: Movement, strafing + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(LEFT_AXIS_Y_NEG), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(LEFT_AXIS_Y_POS), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(LEFT_AXIS_X_POS), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(LEFT_AXIS_X_NEG), JOYSTICK_MOVE_SPEED); + + // Right Joystick: Camera orientation + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(RIGHT_AXIS_X_POS), JOYSTICK_YAW_SPEED); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(RIGHT_AXIS_X_NEG), JOYSTICK_YAW_SPEED); + mapper.addInputChannel(UserInputMapper::PITCH_UP, makeInput(RIGHT_AXIS_Y_NEG), JOYSTICK_PITCH_SPEED); + mapper.addInputChannel(UserInputMapper::PITCH_DOWN, makeInput(RIGHT_AXIS_Y_POS), JOYSTICK_PITCH_SPEED); + + // Dpad movement + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_UP), DPAD_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_DOWN), DPAD_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_RIGHT), DPAD_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_LEFT), DPAD_MOVE_SPEED); + + // Button controls + mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(SDL_CONTROLLER_BUTTON_Y), DPAD_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(SDL_CONTROLLER_BUTTON_A), DPAD_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(SDL_CONTROLLER_BUTTON_X), JOYSTICK_YAW_SPEED); + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_B), JOYSTICK_YAW_SPEED); + + + // Hold front right shoulder button for precision controls + // Left Joystick: Movement, strafing + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(LEFT_AXIS_Y_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(LEFT_AXIS_Y_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(LEFT_AXIS_X_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(LEFT_AXIS_X_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); + + // Right Joystick: Camera orientation + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(RIGHT_AXIS_X_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(RIGHT_AXIS_X_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); + mapper.addInputChannel(UserInputMapper::PITCH_UP, makeInput(RIGHT_AXIS_Y_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_PITCH_SPEED/2.); + mapper.addInputChannel(UserInputMapper::PITCH_DOWN, makeInput(RIGHT_AXIS_Y_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_PITCH_SPEED/2.); + + // Dpad movement + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_UP), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_DOWN), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_RIGHT), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_LEFT), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); + + // Button controls + mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(SDL_CONTROLLER_BUTTON_Y), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(SDL_CONTROLLER_BUTTON_A), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(SDL_CONTROLLER_BUTTON_X), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_B), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); +#endif +} + +float Joystick::getButton(int channel) const { + if (!_buttonPressedMap.empty()) { + if (_buttonPressedMap.find(channel) != _buttonPressedMap.end()) { + return 1.0f; + } else { + return 0.0f; + } + } + return 0.0f; +} + +float Joystick::getAxis(int channel) const { + auto axis = _axisStateMap.find(channel); + if (axis != _axisStateMap.end()) { + return (*axis).second; + } else { + return 0.0f; + } +} + +#ifdef HAVE_SDL2 +UserInputMapper::Input Joystick::makeInput(SDL_GameControllerButton button) { + return UserInputMapper::Input(_deviceID, button, UserInputMapper::ChannelType::BUTTON); +} +#endif + +UserInputMapper::Input Joystick::makeInput(Joystick::JoystickAxisChannel axis) { + return UserInputMapper::Input(_deviceID, axis, UserInputMapper::ChannelType::AXIS); +} + diff --git a/interface/src/devices/Joystick.h b/interface/src/devices/Joystick.h index eeeeb03759..c5ca7a6f7f 100644 --- a/interface/src/devices/Joystick.h +++ b/interface/src/devices/Joystick.h @@ -20,6 +20,8 @@ #undef main #endif +#include "ui/UserInputMapper.h" + class Joystick : public QObject { Q_OBJECT @@ -29,12 +31,38 @@ class Joystick : public QObject { Q_PROPERTY(int instanceId READ getInstanceId) #endif - Q_PROPERTY(int numAxes READ getNumAxes) - Q_PROPERTY(int numButtons READ getNumButtons) public: + enum JoystickAxisChannel { + LEFT_AXIS_X_POS = 0, + LEFT_AXIS_X_NEG, + LEFT_AXIS_Y_POS, + LEFT_AXIS_Y_NEG, + RIGHT_AXIS_X_POS, + RIGHT_AXIS_X_NEG, + RIGHT_AXIS_Y_POS, + RIGHT_AXIS_Y_NEG, + }; + Joystick(); ~Joystick(); + typedef std::unordered_set ButtonPressedMap; + typedef std::map AxisStateMap; + + float getButton(int channel) const; + float getAxis(int channel) const; + +#ifdef HAVE_SDL2 + UserInputMapper::Input makeInput(SDL_GameControllerButton button); +#endif + UserInputMapper::Input makeInput(Joystick::JoystickAxisChannel axis); + + void registerToUserInputMapper(UserInputMapper& mapper); + void assignDefaultInputMapping(UserInputMapper& mapper); + + void update(); + void focusOutEvent(); + #ifdef HAVE_SDL2 Joystick(SDL_JoystickID instanceId, const QString& name, SDL_GameController* sdlGameController); #endif @@ -51,15 +79,8 @@ public: int getInstanceId() const { return _instanceId; } #endif - const QVector& getAxes() const { return _axes; } - const QVector& getButtons() const { return _buttons; } + int getDeviceID() { return _deviceID; } - int getNumAxes() const { return _axes.size(); } - int getNumButtons() const { return _buttons.size(); } - -signals: - void axisValueChanged(int axis, float newValue, float oldValue); - void buttonStateChanged(int button, float newValue, float oldValue); private: #ifdef HAVE_SDL2 SDL_GameController* _sdlGameController; @@ -68,8 +89,12 @@ private: #endif QString _name; - QVector _axes; - QVector _buttons; + +protected: + int _deviceID = 0; + + ButtonPressedMap _buttonPressedMap; + AxisStateMap _axisStateMap; }; -#endif // hifi_JoystickTracker_h +#endif // hifi_Joystick_h diff --git a/interface/src/scripting/JoystickScriptingInterface.cpp b/interface/src/devices/SDL2Manager.cpp similarity index 62% rename from interface/src/scripting/JoystickScriptingInterface.cpp rename to interface/src/devices/SDL2Manager.cpp index 0490b1f704..32408fce18 100644 --- a/interface/src/scripting/JoystickScriptingInterface.cpp +++ b/interface/src/devices/SDL2Manager.cpp @@ -1,73 +1,66 @@ // -// JoystickScriptingInterface.cpp +// SDL2Manager.cpp // interface/src/devices // -// Created by Andrzej Kapolka on 5/15/14. -// Copyright 2014 High Fidelity, Inc. +// Created by Sam Gondelman on 6/5/15. +// Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include -#include -#include - -#ifdef HAVE_SDL2 -#include -#undef main -#endif #include #include #include -#include "Application.h" +#include "Application.h" -#include "JoystickScriptingInterface.h" +#include "SDL2Manager.h" #ifdef HAVE_SDL2 -SDL_JoystickID getInstanceId(SDL_GameController* controller) { +SDL_JoystickID SDL2Manager::getInstanceId(SDL_GameController* controller) { SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller); return SDL_JoystickInstanceID(joystick); } #endif -JoystickScriptingInterface& JoystickScriptingInterface::getInstance() { - static JoystickScriptingInterface sharedInstance; - return sharedInstance; -} - -JoystickScriptingInterface::JoystickScriptingInterface() : +SDL2Manager::SDL2Manager() : #ifdef HAVE_SDL2 - _openJoysticks(), +_openJoysticks(), #endif - _isInitialized(false) +_isInitialized(false) { #ifdef HAVE_SDL2 bool initSuccess = (SDL_Init(SDL_INIT_GAMECONTROLLER) == 0); if (initSuccess) { int joystickCount = SDL_NumJoysticks(); - + for (int i = 0; i < joystickCount; i++) { SDL_GameController* controller = SDL_GameControllerOpen(i); if (controller) { SDL_JoystickID id = getInstanceId(controller); - Joystick* joystick = new Joystick(id, SDL_GameControllerName(controller), controller); - _openJoysticks[id] = joystick; + if (!_openJoysticks.contains(id)) { + Joystick* joystick = new Joystick(id, SDL_GameControllerName(controller), controller); + _openJoysticks[id] = joystick; + joystick->registerToUserInputMapper(*Application::getUserInputMapper()); + joystick->assignDefaultInputMapping(*Application::getUserInputMapper()); + emit joystickAdded(joystick); + } } } - + _isInitialized = true; } else { - qDebug() << "Error initializing SDL"; + qDebug() << "Error initializing SDL2 Manager"; } #endif } -JoystickScriptingInterface::~JoystickScriptingInterface() { +SDL2Manager::~SDL2Manager() { #ifdef HAVE_SDL2 qDeleteAll(_openJoysticks); @@ -75,34 +68,25 @@ JoystickScriptingInterface::~JoystickScriptingInterface() { #endif } -const QObjectList JoystickScriptingInterface::getAllJoysticks() const { - QObjectList objectList; -#ifdef HAVE_SDL2 - const QList joystickList = _openJoysticks.values(); - for (int i = 0; i < joystickList.length(); i++) { - objectList << joystickList[i]; - } -#endif - return objectList; +SDL2Manager* SDL2Manager::getInstance() { + static SDL2Manager sharedInstance; + return &sharedInstance; } -Joystick* JoystickScriptingInterface::joystickWithName(const QString& name) { -#ifdef HAVE_SDL2 - QMap::iterator iter = _openJoysticks.begin(); - while (iter != _openJoysticks.end()) { - if (iter.value()->getName() == name) { - return iter.value(); - } - iter++; +void SDL2Manager::focusOutEvent() { + for (auto joystick : _openJoysticks) { + joystick->focusOutEvent(); } -#endif - return NULL; } -void JoystickScriptingInterface::update() { +void SDL2Manager::update() { #ifdef HAVE_SDL2 if (_isInitialized) { - PerformanceTimer perfTimer("JoystickScriptingInterface::update"); + for (auto joystick : _openJoysticks) { + joystick->update(); + } + + PerformanceTimer perfTimer("SDL2Manager::update"); SDL_GameControllerUpdate(); SDL_Event event; while (SDL_PollEvent(&event)) { @@ -120,16 +104,16 @@ void JoystickScriptingInterface::update() { if (event.cbutton.button == SDL_CONTROLLER_BUTTON_BACK) { // this will either start or stop a global back event QEvent::Type backType = (event.type == SDL_CONTROLLERBUTTONDOWN) - ? HFBackEvent::startType() - : HFBackEvent::endType(); + ? HFBackEvent::startType() + : HFBackEvent::endType(); HFBackEvent backEvent(backType); qApp->sendEvent(qApp, &backEvent); } else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_A) { // this will either start or stop a global action event QEvent::Type actionType = (event.type == SDL_CONTROLLERBUTTONDOWN) - ? HFActionEvent::startType() - : HFActionEvent::endType(); + ? HFActionEvent::startType() + : HFActionEvent::endType(); // global action events fire in the center of the screen Application* app = Application::getInstance(); @@ -141,14 +125,19 @@ void JoystickScriptingInterface::update() { } else if (event.type == SDL_CONTROLLERDEVICEADDED) { SDL_GameController* controller = SDL_GameControllerOpen(event.cdevice.which); - + SDL_JoystickID id = getInstanceId(controller); - Joystick* joystick = new Joystick(id, SDL_GameControllerName(controller), controller); - _openJoysticks[id] = joystick; - emit joystickAdded(joystick); + if (!_openJoysticks.contains(id)) { + Joystick* joystick = new Joystick(id, SDL_GameControllerName(controller), controller); + _openJoysticks[id] = joystick; + joystick->registerToUserInputMapper(*Application::getUserInputMapper()); + joystick->assignDefaultInputMapping(*Application::getUserInputMapper()); + emit joystickAdded(joystick); + } } else if (event.type == SDL_CONTROLLERDEVICEREMOVED) { Joystick* joystick = _openJoysticks[event.cdevice.which]; _openJoysticks.remove(event.cdevice.which); + Application::getUserInputMapper()->removeDevice(joystick->getDeviceID()); emit joystickRemoved(joystick); } } diff --git a/interface/src/scripting/JoystickScriptingInterface.h b/interface/src/devices/SDL2Manager.h similarity index 53% rename from interface/src/scripting/JoystickScriptingInterface.h rename to interface/src/devices/SDL2Manager.h index c9a68d24b1..0a32570ee2 100644 --- a/interface/src/scripting/JoystickScriptingInterface.h +++ b/interface/src/devices/SDL2Manager.h @@ -1,77 +1,46 @@ // -// JoystickScriptingInterface.h +// SDL2Manager.h // interface/src/devices // -// Created by Andrzej Kapolka on 5/15/14. -// Copyright 2014 High Fidelity, Inc. +// Created by Sam Gondelman on 6/5/15. +// Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_JoystickScriptingInterface_h -#define hifi_JoystickScriptingInterface_h - -#include -#include +#ifndef hifi__SDL2Manager_h +#define hifi__SDL2Manager_h #ifdef HAVE_SDL2 #include #endif +#include "ui/UserInputMapper.h" + #include "devices/Joystick.h" -/// Handles joystick input through SDL. -class JoystickScriptingInterface : public QObject { +class SDL2Manager : public QObject { Q_OBJECT - -#ifdef HAVE_SDL2 - Q_PROPERTY(int AXIS_INVALID READ axisInvalid) - Q_PROPERTY(int AXIS_LEFT_X READ axisLeftX) - Q_PROPERTY(int AXIS_LEFT_Y READ axisLeftY) - Q_PROPERTY(int AXIS_RIGHT_X READ axisRightX) - Q_PROPERTY(int AXIS_RIGHT_Y READ axisRightY) - Q_PROPERTY(int AXIS_TRIGGER_LEFT READ axisTriggerLeft) - Q_PROPERTY(int AXIS_TRIGGER_RIGHT READ axisTriggerRight) - Q_PROPERTY(int AXIS_MAX READ axisMax) - - Q_PROPERTY(int BUTTON_INVALID READ buttonInvalid) - Q_PROPERTY(int BUTTON_FACE_BOTTOM READ buttonFaceBottom) - Q_PROPERTY(int BUTTON_FACE_RIGHT READ buttonFaceRight) - Q_PROPERTY(int BUTTON_FACE_LEFT READ buttonFaceLeft) - Q_PROPERTY(int BUTTON_FACE_TOP READ buttonFaceTop) - Q_PROPERTY(int BUTTON_BACK READ buttonBack) - Q_PROPERTY(int BUTTON_GUIDE READ buttonGuide) - Q_PROPERTY(int BUTTON_START READ buttonStart) - Q_PROPERTY(int BUTTON_LEFT_STICK READ buttonLeftStick) - Q_PROPERTY(int BUTTON_RIGHT_STICK READ buttonRightStick) - Q_PROPERTY(int BUTTON_LEFT_SHOULDER READ buttonLeftShoulder) - Q_PROPERTY(int BUTTON_RIGHT_SHOULDER READ buttonRightShoulder) - Q_PROPERTY(int BUTTON_DPAD_UP READ buttonDpadUp) - Q_PROPERTY(int BUTTON_DPAD_DOWN READ buttonDpadDown) - Q_PROPERTY(int BUTTON_DPAD_LEFT READ buttonDpadLeft) - Q_PROPERTY(int BUTTON_DPAD_RIGHT READ buttonDpadRight) - Q_PROPERTY(int BUTTON_MAX READ buttonMax) - - Q_PROPERTY(int BUTTON_PRESSED READ buttonPressed) - Q_PROPERTY(int BUTTON_RELEASED READ buttonRelease) -#endif - + public: - static JoystickScriptingInterface& getInstance(); - + SDL2Manager(); + ~SDL2Manager(); + + void focusOutEvent(); + void update(); - -public slots: - Joystick* joystickWithName(const QString& name); - const QObjectList getAllJoysticks() const; - + + static SDL2Manager* getInstance(); + signals: void joystickAdded(Joystick* joystick); void joystickRemoved(Joystick* joystick); - + private: #ifdef HAVE_SDL2 + SDL_JoystickID getInstanceId(SDL_GameController* controller); + int axisInvalid() const { return SDL_CONTROLLER_AXIS_INVALID; } int axisLeftX() const { return SDL_CONTROLLER_AXIS_LEFTX; } int axisLeftY() const { return SDL_CONTROLLER_AXIS_LEFTY; } @@ -80,7 +49,7 @@ private: int axisTriggerLeft() const { return SDL_CONTROLLER_AXIS_TRIGGERLEFT; } int axisTriggerRight() const { return SDL_CONTROLLER_AXIS_TRIGGERRIGHT; } int axisMax() const { return SDL_CONTROLLER_AXIS_MAX; } - + int buttonInvalid() const { return SDL_CONTROLLER_BUTTON_INVALID; } int buttonFaceBottom() const { return SDL_CONTROLLER_BUTTON_A; } int buttonFaceRight() const { return SDL_CONTROLLER_BUTTON_B; } @@ -98,18 +67,15 @@ private: int buttonDpadLeft() const { return SDL_CONTROLLER_BUTTON_DPAD_LEFT; } int buttonDpadRight() const { return SDL_CONTROLLER_BUTTON_DPAD_RIGHT; } int buttonMax() const { return SDL_CONTROLLER_BUTTON_MAX; } - + int buttonPressed() const { return SDL_PRESSED; } int buttonRelease() const { return SDL_RELEASED; } #endif - - JoystickScriptingInterface(); - ~JoystickScriptingInterface(); - + #ifdef HAVE_SDL2 QMap _openJoysticks; #endif bool _isInitialized; }; -#endif // hifi_JoystickScriptingInterface_h +#endif // hifi__SDL2Manager_h diff --git a/interface/src/ui/UserInputMapper.cpp b/interface/src/ui/UserInputMapper.cpp index e994b3cf30..2c28b79c75 100755 --- a/interface/src/ui/UserInputMapper.cpp +++ b/interface/src/ui/UserInputMapper.cpp @@ -106,6 +106,11 @@ void UserInputMapper::removeAllInputChannelsForDevice(uint16 device) { } } +void UserInputMapper::removeDevice(int device) { + removeAllInputChannelsForDevice((uint16) device); + _registeredDevices.erase(device); +} + int UserInputMapper::getInputChannels(InputChannels& channels) const { for (auto& channel : _actionToInputsMap) { channels.push_back(channel.second); diff --git a/interface/src/ui/UserInputMapper.h b/interface/src/ui/UserInputMapper.h index 0a08e277db..84ca192e3e 100755 --- a/interface/src/ui/UserInputMapper.h +++ b/interface/src/ui/UserInputMapper.h @@ -189,6 +189,7 @@ public: bool removeInputChannel(InputChannel channel); void removeAllInputChannels(); void removeAllInputChannelsForDevice(uint16 device); + void removeDevice(int device); //Grab all the input channels currently in use, return the number int getInputChannels(InputChannels& channels) const; QVector getAllInputsForDevice(uint16 device); From 2bdef6205e5d99f4b7fad1f9fed3dd51ad4b35dd Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Thu, 11 Jun 2015 16:20:46 -0700 Subject: [PATCH 02/12] added more available inputs to joystick and keyboardmousedevice --- interface/src/devices/Joystick.cpp | 10 +++++++ interface/src/devices/KeyboardMouseDevice.cpp | 26 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index 659e5fa175..43dc50b252 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -109,6 +109,16 @@ void Joystick::registerToUserInputMapper(UserInputMapper& mapper) { availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_LEFTSHOULDER), "L1")); availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), "R1")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_Y_NEG), "Left Stick Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_Y_POS), "Left Stick Down")); + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_X_POS), "Left Stick Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_X_NEG), "Left Stick Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_AXIS_Y_NEG), "Right Stick Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_AXIS_Y_POS), "Right Stick Down")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_AXIS_X_POS), "Right Stick Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_AXIS_X_NEG), "Right Stick Left")); + #endif return availableInputs; }; diff --git a/interface/src/devices/KeyboardMouseDevice.cpp b/interface/src/devices/KeyboardMouseDevice.cpp index 8a336064e5..5f18c02c7e 100755 --- a/interface/src/devices/KeyboardMouseDevice.cpp +++ b/interface/src/devices/KeyboardMouseDevice.cpp @@ -170,7 +170,33 @@ void KeyboardMouseDevice::registerToUserInputMapper(UserInputMapper& mapper) { for (int i = (int) Qt::Key_A; i <= (int) Qt::Key_Z; i++) { availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::Key(i)), QKeySequence(Qt::Key(i)).toString())); } + for (int i = (int) Qt::Key_Left; i <= (int) Qt::Key_Down; i++) { + availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::Key(i)), QKeySequence(Qt::Key(i)).toString())); + } availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::Key_Space), QKeySequence(Qt::Key_Space).toString())); + availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::Key_Shift), "Shift")); + availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::Key_PageUp), QKeySequence(Qt::Key_PageUp).toString())); + availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::Key_PageDown), QKeySequence(Qt::Key_PageDown).toString())); + + availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::LeftButton), "Left Mouse Click")); + availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::MiddleButton), "Middle Mouse Click")); + availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::RightButton), "Right Mouse Click")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_X_POS), "Mouse Move Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_X_NEG), "Mouse Move Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_Y_POS), "Mouse Move Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_Y_NEG), "Mouse Move Down")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_WHEEL_Y_POS), "Mouse Wheel Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_WHEEL_Y_NEG), "Mouse Wheel Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_WHEEL_X_POS), "Mouse Wheel Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_WHEEL_X_NEG), "Mouse Wheel Down")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(TOUCH_AXIS_X_POS), "Touchpad Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(TOUCH_AXIS_X_NEG), "Touchpad Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(TOUCH_AXIS_Y_POS), "Touchpad Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(TOUCH_AXIS_Y_NEG), "Touchpad Down")); + return availableInputs; }; proxy->resetDeviceBindings = [this, &mapper] () -> bool { From 72cc070f0a7df6f1d5d6e5f020dc60fbc482c919 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Thu, 11 Jun 2015 18:24:32 -0700 Subject: [PATCH 03/12] enabled remappable zooming (with keyboard: shift + w, shift + s, and others), switches to first person if you zoom in a lot --- interface/src/Application.cpp | 15 +++++++++++---- interface/src/avatar/Avatar.h | 2 ++ interface/src/avatar/MyAvatar.cpp | 8 ++++++++ interface/src/avatar/MyAvatar.h | 9 +++++++++ interface/src/devices/KeyboardMouseDevice.cpp | 14 +++++++------- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e126882004..f66980ab71 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -193,7 +193,6 @@ const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::D const QString DEFAULT_SCRIPTS_JS_URL = "http://s3.amazonaws.com/hifi-public/scripts/defaultScripts.js"; Setting::Handle maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS); - #ifdef Q_OS_WIN class MyNativeEventFilter : public QAbstractNativeEventFilter { public: @@ -881,6 +880,10 @@ void Application::paintGL() { } glEnable(GL_LINE_SMOOTH); + + const float CAMERA_PERSON_THRESHOLD = MyAvatar::ZOOM_MIN * _myAvatar->getScale(); + Menu::getInstance()->setIsOptionChecked("First Person", _myAvatar->getBoomLength() * _myAvatar->getScale() <= CAMERA_PERSON_THRESHOLD); + Application::getInstance()->cameraMenuChanged(); if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { // Always use the default eye position, not the actual head eye position. @@ -899,9 +902,8 @@ void Application::paintGL() { } } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - static const float THIRD_PERSON_CAMERA_DISTANCE = 1.5f; _myCamera.setPosition(_myAvatar->getDefaultEyePosition() + - _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, 1.0f) * THIRD_PERSON_CAMERA_DISTANCE * _myAvatar->getScale()); + _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, 1.0f) * _myAvatar->getBoomLength() * _myAvatar->getScale()); if (OculusManager::isConnected()) { _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation()); } else { @@ -2370,10 +2372,14 @@ void Application::cameraMenuChanged() { } else if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) { if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); + _myAvatar->setBoomLength(MyAvatar::ZOOM_MIN); } } else { if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); + if (_myAvatar->getBoomLength() == MyAvatar::ZOOM_MIN) { + _myAvatar->setBoomLength(MyAvatar::ZOOM_DEFAULT); + } } } } @@ -2472,7 +2478,8 @@ void Application::update(float deltaTime) { _myAvatar->setDriveKeys(ROT_DOWN, _userInputMapper.getActionState(UserInputMapper::PITCH_DOWN)); _myAvatar->setDriveKeys(ROT_LEFT, _userInputMapper.getActionState(UserInputMapper::YAW_LEFT)); _myAvatar->setDriveKeys(ROT_RIGHT, _userInputMapper.getActionState(UserInputMapper::YAW_RIGHT)); - + _myAvatar->setDriveKeys(BOOM_IN, _userInputMapper.getActionState(UserInputMapper::BOOM_IN)); + _myAvatar->setDriveKeys(BOOM_OUT, _userInputMapper.getActionState(UserInputMapper::BOOM_OUT)); updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process... diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index b198d12a6e..2590808347 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -52,6 +52,8 @@ enum DriveKeys { ROT_RIGHT, ROT_UP, ROT_DOWN, + BOOM_IN, + BOOM_OUT, MAX_DRIVE_KEYS }; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c4e08b5dba..6fe99b89e4 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -70,6 +70,10 @@ const int SCRIPTED_MOTOR_CAMERA_FRAME = 0; const int SCRIPTED_MOTOR_AVATAR_FRAME = 1; const int SCRIPTED_MOTOR_WORLD_FRAME = 2; +const float MyAvatar::ZOOM_MIN = .5f; +const float MyAvatar::ZOOM_MAX = 10.0f; +const float MyAvatar::ZOOM_DEFAULT = 1.5f; + MyAvatar::MyAvatar() : Avatar(), _turningKeyPressTime(0.0f), @@ -77,6 +81,7 @@ MyAvatar::MyAvatar() : _wasPushing(false), _isPushing(false), _isBraking(false), + _boomLength(ZOOM_DEFAULT), _trapDuration(0.0f), _thrust(0.0f), _keyboardMotorVelocity(0.0f), @@ -1347,6 +1352,9 @@ glm::vec3 MyAvatar::applyKeyboardMotor(float deltaTime, const glm::vec3& localVe } } } + + _boomLength += _driveKeys[BOOM_OUT] - _driveKeys[BOOM_IN]; + _boomLength = glm::clamp(_boomLength, ZOOM_MIN, ZOOM_MAX); return newLocalVelocity; } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index a3dc34e6e0..7adaf908f4 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -162,6 +162,13 @@ public: const RecorderPointer getRecorder() const { return _recorder; } const PlayerPointer getPlayer() const { return _player; } + float getBoomLength() const { return _boomLength; } + void setBoomLength(float boomLength) { _boomLength = boomLength; } + + static const float ZOOM_MIN; + static const float ZOOM_MAX; + static const float ZOOM_DEFAULT; + public slots: void increaseSize(); void decreaseSize(); @@ -210,6 +217,8 @@ private: bool _wasPushing; bool _isPushing; bool _isBraking; + + float _boomLength; float _trapDuration; // seconds that avatar has been trapped by collisions glm::vec3 _thrust; // impulse accumulator for outside sources diff --git a/interface/src/devices/KeyboardMouseDevice.cpp b/interface/src/devices/KeyboardMouseDevice.cpp index 5f18c02c7e..aeeb2480e7 100755 --- a/interface/src/devices/KeyboardMouseDevice.cpp +++ b/interface/src/devices/KeyboardMouseDevice.cpp @@ -215,7 +215,7 @@ void KeyboardMouseDevice::assignDefaultInputMapping(UserInputMapper& mapper) { const float MOUSE_PITCH_SPEED = 0.25f; const float TOUCH_YAW_SPEED = 0.5f; const float TOUCH_PITCH_SPEED = 0.25f; - //const float BUTTON_BOOM_SPEED = 0.1f; + const float BUTTON_BOOM_SPEED = 0.1f; // AWSD keys mapping mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(Qt::Key_S), BUTTON_MOVE_SPEED); @@ -225,8 +225,8 @@ void KeyboardMouseDevice::assignDefaultInputMapping(UserInputMapper& mapper) { mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(Qt::Key_C), BUTTON_MOVE_SPEED); mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(Qt::Key_E), BUTTON_MOVE_SPEED); - // mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(Qt::Key_W), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); - // mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(Qt::Key_S), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(Qt::Key_W), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(Qt::Key_S), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(Qt::Key_A), makeInput(Qt::RightButton), BUTTON_YAW_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(Qt::Key_D), makeInput(Qt::RightButton), BUTTON_YAW_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(Qt::Key_A), makeInput(Qt::Key_Shift), BUTTON_YAW_SPEED); @@ -242,8 +242,8 @@ void KeyboardMouseDevice::assignDefaultInputMapping(UserInputMapper& mapper) { mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(Qt::Key_PageDown), BUTTON_MOVE_SPEED); mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(Qt::Key_PageUp), BUTTON_MOVE_SPEED); - // mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(Qt::Key_Up), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); - // mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(Qt::Key_Down), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(Qt::Key_Up), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(Qt::Key_Down), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(Qt::Key_Left), makeInput(Qt::RightButton), BUTTON_YAW_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(Qt::Key_Right), makeInput(Qt::RightButton), BUTTON_YAW_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(Qt::Key_Left), makeInput(Qt::Key_Shift), BUTTON_YAW_SPEED); @@ -272,8 +272,8 @@ void KeyboardMouseDevice::assignDefaultInputMapping(UserInputMapper& mapper) { mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(TOUCH_AXIS_X_POS), TOUCH_YAW_SPEED); // Wheel move - //mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(MOUSE_AXIS_WHEEL_Y_NEG), BUTTON_BOOM_SPEED); - //mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(MOUSE_AXIS_WHEEL_Y_POS), BUTTON_BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(MOUSE_AXIS_WHEEL_Y_NEG), BUTTON_BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(MOUSE_AXIS_WHEEL_Y_POS), BUTTON_BOOM_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(MOUSE_AXIS_WHEEL_X_NEG), BUTTON_YAW_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(MOUSE_AXIS_WHEEL_X_POS), BUTTON_YAW_SPEED); From b4e108cd3bcf288f9a09e731dd92639d7c8a1772 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Fri, 12 Jun 2015 10:16:00 -0700 Subject: [PATCH 04/12] added zooming to default joystick controls --- interface/src/Application.cpp | 3 +- interface/src/devices/Joystick.cpp | 47 +++++++++++++++++++++--------- interface/src/devices/Joystick.h | 2 ++ 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f66980ab71..a3b226dafc 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -881,8 +881,7 @@ void Application::paintGL() { glEnable(GL_LINE_SMOOTH); - const float CAMERA_PERSON_THRESHOLD = MyAvatar::ZOOM_MIN * _myAvatar->getScale(); - Menu::getInstance()->setIsOptionChecked("First Person", _myAvatar->getBoomLength() * _myAvatar->getScale() <= CAMERA_PERSON_THRESHOLD); + Menu::getInstance()->setIsOptionChecked("First Person", _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); Application::getInstance()->cameraMenuChanged(); if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index 43dc50b252..cf1e6bce47 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -59,20 +59,30 @@ void Joystick::focusOutEvent() { void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) { SDL_GameControllerAxis axis = (SDL_GameControllerAxis) event.axis; - if (axis == SDL_CONTROLLER_AXIS_LEFTX) { - _axisStateMap[makeInput(LEFT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(LEFT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; - } else if (axis == SDL_CONTROLLER_AXIS_LEFTY) { - _axisStateMap[makeInput(LEFT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(LEFT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; - } else if (axis == SDL_CONTROLLER_AXIS_RIGHTX) { - _axisStateMap[makeInput(RIGHT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(RIGHT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; - } else if (axis == SDL_CONTROLLER_AXIS_RIGHTY) { - _axisStateMap[makeInput(RIGHT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(RIGHT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + switch (axis) { + case SDL_CONTROLLER_AXIS_LEFTX: + _axisStateMap[makeInput(LEFT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + break; + case SDL_CONTROLLER_AXIS_LEFTY: + _axisStateMap[makeInput(LEFT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + break; + case SDL_CONTROLLER_AXIS_RIGHTX: + _axisStateMap[makeInput(RIGHT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + break; + case SDL_CONTROLLER_AXIS_RIGHTY: + _axisStateMap[makeInput(RIGHT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + break; + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: + _axisStateMap[makeInput(RIGHT_SHOULDER).getChannel()] = event.value / MAX_AXIS; + break; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: + _axisStateMap[makeInput(LEFT_SHOULDER).getChannel()] = event.value / MAX_AXIS; + break; } - } void Joystick::handleButtonEvent(const SDL_ControllerButtonEvent& event) { @@ -109,6 +119,8 @@ void Joystick::registerToUserInputMapper(UserInputMapper& mapper) { availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_LEFTSHOULDER), "L1")); availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), "R1")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_SHOULDER), "L2")); + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_SHOULDER), "R2")); availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_Y_NEG), "Left Stick Up")); availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_Y_POS), "Left Stick Down")); @@ -136,6 +148,7 @@ void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) { const float DPAD_MOVE_SPEED = .5f; const float JOYSTICK_YAW_SPEED = 0.5f; const float JOYSTICK_PITCH_SPEED = 0.25f; + const float BOOM_SPEED = 0.1f; // Y axes are flipped (up is negative) // Left Joystick: Movement, strafing @@ -162,6 +175,10 @@ void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) { mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(SDL_CONTROLLER_BUTTON_X), JOYSTICK_YAW_SPEED); mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_B), JOYSTICK_YAW_SPEED); + // Zoom + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(RIGHT_SHOULDER), BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(LEFT_SHOULDER), BOOM_SPEED); + // Hold front right shoulder button for precision controls // Left Joystick: Movement, strafing @@ -187,6 +204,10 @@ void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) { mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(SDL_CONTROLLER_BUTTON_A), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(SDL_CONTROLLER_BUTTON_X), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_B), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); + + // Zoom + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(RIGHT_SHOULDER), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), BOOM_SPEED/2.); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(LEFT_SHOULDER), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), BOOM_SPEED/2.); #endif } diff --git a/interface/src/devices/Joystick.h b/interface/src/devices/Joystick.h index c5ca7a6f7f..c546a82aaa 100644 --- a/interface/src/devices/Joystick.h +++ b/interface/src/devices/Joystick.h @@ -41,6 +41,8 @@ public: RIGHT_AXIS_X_NEG, RIGHT_AXIS_Y_POS, RIGHT_AXIS_Y_NEG, + RIGHT_SHOULDER, + LEFT_SHOULDER, }; Joystick(); From 1a8df6509fcffe9015573d55051871701682cbdd Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Fri, 12 Jun 2015 18:22:56 -0700 Subject: [PATCH 05/12] userinputmapper supports hydra, but some hydra events still register as mouse events --- interface/src/Application.cpp | 1 + interface/src/devices/Joystick.cpp | 6 +- interface/src/devices/KeyboardMouseDevice.cpp | 4 +- interface/src/devices/SixenseManager.cpp | 149 +++++++++++++++++- interface/src/devices/SixenseManager.h | 34 ++++ 5 files changed, 189 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a3b226dafc..a1ab6d35ae 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1456,6 +1456,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) { void Application::focusOutEvent(QFocusEvent* event) { _keyboardMouseDevice.focusOutEvent(event); + SixenseManager::getInstance().focusOutEvent(); SDL2Manager::getInstance()->focusOutEvent(); // synthesize events for keys currently pressed, since we may not get their release events diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index cf1e6bce47..5d7e51b103 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -82,6 +82,8 @@ void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) { case SDL_CONTROLLER_AXIS_TRIGGERLEFT: _axisStateMap[makeInput(LEFT_SHOULDER).getChannel()] = event.value / MAX_AXIS; break; + default: + break; } } @@ -102,8 +104,8 @@ void Joystick::registerToUserInputMapper(UserInputMapper& mapper) { _deviceID = mapper.getFreeDeviceID(); auto proxy = UserInputMapper::DeviceProxy::Pointer(new UserInputMapper::DeviceProxy(_name)); - proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input._channel); }; - proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input._channel); }; + proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input.getChannel()); }; + proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input.getChannel()); }; proxy->getAvailabeInputs = [this] () -> QVector { QVector availableInputs; #ifdef HAVE_SDL2 diff --git a/interface/src/devices/KeyboardMouseDevice.cpp b/interface/src/devices/KeyboardMouseDevice.cpp index aeeb2480e7..fcb60cca26 100755 --- a/interface/src/devices/KeyboardMouseDevice.cpp +++ b/interface/src/devices/KeyboardMouseDevice.cpp @@ -160,8 +160,8 @@ void KeyboardMouseDevice::registerToUserInputMapper(UserInputMapper& mapper) { _deviceID = mapper.getFreeDeviceID(); auto proxy = UserInputMapper::DeviceProxy::Pointer(new UserInputMapper::DeviceProxy("Keyboard")); - proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input._channel); }; - proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input._channel); }; + proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input.getChannel()); }; + proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input.getChannel()); }; proxy->getAvailabeInputs = [this] () -> QVector { QVector availableInputs; for (int i = (int) Qt::Key_0; i <= (int) Qt::Key_9; i++) { diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index f1a762e64f..54cf202838 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -38,6 +38,10 @@ typedef int (*SixenseTakeIntFunction)(int); typedef int (*SixenseTakeIntAndSixenseControllerData)(int, sixenseControllerData*); #endif +// These bits aren't used for buttons, so they can be used as masks: +const unsigned int LEFT_MASK = 0; +const unsigned int RIGHT_MASK = 1U << 1; + #endif SixenseManager& SixenseManager::getInstance() { @@ -147,6 +151,7 @@ void SixenseManager::update(float deltaTime) { #ifdef HAVE_SIXENSE Hand* hand = DependencyManager::get()->getMyAvatar()->getHand(); if (_isInitialized && _isEnabled) { + _buttonPressedMap.clear(); #ifdef __APPLE__ SixenseBaseFunction sixenseGetNumActiveControllers = (SixenseBaseFunction) _sixenseLibrary->resolve("sixenseGetNumActiveControllers"); @@ -154,12 +159,18 @@ void SixenseManager::update(float deltaTime) { if (sixenseGetNumActiveControllers() == 0) { _hydrasConnected = false; + if (_deviceID) { + Application::getUserInputMapper()->removeDevice(_deviceID); + _deviceID = 0; + } return; } PerformanceTimer perfTimer("sixense"); if (!_hydrasConnected) { _hydrasConnected = true; + registerToUserInputMapper(*Application::getUserInputMapper()); + getInstance().assignDefaultInputMapping(*Application::getUserInputMapper()); UserActivityLogger::getInstance().connectedDevice("spatial_controller", "hydra"); } @@ -216,12 +227,14 @@ void SixenseManager::update(float deltaTime) { palm->setActive(false); // if this isn't a Sixsense ID palm, always make it inactive } - // Read controller buttons and joystick into the hand palm->setControllerButtons(data->buttons); palm->setTrigger(data->trigger); palm->setJoystick(data->joystick_x, data->joystick_y); + handleButtonEvent(data->buttons, numActiveControllers - 1); + handleAxisEvent(data->joystick_x, data->joystick_y, data->trigger, numActiveControllers - 1); + // Emulate the mouse so we can use scripts if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput) && !_controllersAtBase) { emulateMouse(palm, numActiveControllers - 1); @@ -590,3 +603,137 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) { #endif // HAVE_SIXENSE +void SixenseManager::focusOutEvent() { + _axisStateMap.clear(); + _buttonPressedMap.clear(); +}; + +void SixenseManager::handleAxisEvent(float stickX, float stickY, float trigger, int index) { + _axisStateMap[makeInput(AXIS_Y_POS, index).getChannel()] = (stickY > 0) ? stickY : 0.0f; + _axisStateMap[makeInput(AXIS_Y_NEG, index).getChannel()] = (stickY < 0) ? -stickY : 0.0f; + _axisStateMap[makeInput(AXIS_X_POS, index).getChannel()] = (stickX > 0) ? stickX : 0.0f; + _axisStateMap[makeInput(AXIS_X_NEG, index).getChannel()] = (stickX < 0) ? -stickX : 0.0f; + _axisStateMap[makeInput(BACK_TRIGGER, index).getChannel()] = trigger; +} + +void SixenseManager::handleButtonEvent(unsigned int buttons, int index) { + if (buttons & BUTTON_0) { + _buttonPressedMap.insert(makeInput(BUTTON_0, index).getChannel()); + } + if (buttons & BUTTON_1) { + _buttonPressedMap.insert(makeInput(BUTTON_1, index).getChannel()); + } + if (buttons & BUTTON_2) { + _buttonPressedMap.insert(makeInput(BUTTON_2, index).getChannel()); + } + if (buttons & BUTTON_3) { + _buttonPressedMap.insert(makeInput(BUTTON_3, index).getChannel()); + } + if (buttons & BUTTON_4) { + _buttonPressedMap.insert(makeInput(BUTTON_4, index).getChannel()); + } + if (buttons & BUTTON_FWD) { + _buttonPressedMap.insert(makeInput(BUTTON_FWD, index).getChannel()); + } +} + +void SixenseManager::registerToUserInputMapper(UserInputMapper& mapper) { + // Grab the current free device ID + _deviceID = mapper.getFreeDeviceID(); + + auto proxy = UserInputMapper::DeviceProxy::Pointer(new UserInputMapper::DeviceProxy("Hydra")); + proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input.getChannel()); }; + proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input.getChannel()); }; + proxy->getAvailabeInputs = [this] () -> QVector { + QVector availableInputs; + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_0, 0), "Left Start")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_1, 0), "Left Button 1")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_2, 0), "Left Button 2")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_3, 0), "Left Button 3")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_4, 0), "Left Button 4")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_FWD, 0), "L1")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BACK_TRIGGER, 0), "L2")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_POS, 0), "Left Stick Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_NEG, 0), "Left Stick Down")); + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_POS, 0), "Left Stick Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_NEG, 0), "Left Stick Left")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_0, 1), "Right Start")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_1, 1), "Right Button 1")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_2, 1), "Right Button 2")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_3, 1), "Right Button 3")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_4, 1), "Right Button 4")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_FWD, 1), "R1")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BACK_TRIGGER, 1), "R2")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_POS, 1), "Right Stick Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_NEG, 1), "Right Stick Down")); + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_POS, 1), "Right Stick Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_NEG, 1), "Right Stick Left")); + return availableInputs; + }; + proxy->resetDeviceBindings = [this, &mapper] () -> bool { + mapper.removeAllInputChannelsForDevice(_deviceID); + this->assignDefaultInputMapping(mapper); + return true; + }; + mapper.registerDevice(_deviceID, proxy); +} + +void SixenseManager::assignDefaultInputMapping(UserInputMapper& mapper) { + const float JOYSTICK_MOVE_SPEED = 1.0f; + const float JOYSTICK_YAW_SPEED = 0.5f; + const float JOYSTICK_PITCH_SPEED = 0.25f; + const float BUTTON_MOVE_SPEED = 1.0f; + const float BOOM_SPEED = .1f; + + // Left Joystick: Movement, strafing + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(AXIS_Y_POS, 0), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(AXIS_Y_NEG, 0), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(AXIS_X_POS, 0), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(AXIS_X_NEG, 0), JOYSTICK_MOVE_SPEED); + + // Right Joystick: Camera orientation + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(AXIS_X_POS, 1), JOYSTICK_YAW_SPEED); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(AXIS_X_NEG, 1), JOYSTICK_YAW_SPEED); + mapper.addInputChannel(UserInputMapper::PITCH_UP, makeInput(AXIS_Y_POS, 1), JOYSTICK_PITCH_SPEED); + mapper.addInputChannel(UserInputMapper::PITCH_DOWN, makeInput(AXIS_Y_NEG, 1), JOYSTICK_PITCH_SPEED); + + // Buttons + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(BUTTON_3, 0), BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(BUTTON_1, 0), BOOM_SPEED); + + mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(BUTTON_3, 1), BUTTON_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(BUTTON_1, 1), BUTTON_MOVE_SPEED); +} + +float SixenseManager::getButton(int channel) const { + if (!_buttonPressedMap.empty()) { + if (_buttonPressedMap.find(channel) != _buttonPressedMap.end()) { + return 1.0f; + } else { + return 0.0f; + } + } + return 0.0f; +} + +float SixenseManager::getAxis(int channel) const { + auto axis = _axisStateMap.find(channel); + if (axis != _axisStateMap.end()) { + return (*axis).second; + } else { + return 0.0f; + } +} + +UserInputMapper::Input SixenseManager::makeInput(unsigned int button, int index) { + return UserInputMapper::Input(_deviceID, button | (index == 0 ? LEFT_MASK : RIGHT_MASK), UserInputMapper::ChannelType::BUTTON); +} + +UserInputMapper::Input SixenseManager::makeInput(SixenseManager::JoystickAxisChannel axis, int index) { + return UserInputMapper::Input(_deviceID, axis | (index == 0 ? LEFT_MASK : RIGHT_MASK), UserInputMapper::ChannelType::AXIS); +} diff --git a/interface/src/devices/SixenseManager.h b/interface/src/devices/SixenseManager.h index 6f47f2fac9..2ca6b0fb5b 100644 --- a/interface/src/devices/SixenseManager.h +++ b/interface/src/devices/SixenseManager.h @@ -13,6 +13,7 @@ #define hifi_SixenseManager_h #include +#include #ifdef HAVE_SIXENSE #include @@ -25,6 +26,8 @@ #endif +#include "ui/UserInputMapper.h" + class PalmData; const unsigned int BUTTON_0 = 1U << 0; // the skinny button between 1 and 2 @@ -45,6 +48,14 @@ const bool DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS = false; class SixenseManager : public QObject { Q_OBJECT public: + enum JoystickAxisChannel { + AXIS_Y_POS = 1U << 0, + AXIS_Y_NEG = 1U << 3, + AXIS_X_POS = 1U << 4, + AXIS_X_NEG = 1U << 5, + BACK_TRIGGER = 1U << 6, + }; + static SixenseManager& getInstance(); void initialize(); @@ -60,6 +71,21 @@ public: bool getInvertButtons() const { return _invertButtons; } void setInvertButtons(bool invertSixenseButtons) { _invertButtons = invertSixenseButtons; } + typedef std::unordered_set ButtonPressedMap; + typedef std::map AxisStateMap; + + float getButton(int channel) const; + float getAxis(int channel) const; + + UserInputMapper::Input makeInput(unsigned int button, int index); + UserInputMapper::Input makeInput(JoystickAxisChannel axis, int index); + + void registerToUserInputMapper(UserInputMapper& mapper); + void assignDefaultInputMapping(UserInputMapper& mapper); + + void update(); + void focusOutEvent(); + public slots: void toggleSixense(bool shouldEnable); void setFilter(bool filter); @@ -70,6 +96,8 @@ private: ~SixenseManager(); #ifdef HAVE_SIXENSE + void handleButtonEvent(unsigned int buttons, int index); + void handleAxisEvent(float x, float y, float trigger, int index); void updateCalibration(const sixenseControllerData* controllers); void emulateMouse(PalmData* palm, int index); @@ -110,6 +138,12 @@ private: float _reticleMoveSpeed = DEFAULT_SIXENSE_RETICLE_MOVE_SPEED; bool _invertButtons = DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS; + +protected: + int _deviceID = 0; + + ButtonPressedMap _buttonPressedMap; + AxisStateMap _axisStateMap; }; #endif // hifi_SixenseManager_h From fe576c6bafe98cdcd0432d0d13ca009f77a6e0bc Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Mon, 15 Jun 2015 10:23:24 -0700 Subject: [PATCH 06/12] hands reset when hydras disconnect --- interface/src/devices/SixenseManager.cpp | 10 ++++++++++ interface/src/devices/SixenseManager.h | 1 + 2 files changed, 11 insertions(+) diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 54cf202838..3927850a44 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -65,6 +65,8 @@ SixenseManager::SixenseManager() : _bumperPressed[1] = false; _oldX[1] = -1; _oldY[1] = -1; + _prevPalms[0] = nullptr; + _prevPalms[1] = nullptr; } SixenseManager::~SixenseManager() { @@ -162,6 +164,12 @@ void SixenseManager::update(float deltaTime) { if (_deviceID) { Application::getUserInputMapper()->removeDevice(_deviceID); _deviceID = 0; + if (_prevPalms[0]) { + _prevPalms[0]->setActive(false); + } + if (_prevPalms[1]) { + _prevPalms[1]->setActive(false); + } } return; } @@ -209,6 +217,7 @@ void SixenseManager::update(float deltaTime) { for (size_t j = 0; j < hand->getNumPalms(); j++) { if (hand->getPalms()[j].getSixenseID() == data->controller_index) { palm = &(hand->getPalms()[j]); + _prevPalms[numActiveControllers - 1] = palm; foundHand = true; } } @@ -217,6 +226,7 @@ void SixenseManager::update(float deltaTime) { hand->getPalms().push_back(newPalm); palm = &(hand->getPalms()[hand->getNumPalms() - 1]); palm->setSixenseID(data->controller_index); + _prevPalms[numActiveControllers - 1] = palm; qCDebug(interfaceapp, "Found new Sixense controller, ID %i", data->controller_index); } diff --git a/interface/src/devices/SixenseManager.h b/interface/src/devices/SixenseManager.h index 2ca6b0fb5b..63aa8846ec 100644 --- a/interface/src/devices/SixenseManager.h +++ b/interface/src/devices/SixenseManager.h @@ -132,6 +132,7 @@ private: bool _bumperPressed[2]; int _oldX[2]; int _oldY[2]; + PalmData* _prevPalms[2]; bool _lowVelocityFilter; bool _controllersAtBase; From 40bd747080979be5c69f32a8636c601918cce010 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Mon, 15 Jun 2015 11:13:07 -0700 Subject: [PATCH 07/12] added trigger buttons to hydra, removed hydraMove.js from default scripts --- examples/defaultScripts.js | 1 - interface/src/devices/SixenseManager.cpp | 6 ++++++ interface/src/devices/SixenseManager.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/defaultScripts.js b/examples/defaultScripts.js index 61bed8d9b1..b5e3e3f551 100644 --- a/examples/defaultScripts.js +++ b/examples/defaultScripts.js @@ -11,7 +11,6 @@ Script.load("progress.js"); Script.load("edit.js"); Script.load("selectAudioDevice.js"); -Script.load("controllers/hydra/hydraMove.js"); Script.load("inspect.js"); Script.load("lobby.js"); Script.load("notifications.js"); diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 3927850a44..18c7365ef8 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -645,6 +645,9 @@ void SixenseManager::handleButtonEvent(unsigned int buttons, int index) { if (buttons & BUTTON_FWD) { _buttonPressedMap.insert(makeInput(BUTTON_FWD, index).getChannel()); } + if (buttons & BUTTON_TRIGGER) { + _buttonPressedMap.insert(makeInput(BUTTON_TRIGGER, index).getChannel()); + } } void SixenseManager::registerToUserInputMapper(UserInputMapper& mapper) { @@ -669,6 +672,7 @@ void SixenseManager::registerToUserInputMapper(UserInputMapper& mapper) { availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_NEG, 0), "Left Stick Down")); availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_POS, 0), "Left Stick Right")); availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_NEG, 0), "Left Stick Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_TRIGGER, 0), "Left Trigger Press")); availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_0, 1), "Right Start")); availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_1, 1), "Right Button 1")); @@ -683,6 +687,8 @@ void SixenseManager::registerToUserInputMapper(UserInputMapper& mapper) { availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_NEG, 1), "Right Stick Down")); availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_POS, 1), "Right Stick Right")); availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_NEG, 1), "Right Stick Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_TRIGGER, 1), "Right Trigger Press")); + return availableInputs; }; proxy->resetDeviceBindings = [this, &mapper] () -> bool { diff --git a/interface/src/devices/SixenseManager.h b/interface/src/devices/SixenseManager.h index 63aa8846ec..92cc0742d6 100644 --- a/interface/src/devices/SixenseManager.h +++ b/interface/src/devices/SixenseManager.h @@ -36,6 +36,7 @@ const unsigned int BUTTON_2 = 1U << 6; const unsigned int BUTTON_3 = 1U << 3; const unsigned int BUTTON_4 = 1U << 4; const unsigned int BUTTON_FWD = 1U << 7; +const unsigned int BUTTON_TRIGGER = 1U << 8; // Event type that represents using the controller const unsigned int CONTROLLER_0_EVENT = 1500U; From 4090fd6aa1013fb7043e7054d7e7122c0b243eb4 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Mon, 15 Jun 2015 12:53:14 -0700 Subject: [PATCH 08/12] attempt to fix build errors --- interface/src/devices/SixenseManager.cpp | 8 ++++---- interface/src/devices/SixenseManager.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 18c7365ef8..95a622e7ad 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -19,6 +19,10 @@ #include "UserActivityLogger.h" #include "InterfaceLogging.h" +// These bits aren't used for buttons, so they can be used as masks: +const unsigned int LEFT_MASK = 0; +const unsigned int RIGHT_MASK = 1U << 1; + #ifdef HAVE_SIXENSE const int CALIBRATION_STATE_IDLE = 0; @@ -38,10 +42,6 @@ typedef int (*SixenseTakeIntFunction)(int); typedef int (*SixenseTakeIntAndSixenseControllerData)(int, sixenseControllerData*); #endif -// These bits aren't used for buttons, so they can be used as masks: -const unsigned int LEFT_MASK = 0; -const unsigned int RIGHT_MASK = 1U << 1; - #endif SixenseManager& SixenseManager::getInstance() { diff --git a/interface/src/devices/SixenseManager.h b/interface/src/devices/SixenseManager.h index 92cc0742d6..c27b3ca0e2 100644 --- a/interface/src/devices/SixenseManager.h +++ b/interface/src/devices/SixenseManager.h @@ -96,9 +96,9 @@ private: SixenseManager(); ~SixenseManager(); -#ifdef HAVE_SIXENSE void handleButtonEvent(unsigned int buttons, int index); void handleAxisEvent(float x, float y, float trigger, int index); +#ifdef HAVE_SIXENSE void updateCalibration(const sixenseControllerData* controllers); void emulateMouse(PalmData* palm, int index); From 68a08d969df0df898258450a71025b9b7bc3adea Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Tue, 16 Jun 2015 10:19:40 -0700 Subject: [PATCH 09/12] code review fixes --- interface/src/devices/Joystick.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index 5d7e51b103..7525d66d74 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -44,8 +44,8 @@ void Joystick::closeJoystick() { void Joystick::update() { for (auto axisState : _axisStateMap) { - if (axisState.second < CONTROLLER_THRESHOLD && axisState.second > -CONTROLLER_THRESHOLD) { - _axisStateMap[axisState.first] = 0; + if (fabsf(axisState.second) < CONTROLLER_THRESHOLD) { + _axisStateMap[axisState.first] = 0.0f; } } } From 1ecc954656aa8acf41c611bd2884da9557b366ac Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Tue, 16 Jun 2015 10:25:30 -0700 Subject: [PATCH 10/12] coding standard fixes --- interface/src/devices/Joystick.cpp | 4 ++-- interface/src/devices/SixenseManager.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index 7525d66d74..a302becb77 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -17,7 +17,7 @@ #include "Joystick.h" -const float CONTROLLER_THRESHOLD = .25f; +const float CONTROLLER_THRESHOLD = 0.25f; #ifdef HAVE_SDL2 const float MAX_AXIS = 32768.0f; @@ -147,7 +147,7 @@ void Joystick::registerToUserInputMapper(UserInputMapper& mapper) { void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) { #ifdef HAVE_SDL2 const float JOYSTICK_MOVE_SPEED = 1.0f; - const float DPAD_MOVE_SPEED = .5f; + const float DPAD_MOVE_SPEED = 0.5f; const float JOYSTICK_YAW_SPEED = 0.5f; const float JOYSTICK_PITCH_SPEED = 0.25f; const float BOOM_SPEED = 0.1f; diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 95a622e7ad..959a1e147f 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -161,7 +161,7 @@ void SixenseManager::update(float deltaTime) { if (sixenseGetNumActiveControllers() == 0) { _hydrasConnected = false; - if (_deviceID) { + if (_deviceID != 0) { Application::getUserInputMapper()->removeDevice(_deviceID); _deviceID = 0; if (_prevPalms[0]) { @@ -704,7 +704,7 @@ void SixenseManager::assignDefaultInputMapping(UserInputMapper& mapper) { const float JOYSTICK_YAW_SPEED = 0.5f; const float JOYSTICK_PITCH_SPEED = 0.25f; const float BUTTON_MOVE_SPEED = 1.0f; - const float BOOM_SPEED = .1f; + const float BOOM_SPEED = 0.1f; // Left Joystick: Movement, strafing mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(AXIS_Y_POS, 0), JOYSTICK_MOVE_SPEED); From 814e22364ad6fb46c22ebf6f58bc93796e7f4cd0 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Tue, 16 Jun 2015 11:30:28 -0700 Subject: [PATCH 11/12] coding standard fixes --- interface/src/devices/Joystick.cpp | 52 ++++++++++++------------ interface/src/devices/SixenseManager.cpp | 8 ++-- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index a302becb77..07f3c4873c 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -61,20 +61,20 @@ void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) { switch (axis) { case SDL_CONTROLLER_AXIS_LEFTX: - _axisStateMap[makeInput(LEFT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(LEFT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_X_POS).getChannel()] = (event.value > 0.0f) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_X_NEG).getChannel()] = (event.value < 0.0f) ? -event.value / MAX_AXIS : 0.0f; break; case SDL_CONTROLLER_AXIS_LEFTY: - _axisStateMap[makeInput(LEFT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(LEFT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_Y_POS).getChannel()] = (event.value > 0.0f) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_Y_NEG).getChannel()] = (event.value < 0.0f) ? -event.value / MAX_AXIS : 0.0f; break; case SDL_CONTROLLER_AXIS_RIGHTX: - _axisStateMap[makeInput(RIGHT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(RIGHT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_X_POS).getChannel()] = (event.value > 0.0f) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_X_NEG).getChannel()] = (event.value < 0.0f) ? -event.value / MAX_AXIS : 0.0f; break; case SDL_CONTROLLER_AXIS_RIGHTY: - _axisStateMap[makeInput(RIGHT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(RIGHT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_Y_POS).getChannel()] = (event.value > 0.0f) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_Y_NEG).getChannel()] = (event.value < 0.0f) ? -event.value / MAX_AXIS : 0.0f; break; case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: _axisStateMap[makeInput(RIGHT_SHOULDER).getChannel()] = event.value / MAX_AXIS; @@ -184,32 +184,32 @@ void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) { // Hold front right shoulder button for precision controls // Left Joystick: Movement, strafing - mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(LEFT_AXIS_Y_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(LEFT_AXIS_Y_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(LEFT_AXIS_X_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(LEFT_AXIS_X_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(LEFT_AXIS_Y_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(LEFT_AXIS_Y_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(LEFT_AXIS_X_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(LEFT_AXIS_X_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.0f); // Right Joystick: Camera orientation - mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(RIGHT_AXIS_X_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); - mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(RIGHT_AXIS_X_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); - mapper.addInputChannel(UserInputMapper::PITCH_UP, makeInput(RIGHT_AXIS_Y_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_PITCH_SPEED/2.); - mapper.addInputChannel(UserInputMapper::PITCH_DOWN, makeInput(RIGHT_AXIS_Y_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_PITCH_SPEED/2.); + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(RIGHT_AXIS_X_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(RIGHT_AXIS_X_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::PITCH_UP, makeInput(RIGHT_AXIS_Y_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_PITCH_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::PITCH_DOWN, makeInput(RIGHT_AXIS_Y_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_PITCH_SPEED/2.0f); // Dpad movement - mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_UP), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_DOWN), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_RIGHT), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_LEFT), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_UP), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_DOWN), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_RIGHT), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_LEFT), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); // Button controls - mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(SDL_CONTROLLER_BUTTON_Y), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(SDL_CONTROLLER_BUTTON_A), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(SDL_CONTROLLER_BUTTON_X), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); - mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_B), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); + mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(SDL_CONTROLLER_BUTTON_Y), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(SDL_CONTROLLER_BUTTON_A), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(SDL_CONTROLLER_BUTTON_X), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_B), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.0f); // Zoom - mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(RIGHT_SHOULDER), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), BOOM_SPEED/2.); - mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(LEFT_SHOULDER), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), BOOM_SPEED/2.); + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(RIGHT_SHOULDER), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), BOOM_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(LEFT_SHOULDER), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), BOOM_SPEED/2.0f); #endif } diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 959a1e147f..c2a53508e3 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -619,10 +619,10 @@ void SixenseManager::focusOutEvent() { }; void SixenseManager::handleAxisEvent(float stickX, float stickY, float trigger, int index) { - _axisStateMap[makeInput(AXIS_Y_POS, index).getChannel()] = (stickY > 0) ? stickY : 0.0f; - _axisStateMap[makeInput(AXIS_Y_NEG, index).getChannel()] = (stickY < 0) ? -stickY : 0.0f; - _axisStateMap[makeInput(AXIS_X_POS, index).getChannel()] = (stickX > 0) ? stickX : 0.0f; - _axisStateMap[makeInput(AXIS_X_NEG, index).getChannel()] = (stickX < 0) ? -stickX : 0.0f; + _axisStateMap[makeInput(AXIS_Y_POS, index).getChannel()] = (stickY > 0.0f) ? stickY : 0.0f; + _axisStateMap[makeInput(AXIS_Y_NEG, index).getChannel()] = (stickY < 0.0f) ? -stickY : 0.0f; + _axisStateMap[makeInput(AXIS_X_POS, index).getChannel()] = (stickX > 0.0f) ? stickX : 0.0f; + _axisStateMap[makeInput(AXIS_X_NEG, index).getChannel()] = (stickX < 0.0f) ? -stickX : 0.0f; _axisStateMap[makeInput(BACK_TRIGGER, index).getChannel()] = trigger; } From 156adb1a9870bf4ad0021b973f745984c7368dc8 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Tue, 16 Jun 2015 11:34:59 -0700 Subject: [PATCH 12/12] one more coding standard fix --- interface/src/avatar/MyAvatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6fe99b89e4..586e7a1f56 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -70,7 +70,7 @@ const int SCRIPTED_MOTOR_CAMERA_FRAME = 0; const int SCRIPTED_MOTOR_AVATAR_FRAME = 1; const int SCRIPTED_MOTOR_WORLD_FRAME = 2; -const float MyAvatar::ZOOM_MIN = .5f; +const float MyAvatar::ZOOM_MIN = 0.5f; const float MyAvatar::ZOOM_MAX = 10.0f; const float MyAvatar::ZOOM_DEFAULT = 1.5f;