diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp index 3085b377f0..1413ef0ce1 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp +++ b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp @@ -108,19 +108,13 @@ void SixenseManager::setSixenseFilter(bool filter) { void SixenseManager::pluginUpdate(float deltaTime, bool jointsCaptured) { _inputDevice->update(deltaTime, jointsCaptured); - if (_inputDevice->_calibrationState == CALIBRATION_STATE_COMPLETE) { + if (_inputDevice->_requestReset) { _container->requestReset(); - _inputDevice->_calibrationState = CALIBRATION_STATE_IDLE; + _inputDevice->_requestReset = false; } } void SixenseManager::InputDevice::update(float deltaTime, bool jointsCaptured) { - // FIXME - Some of the code in update() will crash if you haven't actually activated the - // plugin. But we want register with the UserInputMapper if we don't call this. - // We need to clean this up. - //if (!_activated) { - // return; - //} #ifdef HAVE_SIXENSE _buttonPressedMap.clear(); @@ -221,21 +215,23 @@ static const float MINIMUM_ARM_REACH = 0.3f; // meters static const float MAXIMUM_NOISE_LEVEL = 0.05f; // meters static const quint64 LOCK_DURATION = USECS_PER_SECOND / 4; // time for lock to be acquired -void SixenseManager::InputDevice::updateCalibration(void* controllersX) { - auto controllers = reinterpret_cast(controllersX); +static bool calibrationRequested(sixenseControllerData* controllers) { + return (controllers[0].buttons == BUTTON_FWD && controllers[1].buttons == BUTTON_FWD); +} + +void SixenseManager::InputDevice::updateCalibration(sixenseControllerData* controllers) { const sixenseControllerData* dataLeft = controllers; const sixenseControllerData* dataRight = controllers + 1; - // calibration only happpens while both hands are holding BUTTON_FORWARD - if (dataLeft->buttons != BUTTON_FWD || dataRight->buttons != BUTTON_FWD) { - if (_calibrationState == CALIBRATION_STATE_IDLE) { - return; - } + // Calibration buttons aren't set, so check the state, and request a reset if necessary. + if (!calibrationRequested(controllers)) { switch (_calibrationState) { + case CALIBRATION_STATE_IDLE: + return; case CALIBRATION_STATE_COMPLETE: { // compute calibration results - _avatarPosition = - 0.5f * (_reachLeft + _reachRight); // neck is midway between right and left hands + _avatarPosition = -0.5f * (_reachLeft + _reachRight); // neck is midway between right and left hands glm::vec3 xAxis = glm::normalize(_reachRight - _reachLeft); glm::vec3 zAxis = glm::normalize(glm::cross(xAxis, Vectors::UNIT_Y)); xAxis = glm::normalize(glm::cross(Vectors::UNIT_Y, zAxis)); @@ -243,16 +239,19 @@ void SixenseManager::InputDevice::updateCalibration(void* controllersX) { const float Y_OFFSET_CALIBRATED_HANDS_TO_AVATAR = -0.3f; _avatarPosition.y += Y_OFFSET_CALIBRATED_HANDS_TO_AVATAR; qCDebug(inputplugins, "succeess: sixense calibration"); + _requestReset = true; } break; default: - _calibrationState = CALIBRATION_STATE_IDLE; qCDebug(inputplugins, "failed: sixense calibration"); break; } + + _calibrationState = CALIBRATION_STATE_IDLE; return; } + // Calibration buttons are set, continue calibration work // NOTE: Sixense API returns pos data in millimeters but we IMMEDIATELY convert to meters. const float* pos = dataLeft->pos; glm::vec3 positionLeft(pos[0], pos[1], pos[2]); @@ -261,6 +260,7 @@ void SixenseManager::InputDevice::updateCalibration(void* controllersX) { glm::vec3 positionRight(pos[0], pos[1], pos[2]); positionRight *= METERS_PER_MILLIMETER; + // Gather initial calibration data if (_calibrationState == CALIBRATION_STATE_IDLE) { float reach = glm::distance(positionLeft, positionRight); if (reach > 2.0f * MINIMUM_ARM_REACH) { @@ -308,9 +308,6 @@ void SixenseManager::InputDevice::focusOutEvent() { _buttonPressedMap.clear(); }; -void SixenseManager::InputDevice::handleAxisEvent(float stickX, float stickY, float trigger, bool left) { -} - void SixenseManager::InputDevice::handleButtonEvent(unsigned int buttons, bool left) { using namespace controller; if (buttons & BUTTON_0) { diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.h b/libraries/input-plugins/src/input-plugins/SixenseManager.h index bdfbd539cb..8452e1f096 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.h +++ b/libraries/input-plugins/src/input-plugins/SixenseManager.h @@ -19,6 +19,20 @@ #include "InputPlugin.h" +class QLibrary; + +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_2 = 1U << 6; +const unsigned int BUTTON_3 = 1U << 3; +const unsigned int BUTTON_4 = 1U << 4; +const unsigned int BUTTON_FWD = 1U << 7; +const unsigned int BUTTON_TRIGGER = 1U << 8; + +const bool DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS = false; + +struct _sixenseControllerData; + // Handles interaction with the Sixense SDK (e.g., Razer Hydra). class SixenseManager : public InputPlugin { Q_OBJECT @@ -65,9 +79,8 @@ private: virtual void focusOutEvent() override; void handleButtonEvent(unsigned int buttons, bool left); - void handleAxisEvent(float x, float y, float trigger, bool left); void handlePoseEvent(float deltaTime, glm::vec3 position, glm::quat rotation, bool left); - void updateCalibration(void* controllers); + void updateCalibration(_sixenseControllerData* controllers); friend class SixenseManager; @@ -79,6 +92,7 @@ private: glm::quat _avatarRotation; // in hydra-frame float _lastDistance; + bool _requestReset { false }; // these are measured values used to compute the calibration results quint64 _lockExpiry; glm::vec3 _averageLeft;