almost finished plugin architecture, general plugin improvements. menu actions don't work all the time, joint controllers need to be handled better, and activate/deactive aren't always called correctly

This commit is contained in:
Anthony J. Thibault 2015-07-16 18:16:59 -07:00
parent 1083534d83
commit 060f6c19a6
20 changed files with 371 additions and 208 deletions

View file

@ -64,6 +64,7 @@
#include <DeferredLightingEffect.h>
#include <DependencyManager.h>
#include <display-plugins/DisplayPlugin.h>
#include <EntityScriptingInterface.h>
#include <ErrorDialog.h>
#include <GlowEffect.h>
@ -74,6 +75,9 @@
#include <HFActionEvent.h>
#include <HFBackEvent.h>
#include <InfoView.h>
#include <input-plugins/InputPlugin.h>
#include <input-plugins/Joystick.h> // this should probably be removed
#include <input-plugins/SixenseManager.h> // this definitely should be removed
#include <LogHandler.h>
#include <MainWindow.h>
#include <MessageDialog.h>
@ -123,9 +127,6 @@
#include "devices/Leapmotion.h"
#include "devices/RealSense.h"
#include "devices/MIDIManager.h"
#include <input-plugins/SDL2Manager.h>
#include <input-plugins/SixenseManager.h>
#include <input-plugins/ViveControllerManager.h>
#include "RenderDeferredTask.h"
#include "scripting/AccountScriptingInterface.h"
#include "scripting/AudioDeviceScriptingInterface.h"
@ -621,9 +622,19 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
auto userInputMapper = DependencyManager::get<UserInputMapper>();
connect(userInputMapper.data(), &UserInputMapper::actionEvent, &_controllerScriptingInterface, &AbstractControllerScriptingInterface::actionEvent);
auto inputPlugins = getInputPlugins();
foreach(auto inputPlugin, inputPlugins) {
QString name = inputPlugin->getName();
if (name == KeyboardMouseDevice::NAME) {
_keyboardMouseDevice = static_cast<KeyboardMouseDevice*>(inputPlugin.data()); // TODO: this seems super hacky
}
}
//updateInputModes(); // TODO: shouldn't have to call this explicitly
// Setup the keyboardMouseDevice and the user input mapper with the default bindings
_keyboardMouseDevice.registerToUserInputMapper(*userInputMapper);
_keyboardMouseDevice.assignDefaultInputMapping(*userInputMapper);
_keyboardMouseDevice->registerToUserInputMapper(*userInputMapper);
_keyboardMouseDevice->assignDefaultInputMapping(*userInputMapper);
// check first run...
if (_firstRun.get()) {
@ -676,11 +687,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
connect(ddeTracker.data(), &FaceTracker::muteToggled, this, &Application::faceTrackerMuteToggled);
#endif
if (ViveControllerManager::getInstance().isSupported()) {
ViveControllerManager::getInstance().init();
ViveControllerManager::getInstance().activate(NULL);
}
_oldHandMouseX[0] = -1;
_oldHandMouseY[0] = -1;
_oldHandMouseX[1] = -1;
@ -771,6 +777,15 @@ Application::~Application() {
getActiveDisplayPlugin()->deactivate();
auto inputPlugins = getInputPlugins();
foreach(auto inputPlugin, inputPlugins) {
QString name = inputPlugin->getName();
QAction* action = Menu::getInstance()->getActionForOption(name);
if (action->isChecked()) {
inputPlugin->deactivate();
}
}
// remove avatars from physics engine
DependencyManager::get<AvatarManager>()->clearOtherAvatars();
_physicsEngine.deleteObjects(DependencyManager::get<AvatarManager>()->getObjectsToDelete());
@ -1344,7 +1359,9 @@ void Application::keyPressEvent(QKeyEvent* event) {
}
if (hasFocus()) {
_keyboardMouseDevice.keyPressEvent(event);
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
_keyboardMouseDevice->keyPressEvent(event);
}
bool isShifted = event->modifiers().testFlag(Qt::ShiftModifier);
bool isMeta = event->modifiers().testFlag(Qt::ControlModifier);
@ -1614,7 +1631,9 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
return;
}
_keyboardMouseDevice.keyReleaseEvent(event);
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
_keyboardMouseDevice->keyReleaseEvent(event);
}
switch (event->key()) {
case Qt::Key_Space: {
@ -1641,10 +1660,14 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
}
void Application::focusOutEvent(QFocusEvent* event) {
_keyboardMouseDevice.pluginFocusOutEvent();
SixenseManager::getInstance().pluginFocusOutEvent();
SDL2Manager::getInstance()->pluginFocusOutEvent();
ViveControllerManager::getInstance().pluginFocusOutEvent();
auto inputPlugins = getInputPlugins();
foreach(auto inputPlugin, inputPlugins) {
QString name = inputPlugin->getName();
QAction* action = Menu::getInstance()->getActionForOption(name);
if (action->isChecked()) {
inputPlugin->pluginFocusOutEvent();
}
}
// synthesize events for keys currently pressed, since we may not get their release events
foreach (int key, _keysPressed) {
@ -1687,7 +1710,9 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
return;
}
_keyboardMouseDevice.mouseMoveEvent(event, deviceID);
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
_keyboardMouseDevice->mouseMoveEvent(event, deviceID);
}
}
@ -1708,7 +1733,9 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
if (hasFocus()) {
_keyboardMouseDevice.mousePressEvent(event);
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
_keyboardMouseDevice->mousePressEvent(event);
}
if (event->button() == Qt::LeftButton) {
_mouseDragStarted = getTrueMouse();
@ -1748,7 +1775,9 @@ void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) {
}
if (hasFocus()) {
_keyboardMouseDevice.mouseReleaseEvent(event);
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
_keyboardMouseDevice->mouseReleaseEvent(event);
}
if (event->button() == Qt::LeftButton) {
_mousePressed = false;
@ -1775,7 +1804,9 @@ void Application::touchUpdateEvent(QTouchEvent* event) {
return;
}
_keyboardMouseDevice.touchUpdateEvent(event);
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
_keyboardMouseDevice->touchUpdateEvent(event);
}
bool validTouch = false;
if (hasFocus()) {
@ -1809,7 +1840,9 @@ void Application::touchBeginEvent(QTouchEvent* event) {
return;
}
_keyboardMouseDevice.touchBeginEvent(event);
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
_keyboardMouseDevice->touchBeginEvent(event);
}
}
@ -1824,7 +1857,9 @@ void Application::touchEndEvent(QTouchEvent* event) {
return;
}
_keyboardMouseDevice.touchEndEvent(event);
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
_keyboardMouseDevice->touchEndEvent(event);
}
// put any application specific touch behavior below here..
_touchDragStartedAvg = _touchAvg;
@ -1840,8 +1875,10 @@ void Application::wheelEvent(QWheelEvent* event) {
if (_controllerScriptingInterface.isWheelCaptured()) {
return;
}
_keyboardMouseDevice.wheelEvent(event);
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
_keyboardMouseDevice->wheelEvent(event);
}
}
void Application::dropEvent(QDropEvent *event) {
@ -1964,6 +2001,14 @@ void Application::idle() {
PerformanceTimer perfTimer("updateGL");
PerformanceWarning warn(showWarnings, "Application::idle()... updateGL()");
getActiveDisplayPlugin()->idle();
auto inputPlugins = getInputPlugins();
foreach(auto inputPlugin, inputPlugins) {
QString name = inputPlugin->getName();
QAction* action = Menu::getInstance()->getActionForOption(name);
if (action->isChecked()) {
inputPlugin->idle();
}
}
}
{
PerformanceTimer perfTimer("rest");
@ -2625,10 +2670,14 @@ void Application::update(float deltaTime) {
userInputMapper->setSensorToWorldMat(_myAvatar->getSensorToWorldMatrix());
userInputMapper->update(deltaTime);
_keyboardMouseDevice.pluginUpdate(deltaTime);
SixenseManager::getInstance().pluginUpdate(deltaTime);
SDL2Manager::getInstance()->pluginUpdate(deltaTime);
ViveControllerManager::getInstance().pluginUpdate(deltaTime);
auto inputPlugins = getInputPlugins();
foreach(auto inputPlugin, inputPlugins) {
QString name = inputPlugin->getName();
QAction* action = Menu::getInstance()->getActionForOption(name);
if (action->isChecked()) {
inputPlugin->pluginUpdate(deltaTime); // add flag to prevent multiple devices from modifying joints
}
}
// Dispatch input events
_controllerScriptingInterface.updateInputControllers();
@ -2826,7 +2875,7 @@ void Application::setPalmData(Hand* hand, UserInputMapper::PoseValue pose, int i
palm->setActive(pose.isValid());
// TODO: velocity filters, tip velocities, et.c
// TODO: velocity filters, tip velocities, etc.
// see SixenseManager
// transform from sensor space, to world space, to avatar model space.
@ -2872,8 +2921,7 @@ void Application::emulateMouse(Hand* hand, float click, float shift, int index)
float yAngle = 0.5f - ((atan2f(direction.z, direction.y) + (float)M_PI_2));
auto canvasSize = qApp->getCanvasSize();
// Get the pixel range over which the xAngle and yAngle are scaled
// TODO: move this from SixenseManager
float cursorRange = canvasSize.x * SixenseManager::getInstance().getCursorPixelRangeMult();
float cursorRange = canvasSize.x * InputDevice::getCursorPixelRangeMult();
pos.setX(canvasSize.x / 2.0f + cursorRange * xAngle);
pos.setY(canvasSize.y / 2.0f + cursorRange * yAngle);
@ -5128,6 +5176,51 @@ void Application::updateDisplayMode() {
Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin");
}
static QVector<QPair<QString, QString>> _currentInputPluginActions;
void Application::updateInputModes() {
auto menu = Menu::getInstance();
auto inputPlugins = getInputPlugins();
auto offscreenUi = DependencyManager::get<OffscreenUi>();
InputPluginPointer newInputPlugin = InputPluginPointer(nullptr);
InputPluginPointer removedInputPlugin = InputPluginPointer(nullptr);
foreach(InputPluginPointer inputPlugin, inputPlugins) {
QString name = inputPlugin->getName();
QAction* action = menu->getActionForOption(name);
if (action->isChecked() && !_activeInputPlugins.contains(inputPlugin)) {
_activeInputPlugins.append(inputPlugin);
newInputPlugin = inputPlugin;
break;
} else if (!action->isChecked() && _activeInputPlugins.contains(inputPlugin)) {
_activeInputPlugins.removeOne(inputPlugin);
removedInputPlugin = inputPlugin;
break;
}
}
// A plugin was checked
if (newInputPlugin) {
newInputPlugin->activate(this);
newInputPlugin->installEventFilter(qApp);
newInputPlugin->installEventFilter(offscreenUi.data());
} else if (removedInputPlugin) { // A plugin was unchecked
removedInputPlugin->deactivate();
removedInputPlugin->removeEventFilter(qApp);
removedInputPlugin->removeEventFilter(offscreenUi.data());
}
if (newInputPlugin || removedInputPlugin) {
if (!_currentInputPluginActions.isEmpty()) {
auto menu = Menu::getInstance();
foreach(auto itemInfo, _currentInputPluginActions) {
menu->removeMenuItem(itemInfo.first, itemInfo.second);
}
_currentInputPluginActions.clear();
}
}
}
void Application::addMenuItem(const QString& path, const QString& name, std::function<void()> onClicked, bool checkable, bool checked, const QString& groupName) {
auto menu = Menu::getInstance();
MenuWrapper* parentItem = menu->getMenu(path);
@ -5136,6 +5229,7 @@ void Application::addMenuItem(const QString& path, const QString& name, std::fun
onClicked();
});
_currentDisplayPluginActions.push_back({ path, name });
_currentInputPluginActions.push_back({ path, name });
}
GlWindow* Application::getVisibleWindow() {

View file

@ -54,6 +54,7 @@
#include "Stars.h"
#include "avatar/Avatar.h"
#include "avatar/MyAvatar.h"
#include <input-plugins/KeyboardMouseDevice.h>
#include "scripting/ControllerScriptingInterface.h"
#include "scripting/WebWindowClass.h"
#include "ui/BandwidthDialog.h"
@ -68,11 +69,11 @@
#include "ui/ApplicationCompositor.h"
#include "ui/RunningScriptsWidget.h"
#include "ui/ToolWindow.h"
#include "devices/KeyboardMouseDevice.h"
#include "octree/OctreeFade.h"
#include "octree/OctreePacketProcessor.h"
#include "UndoStackScriptingInterface.h"
#include "DisplayPlugins.h"
#include "InputPlugins.h"
#include "render/Engine.h"
class QGLWidget;
@ -385,6 +386,7 @@ public slots:
void nodeKilled(SharedNodePointer node);
void packetSent(quint64 length);
void updateDisplayMode();
void updateInputModes();
QVector<EntityItemID> pasteEntities(float x, float y, float z);
bool exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs);
@ -513,6 +515,7 @@ private:
OffscreenGlCanvas* _offscreenContext;
DisplayPluginPointer _displayPlugin;
InputPluginList _activeInputPlugins;
MainWindow* _window;
@ -553,10 +556,10 @@ private:
OctreeQuery _octreeQuery; // NodeData derived class for querying octee cells from octree servers
KeyboardMouseDevice _keyboardMouseDevice; // Default input device, the good old keyboard mouse and maybe touchpad
MyAvatar* _myAvatar; // TODO: move this and relevant code to AvatarManager (or MyAvatar as the case may be)
Camera _myCamera; // My view onto the world
Camera _mirrorCamera; // Cammera for mirror view
KeyboardMouseDevice* _keyboardMouseDevice; // Default input device, the good old keyboard mouse and maybe touchpad
MyAvatar* _myAvatar; // TODO: move this and relevant code to AvatarManager (or MyAvatar as the case may be)
Camera _myCamera; // My view onto the world
Camera _mirrorCamera; // Cammera for mirror view
QRect _mirrorViewRect;
Setting::Handle<bool> _firstRun;

View file

@ -0,0 +1,64 @@
//
// Created by Bradley Austin Davis on 2015/05/30
// 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 "InputPlugins.h"
#include "Application.h"
#include <input-plugins/InputPlugin.h>
#include <input-plugins/KeyboardMouseDevice.h>
#include <input-plugins/SDL2Manager.h>
#include <input-plugins/SixenseManager.h>
#include <input-plugins/ViveControllerManager.h>
static void addInputPluginToMenu(InputPluginPointer inputPlugin, bool active = false) {
auto menu = Menu::getInstance();
QString name = inputPlugin->getName();
Q_ASSERT(!menu->menuItemExists(MenuOption::InputMenu, name));
static QActionGroup* inputPluginGroup = nullptr;
if (!inputPluginGroup) {
inputPluginGroup = new QActionGroup(menu);
}
auto parent = menu->getMenu(MenuOption::InputMenu);
auto action = menu->addCheckableActionToQMenuAndActionHash(parent,
name, 0, true, qApp,
SLOT(updateInputModes()));
inputPluginGroup->addAction(action);
Q_ASSERT(menu->menuItemExists(MenuOption::InputMenu, name));
qApp->updateInputModes(); // TODO: this should be called automatically
}
// FIXME move to a plugin manager class
const InputPluginList& getInputPlugins() {
static InputPluginList INPUT_PLUGINS;
static bool init = false;
if (!init) {
init = true;
InputPlugin* PLUGIN_POOL[] = {
new KeyboardMouseDevice(),
new SDL2Manager(),
new SixenseManager(),
new ViveControllerManager(),
nullptr
};
for (int i = 0; PLUGIN_POOL[i]; ++i) {
InputPlugin * plugin = PLUGIN_POOL[i];
if (plugin->isSupported()) {
plugin->init();
InputPluginPointer pluginPointer(plugin);
addInputPluginToMenu(pluginPointer, plugin == *PLUGIN_POOL);
INPUT_PLUGINS.push_back(pluginPointer);
}
}
}
return INPUT_PLUGINS;
}

View file

@ -0,0 +1,18 @@
//
// Created by Sam Gondelman on 7/16/2015
// 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
//
#pragma once
class InputPlugin;
#include <QVector>
#include <QSharedPointer>
using InputPluginPointer = QSharedPointer<InputPlugin>;
using InputPluginList = QVector<InputPluginPointer>;
const InputPluginList& getInputPlugins();

View file

@ -226,6 +226,10 @@ Menu::Menu() {
MenuWrapper* avatarMenu = addMenu("Avatar");
QObject* avatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
MenuWrapper* inputModeMenu = addMenu(MenuOption::InputMenu);
QActionGroup* inputModeGroup = new QActionGroup(inputModeMenu);
inputModeGroup->setExclusive(false);
MenuWrapper* avatarSizeMenu = avatarMenu->addMenu("Size");
addActionToQMenuAndActionHash(avatarSizeMenu,
MenuOption::IncreaseAvatarSize,

View file

@ -80,6 +80,13 @@ public:
const QKeySequence& shortcut = 0,
QAction::MenuRole role = QAction::NoRole,
int menuItemLocation = UNSPECIFIED_POSITION);
QAction* addCheckableActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
const QString& actionName,
const QKeySequence& shortcut = 0,
const bool checked = false,
const QObject* receiver = NULL,
const char* member = NULL,
int menuItemLocation = UNSPECIFIED_POSITION);
void removeAction(MenuWrapper* menu, const QString& actionName);
@ -109,14 +116,6 @@ private:
void addDisabledActionAndSeparator(MenuWrapper* destinationMenu, const QString& actionName,
int menuItemLocation = UNSPECIFIED_POSITION);
QAction* addCheckableActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
const QString& actionName,
const QKeySequence& shortcut = 0,
const bool checked = false,
const QObject* receiver = NULL,
const char* member = NULL,
int menuItemLocation = UNSPECIFIED_POSITION);
QAction* getActionFromName(const QString& menuName, MenuWrapper* menu);
MenuWrapper* getSubMenuFromName(const QString& menuName, MenuWrapper* menu);
MenuWrapper* getMenuParent(const QString& menuName, QString& finalMenuPart);
@ -203,6 +202,7 @@ namespace MenuOption {
const QString HandLasers = "Enable Hand UI Lasers";
const QString IncreaseAvatarSize = "Increase Avatar Size";
const QString IndependentMode = "Independent Mode";
const QString InputMenu = "Avatar>Input Devices";
const QString KeyboardMotorControl = "Enable Keyboard Motor Control";
const QString LeapMotionOnHMD = "Leap Motion on HMD";
const QString LoadScript = "Open and Run Script File...";

View file

@ -22,7 +22,8 @@
#include "Tooltip.h"
#include "Application.h"
#include <input-plugins\SixenseManager.h> // TODO: any references to sixense should be removed here
#include <input-plugins/SixenseManager.h> // TODO: any references to sixense should be removed here
#include <input-plugins/InputDevice.h>
// Used to animate the magnification windows
@ -506,7 +507,7 @@ void ApplicationCompositor::renderControllerPointers(gpu::Batch& batch) {
float yAngle = 0.5f - ((atan2f(direction.z, direction.y) + (float)M_PI_2));
// Get the pixel range over which the xAngle and yAngle are scaled
float cursorRange = canvasSize.x * SixenseManager::getInstance().getCursorPixelRangeMult();
float cursorRange = canvasSize.x * InputDevice::getCursorPixelRangeMult();
mouseX = (canvasSize.x / 2.0f + cursorRange * xAngle);
mouseY = (canvasSize.y / 2.0f + cursorRange * yAngle);

View file

@ -182,7 +182,7 @@ void PreferencesDialog::loadPreferences() {
#endif
SixenseManager& sixense = SixenseManager::getInstance();
ui.sixenseReticleMoveSpeedSpin->setValue(sixense.getReticleMoveSpeed());
ui.sixenseReticleMoveSpeedSpin->setValue(InputDevice::getReticleMoveSpeed());
ui.invertSixenseButtonsCheckBox->setChecked(sixense.getInvertButtons());
// LOD items
@ -246,7 +246,7 @@ void PreferencesDialog::savePreferences() {
qApp->getApplicationCompositor().setHmdUIAngularSize(ui.oculusUIAngularSizeSpin->value());
SixenseManager& sixense = SixenseManager::getInstance();
sixense.setReticleMoveSpeed(ui.sixenseReticleMoveSpeedSpin->value());
InputDevice::setReticleMoveSpeed(ui.sixenseReticleMoveSpeedSpin->value());
sixense.setInvertButtons(ui.invertSixenseButtonsCheckBox->isChecked());
auto audio = DependencyManager::get<AudioClient>();

View file

@ -36,6 +36,7 @@ const QString & OpenVrDisplayPlugin::getName() const {
}
vr::IVRSystem *_hmd{ nullptr };
int hmdRefCount = 0;
static vr::IVRCompositor* _compositor{ nullptr };
vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
@ -79,6 +80,7 @@ bool OpenVrDisplayPlugin::isSupported() const {
}
void OpenVrDisplayPlugin::activate(PluginContainer * container) {
hmdRefCount++;
vr::HmdError eError = vr::HmdError_None;
if (!_hmd) {
_hmd = vr::VR_Init(&eError);
@ -119,8 +121,12 @@ void OpenVrDisplayPlugin::activate(PluginContainer * container) {
}
void OpenVrDisplayPlugin::deactivate() {
vr::VR_Shutdown();
_hmd = nullptr;
hmdRefCount--;
if (hmdRefCount == 0 && _hmd) {
vr::VR_Shutdown();
_hmd = nullptr;
}
_compositor = nullptr;
}

View file

@ -7,6 +7,20 @@
//
#include "InputDevice.h"
const float DEFAULT_HAND_RETICLE_MOVE_SPEED = 37.5f;
float InputDevice::reticleMoveSpeed = DEFAULT_HAND_RETICLE_MOVE_SPEED;
//Constants for getCursorPixelRangeMultiplier()
const float MIN_PIXEL_RANGE_MULT = 0.4f;
const float MAX_PIXEL_RANGE_MULT = 2.0f;
const float RANGE_MULT = (MAX_PIXEL_RANGE_MULT - MIN_PIXEL_RANGE_MULT) * 0.01f;
//Returns a multiplier to be applied to the cursor range for the controllers
float InputDevice::getCursorPixelRangeMult() {
//scales (0,100) to (MINIMUM_PIXEL_RANGE_MULT, MAXIMUM_PIXEL_RANGE_MULT)
return InputDevice::reticleMoveSpeed * RANGE_MULT + MIN_PIXEL_RANGE_MULT;
}
float InputDevice::getButton(int channel) const {
if (!_buttonPressedMap.empty()) {
if (_buttonPressedMap.find(channel) != _buttonPressedMap.end()) {
@ -37,4 +51,4 @@ UserInputMapper::PoseValue InputDevice::getPose(int channel) const {
else {
return UserInputMapper::PoseValue();
}
}
}

View file

@ -40,6 +40,10 @@ public:
int getDeviceID() { return _deviceID; }
static float getCursorPixelRangeMult();
static float getReticleMoveSpeed() { return reticleMoveSpeed; }
static void setReticleMoveSpeed(float sixenseReticleMoveSpeed) { reticleMoveSpeed = sixenseReticleMoveSpeed; }
protected:
int _deviceID = 0;
@ -48,4 +52,7 @@ protected:
ButtonPressedMap _buttonPressedMap;
AxisStateMap _axisStateMap;
PoseStateMap _poseStateMap;
};
private:
static float reticleMoveSpeed;
};

View file

@ -9,11 +9,9 @@
#include <plugins/Plugin.h>
const float DEFAULT_HAND_RETICLE_MOVE_SPEED = 37.5f;
class InputPlugin : public Plugin {
public:
virtual bool isHandController() const = 0;
virtual bool isJointController() const = 0;
virtual void pluginFocusOutEvent() = 0;

View file

@ -11,7 +11,7 @@
//
#include "KeyboardMouseDevice.h"
const QString KeyboardMouseDevice::NAME = "Keyboard";
const QString KeyboardMouseDevice::NAME = "Keyboard/Mouse";
void KeyboardMouseDevice::update(float deltaTime) {
_axisStateMap.clear();

View file

@ -14,8 +14,8 @@
#include <QTouchEvent>
#include <chrono>
#include <input-plugins/InputDevice.h>
#include <input-plugins/InputPlugin.h>
#include "InputDevice.h"
#include "InputPlugin.h"
class KeyboardMouseDevice : public InputPlugin, public InputDevice {
Q_OBJECT
@ -58,14 +58,11 @@ public:
// Plugin functions
virtual bool isSupported() const override { return true; }
virtual bool isHandController() const override { return false; }
virtual bool isJointController() const override { return false; }
const QString& getName() const { return NAME; }
virtual void init() override {};
virtual void deinit() override {};
virtual void activate(PluginContainer * container) override {};
virtual void deactivate() override {};
virtual void idle() override {};
virtual void pluginFocusOutEvent() override { focusOutEvent(); }
virtual void pluginUpdate(float deltaTime) override { update(deltaTime); }
@ -96,6 +93,8 @@ public:
UserInputMapper::Input makeInput(KeyboardMouseDevice::TouchAxisChannel axis);
UserInputMapper::Input makeInput(KeyboardMouseDevice::TouchButtonChannel button);
static const QString NAME;
protected:
QPoint _lastCursor;
glm::vec2 _lastTouch;
@ -104,9 +103,6 @@ protected:
glm::vec2 evalAverageTouchPoints(const QList<QTouchEvent::TouchPoint>& points) const;
std::chrono::high_resolution_clock _clock;
std::chrono::high_resolution_clock::time_point _lastTouchTime;
private:
static const QString NAME;
};
#endif // hifi_KeyboardMouseDevice_h

View file

@ -32,15 +32,18 @@ _openJoysticks(),
#endif
_isInitialized(false)
{
}
void SDL2Manager::init() {
#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);
if (!_openJoysticks.contains(id)) {
@ -53,27 +56,23 @@ _isInitialized(false)
}
}
}
_isInitialized = true;
} else {
}
else {
qDebug() << "Error initializing SDL2 Manager";
}
#endif
}
SDL2Manager::~SDL2Manager() {
void SDL2Manager::deinit() {
#ifdef HAVE_SDL2
qDeleteAll(_openJoysticks);
SDL_Quit();
#endif
}
SDL2Manager* SDL2Manager::getInstance() {
static SDL2Manager sharedInstance;
return &sharedInstance;
}
bool SDL2Manager::isSupported() const {
#ifdef HAVE_SDL2
return true;

View file

@ -26,20 +26,16 @@ class SDL2Manager : public InputPlugin {
public:
SDL2Manager();
~SDL2Manager();
static SDL2Manager* getInstance();
// Plugin functions
virtual bool isSupported() const override;
virtual bool isHandController() const override { return false; }
virtual bool isJointController() const override { return false; }
const QString& getName() const { return NAME; }
virtual void init() override {};
virtual void deinit() override {};
virtual void init() override;
virtual void deinit() override;
virtual void activate(PluginContainer * container) override {};
virtual void deactivate() override {};
virtual void idle() override {};
virtual void pluginFocusOutEvent() override;
virtual void pluginUpdate(float deltaTime) override;

View file

@ -68,24 +68,6 @@ SixenseManager::SixenseManager() :
}
SixenseManager::~SixenseManager() {
#ifdef HAVE_SIXENSE_
if (_isInitialized) {
#ifdef __APPLE__
SixenseBaseFunction sixenseExit = (SixenseBaseFunction) _sixenseLibrary->resolve("sixenseExit");
#endif
sixenseExit();
}
#ifdef __APPLE__
delete _sixenseLibrary;
#endif
#endif
}
bool SixenseManager::isSupported() const {
#ifdef HAVE_SIXENSE
return true;
@ -138,6 +120,24 @@ void SixenseManager::init() {
#endif
}
void SixenseManager::deinit() {
#ifdef HAVE_SIXENSE_
if (_isInitialized) {
#ifdef __APPLE__
SixenseBaseFunction sixenseExit = (SixenseBaseFunction)_sixenseLibrary->resolve("sixenseExit");
#endif
sixenseExit();
}
#ifdef __APPLE__
delete _sixenseLibrary;
#endif
#endif
}
void SixenseManager::setFilter(bool filter) {
#ifdef HAVE_SIXENSE
@ -175,12 +175,6 @@ void SixenseManager::update(float deltaTime) {
userInputMapper->removeDevice(_deviceID);
_deviceID = 0;
_poseStateMap.clear();
// if (_prevPalms[0]) {
// _prevPalms[0]->setActive(false);
// }
// if (_prevPalms[1]) {
// _prevPalms[1]->setActive(false);
// }
}
return;
}
@ -296,17 +290,6 @@ void SixenseManager::update(float deltaTime) {
#endif // HAVE_SIXENSE
}
//Constants for getCursorPixelRangeMultiplier()
const float MIN_PIXEL_RANGE_MULT = 0.4f;
const float MAX_PIXEL_RANGE_MULT = 2.0f;
const float RANGE_MULT = (MAX_PIXEL_RANGE_MULT - MIN_PIXEL_RANGE_MULT) * 0.01f;
//Returns a multiplier to be applied to the cursor range for the controllers
float SixenseManager::getCursorPixelRangeMult() const {
//scales (0,100) to (MINIMUM_PIXEL_RANGE_MULT, MAXIMUM_PIXEL_RANGE_MULT)
return _reticleMoveSpeed * RANGE_MULT + MIN_PIXEL_RANGE_MULT;
}
void SixenseManager::toggleSixense(bool shouldEnable) {
if (shouldEnable && !isInitialized()) {
init();

View file

@ -52,19 +52,20 @@ public:
LEFT_HAND = 0,
RIGHT_HAND,
};
SixenseManager();
static SixenseManager& getInstance();
// Plugin functions
virtual bool isSupported() const override;
virtual bool isHandController() const override { return false; }
virtual bool isJointController() const override { return true; }
const QString& getName() const { return NAME; }
virtual void init() override;
virtual void deinit() override {};
virtual void deinit() override;
virtual void activate(PluginContainer * container) override {};
virtual void deactivate() override {};
virtual void idle() override {};
virtual void deactivate() override { _poseStateMap.clear(); };
virtual void pluginFocusOutEvent() override { focusOutEvent(); }
virtual void pluginUpdate(float deltaTime) override { update(deltaTime); }
@ -79,10 +80,6 @@ public:
void setIsEnabled(bool isEnabled) { _isEnabled = isEnabled; }
float getCursorPixelRangeMult() const;
float getReticleMoveSpeed() const { return _reticleMoveSpeed; }
void setReticleMoveSpeed(float sixenseReticleMoveSpeed) { _reticleMoveSpeed = sixenseReticleMoveSpeed; }
bool getInvertButtons() const { return _invertButtons; }
void setInvertButtons(bool invertSixenseButtons) { _invertButtons = invertSixenseButtons; }
@ -95,10 +92,7 @@ public slots:
void setFilter(bool filter);
void setLowVelocityFilter(bool lowVelocityFilter) { _lowVelocityFilter = lowVelocityFilter; };
private:
SixenseManager();
~SixenseManager();
private:
void handleButtonEvent(unsigned int buttons, int index);
void handleAxisEvent(float x, float y, float trigger, int index);
void handlePoseEvent(glm::vec3 position, glm::quat rotation, int index);
@ -134,8 +128,7 @@ private:
bool _lowVelocityFilter;
bool _controllersAtBase;
float _reticleMoveSpeed = DEFAULT_HAND_RETICLE_MOVE_SPEED;
bool _invertButtons = DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS;
static const QString NAME;

View file

@ -22,6 +22,7 @@
#include "UserActivityLogger.h"
extern vr::IVRSystem *_hmd;
extern int hmdRefCount;
extern vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
extern mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
@ -43,15 +44,8 @@ const QString CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b";
const QString ViveControllerManager::NAME = "OpenVR";
ViveControllerManager& ViveControllerManager::getInstance() {
static ViveControllerManager sharedInstance;
return sharedInstance;
}
ViveControllerManager::ViveControllerManager() :
InputDevice("SteamVR Controller"),
_isInitialized(false),
_isEnabled(true),
_trackedControllers(0),
_modelLoaded(false),
_leftHandRenderID(0),
@ -60,19 +54,12 @@ ViveControllerManager::ViveControllerManager() :
}
ViveControllerManager::~ViveControllerManager() {
}
bool ViveControllerManager::isSupported() const {
return vr::VR_IsHmdPresent();
}
void ViveControllerManager::deinit() {
// TODO: deinit openvr? avoid conflicts with display plugin
}
void ViveControllerManager::init() {
void ViveControllerManager::activate(PluginContainer* container) {
hmdRefCount++;
if (!_hmd) {
vr::HmdError eError = vr::HmdError_None;
_hmd = vr::VR_Init(&eError);
@ -125,8 +112,16 @@ void ViveControllerManager::init() {
_modelLoaded = true;
}
}
_isInitialized = true;
void ViveControllerManager::deactivate() {
hmdRefCount--;
if (hmdRefCount == 0 && _hmd) {
vr::VR_Shutdown();
_hmd = nullptr;
}
_poseStateMap.clear();
}
void ViveControllerManager::updateRendering(RenderArgs* args, render::ScenePointer scene, render::PendingChanges pendingChanges) {
@ -192,68 +187,68 @@ void ViveControllerManager::renderHand(UserInputMapper::PoseValue pose, gpu::Bat
}
void ViveControllerManager::update(float deltaTime) {
// TODO: This shouldn't be necessary
if (!_hmd) {
return;
}
_buttonPressedMap.clear();
if (_isInitialized && _isEnabled) {
PerformanceTimer perfTimer("ViveControllerManager::update");
PerformanceTimer perfTimer("ViveControllerManager::update");
int numTrackedControllers = 0;
int numTrackedControllers = 0;
for (vr::TrackedDeviceIndex_t device = vr::k_unTrackedDeviceIndex_Hmd + 1;
device < vr::k_unMaxTrackedDeviceCount && numTrackedControllers < 2; ++device) {
for (vr::TrackedDeviceIndex_t device = vr::k_unTrackedDeviceIndex_Hmd + 1;
device < vr::k_unMaxTrackedDeviceCount && numTrackedControllers < 2; ++device) {
if (!_hmd->IsTrackedDeviceConnected(device)) {
continue;
}
if (!_hmd->IsTrackedDeviceConnected(device)) {
continue;
}
if(_hmd->GetTrackedDeviceClass(device) != vr::TrackedDeviceClass_Controller) {
continue;
}
if(_hmd->GetTrackedDeviceClass(device) != vr::TrackedDeviceClass_Controller) {
continue;
}
if (!_trackedDevicePose[device].bPoseIsValid) {
continue;
}
if (!_trackedDevicePose[device].bPoseIsValid) {
continue;
}
numTrackedControllers++;
numTrackedControllers++;
const mat4& mat = _trackedDevicePoseMat4[device];
const mat4& mat = _trackedDevicePoseMat4[device];
handlePoseEvent(mat, numTrackedControllers - 1);
handlePoseEvent(mat, numTrackedControllers - 1);
// handle inputs
vr::VRControllerState_t controllerState = vr::VRControllerState_t();
if (_hmd->GetControllerState(device, &controllerState)) {
//qDebug() << (numTrackedControllers == 1 ? "Left: " : "Right: ");
//qDebug() << "Trackpad: " << controllerState.rAxis[0].x << " " << controllerState.rAxis[0].y;
//qDebug() << "Trigger: " << controllerState.rAxis[1].x << " " << controllerState.rAxis[1].y;
handleButtonEvent(controllerState.ulButtonPressed, numTrackedControllers - 1);
for (int i = 0; i < vr::k_unControllerStateAxisCount; i++) {
handleAxisEvent(Axis(i), controllerState.rAxis[i].x, controllerState.rAxis[i].y, numTrackedControllers - 1);
}
// handle inputs
vr::VRControllerState_t controllerState = vr::VRControllerState_t();
if (_hmd->GetControllerState(device, &controllerState)) {
//qDebug() << (numTrackedControllers == 1 ? "Left: " : "Right: ");
//qDebug() << "Trackpad: " << controllerState.rAxis[0].x << " " << controllerState.rAxis[0].y;
//qDebug() << "Trigger: " << controllerState.rAxis[1].x << " " << controllerState.rAxis[1].y;
handleButtonEvent(controllerState.ulButtonPressed, numTrackedControllers - 1);
for (int i = 0; i < vr::k_unControllerStateAxisCount; i++) {
handleAxisEvent(Axis(i), controllerState.rAxis[i].x, controllerState.rAxis[i].y, numTrackedControllers - 1);
}
}
auto userInputMapper = DependencyManager::get<UserInputMapper>();
if (numTrackedControllers == 0) {
if (_deviceID != 0) {
userInputMapper->removeDevice(_deviceID);
_deviceID = 0;
_poseStateMap.clear();
}
}
if (_trackedControllers == 0 && numTrackedControllers > 0) {
registerToUserInputMapper(*userInputMapper);
assignDefaultInputMapping(*userInputMapper);
UserActivityLogger::getInstance().connectedDevice("spatial_controller", "steamVR");
}
_trackedControllers = numTrackedControllers;
}
auto userInputMapper = DependencyManager::get<UserInputMapper>();
if (numTrackedControllers == 0) {
if (_deviceID != 0) {
userInputMapper->removeDevice(_deviceID);
_deviceID = 0;
_poseStateMap.clear();
}
}
if (_trackedControllers == 0 && numTrackedControllers > 0) {
registerToUserInputMapper(*userInputMapper);
assignDefaultInputMapping(*userInputMapper);
UserActivityLogger::getInstance().connectedDevice("spatial_controller", "steamVR");
}
_trackedControllers = numTrackedControllers;
}
void ViveControllerManager::focusOutEvent() {

View file

@ -48,18 +48,15 @@ public:
RIGHT_HAND,
};
static ViveControllerManager& getInstance();
ViveControllerManager();
// Plugin functions
virtual bool isSupported() const override;
virtual bool isHandController() const override { return true; }
virtual bool isJointController() const override { return true; }
const QString& getName() const { return NAME; }
virtual void init() override;
virtual void deinit() override;
virtual void activate(PluginContainer * container) override {};
virtual void deactivate() override {};
virtual void idle() override {};
virtual void activate(PluginContainer * container) override;
virtual void deactivate() override;
virtual void pluginFocusOutEvent() override { focusOutEvent(); }
virtual void pluginUpdate(float deltaTime) override { update(deltaTime); }
@ -77,17 +74,12 @@ public:
UserInputMapper::Input makeInput(JointChannel joint);
private:
ViveControllerManager();
~ViveControllerManager();
void renderHand(UserInputMapper::PoseValue pose, gpu::Batch& batch, int index);
void handleButtonEvent(uint64_t buttons, int index);
void handleAxisEvent(Axis axis, float x, float y, int index);
void handlePoseEvent(const mat4& mat, int index);
bool _isInitialized;
bool _isEnabled;
int _trackedControllers;
bool _modelLoaded;