HMD mouse checkpoint

This commit is contained in:
Brad Hefta-Gaub 2016-02-17 21:19:01 -08:00
parent a25581c656
commit 8b8b99c7e0
13 changed files with 260 additions and 114 deletions

View file

@ -786,8 +786,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
}
if (action == controller::toInt(controller::Action::RETICLE_CLICK)) {
auto globalPos = QCursor::pos();
auto localPos = _glWidget->mapFromGlobal(globalPos);
auto reticlePos = _compositor.getReticlePosition();
QPoint globalPos(reticlePos.x, reticlePos.y);
// FIXME - it would be nice if this was self contained in the _compositor or Reticle class
auto localPos = isHMDMode() ? globalPos : _glWidget->mapFromGlobal(globalPos);
if (state) {
QMouseEvent mousePress(QEvent::MouseButtonPress, localPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
sendEvent(_glWidget, &mousePress);
@ -809,9 +812,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
auto reticlePosition = _compositor.getReticlePosition();
offscreenUi->toggleMenu(_glWidget->mapFromGlobal(QPoint(reticlePosition.x, reticlePosition.y)));
} else if (action == controller::toInt(controller::Action::RETICLE_X)) {
qDebug() << "Action::RETICLE_X...";
auto oldPos = _compositor.getReticlePosition();
_compositor.setReticlePosition({ oldPos.x + state, oldPos.y });
} else if (action == controller::toInt(controller::Action::RETICLE_Y)) {
qDebug() << "Action::RETICLE_Y...";
auto oldPos = _compositor.getReticlePosition();
_compositor.setReticlePosition({ oldPos.x, oldPos.y + state });
}
@ -955,7 +960,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
// If the user clicks somewhere where there is NO entity at all, we will release focus
connect(getEntities(), &EntityTreeRenderer::mousePressOffEntity,
[=](const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event, unsigned int deviceId) {
[=](const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event) {
_keyboardFocusedItem = UNKNOWN_ENTITY_ID;
if (_keyboardFocusHighlight) {
_keyboardFocusHighlight->setVisible(false);
@ -1261,7 +1266,8 @@ void Application::initializeUi() {
QPointF result = pt;
auto displayPlugin = getActiveDisplayPlugin();
if (displayPlugin->isHmd()) {
auto resultVec = _compositor.screenToOverlay(toGlm(pt));
auto fakeScreen = _compositor.getReticlePosition();
auto resultVec = _compositor.screenToOverlay(fakeScreen); // toGlm(pt));
result = QPointF(resultVec.x, resultVec.y);
}
return result.toPoint();
@ -1736,6 +1742,7 @@ bool Application::event(QEvent* event) {
switch (event->type()) {
case QEvent::MouseMove:
qDebug() << __FUNCTION__ << "(QEvent::MouseMove)... line:" << __LINE__;
mouseMoveEvent((QMouseEvent*)event);
return true;
case QEvent::MouseButtonPress:
@ -1772,6 +1779,9 @@ bool Application::event(QEvent* event) {
case QEvent::Drop:
dropEvent(static_cast<QDropEvent*>(event));
return true;
case QEvent::Leave:
qDebug() << __FUNCTION__ << "().... QEvent::Leave";
break; // fall through
default:
break;
}
@ -1800,6 +1810,12 @@ bool Application::event(QEvent* event) {
}
bool Application::eventFilter(QObject* object, QEvent* event) {
if (event->type() == QEvent::Leave) {
qDebug() << __FUNCTION__ << "().... QEvent::Leave";
_compositor.handleLeaveEvent();
}
if (event->type() == QEvent::ShortcutOverride) {
if (DependencyManager::get<OffscreenUi>()->shouldSwallowShortcut(event)) {
event->accept();
@ -2152,13 +2168,7 @@ void Application::focusOutEvent(QFocusEvent* event) {
_keysPressed.clear();
}
void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
PROFILE_RANGE(__FUNCTION__);
if (_aboutToQuit) {
return;
}
void Application::maybeToggleMenuVisible(QMouseEvent* event) {
#ifndef Q_OS_MAC
// If in full screen, and our main windows menu bar is hidden, and we're close to the top of the QMainWindow
// then show the menubar.
@ -2170,7 +2180,7 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
if (event->pos().y() <= MENU_TOGGLE_AREA) {
menuBar->setVisible(true);
}
} else {
} else {
if (event->pos().y() > MENU_TOGGLE_AREA) {
menuBar->setVisible(false);
}
@ -2178,9 +2188,38 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
}
}
#endif
}
/// called by ApplicationCompositor when in HMD mode and we're faking our mouse movement
void Application::fakeMouseEvent(QMouseEvent* event) {
_fakedMouseEvent = true;
sendEvent(_glWidget, event);
_fakedMouseEvent = false;
}
void Application::mouseMoveEvent(QMouseEvent* event) {
PROFILE_RANGE(__FUNCTION__);
if (_aboutToQuit) {
return;
}
qDebug() << __FUNCTION__ << "line:" << __LINE__ << "event:" << event << "_fakedMouseEvent:" << _fakedMouseEvent;
maybeToggleMenuVisible(event);
// if this is a real mouse event, and we're in HMD mode, then we should use it to move the
// compositor reticle
if (!_fakedMouseEvent && isHMDMode()) {
_compositor.handleRealMouseMoveEvent(event);
return; // bail
}
if (!_fakedMouseEvent) {
_compositor.trackRealMouseMoveEvent(event); // FIXME - super janky
}
auto offscreenUi = DependencyManager::get<OffscreenUi>();
QPointF transformedPos = offscreenUi->mapToVirtualScreen(event->localPos(), _glWidget);
auto eventPosition = _compositor.getMouseEventPosition(event);
QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition, _glWidget);
auto button = event->button();
auto buttons = event->buttons();
// Determine if the ReticleClick Action is 1 and if so, fake include the LeftMouseButton
@ -2196,21 +2235,21 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
event->screenPos(), button,
buttons, event->modifiers());
getEntities()->mouseMoveEvent(&mappedEvent, deviceID);
_controllerScriptingInterface->emitMouseMoveEvent(&mappedEvent, deviceID); // send events to any registered scripts
getEntities()->mouseMoveEvent(&mappedEvent);
_controllerScriptingInterface->emitMouseMoveEvent(&mappedEvent); // send events to any registered scripts
// if one of our scripts have asked to capture this event, then stop processing it
if (_controllerScriptingInterface->isMouseCaptured()) {
return;
}
if (deviceID == 0 && Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
_keyboardMouseDevice->mouseMoveEvent(event, deviceID);
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
_keyboardMouseDevice->mouseMoveEvent(event);
}
}
void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
void Application::mousePressEvent(QMouseEvent* event) {
// Inhibit the menu if the user is using alt-mouse dragging
_altPressed = false;
@ -2220,14 +2259,21 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
// keyboard shortcuts not to be swallowed by them. In particular, WebEngineViews
// will consume all keyboard events.
offscreenUi->unfocusWindows();
QPointF transformedPos = offscreenUi->mapToVirtualScreen(event->localPos(), _glWidget);
qDebug() << __FUNCTION__ << "event:" << event;
auto eventPosition = _compositor.getMouseEventPosition(event);
QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition, _glWidget);
qDebug() << __FUNCTION__ << " eventPosition:" << eventPosition;
qDebug() << __FUNCTION__ << "transformedPos:" << transformedPos;
QMouseEvent mappedEvent(event->type(),
transformedPos,
event->screenPos(), event->button(),
event->buttons(), event->modifiers());
if (!_aboutToQuit) {
getEntities()->mousePressEvent(&mappedEvent, deviceID);
getEntities()->mousePressEvent(&mappedEvent);
}
_controllerScriptingInterface->emitMousePressEvent(&mappedEvent); // send events to any registered scripts
@ -2239,7 +2285,7 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
if (hasFocus()) {
if (deviceID == 0 && Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
_keyboardMouseDevice->mousePressEvent(event);
}
@ -2253,7 +2299,7 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
}
}
void Application::mouseDoublePressEvent(QMouseEvent* event, unsigned int deviceID) {
void Application::mouseDoublePressEvent(QMouseEvent* event) {
// if one of our scripts have asked to capture this event, then stop processing it
if (_controllerScriptingInterface->isMouseCaptured()) {
return;
@ -2262,17 +2308,18 @@ void Application::mouseDoublePressEvent(QMouseEvent* event, unsigned int deviceI
_controllerScriptingInterface->emitMouseDoublePressEvent(event);
}
void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) {
void Application::mouseReleaseEvent(QMouseEvent* event) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
QPointF transformedPos = offscreenUi->mapToVirtualScreen(event->localPos(), _glWidget);
auto eventPosition = _compositor.getMouseEventPosition(event);
QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition, _glWidget);
QMouseEvent mappedEvent(event->type(),
transformedPos,
event->screenPos(), event->button(),
event->buttons(), event->modifiers());
if (!_aboutToQuit) {
getEntities()->mouseReleaseEvent(&mappedEvent, deviceID);
getEntities()->mouseReleaseEvent(&mappedEvent);
}
_controllerScriptingInterface->emitMouseReleaseEvent(&mappedEvent); // send events to any registered scripts
@ -2283,7 +2330,7 @@ void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) {
}
if (hasFocus()) {
if (deviceID == 0 && Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
_keyboardMouseDevice->mouseReleaseEvent(event);
}
@ -4689,6 +4736,14 @@ glm::uvec2 Application::getCanvasSize() const {
return glm::uvec2(_glWidget->width(), _glWidget->height());
}
QRect Application::getApplicationGeometry() const {
auto geometry = _glWidget->geometry();
auto topLeft = geometry.topLeft();
auto topLeftScreen = _glWidget->mapToGlobal(topLeft);
geometry.moveTopLeft(topLeftScreen);
return geometry;
}
glm::uvec2 Application::getUiSize() const {
return getActiveDisplayPlugin()->getRecommendedUiSize();
}

View file

@ -114,6 +114,8 @@ public:
bool eventFilter(QObject* object, QEvent* event) override;
glm::uvec2 getCanvasSize() const;
QRect getApplicationGeometry() const;
glm::uvec2 getUiSize() const;
QSize getDeviceSize() const;
bool hasFocus() const;
@ -219,6 +221,8 @@ public:
float getAverageSimsPerSecond();
void fakeMouseEvent(QMouseEvent* event);
signals:
void svoImportRequested(const QString& url);
@ -368,10 +372,10 @@ private:
void focusOutEvent(QFocusEvent* event);
void focusInEvent(QFocusEvent* event);
void mouseMoveEvent(QMouseEvent* event, unsigned int deviceID = 0);
void mousePressEvent(QMouseEvent* event, unsigned int deviceID = 0);
void mouseDoublePressEvent(QMouseEvent* event, unsigned int deviceID = 0);
void mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID = 0);
void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseDoublePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
void touchBeginEvent(QTouchEvent* event);
void touchEndEvent(QTouchEvent* event);
@ -381,6 +385,7 @@ private:
void dropEvent(QDropEvent* event);
void dragEnterEvent(QDragEnterEvent* event);
void maybeToggleMenuVisible(QMouseEvent* event);
bool _dependencyManagerIsSetup;
@ -510,6 +515,8 @@ private:
bool _settingsLoaded { false };
bool _pendingPaint { false };
QTimer* _idleTimer { nullptr };
bool _fakedMouseEvent { false };
};
#endif // hifi_Application_h

View file

@ -164,10 +164,10 @@ InputController::Key InputController::getKey() const {
void ControllerScriptingInterface::emitKeyPressEvent(QKeyEvent* event) { emit keyPressEvent(KeyEvent(*event)); }
void ControllerScriptingInterface::emitKeyReleaseEvent(QKeyEvent* event) { emit keyReleaseEvent(KeyEvent(*event)); }
void ControllerScriptingInterface::emitMouseMoveEvent(QMouseEvent* event, unsigned int deviceID) { emit mouseMoveEvent(MouseEvent(*event, deviceID)); }
void ControllerScriptingInterface::emitMousePressEvent(QMouseEvent* event, unsigned int deviceID) { emit mousePressEvent(MouseEvent(*event, deviceID)); }
void ControllerScriptingInterface::emitMouseDoublePressEvent(QMouseEvent* event, unsigned int deviceID) { emit mouseDoublePressEvent(MouseEvent(*event, deviceID)); }
void ControllerScriptingInterface::emitMouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) { emit mouseReleaseEvent(MouseEvent(*event, deviceID)); }
void ControllerScriptingInterface::emitMouseMoveEvent(QMouseEvent* event) { emit mouseMoveEvent(MouseEvent(*event)); }
void ControllerScriptingInterface::emitMousePressEvent(QMouseEvent* event) { emit mousePressEvent(MouseEvent(*event)); }
void ControllerScriptingInterface::emitMouseDoublePressEvent(QMouseEvent* event) { emit mouseDoublePressEvent(MouseEvent(*event)); }
void ControllerScriptingInterface::emitMouseReleaseEvent(QMouseEvent* event) { emit mouseReleaseEvent(MouseEvent(*event)); }
void ControllerScriptingInterface::emitTouchBeginEvent(const TouchEvent& event) { emit touchBeginEvent(event); }
void ControllerScriptingInterface::emitTouchEndEvent(const TouchEvent& event) { emit touchEndEvent(event); }

View file

@ -70,10 +70,10 @@ public:
void handleMetaEvent(HFMetaEvent* event);
void emitMouseMoveEvent(QMouseEvent* event, unsigned int deviceID = 0);
void emitMousePressEvent(QMouseEvent* event, unsigned int deviceID = 0);
void emitMouseDoublePressEvent(QMouseEvent* event, unsigned int deviceID = 0);
void emitMouseReleaseEvent(QMouseEvent* event, unsigned int deviceID = 0);
void emitMouseMoveEvent(QMouseEvent* event);
void emitMousePressEvent(QMouseEvent* event);
void emitMouseDoublePressEvent(QMouseEvent* event);
void emitMouseReleaseEvent(QMouseEvent* event);
void emitTouchBeginEvent(const TouchEvent& event);
void emitTouchEndEvent(const TouchEvent& event);
@ -111,10 +111,10 @@ signals:
void backStartEvent();
void backEndEvent();
void mouseMoveEvent(const MouseEvent& event, unsigned int deviceID = 0);
void mousePressEvent(const MouseEvent& event, unsigned int deviceID = 0);
void mouseDoublePressEvent(const MouseEvent& event, unsigned int deviceID = 0);
void mouseReleaseEvent(const MouseEvent& event, unsigned int deviceID = 0);
void mouseMoveEvent(const MouseEvent& event);
void mousePressEvent(const MouseEvent& event);
void mouseDoublePressEvent(const MouseEvent& event);
void mouseReleaseEvent(const MouseEvent& event);
void touchBeginEvent(const TouchEvent& event);
void touchEndEvent(const TouchEvent& event);

View file

@ -216,7 +216,7 @@ void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) {
//draw the mouse pointer
// Get the mouse coordinates and convert to NDC [-1, 1]
vec2 canvasSize = qApp->getCanvasSize();
vec2 canvasSize = qApp->getCanvasSize(); // desktop, use actual canvas...
vec2 mousePosition = toNormalizedDeviceScale(vec2(qApp->getMouse()), canvasSize);
// Invert the Y axis
mousePosition.y *= -1.0f;
@ -246,7 +246,8 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
updateTooltips();
vec2 canvasSize = qApp->getCanvasSize();
glm::uvec2 screenSize { VIRTUAL_SCREEN_SIZE_X, VIRTUAL_SCREEN_SIZE_Y }; // = qApp->getCanvasSize(); // HMD use virtual screen size
vec2 canvasSize = screenSize;
_textureAspectRatio = aspect(canvasSize);
auto geometryCache = DependencyManager::get<GeometryCache>();
@ -288,8 +289,9 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
glm::mat4 overlayXfm;
_modelTransform.getMatrix(overlayXfm);
glm::vec2 projection = screenToSpherical(qApp->getTrueMouse());
auto reticlePosition = getReticlePosition();
//qDebug() << "reticlePosition:" << reticlePosition; // FIXME - remove this debugging
glm::vec2 projection = screenToSpherical(reticlePosition);
float cursorDepth = getReticleDepth();
mat4 pointerXfm = glm::scale(mat4(), vec3(cursorDepth)) * glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
mat4 reticleXfm = overlayXfm * pointerXfm;
@ -300,6 +302,85 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
});
}
QPointF ApplicationCompositor::getMouseEventPosition(QMouseEvent* event) {
if (qApp->isHMDMode()) {
return QPointF(_reticlePositionInHMD.x, _reticlePositionInHMD.y);
}
return event->localPos();
}
void ApplicationCompositor::handleLeaveEvent() {
if (qApp->isHMDMode()) {
auto applicationGeometry = qApp->getApplicationGeometry();
qDebug() << "SENDING mouse back to center:" << applicationGeometry.center();
_ignoreMouseMove = true;
auto sendToPos = applicationGeometry.center();
QCursor::setPos(sendToPos);
_lastKnownRealMouse = sendToPos;
}
}
void ApplicationCompositor::trackRealMouseMoveEvent(QMouseEvent* event) {
qDebug() << __FUNCTION__ << "() BEFORE _lastKnownRealMouse:" << _lastKnownRealMouse;
_lastKnownRealMouse = QCursor::pos();
qDebug() << __FUNCTION__ << "() AFTER _lastKnownRealMouse:" << _lastKnownRealMouse;
}
void ApplicationCompositor::handleRealMouseMoveEvent(QMouseEvent* event) {
qDebug() << __FUNCTION__ << "() event:" << event;
if (_ignoreMouseMove) {
qDebug() << __FUNCTION__ << "() IGNORE MOUSE MOVE!!!";
_ignoreMouseMove = false;
return;
}
auto applicationGeometry = qApp->getApplicationGeometry();
qDebug() << ".... applicationGeometry:" << applicationGeometry;
auto newPosition = QCursor::pos();
auto changeInRealMouse = newPosition - _lastKnownRealMouse;
qDebug() << __FUNCTION__ << "() ..... _lastKnownRealMouse:" << _lastKnownRealMouse;
qDebug() << __FUNCTION__ << "() ............. newPosition:" << newPosition;
qDebug() << __FUNCTION__ << "() ....... changeInRealMouse:" << changeInRealMouse;
auto newReticlePosition = _reticlePositionInHMD + toGlm(changeInRealMouse);
_lastKnownRealMouse = newPosition;
qDebug() << ".... about to call setReticlePosition() newReticlePosition:" << newReticlePosition;
setReticlePosition(newReticlePosition);
}
glm::vec2 ApplicationCompositor::getReticlePosition() {
if (qApp->isHMDMode()) {
return _reticlePositionInHMD;
}
return toGlm(QCursor::pos());
}
void ApplicationCompositor::setReticlePosition(glm::vec2 position) {
if (qApp->isHMDMode()) {
_reticlePositionInHMD = glm::clamp(position, vec2(0), vec2(VIRTUAL_SCREEN_SIZE_X, VIRTUAL_SCREEN_SIZE_Y));
// in HMD mode we need to fake our mouse moves...
QPoint globalPos(_reticlePositionInHMD.x, _reticlePositionInHMD.y);
QMouseEvent event(QEvent::MouseMove, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
qDebug() << "about to call .... qApp->fakeMouseEvent(&event);";
qApp->fakeMouseEvent(&event);
} else {
// NOTE: This is some debugging code we will leave in while debugging various reticle movement strategies,
// remove it after we're done
const float REASONABLE_CHANGE = 50.0f;
glm::vec2 oldPos = toGlm(QCursor::pos());
auto distance = glm::distance(oldPos, position);
if (distance > REASONABLE_CHANGE) {
qDebug() << "Contrller::ScriptingInterface ---- UNREASONABLE CHANGE! distance:" << distance << " oldPos:" << oldPos << " newPos:" << position;
}
QCursor::setPos(position.x, position.y);
}
}
// FIXME - this probably is hella buggy and probably doesn't work correctly
// we should kill it asap.
@ -460,7 +541,7 @@ void ApplicationCompositor::drawSphereSection(gpu::Batch& batch) {
}
glm::vec2 ApplicationCompositor::screenToSpherical(const glm::vec2& screenPos) {
auto screenSize = qApp->getCanvasSize();
glm::uvec2 screenSize { VIRTUAL_SCREEN_SIZE_X, VIRTUAL_SCREEN_SIZE_Y }; // = qApp->getCanvasSize();
glm::vec2 result;
result.x = -(screenPos.x / screenSize.x - 0.5f);
result.y = (screenPos.y / screenSize.y - 0.5f);
@ -470,11 +551,12 @@ glm::vec2 ApplicationCompositor::screenToSpherical(const glm::vec2& screenPos) {
}
glm::vec2 ApplicationCompositor::sphericalToScreen(const glm::vec2& sphericalPos) {
glm::uvec2 screenSize { VIRTUAL_SCREEN_SIZE_X, VIRTUAL_SCREEN_SIZE_Y }; // = qApp->getCanvasSize();
glm::vec2 result = sphericalPos;
result.x *= -1.0f;
result /= MOUSE_RANGE;
result += 0.5f;
result *= qApp->getCanvasSize();
result *= screenSize;
return result;
}

View file

@ -10,6 +10,7 @@
#define hifi_ApplicationCompositor_h
#include <QCursor>
#include <QMouseEvent>
#include <QObject>
#include <QPropertyAnimation>
#include <cstdint>
@ -25,6 +26,10 @@ class PalmData;
class RenderArgs;
class ReticleInterface;
const int VIRTUAL_SCREEN_SIZE_X = 4096;
const int VIRTUAL_SCREEN_SIZE_Y = 2160;
const float MAGNIFY_WIDTH = 220.0f;
const float MAGNIFY_HEIGHT = 100.0f;
const float MAGNIFY_MULT = 2.0f;
@ -88,24 +93,16 @@ public:
Q_INVOKABLE float getReticleDepth() { return _reticleDepth; }
Q_INVOKABLE void setReticleDepth(float depth) { _reticleDepth = depth; }
Q_INVOKABLE glm::vec2 getReticlePosition() {
return toGlm(QCursor::pos());
}
Q_INVOKABLE void setReticlePosition(glm::vec2 position) {
// NOTE: This is some debugging code we will leave in while debugging various reticle movement strategies,
// remove it after we're done
const float REASONABLE_CHANGE = 50.0f;
glm::vec2 oldPos = toGlm(QCursor::pos());
auto distance = glm::distance(oldPos, position);
if (distance > REASONABLE_CHANGE) {
qDebug() << "Contrller::ScriptingInterface ---- UNREASONABLE CHANGE! distance:" << distance << " oldPos:" << oldPos << " newPos:" << position;
}
QCursor::setPos(position.x, position.y);
}
Q_INVOKABLE glm::vec2 getReticlePosition();
Q_INVOKABLE void setReticlePosition(glm::vec2 position);
ReticleInterface* getReticleInterface() { return _reticleInterface; }
void handleRealMouseMoveEvent(QMouseEvent* event);
void trackRealMouseMoveEvent(QMouseEvent* event);
void handleLeaveEvent();
QPointF getMouseEventPosition(QMouseEvent* event);
private:
void displayOverlayTextureStereo(RenderArgs* renderArgs, float aspectRatio, float fov);
@ -146,6 +143,14 @@ private:
bool _reticleVisible { true };
float _reticleDepth { 1.0f };
// NOTE: when the compositor is running in HMD mode, it will control the reticle position as a custom
// application specific position, when it's in desktop mode, the reticle position will simply move
// the system mouse.
glm::vec2 _reticlePositionInHMD{ 0.0f, 0.0f };
QPointF _lastKnownRealMouse;
QPoint _lastKnownCursorPos;
bool _ignoreMouseMove { false };
ReticleInterface* _reticleInterface;
};

View file

@ -492,16 +492,16 @@ RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(cons
void EntityTreeRenderer::connectSignalsToSlots(EntityScriptingInterface* entityScriptingInterface) {
connect(this, &EntityTreeRenderer::mousePressOnEntity, entityScriptingInterface,
[=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId){
entityScriptingInterface->mousePressOnEntity(intersection.entityID, MouseEvent(*event, deviceId));
[=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event){
entityScriptingInterface->mousePressOnEntity(intersection.entityID, MouseEvent(*event));
});
connect(this, &EntityTreeRenderer::mouseMoveOnEntity, entityScriptingInterface,
[=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId) {
entityScriptingInterface->mouseMoveOnEntity(intersection.entityID, MouseEvent(*event, deviceId));
[=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event) {
entityScriptingInterface->mouseMoveOnEntity(intersection.entityID, MouseEvent(*event));
});
connect(this, &EntityTreeRenderer::mouseReleaseOnEntity, entityScriptingInterface,
[=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId) {
entityScriptingInterface->mouseReleaseOnEntity(intersection.entityID, MouseEvent(*event, deviceId));
[=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event) {
entityScriptingInterface->mouseReleaseOnEntity(intersection.entityID, MouseEvent(*event));
});
connect(this, &EntityTreeRenderer::clickDownOnEntity, entityScriptingInterface, &EntityScriptingInterface::clickDownOnEntity);
@ -519,7 +519,7 @@ void EntityTreeRenderer::connectSignalsToSlots(EntityScriptingInterface* entityS
connect(DependencyManager::get<SceneScriptingInterface>().data(), &SceneScriptingInterface::shouldRenderEntitiesChanged, this, &EntityTreeRenderer::updateEntityRenderStatus, Qt::QueuedConnection);
}
void EntityTreeRenderer::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) {
// If we don't have a tree, or we're in the process of shutting down, then don't
// process these events.
if (!_tree || _shuttingDown) {
@ -540,20 +540,20 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event, unsigned int device
}
emit mousePressOnEntity(rayPickResult, event, deviceID);
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mousePressOnEntity", MouseEvent(*event, deviceID));
emit mousePressOnEntity(rayPickResult, event);
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mousePressOnEntity", MouseEvent(*event));
_currentClickingOnEntityID = rayPickResult.entityID;
emit clickDownOnEntity(_currentClickingOnEntityID, MouseEvent(*event, deviceID));
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "clickDownOnEntity", MouseEvent(*event, deviceID));
emit clickDownOnEntity(_currentClickingOnEntityID, MouseEvent(*event));
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "clickDownOnEntity", MouseEvent(*event));
} else {
emit mousePressOffEntity(rayPickResult, event, deviceID);
emit mousePressOffEntity(rayPickResult, event);
}
_lastMouseEvent = MouseEvent(*event, deviceID);
_lastMouseEvent = MouseEvent(*event);
_lastMouseEventValid = true;
}
void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) {
void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) {
// If we don't have a tree, or we're in the process of shutting down, then don't
// process these events.
if (!_tree || _shuttingDown) {
@ -565,24 +565,24 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event, unsigned int devi
RayToEntityIntersectionResult rayPickResult = findRayIntersectionWorker(ray, Octree::Lock, precisionPicking);
if (rayPickResult.intersects) {
//qCDebug(entitiesrenderer) << "mouseReleaseEvent over entity:" << rayPickResult.entityID;
emit mouseReleaseOnEntity(rayPickResult, event, deviceID);
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseReleaseOnEntity", MouseEvent(*event, deviceID));
emit mouseReleaseOnEntity(rayPickResult, event);
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseReleaseOnEntity", MouseEvent(*event));
}
// Even if we're no longer intersecting with an entity, if we started clicking on it, and now
// we're releasing the button, then this is considered a clickOn event
if (!_currentClickingOnEntityID.isInvalidID()) {
emit clickReleaseOnEntity(_currentClickingOnEntityID, MouseEvent(*event, deviceID));
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "clickReleaseOnEntity", MouseEvent(*event, deviceID));
emit clickReleaseOnEntity(_currentClickingOnEntityID, MouseEvent(*event));
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "clickReleaseOnEntity", MouseEvent(*event));
}
// makes it the unknown ID, we just released so we can't be clicking on anything
_currentClickingOnEntityID = UNKNOWN_ENTITY_ID;
_lastMouseEvent = MouseEvent(*event, deviceID);
_lastMouseEvent = MouseEvent(*event);
_lastMouseEventValid = true;
}
void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
// If we don't have a tree, or we're in the process of shutting down, then don't
// process these events.
if (!_tree || _shuttingDown) {
@ -596,28 +596,28 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event, unsigned int deviceI
RayToEntityIntersectionResult rayPickResult = findRayIntersectionWorker(ray, Octree::TryLock, precisionPicking);
if (rayPickResult.intersects) {
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveEvent", MouseEvent(*event, deviceID));
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveOnEntity", MouseEvent(*event, deviceID));
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveEvent", MouseEvent(*event));
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveOnEntity", MouseEvent(*event));
// handle the hover logic...
// if we were previously hovering over an entity, and this new entity is not the same as our previous entity
// then we need to send the hover leave.
if (!_currentHoverOverEntityID.isInvalidID() && rayPickResult.entityID != _currentHoverOverEntityID) {
emit hoverLeaveEntity(_currentHoverOverEntityID, MouseEvent(*event, deviceID));
_entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", MouseEvent(*event, deviceID));
emit hoverLeaveEntity(_currentHoverOverEntityID, MouseEvent(*event));
_entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", MouseEvent(*event));
}
// If the new hover entity does not match the previous hover entity then we are entering the new one
// this is true if the _currentHoverOverEntityID is known or unknown
if (rayPickResult.entityID != _currentHoverOverEntityID) {
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverEnterEntity", MouseEvent(*event, deviceID));
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverEnterEntity", MouseEvent(*event));
}
// and finally, no matter what, if we're intersecting an entity then we're definitely hovering over it, and
// we should send our hover over event
emit hoverOverEntity(rayPickResult.entityID, MouseEvent(*event, deviceID));
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverOverEntity", MouseEvent(*event, deviceID));
emit hoverOverEntity(rayPickResult.entityID, MouseEvent(*event));
_entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverOverEntity", MouseEvent(*event));
// remember what we're hovering over
_currentHoverOverEntityID = rayPickResult.entityID;
@ -627,8 +627,8 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event, unsigned int deviceI
// if we were previously hovering over an entity, and we're no longer hovering over any entity then we need to
// send the hover leave for our previous entity
if (!_currentHoverOverEntityID.isInvalidID()) {
emit hoverLeaveEntity(_currentHoverOverEntityID, MouseEvent(*event, deviceID));
_entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", MouseEvent(*event, deviceID));
emit hoverLeaveEntity(_currentHoverOverEntityID, MouseEvent(*event));
_entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", MouseEvent(*event));
_currentHoverOverEntityID = UNKNOWN_ENTITY_ID; // makes it the unknown ID
}
}
@ -636,10 +636,10 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event, unsigned int deviceI
// Even if we're no longer intersecting with an entity, if we started clicking on an entity and we have
// not yet released the hold then this is still considered a holdingClickOnEntity event
if (!_currentClickingOnEntityID.isInvalidID()) {
emit holdingClickOnEntity(_currentClickingOnEntityID, MouseEvent(*event, deviceID));
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "holdingClickOnEntity", MouseEvent(*event, deviceID));
emit holdingClickOnEntity(_currentClickingOnEntityID, MouseEvent(*event));
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "holdingClickOnEntity", MouseEvent(*event));
}
_lastMouseEvent = MouseEvent(*event, deviceID);
_lastMouseEvent = MouseEvent(*event);
_lastMouseEventValid = true;
}

View file

@ -74,9 +74,9 @@ public:
void deleteReleasedModels();
// event handles which may generate entity related events
void mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID);
void mousePressEvent(QMouseEvent* event, unsigned int deviceID);
void mouseMoveEvent(QMouseEvent* event, unsigned int deviceID);
void mouseReleaseEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
/// connect our signals to anEntityScriptingInterface for firing of events related clicking,
/// hovering over, and entering entities
@ -86,10 +86,10 @@ public:
QList<EntityItemID>& getEntitiesLastInScene() { return _entityIDsLastInScene; }
signals:
void mousePressOnEntity(const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId);
void mousePressOffEntity(const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId);
void mouseMoveOnEntity(const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId);
void mouseReleaseOnEntity(const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId);
void mousePressOnEntity(const RayToEntityIntersectionResult& intersection, const QMouseEvent* event);
void mousePressOffEntity(const RayToEntityIntersectionResult& intersection, const QMouseEvent* event);
void mouseMoveOnEntity(const RayToEntityIntersectionResult& intersection, const QMouseEvent* event);
void mouseReleaseOnEntity(const RayToEntityIntersectionResult& intersection, const QMouseEvent* event);
void clickDownOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
void holdingClickOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);

