Implementd sixense mouse emulation

This commit is contained in:
barnold1953 2014-06-11 17:02:08 -07:00
parent d9b4032ca0
commit eff097638c
4 changed files with 159 additions and 3 deletions

View file

@ -1090,6 +1090,13 @@ void Application::focusOutEvent(QFocusEvent* event) {
}
void Application::mouseMoveEvent(QMouseEvent* event) {
bool showMouse = true;
// If this mouse move event is emitted by a controller, dont show the mouse cursor
if (event->type() == CONTROLLER_MOVE_EVENT) {
showMouse = false;
}
_controllerScriptingInterface.emitMouseMoveEvent(event); // send events to any registered scripts
// if one of our scripts have asked to capture this event, then stop processing it
@ -1097,10 +1104,9 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
return;
}
_lastMouseMove = usecTimestampNow();
if (_mouseHidden && !OculusManager::isConnected()) {
if (_mouseHidden && showMouse && !OculusManager::isConnected()) {
getGLWidget()->setCursor(Qt::ArrowCursor);
_mouseHidden = false;
_seenMouseMove = true;

View file

@ -39,6 +39,10 @@ SixenseManager::SixenseManager() {
sixenseInit();
#endif
_triggerPressed = false;
_bumperPressed = false;
_oldPos.setX(-1);
_oldPos.setY(-1);
}
SixenseManager::~SixenseManager() {
@ -107,6 +111,12 @@ void SixenseManager::update(float deltaTime) {
palm->setTrigger(data->trigger);
palm->setJoystick(data->joystick_x, data->joystick_y);
// Emulate the mouse so we can use scripts
if (numActiveControllers == 2) {
emulateMouse(palm);
}
// NOTE: Sixense API returns pos data in millimeters but we IMMEDIATELY convert to meters.
glm::vec3 position(data->pos[0], data->pos[1], data->pos[2]);
position *= METERS_PER_MILLIMETER;
@ -313,5 +323,63 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers)
}
}
}
//Injecting mouse movements and clicks
void SixenseManager::emulateMouse(PalmData *palm) {
MyAvatar* avatar = Application::getInstance()->getAvatar();
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() != _oldPos.x() || pos.y() != _oldPos.y()) {
QMouseEvent mouseEvent(static_cast<QEvent::Type>(CONTROLLER_MOVE_EVENT), pos, Qt::NoButton, Qt::NoButton, 0);
Application::getInstance()->mouseMoveEvent(&mouseEvent);
}
_oldPos = pos;
//Check for bumper press ( Right Click )
if (palm->getControllerButtons() & BUTTON_FWD) {
if (!_bumperPressed) {
_bumperPressed = true;
QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::RightButton, Qt::RightButton, 0);
Application::getInstance()->mousePressEvent(&mouseEvent);
}
} else if (_bumperPressed) {
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0);
Application::getInstance()->mouseReleaseEvent(&mouseEvent);
_bumperPressed = false;
}
//Check for trigger press ( Left Click )
if (palm->getTrigger() == 1.0f) {
if (!_triggerPressed) {
_triggerPressed = true;
QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, 0);
Application::getInstance()->mousePressEvent(&mouseEvent);
}
} else if (_triggerPressed) {
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0);
Application::getInstance()->mouseReleaseEvent(&mouseEvent);
_triggerPressed = false;
}
}
#endif // HAVE_SIXENSE

View file

@ -27,6 +27,9 @@ const unsigned int BUTTON_3 = 1U << 3;
const unsigned int BUTTON_4 = 1U << 4;
const unsigned int BUTTON_FWD = 1U << 7;
// Event type that represents moving the controller
const unsigned int CONTROLLER_MOVE_EVENT = 1500U;
/// Handles interaction with the Sixense SDK (e.g., Razer Hydra).
class SixenseManager : public QObject {
Q_OBJECT
@ -44,6 +47,7 @@ public slots:
private:
#ifdef HAVE_SIXENSE
void updateCalibration(const sixenseControllerData* controllers);
void emulateMouse(PalmData *palm);
int _calibrationState;
@ -65,6 +69,11 @@ private:
#endif
quint64 _lastMovement;
glm::vec3 _amountMoved;
// for mouse emulation
bool _triggerPressed;
bool _bumperPressed;
QPoint _oldPos;
};
#endif // hifi_SixenseManager_h

View file

@ -35,6 +35,78 @@ ApplicationOverlay::~ApplicationOverlay() {
const float WHITE_TEXT[] = { 0.93f, 0.93f, 0.93f };
void renderControllerPointer()
{
Application* application = Application::getInstance();
QGLWidget* glWidget = application->getGLWidget();
MyAvatar* myAvatar = application->getAvatar();
const HandData* handData = Application::getInstance()->getAvatar()->getHandData();
int numberOfPalms = handData->getNumPalms();
int palmIndex = 3;
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
void ApplicationOverlay::renderOverlay(bool renderToTexture) {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
@ -254,8 +326,9 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
glVertex2i(mouseX + crossPad, mouseY - pointerHeight);
glEnd();
} else { //only render controller pointer if we aren't already rendering a mouse pointer
renderControllerPointer();
}
glPopMatrix();
glMatrixMode(GL_MODELVIEW);