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();
#endif
_triggerPressed = false;
_bumperPressed = false;
_oldX = -1;
_oldY = -1;
_triggerPressed[0] = false;
_bumperPressed[0] = false;
_oldX[0] = -1;
_oldY[0] = -1;
_triggerPressed[1] = false;
_bumperPressed[1] = false;
_oldX[1] = -1;
_oldY[1] = -1;
}
SixenseManager::~SixenseManager() {
@ -115,9 +119,9 @@ void SixenseManager::update(float deltaTime) {
// Emulate the mouse so we can use scripts
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) {
// Check if we are on the correct palm
if ((Menu::getInstance()->isOptionChecked(MenuOption::SixenseLeftHanded) && numActiveControllers == 1) || numActiveControllers == 2) {
emulateMouse(palm);
}
//if ((Menu::getInstance()->isOptionChecked(MenuOption::SixenseLeftHanded) && numActiveControllers == 1) || numActiveControllers == 2) {
emulateMouse(palm, numActiveControllers - 1);
//}
}
// 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
void SixenseManager::emulateMouse(PalmData *palm) {
void SixenseManager::emulateMouse(PalmData* palm, int index) {
MyAvatar* avatar = Application::getInstance()->getAvatar();
QGLWidget* widget = Application::getInstance()->getGLWidget();
QPoint pos;
// Get directon relative to avatar orientation
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 triggerButton;
@ -362,42 +349,79 @@ void SixenseManager::emulateMouse(PalmData *palm) {
bumperButton = Qt::RightButton;
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 )
if (palm->getControllerButtons() & BUTTON_FWD) {
if (!_bumperPressed) {
_bumperPressed = true;
if (!_bumperPressed[index]) {
_bumperPressed[index] = true;
QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, bumperButton, bumperButton, 0);
Application::getInstance()->mousePressEvent(&mouseEvent);
}
} else if (_bumperPressed) {
} else if (_bumperPressed[index]) {
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, bumperButton, bumperButton, 0);
Application::getInstance()->mouseReleaseEvent(&mouseEvent);
_bumperPressed = false;
_bumperPressed[index] = false;
}
//Check for trigger press ( Left Click )
if (palm->getTrigger() == 1.0f) {
if (!_triggerPressed) {
_triggerPressed = true;
if (!_triggerPressed[index]) {
_triggerPressed[index] = true;
QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, triggerButton, triggerButton, 0);
Application::getInstance()->mousePressEvent(&mouseEvent);
}
} else if (_triggerPressed) {
} else if (_triggerPressed[index]) {
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, triggerButton, triggerButton, 0);
Application::getInstance()->mouseReleaseEvent(&mouseEvent);
_triggerPressed = false;
_triggerPressed[index] = false;
}
}
#endif // HAVE_SIXENSE

View file

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

View file

@ -45,70 +45,76 @@ void renderControllerPointer() {
int palmIndex;
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLeftHanded)) {
/*if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLeftHanded)) {
palmIndex = 2;
} else {
palmIndex = 3;
}*/
for (palmIndex = 2; palmIndex < 4; palmIndex++) {
const PalmData* palmData = NULL;
if (palmIndex >= handData->getPalms().size()) {
return;
}
if (handData->getPalms()[palmIndex].isActive()) {
palmData = &handData->getPalms()[palmIndex];
} else {
return;
}
// Get directon relative to avatar orientation
glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * palmData->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 = glWidget->width();
int mouseX = cursorRange * xAngle;
int mouseY = cursorRange * yAngle;
if (mouseX < 0) {
//mouseX = 0;
continue;
} else if (mouseX > glWidget->width()) {
//mouseX = glWidget->width();
continue;
}
if (mouseY < 0) {
//mouseY = 0;
continue;
} else if (mouseY > glWidget->width()) {
//mouseY = glWidget->width();
continue;
}
const float pointerWidth = 40;
const float pointerHeight = 40;
const float crossPad = 16;
mouseX -= pointerWidth / 2.0f;
mouseY += pointerHeight / 2.0f;
glBegin(GL_QUADS);
glColor3f(0.0f, 0.0f, 1.0f);
//Horizontal crosshair
glVertex2i(mouseX, mouseY - crossPad);
glVertex2i(mouseX + pointerWidth, mouseY - crossPad);
glVertex2i(mouseX + pointerWidth, mouseY - pointerHeight + crossPad);
glVertex2i(mouseX, mouseY - pointerHeight + crossPad);
//Vertical crosshair
glVertex2i(mouseX + crossPad, mouseY);
glVertex2i(mouseX + pointerWidth - crossPad, mouseY);
glVertex2i(mouseX + pointerWidth - crossPad, mouseY - pointerHeight);
glVertex2i(mouseX + crossPad, mouseY - pointerHeight);
glEnd();
}
const PalmData* palmData = NULL;
if (palmIndex >= handData->getPalms().size()) {
return;
}
if (handData->getPalms()[palmIndex].isActive()) {
palmData = &handData->getPalms()[palmIndex];
} else {
return;
}
// Get directon relative to avatar orientation
glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * palmData->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 = glWidget->width();
int mouseX = cursorRange * xAngle;
int mouseY = cursorRange * yAngle;
if (mouseX < 0) {
mouseX = 0;
} else if (mouseX > glWidget->width()) {
mouseX = glWidget->width();
}
if (mouseY < 0) {
mouseY = 0;
} else if (mouseY > glWidget->width()) {
mouseY = glWidget->width();
}
const float pointerWidth = 40;
const float pointerHeight = 40;
const float crossPad = 16;
mouseX -= pointerWidth / 2.0f;
mouseY += pointerHeight / 2.0f;
glBegin(GL_QUADS);
glColor3f(0, 0, 1);
//Horizontal crosshair
glVertex2i(mouseX, mouseY - crossPad);
glVertex2i(mouseX + pointerWidth, mouseY - crossPad);
glVertex2i(mouseX + pointerWidth, mouseY - pointerHeight + crossPad);
glVertex2i(mouseX, mouseY - pointerHeight + crossPad);
//Vertical crosshair
glVertex2i(mouseX + crossPad, mouseY);
glVertex2i(mouseX + pointerWidth - crossPad, mouseY);
glVertex2i(mouseX + pointerWidth - crossPad, mouseY - pointerHeight);
glVertex2i(mouseX + crossPad, mouseY - pointerHeight);
glEnd();
}
// Renders the overlays either to a texture or to the screen