View file

@ -85,7 +85,7 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
_texture = textureId;
});
auto forwardMouseEvent = [=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event, unsigned int deviceId) {
auto forwardMouseEvent = [=](const RayToEntityIntersectionResult& intersection, const QMouseEvent* event) {
// Ignore mouse interaction if we're locked
if (this->getLocked()) {
return;

View file

@ -57,7 +57,7 @@ void KeyboardMouseDevice::keyReleaseEvent(QKeyEvent* event) {
_inputDevice->_buttonPressedMap.erase(input.getChannel());
}
void KeyboardMouseDevice::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
void KeyboardMouseDevice::mousePressEvent(QMouseEvent* event) {
auto input = _inputDevice->makeInput((Qt::MouseButton) event->button());
auto result = _inputDevice->_buttonPressedMap.insert(input.getChannel());
if (!result.second) {
@ -70,7 +70,7 @@ void KeyboardMouseDevice::mousePressEvent(QMouseEvent* event, unsigned int devic
eraseMouseClicked();
}
void KeyboardMouseDevice::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) {
void KeyboardMouseDevice::mouseReleaseEvent(QMouseEvent* event) {
auto input = _inputDevice->makeInput((Qt::MouseButton) event->button());
_inputDevice->_buttonPressedMap.erase(input.getChannel());
@ -89,7 +89,7 @@ void KeyboardMouseDevice::eraseMouseClicked() {
_inputDevice->_buttonPressedMap.erase(_inputDevice->makeInput(Qt::RightButton, true).getChannel());
}
void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event) {
QPoint currentPos = event->pos();
QPoint currentMove = currentPos - _lastCursor;

View file

@ -75,9 +75,9 @@ public:
void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event);
void mouseMoveEvent(QMouseEvent* event, unsigned int deviceID = 0);
void mousePressEvent(QMouseEvent* event, unsigned int deviceID = 0);
void mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID = 0);
void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
void eraseMouseClicked();
void touchBeginEvent(const QTouchEvent* event);

View file

@ -29,10 +29,9 @@ MouseEvent::MouseEvent() :
}
MouseEvent::MouseEvent(const QMouseEvent& event, const unsigned int deviceID) :
MouseEvent::MouseEvent(const QMouseEvent& event) :
x(event.x()),
y(event.y()),
deviceID(deviceID),
isLeftButton(event.buttons().testFlag(Qt::LeftButton)),
isRightButton(event.buttons().testFlag(Qt::RightButton)),
isMiddleButton(event.buttons().testFlag(Qt::MiddleButton)),
@ -66,7 +65,6 @@ QScriptValue MouseEvent::toScriptValue(QScriptEngine* engine, const MouseEvent&
obj.setProperty("x", event.x);
obj.setProperty("y", event.y);
obj.setProperty("button", event.button);
obj.setProperty("deviceID", event.deviceID);
obj.setProperty("isLeftButton", event.isLeftButton);
obj.setProperty("isRightButton", event.isRightButton);
obj.setProperty("isMiddleButton", event.isMiddleButton);

View file

@ -17,7 +17,7 @@
class MouseEvent {
public:
MouseEvent();
MouseEvent(const QMouseEvent& event, const unsigned int deviceID = 0);
MouseEvent(const QMouseEvent& event);
static QScriptValue toScriptValue(QScriptEngine* engine, const MouseEvent& event);
static void fromScriptValue(const QScriptValue& object, MouseEvent& event);
@ -26,7 +26,6 @@ public:
int x;
int y;
unsigned int deviceID;
QString button;
bool isLeftButton;
bool isRightButton;