mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 16:55:07 +02:00
input plugin architecture, fixed sixense
This commit is contained in:
parent
fb62fda2d2
commit
56e7af081e
23 changed files with 344 additions and 326 deletions
|
@ -2,7 +2,7 @@ set(TARGET_NAME interface)
|
|||
project(${TARGET_NAME})
|
||||
|
||||
# set a default root dir for each of our optional externals if it was not passed
|
||||
set(OPTIONAL_EXTERNALS "Faceshift" "LeapMotion" "RtMidi" "SDL2" "RSSDK")
|
||||
set(OPTIONAL_EXTERNALS "Faceshift" "LeapMotion" "RtMidi" "RSSDK")
|
||||
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
||||
string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE)
|
||||
if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR)
|
||||
|
|
|
@ -124,6 +124,7 @@
|
|||
#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"
|
||||
|
@ -675,9 +676,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
connect(ddeTracker.data(), &FaceTracker::muteToggled, this, &Application::faceTrackerMuteToggled);
|
||||
#endif
|
||||
|
||||
ViveControllerManager::getInstance().init();
|
||||
if (ViveControllerManager::getInstance().isSupported()) {
|
||||
ViveControllerManager::getInstance().activate();
|
||||
ViveControllerManager::getInstance().init();
|
||||
ViveControllerManager::getInstance().activate(NULL);
|
||||
}
|
||||
|
||||
_oldHandMouseX[0] = -1;
|
||||
|
@ -1640,10 +1641,10 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
|||
}
|
||||
|
||||
void Application::focusOutEvent(QFocusEvent* event) {
|
||||
_keyboardMouseDevice.focusOutEvent(event);
|
||||
SixenseManager::getInstance().focusOutEvent();
|
||||
SDL2Manager::getInstance()->focusOutEvent();
|
||||
ViveControllerManager::getInstance().focusOutEvent();
|
||||
_keyboardMouseDevice.pluginFocusOutEvent();
|
||||
SixenseManager::getInstance().pluginFocusOutEvent();
|
||||
SDL2Manager::getInstance()->pluginFocusOutEvent();
|
||||
ViveControllerManager::getInstance().pluginFocusOutEvent();
|
||||
|
||||
// synthesize events for keys currently pressed, since we may not get their release events
|
||||
foreach (int key, _keysPressed) {
|
||||
|
@ -2615,15 +2616,16 @@ void Application::update(float deltaTime) {
|
|||
_lastFaceTrackerUpdate = 0;
|
||||
}
|
||||
|
||||
SixenseManager::getInstance().update(deltaTime);
|
||||
SDL2Manager::getInstance()->update();
|
||||
ViveControllerManager::getInstance().update();
|
||||
}
|
||||
|
||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||
userInputMapper->setSensorToWorldMat(_myAvatar->getSensorToWorldMatrix());
|
||||
userInputMapper->update(deltaTime);
|
||||
_keyboardMouseDevice.update();
|
||||
|
||||
_keyboardMouseDevice.pluginUpdate(deltaTime);
|
||||
SixenseManager::getInstance().pluginUpdate(deltaTime);
|
||||
SDL2Manager::getInstance()->pluginUpdate(deltaTime);
|
||||
ViveControllerManager::getInstance().pluginUpdate(deltaTime);
|
||||
|
||||
// Dispatch input events
|
||||
_controllerScriptingInterface.updateInputControllers();
|
||||
|
@ -3734,7 +3736,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
}
|
||||
renderArgs->_debugFlags = renderDebugFlags;
|
||||
_entities.render(renderArgs);
|
||||
ViveControllerManager::getInstance().updateRendering(renderArgs, _main3DScene, pendingChanges);
|
||||
//ViveControllerManager::getInstance().updateRendering(renderArgs, _main3DScene, pendingChanges);
|
||||
}
|
||||
|
||||
// render the ambient occlusion effect if enabled
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
#include "Stars.h"
|
||||
#include "avatar/Avatar.h"
|
||||
#include "avatar/MyAvatar.h"
|
||||
#include "devices/SixenseManager.h"
|
||||
#include "scripting/ControllerScriptingInterface.h"
|
||||
#include "scripting/WebWindowClass.h"
|
||||
#include "ui/BandwidthDialog.h"
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "devices/DdeFaceTracker.h"
|
||||
#include "devices/Faceshift.h"
|
||||
#include "devices/RealSense.h"
|
||||
//#include "devices/SixenseManager.h"
|
||||
#include <input-plugins\SixenseManager.h> // TODO: should be able to remove this once input plugin architecture is finished
|
||||
#include "MainWindow.h"
|
||||
#include "scripting/MenuScriptingInterface.h"
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
//
|
||||
#include "KeyboardMouseDevice.h"
|
||||
|
||||
void KeyboardMouseDevice::update() {
|
||||
const QString KeyboardMouseDevice::NAME = "Keyboard";
|
||||
|
||||
void KeyboardMouseDevice::update(float deltaTime) {
|
||||
_axisStateMap.clear();
|
||||
|
||||
// For touch event, we need to check that the last event is not too long ago
|
||||
|
@ -27,7 +29,7 @@ void KeyboardMouseDevice::update() {
|
|||
}
|
||||
}
|
||||
|
||||
void KeyboardMouseDevice::focusOutEvent(QFocusEvent* event) {
|
||||
void KeyboardMouseDevice::focusOutEvent() {
|
||||
_buttonPressedMap.clear();
|
||||
};
|
||||
|
||||
|
@ -159,7 +161,7 @@ void KeyboardMouseDevice::registerToUserInputMapper(UserInputMapper& mapper) {
|
|||
// Grab the current free device ID
|
||||
_deviceID = mapper.getFreeDeviceID();
|
||||
|
||||
auto proxy = UserInputMapper::DeviceProxy::Pointer(new UserInputMapper::DeviceProxy("Keyboard"));
|
||||
auto proxy = UserInputMapper::DeviceProxy::Pointer(new UserInputMapper::DeviceProxy(_name));
|
||||
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<UserInputMapper::InputPair> {
|
||||
|
@ -282,23 +284,3 @@ void KeyboardMouseDevice::assignDefaultInputMapping(UserInputMapper& mapper) {
|
|||
mapper.addInputChannel(UserInputMapper::ACTION2, makeInput(Qt::Key_T));
|
||||
}
|
||||
|
||||
float KeyboardMouseDevice::getButton(int channel) const {
|
||||
if (!_buttonPressedMap.empty()) {
|
||||
if (_buttonPressedMap.find(channel) != _buttonPressedMap.end()) {
|
||||
return 1.0f;
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float KeyboardMouseDevice::getAxis(int channel) const {
|
||||
auto axis = _axisStateMap.find(channel);
|
||||
if (axis != _axisStateMap.end()) {
|
||||
return (*axis).second;
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,11 +14,12 @@
|
|||
|
||||
#include <QTouchEvent>
|
||||
#include <chrono>
|
||||
#include <input-plugins/UserInputMapper.h>
|
||||
#include <input-plugins/InputDevice.h>
|
||||
#include <input-plugins/InputPlugin.h>
|
||||
|
||||
class KeyboardMouseDevice {
|
||||
class KeyboardMouseDevice : public InputPlugin, public InputDevice {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
enum KeyboardChannel {
|
||||
KEYBOARD_FIRST = 0,
|
||||
KEYBOARD_LAST = 255,
|
||||
|
@ -53,10 +54,27 @@ public:
|
|||
TOUCH_BUTTON_PRESS = TOUCH_AXIS_Y_NEG + 1,
|
||||
};
|
||||
|
||||
typedef std::unordered_set<int> ButtonPressedMap;
|
||||
typedef std::map<int, float> AxisStateMap; // 8 axes
|
||||
KeyboardMouseDevice() : InputDevice("Keyboard") {}
|
||||
|
||||
void focusOutEvent(QFocusEvent* event);
|
||||
// Plugin functions
|
||||
virtual bool isSupported() const override { return true; }
|
||||
virtual bool isHandController() 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); }
|
||||
|
||||
// Device functions
|
||||
virtual void registerToUserInputMapper(UserInputMapper& mapper) override;
|
||||
virtual void assignDefaultInputMapping(UserInputMapper& mapper) override;
|
||||
virtual void update(float deltaTime) override;
|
||||
virtual void focusOutEvent() override;
|
||||
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void keyReleaseEvent(QKeyEvent* event);
|
||||
|
@ -70,32 +88,15 @@ public:
|
|||
void touchUpdateEvent(const QTouchEvent* event);
|
||||
|
||||
void wheelEvent(QWheelEvent* event);
|
||||
|
||||
// Get current state for each channels
|
||||
float getButton(int channel) const;
|
||||
float getAxis(int channel) const;
|
||||
|
||||
|
||||
// Let's make it easy for Qt because we assume we love Qt forever
|
||||
UserInputMapper::Input makeInput(Qt::Key code);
|
||||
UserInputMapper::Input makeInput(Qt::MouseButton code);
|
||||
UserInputMapper::Input makeInput(KeyboardMouseDevice::MouseAxisChannel axis);
|
||||
UserInputMapper::Input makeInput(KeyboardMouseDevice::TouchAxisChannel axis);
|
||||
UserInputMapper::Input makeInput(KeyboardMouseDevice::TouchButtonChannel button);
|
||||
|
||||
KeyboardMouseDevice() {}
|
||||
|
||||
void registerToUserInputMapper(UserInputMapper& mapper);
|
||||
void assignDefaultInputMapping(UserInputMapper& mapper);
|
||||
|
||||
// Update call MUST be called once per simulation loop
|
||||
// It takes care of updating the action states and deltas
|
||||
void update();
|
||||
|
||||
protected:
|
||||
ButtonPressedMap _buttonPressedMap;
|
||||
AxisStateMap _axisStateMap;
|
||||
|
||||
int _deviceID = 0;
|
||||
QPoint _lastCursor;
|
||||
glm::vec2 _lastTouch;
|
||||
bool _isTouching = false;
|
||||
|
@ -103,6 +104,9 @@ 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
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
|
||||
#include "Application.h"
|
||||
#include "devices/MotionTracker.h"
|
||||
//#include "devices/SixenseManager.h"
|
||||
#include "ControllerScriptingInterface.h"
|
||||
|
||||
// TODO: this needs to be removed, as well as any related controller-specific information
|
||||
#include <input-plugins\SixenseManager.h>
|
||||
|
||||
|
||||
ControllerScriptingInterface::ControllerScriptingInterface() :
|
||||
_mouseCaptured(false),
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "Tooltip.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include <input-plugins\SixenseManager.h> // TODO: any references to sixense should be removed here
|
||||
|
||||
|
||||
// Used to animate the magnification windows
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <AudioClient.h>
|
||||
#include <avatar/AvatarManager.h>
|
||||
#include <devices/Faceshift.h>
|
||||
#include <devices/SixenseManager.h>
|
||||
#include <NetworkingConstants.h>
|
||||
|
||||
#include "Application.h"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <avatar/AvatarManager.h>
|
||||
#include <devices/DdeFaceTracker.h>
|
||||
#include <devices/Faceshift.h>
|
||||
#include <devices/SixenseManager.h>
|
||||
#include <input-plugins/SixenseManager.h> // TODO: This should be replaced with InputDevice/InputPlugin, or something similar
|
||||
#include <NetworkingConstants.h>
|
||||
|
||||
#include "Application.h"
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
set(TARGET_NAME input-plugins)
|
||||
|
||||
# set a default root dir for each of our optional externals if it was not passed
|
||||
set(OPTIONAL_EXTERNALS "SDL2" "Sixense")
|
||||
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
||||
string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE)
|
||||
if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR)
|
||||
string(TOLOWER ${EXTERNAL} ${EXTERNAL}_LOWERCASE)
|
||||
set(${${EXTERNAL}_UPPERCASE}_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/${${EXTERNAL}_LOWERCASE}")
|
||||
endif ()
|
||||
endforeach()
|
||||
|
||||
setup_hifi_library()
|
||||
|
||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||
|
@ -16,7 +26,45 @@ find_package(OpenVR REQUIRED)
|
|||
target_include_directories(${TARGET_NAME} PRIVATE ${OPENVR_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES})
|
||||
|
||||
add_dependency_external_projects(Sixense)
|
||||
find_package(Sixense REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE ${SIXENSE_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${SIXENSE_LIBRARIES})
|
||||
#add_dependency_external_projects(Sixense)
|
||||
#find_package(Sixense REQUIRED)
|
||||
#target_include_directories(${TARGET_NAME} PRIVATE ${SIXENSE_INCLUDE_DIRS})
|
||||
#target_link_libraries(${TARGET_NAME} ${SIXENSE_LIBRARIES})
|
||||
|
||||
# perform standard include and linking for found externals
|
||||
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
||||
|
||||
if (${${EXTERNAL}_UPPERCASE}_REQUIRED)
|
||||
find_package(${EXTERNAL} REQUIRED)
|
||||
else ()
|
||||
find_package(${EXTERNAL})
|
||||
endif ()
|
||||
|
||||
if (${${EXTERNAL}_UPPERCASE}_FOUND AND NOT DISABLE_${${EXTERNAL}_UPPERCASE})
|
||||
add_definitions(-DHAVE_${${EXTERNAL}_UPPERCASE})
|
||||
|
||||
# include the library directories (ignoring warnings)
|
||||
if (NOT ${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS)
|
||||
set(${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS ${${${EXTERNAL}_UPPERCASE}_INCLUDE_DIR})
|
||||
endif ()
|
||||
|
||||
include_directories(SYSTEM ${${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS})
|
||||
|
||||
# perform the system include hack for OS X to ignore warnings
|
||||
if (APPLE)
|
||||
foreach(EXTERNAL_INCLUDE_DIR ${${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS})
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${EXTERNAL_INCLUDE_DIR}")
|
||||
endforeach()
|
||||
endif ()
|
||||
|
||||
if (NOT ${${EXTERNAL}_UPPERCASE}_LIBRARIES)
|
||||
set(${${EXTERNAL}_UPPERCASE}_LIBRARIES ${${${EXTERNAL}_UPPERCASE}_LIBRARY})
|
||||
endif ()
|
||||
|
||||
if (NOT APPLE OR NOT ${${EXTERNAL}_UPPERCASE} MATCHES "SIXENSE")
|
||||
target_link_libraries(${TARGET_NAME} ${${${EXTERNAL}_UPPERCASE}_LIBRARIES})
|
||||
elseif (APPLE AND NOT INSTALLER_BUILD)
|
||||
add_definitions(-DSIXENSE_LIB_FILENAME=\"${${${EXTERNAL}_UPPERCASE}_LIBRARY_RELEASE}\")
|
||||
endif ()
|
||||
endif ()
|
||||
endforeach()
|
40
libraries/input-plugins/src/input-plugins/InputDevice.cpp
Normal file
40
libraries/input-plugins/src/input-plugins/InputDevice.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
//
|
||||
// Created by Sam Gondelman on 7/15/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
|
||||
//
|
||||
#include "InputDevice.h"
|
||||
|
||||
float InputDevice::getButton(int channel) const {
|
||||
if (!_buttonPressedMap.empty()) {
|
||||
if (_buttonPressedMap.find(channel) != _buttonPressedMap.end()) {
|
||||
return 1.0f;
|
||||
}
|
||||
else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float InputDevice::getAxis(int channel) const {
|
||||
auto axis = _axisStateMap.find(channel);
|
||||
if (axis != _axisStateMap.end()) {
|
||||
return (*axis).second;
|
||||
}
|
||||
else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
UserInputMapper::PoseValue InputDevice::getPose(int channel) const {
|
||||
auto pose = _poseStateMap.find(channel);
|
||||
if (pose != _poseStateMap.end()) {
|
||||
return (*pose).second;
|
||||
}
|
||||
else {
|
||||
return UserInputMapper::PoseValue();
|
||||
}
|
||||
}
|
51
libraries/input-plugins/src/input-plugins/InputDevice.h
Normal file
51
libraries/input-plugins/src/input-plugins/InputDevice.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// Created by Sam Gondelman on 7/15/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
|
||||
|
||||
#include "UserInputMapper.h"
|
||||
|
||||
// Event types for each controller
|
||||
const unsigned int CONTROLLER_0_EVENT = 1500U;
|
||||
const unsigned int CONTROLLER_1_EVENT = 1501U;
|
||||
|
||||
// NOTE: If something inherits from both InputDevice and InputPlugin, InputPlugin must go first.
|
||||
// e.g. class Example : public InputPlugin, public InputDevice
|
||||
// instead of class Example : public InputDevice, public InputPlugin
|
||||
class InputDevice {
|
||||
public:
|
||||
InputDevice::InputDevice(const QString& name) : _name(name) {}
|
||||
|
||||
typedef std::unordered_set<int> ButtonPressedMap;
|
||||
typedef std::map<int, float> AxisStateMap;
|
||||
typedef std::map<int, UserInputMapper::PoseValue> PoseStateMap;
|
||||
|
||||
// Get current state for each channel
|
||||
float getButton(int channel) const;
|
||||
float getAxis(int channel) const;
|
||||
UserInputMapper::PoseValue getPose(int channel) const;
|
||||
|
||||
virtual void registerToUserInputMapper(UserInputMapper& mapper) = 0;
|
||||
virtual void assignDefaultInputMapping(UserInputMapper& mapper) = 0;
|
||||
|
||||
// Update call MUST be called once per simulation loop
|
||||
// It takes care of updating the action states and deltas
|
||||
virtual void update(float deltaTime) = 0;
|
||||
|
||||
virtual void focusOutEvent() = 0;
|
||||
|
||||
int getDeviceID() { return _deviceID; }
|
||||
|
||||
protected:
|
||||
int _deviceID = 0;
|
||||
|
||||
QString _name;
|
||||
|
||||
ButtonPressedMap _buttonPressedMap;
|
||||
AxisStateMap _axisStateMap;
|
||||
PoseStateMap _poseStateMap;
|
||||
};
|
|
@ -5,4 +5,4 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "InputPlugin.h"
|
||||
#include "InputPlugin.h"
|
|
@ -9,9 +9,14 @@
|
|||
|
||||
#include <plugins/Plugin.h>
|
||||
|
||||
const float DEFAULT_HAND_RETICLE_MOVE_SPEED = 37.5f;
|
||||
|
||||
class InputPlugin : public Plugin {
|
||||
Q_OBJECT
|
||||
public:
|
||||
virtual bool isHandController() = 0;
|
||||
virtual bool isHandController() const = 0;
|
||||
|
||||
virtual void pluginFocusOutEvent() = 0;
|
||||
|
||||
virtual void pluginUpdate(float deltaTime) = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ const float CONTROLLER_THRESHOLD = 0.3f;
|
|||
const float MAX_AXIS = 32768.0f;
|
||||
|
||||
Joystick::Joystick(SDL_JoystickID instanceId, const QString& name, SDL_GameController* sdlGameController) :
|
||||
InputDevice(name),
|
||||
_sdlGameController(sdlGameController),
|
||||
_sdlJoystick(SDL_GameControllerGetJoystick(_sdlGameController)),
|
||||
_instanceId(instanceId)
|
||||
|
@ -40,7 +41,7 @@ void Joystick::closeJoystick() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void Joystick::update() {
|
||||
void Joystick::update(float deltaTime) {
|
||||
for (auto axisState : _axisStateMap) {
|
||||
if (fabsf(axisState.second) < CONTROLLER_THRESHOLD) {
|
||||
_axisStateMap[axisState.first] = 0.0f;
|
||||
|
@ -212,26 +213,6 @@ void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) {
|
|||
#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);
|
||||
|
|
|
@ -20,11 +20,10 @@
|
|||
#undef main
|
||||
#endif
|
||||
|
||||
#include "UserInputMapper.h"
|
||||
#include "InputDevice.h"
|
||||
|
||||
class Joystick : public QObject {
|
||||
class Joystick : public QObject, InputDevice {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString name READ getName)
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
|
@ -44,27 +43,23 @@ public:
|
|||
RIGHT_SHOULDER,
|
||||
LEFT_SHOULDER,
|
||||
};
|
||||
|
||||
const QString& getName() const { return _name; }
|
||||
|
||||
// Device functions
|
||||
virtual void registerToUserInputMapper(UserInputMapper& mapper) override;
|
||||
virtual void assignDefaultInputMapping(UserInputMapper& mapper) override;
|
||||
virtual void update(float deltaTime) override;
|
||||
virtual void focusOutEvent() override;
|
||||
|
||||
Joystick();
|
||||
Joystick() : InputDevice("Joystick") {}
|
||||
~Joystick();
|
||||
|
||||
typedef std::unordered_set<int> ButtonPressedMap;
|
||||
typedef std::map<int, float> 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
|
||||
|
@ -76,27 +71,16 @@ public:
|
|||
void handleButtonEvent(const SDL_ControllerButtonEvent& event);
|
||||
#endif
|
||||
|
||||
const QString& getName() const { return _name; }
|
||||
#ifdef HAVE_SDL2
|
||||
int getInstanceId() const { return _instanceId; }
|
||||
#endif
|
||||
|
||||
int getDeviceID() { return _deviceID; }
|
||||
|
||||
private:
|
||||
#ifdef HAVE_SDL2
|
||||
SDL_GameController* _sdlGameController;
|
||||
SDL_Joystick* _sdlJoystick;
|
||||
SDL_JoystickID _instanceId;
|
||||
#endif
|
||||
|
||||
QString _name;
|
||||
|
||||
protected:
|
||||
int _deviceID = 0;
|
||||
|
||||
ButtonPressedMap _buttonPressedMap;
|
||||
AxisStateMap _axisStateMap;
|
||||
};
|
||||
|
||||
#endif // hifi_Joystick_h
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#include "SDL2Manager.h"
|
||||
|
||||
const QString SDL2Manager::NAME = "SDL2";
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
SDL_JoystickID SDL2Manager::getInstanceId(SDL_GameController* controller) {
|
||||
SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller);
|
||||
|
@ -72,7 +74,15 @@ SDL2Manager* SDL2Manager::getInstance() {
|
|||
return &sharedInstance;
|
||||
}
|
||||
|
||||
void SDL2Manager::focusOutEvent() {
|
||||
bool SDL2Manager::isSupported() const {
|
||||
#ifdef HAVE_SDL2
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SDL2Manager::pluginFocusOutEvent() {
|
||||
#ifdef HAVE_SDL2
|
||||
for (auto joystick : _openJoysticks) {
|
||||
joystick->focusOutEvent();
|
||||
|
@ -80,12 +90,12 @@ void SDL2Manager::focusOutEvent() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void SDL2Manager::update() {
|
||||
void SDL2Manager::pluginUpdate(float deltaTime) {
|
||||
#ifdef HAVE_SDL2
|
||||
if (_isInitialized) {
|
||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||
for (auto joystick : _openJoysticks) {
|
||||
joystick->update();
|
||||
joystick->update(deltaTime);
|
||||
}
|
||||
|
||||
PerformanceTimer perfTimer("SDL2Manager::update");
|
||||
|
|
|
@ -16,22 +16,33 @@
|
|||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "InputPlugin.h"
|
||||
#include "UserInputMapper.h"
|
||||
|
||||
#include "Joystick.h"
|
||||
|
||||
class SDL2Manager : public QObject {
|
||||
class SDL2Manager : public InputPlugin {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SDL2Manager();
|
||||
~SDL2Manager();
|
||||
|
||||
void focusOutEvent();
|
||||
|
||||
void update();
|
||||
|
||||
|
||||
static SDL2Manager* getInstance();
|
||||
|
||||
// Plugin functions
|
||||
virtual bool isSupported() const override;
|
||||
virtual bool isHandController() 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;
|
||||
virtual void pluginUpdate(float deltaTime) override;
|
||||
|
||||
signals:
|
||||
void joystickAdded(Joystick* joystick);
|
||||
|
@ -70,12 +81,11 @@ private:
|
|||
|
||||
int buttonPressed() const { return SDL_PRESSED; }
|
||||
int buttonRelease() const { return SDL_RELEASED; }
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
|
||||
QMap<SDL_JoystickID, Joystick*> _openJoysticks;
|
||||
#endif
|
||||
bool _isInitialized;
|
||||
static const QString NAME;
|
||||
};
|
||||
|
||||
#endif // hifi__SDL2Manager_h
|
||||
|
|
|
@ -11,13 +11,16 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include <avatar/AvatarManager.h>
|
||||
#include <PerfStat.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "NumericalConstants.h"
|
||||
#include "SixenseManager.h"
|
||||
#include "UserActivityLogger.h"
|
||||
#include "InterfaceLogging.h"
|
||||
|
||||
// TODO: This should not be here
|
||||
#include <QLoggingCategory>
|
||||
Q_DECLARE_LOGGING_CATEGORY(inputplugins)
|
||||
Q_LOGGING_CATEGORY(inputplugins, "hifi.inputplugins")
|
||||
|
||||
// These bits aren't used for buttons, so they can be used as masks:
|
||||
const unsigned int LEFT_MASK = 0;
|
||||
|
@ -46,12 +49,15 @@ typedef int (*SixenseTakeIntAndSixenseControllerData)(int, sixenseControllerData
|
|||
|
||||
#endif
|
||||
|
||||
const QString SixenseManager::NAME = "Sixense";
|
||||
|
||||
SixenseManager& SixenseManager::getInstance() {
|
||||
static SixenseManager sharedInstance;
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
SixenseManager::SixenseManager() :
|
||||
InputDevice("Hydra"),
|
||||
#if defined(HAVE_SIXENSE) && defined(__APPLE__)
|
||||
_sixenseLibrary(NULL),
|
||||
#endif
|
||||
|
@ -80,7 +86,15 @@ SixenseManager::~SixenseManager() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void SixenseManager::initialize() {
|
||||
bool SixenseManager::isSupported() const {
|
||||
#ifdef HAVE_SIXENSE
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SixenseManager::init() {
|
||||
#ifdef HAVE_SIXENSE
|
||||
|
||||
if (!_isInitialized) {
|
||||
|
@ -144,18 +158,21 @@ void SixenseManager::setFilter(bool filter) {
|
|||
|
||||
void SixenseManager::update(float deltaTime) {
|
||||
#ifdef HAVE_SIXENSE
|
||||
Hand* hand = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHand();
|
||||
//Hand* hand = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHand();
|
||||
if (_isInitialized && _isEnabled) {
|
||||
_buttonPressedMap.clear();
|
||||
|
||||
#ifdef __APPLE__
|
||||
SixenseBaseFunction sixenseGetNumActiveControllers =
|
||||
(SixenseBaseFunction) _sixenseLibrary->resolve("sixenseGetNumActiveControllers");
|
||||
#endif
|
||||
|
||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||
|
||||
if (sixenseGetNumActiveControllers() == 0) {
|
||||
_hydrasConnected = false;
|
||||
if (_deviceID != 0) {
|
||||
Application::getUserInputMapper()->removeDevice(_deviceID);
|
||||
userInputMapper->removeDevice(_deviceID);
|
||||
_deviceID = 0;
|
||||
_poseStateMap.clear();
|
||||
// if (_prevPalms[0]) {
|
||||
|
@ -171,8 +188,8 @@ void SixenseManager::update(float deltaTime) {
|
|||
PerformanceTimer perfTimer("sixense");
|
||||
if (!_hydrasConnected) {
|
||||
_hydrasConnected = true;
|
||||
registerToUserInputMapper(*Application::getUserInputMapper());
|
||||
getInstance().assignDefaultInputMapping(*Application::getUserInputMapper());
|
||||
registerToUserInputMapper(*userInputMapper);
|
||||
getInstance().assignDefaultInputMapping(*userInputMapper);
|
||||
UserActivityLogger::getInstance().connectedDevice("spatial_controller", "hydra");
|
||||
}
|
||||
|
||||
|
@ -240,7 +257,7 @@ void SixenseManager::update(float deltaTime) {
|
|||
glm::quat rotation(data->rot_quat[3], -data->rot_quat[0], data->rot_quat[1], -data->rot_quat[2]);
|
||||
rotation = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)) * _orbRotation * rotation;
|
||||
|
||||
handlePoseEvent(position, rotation, numActiveControlers - 1);
|
||||
handlePoseEvent(position, rotation, numActiveControllers - 1);
|
||||
} else {
|
||||
_poseStateMap.clear();
|
||||
}
|
||||
|
@ -292,9 +309,9 @@ float SixenseManager::getCursorPixelRangeMult() const {
|
|||
|
||||
void SixenseManager::toggleSixense(bool shouldEnable) {
|
||||
if (shouldEnable && !isInitialized()) {
|
||||
initialize();
|
||||
setFilter(Menu::getInstance()->isOptionChecked(MenuOption::FilterSixense));
|
||||
setLowVelocityFilter(Menu::getInstance()->isOptionChecked(MenuOption::LowVelocityFilter));
|
||||
init();
|
||||
//setFilter(Menu::getInstance()->isOptionChecked(MenuOption::FilterSixense));
|
||||
//setLowVelocityFilter(Menu::getInstance()->isOptionChecked(MenuOption::LowVelocityFilter));
|
||||
}
|
||||
setIsEnabled(shouldEnable);
|
||||
}
|
||||
|
@ -337,11 +354,11 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers)
|
|||
glm::vec3 zAxis = glm::normalize(glm::cross(xAxis, yAxis));
|
||||
xAxis = glm::normalize(glm::cross(yAxis, zAxis));
|
||||
_orbRotation = glm::inverse(glm::quat_cast(glm::mat3(xAxis, yAxis, zAxis)));
|
||||
qCDebug(interfaceapp, "succeess: sixense calibration");
|
||||
qCDebug(inputplugins, "succeess: sixense calibration");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
qCDebug(interfaceapp, "failed: sixense calibration");
|
||||
qCDebug(inputplugins, "failed: sixense calibration");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -360,7 +377,7 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers)
|
|||
if (_calibrationState == CALIBRATION_STATE_IDLE) {
|
||||
float reach = glm::distance(positionLeft, positionRight);
|
||||
if (reach > 2.0f * MINIMUM_ARM_REACH) {
|
||||
qCDebug(interfaceapp, "started: sixense calibration");
|
||||
qCDebug(inputplugins, "started: sixense calibration");
|
||||
_averageLeft = positionLeft;
|
||||
_averageRight = positionRight;
|
||||
_reachLeft = _averageLeft;
|
||||
|
@ -393,7 +410,7 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers)
|
|||
_lastDistance = 0.0f;
|
||||
_reachUp = 0.5f * (_reachLeft + _reachRight);
|
||||
_calibrationState = CALIBRATION_STATE_Y;
|
||||
qCDebug(interfaceapp, "success: sixense calibration: left");
|
||||
qCDebug(inputplugins, "success: sixense calibration: left");
|
||||
}
|
||||
}
|
||||
else if (_calibrationState == CALIBRATION_STATE_Y) {
|
||||
|
@ -412,7 +429,7 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers)
|
|||
_lastDistance = 0.0f;
|
||||
_lockExpiry = now + LOCK_DURATION;
|
||||
_calibrationState = CALIBRATION_STATE_Z;
|
||||
qCDebug(interfaceapp, "success: sixense calibration: up");
|
||||
qCDebug(inputplugins, "success: sixense calibration: up");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -434,7 +451,7 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers)
|
|||
if (fabsf(_lastDistance) > 0.05f * MINIMUM_ARM_REACH) {
|
||||
// lock has expired so clamp the data and move on
|
||||
_calibrationState = CALIBRATION_STATE_COMPLETE;
|
||||
qCDebug(interfaceapp, "success: sixense calibration: forward");
|
||||
qCDebug(inputplugins, "success: sixense calibration: forward");
|
||||
// TODO: it is theoretically possible to detect that the controllers have been
|
||||
// accidentally switched (left hand is holding right controller) and to swap the order.
|
||||
}
|
||||
|
@ -547,7 +564,7 @@ void SixenseManager::registerToUserInputMapper(UserInputMapper& mapper) {
|
|||
// Grab the current free device ID
|
||||
_deviceID = mapper.getFreeDeviceID();
|
||||
|
||||
auto proxy = UserInputMapper::DeviceProxy::Pointer(new UserInputMapper::DeviceProxy("Hydra"));
|
||||
auto proxy = UserInputMapper::DeviceProxy::Pointer(new UserInputMapper::DeviceProxy(_name));
|
||||
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->getPose = [this](const UserInputMapper::Input& input, int timestamp) -> UserInputMapper::PoseValue { return this->getPose(input.getChannel()); };
|
||||
|
@ -633,35 +650,6 @@ void SixenseManager::assignDefaultInputMapping(UserInputMapper& mapper) {
|
|||
|
||||
}
|
||||
|
||||
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::PoseValue SixenseManager::getPose(int channel) const {
|
||||
auto pose = _poseStateMap.find(channel);
|
||||
if (pose != _poseStateMap.end()) {
|
||||
return (*pose).second;
|
||||
} else {
|
||||
return UserInputMapper::PoseValue();
|
||||
}
|
||||
}
|
||||
|
||||
UserInputMapper::Input SixenseManager::makeInput(unsigned int button, int index) {
|
||||
return UserInputMapper::Input(_deviceID, button | (index == 0 ? LEFT_MASK : RIGHT_MASK), UserInputMapper::ChannelType::BUTTON);
|
||||
}
|
|
@ -12,9 +12,6 @@
|
|||
#ifndef hifi_SixenseManager_h
|
||||
#define hifi_SixenseManager_h
|
||||
|
||||
#include <QObject>
|
||||
#include <unordered_set>
|
||||
|
||||
#ifdef HAVE_SIXENSE
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
@ -26,7 +23,8 @@
|
|||
|
||||
#endif
|
||||
|
||||
#include <input-plugins/UserInputMapper.h>
|
||||
#include "InputPlugin.h"
|
||||
#include "InputDevice.h"
|
||||
|
||||
const unsigned int BUTTON_0 = 1U << 0; // the skinny button between 1 and 2
|
||||
const unsigned int BUTTON_1 = 1U << 5;
|
||||
|
@ -36,15 +34,10 @@ 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;
|
||||
const unsigned int CONTROLLER_1_EVENT = 1501U;
|
||||
|
||||
const float DEFAULT_SIXENSE_RETICLE_MOVE_SPEED = 37.5f;
|
||||
const bool DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS = false;
|
||||
|
||||
/// Handles interaction with the Sixense SDK (e.g., Razer Hydra).
|
||||
class SixenseManager : public QObject {
|
||||
// Handles interaction with the Sixense SDK (e.g., Razer Hydra).
|
||||
class SixenseManager : public InputPlugin, public InputDevice {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum JoystickAxisChannel {
|
||||
|
@ -61,13 +54,31 @@ public:
|
|||
};
|
||||
|
||||
static SixenseManager& getInstance();
|
||||
|
||||
void initialize();
|
||||
|
||||
// Plugin functions
|
||||
virtual bool isSupported() const override;
|
||||
virtual bool isHandController() 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); }
|
||||
|
||||
// Device functions
|
||||
virtual void registerToUserInputMapper(UserInputMapper& mapper) override;
|
||||
virtual void assignDefaultInputMapping(UserInputMapper& mapper) override;
|
||||
virtual void update(float deltaTime) override;
|
||||
virtual void focusOutEvent() override;
|
||||
|
||||
bool isInitialized() const { return _isInitialized; }
|
||||
|
||||
void setIsEnabled(bool isEnabled) { _isEnabled = isEnabled; }
|
||||
|
||||
void update(float deltaTime);
|
||||
float getCursorPixelRangeMult() const;
|
||||
|
||||
float getReticleMoveSpeed() const { return _reticleMoveSpeed; }
|
||||
|
@ -75,23 +86,10 @@ public:
|
|||
bool getInvertButtons() const { return _invertButtons; }
|
||||
void setInvertButtons(bool invertSixenseButtons) { _invertButtons = invertSixenseButtons; }
|
||||
|
||||
typedef std::unordered_set<int> ButtonPressedMap;
|
||||
typedef std::map<int, float> AxisStateMap;
|
||||
typedef std::map<int, UserInputMapper::PoseValue> PoseStateMap;
|
||||
|
||||
float getButton(int channel) const;
|
||||
float getAxis(int channel) const;
|
||||
UserInputMapper::PoseValue getPose(int channel) const;
|
||||
|
||||
UserInputMapper::Input makeInput(unsigned int button, int index);
|
||||
UserInputMapper::Input makeInput(JoystickAxisChannel axis, int index);
|
||||
UserInputMapper::Input makeInput(JointChannel joint);
|
||||
|
||||
void registerToUserInputMapper(UserInputMapper& mapper);
|
||||
void assignDefaultInputMapping(UserInputMapper& mapper);
|
||||
|
||||
void focusOutEvent();
|
||||
|
||||
public slots:
|
||||
void toggleSixense(bool shouldEnable);
|
||||
void setFilter(bool filter);
|
||||
|
@ -137,15 +135,10 @@ private:
|
|||
bool _lowVelocityFilter;
|
||||
bool _controllersAtBase;
|
||||
|
||||
float _reticleMoveSpeed = DEFAULT_SIXENSE_RETICLE_MOVE_SPEED;
|
||||
float _reticleMoveSpeed = DEFAULT_HAND_RETICLE_MOVE_SPEED;
|
||||
bool _invertButtons = DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS;
|
||||
|
||||
protected:
|
||||
int _deviceID = 0;
|
||||
|
||||
ButtonPressedMap _buttonPressedMap;
|
||||
AxisStateMap _axisStateMap;
|
||||
PoseStateMap _poseStateMap;
|
||||
static const QString NAME;
|
||||
};
|
||||
|
||||
#endif // hifi_SixenseManager_h
|
|
@ -21,12 +21,6 @@
|
|||
#include "NumericalConstants.h"
|
||||
#include "UserActivityLogger.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
Q_DECLARE_LOGGING_CATEGORY(inputplugins)
|
||||
Q_LOGGING_CATEGORY(inputplugins, "hifi.inputplugins")
|
||||
|
||||
const QString ViveControllerManager::NAME("OpenVR (Vive) Hand Controllers");
|
||||
|
||||
extern vr::IVRSystem *_hmd;
|
||||
extern vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
||||
extern mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
|
||||
|
@ -47,12 +41,15 @@ const unsigned int TRIGGER_BUTTON = 1U << 4;
|
|||
const float CONTROLLER_LENGTH_OFFSET = 0.175f;
|
||||
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),
|
||||
|
@ -67,41 +64,15 @@ ViveControllerManager::~ViveControllerManager() {
|
|||
|
||||
}
|
||||
|
||||
const QString& ViveControllerManager::getName() const {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
bool ViveControllerManager::isSupported() const {
|
||||
return vr::VR_IsHmdPresent();
|
||||
}
|
||||
|
||||
void ViveControllerManager::init() {
|
||||
;
|
||||
}
|
||||
|
||||
void ViveControllerManager::deinit() {
|
||||
;
|
||||
// TODO: deinit openvr? avoid conflicts with display plugin
|
||||
}
|
||||
|
||||
void ViveControllerManager::activate(PluginContainer * container) {
|
||||
activate();
|
||||
}
|
||||
|
||||
/// Called when a plugin is no longer being used. May be called multiple times.
|
||||
void ViveControllerManager::deactivate() {
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the application during it's idle phase. If the plugin needs to do
|
||||
* CPU intensive work, it should launch a thread for that, rather than trying to
|
||||
* do long operations in the idle call
|
||||
*/
|
||||
void ViveControllerManager::idle() {
|
||||
update();
|
||||
}
|
||||
|
||||
void ViveControllerManager::activate() {
|
||||
void ViveControllerManager::init() {
|
||||
if (!_hmd) {
|
||||
vr::HmdError eError = vr::HmdError_None;
|
||||
_hmd = vr::VR_Init(&eError);
|
||||
|
@ -220,7 +191,7 @@ void ViveControllerManager::renderHand(UserInputMapper::PoseValue pose, gpu::Bat
|
|||
batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0);
|
||||
}
|
||||
|
||||
void ViveControllerManager::update() {
|
||||
void ViveControllerManager::update(float deltaTime) {
|
||||
if (!_hmd) {
|
||||
return;
|
||||
}
|
||||
|
@ -333,7 +304,7 @@ void ViveControllerManager::registerToUserInputMapper(UserInputMapper& mapper) {
|
|||
// Grab the current free device ID
|
||||
_deviceID = mapper.getFreeDeviceID();
|
||||
|
||||
auto proxy = UserInputMapper::DeviceProxy::Pointer(new UserInputMapper::DeviceProxy("SteamVR Controller"));
|
||||
auto proxy = UserInputMapper::DeviceProxy::Pointer(new UserInputMapper::DeviceProxy(_name));
|
||||
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->getPose = [this](const UserInputMapper::Input& input, int timestamp) -> UserInputMapper::PoseValue { return this->getPose(input.getChannel()); };
|
||||
|
@ -405,35 +376,6 @@ void ViveControllerManager::assignDefaultInputMapping(UserInputMapper& mapper) {
|
|||
mapper.addInputChannel(UserInputMapper::RIGHT_HAND, makeInput(RIGHT_HAND));
|
||||
}
|
||||
|
||||
float ViveControllerManager::getButton(int channel) const {
|
||||
if (!_buttonPressedMap.empty()) {
|
||||
if (_buttonPressedMap.find(channel) != _buttonPressedMap.end()) {
|
||||
return 1.0f;
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float ViveControllerManager::getAxis(int channel) const {
|
||||
auto axis = _axisStateMap.find(channel);
|
||||
if (axis != _axisStateMap.end()) {
|
||||
return (*axis).second;
|
||||
} else {
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
UserInputMapper::PoseValue ViveControllerManager::getPose(int channel) const {
|
||||
auto pose = _poseStateMap.find(channel);
|
||||
if (pose != _poseStateMap.end()) {
|
||||
return (*pose).second;
|
||||
} else {
|
||||
return UserInputMapper::PoseValue();
|
||||
}
|
||||
}
|
||||
|
||||
UserInputMapper::Input ViveControllerManager::makeInput(unsigned int button, int index) {
|
||||
return UserInputMapper::Input(_deviceID, button | (index == 0 ? LEFT_MASK : RIGHT_MASK), UserInputMapper::ChannelType::BUTTON);
|
||||
}
|
||||
|
|
|
@ -19,34 +19,14 @@
|
|||
|
||||
#include <model/Geometry.h>
|
||||
#include <gpu/Texture.h>
|
||||
#include "InputDevice.h"
|
||||
#include "InputPlugin.h"
|
||||
#include <RenderArgs.h>
|
||||
#include <render/Scene.h>
|
||||
#include "UserInputMapper.h"
|
||||
|
||||
class ViveControllerManager : public InputPlugin {
|
||||
class ViveControllerManager : public InputPlugin, public InputDevice {
|
||||
Q_OBJECT
|
||||
public:
|
||||
virtual const QString& getName() const override;
|
||||
virtual bool isSupported() const override;
|
||||
virtual bool isHandController() { return true; }
|
||||
|
||||
/// Called when plugin is initially loaded, typically at application start
|
||||
virtual void init() override;
|
||||
/// Called when application is shutting down
|
||||
virtual void deinit() override ;
|
||||
|
||||
/// Called when a plugin is being activated for use. May be called multiple times.
|
||||
virtual void activate(PluginContainer * container) override;
|
||||
/// Called when a plugin is no longer being used. May be called multiple times.
|
||||
virtual void deactivate() override;
|
||||
|
||||
/**
|
||||
* Called by the application during it's idle phase. If the plugin needs to do
|
||||
* CPU intensive work, it should launch a thread for that, rather than trying to
|
||||
* do long operations in the idle call
|
||||
*/
|
||||
virtual void idle() override;
|
||||
|
||||
enum JoystickAxisChannel {
|
||||
AXIS_Y_POS = 1U << 1,
|
||||
AXIS_Y_NEG = 1U << 2,
|
||||
|
@ -67,31 +47,35 @@ public:
|
|||
LEFT_HAND = 0,
|
||||
RIGHT_HAND,
|
||||
};
|
||||
|
||||
void focusOutEvent();
|
||||
|
||||
static ViveControllerManager& getInstance();
|
||||
|
||||
// Plugin functions
|
||||
virtual bool isSupported() const override;
|
||||
virtual bool isHandController() 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 pluginFocusOutEvent() override { focusOutEvent(); }
|
||||
virtual void pluginUpdate(float deltaTime) override { update(deltaTime); }
|
||||
|
||||
// Device functions
|
||||
virtual void registerToUserInputMapper(UserInputMapper& mapper) override;
|
||||
virtual void assignDefaultInputMapping(UserInputMapper& mapper) override;
|
||||
virtual void update(float deltaTime) override;
|
||||
virtual void focusOutEvent() override;
|
||||
|
||||
void updateRendering(RenderArgs* args, render::ScenePointer scene, render::PendingChanges pendingChanges);
|
||||
void update();
|
||||
|
||||
static ViveControllerManager& getInstance();
|
||||
|
||||
typedef std::unordered_set<int> ButtonPressedMap;
|
||||
typedef std::map<int, float> AxisStateMap;
|
||||
typedef std::map<int, UserInputMapper::PoseValue> PoseStateMap;
|
||||
|
||||
float getButton(int channel) const;
|
||||
float getAxis(int channel) const;
|
||||
UserInputMapper::PoseValue getPose(int channel) const;
|
||||
|
||||
UserInputMapper::Input makeInput(unsigned int button, int index);
|
||||
UserInputMapper::Input makeInput(JoystickAxisChannel axis, int index);
|
||||
UserInputMapper::Input makeInput(JointChannel joint);
|
||||
|
||||
void registerToUserInputMapper(UserInputMapper& mapper);
|
||||
void assignDefaultInputMapping(UserInputMapper& mapper);
|
||||
|
||||
void activate();
|
||||
|
||||
private:
|
||||
ViveControllerManager();
|
||||
~ViveControllerManager();
|
||||
|
@ -114,13 +98,6 @@ private:
|
|||
int _rightHandRenderID;
|
||||
|
||||
static const QString NAME;
|
||||
|
||||
protected:
|
||||
int _deviceID = 0;
|
||||
|
||||
ButtonPressedMap _buttonPressedMap;
|
||||
AxisStateMap _axisStateMap;
|
||||
PoseStateMap _poseStateMap;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue