fix reticle bugs

This commit is contained in:
howard-stearns 2016-06-23 16:51:15 -07:00
parent 581d87d653
commit f8391f0062
4 changed files with 32 additions and 21 deletions

View file

@ -921,17 +921,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
cycleCamera(); cycleCamera();
} else if (action == controller::toInt(controller::Action::UI_NAV_SELECT)) { } else if (action == controller::toInt(controller::Action::UI_NAV_SELECT)) {
if (!offscreenUi->navigationFocused()) { if (!offscreenUi->navigationFocused()) {
auto reticlePosition = getApplicationCompositor().getReticlePosition(); toggleMenuUnderReticle();
offscreenUi->toggleMenu(QPoint(reticlePosition.x, reticlePosition.y));
} }
} else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) { } else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) {
auto reticlePosition = getApplicationCompositor().getReticlePosition(); toggleMenuUnderReticle();
offscreenUi->toggleMenu(QPoint(reticlePosition.x, reticlePosition.y));
} else if (action == controller::toInt(controller::Action::UI_NAV_SELECT)) {
if (!offscreenUi->navigationFocused()) {
auto reticlePosition = getApplicationCompositor().getReticlePosition();
offscreenUi->toggleMenu(QPoint(reticlePosition.x, reticlePosition.y));
}
} else if (action == controller::toInt(controller::Action::RETICLE_X)) { } else if (action == controller::toInt(controller::Action::RETICLE_X)) {
auto oldPos = getApplicationCompositor().getReticlePosition(); auto oldPos = getApplicationCompositor().getReticlePosition();
getApplicationCompositor().setReticlePosition({ oldPos.x + state, oldPos.y }); getApplicationCompositor().setReticlePosition({ oldPos.x + state, oldPos.y });
@ -1240,7 +1233,16 @@ QString Application::getUserAgent() {
return userAgent; return userAgent;
} }
void Application::toggleMenuUnderReticle() const {
// In HMD, if the menu is near the mouse but not under it, the reticle can be at a significantly
// different depth. When you focus on the menu, the cursor can appear to your crossed eyes as both
// on the menu and off.
// Even in 2D, it is arguable whether the user would want the menu to be to the side.
const float X_LEFT_SHIFT = 50.0;
auto offscreenUi = DependencyManager::get<OffscreenUi>();
auto reticlePosition = getApplicationCompositor().getReticlePosition();
offscreenUi->toggleMenu(QPoint(reticlePosition.x - X_LEFT_SHIFT, reticlePosition.y));
}
void Application::checkChangeCursor() { void Application::checkChangeCursor() {
QMutexLocker locker(&_changeCursorLock); QMutexLocker locker(&_changeCursorLock);
@ -2462,9 +2464,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
void Application::keyReleaseEvent(QKeyEvent* event) { void Application::keyReleaseEvent(QKeyEvent* event) {
if (event->key() == Qt::Key_Alt && _altPressed && hasFocus()) { if (event->key() == Qt::Key_Alt && _altPressed && hasFocus()) {
auto offscreenUi = DependencyManager::get<OffscreenUi>(); toggleMenuUnderReticle();
auto reticlePosition = getApplicationCompositor().getReticlePosition();
offscreenUi->toggleMenu(QPoint(reticlePosition.x, reticlePosition.y));
} }
_keysPressed.remove(event->key()); _keysPressed.remove(event->key());

View file

@ -408,6 +408,7 @@ private:
static void dragEnterEvent(QDragEnterEvent* event); static void dragEnterEvent(QDragEnterEvent* event);
void maybeToggleMenuVisible(QMouseEvent* event) const; void maybeToggleMenuVisible(QMouseEvent* event) const;
void toggleMenuUnderReticle() const;
MainWindow* _window; MainWindow* _window;
QElapsedTimer& _sessionRunTimer; QElapsedTimer& _sessionRunTimer;

View file

@ -492,10 +492,9 @@ void OffscreenUi::unfocusWindows() {
Q_ASSERT(invokeResult); Q_ASSERT(invokeResult);
} }
void OffscreenUi::toggleMenu(const QPoint& screenPosition) { void OffscreenUi::toggleMenu(const QPoint& screenPosition) { // caller should already have mapped using getReticlePosition
emit showDesktop(); // we really only want to do this if you're showing the menu, but for now this works emit showDesktop(); // we really only want to do this if you're showing the menu, but for now this works
auto virtualPos = mapToVirtualScreen(screenPosition, nullptr); QMetaObject::invokeMethod(_desktop, "toggleMenu", Q_ARG(QVariant, screenPosition));
QMetaObject::invokeMethod(_desktop, "toggleMenu", Q_ARG(QVariant, virtualPos));
} }

View file

@ -208,9 +208,9 @@ function isShakingMouse() { // True if the person is waving the mouse around try
return isShaking; return isShaking;
} }
var NON_LINEAR_DIVISOR = 2; var NON_LINEAR_DIVISOR = 2;
var MINIMUM_SEEK_DISTANCE = 0.01; var MINIMUM_SEEK_DISTANCE = 0.1;
function updateSeeking() { function updateSeeking(doNotStartSeeking) {
if (!Reticle.visible || isShakingMouse()) { if (!doNotStartSeeking && (!Reticle.visible || isShakingMouse())) {
if (!isSeeking) { if (!isSeeking) {
print('Start seeking mouse.'); print('Start seeking mouse.');
isSeeking = true; isSeeking = true;
@ -224,8 +224,8 @@ function updateSeeking() {
if (!lookAt2D) { // If this happens, something has gone terribly wrong. if (!lookAt2D) { // If this happens, something has gone terribly wrong.
print('Cannot seek without lookAt position'); print('Cannot seek without lookAt position');
isSeeking = false; isSeeking = false;
return; return; // E.g., if parallel to location in HUD
} // E.g., if parallel to location in HUD }
var copy = Reticle.position; var copy = Reticle.position;
function updateDimension(axis) { function updateDimension(axis) {
var distanceBetween = lookAt2D[axis] - Reticle.position[axis]; var distanceBetween = lookAt2D[axis] - Reticle.position[axis];
@ -353,6 +353,16 @@ clickMapping.from(rightTrigger.full).when(isPointingAtOverlayStartedNonFullTrigg
clickMapping.from(leftTrigger.full).when(isPointingAtOverlayStartedNonFullTrigger(leftTrigger)).to(Controller.Actions.ReticleClick); clickMapping.from(leftTrigger.full).when(isPointingAtOverlayStartedNonFullTrigger(leftTrigger)).to(Controller.Actions.ReticleClick);
clickMapping.from(Controller.Standard.RightSecondaryThumb).peek().to(Controller.Actions.ContextMenu); clickMapping.from(Controller.Standard.RightSecondaryThumb).peek().to(Controller.Actions.ContextMenu);
clickMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(Controller.Actions.ContextMenu); clickMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(Controller.Actions.ContextMenu);
clickMapping.from(Controller.Hardware.Keyboard.RightMouseClicked).peek().to(function () {
// Allow the reticle depth to be set correctly:
// Wait a tick for the context menu to be displayed, and then simulate a (non-hand-controller) mouse move
// so that the system updates qml state (Reticle.pointingAtSystemOverlay) before it gives us a mouseMove.
// We don't want the system code to always do this for us, because, e.g., we do not want to get a mouseMove
// after the Left/RightSecondaryThumb gives us a context menu. Only from the mouse.
Script.setTimeout(function () {
Reticle.setPosition(Reticle.position);
}, 0);
});
// Partial smoothed trigger is activation. // Partial smoothed trigger is activation.
clickMapping.from(rightTrigger.partial).to(makeToggleAction(Controller.Standard.RightHand)); clickMapping.from(rightTrigger.partial).to(makeToggleAction(Controller.Standard.RightHand));
clickMapping.from(leftTrigger.partial).to(makeToggleAction(Controller.Standard.LeftHand)); clickMapping.from(leftTrigger.partial).to(makeToggleAction(Controller.Standard.LeftHand));
@ -386,6 +396,7 @@ function update() {
expireMouseCursor(); expireMouseCursor();
clearSystemLaser(); clearSystemLaser();
} }
updateSeeking(true);
if (!handControllerLockOut.expired(now)) { if (!handControllerLockOut.expired(now)) {
return off(); // Let them use mouse it in peace. return off(); // Let them use mouse it in peace.
} }