mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 06:29:30 +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})
|
project(${TARGET_NAME})
|
||||||
|
|
||||||
# set a default root dir for each of our optional externals if it was not passed
|
# 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})
|
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
||||||
string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE)
|
string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE)
|
||||||
if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR)
|
if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR)
|
||||||
|
|
|
@ -124,6 +124,7 @@
|
||||||
#include "devices/RealSense.h"
|
#include "devices/RealSense.h"
|
||||||
#include "devices/MIDIManager.h"
|
#include "devices/MIDIManager.h"
|
||||||
#include <input-plugins/SDL2Manager.h>
|
#include <input-plugins/SDL2Manager.h>
|
||||||
|
#include <input-plugins/SixenseManager.h>
|
||||||
#include <input-plugins/ViveControllerManager.h>
|
#include <input-plugins/ViveControllerManager.h>
|
||||||
#include "RenderDeferredTask.h"
|
#include "RenderDeferredTask.h"
|
||||||
#include "scripting/AccountScriptingInterface.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);
|
connect(ddeTracker.data(), &FaceTracker::muteToggled, this, &Application::faceTrackerMuteToggled);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ViveControllerManager::getInstance().init();
|
|
||||||
if (ViveControllerManager::getInstance().isSupported()) {
|
if (ViveControllerManager::getInstance().isSupported()) {
|
||||||
ViveControllerManager::getInstance().activate();
|
ViveControllerManager::getInstance().init();
|
||||||
|
ViveControllerManager::getInstance().activate(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
_oldHandMouseX[0] = -1;
|
_oldHandMouseX[0] = -1;
|
||||||
|
@ -1640,10 +1641,10 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::focusOutEvent(QFocusEvent* event) {
|
void Application::focusOutEvent(QFocusEvent* event) {
|
||||||
_keyboardMouseDevice.focusOutEvent(event);
|
_keyboardMouseDevice.pluginFocusOutEvent();
|
||||||
SixenseManager::getInstance().focusOutEvent();
|
SixenseManager::getInstance().pluginFocusOutEvent();
|
||||||
SDL2Manager::getInstance()->focusOutEvent();
|
SDL2Manager::getInstance()->pluginFocusOutEvent();
|
||||||
ViveControllerManager::getInstance().focusOutEvent();
|
ViveControllerManager::getInstance().pluginFocusOutEvent();
|
||||||
|
|
||||||
// synthesize events for keys currently pressed, since we may not get their release events
|
// synthesize events for keys currently pressed, since we may not get their release events
|
||||||
foreach (int key, _keysPressed) {
|
foreach (int key, _keysPressed) {
|
||||||
|
@ -2615,15 +2616,16 @@ void Application::update(float deltaTime) {
|
||||||
_lastFaceTrackerUpdate = 0;
|
_lastFaceTrackerUpdate = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SixenseManager::getInstance().update(deltaTime);
|
|
||||||
SDL2Manager::getInstance()->update();
|
|
||||||
ViveControllerManager::getInstance().update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||||
userInputMapper->setSensorToWorldMat(_myAvatar->getSensorToWorldMatrix());
|
userInputMapper->setSensorToWorldMat(_myAvatar->getSensorToWorldMatrix());
|
||||||
userInputMapper->update(deltaTime);
|
userInputMapper->update(deltaTime);
|
||||||
_keyboardMouseDevice.update();
|
|
||||||
|
_keyboardMouseDevice.pluginUpdate(deltaTime);
|
||||||
|
SixenseManager::getInstance().pluginUpdate(deltaTime);
|
||||||
|
SDL2Manager::getInstance()->pluginUpdate(deltaTime);
|
||||||
|
ViveControllerManager::getInstance().pluginUpdate(deltaTime);
|
||||||
|
|
||||||
// Dispatch input events
|
// Dispatch input events
|
||||||
_controllerScriptingInterface.updateInputControllers();
|
_controllerScriptingInterface.updateInputControllers();
|
||||||
|
@ -3734,7 +3736,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
}
|
}
|
||||||
renderArgs->_debugFlags = renderDebugFlags;
|
renderArgs->_debugFlags = renderDebugFlags;
|
||||||
_entities.render(renderArgs);
|
_entities.render(renderArgs);
|
||||||
ViveControllerManager::getInstance().updateRendering(renderArgs, _main3DScene, pendingChanges);
|
//ViveControllerManager::getInstance().updateRendering(renderArgs, _main3DScene, pendingChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
// render the ambient occlusion effect if enabled
|
// render the ambient occlusion effect if enabled
|
||||||
|
|
|
@ -54,7 +54,6 @@
|
||||||
#include "Stars.h"
|
#include "Stars.h"
|
||||||
#include "avatar/Avatar.h"
|
#include "avatar/Avatar.h"
|
||||||
#include "avatar/MyAvatar.h"
|
#include "avatar/MyAvatar.h"
|
||||||
#include "devices/SixenseManager.h"
|
|
||||||
#include "scripting/ControllerScriptingInterface.h"
|
#include "scripting/ControllerScriptingInterface.h"
|
||||||
#include "scripting/WebWindowClass.h"
|
#include "scripting/WebWindowClass.h"
|
||||||
#include "ui/BandwidthDialog.h"
|
#include "ui/BandwidthDialog.h"
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "devices/DdeFaceTracker.h"
|
#include "devices/DdeFaceTracker.h"
|
||||||
#include "devices/Faceshift.h"
|
#include "devices/Faceshift.h"
|
||||||
#include "devices/RealSense.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 "MainWindow.h"
|
||||||
#include "scripting/MenuScriptingInterface.h"
|
#include "scripting/MenuScriptingInterface.h"
|
||||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
//
|
//
|
||||||
#include "KeyboardMouseDevice.h"
|
#include "KeyboardMouseDevice.h"
|
||||||
|
|
||||||
void KeyboardMouseDevice::update() {
|
const QString KeyboardMouseDevice::NAME = "Keyboard";
|
||||||
|
|
||||||
|
void KeyboardMouseDevice::update(float deltaTime) {
|
||||||
_axisStateMap.clear();
|
_axisStateMap.clear();
|
||||||
|
|
||||||
// For touch event, we need to check that the last event is not too long ago
|
// 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();
|
_buttonPressedMap.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -159,7 +161,7 @@ void KeyboardMouseDevice::registerToUserInputMapper(UserInputMapper& mapper) {
|
||||||
// Grab the current free device ID
|
// Grab the current free device ID
|
||||||
_deviceID = mapper.getFreeDeviceID();
|
_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->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->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input.getChannel()); };
|
||||||
proxy->getAvailabeInputs = [this] () -> QVector<UserInputMapper::InputPair> {
|
proxy->getAvailabeInputs = [this] () -> QVector<UserInputMapper::InputPair> {
|
||||||
|
@ -282,23 +284,3 @@ void KeyboardMouseDevice::assignDefaultInputMapping(UserInputMapper& mapper) {
|
||||||
mapper.addInputChannel(UserInputMapper::ACTION2, makeInput(Qt::Key_T));
|
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 <QTouchEvent>
|
||||||
#include <chrono>
|
#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:
|
public:
|
||||||
|
|
||||||
enum KeyboardChannel {
|
enum KeyboardChannel {
|
||||||
KEYBOARD_FIRST = 0,
|
KEYBOARD_FIRST = 0,
|
||||||
KEYBOARD_LAST = 255,
|
KEYBOARD_LAST = 255,
|
||||||
|
@ -53,10 +54,27 @@ public:
|
||||||
TOUCH_BUTTON_PRESS = TOUCH_AXIS_Y_NEG + 1,
|
TOUCH_BUTTON_PRESS = TOUCH_AXIS_Y_NEG + 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::unordered_set<int> ButtonPressedMap;
|
KeyboardMouseDevice() : InputDevice("Keyboard") {}
|
||||||
typedef std::map<int, float> AxisStateMap; // 8 axes
|
|
||||||
|
|
||||||
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 keyPressEvent(QKeyEvent* event);
|
||||||
void keyReleaseEvent(QKeyEvent* event);
|
void keyReleaseEvent(QKeyEvent* event);
|
||||||
|
@ -70,32 +88,15 @@ public:
|
||||||
void touchUpdateEvent(const QTouchEvent* event);
|
void touchUpdateEvent(const QTouchEvent* event);
|
||||||
|
|
||||||
void wheelEvent(QWheelEvent* 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
|
// Let's make it easy for Qt because we assume we love Qt forever
|
||||||
UserInputMapper::Input makeInput(Qt::Key code);
|
UserInputMapper::Input makeInput(Qt::Key code);
|
||||||
UserInputMapper::Input makeInput(Qt::MouseButton code);
|
UserInputMapper::Input makeInput(Qt::MouseButton code);
|
||||||
UserInputMapper::Input makeInput(KeyboardMouseDevice::MouseAxisChannel axis);
|
UserInputMapper::Input makeInput(KeyboardMouseDevice::MouseAxisChannel axis);
|
||||||
UserInputMapper::Input makeInput(KeyboardMouseDevice::TouchAxisChannel axis);
|
UserInputMapper::Input makeInput(KeyboardMouseDevice::TouchAxisChannel axis);
|
||||||
UserInputMapper::Input makeInput(KeyboardMouseDevice::TouchButtonChannel button);
|
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:
|
protected:
|
||||||
ButtonPressedMap _buttonPressedMap;
|
|
||||||
AxisStateMap _axisStateMap;
|
|
||||||
|
|
||||||
int _deviceID = 0;
|
|
||||||
QPoint _lastCursor;
|
QPoint _lastCursor;
|
||||||
glm::vec2 _lastTouch;
|
glm::vec2 _lastTouch;
|
||||||
bool _isTouching = false;
|
bool _isTouching = false;
|
||||||
|
@ -103,6 +104,9 @@ protected:
|
||||||
glm::vec2 evalAverageTouchPoints(const QList<QTouchEvent::TouchPoint>& points) const;
|
glm::vec2 evalAverageTouchPoints(const QList<QTouchEvent::TouchPoint>& points) const;
|
||||||
std::chrono::high_resolution_clock _clock;
|
std::chrono::high_resolution_clock _clock;
|
||||||
std::chrono::high_resolution_clock::time_point _lastTouchTime;
|
std::chrono::high_resolution_clock::time_point _lastTouchTime;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const QString NAME;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_KeyboardMouseDevice_h
|
#endif // hifi_KeyboardMouseDevice_h
|
||||||
|
|
|
@ -16,9 +16,11 @@
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "devices/MotionTracker.h"
|
#include "devices/MotionTracker.h"
|
||||||
//#include "devices/SixenseManager.h"
|
|
||||||
#include "ControllerScriptingInterface.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() :
|
ControllerScriptingInterface::ControllerScriptingInterface() :
|
||||||
_mouseCaptured(false),
|
_mouseCaptured(false),
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "Tooltip.h"
|
#include "Tooltip.h"
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
#include <input-plugins\SixenseManager.h> // TODO: any references to sixense should be removed here
|
||||||
|
|
||||||
|
|
||||||
// Used to animate the magnification windows
|
// Used to animate the magnification windows
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include <AudioClient.h>
|
#include <AudioClient.h>
|
||||||
#include <avatar/AvatarManager.h>
|
#include <avatar/AvatarManager.h>
|
||||||
#include <devices/Faceshift.h>
|
#include <devices/Faceshift.h>
|
||||||
#include <devices/SixenseManager.h>
|
|
||||||
#include <NetworkingConstants.h>
|
#include <NetworkingConstants.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include <avatar/AvatarManager.h>
|
#include <avatar/AvatarManager.h>
|
||||||
#include <devices/DdeFaceTracker.h>
|
#include <devices/DdeFaceTracker.h>
|
||||||
#include <devices/Faceshift.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 <NetworkingConstants.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
set(TARGET_NAME input-plugins)
|
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()
|
setup_hifi_library()
|
||||||
|
|
||||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
# 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_include_directories(${TARGET_NAME} PRIVATE ${OPENVR_INCLUDE_DIRS})
|
||||||
target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES})
|
target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES})
|
||||||
|
|
||||||
add_dependency_external_projects(Sixense)
|
#add_dependency_external_projects(Sixense)
|
||||||
find_package(Sixense REQUIRED)
|
#find_package(Sixense REQUIRED)
|
||||||
target_include_directories(${TARGET_NAME} PRIVATE ${SIXENSE_INCLUDE_DIRS})
|
#target_include_directories(${TARGET_NAME} PRIVATE ${SIXENSE_INCLUDE_DIRS})
|
||||||
target_link_libraries(${TARGET_NAME} ${SIXENSE_LIBRARIES})
|
#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.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// 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>
|
#include <plugins/Plugin.h>
|
||||||
|
|
||||||
|
const float DEFAULT_HAND_RETICLE_MOVE_SPEED = 37.5f;
|
||||||
|
|
||||||
class InputPlugin : public Plugin {
|
class InputPlugin : public Plugin {
|
||||||
Q_OBJECT
|
|
||||||
public:
|
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;
|
const float MAX_AXIS = 32768.0f;
|
||||||
|
|
||||||
Joystick::Joystick(SDL_JoystickID instanceId, const QString& name, SDL_GameController* sdlGameController) :
|
Joystick::Joystick(SDL_JoystickID instanceId, const QString& name, SDL_GameController* sdlGameController) :
|
||||||
|
InputDevice(name),
|
||||||
_sdlGameController(sdlGameController),
|
_sdlGameController(sdlGameController),
|
||||||
_sdlJoystick(SDL_GameControllerGetJoystick(_sdlGameController)),
|
_sdlJoystick(SDL_GameControllerGetJoystick(_sdlGameController)),
|
||||||
_instanceId(instanceId)
|
_instanceId(instanceId)
|
||||||
|
@ -40,7 +41,7 @@ void Joystick::closeJoystick() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Joystick::update() {
|
void Joystick::update(float deltaTime) {
|
||||||
for (auto axisState : _axisStateMap) {
|
for (auto axisState : _axisStateMap) {
|
||||||
if (fabsf(axisState.second) < CONTROLLER_THRESHOLD) {
|
if (fabsf(axisState.second) < CONTROLLER_THRESHOLD) {
|
||||||
_axisStateMap[axisState.first] = 0.0f;
|
_axisStateMap[axisState.first] = 0.0f;
|
||||||
|
@ -212,26 +213,6 @@ void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) {
|
||||||
#endif
|
#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
|
#ifdef HAVE_SDL2
|
||||||
UserInputMapper::Input Joystick::makeInput(SDL_GameControllerButton button) {
|
UserInputMapper::Input Joystick::makeInput(SDL_GameControllerButton button) {
|
||||||
return UserInputMapper::Input(_deviceID, button, UserInputMapper::ChannelType::BUTTON);
|
return UserInputMapper::Input(_deviceID, button, UserInputMapper::ChannelType::BUTTON);
|
||||||
|
|
|
@ -20,11 +20,10 @@
|
||||||
#undef main
|
#undef main
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "UserInputMapper.h"
|
#include "InputDevice.h"
|
||||||
|
|
||||||
class Joystick : public QObject {
|
class Joystick : public QObject, InputDevice {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(QString name READ getName)
|
Q_PROPERTY(QString name READ getName)
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
|
@ -44,27 +43,23 @@ public:
|
||||||
RIGHT_SHOULDER,
|
RIGHT_SHOULDER,
|
||||||
LEFT_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();
|
~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
|
#ifdef HAVE_SDL2
|
||||||
UserInputMapper::Input makeInput(SDL_GameControllerButton button);
|
UserInputMapper::Input makeInput(SDL_GameControllerButton button);
|
||||||
#endif
|
#endif
|
||||||
UserInputMapper::Input makeInput(Joystick::JoystickAxisChannel axis);
|
UserInputMapper::Input makeInput(Joystick::JoystickAxisChannel axis);
|
||||||
|
|
||||||
void registerToUserInputMapper(UserInputMapper& mapper);
|
|
||||||
void assignDefaultInputMapping(UserInputMapper& mapper);
|
|
||||||
|
|
||||||
void update();
|
|
||||||
void focusOutEvent();
|
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
Joystick(SDL_JoystickID instanceId, const QString& name, SDL_GameController* sdlGameController);
|
Joystick(SDL_JoystickID instanceId, const QString& name, SDL_GameController* sdlGameController);
|
||||||
#endif
|
#endif
|
||||||
|
@ -76,27 +71,16 @@ public:
|
||||||
void handleButtonEvent(const SDL_ControllerButtonEvent& event);
|
void handleButtonEvent(const SDL_ControllerButtonEvent& event);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const QString& getName() const { return _name; }
|
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
int getInstanceId() const { return _instanceId; }
|
int getInstanceId() const { return _instanceId; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int getDeviceID() { return _deviceID; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
SDL_GameController* _sdlGameController;
|
SDL_GameController* _sdlGameController;
|
||||||
SDL_Joystick* _sdlJoystick;
|
SDL_Joystick* _sdlJoystick;
|
||||||
SDL_JoystickID _instanceId;
|
SDL_JoystickID _instanceId;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QString _name;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int _deviceID = 0;
|
|
||||||
|
|
||||||
ButtonPressedMap _buttonPressedMap;
|
|
||||||
AxisStateMap _axisStateMap;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Joystick_h
|
#endif // hifi_Joystick_h
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
#include "SDL2Manager.h"
|
#include "SDL2Manager.h"
|
||||||
|
|
||||||
|
const QString SDL2Manager::NAME = "SDL2";
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
SDL_JoystickID SDL2Manager::getInstanceId(SDL_GameController* controller) {
|
SDL_JoystickID SDL2Manager::getInstanceId(SDL_GameController* controller) {
|
||||||
SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller);
|
SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller);
|
||||||
|
@ -72,7 +74,15 @@ SDL2Manager* SDL2Manager::getInstance() {
|
||||||
return &sharedInstance;
|
return &sharedInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL2Manager::focusOutEvent() {
|
bool SDL2Manager::isSupported() const {
|
||||||
|
#ifdef HAVE_SDL2
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDL2Manager::pluginFocusOutEvent() {
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
for (auto joystick : _openJoysticks) {
|
for (auto joystick : _openJoysticks) {
|
||||||
joystick->focusOutEvent();
|
joystick->focusOutEvent();
|
||||||
|
@ -80,12 +90,12 @@ void SDL2Manager::focusOutEvent() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL2Manager::update() {
|
void SDL2Manager::pluginUpdate(float deltaTime) {
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
if (_isInitialized) {
|
if (_isInitialized) {
|
||||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||||
for (auto joystick : _openJoysticks) {
|
for (auto joystick : _openJoysticks) {
|
||||||
joystick->update();
|
joystick->update(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformanceTimer perfTimer("SDL2Manager::update");
|
PerformanceTimer perfTimer("SDL2Manager::update");
|
||||||
|
|
|
@ -16,22 +16,33 @@
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "InputPlugin.h"
|
||||||
#include "UserInputMapper.h"
|
#include "UserInputMapper.h"
|
||||||
|
|
||||||
#include "Joystick.h"
|
#include "Joystick.h"
|
||||||
|
|
||||||
class SDL2Manager : public QObject {
|
class SDL2Manager : public InputPlugin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SDL2Manager();
|
SDL2Manager();
|
||||||
~SDL2Manager();
|
~SDL2Manager();
|
||||||
|
|
||||||
void focusOutEvent();
|
|
||||||
|
|
||||||
void update();
|
|
||||||
|
|
||||||
static SDL2Manager* getInstance();
|
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:
|
signals:
|
||||||
void joystickAdded(Joystick* joystick);
|
void joystickAdded(Joystick* joystick);
|
||||||
|
@ -70,12 +81,11 @@ private:
|
||||||
|
|
||||||
int buttonPressed() const { return SDL_PRESSED; }
|
int buttonPressed() const { return SDL_PRESSED; }
|
||||||
int buttonRelease() const { return SDL_RELEASED; }
|
int buttonRelease() const { return SDL_RELEASED; }
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
QMap<SDL_JoystickID, Joystick*> _openJoysticks;
|
QMap<SDL_JoystickID, Joystick*> _openJoysticks;
|
||||||
#endif
|
#endif
|
||||||
bool _isInitialized;
|
bool _isInitialized;
|
||||||
|
static const QString NAME;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi__SDL2Manager_h
|
#endif // hifi__SDL2Manager_h
|
||||||
|
|
|
@ -11,13 +11,16 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <avatar/AvatarManager.h>
|
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "NumericalConstants.h"
|
||||||
#include "SixenseManager.h"
|
#include "SixenseManager.h"
|
||||||
#include "UserActivityLogger.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:
|
// These bits aren't used for buttons, so they can be used as masks:
|
||||||
const unsigned int LEFT_MASK = 0;
|
const unsigned int LEFT_MASK = 0;
|
||||||
|
@ -46,12 +49,15 @@ typedef int (*SixenseTakeIntAndSixenseControllerData)(int, sixenseControllerData
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const QString SixenseManager::NAME = "Sixense";
|
||||||
|
|
||||||
SixenseManager& SixenseManager::getInstance() {
|
SixenseManager& SixenseManager::getInstance() {
|
||||||
static SixenseManager sharedInstance;
|
static SixenseManager sharedInstance;
|
||||||
return sharedInstance;
|
return sharedInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
SixenseManager::SixenseManager() :
|
SixenseManager::SixenseManager() :
|
||||||
|
InputDevice("Hydra"),
|
||||||
#if defined(HAVE_SIXENSE) && defined(__APPLE__)
|
#if defined(HAVE_SIXENSE) && defined(__APPLE__)
|
||||||
_sixenseLibrary(NULL),
|
_sixenseLibrary(NULL),
|
||||||
#endif
|
#endif
|
||||||
|
@ -80,7 +86,15 @@ SixenseManager::~SixenseManager() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SixenseManager::initialize() {
|
bool SixenseManager::isSupported() const {
|
||||||
|
#ifdef HAVE_SIXENSE
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SixenseManager::init() {
|
||||||
#ifdef HAVE_SIXENSE
|
#ifdef HAVE_SIXENSE
|
||||||
|
|
||||||
if (!_isInitialized) {
|
if (!_isInitialized) {
|
||||||
|
@ -144,18 +158,21 @@ void SixenseManager::setFilter(bool filter) {
|
||||||
|
|
||||||
void SixenseManager::update(float deltaTime) {
|
void SixenseManager::update(float deltaTime) {
|
||||||
#ifdef HAVE_SIXENSE
|
#ifdef HAVE_SIXENSE
|
||||||
Hand* hand = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHand();
|
//Hand* hand = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHand();
|
||||||
if (_isInitialized && _isEnabled) {
|
if (_isInitialized && _isEnabled) {
|
||||||
_buttonPressedMap.clear();
|
_buttonPressedMap.clear();
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
SixenseBaseFunction sixenseGetNumActiveControllers =
|
SixenseBaseFunction sixenseGetNumActiveControllers =
|
||||||
(SixenseBaseFunction) _sixenseLibrary->resolve("sixenseGetNumActiveControllers");
|
(SixenseBaseFunction) _sixenseLibrary->resolve("sixenseGetNumActiveControllers");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||||
|
|
||||||
if (sixenseGetNumActiveControllers() == 0) {
|
if (sixenseGetNumActiveControllers() == 0) {
|
||||||
_hydrasConnected = false;
|
_hydrasConnected = false;
|
||||||
if (_deviceID != 0) {
|
if (_deviceID != 0) {
|
||||||
Application::getUserInputMapper()->removeDevice(_deviceID);
|
userInputMapper->removeDevice(_deviceID);
|
||||||
_deviceID = 0;
|
_deviceID = 0;
|
||||||
_poseStateMap.clear();
|
_poseStateMap.clear();
|
||||||
// if (_prevPalms[0]) {
|
// if (_prevPalms[0]) {
|
||||||
|
@ -171,8 +188,8 @@ void SixenseManager::update(float deltaTime) {
|
||||||
PerformanceTimer perfTimer("sixense");
|
PerformanceTimer perfTimer("sixense");
|
||||||
if (!_hydrasConnected) {
|
if (!_hydrasConnected) {
|
||||||
_hydrasConnected = true;
|
_hydrasConnected = true;
|
||||||
registerToUserInputMapper(*Application::getUserInputMapper());
|
registerToUserInputMapper(*userInputMapper);
|
||||||
getInstance().assignDefaultInputMapping(*Application::getUserInputMapper());
|
getInstance().assignDefaultInputMapping(*userInputMapper);
|
||||||
UserActivityLogger::getInstance().connectedDevice("spatial_controller", "hydra");
|
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]);
|
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;
|
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 {
|
} else {
|
||||||
_poseStateMap.clear();
|
_poseStateMap.clear();
|
||||||
}
|
}
|
||||||
|
@ -292,9 +309,9 @@ float SixenseManager::getCursorPixelRangeMult() const {
|
||||||
|
|
||||||
void SixenseManager::toggleSixense(bool shouldEnable) {
|
void SixenseManager::toggleSixense(bool shouldEnable) {
|
||||||
if (shouldEnable && !isInitialized()) {
|
if (shouldEnable && !isInitialized()) {
|
||||||
initialize();
|
init();
|
||||||
setFilter(Menu::getInstance()->isOptionChecked(MenuOption::FilterSixense));
|
//setFilter(Menu::getInstance()->isOptionChecked(MenuOption::FilterSixense));
|
||||||
setLowVelocityFilter(Menu::getInstance()->isOptionChecked(MenuOption::LowVelocityFilter));
|
//setLowVelocityFilter(Menu::getInstance()->isOptionChecked(MenuOption::LowVelocityFilter));
|
||||||
}
|
}
|
||||||
setIsEnabled(shouldEnable);
|
setIsEnabled(shouldEnable);
|
||||||
}
|
}
|
||||||
|
@ -337,11 +354,11 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers)
|
||||||
glm::vec3 zAxis = glm::normalize(glm::cross(xAxis, yAxis));
|
glm::vec3 zAxis = glm::normalize(glm::cross(xAxis, yAxis));
|
||||||
xAxis = glm::normalize(glm::cross(yAxis, zAxis));
|
xAxis = glm::normalize(glm::cross(yAxis, zAxis));
|
||||||
_orbRotation = glm::inverse(glm::quat_cast(glm::mat3(xAxis, yAxis, zAxis)));
|
_orbRotation = glm::inverse(glm::quat_cast(glm::mat3(xAxis, yAxis, zAxis)));
|
||||||
qCDebug(interfaceapp, "succeess: sixense calibration");
|
qCDebug(inputplugins, "succeess: sixense calibration");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
qCDebug(interfaceapp, "failed: sixense calibration");
|
qCDebug(inputplugins, "failed: sixense calibration");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +377,7 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers)
|
||||||
if (_calibrationState == CALIBRATION_STATE_IDLE) {
|
if (_calibrationState == CALIBRATION_STATE_IDLE) {
|
||||||
float reach = glm::distance(positionLeft, positionRight);
|
float reach = glm::distance(positionLeft, positionRight);
|
||||||
if (reach > 2.0f * MINIMUM_ARM_REACH) {
|
if (reach > 2.0f * MINIMUM_ARM_REACH) {
|
||||||
qCDebug(interfaceapp, "started: sixense calibration");
|
qCDebug(inputplugins, "started: sixense calibration");
|
||||||
_averageLeft = positionLeft;
|
_averageLeft = positionLeft;
|
||||||
_averageRight = positionRight;
|
_averageRight = positionRight;
|
||||||
_reachLeft = _averageLeft;
|
_reachLeft = _averageLeft;
|
||||||
|
@ -393,7 +410,7 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers)
|
||||||
_lastDistance = 0.0f;
|
_lastDistance = 0.0f;
|
||||||
_reachUp = 0.5f * (_reachLeft + _reachRight);
|
_reachUp = 0.5f * (_reachLeft + _reachRight);
|
||||||
_calibrationState = CALIBRATION_STATE_Y;
|
_calibrationState = CALIBRATION_STATE_Y;
|
||||||
qCDebug(interfaceapp, "success: sixense calibration: left");
|
qCDebug(inputplugins, "success: sixense calibration: left");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (_calibrationState == CALIBRATION_STATE_Y) {
|
else if (_calibrationState == CALIBRATION_STATE_Y) {
|
||||||
|
@ -412,7 +429,7 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers)
|
||||||
_lastDistance = 0.0f;
|
_lastDistance = 0.0f;
|
||||||
_lockExpiry = now + LOCK_DURATION;
|
_lockExpiry = now + LOCK_DURATION;
|
||||||
_calibrationState = CALIBRATION_STATE_Z;
|
_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) {
|
if (fabsf(_lastDistance) > 0.05f * MINIMUM_ARM_REACH) {
|
||||||
// lock has expired so clamp the data and move on
|
// lock has expired so clamp the data and move on
|
||||||
_calibrationState = CALIBRATION_STATE_COMPLETE;
|
_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
|
// 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.
|
// 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
|
// Grab the current free device ID
|
||||||
_deviceID = mapper.getFreeDeviceID();
|
_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->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->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()); };
|
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) {
|
UserInputMapper::Input SixenseManager::makeInput(unsigned int button, int index) {
|
||||||
return UserInputMapper::Input(_deviceID, button | (index == 0 ? LEFT_MASK : RIGHT_MASK), UserInputMapper::ChannelType::BUTTON);
|
return UserInputMapper::Input(_deviceID, button | (index == 0 ? LEFT_MASK : RIGHT_MASK), UserInputMapper::ChannelType::BUTTON);
|
||||||
}
|
}
|
|
@ -12,9 +12,6 @@
|
||||||
#ifndef hifi_SixenseManager_h
|
#ifndef hifi_SixenseManager_h
|
||||||
#define hifi_SixenseManager_h
|
#define hifi_SixenseManager_h
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
#ifdef HAVE_SIXENSE
|
#ifdef HAVE_SIXENSE
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
@ -26,7 +23,8 @@
|
||||||
|
|
||||||
#endif
|
#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_0 = 1U << 0; // the skinny button between 1 and 2
|
||||||
const unsigned int BUTTON_1 = 1U << 5;
|
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_FWD = 1U << 7;
|
||||||
const unsigned int BUTTON_TRIGGER = 1U << 8;
|
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;
|
const bool DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS = false;
|
||||||
|
|
||||||
/// Handles interaction with the Sixense SDK (e.g., Razer Hydra).
|
// Handles interaction with the Sixense SDK (e.g., Razer Hydra).
|
||||||
class SixenseManager : public QObject {
|
class SixenseManager : public InputPlugin, public InputDevice {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum JoystickAxisChannel {
|
enum JoystickAxisChannel {
|
||||||
|
@ -61,13 +54,31 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
static SixenseManager& getInstance();
|
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; }
|
bool isInitialized() const { return _isInitialized; }
|
||||||
|
|
||||||
void setIsEnabled(bool isEnabled) { _isEnabled = isEnabled; }
|
void setIsEnabled(bool isEnabled) { _isEnabled = isEnabled; }
|
||||||
|
|
||||||
void update(float deltaTime);
|
|
||||||
float getCursorPixelRangeMult() const;
|
float getCursorPixelRangeMult() const;
|
||||||
|
|
||||||
float getReticleMoveSpeed() const { return _reticleMoveSpeed; }
|
float getReticleMoveSpeed() const { return _reticleMoveSpeed; }
|
||||||
|
@ -75,23 +86,10 @@ public:
|
||||||
bool getInvertButtons() const { return _invertButtons; }
|
bool getInvertButtons() const { return _invertButtons; }
|
||||||
void setInvertButtons(bool invertSixenseButtons) { _invertButtons = invertSixenseButtons; }
|
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(unsigned int button, int index);
|
||||||
UserInputMapper::Input makeInput(JoystickAxisChannel axis, int index);
|
UserInputMapper::Input makeInput(JoystickAxisChannel axis, int index);
|
||||||
UserInputMapper::Input makeInput(JointChannel joint);
|
UserInputMapper::Input makeInput(JointChannel joint);
|
||||||
|
|
||||||
void registerToUserInputMapper(UserInputMapper& mapper);
|
|
||||||
void assignDefaultInputMapping(UserInputMapper& mapper);
|
|
||||||
|
|
||||||
void focusOutEvent();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void toggleSixense(bool shouldEnable);
|
void toggleSixense(bool shouldEnable);
|
||||||
void setFilter(bool filter);
|
void setFilter(bool filter);
|
||||||
|
@ -137,15 +135,10 @@ private:
|
||||||
bool _lowVelocityFilter;
|
bool _lowVelocityFilter;
|
||||||
bool _controllersAtBase;
|
bool _controllersAtBase;
|
||||||
|
|
||||||
float _reticleMoveSpeed = DEFAULT_SIXENSE_RETICLE_MOVE_SPEED;
|
float _reticleMoveSpeed = DEFAULT_HAND_RETICLE_MOVE_SPEED;
|
||||||
bool _invertButtons = DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS;
|
bool _invertButtons = DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS;
|
||||||
|
|
||||||
protected:
|
static const QString NAME;
|
||||||
int _deviceID = 0;
|
|
||||||
|
|
||||||
ButtonPressedMap _buttonPressedMap;
|
|
||||||
AxisStateMap _axisStateMap;
|
|
||||||
PoseStateMap _poseStateMap;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_SixenseManager_h
|
#endif // hifi_SixenseManager_h
|
|
@ -21,12 +21,6 @@
|
||||||
#include "NumericalConstants.h"
|
#include "NumericalConstants.h"
|
||||||
#include "UserActivityLogger.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::IVRSystem *_hmd;
|
||||||
extern vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
extern vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
||||||
extern mat4 _trackedDevicePoseMat4[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 float CONTROLLER_LENGTH_OFFSET = 0.175f;
|
||||||
const QString CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b";
|
const QString CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b";
|
||||||
|
|
||||||
|
const QString ViveControllerManager::NAME = "OpenVR";
|
||||||
|
|
||||||
ViveControllerManager& ViveControllerManager::getInstance() {
|
ViveControllerManager& ViveControllerManager::getInstance() {
|
||||||
static ViveControllerManager sharedInstance;
|
static ViveControllerManager sharedInstance;
|
||||||
return sharedInstance;
|
return sharedInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
ViveControllerManager::ViveControllerManager() :
|
ViveControllerManager::ViveControllerManager() :
|
||||||
|
InputDevice("SteamVR Controller"),
|
||||||
_isInitialized(false),
|
_isInitialized(false),
|
||||||
_isEnabled(true),
|
_isEnabled(true),
|
||||||
_trackedControllers(0),
|
_trackedControllers(0),
|
||||||
|
@ -67,41 +64,15 @@ ViveControllerManager::~ViveControllerManager() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString& ViveControllerManager::getName() const {
|
|
||||||
return NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ViveControllerManager::isSupported() const {
|
bool ViveControllerManager::isSupported() const {
|
||||||
return vr::VR_IsHmdPresent();
|
return vr::VR_IsHmdPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViveControllerManager::init() {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViveControllerManager::deinit() {
|
void ViveControllerManager::deinit() {
|
||||||
;
|
// TODO: deinit openvr? avoid conflicts with display plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViveControllerManager::activate(PluginContainer * container) {
|
void ViveControllerManager::init() {
|
||||||
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() {
|
|
||||||
if (!_hmd) {
|
if (!_hmd) {
|
||||||
vr::HmdError eError = vr::HmdError_None;
|
vr::HmdError eError = vr::HmdError_None;
|
||||||
_hmd = vr::VR_Init(&eError);
|
_hmd = vr::VR_Init(&eError);
|
||||||
|
@ -220,7 +191,7 @@ void ViveControllerManager::renderHand(UserInputMapper::PoseValue pose, gpu::Bat
|
||||||
batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0);
|
batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViveControllerManager::update() {
|
void ViveControllerManager::update(float deltaTime) {
|
||||||
if (!_hmd) {
|
if (!_hmd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -333,7 +304,7 @@ void ViveControllerManager::registerToUserInputMapper(UserInputMapper& mapper) {
|
||||||
// Grab the current free device ID
|
// Grab the current free device ID
|
||||||
_deviceID = mapper.getFreeDeviceID();
|
_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->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->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()); };
|
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));
|
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) {
|
UserInputMapper::Input ViveControllerManager::makeInput(unsigned int button, int index) {
|
||||||
return UserInputMapper::Input(_deviceID, button | (index == 0 ? LEFT_MASK : RIGHT_MASK), UserInputMapper::ChannelType::BUTTON);
|
return UserInputMapper::Input(_deviceID, button | (index == 0 ? LEFT_MASK : RIGHT_MASK), UserInputMapper::ChannelType::BUTTON);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,34 +19,14 @@
|
||||||
|
|
||||||
#include <model/Geometry.h>
|
#include <model/Geometry.h>
|
||||||
#include <gpu/Texture.h>
|
#include <gpu/Texture.h>
|
||||||
|
#include "InputDevice.h"
|
||||||
#include "InputPlugin.h"
|
#include "InputPlugin.h"
|
||||||
#include <RenderArgs.h>
|
#include <RenderArgs.h>
|
||||||
#include <render/Scene.h>
|
#include <render/Scene.h>
|
||||||
#include "UserInputMapper.h"
|
|
||||||
|
|
||||||
class ViveControllerManager : public InputPlugin {
|
class ViveControllerManager : public InputPlugin, public InputDevice {
|
||||||
|
Q_OBJECT
|
||||||
public:
|
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 {
|
enum JoystickAxisChannel {
|
||||||
AXIS_Y_POS = 1U << 1,
|
AXIS_Y_POS = 1U << 1,
|
||||||
AXIS_Y_NEG = 1U << 2,
|
AXIS_Y_NEG = 1U << 2,
|
||||||
|
@ -67,31 +47,35 @@ public:
|
||||||
LEFT_HAND = 0,
|
LEFT_HAND = 0,
|
||||||
RIGHT_HAND,
|
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 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(unsigned int button, int index);
|
||||||
UserInputMapper::Input makeInput(JoystickAxisChannel axis, int index);
|
UserInputMapper::Input makeInput(JoystickAxisChannel axis, int index);
|
||||||
UserInputMapper::Input makeInput(JointChannel joint);
|
UserInputMapper::Input makeInput(JointChannel joint);
|
||||||
|
|
||||||
void registerToUserInputMapper(UserInputMapper& mapper);
|
|
||||||
void assignDefaultInputMapping(UserInputMapper& mapper);
|
|
||||||
|
|
||||||
void activate();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ViveControllerManager();
|
ViveControllerManager();
|
||||||
~ViveControllerManager();
|
~ViveControllerManager();
|
||||||
|
@ -114,13 +98,6 @@ private:
|
||||||
int _rightHandRenderID;
|
int _rightHandRenderID;
|
||||||
|
|
||||||
static const QString NAME;
|
static const QString NAME;
|
||||||
|
|
||||||
protected:
|
|
||||||
int _deviceID = 0;
|
|
||||||
|
|
||||||
ButtonPressedMap _buttonPressedMap;
|
|
||||||
AxisStateMap _axisStateMap;
|
|
||||||
PoseStateMap _poseStateMap;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue