Experimenting with ambidextrous sixense mouse input

This commit is contained in:
barnold1953 2014-06-12 10:20:35 -07:00
parent 32a9eed88d
commit d0b1880ee4
3 changed files with 132 additions and 102 deletions

View file

@ -39,10 +39,14 @@ SixenseManager::SixenseManager() {
sixenseInit(); sixenseInit();
#endif #endif
_triggerPressed = false; _triggerPressed[0] = false;
_bumperPressed = false; _bumperPressed[0] = false;
_oldX = -1; _oldX[0] = -1;
_oldY = -1; _oldY[0] = -1;
_triggerPressed[1] = false;
_bumperPressed[1] = false;
_oldX[1] = -1;
_oldY[1] = -1;
} }
SixenseManager::~SixenseManager() { SixenseManager::~SixenseManager() {
@ -115,9 +119,9 @@ void SixenseManager::update(float deltaTime) {
// Emulate the mouse so we can use scripts // Emulate the mouse so we can use scripts
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) { if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) {
// Check if we are on the correct palm // Check if we are on the correct palm
if ((Menu::getInstance()->isOptionChecked(MenuOption::SixenseLeftHanded) && numActiveControllers == 1) || numActiveControllers == 2) { //if ((Menu::getInstance()->isOptionChecked(MenuOption::SixenseLeftHanded) && numActiveControllers == 1) || numActiveControllers == 2) {
emulateMouse(palm); emulateMouse(palm, numActiveControllers - 1);
} //}
} }
// NOTE: Sixense API returns pos data in millimeters but we IMMEDIATELY convert to meters. // NOTE: Sixense API returns pos data in millimeters but we IMMEDIATELY convert to meters.
@ -328,30 +332,13 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers)
} }
//Injecting mouse movements and clicks //Injecting mouse movements and clicks
void SixenseManager::emulateMouse(PalmData *palm) { void SixenseManager::emulateMouse(PalmData* palm, int index) {
MyAvatar* avatar = Application::getInstance()->getAvatar(); MyAvatar* avatar = Application::getInstance()->getAvatar();
QGLWidget* widget = Application::getInstance()->getGLWidget();
QPoint pos; QPoint pos;
// Get directon relative to avatar orientation // Get directon relative to avatar orientation
glm::vec3 direction = glm::inverse(avatar->getOrientation()) * palm->getFingerDirection(); glm::vec3 direction = glm::inverse(avatar->getOrientation()) * palm->getFingerDirection();
// Get the angles, scaled between 0-1
float xAngle = (atan2(direction.z, direction.x) + M_PI_2) + 0.5f;
float yAngle = 1.0f - ((atan2(direction.z, direction.y) + M_PI_2) + 0.5f);
float cursorRange = Application::getInstance()->getGLWidget()->width();
pos.setX(cursorRange * xAngle);
pos.setY(cursorRange * yAngle);
//If position has changed, emit a mouse move to the application
if (pos.x() != _oldX || pos.y() != _oldY) {
QMouseEvent mouseEvent(static_cast<QEvent::Type>(CONTROLLER_MOVE_EVENT), pos, Qt::NoButton, Qt::NoButton, 0);
Application::getInstance()->mouseMoveEvent(&mouseEvent);
}
_oldX = pos.x();
_oldY = pos.y();
Qt::MouseButton bumperButton; Qt::MouseButton bumperButton;
Qt::MouseButton triggerButton; Qt::MouseButton triggerButton;
@ -363,41 +350,78 @@ void SixenseManager::emulateMouse(PalmData *palm) {
triggerButton = Qt::LeftButton; triggerButton = Qt::LeftButton;
} }
// Get the angles, scaled between 0-1
float xAngle = (atan2(direction.z, direction.x) + M_PI_2) + 0.5f;
float yAngle = 1.0f - ((atan2(direction.z, direction.y) + M_PI_2) + 0.5f);
float cursorRange = widget->width();
pos.setX(cursorRange * xAngle);
pos.setY(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() < 0 || pos.x() > widget->width() || pos.y() < 0 || pos.y() > widget->height()) {
if (_bumperPressed[index]) {
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, bumperButton, bumperButton, 0);
Application::getInstance()->mouseReleaseEvent(&mouseEvent);
_bumperPressed[index] = false;
}
if (_triggerPressed[index]) {
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, triggerButton, triggerButton, 0);
Application::getInstance()->mouseReleaseEvent(&mouseEvent);
_triggerPressed[index] = false;
}
return;
}
//If position has changed, emit a mouse move to the application
if (pos.x() != _oldX[index] || pos.y() != _oldY[index]) {
QMouseEvent mouseEvent(static_cast<QEvent::Type>(CONTROLLER_MOVE_EVENT), pos, Qt::NoButton, Qt::NoButton, 0);
Application::getInstance()->mouseMoveEvent(&mouseEvent);
}
_oldX[index] = pos.x();
_oldY[index] = pos.y();
//Check for bumper press ( Right Click ) //Check for bumper press ( Right Click )
if (palm->getControllerButtons() & BUTTON_FWD) { if (palm->getControllerButtons() & BUTTON_FWD) {
if (!_bumperPressed) { if (!_bumperPressed[index]) {
_bumperPressed = true; _bumperPressed[index] = true;
QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, bumperButton, bumperButton, 0); QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, bumperButton, bumperButton, 0);
Application::getInstance()->mousePressEvent(&mouseEvent); Application::getInstance()->mousePressEvent(&mouseEvent);
} }
} else if (_bumperPressed) { } else if (_bumperPressed[index]) {
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, bumperButton, bumperButton, 0); QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, bumperButton, bumperButton, 0);
Application::getInstance()->mouseReleaseEvent(&mouseEvent); Application::getInstance()->mouseReleaseEvent(&mouseEvent);
_bumperPressed = false; _bumperPressed[index] = false;
} }
//Check for trigger press ( Left Click ) //Check for trigger press ( Left Click )
if (palm->getTrigger() == 1.0f) { if (palm->getTrigger() == 1.0f) {
if (!_triggerPressed) { if (!_triggerPressed[index]) {
_triggerPressed = true; _triggerPressed[index] = true;
QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, triggerButton, triggerButton, 0); QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, triggerButton, triggerButton, 0);
Application::getInstance()->mousePressEvent(&mouseEvent); Application::getInstance()->mousePressEvent(&mouseEvent);
} }
} else if (_triggerPressed) { } else if (_triggerPressed[index]) {
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, triggerButton, triggerButton, 0); QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, triggerButton, triggerButton, 0);
Application::getInstance()->mouseReleaseEvent(&mouseEvent); Application::getInstance()->mouseReleaseEvent(&mouseEvent);
_triggerPressed = false; _triggerPressed[index] = false;
} }
} }
#endif // HAVE_SIXENSE #endif // HAVE_SIXENSE

