mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 19:13:38 +02:00
Implementd sixense mouse emulation
This commit is contained in:
parent
d9b4032ca0
commit
eff097638c
4 changed files with 159 additions and 3 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue