History

Merge pull request #8335 from hyperlogic/feature/hand-controller-web-entity-integration

handControllerGrab and web entity input integration

Brad Hefta-Gaub committed 10 years ago

Commit 21bc06f2 parents 52cd222 d015c5c21 files · +1069 −318Browse files

Showing the changes to interface/src/Application.cpp (1 of 21 files). Show all

Unified · Split

interface/src/Application.cpp+139−74
@@ -1067,70 +1067,23 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : · 1066 unmodified lines
1067 // If the user clicks an an entity, we will check that it's an unlocked web entity, and if so, set the focus to it1067 // If the user clicks an an entity, we will check that it's an unlocked web entity, and if so, set the focus to it
1068 auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();1068 auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
1069 connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity,1069 connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity,
1070 [this, entityScriptingInterface](const EntityItemID& entityItemID, const MouseEvent& event) {1070 [this](const EntityItemID& entityItemID, const PointerEvent& event) {
1071 if (_keyboardFocusedItem != entityItemID) {1071 setKeyboardFocusEntity(entityItemID);
1072 _keyboardFocusedItem = UNKNOWN_ENTITY_ID;
1073 auto properties = entityScriptingInterface->getEntityProperties(entityItemID);
1074 if (EntityTypes::Web == properties.getType() && !properties.getLocked() && properties.getVisible()) {
1075 auto entity = entityScriptingInterface->getEntityTree()->findEntityByID(entityItemID);
1076 RenderableWebEntityItem* webEntity = dynamic_cast<RenderableWebEntityItem*>(entity.get());
1077 if (webEntity) {
1078 webEntity->setProxyWindow(_window->windowHandle());
1079 if (_keyboardMouseDevice->isActive()) {
1080 _keyboardMouseDevice->pluginFocusOutEvent();
1081 }
1082 _keyboardFocusedItem = entityItemID;
1083 _lastAcceptedKeyPress = usecTimestampNow();
1084 if (_keyboardFocusHighlightID < 0 || !getOverlays().isAddedOverlay(_keyboardFocusHighlightID)) {
1085 _keyboardFocusHighlight = new Cube3DOverlay();
1086 _keyboardFocusHighlight->setAlpha(1.0f);
1087 _keyboardFocusHighlight->setBorderSize(1.0f);
1088 _keyboardFocusHighlight->setColor({ 0xFF, 0xEF, 0x00 });
1089 _keyboardFocusHighlight->setIsSolid(false);
1090 _keyboardFocusHighlight->setPulseMin(0.5);
1091 _keyboardFocusHighlight->setPulseMax(1.0);
1092 _keyboardFocusHighlight->setColorPulse(1.0);
1093 _keyboardFocusHighlight->setIgnoreRayIntersection(true);
1094 _keyboardFocusHighlight->setDrawInFront(true);
1095 }
1096 _keyboardFocusHighlight->setRotation(webEntity->getRotation());
1097 _keyboardFocusHighlight->setPosition(webEntity->getPosition());
1098 _keyboardFocusHighlight->setDimensions(webEntity->getDimensions() * 1.05f);
1099 _keyboardFocusHighlight->setVisible(true);
1100 _keyboardFocusHighlightID = getOverlays().addOverlay(_keyboardFocusHighlight);
1101 }
1102 }
1103 if (_keyboardFocusedItem == UNKNOWN_ENTITY_ID && _keyboardFocusHighlight) {
1104 _keyboardFocusHighlight->setVisible(false);
1105 }
1106
1107 }
1108 });1072 });
1109 1073
1110 connect(entityScriptingInterface.data(), &EntityScriptingInterface::deletingEntity,1074 connect(entityScriptingInterface.data(), &EntityScriptingInterface::deletingEntity, [=](const EntityItemID& entityItemID) {
1111 [=](const EntityItemID& entityItemID) {1075 if (entityItemID == _keyboardFocusedItem.get()) {
1112 if (entityItemID == _keyboardFocusedItem) {1076 setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
1113 _keyboardFocusedItem = UNKNOWN_ENTITY_ID;
1114 if (_keyboardFocusHighlight) {
1115 _keyboardFocusHighlight->setVisible(false);
1116 }
1117 }1077 }
1118 });1078 });
1119 1079
1120 // If the user clicks somewhere where there is NO entity at all, we will release focus1080 // If the user clicks somewhere where there is NO entity at all, we will release focus
1121 connect(getEntities(), &EntityTreeRenderer::mousePressOffEntity,1081 connect(getEntities(), &EntityTreeRenderer::mousePressOffEntity, [=]() {
1122 [=](const RayToEntityIntersectionResult& entityItemID, const QMouseEvent* event) {1082 setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
1123 _keyboardFocusedItem = UNKNOWN_ENTITY_ID;
1124 if (_keyboardFocusHighlight) {
1125 _keyboardFocusHighlight->setVisible(false);
1126 }
1127 });1083 });
1128 1084
1129 connect(this, &Application::aboutToQuit, [=]() {1085 connect(this, &Application::aboutToQuit, [=]() {
1130 _keyboardFocusedItem = UNKNOWN_ENTITY_ID;1086 setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
1131 if (_keyboardFocusHighlight) {
1132 _keyboardFocusHighlight->setVisible(false);
1133 }
1134 });1087 });
1135 1088
1136 // Add periodic checks to send user activity data1089 // Add periodic checks to send user activity data
@@ -1403,11 +1356,13 @@ void Application::cleanupBeforeQuit() { · 266 unmodified lines
1403 // FIXME: once we move to shared pointer for the INputDevice we shoud remove this naked delete:1356 // FIXME: once we move to shared pointer for the INputDevice we shoud remove this naked delete:
1404 _applicationStateDevice.reset();1357 _applicationStateDevice.reset();
1405 1358
1406 if (_keyboardFocusHighlightID > 0) {1359 {
1407 getOverlays().deleteOverlay(_keyboardFocusHighlightID);1360 if (_keyboardFocusHighlightID > 0) {
1408 _keyboardFocusHighlightID = -1;1361 getOverlays().deleteOverlay(_keyboardFocusHighlightID);
1362 _keyboardFocusHighlightID = -1;
1363 }
1364 _keyboardFocusHighlight = nullptr;
1409 }1365 }
1410 _keyboardFocusHighlight = nullptr;
1411 1366
1412 auto nodeList = DependencyManager::get<NodeList>();1367 auto nodeList = DependencyManager::get<NodeList>();
1413 1368
@@ -2122,16 +2077,16 @@ bool Application::event(QEvent* event) { · 708 unmodified lines
2122 return true;2077 return true;
2123 }2078 }
2124 2079
2125 if (!_keyboardFocusedItem.isInvalidID()) {2080 {
2126 switch (event->type()) {2081 if (!_keyboardFocusedItem.get().isInvalidID()) {
2082 switch (event->type()) {
2127 case QEvent::KeyPress:2083 case QEvent::KeyPress:
2128 case QEvent::KeyRelease: {2084 case QEvent::KeyRelease: {
2129 auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();2085 auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
2130 auto entity = entityScriptingInterface->getEntityTree()->findEntityByID(_keyboardFocusedItem);2086 auto entity = getEntities()->getTree()->findEntityByID(_keyboardFocusedItem.get());
2131 RenderableWebEntityItem* webEntity = dynamic_cast<RenderableWebEntityItem*>(entity.get());2087 if (entity && entity->getEventHandler()) {
2132 if (webEntity && webEntity->getEventHandler()) {
2133 event->setAccepted(false);2088 event->setAccepted(false);
2134 QCoreApplication::sendEvent(webEntity->getEventHandler(), event);2089 QCoreApplication::sendEvent(entity->getEventHandler(), event);
2135 if (event->isAccepted()) {2090 if (event->isAccepted()) {
2136 _lastAcceptedKeyPress = usecTimestampNow();2091 _lastAcceptedKeyPress = usecTimestampNow();
2137 return true;2092 return true;
@@ -2142,6 +2097,7 @@ bool Application::event(QEvent* event) { · 4 unmodified lines
2142 2097
2143 default:2098 default:
2144 break;2099 break;
2100 }
2145 }2101 }
2146 }2102 }
2147 2103
@@ -2691,7 +2647,10 @@ void Application::mouseMoveEvent(QMouseEvent* event) { · 543 unmodified lines
2691 event->screenPos(), button,2647 event->screenPos(), button,
2692 buttons, event->modifiers());2648 buttons, event->modifiers());
2693 2649
2694 getEntities()->mouseMoveEvent(&mappedEvent);2650 if (compositor.getReticleVisible() || !isHMDMode() || !compositor.getReticleOverDesktop() ||
2651 getOverlays().getOverlayAtPoint(glm::vec2(transformedPos.x(), transformedPos.y()))) {
2652 getEntities()->mouseMoveEvent(&mappedEvent);
2653 }
2695 _controllerScriptingInterface->emitMouseMoveEvent(&mappedEvent); // send events to any registered scripts2654 _controllerScriptingInterface->emitMouseMoveEvent(&mappedEvent); // send events to any registered scripts
2696 2655
2697 // if one of our scripts have asked to capture this event, then stop processing it2656 // if one of our scripts have asked to capture this event, then stop processing it
@@ -2981,14 +2940,6 @@ void Application::idle(float nsecsElapsed) { · 283 unmodified lines
2981 _simCounter.increment();2940 _simCounter.increment();
2982 2941
2983 PerformanceTimer perfTimer("idle");2942 PerformanceTimer perfTimer("idle");
2984 // Drop focus from _keyboardFocusedItem if no keyboard messages for 30 seconds
2985 if (!_keyboardFocusedItem.isInvalidID()) {
2986 const quint64 LOSE_FOCUS_AFTER_ELAPSED_TIME = 30 * USECS_PER_SECOND; // if idle for 30 seconds, drop focus
2987 quint64 elapsedSinceAcceptedKeyPress = usecTimestampNow() - _lastAcceptedKeyPress;
2988 if (elapsedSinceAcceptedKeyPress > LOSE_FOCUS_AFTER_ELAPSED_TIME) {
2989 _keyboardFocusedItem = UNKNOWN_ENTITY_ID;
2990 }
2991 }
2992 2943
2993 // Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing2944 // Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
2994 // details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing2945 // details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing
@@ -3002,6 +2953,27 @@ void Application::idle(float nsecsElapsed) { · 7 unmodified lines
3002 static const float BIGGEST_DELTA_TIME_SECS = 0.25f;2953 static const float BIGGEST_DELTA_TIME_SECS = 0.25f;
3003 update(glm::clamp(secondsSinceLastUpdate, 0.0f, BIGGEST_DELTA_TIME_SECS));2954 update(glm::clamp(secondsSinceLastUpdate, 0.0f, BIGGEST_DELTA_TIME_SECS));
3004 }2955 }
2956
2957
2958 // Drop focus from _keyboardFocusedItem if no keyboard messages for 30 seconds
2959 {
2960 if (!_keyboardFocusedItem.get().isInvalidID()) {
2961 const quint64 LOSE_FOCUS_AFTER_ELAPSED_TIME = 30 * USECS_PER_SECOND; // if idle for 30 seconds, drop focus
2962 quint64 elapsedSinceAcceptedKeyPress = usecTimestampNow() - _lastAcceptedKeyPress;
2963 if (elapsedSinceAcceptedKeyPress > LOSE_FOCUS_AFTER_ELAPSED_TIME) {
2964 setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
2965 } else {
2966 // update position of highlight overlay
2967 auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
2968 auto entity = getEntities()->getTree()->findEntityByID(_keyboardFocusedItem.get());
2969 if (entity && _keyboardFocusHighlight) {
2970 _keyboardFocusHighlight->setRotation(entity->getRotation());
2971 _keyboardFocusHighlight->setPosition(entity->getPosition());
2972 }
2973 }
2974 }
2975 }
2976
3005 {2977 {
3006 PerformanceTimer perfTimer("pluginIdle");2978 PerformanceTimer perfTimer("pluginIdle");
3007 PerformanceWarning warn(showWarnings, "Application::idle()... pluginIdle()");2979 PerformanceWarning warn(showWarnings, "Application::idle()... pluginIdle()");
@@ -3586,6 +3558,54 @@ void Application::rotationModeChanged() const { · 578 unmodified lines
3586 }3558 }
3587}3559}
3588 3560
3561QUuid Application::getKeyboardFocusEntity() const {
3562 return _keyboardFocusedItem.get();
3563}
3564
3565void Application::setKeyboardFocusEntity(QUuid id) {
3566 EntityItemID entityItemID(id);
3567 setKeyboardFocusEntity(entityItemID);
3568}
3569
3570void Application::setKeyboardFocusEntity(EntityItemID entityItemID) {
3571 auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
3572 if (_keyboardFocusedItem.get() != entityItemID) {
3573 _keyboardFocusedItem.set(UNKNOWN_ENTITY_ID);
3574 auto properties = entityScriptingInterface->getEntityProperties(entityItemID);
3575 if (!properties.getLocked() && properties.getVisible()) {
3576 auto entity = getEntities()->getTree()->findEntityByID(entityItemID);
3577 if (entity && entity->wantsKeyboardFocus()) {
3578 entity->setProxyWindow(_window->windowHandle());
3579 if (_keyboardMouseDevice->isActive()) {
3580 _keyboardMouseDevice->pluginFocusOutEvent();
3581 }
3582 _keyboardFocusedItem.set(entityItemID);
3583 _lastAcceptedKeyPress = usecTimestampNow();
3584 if (_keyboardFocusHighlightID < 0 || !getOverlays().isAddedOverlay(_keyboardFocusHighlightID)) {
3585 _keyboardFocusHighlight = new Cube3DOverlay();
3586 _keyboardFocusHighlight->setAlpha(1.0f);
3587 _keyboardFocusHighlight->setBorderSize(1.0f);
3588 _keyboardFocusHighlight->setColor({ 0xFF, 0xEF, 0x00 });
3589 _keyboardFocusHighlight->setIsSolid(false);
3590 _keyboardFocusHighlight->setPulseMin(0.5);
3591 _keyboardFocusHighlight->setPulseMax(1.0);
3592 _keyboardFocusHighlight->setColorPulse(1.0);
3593 _keyboardFocusHighlight->setIgnoreRayIntersection(true);
3594 _keyboardFocusHighlight->setDrawInFront(false);
3595 }
3596 _keyboardFocusHighlight->setRotation(entity->getRotation());
3597 _keyboardFocusHighlight->setPosition(entity->getPosition());
3598 _keyboardFocusHighlight->setDimensions(entity->getDimensions() * 1.05f);
3599 _keyboardFocusHighlight->setVisible(true);
3600 _keyboardFocusHighlightID = getOverlays().addOverlay(_keyboardFocusHighlight);
3601 }
3602 }
3603 if (_keyboardFocusedItem.get() == UNKNOWN_ENTITY_ID && _keyboardFocusHighlight) {
3604 _keyboardFocusHighlight->setVisible(false);
3605 }
3606 }
3607}
3608
3589void Application::updateDialogs(float deltaTime) const {3609void Application::updateDialogs(float deltaTime) const {
3590 PerformanceTimer perfTimer("updateDialogs");3610 PerformanceTimer perfTimer("updateDialogs");
3591 bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);3611 bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
@@ -5642,3 +5662,48 @@ bool Application::makeRenderingContextCurrent() { · 2050 unmodified lines
5642bool Application::isForeground() const { 5662bool Application::isForeground() const {
5643 return _isForeground && !_window->isMinimized(); 5663 return _isForeground && !_window->isMinimized();
5644}5664}
5665
5666void Application::sendMousePressOnEntity(QUuid id, PointerEvent event) {
5667 EntityItemID entityItemID(id);
5668 emit getEntities()->mousePressOnEntity(entityItemID, event);
5669}
5670
5671void Application::sendMouseMoveOnEntity(QUuid id, PointerEvent event) {
5672 EntityItemID entityItemID(id);
5673 emit getEntities()->mouseMoveOnEntity(entityItemID, event);
5674}
5675
5676void Application::sendMouseReleaseOnEntity(QUuid id, PointerEvent event) {
5677 EntityItemID entityItemID(id);
5678 emit getEntities()->mouseReleaseOnEntity(entityItemID, event);
5679}
5680
5681void Application::sendClickDownOnEntity(QUuid id, PointerEvent event) {
5682 EntityItemID entityItemID(id);
5683 emit getEntities()->clickDownOnEntity(entityItemID, event);
5684}
5685
5686void Application::sendHoldingClickOnEntity(QUuid id, PointerEvent event) {
5687 EntityItemID entityItemID(id);
5688 emit getEntities()->holdingClickOnEntity(entityItemID, event);
5689}
5690
5691void Application::sendClickReleaseOnEntity(QUuid id, PointerEvent event) {
5692 EntityItemID entityItemID(id);
5693 emit getEntities()->clickReleaseOnEntity(entityItemID, event);
5694}
5695
5696void Application::sendHoverEnterEntity(QUuid id, PointerEvent event) {
5697 EntityItemID entityItemID(id);
5698 emit getEntities()->hoverEnterEntity(entityItemID, event);
5699}
5700
5701void Application::sendHoverOverEntity(QUuid id, PointerEvent event) {
5702 EntityItemID entityItemID(id);
5703 emit getEntities()->hoverOverEntity(entityItemID, event);
5704}
5705
5706void Application::sendHoverLeaveEntity(QUuid id, PointerEvent event) {
5707 EntityItemID entityItemID(id);
5708 emit getEntities()->hoverLeaveEntity(entityItemID, event);
5709}