correct hand rotation, buttons and axes work

This commit is contained in:
Sam Gondelman 2015-07-06 16:30:56 -07:00
parent 3f6fbd058c
commit 33e4893c17
2 changed files with 119 additions and 102 deletions

View file

@ -13,19 +13,29 @@
#include <PerfStat.h> #include <PerfStat.h>
//#include <display-plugins\openvr\OpenVrDisplayPlugin.h>
#include <display-plugins\openvr\OpenVrHelpers.h> #include <display-plugins\openvr\OpenVrHelpers.h>
#include "NumericalConstants.h"
#include "UserActivityLogger.h" #include "UserActivityLogger.h"
#include <QLoggingCategory> #include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(inputplugins) Q_DECLARE_LOGGING_CATEGORY(inputplugins)
Q_LOGGING_CATEGORY(inputplugins, "hifi.inputplugins") Q_LOGGING_CATEGORY(inputplugins, "hifi.inputplugins")
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];
const unsigned int LEFT_MASK = 0U;
const unsigned int RIGHT_MASK = 1U;
const uint64_t VR_BUTTON_A = 1U << 1;
const uint64_t VR_GRIP_BUTTON = 1U << 2;
const uint64_t VR_TRACKPAD_BUTTON = 1ULL << 32;
const unsigned int BUTTON_A = 1U << 1;
const unsigned int GRIP_BUTTON = 1U << 2;
const unsigned int TRACKPAD_BUTTON = 1U << 3;
ViveControllerManager& ViveControllerManager::getInstance() { ViveControllerManager& ViveControllerManager::getInstance() {
static ViveControllerManager sharedInstance; static ViveControllerManager sharedInstance;
return sharedInstance; return sharedInstance;
@ -57,61 +67,64 @@ void ViveControllerManager::update() {
if (!_hmd) { if (!_hmd) {
return; return;
} }
_buttonPressedMap.clear();
if (_isInitialized && _isEnabled) { if (_isInitialized && _isEnabled) {
PerformanceTimer perfTimer("Vive Controllers"); PerformanceTimer perfTimer("Vive Controllers");
int trackedControllerCount = 0; int numTrackedControllers = 0;
for (vr::TrackedDeviceIndex_t unTrackedDevice = vr::k_unTrackedDeviceIndex_Hmd + 1; for (vr::TrackedDeviceIndex_t device = vr::k_unTrackedDeviceIndex_Hmd + 1;
unTrackedDevice < vr::k_unMaxTrackedDeviceCount && trackedControllerCount < 2; ++unTrackedDevice) { device < vr::k_unMaxTrackedDeviceCount && numTrackedControllers < 2; ++device) {
if (!_hmd->IsTrackedDeviceConnected(unTrackedDevice)) { if (!_hmd->IsTrackedDeviceConnected(device)) {
continue; continue;
} }
if(_hmd->GetTrackedDeviceClass(unTrackedDevice) != vr::TrackedDeviceClass_Controller) { if(_hmd->GetTrackedDeviceClass(device) != vr::TrackedDeviceClass_Controller) {
continue;
}
if (!_trackedDevicePose[device].bPoseIsValid) {
continue; continue;
} }
trackedControllerCount++; numTrackedControllers++;
if(!_trackedDevicePose[unTrackedDevice].bPoseIsValid) { const mat4& mat = _trackedDevicePoseMat4[device];
continue;
}
const mat4& mat = _trackedDevicePoseMat4[unTrackedDevice];
handlePoseEvent(mat, trackedControllerCount - 1); handlePoseEvent(mat, numTrackedControllers - 1);
// handle inputs // handle inputs
//vr::VRControllerState_t* controllerState; vr::VRControllerState_t controllerState = vr::VRControllerState_t();
//if(_hmd->GetControllerState(unTrackedDevice, controllerState)) { if (_hmd->GetControllerState(device, &controllerState)) {
// handleButtonEvent(controllerState.ulButtonPressed, numTrackedControllers - 1);
//} for (int i = 0; i < 5; i++) {
handleAxisEvent(Axis(i), controllerState.rAxis[i].x, controllerState.rAxis[i].y, numTrackedControllers - 1);
}
}
} }
auto userInputMapper = DependencyManager::get<UserInputMapper>(); auto userInputMapper = DependencyManager::get<UserInputMapper>();
if (trackedControllerCount == 0) { if (numTrackedControllers == 0) {
if (_deviceID != 0) { if (_deviceID != 0) {
userInputMapper->removeDevice(_deviceID); userInputMapper->removeDevice(_deviceID);
_deviceID = 0; _deviceID = 0;
_poseStateMap[makeInput(LEFT_HAND).getChannel()] = UserInputMapper::PoseValue(); _poseStateMap[makeInput(LEFT_HAND).getChannel()] = UserInputMapper::PoseValue();
_poseStateMap[makeInput(RIGHT_HAND).getChannel()] = UserInputMapper::PoseValue(); _poseStateMap[makeInput(RIGHT_HAND).getChannel()] = UserInputMapper::PoseValue();
} }
_trackedControllers = trackedControllerCount; _trackedControllers = numTrackedControllers;
return; return;
} }
if (_trackedControllers == 0 && trackedControllerCount > 0) { if (_trackedControllers == 0 && numTrackedControllers > 0) {
registerToUserInputMapper(*userInputMapper); registerToUserInputMapper(*userInputMapper);
assignDefaultInputMapping(*userInputMapper); assignDefaultInputMapping(*userInputMapper);
UserActivityLogger::getInstance().connectedDevice("spatial_controller", "steamVR"); UserActivityLogger::getInstance().connectedDevice("spatial_controller", "steamVR");
} }
_trackedControllers = trackedControllerCount; _trackedControllers = numTrackedControllers;
} }
} }
@ -120,18 +133,27 @@ void ViveControllerManager::focusOutEvent() {
_buttonPressedMap.clear(); _buttonPressedMap.clear();
}; };
void ViveControllerManager::handleAxisEvent(float stickX, float stickY, float trigger, int index) { void ViveControllerManager::handleAxisEvent(Axis axis, float x, float y, int index) {
// _axisStateMap[makeInput(AXIS_Y_POS, index).getChannel()] = (stickY > 0.0f) ? stickY : 0.0f; if (axis == TRACKPAD_AXIS) {
// _axisStateMap[makeInput(AXIS_Y_NEG, index).getChannel()] = (stickY < 0.0f) ? -stickY : 0.0f; _axisStateMap[makeInput(AXIS_Y_POS, index).getChannel()] = (y > 0.0f) ? y : 0.0f;
// _axisStateMap[makeInput(AXIS_X_POS, index).getChannel()] = (stickX > 0.0f) ? stickX : 0.0f; _axisStateMap[makeInput(AXIS_Y_NEG, index).getChannel()] = (y < 0.0f) ? -y : 0.0f;
// _axisStateMap[makeInput(AXIS_X_NEG, index).getChannel()] = (stickX < 0.0f) ? -stickX : 0.0f; _axisStateMap[makeInput(AXIS_X_POS, index).getChannel()] = (x > 0.0f) ? x : 0.0f;
// _axisStateMap[makeInput(BACK_TRIGGER, index).getChannel()] = trigger; _axisStateMap[makeInput(AXIS_X_NEG, index).getChannel()] = (x < 0.0f) ? -x : 0.0f;
} else if (axis == TRIGGER_AXIS) {
_axisStateMap[makeInput(BACK_TRIGGER, index).getChannel()] = x;
}
} }
void ViveControllerManager::handleButtonEvent(unsigned int buttons, int index) { void ViveControllerManager::handleButtonEvent(uint64_t buttons, int index) {
// if (buttons & BUTTON_0) { if (buttons & VR_BUTTON_A) {
// _buttonPressedMap.insert(makeInput(BUTTON_0, index).getChannel()); _buttonPressedMap.insert(makeInput(BUTTON_A, index).getChannel());
// } }
if (buttons & VR_GRIP_BUTTON) {
_buttonPressedMap.insert(makeInput(GRIP_BUTTON, index).getChannel());
}
if (buttons & VR_TRACKPAD_BUTTON) {
_buttonPressedMap.insert(makeInput(TRACKPAD_BUTTON, index).getChannel());
}
} }
void ViveControllerManager::handlePoseEvent(const mat4& mat, int index) { void ViveControllerManager::handlePoseEvent(const mat4& mat, int index) {
@ -140,8 +162,15 @@ void ViveControllerManager::handlePoseEvent(const mat4& mat, int index) {
glm::vec3 position = glm::vec3(mat[3][0], mat[3][1], mat[3][2]) - headPos; glm::vec3 position = glm::vec3(mat[3][0], mat[3][1], mat[3][2]) - headPos;
glm::quat rotation = glm::quat_cast(mat); glm::quat rotation = glm::quat_cast(mat);
//rotation = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)) * rotation;
_poseStateMap[makeInput(JointChannel(index)).getChannel()] = UserInputMapper::PoseValue(position, rotation); // Flip the rotation appropriately for each hand
if (index == LEFT_HAND) {
rotation = rotation * glm::angleAxis(PI, glm::vec3(1.0f, 0.0f, 0.0f)) * glm::angleAxis(PI_OVER_TWO, glm::vec3(0.0f, 0.0f, 1.0f));
} else if (index == RIGHT_HAND) {
rotation = rotation * glm::angleAxis(PI, glm::vec3(1.0f, 0.0f, 0.0f)) * glm::angleAxis(PI + PI_OVER_TWO, glm::vec3(0.0f, 0.0f, 1.0f));
}
_poseStateMap[makeInput(JointChannel(index)).getChannel()] = UserInputMapper::PoseValue(position, - rotation);
} }
void ViveControllerManager::registerToUserInputMapper(UserInputMapper& mapper) { void ViveControllerManager::registerToUserInputMapper(UserInputMapper& mapper) {
@ -154,35 +183,25 @@ void ViveControllerManager::registerToUserInputMapper(UserInputMapper& mapper) {
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()); };
proxy->getAvailabeInputs = [this] () -> QVector<UserInputMapper::InputPair> { proxy->getAvailabeInputs = [this] () -> QVector<UserInputMapper::InputPair> {
QVector<UserInputMapper::InputPair> availableInputs; QVector<UserInputMapper::InputPair> availableInputs;
// availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_0, 0), "Left Start")); availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_A, 0), "Left Button A"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_1, 0), "Left Button 1")); availableInputs.append(UserInputMapper::InputPair(makeInput(GRIP_BUTTON, 0), "Left Grip Button"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_2, 0), "Left Button 2")); availableInputs.append(UserInputMapper::InputPair(makeInput(TRACKPAD_BUTTON, 0), "Left Trackpad Button"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_3, 0), "Left Button 3"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_4, 0), "Left Button 4")); availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_POS, 0), "Left Trackpad Up"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_NEG, 0), "Left Trackpad Down"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_FWD, 0), "L1")); availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_POS, 0), "Left Trackpad Right"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BACK_TRIGGER, 0), "L2")); availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_NEG, 0), "Left Trackpad Left"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BACK_TRIGGER, 0), "Left Back Trigger"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_POS, 0), "Left Stick Up"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_NEG, 0), "Left Stick Down")); availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_A, 1), "Right Button A"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_POS, 0), "Left Stick Right")); availableInputs.append(UserInputMapper::InputPair(makeInput(GRIP_BUTTON, 1), "Right Grip Button"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_NEG, 0), "Left Stick Left")); availableInputs.append(UserInputMapper::InputPair(makeInput(TRACKPAD_BUTTON, 1), "Right Trackpad Button"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_TRIGGER, 0), "Left Trigger Press"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_POS, 1), "Right Trackpad Up"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_0, 1), "Right Start")); availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_NEG, 1), "Right Trackpad Down"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_1, 1), "Right Button 1")); availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_POS, 1), "Right Trackpad Right"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_2, 1), "Right Button 2")); availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_NEG, 1), "Right Trackpad Left"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_3, 1), "Right Button 3")); availableInputs.append(UserInputMapper::InputPair(makeInput(BACK_TRIGGER, 1), "Right Back Trigger"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_4, 1), "Right Button 4"));
//
// availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_FWD, 1), "R1"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BACK_TRIGGER, 1), "R2"));
//
// availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_POS, 1), "Right Stick Up"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_NEG, 1), "Right Stick Down"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_POS, 1), "Right Stick Right"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_NEG, 1), "Right Stick Left"));
// availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_TRIGGER, 1), "Right Trigger Press"));
return availableInputs; return availableInputs;
}; };
@ -196,36 +215,28 @@ void ViveControllerManager::registerToUserInputMapper(UserInputMapper& mapper) {
void ViveControllerManager::assignDefaultInputMapping(UserInputMapper& mapper) { void ViveControllerManager::assignDefaultInputMapping(UserInputMapper& mapper) {
const float JOYSTICK_MOVE_SPEED = 1.0f; const float JOYSTICK_MOVE_SPEED = 1.0f;
const float JOYSTICK_YAW_SPEED = 0.5f;
const float JOYSTICK_PITCH_SPEED = 0.25f;
const float BUTTON_MOVE_SPEED = 1.0f;
const float BOOM_SPEED = 0.1f; const float BOOM_SPEED = 0.1f;
// // Left Joystick: Movement, strafing // Left Trackpad: Movement, strafing
// mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(AXIS_Y_POS, 0), JOYSTICK_MOVE_SPEED); mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(AXIS_Y_POS, 0), JOYSTICK_MOVE_SPEED);
// mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(AXIS_Y_NEG, 0), JOYSTICK_MOVE_SPEED); mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(AXIS_Y_NEG, 0), JOYSTICK_MOVE_SPEED);
// mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(AXIS_X_POS, 0), JOYSTICK_MOVE_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(AXIS_X_POS, 0), JOYSTICK_MOVE_SPEED);
// mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(AXIS_X_NEG, 0), JOYSTICK_MOVE_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(AXIS_X_NEG, 0), JOYSTICK_MOVE_SPEED);
//
// // Right Joystick: Camera orientation // Right Trackpad: Vertical movement, zooming
// mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(AXIS_X_POS, 1), JOYSTICK_YAW_SPEED); mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(AXIS_Y_POS, 1), JOYSTICK_MOVE_SPEED);
// mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(AXIS_X_NEG, 1), JOYSTICK_YAW_SPEED); mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(AXIS_Y_NEG, 1), JOYSTICK_MOVE_SPEED);
// mapper.addInputChannel(UserInputMapper::PITCH_UP, makeInput(AXIS_Y_POS, 1), JOYSTICK_PITCH_SPEED); mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(AXIS_X_POS, 1), BOOM_SPEED);
// mapper.addInputChannel(UserInputMapper::PITCH_DOWN, makeInput(AXIS_Y_NEG, 1), JOYSTICK_PITCH_SPEED); mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(AXIS_X_NEG, 1), BOOM_SPEED);
//
// // Buttons
// mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(BUTTON_3, 0), BOOM_SPEED);
// mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(BUTTON_1, 0), BOOM_SPEED);
//
// mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(BUTTON_3, 1), BUTTON_MOVE_SPEED);
// mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(BUTTON_1, 1), BUTTON_MOVE_SPEED);
//
// mapper.addInputChannel(UserInputMapper::SHIFT, makeInput(BUTTON_2, 0));
// mapper.addInputChannel(UserInputMapper::SHIFT, makeInput(BUTTON_2, 1));
//
// mapper.addInputChannel(UserInputMapper::ACTION1, makeInput(BUTTON_4, 0));
// mapper.addInputChannel(UserInputMapper::ACTION2, makeInput(BUTTON_4, 1));
// Buttons
mapper.addInputChannel(UserInputMapper::SHIFT, makeInput(GRIP_BUTTON, 0));
mapper.addInputChannel(UserInputMapper::SHIFT, makeInput(GRIP_BUTTON, 1));
mapper.addInputChannel(UserInputMapper::ACTION1, makeInput(BUTTON_A, 0));
mapper.addInputChannel(UserInputMapper::ACTION2, makeInput(BUTTON_A, 1));
// Hands
mapper.addInputChannel(UserInputMapper::LEFT_HAND, makeInput(LEFT_HAND)); mapper.addInputChannel(UserInputMapper::LEFT_HAND, makeInput(LEFT_HAND));
mapper.addInputChannel(UserInputMapper::RIGHT_HAND, makeInput(RIGHT_HAND)); mapper.addInputChannel(UserInputMapper::RIGHT_HAND, makeInput(RIGHT_HAND));
} }
@ -260,13 +271,11 @@ UserInputMapper::PoseValue ViveControllerManager::getPose(int channel) const {
} }
UserInputMapper::Input ViveControllerManager::makeInput(unsigned int button, int index) { UserInputMapper::Input ViveControllerManager::makeInput(unsigned int button, int index) {
return UserInputMapper::Input(); 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);
} }
UserInputMapper::Input ViveControllerManager::makeInput(ViveControllerManager::JoystickAxisChannel axis, int index) { UserInputMapper::Input ViveControllerManager::makeInput(ViveControllerManager::JoystickAxisChannel axis, int index) {
return UserInputMapper::Input(); return UserInputMapper::Input(_deviceID, axis | (index == 0 ? LEFT_MASK : RIGHT_MASK), UserInputMapper::ChannelType::AXIS);
// return UserInputMapper::Input(_deviceID, axis | (index == 0 ? LEFT_MASK : RIGHT_MASK), UserInputMapper::ChannelType::AXIS);
} }
UserInputMapper::Input ViveControllerManager::makeInput(JointChannel joint) { UserInputMapper::Input ViveControllerManager::makeInput(JointChannel joint) {

View file

@ -24,11 +24,19 @@ class ViveControllerManager : public QObject {
public: public:
enum JoystickAxisChannel { enum JoystickAxisChannel {
AXIS_Y_POS = 1U << 0, AXIS_Y_POS = 1U << 1,
AXIS_Y_NEG = 1U << 3, AXIS_Y_NEG = 1U << 2,
AXIS_X_POS = 1U << 4, AXIS_X_POS = 1U << 3,
AXIS_X_NEG = 1U << 5, AXIS_X_NEG = 1U << 4,
BACK_TRIGGER = 1U << 6, BACK_TRIGGER = 1U << 5,
};
enum Axis {
TRACKPAD_AXIS = 0,
TRIGGER_AXIS,
AXIS_2,
AXIS_3,
AXIS_4,
}; };
enum JointChannel { enum JointChannel {
@ -63,8 +71,8 @@ private:
ViveControllerManager(); ViveControllerManager();
~ViveControllerManager(); ~ViveControllerManager();
void handleButtonEvent(unsigned int buttons, int index); void handleButtonEvent(uint64_t buttons, int index);
void handleAxisEvent(float x, float y, float trigger, int index); void handleAxisEvent(Axis axis, float x, float y, int index);
void handlePoseEvent(const mat4& mat, int index); void handlePoseEvent(const mat4& mat, int index);
bool _isInitialized; bool _isInitialized;