View file

@ -47,7 +47,7 @@ public slots:
private: private:
#ifdef HAVE_SIXENSE #ifdef HAVE_SIXENSE
void updateCalibration(const sixenseControllerData* controllers); void updateCalibration(const sixenseControllerData* controllers);
void emulateMouse(PalmData *palm); void emulateMouse(PalmData* palm, int index);
int _calibrationState; int _calibrationState;
@ -70,11 +70,11 @@ private:
quint64 _lastMovement; quint64 _lastMovement;
glm::vec3 _amountMoved; glm::vec3 _amountMoved;
// for mouse emulation // for mouse emulation with the two controllers
bool _triggerPressed; bool _triggerPressed[2];
bool _bumperPressed; bool _bumperPressed[2];
int _oldX; int _oldX[2];
int _oldY; int _oldY[2];
}; };
#endif // hifi_SixenseManager_h #endif // hifi_SixenseManager_h

View file

@ -45,11 +45,12 @@ void renderControllerPointer() {
int palmIndex; int palmIndex;
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLeftHanded)) { /*if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLeftHanded)) {
palmIndex = 2; palmIndex = 2;
} else { } else {
palmIndex = 3; palmIndex = 3;
} }*/
for (palmIndex = 2; palmIndex < 4; palmIndex++) {
const PalmData* palmData = NULL; const PalmData* palmData = NULL;
if (palmIndex >= handData->getPalms().size()) { if (palmIndex >= handData->getPalms().size()) {
@ -75,14 +76,18 @@ void renderControllerPointer() {
int mouseY = cursorRange * yAngle; int mouseY = cursorRange * yAngle;
if (mouseX < 0) { if (mouseX < 0) {
mouseX = 0; //mouseX = 0;
continue;
} else if (mouseX > glWidget->width()) { } else if (mouseX > glWidget->width()) {
mouseX = glWidget->width(); //mouseX = glWidget->width();
continue;
} }
if (mouseY < 0) { if (mouseY < 0) {
mouseY = 0; //mouseY = 0;
continue;
} else if (mouseY > glWidget->width()) { } else if (mouseY > glWidget->width()) {
mouseY = glWidget->width(); //mouseY = glWidget->width();
continue;
} }
const float pointerWidth = 40; const float pointerWidth = 40;
@ -94,7 +99,7 @@ void renderControllerPointer() {
glBegin(GL_QUADS); glBegin(GL_QUADS);
glColor3f(0, 0, 1); glColor3f(0.0f, 0.0f, 1.0f);
//Horizontal crosshair //Horizontal crosshair
glVertex2i(mouseX, mouseY - crossPad); glVertex2i(mouseX, mouseY - crossPad);
@ -109,6 +114,7 @@ void renderControllerPointer() {
glVertex2i(mouseX + crossPad, mouseY - pointerHeight); glVertex2i(mouseX + crossPad, mouseY - pointerHeight);
glEnd(); glEnd();
}
} }
// Renders the overlays either to a texture or to the screen // Renders the overlays either to a texture or to the screen