mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 13:43:49 +02:00
added left/right hand click actions, vive controller should be able to emulate mouse events
This commit is contained in:
parent
5293effc2e
commit
d75353eeb2
10 changed files with 168 additions and 17 deletions
|
@ -671,6 +671,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
#endif
|
||||
|
||||
ViveControllerManager::getInstance().activate();
|
||||
|
||||
_oldHandMouseX[0] = -1;
|
||||
_oldHandMouseY[0] = -1;
|
||||
_oldHandMouseX[1] = -1;
|
||||
_oldHandMouseY[1] = -1;
|
||||
_oldHandLeftClick[0] = false;
|
||||
_oldHandRightClick[0] = false;
|
||||
_oldHandLeftClick[1] = false;
|
||||
_oldHandRightClick[1] = false;
|
||||
|
||||
auto applicationUpdater = DependencyManager::get<AutoUpdater>();
|
||||
connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);
|
||||
|
@ -2622,6 +2631,12 @@ void Application::update(float deltaTime) {
|
|||
Hand* hand = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHand();
|
||||
setPalmData(hand, leftHand, LEFT_HAND_INDEX);
|
||||
setPalmData(hand, rightHand, RIGHT_HAND_INDEX);
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::HandMouseInput)) {
|
||||
emulateMouse(hand, userInputMapper->getActionState(UserInputMapper::LEFT_HAND_CLICK),
|
||||
userInputMapper->getActionState(UserInputMapper::SHIFT), LEFT_HAND_INDEX);
|
||||
emulateMouse(hand, userInputMapper->getActionState(UserInputMapper::RIGHT_HAND_CLICK),
|
||||
userInputMapper->getActionState(UserInputMapper::SHIFT), RIGHT_HAND_INDEX);
|
||||
}
|
||||
}
|
||||
_myAvatar->setDriveKeys(BOOM_IN, userInputMapper->getActionState(UserInputMapper::BOOM_IN));
|
||||
_myAvatar->setDriveKeys(BOOM_OUT, userInputMapper->getActionState(UserInputMapper::BOOM_OUT));
|
||||
|
@ -2802,6 +2817,121 @@ void Application::setPalmData(Hand* hand, UserInputMapper::PoseValue pose, int i
|
|||
palm->setRawRotation(pose.getRotation());
|
||||
}
|
||||
|
||||
void Application::emulateMouse(Hand* hand, float click, float shift, int index) {
|
||||
// Locate the palm, if it exists and is active
|
||||
PalmData* palm;
|
||||
bool foundHand = false;
|
||||
for (size_t j = 0; j < hand->getNumPalms(); j++) {
|
||||
if (hand->getPalms()[j].getSixenseID() == index) {
|
||||
palm = &(hand->getPalms()[j]);
|
||||
foundHand = true;
|
||||
}
|
||||
}
|
||||
if (!foundHand || !palm->isActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Process the mouse events
|
||||
QPoint pos;
|
||||
|
||||
unsigned int deviceID = index == 0 ? CONTROLLER_0_EVENT : CONTROLLER_1_EVENT;
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::HandLasers) || qApp->isHMDMode()) {
|
||||
pos = qApp->getApplicationCompositor().getPalmClickLocation(palm);
|
||||
}
|
||||
else {
|
||||
// Get directon relative to avatar orientation
|
||||
glm::vec3 direction = glm::inverse(_myAvatar->getOrientation()) * palm->getFingerDirection();
|
||||
|
||||
// Get the angles, scaled between (-0.5,0.5)
|
||||
float xAngle = (atan2(direction.z, direction.x) + M_PI_2);
|
||||
float yAngle = 0.5f - ((atan2f(direction.z, direction.y) + (float)M_PI_2));
|
||||
auto canvasSize = qApp->getCanvasSize();
|
||||
// Get the pixel range over which the xAngle and yAngle are scaled
|
||||
// TODO: move this from SixenseManager
|
||||
float cursorRange = canvasSize.x * SixenseManager::getInstance().getCursorPixelRangeMult();
|
||||
|
||||
pos.setX(canvasSize.x / 2.0f + cursorRange * xAngle);
|
||||
pos.setY(canvasSize.y / 2.0f + cursorRange * yAngle);
|
||||
|
||||
}
|
||||
|
||||
//If we are off screen then we should stop processing, and if a trigger or bumper is pressed,
|
||||
//we should unpress them.
|
||||
if (pos.x() == INT_MAX) {
|
||||
if (_oldHandLeftClick[index]) {
|
||||
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0);
|
||||
|
||||
qApp->mouseReleaseEvent(&mouseEvent, deviceID);
|
||||
|
||||
_oldHandLeftClick[index] = false;
|
||||
}
|
||||
if (_oldHandRightClick[index]) {
|
||||
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0);
|
||||
|
||||
qApp->mouseReleaseEvent(&mouseEvent, deviceID);
|
||||
|
||||
_oldHandRightClick[index] = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//If position has changed, emit a mouse move to the application
|
||||
if (pos.x() != _oldHandMouseX[index] || pos.y() != _oldHandMouseY[index]) {
|
||||
QMouseEvent mouseEvent(QEvent::MouseMove, pos, Qt::NoButton, Qt::NoButton, 0);
|
||||
|
||||
// Only send the mouse event if the opposite left button isnt held down.
|
||||
// Is this check necessary?
|
||||
if (!_oldHandLeftClick[(int)(!index)]) {
|
||||
qApp->mouseMoveEvent(&mouseEvent, deviceID);
|
||||
}
|
||||
}
|
||||
_oldHandMouseX[index] = pos.x();
|
||||
_oldHandMouseY[index] = pos.y();
|
||||
|
||||
//We need separate coordinates for clicks, since we need to check if
|
||||
//a magnification window was clicked on
|
||||
int clickX = pos.x();
|
||||
int clickY = pos.y();
|
||||
//Set pos to the new click location, which may be the same if no magnification window is open
|
||||
pos.setX(clickX);
|
||||
pos.setY(clickY);
|
||||
|
||||
// Right click
|
||||
if (shift == 1.0f && click == 1.0f) {
|
||||
if (!_oldHandRightClick[index]) {
|
||||
_oldHandRightClick[index] = true;
|
||||
|
||||
QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::RightButton, Qt::RightButton, 0);
|
||||
|
||||
qApp->mousePressEvent(&mouseEvent, deviceID);
|
||||
}
|
||||
} else if (_oldHandRightClick[index]) {
|
||||
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0);
|
||||
|
||||
qApp->mouseReleaseEvent(&mouseEvent, deviceID);
|
||||
|
||||
_oldHandRightClick[index] = false;
|
||||
}
|
||||
|
||||
// Left click
|
||||
if (shift != 1.0f && click == 1.0f) {
|
||||
if (!_oldHandLeftClick[index]) {
|
||||
_oldHandLeftClick[index] = true;
|
||||
|
||||
QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, 0);
|
||||
|
||||
qApp->mousePressEvent(&mouseEvent, deviceID);
|
||||
}
|
||||
} else if (_oldHandLeftClick[index]) {
|
||||
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0);
|
||||
|
||||
qApp->mouseReleaseEvent(&mouseEvent, deviceID);
|
||||
|
||||
_oldHandLeftClick[index] = false;
|
||||
}
|
||||
}
|
||||
|
||||
int Application::sendNackPackets() {
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::DisableNackPackets)) {
|
||||
|
@ -3683,7 +3813,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
sceneInterface->setEngineDrawnOverlay3DItems(engineRC->_numDrawnOverlay3DItems);
|
||||
}
|
||||
//Render the sixense lasers
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::HandLasers)) {
|
||||
_myAvatar->renderLaserPointers(*renderArgs->_batch);
|
||||
}
|
||||
|
||||
|
|
|
@ -482,8 +482,9 @@ private:
|
|||
void cleanupBeforeQuit();
|
||||
|
||||
void update(float deltaTime);
|
||||
|
||||
|
||||
void setPalmData(Hand* hand, UserInputMapper::PoseValue pose, int index);
|
||||
void emulateMouse(Hand* hand, float click, float shift, int index);
|
||||
|
||||
// Various helper functions called during update()
|
||||
void updateLOD();
|
||||
|
@ -671,6 +672,11 @@ private:
|
|||
|
||||
glm::vec3 _headPosition;
|
||||
glm::quat _headOrientation;
|
||||
|
||||
int _oldHandMouseX[2];
|
||||
int _oldHandMouseY[2];
|
||||
bool _oldHandLeftClick[2];
|
||||
bool _oldHandRightClick[2];
|
||||
};
|
||||
|
||||
#endif // hifi_Application_h
|
||||
|
|
|
@ -466,6 +466,8 @@ Menu::Menu() {
|
|||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlternateIK, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHands, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::HandMouseInput, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::HandLasers, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::ShowIKConstraints, 0, false);
|
||||
|
||||
#if 0
|
||||
|
@ -489,8 +491,6 @@ Menu::Menu() {
|
|||
true,
|
||||
qApp,
|
||||
SLOT(setLowVelocityFilter(bool)));
|
||||
addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseMouseInput, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseLasers, 0, false);
|
||||
#endif
|
||||
|
||||
MenuWrapper* leapOptionsMenu = handOptionsMenu->addMenu("Leap Motion");
|
||||
|
|
|
@ -199,6 +199,8 @@ namespace MenuOption {
|
|||
const QString FrameTimer = "Show Timer";
|
||||
const QString FullscreenMirror = "Fullscreen Mirror";
|
||||
const QString GlowWhenSpeaking = "Glow When Speaking";
|
||||
const QString HandMouseInput = "Enable Hand Mouse Input";
|
||||
const QString HandLasers = "Enable Hand UI Lasers";
|
||||
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
||||
const QString IndependentMode = "Independent Mode";
|
||||
const QString KeyboardMotorControl = "Enable Keyboard Motor Control";
|
||||
|
@ -270,8 +272,6 @@ namespace MenuOption {
|
|||
const QString ShowRealtimeEntityStats = "Show Realtime Entity Stats";
|
||||
const QString SimpleShadows = "Simple";
|
||||
const QString SixenseEnabled = "Enable Hydra Support";
|
||||
const QString SixenseMouseInput = "Enable Sixense Mouse Input";
|
||||
const QString SixenseLasers = "Enable Sixense UI Lasers";
|
||||
const QString ShiftHipsForIdleAnimations = "Shift hips for idle animations";
|
||||
const QString Stars = "Stars";
|
||||
const QString Stats = "Stats";
|
||||
|
|
|
@ -248,7 +248,7 @@ void SixenseManager::update(float deltaTime) {
|
|||
handleAxisEvent(data->joystick_x, data->joystick_y, data->trigger, numActiveControllers - 1);
|
||||
|
||||
// Emulate the mouse so we can use scripts
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput) && !_controllersAtBase) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::HandMouseInput) && !_controllersAtBase) {
|
||||
emulateMouse(palm, numActiveControllers - 1);
|
||||
}
|
||||
|
||||
|
@ -518,7 +518,7 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) {
|
|||
triggerButton = Qt::LeftButton;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers) || qApp->isHMDMode()) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::HandLasers) || qApp->isHMDMode()) {
|
||||
pos = qApp->getApplicationCompositor().getPalmClickLocation(palm);
|
||||
} else {
|
||||
// Get directon relative to avatar orientation
|
||||
|
|
|
@ -415,7 +415,7 @@ void ApplicationCompositor::renderPointers(gpu::Batch& batch) {
|
|||
_magActive[MOUSE] = _magnifier;
|
||||
_reticleActive[LEFT_CONTROLLER] = false;
|
||||
_reticleActive[RIGHT_CONTROLLER] = false;
|
||||
} else if (qApp->getLastMouseMoveWasSimulated() && Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) {
|
||||
} else if (qApp->getLastMouseMoveWasSimulated() && Menu::getInstance()->isOptionChecked(MenuOption::HandMouseInput)) {
|
||||
//only render controller pointer if we aren't already rendering a mouse pointer
|
||||
_reticleActive[MOUSE] = false;
|
||||
_magActive[MOUSE] = false;
|
||||
|
@ -490,7 +490,7 @@ void ApplicationCompositor::renderControllerPointers(gpu::Batch& batch) {
|
|||
|
||||
auto canvasSize = qApp->getCanvasSize();
|
||||
int mouseX, mouseY;
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::HandLasers)) {
|
||||
QPoint res = getPalmClickLocation(palmData);
|
||||
mouseX = res.x();
|
||||
mouseY = res.y();
|
||||
|
|
|
@ -248,6 +248,8 @@ void UserInputMapper::assignDefaulActionScales() {
|
|||
_actionScales[BOOM_OUT] = 0.5f; // .5m per unit
|
||||
_actionScales[LEFT_HAND] = 1.0f; // default
|
||||
_actionScales[RIGHT_HAND] = 1.0f; // default
|
||||
_actionScales[LEFT_HAND_CLICK] = 1.0f; // on
|
||||
_actionScales[RIGHT_HAND_CLICK] = 1.0f; // on
|
||||
_actionStates[SHIFT] = 1.0f; // on
|
||||
_actionStates[ACTION1] = 1.0f; // default
|
||||
_actionStates[ACTION2] = 1.0f; // default
|
||||
|
@ -270,6 +272,8 @@ void UserInputMapper::createActionNames() {
|
|||
_actionNames[BOOM_OUT] = "BOOM_OUT";
|
||||
_actionNames[LEFT_HAND] = "LEFT_HAND";
|
||||
_actionNames[RIGHT_HAND] = "RIGHT_HAND";
|
||||
_actionNames[LEFT_HAND_CLICK] = "LEFT_HAND_CLICK";
|
||||
_actionNames[RIGHT_HAND_CLICK] = "RIGHT_HAND_CLICK";
|
||||
_actionNames[SHIFT] = "SHIFT";
|
||||
_actionNames[ACTION1] = "ACTION1";
|
||||
_actionNames[ACTION2] = "ACTION2";
|
||||
|
|
|
@ -152,7 +152,10 @@ public:
|
|||
|
||||
LEFT_HAND,
|
||||
RIGHT_HAND,
|
||||
|
||||
|
||||
LEFT_HAND_CLICK,
|
||||
RIGHT_HAND_CLICK,
|
||||
|
||||
SHIFT,
|
||||
|
||||
ACTION1,
|
||||
|
|
|
@ -31,10 +31,12 @@ 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 uint64_t VR_TRIGGER_BUTTON = 1ULL << 33;
|
||||
|
||||
const unsigned int BUTTON_A = 1U << 1;
|
||||
const unsigned int GRIP_BUTTON = 1U << 2;
|
||||
const unsigned int TRACKPAD_BUTTON = 1U << 3;
|
||||
const unsigned int TRIGGER_BUTTON = 1U << 4;
|
||||
|
||||
ViveControllerManager& ViveControllerManager::getInstance() {
|
||||
static ViveControllerManager sharedInstance;
|
||||
|
@ -111,11 +113,9 @@ void ViveControllerManager::update() {
|
|||
if (_deviceID != 0) {
|
||||
userInputMapper->removeDevice(_deviceID);
|
||||
_deviceID = 0;
|
||||
_poseStateMap[makeInput(LEFT_HAND).getChannel()] = UserInputMapper::PoseValue();
|
||||
_poseStateMap[makeInput(RIGHT_HAND).getChannel()] = UserInputMapper::PoseValue();
|
||||
//_poseStateMap[makeInput(LEFT_HAND).getChannel()] = UserInputMapper::PoseValue();
|
||||
//_poseStateMap[makeInput(RIGHT_HAND).getChannel()] = UserInputMapper::PoseValue();
|
||||
}
|
||||
_trackedControllers = numTrackedControllers;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_trackedControllers == 0 && numTrackedControllers > 0) {
|
||||
|
@ -154,6 +154,9 @@ void ViveControllerManager::handleButtonEvent(uint64_t buttons, int index) {
|
|||
if (buttons & VR_TRACKPAD_BUTTON) {
|
||||
_buttonPressedMap.insert(makeInput(TRACKPAD_BUTTON, index).getChannel());
|
||||
}
|
||||
if (buttons & VR_TRIGGER_BUTTON) {
|
||||
_buttonPressedMap.insert(makeInput(TRIGGER_BUTTON, index).getChannel());
|
||||
}
|
||||
}
|
||||
|
||||
void ViveControllerManager::handlePoseEvent(const mat4& mat, int index) {
|
||||
|
@ -186,6 +189,7 @@ void ViveControllerManager::registerToUserInputMapper(UserInputMapper& mapper) {
|
|||
availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_A, 0), "Left Button A"));
|
||||
availableInputs.append(UserInputMapper::InputPair(makeInput(GRIP_BUTTON, 0), "Left Grip Button"));
|
||||
availableInputs.append(UserInputMapper::InputPair(makeInput(TRACKPAD_BUTTON, 0), "Left Trackpad Button"));
|
||||
availableInputs.append(UserInputMapper::InputPair(makeInput(TRIGGER_BUTTON, 0), "Left Trigger Button"));
|
||||
|
||||
availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_POS, 0), "Left Trackpad Up"));
|
||||
availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_NEG, 0), "Left Trackpad Down"));
|
||||
|
@ -196,6 +200,7 @@ void ViveControllerManager::registerToUserInputMapper(UserInputMapper& mapper) {
|
|||
availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_A, 1), "Right Button A"));
|
||||
availableInputs.append(UserInputMapper::InputPair(makeInput(GRIP_BUTTON, 1), "Right Grip Button"));
|
||||
availableInputs.append(UserInputMapper::InputPair(makeInput(TRACKPAD_BUTTON, 1), "Right Trackpad Button"));
|
||||
availableInputs.append(UserInputMapper::InputPair(makeInput(TRIGGER_BUTTON, 1), "Right Trigger Button"));
|
||||
|
||||
availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_POS, 1), "Right Trackpad Up"));
|
||||
availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_NEG, 1), "Right Trackpad Down"));
|
||||
|
@ -235,6 +240,9 @@ void ViveControllerManager::assignDefaultInputMapping(UserInputMapper& mapper) {
|
|||
|
||||
mapper.addInputChannel(UserInputMapper::ACTION1, makeInput(BUTTON_A, 0));
|
||||
mapper.addInputChannel(UserInputMapper::ACTION2, makeInput(BUTTON_A, 1));
|
||||
|
||||
mapper.addInputChannel(UserInputMapper::LEFT_HAND_CLICK, makeInput(TRIGGER_BUTTON, 0));
|
||||
mapper.addInputChannel(UserInputMapper::RIGHT_HAND_CLICK, makeInput(TRIGGER_BUTTON, 1));
|
||||
|
||||
// Hands
|
||||
mapper.addInputChannel(UserInputMapper::LEFT_HAND, makeInput(LEFT_HAND));
|
||||
|
|
|
@ -148,6 +148,8 @@ public:
|
|||
GlowWhenSpeaking,
|
||||
NamesAboveHeads,
|
||||
GoToUser,
|
||||
HandMouseInput,
|
||||
HandLasers,
|
||||
HMDTools,
|
||||
IncreaseAvatarSize,
|
||||
KeyboardMotorControl,
|
||||
|
@ -214,8 +216,6 @@ public:
|
|||
ShowIKConstraints,
|
||||
SimpleShadows,
|
||||
SixenseEnabled,
|
||||
SixenseMouseInput,
|
||||
SixenseLasers,
|
||||
ShiftHipsForIdleAnimations,
|
||||
Stars,
|
||||
Stats,
|
||||
|
|
Loading…
Reference in a new issue