diff --git a/interface/resources/qml/hifi/audio/PlaySampleSound.qml b/interface/resources/qml/hifi/audio/PlaySampleSound.qml index fdf579420d..dec2e9bfc9 100644 --- a/interface/resources/qml/hifi/audio/PlaySampleSound.qml +++ b/interface/resources/qml/hifi/audio/PlaySampleSound.qml @@ -22,8 +22,7 @@ RowLayout { property var sample: null; property bool isPlaying: false; function createSampleSound() { - var SOUND = Qt.resolvedUrl("../../../sounds/sample.wav"); - sound = SoundCache.getSound(SOUND); + sound = ApplicationInterface.getSampleSound(); sample = null; } function playSound() { diff --git a/interface/resources/sounds/sample.wav b/interface/resources/sounds/sample.wav index d461ab9186..9c9289bb51 100644 Binary files a/interface/resources/sounds/sample.wav and b/interface/resources/sounds/sample.wav differ diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 87d4db9936..f2bb52ea47 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -692,7 +692,6 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); - DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); @@ -760,7 +759,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _notifiedPacketVersionMismatchThisDomain(false), _maxOctreePPS(maxOctreePacketsPerSecond.get()), _lastFaceTrackerUpdate(0), - _snapshotSound(nullptr) + _snapshotSound(nullptr), + _sampleSound(nullptr) + { auto steamClient = PluginManager::getInstance()->getSteamClientPlugin(); setProperty(hifi::properties::STEAM, (steamClient && steamClient->isRunning())); @@ -805,7 +806,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo installNativeEventFilter(&MyNativeEventFilter::getInstance()); #endif - _logger = new FileLogger(this); qInstallMessageHandler(messageHandler); @@ -982,6 +982,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo connect(myAvatar.get(), &MyAvatar::positionGoneTo, DependencyManager::get().data(), &AddressManager::storeCurrentAddress); + // Inititalize sample before registering + QFileInfo infSample = QFileInfo(PathUtils::resourcesPath() + "sounds/sample.wav"); + _sampleSound = DependencyManager::get()->getSound(QUrl::fromLocalFile(infSample.absoluteFilePath())); + auto scriptEngines = DependencyManager::get().data(); scriptEngines->registerScriptInitializer([this](ScriptEnginePointer engine){ registerScriptEngineWithApplicationServices(engine); @@ -1183,7 +1187,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // allow you to move an entity around in your hand _entityEditSender.setPacketsPerSecond(3000); // super high!! + // Overlays need to exist before we set the ContextOverlayInterface dependency _overlays.init(); // do this before scripts load + DependencyManager::set(); + // Make sure we don't time out during slow operations at startup updateHeartbeat(); @@ -1473,53 +1480,19 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo } }); - // If the user clicks somewhere where there is NO entity at all, we will release focus - connect(getEntities().data(), &EntityTreeRenderer::mousePressOffEntity, [=]() { - setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); - }); - // Keyboard focus handling for Web overlays. auto overlays = &(qApp->getOverlays()); - - connect(overlays, &Overlays::mousePressOnOverlay, [=](const OverlayID& overlayID, const PointerEvent& event) { - auto thisOverlay = std::dynamic_pointer_cast(overlays->getOverlay(overlayID)); - // Only Web overlays can have keyboard focus. - if (thisOverlay) { - setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); - setKeyboardFocusOverlay(overlayID); - } - }); - connect(overlays, &Overlays::overlayDeleted, [=](const OverlayID& overlayID) { if (overlayID == _keyboardFocusedOverlay.get()) { setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); } }); - connect(overlays, &Overlays::mousePressOffOverlay, [=]() { - setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); - }); - connect(this, &Application::aboutToQuit, [=]() { setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); }); - connect(overlays, - SIGNAL(mousePressOnOverlay(const OverlayID&, const PointerEvent&)), - DependencyManager::get().data(), - SLOT(contextOverlays_mousePressOnOverlay(const OverlayID&, const PointerEvent&))); - - connect(overlays, - SIGNAL(hoverEnterOverlay(const OverlayID&, const PointerEvent&)), - DependencyManager::get().data(), - SLOT(contextOverlays_hoverEnterOverlay(const OverlayID&, const PointerEvent&))); - - connect(overlays, - SIGNAL(hoverLeaveOverlay(const OverlayID&, const PointerEvent&)), - DependencyManager::get().data(), - SLOT(contextOverlays_hoverLeaveOverlay(const OverlayID&, const PointerEvent&))); - // Add periodic checks to send user activity data static int CHECK_NEARBY_AVATARS_INTERVAL_MS = 10000; static int NEARBY_AVATAR_RADIUS_METERS = 10; @@ -1788,9 +1761,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo return entityServerNode && !isPhysicsEnabled(); }); - QFileInfo inf = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav"); - _snapshotSound = DependencyManager::get()->getSound(QUrl::fromLocalFile(inf.absoluteFilePath())); - + QFileInfo infSnap = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav"); + _snapshotSound = DependencyManager::get()->getSound(QUrl::fromLocalFile(infSnap.absoluteFilePath())); + QVariant testProperty = property(hifi::properties::TEST); qDebug() << testProperty; if (testProperty.isValid()) { @@ -4203,6 +4176,7 @@ void Application::initDisplay() { } void Application::init() { + // Make sure Login state is up to date DependencyManager::get()->toggleLoginDialog(); @@ -4555,14 +4529,9 @@ QUuid Application::getKeyboardFocusEntity() const { return _keyboardFocusedEntity.get(); } -void Application::setKeyboardFocusEntity(QUuid id) { - EntityItemID entityItemID(id); - setKeyboardFocusEntity(entityItemID); -} - static const float FOCUS_HIGHLIGHT_EXPANSION_FACTOR = 1.05f; -void Application::setKeyboardFocusEntity(EntityItemID entityItemID) { +void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) { if (_keyboardFocusedEntity.get() != entityItemID) { _keyboardFocusedEntity.set(entityItemID); @@ -4599,7 +4568,7 @@ OverlayID Application::getKeyboardFocusOverlay() { return _keyboardFocusedOverlay.get(); } -void Application::setKeyboardFocusOverlay(OverlayID overlayID) { +void Application::setKeyboardFocusOverlay(const OverlayID& overlayID) { if (overlayID != _keyboardFocusedOverlay.get()) { _keyboardFocusedOverlay.set(overlayID); @@ -6811,6 +6780,10 @@ void Application::loadScriptURLDialog() const { }); } +SharedSoundPointer Application::getSampleSound() const { + return _sampleSound; +} + void Application::loadLODToolsDialog() { auto tabletScriptingInterface = DependencyManager::get(); auto tablet = dynamic_cast(tabletScriptingInterface->getTablet(SYSTEM_TABLET)); @@ -7433,51 +7406,6 @@ bool Application::isForeground() const { return _isForeground && !_window->isMinimized(); } -void Application::sendMousePressOnEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->mousePressOnEntity(entityItemID, event); -} - -void Application::sendMouseMoveOnEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->mouseMoveOnEntity(entityItemID, event); -} - -void Application::sendMouseReleaseOnEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->mouseReleaseOnEntity(entityItemID, event); -} - -void Application::sendClickDownOnEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->clickDownOnEntity(entityItemID, event); -} - -void Application::sendHoldingClickOnEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->holdingClickOnEntity(entityItemID, event); -} - -void Application::sendClickReleaseOnEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->clickReleaseOnEntity(entityItemID, event); -} - -void Application::sendHoverEnterEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->hoverEnterEntity(entityItemID, event); -} - -void Application::sendHoverOverEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->hoverOverEntity(entityItemID, event); -} - -void Application::sendHoverLeaveEntity(QUuid id, PointerEvent event) { - EntityItemID entityItemID(id); - emit getEntities()->hoverLeaveEntity(entityItemID, event); -} - // FIXME? perhaps two, one for the main thread and one for the offscreen UI rendering thread? static const int UI_RESERVED_THREADS = 1; // Windows won't let you have all the cores diff --git a/interface/src/Application.h b/interface/src/Application.h index b6c09bbd87..ab7acc8166 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -277,18 +277,6 @@ public: gpu::TexturePointer getDefaultSkyboxTexture() const { return _defaultSkyboxTexture; } gpu::TexturePointer getDefaultSkyboxAmbientTexture() const { return _defaultSkyboxAmbientTexture; } - Q_INVOKABLE void sendMousePressOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendMouseMoveOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendMouseReleaseOnEntity(QUuid id, PointerEvent event); - - Q_INVOKABLE void sendClickDownOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendHoldingClickOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendClickReleaseOnEntity(QUuid id, PointerEvent event); - - Q_INVOKABLE void sendHoverEnterEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendHoverOverEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendHoverLeaveEntity(QUuid id, PointerEvent event); - OverlayID getTabletScreenID() const; OverlayID getTabletHomeButtonID() const; QUuid getTabletFrameID() const; // may be an entity or an overlay @@ -326,6 +314,7 @@ public slots: void toggleEntityScriptServerLogDialog(); Q_INVOKABLE void showAssetServerWidget(QString filePath = ""); Q_INVOKABLE void loadAddAvatarBookmarkDialog() const; + Q_INVOKABLE SharedSoundPointer getSampleSound() const; void showDialog(const QUrl& widgetUrl, const QUrl& tabletUrl, const QString& name) const; @@ -388,11 +377,10 @@ public slots: void setKeyboardFocusHighlight(const glm::vec3& position, const glm::quat& rotation, const glm::vec3& dimensions); QUuid getKeyboardFocusEntity() const; // thread-safe - void setKeyboardFocusEntity(QUuid id); - void setKeyboardFocusEntity(EntityItemID entityItemID); + void setKeyboardFocusEntity(const EntityItemID& entityItemID); OverlayID getKeyboardFocusOverlay(); - void setKeyboardFocusOverlay(OverlayID overlayID); + void setKeyboardFocusOverlay(const OverlayID& overlayID); void addAssetToWorldMessageClose(); @@ -702,6 +690,7 @@ private: FileScriptingInterface* _fileDownload; AudioInjectorPointer _snapshotSoundInjector; SharedSoundPointer _snapshotSound; + SharedSoundPointer _sampleSound; DisplayPluginPointer _autoSwitchDisplayModeSupportedHMDPlugin; QString _autoSwitchDisplayModeSupportedHMDPluginName; diff --git a/interface/src/ui/overlays/Billboardable.cpp b/interface/src/ui/overlays/Billboardable.cpp index 892a9d998d..5e912864fc 100644 --- a/interface/src/ui/overlays/Billboardable.cpp +++ b/interface/src/ui/overlays/Billboardable.cpp @@ -37,7 +37,7 @@ bool Billboardable::pointTransformAtCamera(Transform& transform, glm::quat offse // use the referencial from the avatar, y isn't always up glm::vec3 avatarUP = DependencyManager::get()->getMyAvatar()->getOrientation()*Vectors::UP; - glm::quat rotation(conjugate(toQuat(glm::lookAt(billboardPos, cameraPos, avatarUP)))); + glm::quat rotation(conjugate(toQuat(glm::lookAt(cameraPos, billboardPos, avatarUP)))); transform.setRotation(rotation); transform.postRotate(offsetRotation); diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index e39a4edc11..70b75a0b17 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -43,10 +43,10 @@ ContextOverlayInterface::ContextOverlayInterface() { _entityPropertyFlags += PROP_REGISTRATION_POINT; _entityPropertyFlags += PROP_CERTIFICATE_ID; - auto entityTreeRenderer = DependencyManager::get().data(); - connect(entityTreeRenderer, SIGNAL(mousePressOnEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(createOrDestroyContextOverlay(const EntityItemID&, const PointerEvent&))); - connect(entityTreeRenderer, SIGNAL(hoverEnterEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(contextOverlays_hoverEnterEntity(const EntityItemID&, const PointerEvent&))); - connect(entityTreeRenderer, SIGNAL(hoverLeaveEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(contextOverlays_hoverLeaveEntity(const EntityItemID&, const PointerEvent&))); + auto entityScriptingInterface = DependencyManager::get().data(); + connect(entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity, this, &ContextOverlayInterface::createOrDestroyContextOverlay); + connect(entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity, this, &ContextOverlayInterface::contextOverlays_hoverEnterEntity); + connect(entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity, this, &ContextOverlayInterface::contextOverlays_hoverLeaveEntity); connect(_tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"), &TabletProxy::tabletShownChanged, this, [&]() { if (_contextOverlayJustClicked && _hmdScriptingInterface->isMounted()) { QUuid tabletFrameID = _hmdScriptingInterface->getCurrentTabletFrameID(); @@ -59,9 +59,12 @@ ContextOverlayInterface::ContextOverlayInterface() { _contextOverlayJustClicked = false; } }); - auto entityScriptingInterface = DependencyManager::get().data(); connect(entityScriptingInterface, &EntityScriptingInterface::deletingEntity, this, &ContextOverlayInterface::deletingEntity); + connect(&qApp->getOverlays(), &Overlays::mousePressOnOverlay, this, &ContextOverlayInterface::contextOverlays_mousePressOnOverlay); + connect(&qApp->getOverlays(), &Overlays::hoverEnterOverlay, this, &ContextOverlayInterface::contextOverlays_hoverEnterOverlay); + connect(&qApp->getOverlays(), &Overlays::hoverLeaveOverlay, this, &ContextOverlayInterface::contextOverlays_hoverLeaveOverlay); + connect(_selectionScriptingInterface.data(), &SelectionScriptingInterface::selectedItemsListChanged, &_selectionToSceneHandler, &SelectionToSceneHandler::selectedItemsListChanged); } diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 5e5b9367a6..fd5aae4027 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -717,39 +717,34 @@ bool Overlays::isAddedOverlay(OverlayID id) { } void Overlays::sendMousePressOnOverlay(const OverlayID& overlayID, const PointerEvent& event) { - QMetaObject::invokeMethod(this, "mousePressOnOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); + mousePressEvent(overlayID, event); } void Overlays::sendMouseReleaseOnOverlay(const OverlayID& overlayID, const PointerEvent& event) { - QMetaObject::invokeMethod(this, "mouseReleaseOnOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); + mouseReleaseEvent(overlayID, event); } void Overlays::sendMouseMoveOnOverlay(const OverlayID& overlayID, const PointerEvent& event) { - QMetaObject::invokeMethod(this, "mouseMoveOnOverlay", Q_ARG(OverlayID, overlayID), Q_ARG(PointerEvent, event)); + mouseMoveEvent(overlayID, event); } -void Overlays::sendHoverEnterOverlay(const OverlayID& id, const PointerEvent& event) { - QMetaObject::invokeMethod(this, "hoverEnterOverlay", Q_ARG(OverlayID, id), Q_ARG(PointerEvent, event)); +void Overlays::sendHoverEnterOverlay(const OverlayID& overlayID, const PointerEvent& event) { + emit hoverEnterOverlay(overlayID, event); } -void Overlays::sendHoverOverOverlay(const OverlayID& id, const PointerEvent& event) { - QMetaObject::invokeMethod(this, "hoverOverOverlay", Q_ARG(OverlayID, id), Q_ARG(PointerEvent, event)); +void Overlays::sendHoverOverOverlay(const OverlayID& overlayID, const PointerEvent& event) { + emit hoverOverOverlay(overlayID, event); } -void Overlays::sendHoverLeaveOverlay(const OverlayID& id, const PointerEvent& event) { - QMetaObject::invokeMethod(this, "hoverLeaveOverlay", Q_ARG(OverlayID, id), Q_ARG(PointerEvent, event)); +void Overlays::sendHoverLeaveOverlay(const OverlayID& overlayID, const PointerEvent& event) { + hoverLeaveEvent(overlayID, event); } OverlayID Overlays::getKeyboardFocusOverlay() { return qApp->getKeyboardFocusOverlay(); } -void Overlays::setKeyboardFocusOverlay(OverlayID id) { - if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "setKeyboardFocusOverlay", Q_ARG(OverlayID, id)); - return; - } - +void Overlays::setKeyboardFocusOverlay(const OverlayID& id) { qApp->setKeyboardFocusOverlay(id); } @@ -884,13 +879,35 @@ bool Overlays::mousePressEvent(QMouseEvent* event) { _currentClickingOnOverlayID = rayPickResult.overlayID; PointerEvent pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press); - emit mousePressOnOverlay(_currentClickingOnOverlayID, pointerEvent); + mousePressEvent(_currentClickingOnOverlayID, pointerEvent); return true; } + // if we didn't press on an overlay, disable overlay keyboard focus + setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); + // emit to scripts emit mousePressOffOverlay(); return false; } +void Overlays::mousePressEvent(const OverlayID& overlayID, const PointerEvent& event) { + // TODO: generalize this to allow any overlay to recieve events + std::shared_ptr thisOverlay; + if (getOverlayType(overlayID) == "web3d") { + thisOverlay = std::static_pointer_cast(getOverlay(overlayID)); + } + if (thisOverlay) { + // Focus keyboard on web overlays + DependencyManager::get()->setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); + setKeyboardFocusOverlay(overlayID); + + // Send to web overlay + QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); + } + + // emit to scripts + emit mousePressOnOverlay(overlayID, event); +} + bool Overlays::mouseDoublePressEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent"); @@ -900,13 +917,30 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) { _currentClickingOnOverlayID = rayPickResult.overlayID; auto pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press); + // emit to scripts emit mouseDoublePressOnOverlay(_currentClickingOnOverlayID, pointerEvent); return true; } + // emit to scripts emit mouseDoublePressOffOverlay(); return false; } +void Overlays::hoverLeaveEvent(const OverlayID& overlayID, const PointerEvent& event) { + // TODO: generalize this to allow any overlay to recieve events + std::shared_ptr thisOverlay; + if (getOverlayType(overlayID) == "web3d") { + thisOverlay = std::static_pointer_cast(getOverlay(overlayID)); + } + if (thisOverlay) { + // Send to web overlay + QMetaObject::invokeMethod(thisOverlay.get(), "hoverLeaveOverlay", Q_ARG(PointerEvent, event)); + } + + // emit to scripts + emit hoverLeaveOverlay(overlayID, event); +} + bool Overlays::mouseReleaseEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mouseReleaseEvent"); @@ -914,13 +948,28 @@ bool Overlays::mouseReleaseEvent(QMouseEvent* event) { RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray); if (rayPickResult.intersects) { auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release); - emit mouseReleaseOnOverlay(rayPickResult.overlayID, pointerEvent); + mouseReleaseEvent(rayPickResult.overlayID, pointerEvent); } _currentClickingOnOverlayID = UNKNOWN_OVERLAY_ID; return false; } +void Overlays::mouseReleaseEvent(const OverlayID& overlayID, const PointerEvent& event) { + // TODO: generalize this to allow any overlay to recieve events + std::shared_ptr thisOverlay; + if (getOverlayType(overlayID) == "web3d") { + thisOverlay = std::static_pointer_cast(getOverlay(overlayID)); + } + if (thisOverlay) { + // Send to web overlay + QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); + } + + // emit to scripts + emit mouseReleaseOnOverlay(overlayID, event); +} + bool Overlays::mouseMoveEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mouseMoveEvent"); @@ -928,12 +977,12 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) { RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray); if (rayPickResult.intersects) { auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move); - emit mouseMoveOnOverlay(rayPickResult.overlayID, pointerEvent); + mouseMoveEvent(rayPickResult.overlayID, pointerEvent); // If previously hovering over a different overlay then leave hover on that overlay. if (_currentHoverOverOverlayID != UNKNOWN_OVERLAY_ID && rayPickResult.overlayID != _currentHoverOverOverlayID) { auto pointerEvent = calculateOverlayPointerEvent(_currentHoverOverOverlayID, ray, rayPickResult, event, PointerEvent::Move); - emit hoverLeaveOverlay(_currentHoverOverOverlayID, pointerEvent); + hoverLeaveEvent(_currentHoverOverOverlayID, pointerEvent); } // If hovering over a new overlay then enter hover on that overlay. @@ -949,7 +998,7 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) { // If previously hovering an overlay then leave hover. if (_currentHoverOverOverlayID != UNKNOWN_OVERLAY_ID) { auto pointerEvent = calculateOverlayPointerEvent(_currentHoverOverOverlayID, ray, rayPickResult, event, PointerEvent::Move); - emit hoverLeaveOverlay(_currentHoverOverOverlayID, pointerEvent); + hoverLeaveEvent(_currentHoverOverOverlayID, pointerEvent); _currentHoverOverOverlayID = UNKNOWN_OVERLAY_ID; } @@ -957,6 +1006,21 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) { return false; } +void Overlays::mouseMoveEvent(const OverlayID& overlayID, const PointerEvent& event) { + // TODO: generalize this to allow any overlay to recieve events + std::shared_ptr thisOverlay; + if (getOverlayType(overlayID) == "web3d") { + thisOverlay = std::static_pointer_cast(getOverlay(overlayID)); + } + if (thisOverlay) { + // Send to web overlay + QMetaObject::invokeMethod(thisOverlay.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); + } + + // emit to scripts + emit mouseMoveOnOverlay(overlayID, event); +} + QVector Overlays::findOverlays(const glm::vec3& center, float radius) { QVector result; //if (QThread::currentThread() != thread()) { diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 732a437eae..988b288741 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -107,6 +107,11 @@ public: bool mouseReleaseEvent(QMouseEvent* event); bool mouseMoveEvent(QMouseEvent* event); + void mousePressEvent(const OverlayID& overlayID, const PointerEvent& event); + void mouseMoveEvent(const OverlayID& overlayID, const PointerEvent& event); + void mouseReleaseEvent(const OverlayID& overlayID, const PointerEvent& event); + void hoverLeaveEvent(const OverlayID& overlayID, const PointerEvent& event); + void cleanupAllOverlays(); public slots: @@ -298,12 +303,12 @@ public slots: void sendMouseReleaseOnOverlay(const OverlayID& overlayID, const PointerEvent& event); void sendMouseMoveOnOverlay(const OverlayID& overlayID, const PointerEvent& event); - void sendHoverEnterOverlay(const OverlayID& id, const PointerEvent& event); - void sendHoverOverOverlay(const OverlayID& id, const PointerEvent& event); - void sendHoverLeaveOverlay(const OverlayID& id, const PointerEvent& event); + void sendHoverEnterOverlay(const OverlayID& overlayID, const PointerEvent& event); + void sendHoverOverOverlay(const OverlayID& overlayID, const PointerEvent& event); + void sendHoverLeaveOverlay(const OverlayID& overlayID, const PointerEvent& event); OverlayID getKeyboardFocusOverlay(); - void setKeyboardFocusOverlay(OverlayID id); + void setKeyboardFocusOverlay(const OverlayID& id); signals: /**jsdoc diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 363c85b395..0c75803d35 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -125,11 +125,7 @@ void Web3DOverlay::destroyWebSurface() { } _webSurface->pause(); - auto overlays = &(qApp->getOverlays()); - QObject::disconnect(overlays, &Overlays::mousePressOnOverlay, this, nullptr); - QObject::disconnect(overlays, &Overlays::mouseReleaseOnOverlay, this, nullptr); - QObject::disconnect(overlays, &Overlays::mouseMoveOnOverlay, this, nullptr); - QObject::disconnect(overlays, &Overlays::hoverLeaveOverlay, this, nullptr); + QObject::disconnect(this, &Web3DOverlay::scriptEventReceived, _webSurface.data(), &OffscreenQmlSurface::emitScriptEvent); QObject::disconnect(_webSurface.data(), &OffscreenQmlSurface::webEventReceived, this, &Web3DOverlay::webEventReceived); DependencyManager::get()->release(QML, _webSurface); @@ -160,35 +156,17 @@ void Web3DOverlay::buildWebSurface() { _webSurface->resume(); }); - auto selfOverlayID = getOverlayID(); - std::weak_ptr weakSelf = std::dynamic_pointer_cast(qApp->getOverlays().getOverlay(selfOverlayID)); - auto forwardPointerEvent = [=](OverlayID overlayID, const PointerEvent& event) { - auto self = weakSelf.lock(); - if (self && overlayID == selfOverlayID) { - self->handlePointerEvent(event); - } - }; - - auto overlays = &(qApp->getOverlays()); - QObject::connect(overlays, &Overlays::mousePressOnOverlay, this, forwardPointerEvent); - QObject::connect(overlays, &Overlays::mouseReleaseOnOverlay, this, forwardPointerEvent); - QObject::connect(overlays, &Overlays::mouseMoveOnOverlay, this, forwardPointerEvent); - QObject::connect(overlays, &Overlays::hoverLeaveOverlay, this, [=](OverlayID overlayID, const PointerEvent& event) { - auto self = weakSelf.lock(); - if (!self) { - return; - } - if (overlayID == selfOverlayID && (self->_pressed || (!self->_activeTouchPoints.empty() && self->_touchBeginAccepted))) { - PointerEvent endEvent(PointerEvent::Release, event.getID(), event.getPos2D(), event.getPos3D(), event.getNormal(), event.getDirection(), - event.getButton(), event.getButtons(), event.getKeyboardModifiers()); - forwardPointerEvent(overlayID, endEvent); - } - }); - QObject::connect(this, &Web3DOverlay::scriptEventReceived, _webSurface.data(), &OffscreenQmlSurface::emitScriptEvent); QObject::connect(_webSurface.data(), &OffscreenQmlSurface::webEventReceived, this, &Web3DOverlay::webEventReceived); } +void Web3DOverlay::hoverLeaveOverlay(const PointerEvent& event) { + if ((_pressed || (!_activeTouchPoints.empty() && _touchBeginAccepted))) { + PointerEvent endEvent(PointerEvent::Release, event.getID(), event.getPos2D(), event.getPos3D(), event.getNormal(), event.getDirection(), + event.getButton(), event.getButtons(), event.getKeyboardModifiers()); + handlePointerEvent(endEvent); + } +} void Web3DOverlay::update(float deltatime) { if (_webSurface) { diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index de74b95b3e..c7f338f0e6 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -39,7 +39,8 @@ public: QObject* getEventHandler(); void setProxyWindow(QWindow* proxyWindow); - void handlePointerEvent(const PointerEvent& event); + Q_INVOKABLE void hoverLeaveOverlay(const PointerEvent& event); + Q_INVOKABLE void handlePointerEvent(const PointerEvent& event); void handlePointerEventAsTouch(const PointerEvent& event); void handlePointerEventAsMouse(const PointerEvent& event); diff --git a/libraries/audio/src/SoundCache.h b/libraries/audio/src/SoundCache.h index 97d5f659d8..bc4ddf303f 100644 --- a/libraries/audio/src/SoundCache.h +++ b/libraries/audio/src/SoundCache.h @@ -23,7 +23,6 @@ class SoundCache : public ResourceCache, public Dependency { public: Q_INVOKABLE SharedSoundPointer getSound(const QUrl& url); - protected: virtual QSharedPointer createResource(const QUrl& url, const QSharedPointer& fallback, const void* extra) override; diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 4238eb4050..bf17f34749 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -35,6 +35,8 @@ #include "EntitiesRendererLogging.h" #include "RenderableEntityItem.h" +#include "RenderableWebEntityItem.h" + size_t std::hash::operator()(const EntityItemID& id) const { return qHash(id); } std::function EntityTreeRenderer::_entitiesShouldFadeFunction; @@ -55,6 +57,32 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf EntityRenderer::initEntityRenderers(); _currentHoverOverEntityID = UNKNOWN_ENTITY_ID; _currentClickingOnEntityID = UNKNOWN_ENTITY_ID; + + // Forward mouse events to web entities + auto handlePointerEvent = [&](const EntityItemID& entityID, const PointerEvent& event) { + std::shared_ptr thisEntity; + auto entity = getEntity(entityID); + if (entity && entity->getType() == EntityTypes::Web) { + thisEntity = std::static_pointer_cast(renderableForEntityId(entityID)); + } + if (thisEntity) { + QMetaObject::invokeMethod(thisEntity.get(), "handlePointerEvent", Q_ARG(PointerEvent, event)); + } + }; + auto entityScriptingInterface = DependencyManager::get(); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, this, handlePointerEvent); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, handlePointerEvent); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, handlePointerEvent); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, this, [&](const EntityItemID& entityID, const PointerEvent& event) { + std::shared_ptr thisEntity; + auto entity = getEntity(entityID); + if (entity && entity->getType() == EntityTypes::Web) { + thisEntity = std::static_pointer_cast(renderableForEntityId(entityID)); + } + if (thisEntity) { + QMetaObject::invokeMethod(thisEntity.get(), "hoverLeaveEntity", Q_ARG(PointerEvent, event)); + } + }); } EntityTreeRenderer::~EntityTreeRenderer() { @@ -78,13 +106,49 @@ render::ItemID EntityTreeRenderer::renderableIdForEntityId(const EntityItemID& i int EntityTreeRenderer::_entitiesScriptEngineCount = 0; void EntityTreeRenderer::resetEntitiesScriptEngine() { - auto oldEngine = _entitiesScriptEngine; _entitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); _scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine); _entitiesScriptEngine->runInThread(); auto entitiesScriptEngineProvider = qSharedPointerCast(_entitiesScriptEngine); - DependencyManager::get()->setEntitiesScriptEngine(entitiesScriptEngineProvider); + auto entityScriptingInterface = DependencyManager::get(); + entityScriptingInterface->setEntitiesScriptEngine(entitiesScriptEngineProvider); + + // Connect mouse events to entity script callbacks + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mousePressOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseDoublePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseDoublePressOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveOnEntity", event); + // FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveEvent", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseReleaseOnEntity", event); + }); + + connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "clickDownOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::holdingClickOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "holdingClickOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "clickReleaseOnEntity", event); + }); + + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverEnterEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverOverEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event); + }); } void EntityTreeRenderer::clear() { @@ -264,8 +328,7 @@ void EntityTreeRenderer::update(bool simulate) { // not yet released the hold then this is still considered a holdingClickOnEntity event // and we want to simulate this message here as well as in mouse move if (_lastPointerEventValid && !_currentClickingOnEntityID.isInvalidID()) { - emit holdingClickOnEntity(_currentClickingOnEntityID, _lastPointerEvent); - _entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "holdingClickOnEntity", _lastPointerEvent); + emit DependencyManager::get()->holdingClickOnEntity(_currentClickingOnEntityID, _lastPointerEvent); } } @@ -435,19 +498,6 @@ void EntityTreeRenderer::processEraseMessage(ReceivedMessage& message, const Sha } void EntityTreeRenderer::connectSignalsToSlots(EntityScriptingInterface* entityScriptingInterface) { - - connect(this, &EntityTreeRenderer::mousePressOnEntity, entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity); - connect(this, &EntityTreeRenderer::mouseMoveOnEntity, entityScriptingInterface, &EntityScriptingInterface::mouseMoveOnEntity); - connect(this, &EntityTreeRenderer::mouseReleaseOnEntity, entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity); - - connect(this, &EntityTreeRenderer::clickDownOnEntity, entityScriptingInterface, &EntityScriptingInterface::clickDownOnEntity); - connect(this, &EntityTreeRenderer::holdingClickOnEntity, entityScriptingInterface, &EntityScriptingInterface::holdingClickOnEntity); - connect(this, &EntityTreeRenderer::clickReleaseOnEntity, entityScriptingInterface, &EntityScriptingInterface::clickReleaseOnEntity); - - connect(this, &EntityTreeRenderer::hoverEnterEntity, entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity); - connect(this, &EntityTreeRenderer::hoverOverEntity, entityScriptingInterface, &EntityScriptingInterface::hoverOverEntity); - connect(this, &EntityTreeRenderer::hoverLeaveEntity, entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity); - connect(this, &EntityTreeRenderer::enterEntity, entityScriptingInterface, &EntityScriptingInterface::enterEntity); connect(this, &EntityTreeRenderer::leaveEntity, entityScriptingInterface, &EntityScriptingInterface::leaveEntity); connect(this, &EntityTreeRenderer::collisionWithEntity, entityScriptingInterface, &EntityScriptingInterface::collisionWithEntity); @@ -516,13 +566,11 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) { } PerformanceTimer perfTimer("EntityTreeRenderer::mousePressEvent"); + auto entityScriptingInterface = DependencyManager::get(); PickRay ray = _viewState->computePickRay(event->x(), event->y()); RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); - if (rayPickResult.intersects) { - //qCDebug(entitiesrenderer) << "mousePressEvent over entity:" << rayPickResult.entityID; - - auto entity = getTree()->findEntityByEntityItemID(rayPickResult.entityID); - auto properties = entity->getProperties(); + if (rayPickResult.intersects && rayPickResult.entity) { + auto properties = rayPickResult.entity->getProperties(); QString urlString = properties.getHref(); QUrl url = QUrl(urlString, QUrl::StrictMode); if (url.isValid() && !url.isEmpty()){ @@ -536,23 +584,16 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) { toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); // TODO -- check for modifier keys? - emit mousePressOnEntity(rayPickResult.entityID, pointerEvent); - - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mousePressOnEntity", pointerEvent); - } + emit entityScriptingInterface->mousePressOnEntity(rayPickResult.entityID, pointerEvent); _currentClickingOnEntityID = rayPickResult.entityID; - emit clickDownOnEntity(_currentClickingOnEntityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "clickDownOnEntity", pointerEvent); - } + emit entityScriptingInterface->clickDownOnEntity(_currentClickingOnEntityID, pointerEvent); _lastPointerEvent = pointerEvent; _lastPointerEventValid = true; } else { - emit mousePressOffEntity(); + emit entityScriptingInterface->mousePressOffEntity(); } } @@ -564,34 +605,25 @@ void EntityTreeRenderer::mouseDoublePressEvent(QMouseEvent* event) { } PerformanceTimer perfTimer("EntityTreeRenderer::mouseDoublePressEvent"); + auto entityScriptingInterface = DependencyManager::get(); PickRay ray = _viewState->computePickRay(event->x(), event->y()); RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); - if (rayPickResult.intersects) { - //qCDebug(entitiesrenderer) << "mouseDoublePressEvent over entity:" << rayPickResult.entityID; - + if (rayPickResult.intersects && rayPickResult.entity) { glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult); PointerEvent pointerEvent(PointerEvent::Press, MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, rayPickResult.surfaceNormal, ray.direction, toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); - emit mouseDoublePressOnEntity(rayPickResult.entityID, pointerEvent); - - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseDoublePressOnEntity", pointerEvent); - } + emit entityScriptingInterface->mouseDoublePressOnEntity(rayPickResult.entityID, pointerEvent); _currentClickingOnEntityID = rayPickResult.entityID; - emit clickDownOnEntity(_currentClickingOnEntityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "doubleclickOnEntity", pointerEvent); - } + emit entityScriptingInterface->clickDownOnEntity(_currentClickingOnEntityID, pointerEvent); _lastPointerEvent = pointerEvent; _lastPointerEventValid = true; - } else { - emit mouseDoublePressOffEntity(); + emit entityScriptingInterface->mouseDoublePressOffEntity(); } } @@ -603,9 +635,10 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) { } PerformanceTimer perfTimer("EntityTreeRenderer::mouseReleaseEvent"); + auto entityScriptingInterface = DependencyManager::get(); PickRay ray = _viewState->computePickRay(event->x(), event->y()); RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); - if (rayPickResult.intersects) { + if (rayPickResult.intersects && rayPickResult.entity) { //qCDebug(entitiesrenderer) << "mouseReleaseEvent over entity:" << rayPickResult.entityID; glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult); @@ -615,31 +648,23 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) { toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); // TODO -- check for modifier keys? - emit mouseReleaseOnEntity(rayPickResult.entityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseReleaseOnEntity", pointerEvent); - } + emit entityScriptingInterface->mouseReleaseOnEntity(rayPickResult.entityID, pointerEvent); _lastPointerEvent = pointerEvent; _lastPointerEventValid = true; } // 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 + // we're releasing the button, then this is considered a clickReleaseOn event if (!_currentClickingOnEntityID.isInvalidID()) { - - auto entity = getTree()->findEntityByID(_currentClickingOnEntityID); - glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult); + glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult); PointerEvent pointerEvent(PointerEvent::Release, MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, rayPickResult.surfaceNormal, ray.direction, toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); // TODO -- check for modifier keys? - emit clickReleaseOnEntity(_currentClickingOnEntityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "clickReleaseOnEntity", pointerEvent); - } + emit entityScriptingInterface->clickReleaseOnEntity(_currentClickingOnEntityID, pointerEvent); } // makes it the unknown ID, we just released so we can't be clicking on anything @@ -654,9 +679,10 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) { } PerformanceTimer perfTimer("EntityTreeRenderer::mouseMoveEvent"); + auto entityScriptingInterface = DependencyManager::get(); PickRay ray = _viewState->computePickRay(event->x(), event->y()); RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); - if (rayPickResult.intersects) { + if (rayPickResult.intersects && rayPickResult.entity) { glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult); PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, @@ -664,48 +690,32 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) { toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); // TODO -- check for modifier keys? - emit mouseMoveOnEntity(rayPickResult.entityID, pointerEvent); - - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveEvent", pointerEvent); - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "mouseMoveOnEntity", pointerEvent); - } + emit entityScriptingInterface->mouseMoveOnEntity(rayPickResult.entityID, pointerEvent); // 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) { - - auto entity = getTree()->findEntityByID(_currentHoverOverEntityID); - glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult); + glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult); PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, rayPickResult.surfaceNormal, ray.direction, toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); // TODO -- check for modifier keys? - emit hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", pointerEvent); - } + emit entityScriptingInterface->hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent); } // 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) { - emit hoverEnterEntity(rayPickResult.entityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverEnterEntity", pointerEvent); - } + emit entityScriptingInterface->hoverEnterEntity(rayPickResult.entityID, pointerEvent); } // 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, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(rayPickResult.entityID, "hoverOverEntity", pointerEvent); - } + emit entityScriptingInterface->hoverOverEntity(rayPickResult.entityID, pointerEvent); // remember what we're hovering over _currentHoverOverEntityID = rayPickResult.entityID; @@ -718,38 +728,18 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) { // 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()) { - - auto entity = getTree()->findEntityByID(_currentHoverOverEntityID); - glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult); + glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult); PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, rayPickResult.surfaceNormal, ray.direction, toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier); // TODO -- check for modifier keys? - emit hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(_currentHoverOverEntityID, "hoverLeaveEntity", pointerEvent); - } + emit entityScriptingInterface->hoverLeaveEntity(_currentHoverOverEntityID, pointerEvent); _currentHoverOverEntityID = UNKNOWN_ENTITY_ID; // makes it the unknown ID - } - } - // 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()) { - - auto entity = getTree()->findEntityByID(_currentClickingOnEntityID); - glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult); - PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID, - pos2D, rayPickResult.intersection, - rayPickResult.surfaceNormal, ray.direction, - toPointerButton(*event), toPointerButtons(*event), - Qt::NoModifier); // TODO -- check for modifier keys? - - emit holdingClickOnEntity(_currentClickingOnEntityID, pointerEvent); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "holdingClickOnEntity", pointerEvent); + _lastPointerEvent = pointerEvent; + _lastPointerEventValid = true; } } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 1b1d46d50c..1eb44f996a 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -117,21 +117,6 @@ public: void onEntityChanged(const EntityItemID& id); signals: - void mousePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void mouseDoublePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void mouseMoveOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void mouseReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void mousePressOffEntity(); - void mouseDoublePressOffEntity(); - - void clickDownOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void holdingClickOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void clickReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); - - void hoverEnterEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void hoverOverEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void hoverLeaveEntity(const EntityItemID& entityItemID, const PointerEvent& event); - void enterEntity(const EntityItemID& entityItemID); void leaveEntity(const EntityItemID& entityItemID); void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 4699f2cd8f..a2e574a829 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -24,7 +24,6 @@ #include #include -#include "EntityTreeRenderer.h" #include "EntitiesRendererLogging.h" @@ -86,6 +85,10 @@ bool WebEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointe return true; } + if (_lastLocked != entity->getLocked()) { + return true; + } + return false; } @@ -136,6 +139,7 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene } _lastDPI = entity->getDPI(); + _lastLocked = entity->getLocked(); glm::vec2 windowSize = getWindowSize(entity); _webSurface->resize(QSize(windowSize.x, windowSize.y)); @@ -234,38 +238,6 @@ bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) { emit entities->webEventReceived(entityItemID, message); }); - auto forwardPointerEvent = [=](const EntityItemID& entityItemID, const PointerEvent& event) { - if (entityItemID == entity->getID()) { - handlePointerEvent(entity, event); - } - }; - - auto renderer = DependencyManager::get(); - QObject::connect(renderer.data(), &EntityTreeRenderer::mousePressOnEntity, this, forwardPointerEvent); - QObject::connect(renderer.data(), &EntityTreeRenderer::mouseReleaseOnEntity, this, forwardPointerEvent); - QObject::connect(renderer.data(), &EntityTreeRenderer::mouseMoveOnEntity, this, forwardPointerEvent); - QObject::connect(renderer.data(), &EntityTreeRenderer::hoverLeaveEntity, this, - [=](const EntityItemID& entityItemID, const PointerEvent& event) { - if (this->_pressed && entity->getID() == entityItemID) { - // If the user mouses off the entity while the button is down, simulate a touch end. - QTouchEvent::TouchPoint point; - point.setId(event.getID()); - point.setState(Qt::TouchPointReleased); - glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * _lastDPI); - QPointF windowPoint(windowPos.x, windowPos.y); - point.setScenePos(windowPoint); - point.setPos(windowPoint); - QList touchPoints; - touchPoints.push_back(point); - QTouchEvent* touchEvent = new QTouchEvent(QEvent::TouchEnd, nullptr, - Qt::NoModifier, Qt::TouchPointReleased, touchPoints); - touchEvent->setWindow(_webSurface->getWindow()); - touchEvent->setDevice(&_touchDevice); - touchEvent->setTarget(_webSurface->getRootItem()); - QCoreApplication::postEvent(_webSurface->getWindow(), touchEvent); - } - }); - return true; } @@ -295,13 +267,6 @@ void WebEntityRenderer::destroyWebSurface() { } webSurface->pause(); - auto renderer = DependencyManager::get(); - if (renderer) { - QObject::disconnect(renderer.data(), &EntityTreeRenderer::mousePressOnEntity, this, nullptr); - QObject::disconnect(renderer.data(), &EntityTreeRenderer::mouseReleaseOnEntity, this, nullptr); - QObject::disconnect(renderer.data(), &EntityTreeRenderer::mouseMoveOnEntity, this, nullptr); - QObject::disconnect(renderer.data(), &EntityTreeRenderer::hoverLeaveEntity, this, nullptr); - } webSurface.reset(); } } @@ -347,13 +312,34 @@ void WebEntityRenderer::loadSourceURL() { } } -void WebEntityRenderer::handlePointerEvent(const TypedEntityPointer& entity, const PointerEvent& event) { +void WebEntityRenderer::hoverLeaveEntity(const PointerEvent& event) { + if (!_lastLocked && _webSurface && _pressed) { + // If the user mouses off the entity while the button is down, simulate a touch end. + QTouchEvent::TouchPoint point; + point.setId(event.getID()); + point.setState(Qt::TouchPointReleased); + glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * _lastDPI); + QPointF windowPoint(windowPos.x, windowPos.y); + point.setScenePos(windowPoint); + point.setPos(windowPoint); + QList touchPoints; + touchPoints.push_back(point); + QTouchEvent* touchEvent = new QTouchEvent(QEvent::TouchEnd, nullptr, + Qt::NoModifier, Qt::TouchPointReleased, touchPoints); + touchEvent->setWindow(_webSurface->getWindow()); + touchEvent->setDevice(&_touchDevice); + touchEvent->setTarget(_webSurface->getRootItem()); + QCoreApplication::postEvent(_webSurface->getWindow(), touchEvent); + } +} + +void WebEntityRenderer::handlePointerEvent(const PointerEvent& event) { // Ignore mouse interaction if we're locked - if (entity->getLocked() || !_webSurface) { + if (_lastLocked || !_webSurface) { return; } - glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * entity->getDPI()); + glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * _lastDPI); QPointF windowPoint(windowPos.x, windowPos.y); if (event.getType() == PointerEvent::Move) { // Forward a mouse move event to webSurface diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.h b/libraries/entities-renderer/src/RenderableWebEntityItem.h index 9c79001dc5..2d162e57fe 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.h +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.h @@ -18,12 +18,16 @@ class PointerEvent; namespace render { namespace entities { class WebEntityRenderer : public TypedEntityRenderer { + Q_OBJECT using Parent = TypedEntityRenderer; friend class EntityRenderer; public: WebEntityRenderer(const EntityItemPointer& entity); + Q_INVOKABLE void hoverLeaveEntity(const PointerEvent& event); + Q_INVOKABLE void handlePointerEvent(const PointerEvent& event); + protected: virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override; virtual bool needsRenderUpdate() const override; @@ -44,9 +48,6 @@ private: bool hasWebSurface(); void loadSourceURL(); glm::vec2 getWindowSize(const TypedEntityPointer& entity) const; - void handlePointerEvent(const TypedEntityPointer& entity, const PointerEvent& event); - -private: int _geometryId{ 0 }; enum contentType { @@ -60,6 +61,7 @@ private: bool _pressed{ false }; QString _lastSourceUrl; uint16_t _lastDPI; + bool _lastLocked; QTimer _timer; uint64_t _lastRenderTime { 0 }; Transform _renderTransform; diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index b1a97010c0..ed7a1469b3 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -51,6 +51,10 @@ EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership connect(nodeList.data(), &NodeList::canRezTmpCertifiedChanged, this, &EntityScriptingInterface::canRezTmpCertifiedChanged); connect(nodeList.data(), &NodeList::canWriteAssetsChanged, this, &EntityScriptingInterface::canWriteAssetsChanged); + // If the user clicks somewhere where there is no entity at all, we will release focus + connect(this, &EntityScriptingInterface::mousePressOffEntity, [=]() { + setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); + }); auto& packetReceiver = nodeList->getPacketReceiver(); packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket"); @@ -1674,44 +1678,44 @@ QUuid EntityScriptingInterface::getKeyboardFocusEntity() const { return result; } -void EntityScriptingInterface::setKeyboardFocusEntity(QUuid id) { - QMetaObject::invokeMethod(qApp, "setKeyboardFocusEntity", Qt::QueuedConnection, Q_ARG(QUuid, id)); +void EntityScriptingInterface::setKeyboardFocusEntity(const EntityItemID& id) { + QMetaObject::invokeMethod(qApp, "setKeyboardFocusEntity", Qt::DirectConnection, Q_ARG(EntityItemID, id)); } -void EntityScriptingInterface::sendMousePressOnEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendMousePressOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendMousePressOnEntity(const EntityItemID& id, const PointerEvent& event) { + emit mousePressOnEntity(id, event); } -void EntityScriptingInterface::sendMouseMoveOnEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendMouseMoveOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendMouseMoveOnEntity(const EntityItemID& id, const PointerEvent& event) { + emit mouseMoveOnEntity(id, event); } -void EntityScriptingInterface::sendMouseReleaseOnEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendMouseReleaseOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendMouseReleaseOnEntity(const EntityItemID& id, const PointerEvent& event) { + emit mouseReleaseOnEntity(id, event); } -void EntityScriptingInterface::sendClickDownOnEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendClickDownOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendClickDownOnEntity(const EntityItemID& id, const PointerEvent& event) { + emit clickDownOnEntity(id, event); } -void EntityScriptingInterface::sendHoldingClickOnEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendHoldingClickOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendHoldingClickOnEntity(const EntityItemID& id, const PointerEvent& event) { + emit holdingClickOnEntity(id, event); } -void EntityScriptingInterface::sendClickReleaseOnEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendClickReleaseOnEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendClickReleaseOnEntity(const EntityItemID& id, const PointerEvent& event) { + emit clickReleaseOnEntity(id, event); } -void EntityScriptingInterface::sendHoverEnterEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendHoverEnterEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendHoverEnterEntity(const EntityItemID& id, const PointerEvent& event) { + emit hoverEnterEntity(id, event); } -void EntityScriptingInterface::sendHoverOverEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendHoverOverEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendHoverOverEntity(const EntityItemID& id, const PointerEvent& event) { + emit hoverOverEntity(id, event); } -void EntityScriptingInterface::sendHoverLeaveEntity(QUuid id, PointerEvent event) { - QMetaObject::invokeMethod(qApp, "sendHoverLeaveEntity", Qt::QueuedConnection, Q_ARG(QUuid, id), Q_ARG(PointerEvent, event)); +void EntityScriptingInterface::sendHoverLeaveEntity(const EntityItemID& id, const PointerEvent& event) { + emit hoverLeaveEntity(id, event); } bool EntityScriptingInterface::wantsHandControllerPointerEvents(QUuid id) { diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index a6d754cf9e..141289884b 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -380,19 +380,19 @@ public slots: Q_INVOKABLE QString getNestableType(QUuid id); Q_INVOKABLE QUuid getKeyboardFocusEntity() const; - Q_INVOKABLE void setKeyboardFocusEntity(QUuid id); + Q_INVOKABLE void setKeyboardFocusEntity(const EntityItemID& id); - Q_INVOKABLE void sendMousePressOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendMouseMoveOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendMouseReleaseOnEntity(QUuid id, PointerEvent event); + Q_INVOKABLE void sendMousePressOnEntity(const EntityItemID& id, const PointerEvent& event); + Q_INVOKABLE void sendMouseMoveOnEntity(const EntityItemID& id, const PointerEvent& event); + Q_INVOKABLE void sendMouseReleaseOnEntity(const EntityItemID& id, const PointerEvent& event); - Q_INVOKABLE void sendClickDownOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendHoldingClickOnEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendClickReleaseOnEntity(QUuid id, PointerEvent event); + Q_INVOKABLE void sendClickDownOnEntity(const EntityItemID& id, const PointerEvent& event); + Q_INVOKABLE void sendHoldingClickOnEntity(const EntityItemID& id, const PointerEvent& event); + Q_INVOKABLE void sendClickReleaseOnEntity(const EntityItemID& id, const PointerEvent& event); - Q_INVOKABLE void sendHoverEnterEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendHoverOverEntity(QUuid id, PointerEvent event); - Q_INVOKABLE void sendHoverLeaveEntity(QUuid id, PointerEvent event); + Q_INVOKABLE void sendHoverEnterEntity(const EntityItemID& id, const PointerEvent& event); + Q_INVOKABLE void sendHoverOverEntity(const EntityItemID& id, const PointerEvent& event); + Q_INVOKABLE void sendHoverLeaveEntity(const EntityItemID& id, const PointerEvent& event); Q_INVOKABLE bool wantsHandControllerPointerEvents(QUuid id); @@ -439,8 +439,11 @@ signals: void canWriteAssetsChanged(bool canWriteAssets); void mousePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); + void mouseDoublePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); void mouseMoveOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); void mouseReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); + void mousePressOffEntity(); + void mouseDoublePressOffEntity(); void clickDownOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); void holdingClickOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 5068047d20..dcb16c08f8 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -511,12 +511,19 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, auto keyLight = lightAndShadow.first; + model::LightPointer keyAmbientLight; + if (lightStage && lightStage->_currentFrame._ambientLights.size()) { + keyAmbientLight = lightStage->getLight(lightStage->_currentFrame._ambientLights.front()); + } + bool hasAmbientMap = (keyAmbientLight != nullptr); + // Setup the global directional pass pipeline { if (deferredLightingEffect->_shadowMapEnabled) { + // If the keylight has an ambient Map then use the Skybox version of the pass // otherwise use the ambient sphere version - if (keyLight->getAmbientMap()) { + if (hasAmbientMap) { program = deferredLightingEffect->_directionalSkyboxLightShadow; locations = deferredLightingEffect->_directionalSkyboxLightShadowLocations; } else { @@ -526,7 +533,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, } else { // If the keylight has an ambient Map then use the Skybox version of the pass // otherwise use the ambient sphere version - if (keyLight->getAmbientMap()) { + if (hasAmbientMap) { program = deferredLightingEffect->_directionalSkyboxLight; locations = deferredLightingEffect->_directionalSkyboxLightLocations; } else { diff --git a/libraries/render-utils/src/Haze.slf b/libraries/render-utils/src/Haze.slf index bf46037fd5..77c820e093 100644 --- a/libraries/render-utils/src/Haze.slf +++ b/libraries/render-utils/src/Haze.slf @@ -138,7 +138,7 @@ void main(void) { } // Mix with background at far range - const float BLEND_DISTANCE = 30000.0; + const float BLEND_DISTANCE = 27000.0; if (distance > BLEND_DISTANCE) { outFragColor = mix(potentialFragColor, fragColor, hazeParams.backgroundBlendValue); } else { diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 98846c5213..6fbcd6a794 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -97,7 +97,6 @@ static const bool HIFI_AUTOREFRESH_FILE_SCRIPTS { true }; Q_DECLARE_METATYPE(QScriptEngine::FunctionSignature) int functionSignatureMetaID = qRegisterMetaType(); -Q_DECLARE_METATYPE(ScriptEnginePointer) int scriptEnginePointerMetaID = qRegisterMetaType(); Q_LOGGING_CATEGORY(scriptengineScript, "hifi.scriptengine.script") diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index db159e7265..17c0e0713a 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -55,6 +55,8 @@ static const int DEFAULT_ENTITY_PPS_PER_SCRIPT = 900; class ScriptEngines; +Q_DECLARE_METATYPE(ScriptEnginePointer) + class CallbackData { public: QScriptValue function; diff --git a/unpublishedScripts/marketplace/stopwatch/models/Stopwatch-min-hand.fbx b/unpublishedScripts/marketplace/stopwatch/models/Stopwatch-min-hand.fbx deleted file mode 100644 index b504da13bd..0000000000 Binary files a/unpublishedScripts/marketplace/stopwatch/models/Stopwatch-min-hand.fbx and /dev/null differ diff --git a/unpublishedScripts/marketplace/stopwatch/models/Stopwatch-sec-hand.fbx b/unpublishedScripts/marketplace/stopwatch/models/Stopwatch-sec-hand.fbx deleted file mode 100644 index 12aa85f126..0000000000 Binary files a/unpublishedScripts/marketplace/stopwatch/models/Stopwatch-sec-hand.fbx and /dev/null differ diff --git a/unpublishedScripts/marketplace/stopwatch/models/Stopwatch.fbx b/unpublishedScripts/marketplace/stopwatch/models/Stopwatch.fbx deleted file mode 100644 index 073544875e..0000000000 Binary files a/unpublishedScripts/marketplace/stopwatch/models/Stopwatch.fbx and /dev/null differ diff --git a/unpublishedScripts/marketplace/stopwatch/models/transparent-box.fbx b/unpublishedScripts/marketplace/stopwatch/models/transparent-box.fbx deleted file mode 100644 index b1df7d962c..0000000000 Binary files a/unpublishedScripts/marketplace/stopwatch/models/transparent-box.fbx and /dev/null differ diff --git a/unpublishedScripts/marketplace/stopwatch/sounds/chime.wav b/unpublishedScripts/marketplace/stopwatch/sounds/chime.wav deleted file mode 100644 index cd7143eeeb..0000000000 Binary files a/unpublishedScripts/marketplace/stopwatch/sounds/chime.wav and /dev/null differ diff --git a/unpublishedScripts/marketplace/stopwatch/sounds/tick.wav b/unpublishedScripts/marketplace/stopwatch/sounds/tick.wav deleted file mode 100644 index 21781f8ce4..0000000000 Binary files a/unpublishedScripts/marketplace/stopwatch/sounds/tick.wav and /dev/null differ diff --git a/unpublishedScripts/marketplace/stopwatch/spawnStopwatch.js b/unpublishedScripts/marketplace/stopwatch/spawnStopwatch.js deleted file mode 100644 index 3a0a8a506b..0000000000 --- a/unpublishedScripts/marketplace/stopwatch/spawnStopwatch.js +++ /dev/null @@ -1,89 +0,0 @@ -// -// spawnStopwatch.js -// -// Created by Ryan Huffman on 1/20/17. -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -var forward = Quat.getFront(MyAvatar.orientation); -Vec3.print("Forward: ", forward); -var positionToSpawn = Vec3.sum(MyAvatar.position, Vec3.multiply(3, forward)); -var scale = 0.5; -positionToSpawn.y += 0.5; - -var stopwatchID = Entities.addEntity({ - type: "Model", - name: "stopwatch/base", - position: positionToSpawn, - modelURL: Script.resolvePath("models/Stopwatch.fbx"), - dimensions: Vec3.multiply(scale, {"x":4.129462242126465,"y":1.058512806892395,"z":5.773681640625}), - rotation: Quat.multiply(MyAvatar.orientation, Quat.fromPitchYawRollDegrees(90, 0, 0)) -}); - -var secondHandID = Entities.addEntity({ - type: "Model", - name: "stopwatch/seconds", - parentID: stopwatchID, - localPosition: Vec3.multiply(scale, {"x":-0.004985813982784748,"y":0.39391064643859863,"z":0.8312804698944092}), - dimensions: Vec3.multiply(scale, {"x":0.14095762372016907,"y":0.02546107769012451,"z":1.6077008247375488}), - registrationPoint: {"x":0.5,"y":0.5,"z":1}, - modelURL: Script.resolvePath("models/Stopwatch-sec-hand.fbx"), -}); - -var minuteHandID = Entities.addEntity({ - type: "Model", - name: "stopwatch/minutes", - parentID: stopwatchID, - localPosition: Vec3.multiply(scale, {"x":-0.0023056098725646734,"y":0.3308190703392029,"z":0.21810021996498108}), - dimensions: Vec3.multiply(scale, {"x":0.045471154153347015,"y":0.015412690117955208,"z":0.22930574417114258}), - registrationPoint: {"x":0.5,"y":0.5,"z":1}, - modelURL: Script.resolvePath("models/Stopwatch-min-hand.fbx"), -}); - -var startStopButtonID = Entities.addEntity({ - type: "Model", - name: "stopwatch/startStop", - parentID: stopwatchID, - dimensions: Vec3.multiply(scale, { x: 0.8, y: 0.8, z: 1.0 }), - localPosition: Vec3.multiply(scale, { x: 0, y: -0.1, z: -2.06 }), - modelURL: Script.resolvePath("models/transparent-box.fbx") -}); - -var resetButtonID = Entities.addEntity({ - type: "Model", - name: "stopwatch/startStop", - parentID: stopwatchID, - dimensions: Vec3.multiply(scale, { x: 0.6, y: 0.6, z: 0.8 }), - localPosition: Vec3.multiply(scale, { x: -1.5, y: -0.1, z: -1.2 }), - localRotation: Quat.fromVec3Degrees({ x: 0, y: 36, z: 0 }), - modelURL: Script.resolvePath("models/transparent-box.fbx") -}); - -Entities.editEntity(stopwatchID, { - userData: JSON.stringify({ - secondHandID: secondHandID, - minuteHandID: minuteHandID - }), - serverScripts: Script.resolvePath("stopwatchServer.js") -}); - -Entities.editEntity(startStopButtonID, { - userData: JSON.stringify({ - stopwatchID: stopwatchID, - grabbableKey: { wantsTrigger: true } - }), - script: Script.resolvePath("stopwatchStartStop.js") -}); - -Entities.editEntity(resetButtonID, { - userData: JSON.stringify({ - stopwatchID: stopwatchID, - grabbableKey: { wantsTrigger: true } - }), - script: Script.resolvePath("stopwatchReset.js") -}); - -Script.stop() diff --git a/unpublishedScripts/marketplace/stopwatch/stopwatchReset.js b/unpublishedScripts/marketplace/stopwatch/stopwatchReset.js deleted file mode 100644 index b65c1e7340..0000000000 --- a/unpublishedScripts/marketplace/stopwatch/stopwatchReset.js +++ /dev/null @@ -1,22 +0,0 @@ -// -// stopwatchReset.js -// -// Created by David Rowe on 26 May 2017. -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -(function () { - this.preload = function (entityID) { - var properties = Entities.getEntityProperties(entityID, "userData"); - this.messageChannel = "STOPWATCH-" + JSON.parse(properties.userData).stopwatchID; - }; - function click() { - Messages.sendMessage(this.messageChannel, "reset"); - } - this.startNearTrigger = click; - this.startFarTrigger = click; - this.clickDownOnEntity = click; -}); diff --git a/unpublishedScripts/marketplace/stopwatch/stopwatchServer.js b/unpublishedScripts/marketplace/stopwatch/stopwatchServer.js deleted file mode 100644 index 6ae1b69087..0000000000 --- a/unpublishedScripts/marketplace/stopwatch/stopwatchServer.js +++ /dev/null @@ -1,132 +0,0 @@ -// -// stopwatchServer.js -// -// Created by Ryan Huffman on 1/20/17. -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -(function() { - var self = this; - - self.equipped = false; - self.isActive = false; - self.seconds = 0; - - self.secondHandID = null; - self.minuteHandID = null; - - self.tickSound = SoundCache.getSound(Script.resolvePath("sounds/tick.wav")); - self.tickInjector = null; - self.tickIntervalID = null; - - self.chimeSound = SoundCache.getSound(Script.resolvePath("sounds/chime.wav")); - - self.preload = function(entityID) { - print("Preloading stopwatch: ", entityID); - self.entityID = entityID; - self.messageChannel = "STOPWATCH-" + entityID; - - var userData = Entities.getEntityProperties(self.entityID, 'userData').userData; - var data = JSON.parse(userData); - self.secondHandID = data.secondHandID; - self.minuteHandID = data.minuteHandID; - - self.resetTimer(); - - Messages.subscribe(self.messageChannel); - Messages.messageReceived.connect(this, self.messageReceived); - }; - self.unload = function() { - print("Unloading stopwatch:", self.entityID); - self.resetTimer(); - Messages.unsubscribe(self.messageChannel); - Messages.messageReceived.disconnect(this, self.messageReceived); - }; - self.messageReceived = function(channel, message, sender) { - print("Message received", channel, sender, message); - if (channel === self.messageChannel) { - switch (message) { - case "startStop": - if (self.isActive) { - self.stopTimer(); - } else { - self.startTimer(); - } - break; - case "reset": - self.stopTimer(); - self.resetTimer(); - break; - } - } - }; - self.getStopwatchPosition = function() { - return Entities.getEntityProperties(self.entityID, "position").position; - }; - self.resetTimer = function() { - print("Resetting stopwatch"); - Entities.editEntity(self.secondHandID, { - localRotation: Quat.fromPitchYawRollDegrees(0, 0, 0), - angularVelocity: { x: 0, y: 0, z: 0 }, - }); - Entities.editEntity(self.minuteHandID, { - localRotation: Quat.fromPitchYawRollDegrees(0, 0, 0), - angularVelocity: { x: 0, y: 0, z: 0 }, - }); - self.seconds = 0; - }; - self.startTimer = function() { - print("Starting stopwatch"); - if (!self.tickInjector) { - self.tickInjector = Audio.playSound(self.tickSound, { - position: self.getStopwatchPosition(), - volume: 0.7, - loop: true - }); - } else { - self.tickInjector.restart(); - } - - self.tickIntervalID = Script.setInterval(function() { - if (self.tickInjector) { - self.tickInjector.setOptions({ - position: self.getStopwatchPosition(), - volume: 0.7, - loop: true - }); - } - self.seconds++; - const degreesPerTick = -360 / 60; - Entities.editEntity(self.secondHandID, { - localRotation: Quat.fromPitchYawRollDegrees(0, self.seconds * degreesPerTick, 0), - }); - - if (self.seconds % 60 == 0) { - Entities.editEntity(self.minuteHandID, { - localRotation: Quat.fromPitchYawRollDegrees(0, (self.seconds / 60) * degreesPerTick, 0), - }); - Audio.playSound(self.chimeSound, { - position: self.getStopwatchPosition(), - volume: 1.0, - loop: false - }); - } - }, 1000); - - self.isActive = true; - }; - self.stopTimer = function () { - print("Stopping stopwatch"); - if (self.tickInjector) { - self.tickInjector.stop(); - } - if (self.tickIntervalID !== null) { - Script.clearInterval(self.tickIntervalID); - self.tickIntervalID = null; - } - self.isActive = false; - }; -}); diff --git a/unpublishedScripts/marketplace/stopwatch/stopwatchStartStop.js b/unpublishedScripts/marketplace/stopwatch/stopwatchStartStop.js deleted file mode 100644 index 88c037ee36..0000000000 --- a/unpublishedScripts/marketplace/stopwatch/stopwatchStartStop.js +++ /dev/null @@ -1,23 +0,0 @@ -// -// stopwatchStartStop.js -// -// Created by David Rowe on 26 May 2017. -// Copyright 2017 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -(function () { - var messageChannel; - this.preload = function (entityID) { - var properties = Entities.getEntityProperties(entityID, "userData"); - this.messageChannel = "STOPWATCH-" + JSON.parse(properties.userData).stopwatchID; - }; - function click() { - Messages.sendMessage(this.messageChannel, "startStop"); - } - this.startNearTrigger = click; - this.startFarTrigger = click; - this.clickDownOnEntity = click; -});