From 69b0691eb6ff10aa0f067e3af0d01d6b43014196 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 18 May 2017 16:35:56 -0700 Subject: [PATCH 01/91] Update content set URL for RC40 --- server-console/src/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-console/src/main.js b/server-console/src/main.js index 4ce1ccfb02..98bda9a10f 100644 --- a/server-console/src/main.js +++ b/server-console/src/main.js @@ -42,7 +42,7 @@ const appIcon = path.join(__dirname, '../resources/console.png'); const DELETE_LOG_FILES_OLDER_THAN_X_SECONDS = 60 * 60 * 24 * 7; // 7 Days const LOG_FILE_REGEX = /(domain-server|ac-monitor|ac)-.*-std(out|err).txt/; -const HOME_CONTENT_URL = "http://cdn.highfidelity.com/content-sets/home-tutorial-RC39.tar.gz"; +const HOME_CONTENT_URL = "http://cdn.highfidelity.com/content-sets/home-tutorial-RC40.tar.gz"; function getBuildInfo() { var buildInfoPath = null; From d7d4ff1f822ce3390e276ee48525b12ef5542c5c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 19 May 2017 11:11:00 -0700 Subject: [PATCH 02/91] Add notes to KtxStorage::maybeOpenFile --- libraries/gpu/src/gpu/Texture_ktx.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index 92ead5f616..9799aecdf5 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -184,6 +184,11 @@ KtxStorage::KtxStorage(const std::string& filename) : _filename(filename) { } std::shared_ptr KtxStorage::maybeOpenFile() const { + // 1. Try to get the shared ptr + // 2. If it doesn't exist, grab the mutex around its creation + // 3. If it was created before we got the mutex, return it + // 4. Otherwise, create it + std::shared_ptr file = _cacheFile.lock(); if (file) { return file; From 50f5ae6e7799c1a4f38fc4167674f49911d441dd Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 19 May 2017 11:16:20 -0700 Subject: [PATCH 03/91] Fix FileStorage to not close files after they are opened This is particularly an issue with KTX file reading/writing where we do both concurrently. --- libraries/gpu/src/gpu/Texture_ktx.cpp | 12 +++++--- libraries/shared/src/shared/Storage.cpp | 41 ++++++------------------- libraries/shared/src/shared/Storage.h | 3 +- 3 files changed, 18 insertions(+), 38 deletions(-) diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index 9799aecdf5..bf5b4d7965 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -210,7 +210,6 @@ std::shared_ptr KtxStorage::maybeOpenFile() const { } PixelsPointer KtxStorage::getMipFace(uint16 level, uint8 face) const { - storage::StoragePointer result; auto faceOffset = _ktxDescriptor->getMipFaceTexelsOffset(level, face); auto faceSize = _ktxDescriptor->getMipFaceTexelsSize(level, face); if (faceSize != 0 && faceOffset != 0) { @@ -226,7 +225,7 @@ PixelsPointer KtxStorage::getMipFace(uint16 level, uint8 face) const { qWarning() << "Failed to get a valid file out of maybeOpenFile " << QString::fromStdString(_filename); } } - return result; + return nullptr; } Size KtxStorage::getMipFaceSize(uint16 level, uint8 face) const { @@ -260,8 +259,13 @@ void KtxStorage::assignMipData(uint16 level, const storage::StoragePointer& stor } auto file = maybeOpenFile(); + if (!file) { + qWarning() << "Failed to open file to assign mip data " << QString::fromStdString(_filename); + return; + } - auto imageData = file->mutableData(); + auto fileData = file->mutableData(); + auto imageData = fileData; imageData += ktx::KTX_HEADER_SIZE + _ktxDescriptor->header.bytesOfKeyValueData + _ktxDescriptor->images[level]._imageOffset; imageData += ktx::IMAGE_SIZE_WIDTH; @@ -276,7 +280,7 @@ void KtxStorage::assignMipData(uint16 level, const storage::StoragePointer& stor memcpy(imageData, storage->data(), storage->size()); _minMipLevelAvailable = level; if (_offsetToMinMipKV > 0) { - auto minMipKeyData = file->mutableData() + ktx::KTX_HEADER_SIZE + _offsetToMinMipKV; + auto minMipKeyData = fileData + ktx::KTX_HEADER_SIZE + _offsetToMinMipKV; memcpy(minMipKeyData, (void*)&_minMipLevelAvailable, 1); } } diff --git a/libraries/shared/src/shared/Storage.cpp b/libraries/shared/src/shared/Storage.cpp index e479559e6a..b07f896df0 100644 --- a/libraries/shared/src/shared/Storage.cpp +++ b/libraries/shared/src/shared/Storage.cpp @@ -70,7 +70,15 @@ StoragePointer FileStorage::create(const QString& filename, size_t size, const u } FileStorage::FileStorage(const QString& filename) : _file(filename) { - if (_file.open(QFile::ReadOnly)) { + bool opened = _file.open(QFile::ReadWrite); + if (opened) { + _hasWriteAccess = true; + } else { + _hasWriteAccess = false; + opened = _file.open(QFile::ReadOnly); + } + + if (opened) { _mapped = _file.map(0, _file.size()); if (_mapped) { _valid = true; @@ -91,35 +99,4 @@ FileStorage::~FileStorage() { if (_file.isOpen()) { _file.close(); } -} - -void FileStorage::ensureWriteAccess() { - if (_hasWriteAccess) { - return; - } - - if (_mapped) { - if (!_file.unmap(_mapped)) { - throw std::runtime_error("Unable to unmap file"); - } - } - if (_file.isOpen()) { - _file.close(); - } - _valid = false; - _mapped = nullptr; - - if (_file.open(QFile::ReadWrite)) { - _mapped = _file.map(0, _file.size()); - if (_mapped) { - _valid = true; - _hasWriteAccess = true; - } else { - qCWarning(storagelogging) << "Failed to map file " << _file.fileName(); - throw std::runtime_error("Failed to map file"); - } - } else { - qCWarning(storagelogging) << "Failed to open file " << _file.fileName(); - throw std::runtime_error("Failed to open file"); - } } \ No newline at end of file diff --git a/libraries/shared/src/shared/Storage.h b/libraries/shared/src/shared/Storage.h index 4cad9fa083..d7946738cf 100644 --- a/libraries/shared/src/shared/Storage.h +++ b/libraries/shared/src/shared/Storage.h @@ -60,11 +60,10 @@ namespace storage { FileStorage& operator=(const FileStorage& other) = delete; const uint8_t* data() const override { return _mapped; } - uint8_t* mutableData() override { ensureWriteAccess(); return _mapped; } + uint8_t* mutableData() override { return _hasWriteAccess ? _mapped : nullptr; } size_t size() const override { return _file.size(); } operator bool() const override { return _valid; } private: - void ensureWriteAccess(); bool _valid { false }; bool _hasWriteAccess { false }; From 53a963726d2c1d76341ab3707ce73d565363d6d1 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 19 May 2017 15:00:53 -0700 Subject: [PATCH 04/91] Add check for valid mutableData in assignMipData --- libraries/gpu/src/gpu/Texture_ktx.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index bf5b4d7965..14282ec525 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -265,6 +265,11 @@ void KtxStorage::assignMipData(uint16 level, const storage::StoragePointer& stor } auto fileData = file->mutableData(); + if (!fileData) { + qWarning() << "Failed to get mutable data for " << QString::fromStdString(_filename); + return; + } + auto imageData = fileData; imageData += ktx::KTX_HEADER_SIZE + _ktxDescriptor->header.bytesOfKeyValueData + _ktxDescriptor->images[level]._imageOffset; imageData += ktx::IMAGE_SIZE_WIDTH; From 5cb25b1ef1692c5daffc647efd86e0bf9a2a668e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 19 May 2017 16:53:25 -0700 Subject: [PATCH 05/91] Increment _identitySequenceId before sending ID packet for agents --- assignment-client/src/Agent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 5864cadc15..96b2336af8 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -584,6 +584,7 @@ void Agent::setIsAvatar(bool isAvatar) { void Agent::sendAvatarIdentityPacket() { if (_isAvatar) { auto scriptedAvatar = DependencyManager::get(); + scriptedAvatar->markIdentityDataChanged(); scriptedAvatar->sendIdentityPacket(); } } From 2928507e4898cc863d701398598895d360f9f6ba Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 19 May 2017 10:48:38 -0700 Subject: [PATCH 06/91] Fix "Reset Settings" window poping up every time --- interface/src/Application.cpp | 8 ++++---- interface/src/Application.h | 2 +- interface/src/CrashHandler.cpp | 5 +---- interface/src/CrashHandler.h | 2 +- interface/src/main.cpp | 3 ++- libraries/shared/src/RunningMarker.cpp | 7 ++++++- libraries/shared/src/RunningMarker.h | 4 +++- 7 files changed, 18 insertions(+), 13 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c39f7294c0..bd66a96879 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -431,7 +431,7 @@ static const QString STATE_ADVANCED_MOVEMENT_CONTROLS = "AdvancedMovement"; static const QString STATE_GROUNDED = "Grounded"; static const QString STATE_NAV_FOCUSED = "NavigationFocused"; -bool setupEssentials(int& argc, char** argv) { +bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { const char** constArgv = const_cast(argv); const char* portStr = getCmdOption(argc, constArgv, "--listenPort"); const int listenPort = portStr ? atoi(portStr) : INVALID_PORT; @@ -458,7 +458,7 @@ bool setupEssentials(int& argc, char** argv) { static const auto SUPPRESS_SETTINGS_RESET = "--suppress-settings-reset"; bool suppressPrompt = cmdOptionExists(argc, const_cast(argv), SUPPRESS_SETTINGS_RESET); - bool previousSessionCrashed = CrashHandler::checkForResetSettings(suppressPrompt); + bool previousSessionCrashed = CrashHandler::checkForResetSettings(runningMarkerExisted, suppressPrompt); DependencyManager::registerInheritance(); DependencyManager::registerInheritance(); @@ -563,11 +563,11 @@ const bool DEFAULT_DESKTOP_TABLET_BECOMES_TOOLBAR = true; const bool DEFAULT_HMD_TABLET_BECOMES_TOOLBAR = false; const bool DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS = false; -Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : +Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bool runningMarkerExisted) : QApplication(argc, argv), _window(new MainWindow(desktop())), _sessionRunTimer(startupTimer), - _previousSessionCrashed(setupEssentials(argc, argv)), + _previousSessionCrashed(setupEssentials(argc, argv, runningMarkerExisted)), _undoStackScriptingInterface(&_undoStack), _entitySimulation(new PhysicalEntitySimulation()), _physicsEngine(new PhysicsEngine(Vectors::ZERO)), diff --git a/interface/src/Application.h b/interface/src/Application.h index 5cf3580c09..d9dc3f389f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -136,7 +136,7 @@ public: static void initPlugins(const QStringList& arguments); static void shutdownPlugins(); - Application(int& argc, char** argv, QElapsedTimer& startup_time); + Application(int& argc, char** argv, QElapsedTimer& startup_time, bool runningMarkerExisted); ~Application(); void postLambdaEvent(std::function f) override; diff --git a/interface/src/CrashHandler.cpp b/interface/src/CrashHandler.cpp index b254cd58de..8081dd3ffc 100644 --- a/interface/src/CrashHandler.cpp +++ b/interface/src/CrashHandler.cpp @@ -28,7 +28,7 @@ #include -bool CrashHandler::checkForResetSettings(bool suppressPrompt) { +bool CrashHandler::checkForResetSettings(bool wasLikelyCrash, bool suppressPrompt) { Settings settings; settings.beginGroup("Developer"); QVariant displayCrashOptions = settings.value(MenuOption::DisplayCrashOptions); @@ -39,9 +39,6 @@ bool CrashHandler::checkForResetSettings(bool suppressPrompt) { // If option does not exist in Interface.ini so assume default behavior. bool displaySettingsResetOnCrash = !displayCrashOptions.isValid() || displayCrashOptions.toBool(); - QFile runningMarkerFile(RunningMarker::getMarkerFilePath(RUNNING_MARKER_FILENAME)); - bool wasLikelyCrash = runningMarkerFile.exists(); - if (suppressPrompt) { return wasLikelyCrash; } diff --git a/interface/src/CrashHandler.h b/interface/src/CrashHandler.h index 308cac3411..da2e1575db 100644 --- a/interface/src/CrashHandler.h +++ b/interface/src/CrashHandler.h @@ -17,7 +17,7 @@ class CrashHandler { public: - static bool checkForResetSettings(bool suppressPrompt = false); + static bool checkForResetSettings(bool wasLikelyCrash, bool suppressPrompt = false); private: enum Action { diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 3430ffbd15..49517eb38e 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -192,6 +192,7 @@ int main(int argc, const char* argv[]) { int exitCode; { RunningMarker runningMarker(nullptr, RUNNING_MARKER_FILENAME); + bool runningMarkerExisted = runningMarker.fileExists(); runningMarker.writeRunningMarkerFile(); bool noUpdater = parser.isSet(noUpdaterOption); @@ -202,7 +203,7 @@ int main(int argc, const char* argv[]) { SandboxUtils::runLocalSandbox(serverContentPath, true, RUNNING_MARKER_FILENAME, noUpdater); } - Application app(argc, const_cast(argv), startupTime); + Application app(argc, const_cast(argv), startupTime, runningMarkerExisted); // Now that the main event loop is setup, launch running marker thread runningMarker.startRunningMarker(); diff --git a/libraries/shared/src/RunningMarker.cpp b/libraries/shared/src/RunningMarker.cpp index f8aaee42df..0c1fd06df8 100644 --- a/libraries/shared/src/RunningMarker.cpp +++ b/libraries/shared/src/RunningMarker.cpp @@ -53,6 +53,11 @@ RunningMarker::~RunningMarker() { _runningMarkerThread->deleteLater(); } +bool RunningMarker::fileExists() const { + QFile runningMarkerFile(getFilePath()); + return runningMarkerFile.exists(); +} + void RunningMarker::writeRunningMarkerFile() { QFile runningMarkerFile(getFilePath()); @@ -69,7 +74,7 @@ void RunningMarker::deleteRunningMarkerFile() { } } -QString RunningMarker::getFilePath() { +QString RunningMarker::getFilePath() const { return QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + _name; } diff --git a/libraries/shared/src/RunningMarker.h b/libraries/shared/src/RunningMarker.h index 1137dbf5fa..f9c8e72d37 100644 --- a/libraries/shared/src/RunningMarker.h +++ b/libraries/shared/src/RunningMarker.h @@ -25,9 +25,11 @@ public: void startRunningMarker(); - QString getFilePath(); + QString getFilePath() const; static QString getMarkerFilePath(QString name); + bool fileExists() const; + void writeRunningMarkerFile(); void deleteRunningMarkerFile(); From 0c4cd96bfddd85c2587f56821043635a46b169b0 Mon Sep 17 00:00:00 2001 From: volansystech Date: Wed, 24 May 2017 12:25:21 +0530 Subject: [PATCH 07/91] Initial Commit : Switch from HMD [Oculus Rift] mode to Desktop mode automatically when user removing Oculus Rift. --- interface/src/Application.cpp | 40 +++++++++++++++++++++++++++++++++++ interface/src/Application.h | 8 +++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ae490c05e7..ced5e51565 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1338,6 +1338,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["active_display_plugin"] = getActiveDisplayPlugin()->getName(); properties["using_hmd"] = isHMDMode(); + if (isOculusRiftPluginAvailable()){ + qCDebug(interfaceapp) << "Oculus Rift Plugin is available"; + QTimer *switchModeTimer = new QTimer(this); + connect(switchModeTimer, SIGNAL(timeout()), this, SLOT(switchmode())); + switchModeTimer->start(500); + } + auto glInfo = getGLContextData(); properties["gl_info"] = glInfo; properties["gpu_used_memory"] = (int)BYTES_TO_MB(gpu::Context::getUsedGPUMemory()); @@ -6833,6 +6840,39 @@ void Application::updateDisplayMode() { Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin"); } +bool Application::isOculusRiftPluginAvailable(){ + bool isOculusRiftPluginAvailable = false; + auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); + // Default to the first item on the list, in case none of the menu items match + DisplayPluginPointer defaultplugin = displayPlugins.at(0); + if (defaultplugin->isHmd() && defaultplugin->getName() == "Oculus Rift"){ + oculusRiftPlugin = defaultplugin; + return true; // No need to iterate again,so return + } + // Iterate to check If Oculus Rift Plugin is available + foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { + QString pluginname = displayPlugin->getName(); + if (displayPlugin->isHmd() && pluginname == "Oculus Rift") { + oculusRiftPlugin = displayPlugin; + _isDisplayVisible = displayPlugin->isDisplayVisible(); + isOculusRiftPluginAvailable = true; + break; + } + } + return isOculusRiftPluginAvailable; +} + +void Application::switchmode(){ + bool isDisplayVisible = oculusRiftPlugin->isDisplayVisible(); + if (isDisplayVisible != _isDisplayVisible){ + if (isDisplayVisible == false && _isDisplayVisible == true){ + qCDebug(interfaceapp) << "switching from HMD to desktop mode"; + setActiveDisplayPlugin("Desktop"); + } + } + _isDisplayVisible = isDisplayVisible; // assign current status +} + mat4 Application::getEyeProjection(int eye) const { QMutexLocker viewLocker(&_viewMutex); if (isHMDMode()) { diff --git a/interface/src/Application.h b/interface/src/Application.h index d9dc3f389f..c181e74c74 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -152,7 +152,7 @@ public: void paintGL(); void resizeGL(); - bool event(QEvent* event) override; + bool event(QEvent* event) override; bool eventFilter(QObject* object, QEvent* event) override; glm::uvec2 getCanvasSize() const; @@ -443,7 +443,7 @@ private slots: void addAssetToWorldErrorTimeout(); void handleSandboxStatus(QNetworkReply* reply); - + void switchmode(); private: static void initDisplay(); void init(); @@ -683,6 +683,10 @@ private: FileScriptingInterface* _fileDownload; AudioInjector* _snapshotSoundInjector { nullptr }; SharedSoundPointer _snapshotSound; + + bool isOculusRiftPluginAvailable(); + DisplayPluginPointer oculusRiftPlugin; + bool _isDisplayVisible; }; From ac55908e42984a27c91cd386609808f61073376b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 16:50:06 -0700 Subject: [PATCH 08/91] add additional information to stats/launch activities --- interface/src/Application.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index bd66a96879..253277b37f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -946,6 +946,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["processor_l3_cache_count"] = procInfo.numProcessorCachesL3; } + // add firstRun flag from settings to launch event + Setting::Handle firstRun { Settings::firstRun, true }; + properties["first_run"] = firstRun.get(); + UserActivityLogger::getInstance().logAction("launch", properties); // Tell our entity edit sender about our known jurisdictions @@ -1305,6 +1309,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["kbps_in"] = bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond(); properties["kbps_out"] = bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond(); + properties["asset_in_kbps"] = bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AssetServer); + auto nodeList = DependencyManager::get(); SharedNodePointer entityServerNode = nodeList->soloNodeOfType(NodeType::EntityServer); SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer); @@ -1317,10 +1323,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["asset_ping"] = assetServerNode ? assetServerNode->getPingMs() : -1; properties["messages_ping"] = messagesMixerNode ? messagesMixerNode->getPingMs() : -1; + auto loadingRequests = ResourceCache::getLoadingRequests(); properties["active_downloads"] = loadingRequests.size(); properties["pending_downloads"] = ResourceCache::getPendingRequestCount(); + properties["processing_resources"] = DependencyManager::get()->getStat("Processing").toInt(); + properties["pending_processing_resources"] = DependencyManager::get()->getStat("PendingProcessing").toInt(); + properties["throttled"] = _displayPlugin ? _displayPlugin->isThrottled() : false; auto myAvatar = getMyAvatar(); @@ -1335,6 +1345,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["deleted_entity_cnt"] = entityActivityTracking.deletedEntityCount; properties["edited_entity_cnt"] = entityActivityTracking.editedEntityCount; + NodeToOctreeSceneStats* octreeServerSceneStats = getOcteeSceneStats(); + unsigned long totalServerOctreeElements = 0; + for (NodeToOctreeSceneStatsIterator i = octreeServerSceneStats->begin(); i != octreeServerSceneStats->end(); i++) { + totalServerOctreeElements += i->second.getTotalElements(); + } + + properties["local_octree_elements"] = (qint64) OctreeElement::getInternalNodeCount(); + properties["server_octree_elements"] = (qint64) totalServerOctreeElements; + properties["active_display_plugin"] = getActiveDisplayPlugin()->getName(); properties["using_hmd"] = isHMDMode(); From 3743cd23b4fe6d74092d34ba3c62b1bb32b7f8fa Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 17:20:24 -0700 Subject: [PATCH 09/91] add detailed download stats for file/http/atp --- interface/src/Application.cpp | 33 +++++++++++++++++-- .../networking/src/AssetResourceRequest.cpp | 22 +++++++++++-- .../networking/src/FileResourceRequest.cpp | 11 +++++++ .../networking/src/HTTPResourceRequest.cpp | 16 +++++++++ libraries/networking/src/ResourceRequest.h | 12 +++++++ 5 files changed, 90 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 253277b37f..08981ee6c1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -111,6 +111,7 @@ #include #include #include +#include #include #include #include @@ -1328,8 +1329,36 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["active_downloads"] = loadingRequests.size(); properties["pending_downloads"] = ResourceCache::getPendingRequestCount(); - properties["processing_resources"] = DependencyManager::get()->getStat("Processing").toInt(); - properties["pending_processing_resources"] = DependencyManager::get()->getStat("PendingProcessing").toInt(); + auto statTracker = DependencyManager::get(); + + properties["processing_resources"] = statTracker->getStat("Processing").toInt(); + properties["pending_processing_resources"] = statTracker->getStat("PendingProcessing").toInt(); + + properties["started_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_STARTED).toInt(); + properties["started_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_STARTED).toInt(); + properties["started_file_requests"] = statTracker->getStat(STAT_FILE_REQUEST_STARTED).toInt(); + auto totalRequestsStarted = properties["started_atp_requests"].toInt() + + properties["started_http_requests"].toInt() + properties["started_file_requests"].toInt(); + properties["started_requests"] = totalRequestsStarted; + + properties["successful_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_SUCCESS).toInt(); + properties["successful_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_SUCCESS).toInt(); + properties["successful_file_requests"] = statTracker->getStat(STAT_FILE_REQUEST_SUCCESS).toInt(); + auto totalRequestsSuccessful = properties["successful_atp_requests"].toInt() + + properties["successful_http_requests"].toInt() + properties["successful_file_requests"].toInt(); + properties["successful_requests"] = totalRequestsSuccessful; + + properties["failed_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_FAILED).toInt(); + properties["failed_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); + properties["failed_file_requests"] = statTracker->getStat(STAT_FILE_REQUEST_FAILED).toInt(); + auto totalRequestsFailed = properties["failed_atp_requests"].toInt() + + properties["failed_http_requests"].toInt() + properties["failed_file_requests"].toInt(); + properties["failed_requests"] = totalRequestsFailed; + + properties["cache_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_CACHE).toInt(); + properties["cache_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); + auto totalRequestsCache = properties["cache_atp_requests"].toInt() + properties["cache_http_requests"].toInt(); + properties["cache_requests"] = totalRequestsCache; properties["throttled"] = _displayPlugin ? _displayPlugin->isThrottled() : false; diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index a4d5d66923..d23d85d79e 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -13,12 +13,14 @@ #include +#include +#include +#include + #include "AssetClient.h" #include "AssetUtils.h" #include "MappingRequest.h" #include "NetworkLogging.h" -#include -#include static const int DOWNLOAD_PROGRESS_LOG_INTERVAL_SECONDS = 5; @@ -48,6 +50,8 @@ bool AssetResourceRequest::urlIsAssetHash(const QUrl& url) { } void AssetResourceRequest::doSend() { + DependencyManager::get()->incrementStat(STAT_ATP_REQUEST_STARTED); + // We'll either have a hash or an ATP path to a file (that maps to a hash) if (urlIsAssetHash(_url)) { // We've detected that this is a hash - simply use AssetClient to request that asset @@ -100,6 +104,8 @@ void AssetResourceRequest::requestMappingForPath(const AssetPath& path) { _state = Finished; emit finished(); + DependencyManager::get()->incrementStat(STAT_ATP_REQUEST_FAILED); + break; } } @@ -140,10 +146,22 @@ void AssetResourceRequest::requestHash(const AssetHash& hash) { _result = Error; break; } + + auto statTracker = DependencyManager::get(); _state = Finished; emit finished(); + if (_result == Success) { + statTracker->incrementStat(STAT_ATP_REQUEST_SUCCESS); + + if (loadedFromCache()) { + statTracker->incrementStat(STAT_ATP_REQUEST_CACHE); + } + } else { + statTracker->incrementStat(STAT_ATP_REQUEST_FAILED); + } + _assetRequest->deleteLater(); _assetRequest = nullptr; }); diff --git a/libraries/networking/src/FileResourceRequest.cpp b/libraries/networking/src/FileResourceRequest.cpp index 1e549e5fa3..d0e2721679 100644 --- a/libraries/networking/src/FileResourceRequest.cpp +++ b/libraries/networking/src/FileResourceRequest.cpp @@ -15,7 +15,12 @@ #include +#include + void FileResourceRequest::doSend() { + auto statTracker = DependencyManager::get(); + statTracker->incrementStat(STAT_FILE_REQUEST_STARTED); + QString filename = _url.toLocalFile(); // sometimes on windows, we see the toLocalFile() return null, @@ -60,4 +65,10 @@ void FileResourceRequest::doSend() { _state = Finished; emit finished(); + + if (_result == ResourceRequest::Success) { + statTracker->incrementStat(STAT_FILE_REQUEST_SUCCESS); + } else { + statTracker->incrementStat(STAT_FILE_REQUEST_FAILED); + } } diff --git a/libraries/networking/src/HTTPResourceRequest.cpp b/libraries/networking/src/HTTPResourceRequest.cpp index c6a4b93e51..266ea429a0 100644 --- a/libraries/networking/src/HTTPResourceRequest.cpp +++ b/libraries/networking/src/HTTPResourceRequest.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "NetworkAccessManager.h" #include "NetworkLogging.h" @@ -49,6 +50,8 @@ void HTTPResourceRequest::cleanupTimer() { } void HTTPResourceRequest::doSend() { + DependencyManager::get()->incrementStat(STAT_HTTP_REQUEST_STARTED); + QNetworkRequest networkRequest(_url); networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); @@ -178,6 +181,17 @@ void HTTPResourceRequest::onRequestFinished() { _state = Finished; emit finished(); + + auto statTracker = DependencyManager::get(); + if (_result == Success) { + statTracker->incrementStat(STAT_HTTP_REQUEST_SUCCESS); + + if (loadedFromCache()) { + statTracker->incrementStat(STAT_HTTP_REQUEST_CACHE); + } + } else { + statTracker->incrementStat(STAT_HTTP_REQUEST_FAILED); + } } void HTTPResourceRequest::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) { @@ -202,4 +216,6 @@ void HTTPResourceRequest::onTimeout() { _result = Timeout; _state = Finished; emit finished(); + + DependencyManager::get()->incrementStat(STAT_HTTP_REQUEST_FAILED); } diff --git a/libraries/networking/src/ResourceRequest.h b/libraries/networking/src/ResourceRequest.h index ef40cb3455..452380f2f3 100644 --- a/libraries/networking/src/ResourceRequest.h +++ b/libraries/networking/src/ResourceRequest.h @@ -19,6 +19,18 @@ #include "ByteRange.h" +const QString STAT_ATP_REQUEST_STARTED = "StartedATPRequest"; +const QString STAT_HTTP_REQUEST_STARTED = "StartedHTTPRequest"; +const QString STAT_FILE_REQUEST_STARTED = "StartedFileRequest"; +const QString STAT_ATP_REQUEST_SUCCESS = "SuccessfulATPRequest"; +const QString STAT_HTTP_REQUEST_SUCCESS = "SuccessfulHTTPRequest"; +const QString STAT_FILE_REQUEST_SUCCESS = "SuccessfulFileRequest"; +const QString STAT_ATP_REQUEST_FAILED = "FailedATPRequest"; +const QString STAT_HTTP_REQUEST_FAILED = "FailedHTTPRequest"; +const QString STAT_FILE_REQUEST_FAILED = "FailedFileRequest"; +const QString STAT_ATP_REQUEST_CACHE = "CacheATPRequest"; +const QString STAT_HTTP_REQUEST_CACHE = "CacheHTTPRequest"; + class ResourceRequest : public QObject { Q_OBJECT public: From 48c4db1ca4a6bfcd687a76caaa66c6194d055142 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 17:36:21 -0700 Subject: [PATCH 10/91] nest the download stats so they are cleaner --- interface/src/Application.cpp | 55 +++++++++++-------- .../networking/src/AssetResourceRequest.cpp | 10 +++- libraries/networking/src/ResourceRequest.h | 3 + 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 08981ee6c1..4d18c26296 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1324,7 +1324,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["asset_ping"] = assetServerNode ? assetServerNode->getPingMs() : -1; properties["messages_ping"] = messagesMixerNode ? messagesMixerNode->getPingMs() : -1; - auto loadingRequests = ResourceCache::getLoadingRequests(); properties["active_downloads"] = loadingRequests.size(); properties["pending_downloads"] = ResourceCache::getPendingRequestCount(); @@ -1334,31 +1333,41 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["processing_resources"] = statTracker->getStat("Processing").toInt(); properties["pending_processing_resources"] = statTracker->getStat("PendingProcessing").toInt(); - properties["started_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_STARTED).toInt(); - properties["started_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_STARTED).toInt(); - properties["started_file_requests"] = statTracker->getStat(STAT_FILE_REQUEST_STARTED).toInt(); - auto totalRequestsStarted = properties["started_atp_requests"].toInt() - + properties["started_http_requests"].toInt() + properties["started_file_requests"].toInt(); - properties["started_requests"] = totalRequestsStarted; + QJsonObject startedRequests; + startedRequests["atp"] = statTracker->getStat(STAT_ATP_REQUEST_STARTED).toInt(); + startedRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_STARTED).toInt(); + startedRequests["file"] = statTracker->getStat(STAT_FILE_REQUEST_STARTED).toInt(); + startedRequests["total"] = startedRequests["atp"].toInt() + startedRequests["http"].toInt() + + startedRequests["file"].toInt(); + properties["started_requests"] = startedRequests; - properties["successful_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_SUCCESS).toInt(); - properties["successful_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_SUCCESS).toInt(); - properties["successful_file_requests"] = statTracker->getStat(STAT_FILE_REQUEST_SUCCESS).toInt(); - auto totalRequestsSuccessful = properties["successful_atp_requests"].toInt() - + properties["successful_http_requests"].toInt() + properties["successful_file_requests"].toInt(); - properties["successful_requests"] = totalRequestsSuccessful; + QJsonObject successfulRequests; + successfulRequests["atp"] = statTracker->getStat(STAT_ATP_REQUEST_SUCCESS).toInt(); + successfulRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_SUCCESS).toInt(); + successfulRequests["file"] = statTracker->getStat(STAT_FILE_REQUEST_SUCCESS).toInt(); + successfulRequests["total"] = successfulRequests["atp"].toInt() + successfulRequests["http"].toInt() + + successfulRequests["file"].toInt(); + properties["successful_requests"] = successfulRequests; - properties["failed_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_FAILED).toInt(); - properties["failed_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); - properties["failed_file_requests"] = statTracker->getStat(STAT_FILE_REQUEST_FAILED).toInt(); - auto totalRequestsFailed = properties["failed_atp_requests"].toInt() - + properties["failed_http_requests"].toInt() + properties["failed_file_requests"].toInt(); - properties["failed_requests"] = totalRequestsFailed; + QJsonObject failedRequests; + failedRequests["atp"] = statTracker->getStat(STAT_ATP_REQUEST_FAILED).toInt(); + failedRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); + failedRequests["file"] = statTracker->getStat(STAT_FILE_REQUEST_FAILED).toInt(); + failedRequests["total"] = failedRequests["atp"].toInt() + failedRequests["http"].toInt() + + failedRequests["file"].toInt(); + properties["failed_requests"] = failedRequests; - properties["cache_atp_requests"] = statTracker->getStat(STAT_ATP_REQUEST_CACHE).toInt(); - properties["cache_http_requests"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); - auto totalRequestsCache = properties["cache_atp_requests"].toInt() + properties["cache_http_requests"].toInt(); - properties["cache_requests"] = totalRequestsCache; + QJsonObject cacheRequests; + cacheRequests["atp"] = statTracker->getStat(STAT_ATP_REQUEST_CACHE).toInt(); + cacheRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); + cacheRequests["total"] = cacheRequests["atp"].toInt() + cacheRequests["http"].toInt(); + properties["cache_requests"] = cacheRequests; + + QJsonObject atpMappingRequests; + atpMappingRequests["started"] = statTracker->getStat(STAT_ATP_MAPPING_REQUEST_STARTED).toInt(); + atpMappingRequests["failed"] = statTracker->getStat(STAT_ATP_MAPPING_REQUEST_FAILED).toInt(); + atpMappingRequests["successful"] = statTracker->getStat(STAT_ATP_MAPPING_REQUEST_SUCCESS).toInt(); + properties["atp_mapping_requests"] = atpMappingRequests; properties["throttled"] = _displayPlugin ? _displayPlugin->isThrottled() : false; diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index d23d85d79e..fc83fb6cae 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -69,11 +69,14 @@ void AssetResourceRequest::doSend() { } void AssetResourceRequest::requestMappingForPath(const AssetPath& path) { + auto statTracker = DependencyManager::get(); + statTracker->incrementStat(STAT_ATP_MAPPING_REQUEST_STARTED); + auto assetClient = DependencyManager::get(); _assetMappingRequest = assetClient->createGetMappingRequest(path); // make sure we'll hear about the result of the get mapping request - connect(_assetMappingRequest, &GetMappingRequest::finished, this, [this, path](GetMappingRequest* request){ + connect(_assetMappingRequest, &GetMappingRequest::finished, this, [this, path, statTracker](GetMappingRequest* request){ Q_ASSERT(_state == InProgress); Q_ASSERT(request == _assetMappingRequest); @@ -84,6 +87,8 @@ void AssetResourceRequest::requestMappingForPath(const AssetPath& path) { requestHash(request->getHash()); + statTracker->incrementStat(STAT_ATP_MAPPING_REQUEST_SUCCESS); + break; default: { switch (request->getError()) { @@ -104,7 +109,8 @@ void AssetResourceRequest::requestMappingForPath(const AssetPath& path) { _state = Finished; emit finished(); - DependencyManager::get()->incrementStat(STAT_ATP_REQUEST_FAILED); + statTracker->incrementStat(STAT_ATP_MAPPING_REQUEST_FAILED); + statTracker->incrementStat(STAT_ATP_REQUEST_FAILED); break; } diff --git a/libraries/networking/src/ResourceRequest.h b/libraries/networking/src/ResourceRequest.h index 452380f2f3..39bcb3fe93 100644 --- a/libraries/networking/src/ResourceRequest.h +++ b/libraries/networking/src/ResourceRequest.h @@ -30,6 +30,9 @@ const QString STAT_HTTP_REQUEST_FAILED = "FailedHTTPRequest"; const QString STAT_FILE_REQUEST_FAILED = "FailedFileRequest"; const QString STAT_ATP_REQUEST_CACHE = "CacheATPRequest"; const QString STAT_HTTP_REQUEST_CACHE = "CacheHTTPRequest"; +const QString STAT_ATP_MAPPING_REQUEST_STARTED = "StartedATPMappingRequest"; +const QString STAT_ATP_MAPPING_REQUEST_FAILED = "FailedATPMappingRequest"; +const QString STAT_ATP_MAPPING_REQUEST_SUCCESS = "SuccessfulATPMappingRequest"; class ResourceRequest : public QObject { Q_OBJECT From 5e61f20df8d5c59cf02108579040245c51654805 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 17:37:42 -0700 Subject: [PATCH 11/91] add more details about pending downloads --- interface/src/Application.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4d18c26296..28d183a18b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1325,8 +1325,20 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["messages_ping"] = messagesMixerNode ? messagesMixerNode->getPingMs() : -1; auto loadingRequests = ResourceCache::getLoadingRequests(); + + QJsonArray loadingRequestsStats; + for (const auto& request : loadingRequests) { + QJsonObject requestStats; + requestStats["filename"] = request->getURL().fileName(); + requestStats["received"] = request->getBytesReceived(); + requestStats["total"] = request->getBytesTotal(); + requestStats["attempts"] = (int)request->getDownloadAttempts(); + loadingRequestsStats.append(requestStats); + } + properties["active_downloads"] = loadingRequests.size(); properties["pending_downloads"] = ResourceCache::getPendingRequestCount(); + properties["active_downloads_details"] = loadingRequestsStats; auto statTracker = DependencyManager::get(); From c37fd335e1d6560692fdc1a3bfd0db642751cf38 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 17:41:52 -0700 Subject: [PATCH 12/91] track the number of local socket changes --- interface/src/Application.cpp | 2 ++ libraries/networking/src/LimitedNodeList.cpp | 4 ++-- libraries/networking/src/LimitedNodeList.h | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 28d183a18b..1f5eebee84 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1429,6 +1429,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo lastLeftHandPose = leftHandPose; lastRightHandPose = rightHandPose; + properties["local_socket_changes"] = DependencyManager::get()->getStat(LOCAL_SOCKET_CHANGE_STAT).toInt(); + UserActivityLogger::getInstance().logAction("stats", properties); }); sendStatsTimer->start(); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 8feb695c79..cba1e664ab 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "AccountManager.h" @@ -37,7 +38,6 @@ #include "HifiSockAddr.h" #include "NetworkLogging.h" #include "udt/Packet.h" -#include static Setting::Handle LIMITED_NODELIST_LOCAL_PORT("LimitedNodeList.LocalPort", 0); @@ -1044,10 +1044,10 @@ void LimitedNodeList::setLocalSocket(const HifiSockAddr& sockAddr) { qCInfo(networking) << "Local socket is" << sockAddr; } else { qCInfo(networking) << "Local socket has changed from" << _localSockAddr << "to" << sockAddr; + DependencyManager::get()->incrementStat(LOCAL_SOCKET_CHANGE_STAT); } _localSockAddr = sockAddr; - emit localSockAddrChanged(_localSockAddr); } } diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 3eb898463a..056a4d16cf 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -66,6 +66,8 @@ const QHostAddress DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME = QHostAddress::Lo const QString USERNAME_UUID_REPLACEMENT_STATS_KEY = "$username"; +const QString LOCAL_SOCKET_CHANGE_STAT = "LocalSocketChanges"; + using namespace tbb; typedef std::pair UUIDNodePair; typedef concurrent_unordered_map NodeHash; From fefb34512d399fa2f164ab37ebe82ed205fc94c4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 17:44:09 -0700 Subject: [PATCH 13/91] change asset inbound key to atp --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1f5eebee84..e73d46185e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1310,7 +1310,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["kbps_in"] = bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond(); properties["kbps_out"] = bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond(); - properties["asset_in_kbps"] = bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AssetServer); + properties["atp_in_kbps"] = bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AssetServer); auto nodeList = DependencyManager::get(); SharedNodePointer entityServerNode = nodeList->soloNodeOfType(NodeType::EntityServer); From c671817fa3985967f9bc3dfb310e85ccc74158d0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 17:47:40 -0700 Subject: [PATCH 14/91] fix cache http request count in stats --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e73d46185e..0b05efbadb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1371,7 +1371,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo QJsonObject cacheRequests; cacheRequests["atp"] = statTracker->getStat(STAT_ATP_REQUEST_CACHE).toInt(); - cacheRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); + cacheRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_CACHE).toInt(); cacheRequests["total"] = cacheRequests["atp"].toInt() + cacheRequests["http"].toInt(); properties["cache_requests"] = cacheRequests; From a04fc41e17587853a3d6ebcf2e7a22238911f474 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 17:54:07 -0700 Subject: [PATCH 15/91] don't capture strong pointer to stat tracker --- libraries/networking/src/AssetResourceRequest.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index fc83fb6cae..c0150fd3ed 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -76,7 +76,9 @@ void AssetResourceRequest::requestMappingForPath(const AssetPath& path) { _assetMappingRequest = assetClient->createGetMappingRequest(path); // make sure we'll hear about the result of the get mapping request - connect(_assetMappingRequest, &GetMappingRequest::finished, this, [this, path, statTracker](GetMappingRequest* request){ + connect(_assetMappingRequest, &GetMappingRequest::finished, this, [this, path](GetMappingRequest* request){ + auto statTracker = DependencyManager::get(); + Q_ASSERT(_state == InProgress); Q_ASSERT(request == _assetMappingRequest); From 50285005beead11349656f0ca380ad98b144319d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 18:35:57 -0700 Subject: [PATCH 16/91] add machine fingerprint to the launch event --- interface/src/Application.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0b05efbadb..2fe0af8556 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -951,6 +952,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo Setting::Handle firstRun { Settings::firstRun, true }; properties["first_run"] = firstRun.get(); + // add the user's machine ID to the launch event + properties["machine_fingerprint"] = FingerprintUtils::getMachineFingerprint().toString(); + UserActivityLogger::getInstance().logAction("launch", properties); // Tell our entity edit sender about our known jurisdictions From f897f3f0902c4cef7f04357a26db448b26677f7f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 19:08:25 -0700 Subject: [PATCH 17/91] send machine fingerprint as uuid without curly braces --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2fe0af8556..abccc5197d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -953,7 +953,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["first_run"] = firstRun.get(); // add the user's machine ID to the launch event - properties["machine_fingerprint"] = FingerprintUtils::getMachineFingerprint().toString(); + properties["machine_fingerprint"] = uuidStringWithoutCurlyBraces(FingerprintUtils::getMachineFingerprint()); UserActivityLogger::getInstance().logAction("launch", properties); From d7b3ee9bcb06fbf3df764918e1629e9bbb10327b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 24 May 2017 19:15:10 -0700 Subject: [PATCH 18/91] check for cached ATP assets in right place --- libraries/networking/src/AssetRequest.cpp | 9 +++++++-- libraries/networking/src/AssetRequest.h | 3 +++ libraries/networking/src/AssetResourceRequest.cpp | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/AssetRequest.cpp b/libraries/networking/src/AssetRequest.cpp index 920c7ae036..00fa3d9f2f 100644 --- a/libraries/networking/src/AssetRequest.cpp +++ b/libraries/networking/src/AssetRequest.cpp @@ -15,11 +15,13 @@ #include +#include +#include + #include "AssetClient.h" #include "NetworkLogging.h" #include "NodeList.h" #include "ResourceCache.h" -#include static int requestID = 0; @@ -62,9 +64,12 @@ void AssetRequest::start() { _data = loadFromCache(getUrl()); if (!_data.isNull()) { _error = NoError; - + + _loadedFromCache = true; + _state = Finished; emit finished(this); + return; } diff --git a/libraries/networking/src/AssetRequest.h b/libraries/networking/src/AssetRequest.h index b808ae0ca6..df5cf80ecd 100644 --- a/libraries/networking/src/AssetRequest.h +++ b/libraries/networking/src/AssetRequest.h @@ -52,6 +52,8 @@ public: QUrl getUrl() const { return ::getATPUrl(_hash); } QString getHash() const { return _hash; } + bool loadedFromCache() const { return _loadedFromCache; } + signals: void finished(AssetRequest* thisRequest); void progress(qint64 totalReceived, qint64 total); @@ -66,6 +68,7 @@ private: int _numPendingRequests { 0 }; MessageID _assetRequestID { INVALID_MESSAGE_ID }; const ByteRange _byteRange; + bool _loadedFromCache { false }; }; #endif diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index c0150fd3ed..f4a3b20fd5 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -156,7 +156,11 @@ void AssetResourceRequest::requestHash(const AssetHash& hash) { } auto statTracker = DependencyManager::get(); - + + if (_assetRequest->loadedFromCache()) { + _loadedFromCache = true; + } + _state = Finished; emit finished(); From 1f24e38585cca9d1d7919e803b4806569af34570 Mon Sep 17 00:00:00 2001 From: volansystech Date: Wed, 24 May 2017 21:00:40 +0530 Subject: [PATCH 19/91] Initial Commit: Switching from Desktop mode to HMD [Oculus Rift] mode automatically when the user wear Oculus Rift. --- interface/src/Application.cpp | 54 ++++++++++++++----- interface/src/Application.h | 10 ++-- .../display-plugins/OpenGLDisplayPlugin.cpp | 15 +++++- .../src/display-plugins/OpenGLDisplayPlugin.h | 6 +++ libraries/plugins/src/plugins/Plugin.h | 13 +++++ .../oculus/src/OculusBaseDisplayPlugin.cpp | 11 ++++ plugins/oculus/src/OculusBaseDisplayPlugin.h | 2 + 7 files changed, 92 insertions(+), 19 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ced5e51565..99c2b2febf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1338,11 +1338,18 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["active_display_plugin"] = getActiveDisplayPlugin()->getName(); properties["using_hmd"] = isHMDMode(); - if (isOculusRiftPluginAvailable()){ - qCDebug(interfaceapp) << "Oculus Rift Plugin is available"; - QTimer *switchModeTimer = new QTimer(this); - connect(switchModeTimer, SIGNAL(timeout()), this, SLOT(switchmode())); - switchModeTimer->start(500); + if (isOculusRiftPluginAvailable()) { + // If Oculus Rift Plugin is Available,And Current Display Plugin is not Oculus Rift + // then startOculusRiftStandBySession to listen Oculus HMD Mounted status. + if (getActiveDisplayPlugin()->getName() != "Oculus Rift" && + !oculusRiftPlugin->isFakeSessionActive()) { + startOculusRiftStandBySession(); + } + // Poll periodically to check whether the user has worn Oculus HMD or not. And switch mode + // accordingly. If the user wear HMD, switch to VR mode, if remove switch to Desktop mode. + QTimer *switchDisplayModeTimer = new QTimer(this); + connect(switchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayModeForOculus())); + switchDisplayModeTimer->start(500); } auto glInfo = getGLContextData(); @@ -1574,7 +1581,9 @@ void Application::aboutToQuit() { } getActiveDisplayPlugin()->deactivate(); - + if (oculusRiftPlugin && oculusRiftPlugin->isFakeSessionActive()){ + oculusRiftPlugin->endStandBySession(); + } // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. DependencyManager::get()->hide("RunningScripts"); @@ -6845,7 +6854,7 @@ bool Application::isOculusRiftPluginAvailable(){ auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); // Default to the first item on the list, in case none of the menu items match DisplayPluginPointer defaultplugin = displayPlugins.at(0); - if (defaultplugin->isHmd() && defaultplugin->getName() == "Oculus Rift"){ + if (defaultplugin->isHmd() && defaultplugin->getName() == "Oculus Rift") { oculusRiftPlugin = defaultplugin; return true; // No need to iterate again,so return } @@ -6854,7 +6863,7 @@ bool Application::isOculusRiftPluginAvailable(){ QString pluginname = displayPlugin->getName(); if (displayPlugin->isHmd() && pluginname == "Oculus Rift") { oculusRiftPlugin = displayPlugin; - _isDisplayVisible = displayPlugin->isDisplayVisible(); + _oculusHMDMountedStatus = displayPlugin->isDisplayVisible(); isOculusRiftPluginAvailable = true; break; } @@ -6862,15 +6871,32 @@ bool Application::isOculusRiftPluginAvailable(){ return isOculusRiftPluginAvailable; } -void Application::switchmode(){ - bool isDisplayVisible = oculusRiftPlugin->isDisplayVisible(); - if (isDisplayVisible != _isDisplayVisible){ - if (isDisplayVisible == false && _isDisplayVisible == true){ - qCDebug(interfaceapp) << "switching from HMD to desktop mode"; +void Application::switchDisplayModeForOculus(){ + bool currenthmdMountedStatus = oculusRiftPlugin->isDisplayVisible(); + if (currenthmdMountedStatus != _oculusHMDMountedStatus){ + // Switch to respective mode as soon as currenthmdMountedStatus changes + if (currenthmdMountedStatus == false && _oculusHMDMountedStatus == true) { + qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; setActiveDisplayPlugin("Desktop"); + startOculusRiftStandBySession(); + } + if (currenthmdMountedStatus == true && _oculusHMDMountedStatus == false) { + qCDebug(interfaceapp) << "Switching from Desktop to HMD mode"; + endOculusRiftStandBySession(); + setActiveDisplayPlugin("Oculus Rift"); } } - _isDisplayVisible = isDisplayVisible; // assign current status + _oculusHMDMountedStatus = currenthmdMountedStatus; +} + +bool Application::startOculusRiftStandBySession(){ + bool isStandBySessionStarted = oculusRiftPlugin->startStandBySession(); + qCDebug(interfaceapp) << "startOculusRiftStandBySession: " << isStandBySessionStarted; + return isStandBySessionStarted; +} + +void Application::endOculusRiftStandBySession(){ + oculusRiftPlugin->endStandBySession(); } mat4 Application::getEyeProjection(int eye) const { diff --git a/interface/src/Application.h b/interface/src/Application.h index c181e74c74..a6ac244dc8 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -443,7 +443,7 @@ private slots: void addAssetToWorldErrorTimeout(); void handleSandboxStatus(QNetworkReply* reply); - void switchmode(); + void switchDisplayModeForOculus(); private: static void initDisplay(); void init(); @@ -684,9 +684,13 @@ private: AudioInjector* _snapshotSoundInjector { nullptr }; SharedSoundPointer _snapshotSound; - bool isOculusRiftPluginAvailable(); + DisplayPluginPointer oculusRiftPlugin; - bool _isDisplayVisible; + + bool isOculusRiftPluginAvailable(); + bool _oculusHMDMountedStatus; // Keep track of HMD Mounted Flag + bool startOculusRiftStandBySession(); + void endOculusRiftStandBySession(); }; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 306db98b35..639acc7739 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -315,8 +315,7 @@ bool OpenGLDisplayPlugin::activate() { if (isHmd() && (getHmdScreen() >= 0)) { _container->showDisplayPluginsTools(); } - - return Parent::activate(); + return Parent::activate(); } void OpenGLDisplayPlugin::deactivate() { @@ -339,6 +338,18 @@ void OpenGLDisplayPlugin::deactivate() { Parent::deactivate(); } +bool OpenGLDisplayPlugin::startStandBySession() { + if (!activateStandBySession()) { + return false; + } + return Parent::startStandBySession(); +} + +void OpenGLDisplayPlugin::endStandBySession() { + deactivateStandBySession(); + return Parent::endStandBySession(); +} + void OpenGLDisplayPlugin::customizeContext() { auto presentThread = DependencyManager::get(); Q_ASSERT(thread() == presentThread->thread()); diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index e1eea5de6c..ecde3b3c93 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -42,6 +42,8 @@ public: // between the main thread and the presentation thread bool activate() override final; void deactivate() override final; + bool startStandBySession() override final; + void endStandBySession() override final; bool eventFilter(QObject* receiver, QEvent* event) override; bool isDisplayVisible() const override { return true; } @@ -99,6 +101,10 @@ protected: // Returns true on successful activation virtual bool internalActivate() { return true; } virtual void internalDeactivate() {} + + // Returns true on successful activation of standby session + virtual bool activateStandBySession() { return true; } + virtual void deactivateStandBySession() {} // Plugin specific functionality to send the composed scene to the output window or device virtual void internalPresent(); diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index 15588fafa4..74f04fff18 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -53,6 +53,18 @@ public: virtual bool isActive() { return _active; } + virtual bool startStandBySession(){ + _standbysessionactive = true; + return _standbysessionactive; + } + + virtual void endStandBySession(){ + _standbysessionactive = false; + } + + virtual bool isFakeSessionActive() { + return _standbysessionactive; + } /** * Called by the application during it's idle phase. If the plugin needs to do @@ -73,6 +85,7 @@ signals: protected: bool _active { false }; + bool _standbysessionactive { false }; PluginContainer* _container { nullptr }; static const char* UNKNOWN_PLUGIN_ID; diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index 26906ef2fb..28e30e0d21 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -127,6 +127,17 @@ void OculusBaseDisplayPlugin::internalDeactivate() { _session = nullptr; } +bool OculusBaseDisplayPlugin::activateStandBySession() { + _session = acquireOculusSession(); + if (!_session) { + return false; + } + return true; +} +void OculusBaseDisplayPlugin::deactivateStandBySession() { + releaseOculusSession(); + _session = nullptr; +} void OculusBaseDisplayPlugin::updatePresentPose() { //mat4 sensorResetMat; //_currentPresentFrameInfo.sensorSampleTime = ovr_GetTimeInSeconds(); diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h index e5dc75095d..79085f817b 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -33,6 +33,8 @@ protected: void uncustomizeContext() override; bool internalActivate() override; void internalDeactivate() override; + bool activateStandBySession() override; + void deactivateStandBySession() override; void updatePresentPose() override; protected: From a2851b5bcbe9db8147348e5d54543a666e2b690b Mon Sep 17 00:00:00 2001 From: volansystech Date: Thu, 25 May 2017 18:32:46 +0530 Subject: [PATCH 20/91] Put proper comments and indentation. --- interface/src/Application.cpp | 22 +++++++++---------- interface/src/Application.h | 5 ++--- .../display-plugins/OpenGLDisplayPlugin.cpp | 2 +- libraries/plugins/src/plugins/Plugin.h | 16 +++++++------- 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index fda9b7b8f9..a40f31a8bb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1339,14 +1339,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["using_hmd"] = isHMDMode(); if (isOculusRiftPluginAvailable()) { - // If Oculus Rift Plugin is Available,And Current Display Plugin is not Oculus Rift + // If Oculus Rift Plugin is available and current display plugin is not Oculus Rift // then startOculusRiftStandBySession to listen Oculus HMD Mounted status. if (getActiveDisplayPlugin()->getName() != "Oculus Rift" && - !oculusRiftPlugin->isFakeSessionActive()) { + !oculusRiftPlugin->isStandBySessionActive()) { startOculusRiftStandBySession(); } - // Poll periodically to check whether the user has worn Oculus HMD or not. And switch mode - // accordingly. If the user wear HMD, switch to VR mode, if remove switch to Desktop mode. + // Poll periodically to check whether the user has worn Oculus HMD or not. And switch Display mode accordingly. + // If the user wear Oculus HMD then switch to VR mode. If the user removes Oculus HMD then switch to Desktop mode. QTimer *switchDisplayModeTimer = new QTimer(this); connect(switchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayModeForOculus())); switchDisplayModeTimer->start(500); @@ -1581,7 +1581,7 @@ void Application::aboutToQuit() { } getActiveDisplayPlugin()->deactivate(); - if (oculusRiftPlugin && oculusRiftPlugin->isFakeSessionActive()){ + if (oculusRiftPlugin && oculusRiftPlugin->isStandBySessionActive()) { oculusRiftPlugin->endStandBySession(); } // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. @@ -6846,14 +6846,14 @@ void Application::updateDisplayMode() { Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin"); } -bool Application::isOculusRiftPluginAvailable(){ +bool Application::isOculusRiftPluginAvailable() { bool isOculusRiftPluginAvailable = false; auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); // Default to the first item on the list, in case none of the menu items match DisplayPluginPointer defaultplugin = displayPlugins.at(0); if (defaultplugin->isHmd() && defaultplugin->getName() == "Oculus Rift") { oculusRiftPlugin = defaultplugin; - return true; // No need to iterate again,so return + return true; } // Iterate to check If Oculus Rift Plugin is available foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { @@ -6868,9 +6868,9 @@ bool Application::isOculusRiftPluginAvailable(){ return isOculusRiftPluginAvailable; } -void Application::switchDisplayModeForOculus(){ +void Application::switchDisplayModeForOculus() { bool currenthmdMountedStatus = oculusRiftPlugin->isDisplayVisible(); - if (currenthmdMountedStatus != _oculusHMDMountedStatus){ + if (currenthmdMountedStatus != _oculusHMDMountedStatus) { // Switch to respective mode as soon as currenthmdMountedStatus changes if (currenthmdMountedStatus == false && _oculusHMDMountedStatus == true) { qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; @@ -6886,13 +6886,13 @@ void Application::switchDisplayModeForOculus(){ _oculusHMDMountedStatus = currenthmdMountedStatus; } -bool Application::startOculusRiftStandBySession(){ +bool Application::startOculusRiftStandBySession() { bool isStandBySessionStarted = oculusRiftPlugin->startStandBySession(); qCDebug(interfaceapp) << "startOculusRiftStandBySession: " << isStandBySessionStarted; return isStandBySessionStarted; } -void Application::endOculusRiftStandBySession(){ +void Application::endOculusRiftStandBySession() { oculusRiftPlugin->endStandBySession(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 6b172cdb9e..112b650160 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -152,7 +152,7 @@ public: void paintGL(); void resizeGL(); - bool event(QEvent* event) override; + bool event(QEvent* event) override; bool eventFilter(QObject* object, QEvent* event) override; glm::uvec2 getCanvasSize() const; @@ -685,9 +685,8 @@ private: DisplayPluginPointer oculusRiftPlugin; - bool isOculusRiftPluginAvailable(); - bool _oculusHMDMountedStatus; // Keep track of HMD Mounted Flag + bool _oculusHMDMountedStatus; // Keep track of Oculus Rift HMDMounted Flag bool startOculusRiftStandBySession(); void endOculusRiftStandBySession(); }; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 96d3d8114c..cebe844b84 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -315,7 +315,7 @@ bool OpenGLDisplayPlugin::activate() { if (isHmd() && (getHmdScreen() >= 0)) { _container->showDisplayPluginsTools(); } - return Parent::activate(); + return Parent::activate(); } void OpenGLDisplayPlugin::deactivate() { diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index 74f04fff18..045a9eee15 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -53,17 +53,17 @@ public: virtual bool isActive() { return _active; } - virtual bool startStandBySession(){ - _standbysessionactive = true; - return _standbysessionactive; + virtual bool startStandBySession() { + _standbysessionstatus = true; + return _standbysessionstatus; } - virtual void endStandBySession(){ - _standbysessionactive = false; + virtual void endStandBySession() { + _standbysessionstatus = false; } - virtual bool isFakeSessionActive() { - return _standbysessionactive; + virtual bool isStandBySessionActive() { + return _standbysessionstatus; } /** @@ -85,7 +85,7 @@ signals: protected: bool _active { false }; - bool _standbysessionactive { false }; + bool _standbysessionstatus { false }; PluginContainer* _container { nullptr }; static const char* UNKNOWN_PLUGIN_ID; From bdbc6ddcc13eff1c8f28ee298d0f2afc807f9298 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 25 May 2017 10:50:41 -0700 Subject: [PATCH 21/91] change some code to look at head-controller position rather than hmd position --- interface/src/Application.cpp | 4 +- interface/src/avatar/MyAvatar.cpp | 55 ++++++++----------- interface/src/avatar/MyAvatar.h | 11 ++-- interface/src/avatar/MySkeletonModel.cpp | 2 +- .../src/scripting/HMDScriptingInterface.cpp | 2 +- libraries/controllers/src/controllers/Pose.h | 4 ++ 6 files changed, 39 insertions(+), 39 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ae490c05e7..7926905273 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3953,6 +3953,7 @@ void Application::updateMyAvatarLookAtPosition() { lookAtPosition.x = -lookAtPosition.x; } if (isHMD) { + // TODO -- this code is probably wrong, getHeadPose() returns something in sensor frame, not avatar glm::mat4 headPose = getActiveDisplayPlugin()->getHeadPose(); glm::quat hmdRotation = glm::quat_cast(headPose); lookAtSpot = _myCamera.getPosition() + myAvatar->getOrientation() * (hmdRotation * lookAtPosition); @@ -3995,7 +3996,8 @@ void Application::updateMyAvatarLookAtPosition() { } else { // I am not looking at anyone else, so just look forward if (isHMD) { - glm::mat4 worldHMDMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + glm::mat4 worldHMDMat = myAvatar->getSensorToWorldMatrix() * + (glm::mat4)myAvatar->getHeadControllerPoseInSensorFrame(); lookAtSpot = transformPoint(worldHMDMat, glm::vec3(0.0f, 0.0f, -TREE_SCALE)); } else { lookAtSpot = myAvatar->getHead()->getEyePosition() + diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index b4e418b6a2..4bb9a2ef5f 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -401,7 +401,7 @@ void MyAvatar::update(float deltaTime) { // update moving average of HMD facing in xz plane. const float HMD_FACING_TIMESCALE = 4.0f; // very slow average float tau = deltaTime / HMD_FACING_TIMESCALE; - _hmdSensorFacingMovingAverage = lerp(_hmdSensorFacingMovingAverage, _hmdSensorFacing, tau); + _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, _headControllerFacing, tau); if (_smoothOrientationTimer < SMOOTH_TIME_ORIENTATION) { _rotationChanged = usecTimestampNow(); @@ -409,16 +409,18 @@ void MyAvatar::update(float deltaTime) { } #ifdef DEBUG_DRAW_HMD_MOVING_AVERAGE - glm::vec3 p = transformPoint(getSensorToWorldMatrix(), _hmdSensorPosition + glm::vec3(_hmdSensorFacingMovingAverage.x, 0.0f, _hmdSensorFacingMovingAverage.y)); + glm::vec3 p = transformPoint(getSensorToWorldMatrix(), getHeadControllerPoseInAvatarFrame() + + glm::vec3(_headControllerFacingMovingAverage.x, 0.0f, _headControllerFacingMovingAverage.y)); DebugDraw::getInstance().addMarker("facing-avg", getOrientation(), p, glm::vec4(1.0f)); - p = transformPoint(getSensorToWorldMatrix(), _hmdSensorPosition + glm::vec3(_hmdSensorFacing.x, 0.0f, _hmdSensorFacing.y)); + p = transformPoint(getSensorToWorldMatrix(), getHMDSensorPosition() + + glm::vec3(_headControllerFacing.x, 0.0f, _headControllerFacing.y)); DebugDraw::getInstance().addMarker("facing", getOrientation(), p, glm::vec4(1.0f)); #endif if (_goToPending) { setPosition(_goToPosition); setOrientation(_goToOrientation); - _hmdSensorFacingMovingAverage = _hmdSensorFacing; // reset moving average + _headControllerFacingMovingAverage = _headControllerFacing; // reset moving average _goToPending = false; // updateFromHMDSensorMatrix (called from paintGL) expects that the sensorToWorldMatrix is updated for any position changes // that happen between render and Application::update (which calls updateSensorToWorldMatrix to do so). @@ -625,7 +627,7 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { _hmdSensorMatrix = hmdSensorMatrix; auto newHmdSensorPosition = extractTranslation(hmdSensorMatrix); - if (newHmdSensorPosition != _hmdSensorPosition && + if (newHmdSensorPosition != getHMDSensorPosition() && glm::length(newHmdSensorPosition) > MAX_HMD_ORIGIN_DISTANCE) { qWarning() << "Invalid HMD sensor position " << newHmdSensorPosition; // Ignore unreasonable HMD sensor data @@ -633,7 +635,7 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { } _hmdSensorPosition = newHmdSensorPosition; _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); - _hmdSensorFacing = getFacingDir2D(_hmdSensorOrientation); + _headControllerFacing = getFacingDir2D(_headControllerPoseInSensorFrameCache.get().rotation); } void MyAvatar::updateJointFromController(controller::Action poseKey, ThreadSafeValueCache& matrixCache) { @@ -671,7 +673,7 @@ void MyAvatar::updateSensorToWorldMatrix() { // Update avatar head rotation with sensor data void MyAvatar::updateFromTrackers(float deltaTime) { - glm::vec3 estimatedPosition, estimatedRotation; + glm::vec3 estimatedRotation; bool inHmd = qApp->isHMDMode(); bool playing = DependencyManager::get()->isPlaying(); @@ -682,11 +684,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) { FaceTracker* tracker = qApp->getActiveFaceTracker(); bool inFacetracker = tracker && !FaceTracker::isMuted(); - if (inHmd) { - estimatedPosition = extractTranslation(getHMDSensorMatrix()); - estimatedPosition.x *= -1.0f; - } else if (inFacetracker) { - estimatedPosition = tracker->getHeadTranslation(); + if (inFacetracker) { estimatedRotation = glm::degrees(safeEulerAngles(tracker->getHeadRotation())); } @@ -1884,20 +1882,14 @@ void MyAvatar::updateOrientation(float deltaTime) { getHead()->setBasePitch(getHead()->getBasePitch() + getDriveKey(PITCH) * _pitchSpeed * deltaTime); - if (qApp->isHMDMode()) { - glm::quat orientation = glm::quat_cast(getSensorToWorldMatrix()) * getHMDSensorOrientation(); - glm::quat bodyOrientation = getWorldBodyOrientation(); - glm::quat localOrientation = glm::inverse(bodyOrientation) * orientation; - - // these angles will be in radians - // ... so they need to be converted to degrees before we do math... - glm::vec3 euler = glm::eulerAngles(localOrientation) * DEGREES_PER_RADIAN; - - Head* head = getHead(); - head->setBaseYaw(YAW(euler)); - head->setBasePitch(PITCH(euler)); - head->setBaseRoll(ROLL(euler)); - } + glm::quat localOrientation = getHeadControllerPoseInAvatarFrame(); + // these angles will be in radians + // ... so they need to be converted to degrees before we do math... + glm::vec3 euler = glm::eulerAngles(localOrientation) * DEGREES_PER_RADIAN; + Head* head = getHead(); + head->setBaseYaw(YAW(euler)); + head->setBasePitch(PITCH(euler)); + head->setBaseRoll(ROLL(euler)); } void MyAvatar::updateActionMotor(float deltaTime) { @@ -2332,8 +2324,8 @@ glm::quat MyAvatar::getWorldBodyOrientation() const { glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { // HMD is in sensor space. - const glm::vec3 hmdPosition = getHMDSensorPosition(); - const glm::quat hmdOrientation = getHMDSensorOrientation(); + const glm::vec3 hmdPosition = getHeadControllerPoseInSensorFrame(); + const glm::quat hmdOrientation = getHeadControllerPoseInSensorFrame(); const glm::quat hmdOrientationYawOnly = cancelOutRollAndPitch(hmdOrientation); const Rig& rig = _skeletonModel->getRig(); @@ -2478,7 +2470,7 @@ bool MyAvatar::FollowHelper::shouldActivateRotation(const MyAvatar& myAvatar, co } else { const float FOLLOW_ROTATION_THRESHOLD = cosf(PI / 6.0f); // 30 degrees glm::vec2 bodyFacing = getFacingDir2D(currentBodyMatrix); - return glm::dot(myAvatar.getHMDSensorFacingMovingAverage(), bodyFacing) < FOLLOW_ROTATION_THRESHOLD; + return glm::dot(myAvatar.getHeadControllerFacingMovingAverage(), bodyFacing) < FOLLOW_ROTATION_THRESHOLD; } } @@ -2625,9 +2617,10 @@ glm::mat4 MyAvatar::computeCameraRelativeHandControllerMatrix(const glm::mat4& c cameraWorldMatrix *= createMatFromScaleQuatAndPos(vec3(-1.0f, 1.0f, 1.0f), glm::quat(), glm::vec3()); } - // compute a NEW sensorToWorldMatrix for the camera. The equation is cameraWorldMatrix = cameraSensorToWorldMatrix * _hmdSensorMatrix. + // compute a NEW sensorToWorldMatrix for the camera. + // The equation is cameraWorldMatrix = cameraSensorToWorldMatrix * _hmdSensorMatrix. // here we solve for the unknown cameraSensorToWorldMatrix. - glm::mat4 cameraSensorToWorldMatrix = cameraWorldMatrix * glm::inverse(_hmdSensorMatrix); + glm::mat4 cameraSensorToWorldMatrix = cameraWorldMatrix * glm::inverse(getHMDSensorMatrix()); // Using the new cameraSensorToWorldMatrix, compute where the controller is in world space. glm::mat4 controllerWorldMatrix = cameraSensorToWorldMatrix * controllerSensorMatrix; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index fde350a43e..05615a600d 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -185,7 +185,6 @@ public: const glm::mat4& getHMDSensorMatrix() const { return _hmdSensorMatrix; } const glm::vec3& getHMDSensorPosition() const { return _hmdSensorPosition; } const glm::quat& getHMDSensorOrientation() const { return _hmdSensorOrientation; } - const glm::vec2& getHMDSensorFacingMovingAverage() const { return _hmdSensorFacingMovingAverage; } Q_INVOKABLE void setOrientationVar(const QVariant& newOrientationVar); Q_INVOKABLE QVariant getOrientationVar() const; @@ -470,6 +469,8 @@ public: controller::Pose getHeadControllerPoseInSensorFrame() const; controller::Pose getHeadControllerPoseInWorldFrame() const; controller::Pose getHeadControllerPoseInAvatarFrame() const; + const glm::vec2& getHeadControllerFacingMovingAverage() const { return _headControllerFacingMovingAverage; } + bool hasDriveInput() const; @@ -664,13 +665,13 @@ private: // working copies -- see AvatarData for thread-safe _sensorToWorldMatrixCache, used for outward facing access glm::mat4 _sensorToWorldMatrix { glm::mat4() }; - // cache of the current HMD sensor position and orientation - // in sensor space. + // cache of the current HMD sensor position and orientation in sensor space. glm::mat4 _hmdSensorMatrix; glm::quat _hmdSensorOrientation; glm::vec3 _hmdSensorPosition; - glm::vec2 _hmdSensorFacing; // facing vector in xz plane - glm::vec2 _hmdSensorFacingMovingAverage { 0, 0 }; // facing vector in xz plane + // cache head controller pose in sensor space + glm::vec2 _headControllerFacing; // facing vector in xz plane + glm::vec2 _headControllerFacingMovingAverage { 0, 0 }; // facing vector in xz plane // cache of the current body position and orientation of the avatar's body, // in sensor space. diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 828a5f8a01..a98055ad35 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -59,7 +59,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { } else { if (qApp->isHMDMode()) { // get HMD position from sensor space into world space, and back into rig space - glm::mat4 worldHMDMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + glm::mat4 worldHMDMat = myAvatar->getHeadControllerPoseInWorldFrame(); glm::mat4 rigToWorld = createMatFromQuatAndPos(getRotation(), getTranslation()); glm::mat4 worldToRig = glm::inverse(rigToWorld); glm::mat4 rigHMDMat = worldToRig * worldHMDMat; diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index 95bf5eb028..d0e8e74d85 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -118,7 +118,7 @@ bool HMDScriptingInterface::getHUDLookAtPosition3D(glm::vec3& result) const { glm::mat4 HMDScriptingInterface::getWorldHMDMatrix() const { auto myAvatar = DependencyManager::get()->getMyAvatar(); - return myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + return myAvatar->getSensorToWorldMatrix() * (glm::mat4)myAvatar->getHeadControllerPoseInSensorFrame(); } glm::vec3 HMDScriptingInterface::getPosition() const { diff --git a/libraries/controllers/src/controllers/Pose.h b/libraries/controllers/src/controllers/Pose.h index a6d1360f9f..10cb65a421 100644 --- a/libraries/controllers/src/controllers/Pose.h +++ b/libraries/controllers/src/controllers/Pose.h @@ -43,6 +43,10 @@ namespace controller { Pose transform(const glm::mat4& mat) const; Pose postTransform(const glm::mat4& mat) const; + operator glm::mat4() const { return createMatFromQuatAndPos(rotation, translation); } + operator glm::quat() const { return rotation; } + operator glm::vec3() const { return translation; } + static QScriptValue toScriptValue(QScriptEngine* engine, const Pose& event); static void fromScriptValue(const QScriptValue& object, Pose& event); }; From af5ba3a90af049f116bd0f2a07a6a94b610a69e2 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 25 May 2017 15:14:10 -0700 Subject: [PATCH 22/91] ask display-plugins if they are head-controllers --- .../resources/controllers/oculus_touch.json | 2 ++ interface/src/Application.cpp | 15 +++++++++++++++ interface/src/Application.h | 1 + interface/src/avatar/MyAvatar.cpp | 18 ++++++++++-------- .../src/scripting/HMDScriptingInterface.cpp | 4 ++++ .../src/scripting/HMDScriptingInterface.h | 1 + .../impl/filters/LowVelocityFilter.h | 2 +- .../Basic2DWindowOpenGLDisplayPlugin.h | 2 ++ .../hmd/DebugHmdDisplayPlugin.h | 1 + .../src/display-plugins/hmd/HmdDisplayPlugin.h | 1 + .../stereo/InterleavedStereoDisplayPlugin.h | 2 ++ .../stereo/SideBySideStereoDisplayPlugin.h | 2 ++ .../src/input-plugins/KeyboardMouseDevice.h | 1 + .../src/input-plugins/TouchscreenDevice.h | 1 + libraries/plugins/src/plugins/DisplayPlugin.h | 1 + libraries/plugins/src/plugins/InputPlugin.h | 1 + libraries/plugins/src/plugins/PluginUtils.cpp | 14 ++++++++++++++ libraries/plugins/src/plugins/PluginUtils.h | 1 + plugins/hifiKinect/src/KinectPlugin.cpp | 16 ++++++++++++++-- plugins/hifiKinect/src/KinectPlugin.h | 1 + plugins/hifiNeuron/src/NeuronPlugin.h | 1 + plugins/hifiSdl2/src/SDL2Manager.h | 1 + plugins/hifiSixense/src/SixenseManager.h | 1 + plugins/oculus/src/OculusControllerManager.h | 1 + plugins/oculus/src/OculusDisplayPlugin.h | 2 ++ plugins/openvr/src/OpenVrDisplayPlugin.h | 4 +++- plugins/openvr/src/ViveControllerManager.h | 1 + 27 files changed, 86 insertions(+), 12 deletions(-) diff --git a/interface/resources/controllers/oculus_touch.json b/interface/resources/controllers/oculus_touch.json index aa574e36dd..544c8bd5b8 100644 --- a/interface/resources/controllers/oculus_touch.json +++ b/interface/resources/controllers/oculus_touch.json @@ -58,5 +58,7 @@ { "from": "OculusTouch.RightThumbUp", "to": "Standard.RightThumbUp" }, { "from": "OculusTouch.LeftIndexPoint", "to": "Standard.LeftIndexPoint" }, { "from": "OculusTouch.RightIndexPoint", "to": "Standard.RightIndexPoint" } + + { "from": "OculusTouch.Head", "to" : "Standard.Head", "when" : [ "Application.InHMD"] } ] } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8761268147..6eb3aedef6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4851,6 +4851,21 @@ bool Application::isHMDMode() const { return getActiveDisplayPlugin()->isHmd(); } +bool Application::isHeadControllerEnabled() const { + const InputPluginList& inputPlugins = PluginManager::getInstance()->getInputPlugins(); + for (auto& ip : inputPlugins) { + if (ip->isActive() && ip->isHeadController()) { + return true; + } + } + foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { + if (displayPlugin->isActive() && displayPlugin->isHeadController()) { + return true; + } + } + return false; +} + float Application::getTargetFrameRate() const { return getActiveDisplayPlugin()->getTargetFrameRate(); } QRect Application::getDesirableApplicationGeometry() const { diff --git a/interface/src/Application.h b/interface/src/Application.h index e8507c39e8..aaf56ef0c2 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -248,6 +248,7 @@ public: // rendering of several elements depend on that // TODO: carry that information on the Camera as a setting virtual bool isHMDMode() const override; + bool isHeadControllerEnabled() const; glm::mat4 getHMDSensorPose() const; glm::mat4 getEyeOffset(int eye) const; glm::mat4 getEyeProjection(int eye) const; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6cf6ef2fee..2f97cee0be 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1845,14 +1845,16 @@ void MyAvatar::updateOrientation(float deltaTime) { getHead()->setBasePitch(getHead()->getBasePitch() + getDriveKey(PITCH) * _pitchSpeed * deltaTime); - glm::quat localOrientation = getHeadControllerPoseInAvatarFrame(); - // these angles will be in radians - // ... so they need to be converted to degrees before we do math... - glm::vec3 euler = glm::eulerAngles(localOrientation) * DEGREES_PER_RADIAN; - Head* head = getHead(); - head->setBaseYaw(YAW(euler)); - head->setBasePitch(PITCH(euler)); - head->setBaseRoll(ROLL(euler)); + if (qApp->isHeadControllerEnabled()) { + glm::quat localOrientation = getHeadControllerPoseInAvatarFrame(); + // these angles will be in radians + // ... so they need to be converted to degrees before we do math... + glm::vec3 euler = glm::eulerAngles(localOrientation) * DEGREES_PER_RADIAN; + Head* head = getHead(); + head->setBaseYaw(YAW(euler)); + head->setBasePitch(PITCH(euler)); + head->setBaseRoll(ROLL(euler)); + } } void MyAvatar::updateActionMotor(float deltaTime) { diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index d0e8e74d85..d347b72d7b 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -54,6 +54,10 @@ bool HMDScriptingInterface::isHMDAvailable(const QString& name) { return PluginUtils::isHMDAvailable(name); } +bool HMDScriptingInterface::isHeadControllerAvailable(const QString& name) { + return PluginUtils::isHeadControllerAvailable(name); +} + bool HMDScriptingInterface::isHandControllerAvailable(const QString& name) { return PluginUtils::isHandControllerAvailable(name); } diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 7ecafdcbcb..4657e61d05 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -43,6 +43,7 @@ public: Q_INVOKABLE QString preferredAudioOutput() const; Q_INVOKABLE bool isHMDAvailable(const QString& name = ""); + Q_INVOKABLE bool isHeadControllerAvailable(const QString& name = ""); Q_INVOKABLE bool isHandControllerAvailable(const QString& name = ""); Q_INVOKABLE bool isSubdeviceContainingNameAvailable(const QString& name); diff --git a/libraries/controllers/src/controllers/impl/filters/LowVelocityFilter.h b/libraries/controllers/src/controllers/impl/filters/LowVelocityFilter.h index d870a5c551..feaf7685fd 100644 --- a/libraries/controllers/src/controllers/impl/filters/LowVelocityFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/LowVelocityFilter.h @@ -22,7 +22,7 @@ namespace controller { _translationConstant(translationConstant), _rotationConstant(rotationConstant) {} virtual float apply(float value) const override { return value; } - virtual Pose apply(Pose newPose) const; + virtual Pose apply(Pose newPose) const override; virtual bool parseParameters(const QJsonValue& parameters) override; private: diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h index f3dd50602c..8dc1d83c1b 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h @@ -26,6 +26,8 @@ public: virtual bool isThrottled() const override; + virtual bool isHeadController() const override { return false; } + protected: mutable bool _isThrottled = false; diff --git a/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h index 9bb82b1836..a971c25bf6 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h @@ -21,6 +21,7 @@ public: bool beginFrameRender(uint32_t frameIndex) override; float getTargetFrameRate() const override { return 90; } + virtual bool isHeadController() const override { return false; } protected: void updatePresentPose() override; diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h index aaa6e347e0..7dfd0fed1e 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h @@ -25,6 +25,7 @@ class HmdDisplayPlugin : public OpenGLDisplayPlugin { public: ~HmdDisplayPlugin(); bool isHmd() const override final { return true; } + bool isHeadController() const override = 0; float getIPD() const override final { return _ipd; } glm::mat4 getEyeToHeadTransform(Eye eye) const override final { return _eyeOffsets[eye]; } glm::mat4 getEyeProjection(Eye eye, const glm::mat4& baseProjection) const override final { return _eyeProjections[eye]; } diff --git a/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h index debd340f24..4834e6c542 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h @@ -17,6 +17,8 @@ public: grouping getGrouping() const override { return ADVANCED; } glm::uvec2 getRecommendedRenderSize() const override; + virtual bool isHeadController() const override { return false; } + protected: // initialize OpenGL context settings needed by the plugin void customizeContext() override; diff --git a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.h index 79bf2a9ecb..aa65fc37e3 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.h @@ -19,6 +19,8 @@ public: virtual grouping getGrouping() const override { return ADVANCED; } virtual glm::uvec2 getRecommendedRenderSize() const override; + virtual bool isHeadController() const override { return false; } + private: static const QString NAME; }; diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h index 3570ec7193..a0e216c904 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h @@ -71,6 +71,7 @@ public: const QString getName() const override { return NAME; } bool isHandController() const override { return false; } + bool isHeadController() const override { return false; } void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h index 65e771e8f0..926f9dbdca 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h @@ -40,6 +40,7 @@ public: virtual const QString getName() const override { return NAME; } bool isHandController() const override { return false; } + bool isHeadController() const override { return false; } virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 754c919fd4..549387b6a4 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -135,6 +135,7 @@ public: virtual int getRequiredThreadCount() const { return 0; } virtual bool isHmd() const { return false; } + virtual bool isHeadController() const = 0; virtual int getHmdScreen() const { return -1; } /// By default, all HMDs are stereo virtual bool isStereo() const { return isHmd(); } diff --git a/libraries/plugins/src/plugins/InputPlugin.h b/libraries/plugins/src/plugins/InputPlugin.h index 0db0b24420..0519ed776d 100644 --- a/libraries/plugins/src/plugins/InputPlugin.h +++ b/libraries/plugins/src/plugins/InputPlugin.h @@ -25,5 +25,6 @@ public: // If an input plugin is only a single device, it will only return it's primary name. virtual QStringList getSubdeviceNames() { return { getName() }; }; virtual bool isHandController() const = 0; + virtual bool isHeadController() const = 0; }; diff --git a/libraries/plugins/src/plugins/PluginUtils.cpp b/libraries/plugins/src/plugins/PluginUtils.cpp index 20dc011f25..4af77156e7 100644 --- a/libraries/plugins/src/plugins/PluginUtils.cpp +++ b/libraries/plugins/src/plugins/PluginUtils.cpp @@ -24,6 +24,20 @@ bool PluginUtils::isHMDAvailable(const QString& pluginName) { return false; } +bool PluginUtils::isHeadControllerAvailable(const QString& pluginName) { + for (auto& inputPlugin : PluginManager::getInstance()->getInputPlugins()) { + if (inputPlugin->isHeadController() && (pluginName.isEmpty() || inputPlugin->getName() == pluginName)) { + return true; + } + } + for (auto& displayPlugin : PluginManager::getInstance()->getDisplayPlugins()) { + if (displayPlugin->isHeadController() && (pluginName.isEmpty() || displayPlugin->getName() == pluginName)) { + return true; + } + } + return false; +}; + bool PluginUtils::isHandControllerAvailable(const QString& pluginName) { for (auto& inputPlugin : PluginManager::getInstance()->getInputPlugins()) { if (inputPlugin->isHandController() && (pluginName.isEmpty() || inputPlugin->getName() == pluginName)) { diff --git a/libraries/plugins/src/plugins/PluginUtils.h b/libraries/plugins/src/plugins/PluginUtils.h index 351c9e7e58..2b6206fe63 100644 --- a/libraries/plugins/src/plugins/PluginUtils.h +++ b/libraries/plugins/src/plugins/PluginUtils.h @@ -16,6 +16,7 @@ class PluginUtils { public: static bool isHMDAvailable(const QString& pluginName = ""); static bool isHandControllerAvailable(const QString& pluginName = ""); + static bool isHeadControllerAvailable(const QString& pluginName = ""); static bool isSubdeviceContainingNameAvailable(QString name); static bool isViveControllerAvailable(); static bool isOculusTouchControllerAvailable(); diff --git a/plugins/hifiKinect/src/KinectPlugin.cpp b/plugins/hifiKinect/src/KinectPlugin.cpp index 3a36be0982..834ee1ea2e 100644 --- a/plugins/hifiKinect/src/KinectPlugin.cpp +++ b/plugins/hifiKinect/src/KinectPlugin.cpp @@ -273,7 +273,19 @@ bool KinectPlugin::activate() { return false; } -bool KinectPlugin::isHandController() const { +bool KinectPlugin::isHandController() const { + bool sensorAvailable = false; +#ifdef HAVE_KINECT + if (_kinectSensor) { + BOOLEAN sensorIsAvailable = FALSE; + HRESULT hr = _kinectSensor->get_IsAvailable(&sensorIsAvailable); + sensorAvailable = SUCCEEDED(hr) && (sensorIsAvailable == TRUE); + } +#endif + return _enabled && _initialized && sensorAvailable; +} + +bool KinectPlugin::isHeadController() const { bool sensorAvailable = false; #ifdef HAVE_KINECT if (_kinectSensor) { @@ -654,4 +666,4 @@ void KinectPlugin::InputDevice::clearState() { int poseIndex = KinectJointIndexToPoseIndex((KinectJointIndex)i); _poseStateMap[poseIndex] = controller::Pose(); } -} \ No newline at end of file +} diff --git a/plugins/hifiKinect/src/KinectPlugin.h b/plugins/hifiKinect/src/KinectPlugin.h index 158e66ee62..e8f0745200 100644 --- a/plugins/hifiKinect/src/KinectPlugin.h +++ b/plugins/hifiKinect/src/KinectPlugin.h @@ -43,6 +43,7 @@ class KinectPlugin : public InputPlugin { Q_OBJECT public: bool isHandController() const override; + bool isHeadController() const override; // Plugin functions virtual void init() override; diff --git a/plugins/hifiNeuron/src/NeuronPlugin.h b/plugins/hifiNeuron/src/NeuronPlugin.h index 43b27d14dd..41c2322465 100644 --- a/plugins/hifiNeuron/src/NeuronPlugin.h +++ b/plugins/hifiNeuron/src/NeuronPlugin.h @@ -26,6 +26,7 @@ public: friend void FrameDataReceivedCallback(void* context, void* sender, _BvhDataHeaderEx* header, float* data); bool isHandController() const override { return false; } + bool isHeadController() const override { return false; } // Plugin functions virtual void init() override; diff --git a/plugins/hifiSdl2/src/SDL2Manager.h b/plugins/hifiSdl2/src/SDL2Manager.h index 4501d0792b..d2bbe8265e 100644 --- a/plugins/hifiSdl2/src/SDL2Manager.h +++ b/plugins/hifiSdl2/src/SDL2Manager.h @@ -28,6 +28,7 @@ public: QStringList getSubdeviceNames() override; bool isHandController() const override { return false; } + bool isHeadController() const override { return false; } void init() override; void deinit() override; diff --git a/plugins/hifiSixense/src/SixenseManager.h b/plugins/hifiSixense/src/SixenseManager.h index 5237dba791..889f6c3bad 100644 --- a/plugins/hifiSixense/src/SixenseManager.h +++ b/plugins/hifiSixense/src/SixenseManager.h @@ -34,6 +34,7 @@ public: // Sixense always seems to initialize even if the hydras are not present. Is there // a way we can properly detect whether the hydras are present? bool isHandController() const override { return false; } + bool isHeadController() const override { return false; } virtual bool activate() override; virtual void deactivate() override; diff --git a/plugins/oculus/src/OculusControllerManager.h b/plugins/oculus/src/OculusControllerManager.h index 11d699ca8e..77b40d3764 100644 --- a/plugins/oculus/src/OculusControllerManager.h +++ b/plugins/oculus/src/OculusControllerManager.h @@ -28,6 +28,7 @@ public: const QString getName() const override { return NAME; } bool isHandController() const override { return _touch != nullptr; } + bool isHeadController() const override { return true; } QStringList getSubdeviceNames() override; bool activate() override; diff --git a/plugins/oculus/src/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h index 9209fd373e..a4978a984e 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.h +++ b/plugins/oculus/src/OculusDisplayPlugin.h @@ -24,6 +24,8 @@ public: virtual QJsonObject getHardwareStats() const; + bool isHeadController() const override { return true; } + protected: QThread::Priority getPresentPriority() override { return QThread::TimeCriticalPriority; } diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h index a60c21a606..9856c27c50 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.h +++ b/plugins/openvr/src/OpenVrDisplayPlugin.h @@ -56,7 +56,9 @@ public: bool isKeyboardVisible() override; // Possibly needs an additional thread for VR submission - int getRequiredThreadCount() const override; + int getRequiredThreadCount() const override; + + bool isHeadController() const override { return true; } protected: bool internalActivate() override; diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index fa2566da45..d147573d7c 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -39,6 +39,7 @@ public: const QString getName() const override { return NAME; } bool isHandController() const override { return true; } + bool isHeadController() const override { return true; } bool activate() override; void deactivate() override; From 64191ee20ac4eac47943232c961ff50fb8eabe64 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 23 May 2017 10:11:16 -0700 Subject: [PATCH 23/91] Make the changes - big thanks to Andrew! --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 9 ++++++--- libraries/entities/src/EntityItemProperties.cpp | 7 ++++++- libraries/entities/src/EntityItemProperties.h | 1 + libraries/entities/src/EntityScriptingInterface.cpp | 10 ++++++---- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 09308baabb..d62181c651 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -1091,15 +1091,18 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons // trigger scripted collision sounds and events for locally owned objects EntityItemPointer entityA = entityTree->findEntityByEntityItemID(idA); - if ((bool)entityA && myNodeID == entityA->getSimulatorID()) { + EntityItemPointer entityB = entityTree->findEntityByEntityItemID(idB); + QUuid entityASimulatorID = entityA->getSimulatorID(); + QUuid entityBSimulatorID = entityB->getSimulatorID(); + if ((bool)entityA && (myNodeID == entityASimulatorID || ((bool)entityB && myNodeID == entityBSimulatorID && entityASimulatorID.isNull()))) { playEntityCollisionSound(entityA, collision); emit collisionWithEntity(idA, idB, collision); if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); } } - EntityItemPointer entityB = entityTree->findEntityByEntityItemID(idB); - if ((bool)entityB && myNodeID == entityB->getSimulatorID()) { + + if ((bool)entityB && (myNodeID == entityBSimulatorID || ((bool)entityA && myNodeID == entityASimulatorID && entityBSimulatorID.isNull()))) { playEntityCollisionSound(entityB, collision); // since we're swapping A and B we need to send the inverted collision Collision invertedCollision(collision); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 1ed020e592..4595ebf70d 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1824,10 +1824,15 @@ bool EntityItemProperties::hasTerseUpdateChanges() const { return _positionChanged || _velocityChanged || _rotationChanged || _angularVelocityChanged || _accelerationChanged; } +bool EntityItemProperties::hasDynamicPhysicsChanges() const { + return _dynamicChanged || _velocityChanged || _angularVelocityChanged || _accelerationChanged; +} + bool EntityItemProperties::hasMiscPhysicsChanges() const { return _gravityChanged || _dimensionsChanged || _densityChanged || _frictionChanged || _restitutionChanged || _dampingChanged || _angularDampingChanged || _registrationPointChanged || - _compoundShapeURLChanged || _dynamicChanged || _collisionlessChanged || _collisionMaskChanged; + _compoundShapeURLChanged || _collisionlessChanged || _collisionMaskChanged || + _rotationChanged || _positionChanged; } void EntityItemProperties::clearSimulationOwner() { diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 590298e102..697c634c67 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -274,6 +274,7 @@ public: void setCreated(QDateTime& v); bool hasTerseUpdateChanges() const; + bool hasDynamicPhysicsChanges() const; bool hasMiscPhysicsChanges() const; void clearSimulationOwner(); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index b184d648da..367343cb60 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -414,15 +414,17 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& entityFound = true; // make sure the properties has a type, so that the encode can know which properties to include properties.setType(entity->getType()); - bool hasTerseUpdateChanges = properties.hasTerseUpdateChanges(); - bool hasPhysicsChanges = properties.hasMiscPhysicsChanges() || hasTerseUpdateChanges; - if (_bidOnSimulationOwnership && hasPhysicsChanges) { + bool hasMiscPhysicsChanges = properties.hasMiscPhysicsChanges(); + bool hasDynamicsChanges = properties.hasDynamicPhysicsChanges(); + // _bidOnSimulationOwnership is set per-instance of the scripting interface. + // It essentially corresponds to "Am I an AC or an Interface client?" - ACs will never bid. + if ((_bidOnSimulationOwnership && ((hasMiscPhysicsChanges && entity->isMoving()) || hasDynamicsChanges))) { auto nodeList = DependencyManager::get(); const QUuid myNodeID = nodeList->getSessionUUID(); if (entity->getSimulatorID() == myNodeID) { // we think we already own the simulation, so make sure to send ALL TerseUpdate properties - if (hasTerseUpdateChanges) { + if (properties.hasTerseUpdateChanges()) { entity->getAllTerseUpdateProperties(properties); } // TODO: if we knew that ONLY TerseUpdate properties have changed in properties AND the object From 827daade1b140c7dbfc142c6116a2fc2d931359e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 23 May 2017 12:50:43 -0700 Subject: [PATCH 24/91] Make this PR a protocol change --- libraries/networking/src/udt/PacketHeaders.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index f88015a4e4..0dbbcd771f 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -114,7 +114,8 @@ public: EntityServerScriptLog, AdjustAvatarSorting, OctreeFileReplacement, - LAST_PACKET_TYPE = OctreeFileReplacement + SimulationBiddingChanges, + LAST_PACKET_TYPE = SimulationBiddingChanges }; }; From 8dec066c2bba98b8d02b88afa057c0c22a97ccfa Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 23 May 2017 14:41:02 -0700 Subject: [PATCH 25/91] Revert 'dynamicChanged' to be a 'misc' physics property --- libraries/entities/src/EntityItemProperties.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 4595ebf70d..fa4df72387 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1825,13 +1825,13 @@ bool EntityItemProperties::hasTerseUpdateChanges() const { } bool EntityItemProperties::hasDynamicPhysicsChanges() const { - return _dynamicChanged || _velocityChanged || _angularVelocityChanged || _accelerationChanged; + return _velocityChanged || _angularVelocityChanged || _accelerationChanged; } bool EntityItemProperties::hasMiscPhysicsChanges() const { return _gravityChanged || _dimensionsChanged || _densityChanged || _frictionChanged || _restitutionChanged || _dampingChanged || _angularDampingChanged || _registrationPointChanged || - _compoundShapeURLChanged || _collisionlessChanged || _collisionMaskChanged || + _compoundShapeURLChanged || _dynamicChanged || _collisionlessChanged || _collisionMaskChanged || _rotationChanged || _positionChanged; } From ebe6ce9c8d3640e7e357755fa11bde766a6b95cb Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 24 May 2017 10:16:51 -0700 Subject: [PATCH 26/91] Committing checkpoint changes, then testing --- .../src/EntityTreeRenderer.cpp | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index d62181c651..7b2333ade9 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -1092,24 +1092,29 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons // trigger scripted collision sounds and events for locally owned objects EntityItemPointer entityA = entityTree->findEntityByEntityItemID(idA); EntityItemPointer entityB = entityTree->findEntityByEntityItemID(idB); - QUuid entityASimulatorID = entityA->getSimulatorID(); - QUuid entityBSimulatorID = entityB->getSimulatorID(); - if ((bool)entityA && (myNodeID == entityASimulatorID || ((bool)entityB && myNodeID == entityBSimulatorID && entityASimulatorID.isNull()))) { - playEntityCollisionSound(entityA, collision); - emit collisionWithEntity(idA, idB, collision); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); - } - } + if ((bool)entityA && (bool)entityB) { + QUuid entityASimulatorID = entityA->getSimulatorID(); + QUuid entityBSimulatorID = entityB->getSimulatorID(); + bool entityAIsStatic = !entityA->getDynamic() && !entityA->isMoving(); + bool entityBIsStatic = !entityB->getDynamic() && !entityB->isMoving(); - if ((bool)entityB && (myNodeID == entityBSimulatorID || ((bool)entityA && myNodeID == entityASimulatorID && entityBSimulatorID.isNull()))) { - playEntityCollisionSound(entityB, collision); - // since we're swapping A and B we need to send the inverted collision - Collision invertedCollision(collision); - invertedCollision.invert(); - emit collisionWithEntity(idB, idA, invertedCollision); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(idB, "collisionWithEntity", idA, invertedCollision); + if (myNodeID == entityASimulatorID || (myNodeID == entityBSimulatorID && entityAIsStatic)) { + playEntityCollisionSound(entityA, collision); + emit collisionWithEntity(idA, idB, collision); + if (_entitiesScriptEngine) { + _entitiesScriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); + } + } + + if (myNodeID == entityBSimulatorID || (myNodeID == entityASimulatorID && entityBIsStatic)) { + playEntityCollisionSound(entityB, collision); + // since we're swapping A and B we need to send the inverted collision + Collision invertedCollision(collision); + invertedCollision.invert(); + emit collisionWithEntity(idB, idA, invertedCollision); + if (_entitiesScriptEngine) { + _entitiesScriptEngine->callEntityScriptMethod(idB, "collisionWithEntity", idA, invertedCollision); + } } } } From 3ec73cc5e1ffe2b7a5cd8c2cbcb81d5159322cf3 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 24 May 2017 11:17:03 -0700 Subject: [PATCH 27/91] Changes after discussion with Brad --- .../src/EntityTreeRenderer.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 7b2333ade9..fccc6f512f 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -1095,10 +1095,20 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons if ((bool)entityA && (bool)entityB) { QUuid entityASimulatorID = entityA->getSimulatorID(); QUuid entityBSimulatorID = entityB->getSimulatorID(); - bool entityAIsStatic = !entityA->getDynamic() && !entityA->isMoving(); - bool entityBIsStatic = !entityB->getDynamic() && !entityB->isMoving(); + bool entityAIsDynamic = entityA->getDynamic(); + bool entityBIsDynamic = entityB->getDynamic(); - if (myNodeID == entityASimulatorID || (myNodeID == entityBSimulatorID && entityAIsStatic)) { +#ifdef WANT_DEBUG + bool bothEntitiesStatic = !entityAIsDynamic && !entityBIsDynamic; + if (bothEntitiesStatic) { + qCDebug(entities) << "A collision has occurred between two static entities!"; + qCDebug(entities) << "Entity A ID:" << entityA->getID(); + qCDebug(entities) << "Entity B ID:" << entityB->getID(); + } + assert(!bothEntitiesStatic); +#endif + + if ((myNodeID == entityASimulatorID && entityAIsDynamic) || (myNodeID == entityBSimulatorID && !entityAIsDynamic)) { playEntityCollisionSound(entityA, collision); emit collisionWithEntity(idA, idB, collision); if (_entitiesScriptEngine) { @@ -1106,7 +1116,7 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons } } - if (myNodeID == entityBSimulatorID || (myNodeID == entityASimulatorID && entityBIsStatic)) { + if ((myNodeID == entityBSimulatorID && entityBIsDynamic) || (myNodeID == entityASimulatorID && !entityBIsDynamic)) { playEntityCollisionSound(entityB, collision); // since we're swapping A and B we need to send the inverted collision Collision invertedCollision(collision); From 21d396bbb507b152c6a89152328b1f68da188f29 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 24 May 2017 14:15:59 -0700 Subject: [PATCH 28/91] Pull out ownership bidding changes --- libraries/entities/src/EntityItemProperties.cpp | 7 +------ libraries/entities/src/EntityItemProperties.h | 1 - libraries/entities/src/EntityScriptingInterface.cpp | 10 ++++------ libraries/networking/src/udt/PacketHeaders.h | 4 ++-- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index fa4df72387..1ed020e592 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1824,15 +1824,10 @@ bool EntityItemProperties::hasTerseUpdateChanges() const { return _positionChanged || _velocityChanged || _rotationChanged || _angularVelocityChanged || _accelerationChanged; } -bool EntityItemProperties::hasDynamicPhysicsChanges() const { - return _velocityChanged || _angularVelocityChanged || _accelerationChanged; -} - bool EntityItemProperties::hasMiscPhysicsChanges() const { return _gravityChanged || _dimensionsChanged || _densityChanged || _frictionChanged || _restitutionChanged || _dampingChanged || _angularDampingChanged || _registrationPointChanged || - _compoundShapeURLChanged || _dynamicChanged || _collisionlessChanged || _collisionMaskChanged || - _rotationChanged || _positionChanged; + _compoundShapeURLChanged || _dynamicChanged || _collisionlessChanged || _collisionMaskChanged; } void EntityItemProperties::clearSimulationOwner() { diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 697c634c67..590298e102 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -274,7 +274,6 @@ public: void setCreated(QDateTime& v); bool hasTerseUpdateChanges() const; - bool hasDynamicPhysicsChanges() const; bool hasMiscPhysicsChanges() const; void clearSimulationOwner(); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 367343cb60..b184d648da 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -414,17 +414,15 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& entityFound = true; // make sure the properties has a type, so that the encode can know which properties to include properties.setType(entity->getType()); - bool hasMiscPhysicsChanges = properties.hasMiscPhysicsChanges(); - bool hasDynamicsChanges = properties.hasDynamicPhysicsChanges(); - // _bidOnSimulationOwnership is set per-instance of the scripting interface. - // It essentially corresponds to "Am I an AC or an Interface client?" - ACs will never bid. - if ((_bidOnSimulationOwnership && ((hasMiscPhysicsChanges && entity->isMoving()) || hasDynamicsChanges))) { + bool hasTerseUpdateChanges = properties.hasTerseUpdateChanges(); + bool hasPhysicsChanges = properties.hasMiscPhysicsChanges() || hasTerseUpdateChanges; + if (_bidOnSimulationOwnership && hasPhysicsChanges) { auto nodeList = DependencyManager::get(); const QUuid myNodeID = nodeList->getSessionUUID(); if (entity->getSimulatorID() == myNodeID) { // we think we already own the simulation, so make sure to send ALL TerseUpdate properties - if (properties.hasTerseUpdateChanges()) { + if (hasTerseUpdateChanges) { entity->getAllTerseUpdateProperties(properties); } // TODO: if we knew that ONLY TerseUpdate properties have changed in properties AND the object diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 0dbbcd771f..2cc3a2c42e 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -114,8 +114,8 @@ public: EntityServerScriptLog, AdjustAvatarSorting, OctreeFileReplacement, - SimulationBiddingChanges, - LAST_PACKET_TYPE = SimulationBiddingChanges + CollisionEventChanges, + LAST_PACKET_TYPE = CollisionEventChanges }; }; From 252298938b89a98235efe0d58306435d67c5b50d Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 25 May 2017 09:28:11 -0700 Subject: [PATCH 29/91] Update conditional to handle 'other unowned' case --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index fccc6f512f..e029ca6ada 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -1108,7 +1108,7 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons assert(!bothEntitiesStatic); #endif - if ((myNodeID == entityASimulatorID && entityAIsDynamic) || (myNodeID == entityBSimulatorID && !entityAIsDynamic)) { + if ((myNodeID == entityASimulatorID && entityAIsDynamic) || (myNodeID == entityBSimulatorID && (!entityAIsDynamic || entityASimulatorID.isNull()))) { playEntityCollisionSound(entityA, collision); emit collisionWithEntity(idA, idB, collision); if (_entitiesScriptEngine) { @@ -1116,7 +1116,7 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons } } - if ((myNodeID == entityBSimulatorID && entityBIsDynamic) || (myNodeID == entityASimulatorID && !entityBIsDynamic)) { + if ((myNodeID == entityBSimulatorID && entityBIsDynamic) || (myNodeID == entityASimulatorID && (!entityBIsDynamic || entityBSimulatorID.isNull()))) { playEntityCollisionSound(entityB, collision); // since we're swapping A and B we need to send the inverted collision Collision invertedCollision(collision); From 0a7a42bdc3855b1b08e92930f182815276130f86 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 26 May 2017 12:04:35 -0700 Subject: [PATCH 30/91] fix force of BC3 instead of BC1a compression --- libraries/image/src/image/Image.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libraries/image/src/image/Image.cpp b/libraries/image/src/image/Image.cpp index dcc65e8995..f274dc54f8 100644 --- a/libraries/image/src/image/Image.cpp +++ b/libraries/image/src/image/Image.cpp @@ -493,10 +493,6 @@ gpu::TexturePointer TextureUsage::process2DTextureColorFromImage(const QImage& s if (validAlpha) { processTextureAlpha(image, validAlpha, alphaAsMask); - - // NOTE: This disables BC1a compression because it was producing odd artifacts on text textures - // for the tutorial. Instead we use BC3 (which is larger) but doesn't produce the same artifacts). - alphaAsMask = false; } gpu::TexturePointer theTexture = nullptr; @@ -506,7 +502,9 @@ gpu::TexturePointer TextureUsage::process2DTextureColorFromImage(const QImage& s gpu::Element formatGPU; if (isColorTexturesCompressionEnabled()) { if (validAlpha) { - formatGPU = alphaAsMask ? gpu::Element::COLOR_COMPRESSED_SRGBA_MASK : gpu::Element::COLOR_COMPRESSED_SRGBA; + // NOTE: This disables BC1a compression because it was producing odd artifacts on text textures + // for the tutorial. Instead we use BC3 (which is larger) but doesn't produce the same artifacts). + formatGPU = gpu::Element::COLOR_COMPRESSED_SRGBA; } else { formatGPU = gpu::Element::COLOR_COMPRESSED_SRGB; } From bf057219acdeb201a1f78be085aa017eae187bd9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 26 May 2017 14:37:24 -0700 Subject: [PATCH 31/91] fix reference to pending transfer count for progress/stats --- scripts/developer/utilities/render/stats.qml | 13 ++++++------- scripts/system/progress.js | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/scripts/developer/utilities/render/stats.qml b/scripts/developer/utilities/render/stats.qml index 7acf678570..54e0dc4ce8 100644 --- a/scripts/developer/utilities/render/stats.qml +++ b/scripts/developer/utilities/render/stats.qml @@ -20,9 +20,9 @@ Item { id: stats spacing: 8 anchors.fill:parent - + property var config: Render.getConfig("Stats") - + function evalEvenHeight() { // Why do we have to do that manually ? cannot seem to find a qml / anchor / layout mode that does that ? return (height - spacing * (children.length - 1)) / children.length @@ -81,7 +81,7 @@ Item { color: "#1AC567" }, { - prop: "textureGPUTransferCount", + prop: "texturePendingGPUTransferCount", label: "Transfer", color: "#9495FF" } @@ -158,7 +158,7 @@ Item { } ] } - + PlotPerf { title: "State Changes" height: parent.evalEvenHeight() @@ -180,7 +180,7 @@ Item { color: "#1AC567" } ] - } + } property var drawOpaqueConfig: Render.getConfig("DrawOpaqueDeferred") property var drawTransparentConfig: Render.getConfig("DrawTransparentDeferred") @@ -211,7 +211,7 @@ Item { color: "#FED959" } ] - } + } PlotPerf { title: "Timing" @@ -250,4 +250,3 @@ Item { } } - diff --git a/scripts/system/progress.js b/scripts/system/progress.js index 81da38c8c2..f4741c5b6a 100644 --- a/scripts/system/progress.js +++ b/scripts/system/progress.js @@ -261,7 +261,7 @@ } } - gpuTextures = Render.getConfig("Stats").textureGPUTransferCount; + gpuTextures = Render.getConfig("Stats").texturePendingGPUTransferCount; // Update state if (!visible) { // Not visible because no recent downloads @@ -290,7 +290,7 @@ }, FADE_OUT_WAIT); } } else { - if (displayProgress < 100 || gpuTextures > 0) { // Was finished and waiting to fade out but have resumed so + if (displayProgress < 100 || gpuTextures > 0) { // Was finished and waiting to fade out but have resumed so // don't fade out Script.clearInterval(fadeWaitTimer); fadeWaitTimer = null; From 0920dbc1a8910c986b2c83b2422aa7fa63e192d9 Mon Sep 17 00:00:00 2001 From: volansystech Date: Mon, 29 May 2017 15:53:33 +0530 Subject: [PATCH 32/91] Resolve the comments of @ZappoMan. --- interface/src/Application.cpp | 111 +++++++++--------- interface/src/Application.h | 13 +- .../display-plugins/OpenGLDisplayPlugin.cpp | 12 +- .../src/display-plugins/OpenGLDisplayPlugin.h | 10 +- libraries/plugins/src/plugins/Plugin.h | 22 ++-- .../oculus/src/OculusBaseDisplayPlugin.cpp | 14 +-- plugins/oculus/src/OculusBaseDisplayPlugin.h | 4 +- 7 files changed, 92 insertions(+), 94 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a40f31a8bb..57a627fe53 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -244,6 +244,8 @@ static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStanda Setting::Handle maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS); static const QString MARKETPLACE_CDN_HOSTNAME = "mpassets.highfidelity.com"; +static const int INTERVAL_TO_CHECK_HMD_MOUNTED_STATUS = 500; // milliseconds +static const QString OCULUS_RIFT_DISPLAY_PLUGIN_NAME = "Oculus Rift"; const QHash Application::_acceptedExtensions { { SVO_EXTENSION, &Application::importSVOFromURL }, @@ -1338,19 +1340,20 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["active_display_plugin"] = getActiveDisplayPlugin()->getName(); properties["using_hmd"] = isHMDMode(); - if (isOculusRiftPluginAvailable()) { - // If Oculus Rift Plugin is available and current display plugin is not Oculus Rift - // then startOculusRiftStandBySession to listen Oculus HMD Mounted status. - if (getActiveDisplayPlugin()->getName() != "Oculus Rift" && - !oculusRiftPlugin->isStandBySessionActive()) { - startOculusRiftStandBySession(); - } - // Poll periodically to check whether the user has worn Oculus HMD or not. And switch Display mode accordingly. - // If the user wear Oculus HMD then switch to VR mode. If the user removes Oculus HMD then switch to Desktop mode. - QTimer *switchDisplayModeTimer = new QTimer(this); - connect(switchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayModeForOculus())); - switchDisplayModeTimer->start(500); - } + if (isHMDPluginAvailable()) { + // Currently, autoswitch display mode support is only for Oculus Rift. + // If HMD Plugin is available and current display plugin is not HMD plugin + // then startHMDStandBySession to listen HMD Mounted status. + if (getActiveDisplayPlugin()->getName() != _hmdPluginName && + !_hmdPlugin->isStandBySessionActive()) { + startHMDStandBySession(); + } + // Poll periodically to check whether the user has worn HMD or not. And switch Display mode accordingly. + // If the user wear HMD then switch to VR mode. If the user removes HMD then switch to Desktop mode. + QTimer *switchDisplayModeTimer = new QTimer(this); + connect(switchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayMode())); + switchDisplayModeTimer->start(INTERVAL_TO_CHECK_HMD_MOUNTED_STATUS); + } auto glInfo = getGLContextData(); properties["gl_info"] = glInfo; @@ -1581,8 +1584,8 @@ void Application::aboutToQuit() { } getActiveDisplayPlugin()->deactivate(); - if (oculusRiftPlugin && oculusRiftPlugin->isStandBySessionActive()) { - oculusRiftPlugin->endStandBySession(); + if (_hmdPlugin && _hmdPlugin->isStandBySessionActive()) { + _hmdPlugin->endStandBySession(); } // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. DependencyManager::get()->hide("RunningScripts"); @@ -6846,54 +6849,48 @@ void Application::updateDisplayMode() { Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin"); } -bool Application::isOculusRiftPluginAvailable() { - bool isOculusRiftPluginAvailable = false; - auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); - // Default to the first item on the list, in case none of the menu items match - DisplayPluginPointer defaultplugin = displayPlugins.at(0); - if (defaultplugin->isHmd() && defaultplugin->getName() == "Oculus Rift") { - oculusRiftPlugin = defaultplugin; - return true; - } - // Iterate to check If Oculus Rift Plugin is available - foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { - QString pluginname = displayPlugin->getName(); - if (displayPlugin->isHmd() && pluginname == "Oculus Rift") { - oculusRiftPlugin = displayPlugin; - _oculusHMDMountedStatus = displayPlugin->isDisplayVisible(); - isOculusRiftPluginAvailable = true; - break; - } - } - return isOculusRiftPluginAvailable; +bool Application::isHMDPluginAvailable() { + bool isHMDEnabledPluginAvailable = false; + auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); + // Currently, autoswitch display mode support is only for Oculus Rift. + foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { + if (displayPlugin->isHmd() && displayPlugin->getName() == OCULUS_RIFT_DISPLAY_PLUGIN_NAME) { + _hmdPlugin = displayPlugin; + _hmdPluginName = displayPlugin->getName(); + _hmdMountedStatus = displayPlugin->isDisplayVisible(); + isHMDEnabledPluginAvailable = true; + break; + } + } + return isHMDEnabledPluginAvailable; } -void Application::switchDisplayModeForOculus() { - bool currenthmdMountedStatus = oculusRiftPlugin->isDisplayVisible(); - if (currenthmdMountedStatus != _oculusHMDMountedStatus) { - // Switch to respective mode as soon as currenthmdMountedStatus changes - if (currenthmdMountedStatus == false && _oculusHMDMountedStatus == true) { - qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; - setActiveDisplayPlugin("Desktop"); - startOculusRiftStandBySession(); - } - if (currenthmdMountedStatus == true && _oculusHMDMountedStatus == false) { - qCDebug(interfaceapp) << "Switching from Desktop to HMD mode"; - endOculusRiftStandBySession(); - setActiveDisplayPlugin("Oculus Rift"); - } - } - _oculusHMDMountedStatus = currenthmdMountedStatus; +void Application::switchDisplayMode() { + bool currentHMDMountedStatus = _hmdPlugin->isDisplayVisible(); + if (currentHMDMountedStatus != _hmdMountedStatus) { + // Switch to respective mode as soon as currenthmdMountedStatus changes + if (currentHMDMountedStatus == false && _hmdMountedStatus == true) { + qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; + setActiveDisplayPlugin("Desktop"); + startHMDStandBySession(); + } + if (currentHMDMountedStatus == true && _hmdMountedStatus == false) { + qCDebug(interfaceapp) << "Switching from Desktop to HMD mode"; + endHMDStandBySession(); + setActiveDisplayPlugin(_hmdPluginName); + } + } + _hmdMountedStatus = currentHMDMountedStatus; } -bool Application::startOculusRiftStandBySession() { - bool isStandBySessionStarted = oculusRiftPlugin->startStandBySession(); - qCDebug(interfaceapp) << "startOculusRiftStandBySession: " << isStandBySessionStarted; - return isStandBySessionStarted; +bool Application::startHMDStandBySession() { + bool isStandBySessionStarted = _hmdPlugin->startStandBySession(); + qCDebug(interfaceapp) << "startHMDStandBySession: " << isStandBySessionStarted; + return isStandBySessionStarted; } -void Application::endOculusRiftStandBySession() { - oculusRiftPlugin->endStandBySession(); +void Application::endHMDStandBySession() { + _hmdPlugin->endStandBySession(); } mat4 Application::getEyeProjection(int eye) const { diff --git a/interface/src/Application.h b/interface/src/Application.h index 112b650160..699cb9f879 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -442,7 +442,7 @@ private slots: void addAssetToWorldErrorTimeout(); void handleSandboxStatus(QNetworkReply* reply); - void switchDisplayModeForOculus(); + void switchDisplayMode(); private: static void initDisplay(); void init(); @@ -684,11 +684,12 @@ private: SharedSoundPointer _snapshotSound; - DisplayPluginPointer oculusRiftPlugin; - bool isOculusRiftPluginAvailable(); - bool _oculusHMDMountedStatus; // Keep track of Oculus Rift HMDMounted Flag - bool startOculusRiftStandBySession(); - void endOculusRiftStandBySession(); + DisplayPluginPointer _hmdPlugin; // HMD Enabled Plugin + QString _hmdPluginName; + bool isHMDPluginAvailable(); + bool _hmdMountedStatus; // Check HMD Mounted status + bool startHMDStandBySession(); + void endHMDStandBySession(); }; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index cebe844b84..3bdf9a672c 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -339,15 +339,15 @@ void OpenGLDisplayPlugin::deactivate() { } bool OpenGLDisplayPlugin::startStandBySession() { - if (!activateStandBySession()) { - return false; - } - return Parent::startStandBySession(); + if (!activateStandBySession()) { + return false; + } + return Parent::startStandBySession(); } void OpenGLDisplayPlugin::endStandBySession() { - deactivateStandBySession(); - return Parent::endStandBySession(); + deactivateStandBySession(); + return Parent::endStandBySession(); } void OpenGLDisplayPlugin::customizeContext() { diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index ecde3b3c93..9681158c55 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -42,8 +42,8 @@ public: // between the main thread and the presentation thread bool activate() override final; void deactivate() override final; - bool startStandBySession() override final; - void endStandBySession() override final; + bool startStandBySession() override final; + void endStandBySession() override final; bool eventFilter(QObject* receiver, QEvent* event) override; bool isDisplayVisible() const override { return true; } @@ -102,9 +102,9 @@ protected: virtual bool internalActivate() { return true; } virtual void internalDeactivate() {} - // Returns true on successful activation of standby session - virtual bool activateStandBySession() { return true; } - virtual void deactivateStandBySession() {} + // Returns true on successful activation of standby session + virtual bool activateStandBySession() { return true; } + virtual void deactivateStandBySession() {} // Plugin specific functionality to send the composed scene to the output window or device virtual void internalPresent(); diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index 045a9eee15..11ea79186a 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -53,18 +53,18 @@ public: virtual bool isActive() { return _active; } - virtual bool startStandBySession() { - _standbysessionstatus = true; - return _standbysessionstatus; - } + virtual bool startStandBySession() { + _standbysessionstatus = true; + return _standbysessionstatus; + } - virtual void endStandBySession() { - _standbysessionstatus = false; - } + virtual void endStandBySession() { + _standbysessionstatus = false; + } - virtual bool isStandBySessionActive() { - return _standbysessionstatus; - } + virtual bool isStandBySessionActive() { + return _standbysessionstatus; + } /** * Called by the application during it's idle phase. If the plugin needs to do @@ -85,7 +85,7 @@ signals: protected: bool _active { false }; - bool _standbysessionstatus { false }; + bool _standbysessionstatus { false }; PluginContainer* _container { nullptr }; static const char* UNKNOWN_PLUGIN_ID; diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index 28e30e0d21..df98abf408 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -128,15 +128,15 @@ void OculusBaseDisplayPlugin::internalDeactivate() { } bool OculusBaseDisplayPlugin::activateStandBySession() { - _session = acquireOculusSession(); - if (!_session) { - return false; - } - return true; + _session = acquireOculusSession(); + if (!_session) { + return false; + } + return true; } void OculusBaseDisplayPlugin::deactivateStandBySession() { - releaseOculusSession(); - _session = nullptr; + releaseOculusSession(); + _session = nullptr; } void OculusBaseDisplayPlugin::updatePresentPose() { //mat4 sensorResetMat; diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h index 79085f817b..1f54742c2d 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -33,8 +33,8 @@ protected: void uncustomizeContext() override; bool internalActivate() override; void internalDeactivate() override; - bool activateStandBySession() override; - void deactivateStandBySession() override; + bool activateStandBySession() override; + void deactivateStandBySession() override; void updatePresentPose() override; protected: From e90b1b5a67c8fd33d539c7d86b677ba24d17f61c Mon Sep 17 00:00:00 2001 From: volansystech Date: Mon, 29 May 2017 18:21:59 +0530 Subject: [PATCH 33/91] Resolve the comments of @ZappoMan. --- interface/src/Application.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d219d7bcb6..b5733fa6f5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -246,6 +246,7 @@ Setting::Handle maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTRE static const QString MARKETPLACE_CDN_HOSTNAME = "mpassets.highfidelity.com"; static const int INTERVAL_TO_CHECK_HMD_MOUNTED_STATUS = 500; // milliseconds static const QString OCULUS_RIFT_DISPLAY_PLUGIN_NAME = "Oculus Rift"; +static const QString DESKTOP_DISPLAY_PLUGIN_NAME = "Desktop"; const QHash Application::_acceptedExtensions { { SVO_EXTENSION, &Application::importSVOFromURL }, @@ -1348,8 +1349,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo !_hmdPlugin->isStandBySessionActive()) { startHMDStandBySession(); } - // Poll periodically to check whether the user has worn HMD or not. And switch Display mode accordingly. - // If the user wear HMD then switch to VR mode. If the user removes HMD then switch to Desktop mode. + // Poll periodically to check whether the user has worn HMD or not. Switch Display mode accordingly. + // If the user wears HMD then switch to VR mode. If the user removes HMD then switch to Desktop mode. QTimer *switchDisplayModeTimer = new QTimer(this); connect(switchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayMode())); switchDisplayModeTimer->start(INTERVAL_TO_CHECK_HMD_MOUNTED_STATUS); @@ -6773,7 +6774,7 @@ void Application::switchDisplayMode() { // Switch to respective mode as soon as currenthmdMountedStatus changes if (currentHMDMountedStatus == false && _hmdMountedStatus == true) { qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; - setActiveDisplayPlugin("Desktop"); + setActiveDisplayPlugin(DESKTOP_DISPLAY_PLUGIN_NAME); startHMDStandBySession(); } if (currentHMDMountedStatus == true && _hmdMountedStatus == false) { From e82e80e8e08cf68572049483b89992a3cd44ea9e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 30 May 2017 09:55:33 -0700 Subject: [PATCH 34/91] OculusDebugDisplayPlugin is head controller --- plugins/oculus/src/OculusDebugDisplayPlugin.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/oculus/src/OculusDebugDisplayPlugin.h b/plugins/oculus/src/OculusDebugDisplayPlugin.h index ec05cd92e2..1cc6bd0f8e 100644 --- a/plugins/oculus/src/OculusDebugDisplayPlugin.h +++ b/plugins/oculus/src/OculusDebugDisplayPlugin.h @@ -15,6 +15,8 @@ public: grouping getGrouping() const override { return DEVELOPER; } bool isSupported() const override; + bool isHeadController() const override { return false; } + protected: void hmdPresent() override {} bool isHmdMounted() const override { return true; } From 8559ed6260f04c61d22eac76d9057e20b8d3b900 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 30 May 2017 16:37:10 -0700 Subject: [PATCH 35/91] Starting to add the stencil mask for hmd --- .../src/gpu/DrawTransformVertexPosition.slv | 28 ++++++++ libraries/gpu/src/gpu/DrawWhite.slf | 18 +++++ libraries/gpu/src/gpu/StandardShaderLib.cpp | 17 +++++ libraries/gpu/src/gpu/StandardShaderLib.h | 8 +++ libraries/model/src/model/Geometry.cpp | 38 ++++++++++ libraries/model/src/model/Geometry.h | 6 ++ .../src/DeferredLightingEffect.cpp | 10 +-- .../render-utils/src/RenderDeferredTask.cpp | 69 +++++++++++++++++++ .../render-utils/src/RenderDeferredTask.h | 16 +++++ 9 files changed, 205 insertions(+), 5 deletions(-) create mode 100644 libraries/gpu/src/gpu/DrawTransformVertexPosition.slv create mode 100644 libraries/gpu/src/gpu/DrawWhite.slf diff --git a/libraries/gpu/src/gpu/DrawTransformVertexPosition.slv b/libraries/gpu/src/gpu/DrawTransformVertexPosition.slv new file mode 100644 index 0000000000..cf66a615f5 --- /dev/null +++ b/libraries/gpu/src/gpu/DrawTransformVertexPosition.slv @@ -0,0 +1,28 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw and transform the fed vertex position with the standard MVP stack +// Output the clip position +// +// Created by Sam Gateau on 5/30/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 +// + +<@include gpu/Transform.slh@> + +<$declareStandardTransform()$> + +layout(location = 0) in vec4 inPosition; + +out vec3 varWorldPos; + +void main(void) { + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + <$transformModelToClipPos(cam, obj, inPosition, gl_Position)$> +} diff --git a/libraries/gpu/src/gpu/DrawWhite.slf b/libraries/gpu/src/gpu/DrawWhite.slf new file mode 100644 index 0000000000..bdecc0c5c5 --- /dev/null +++ b/libraries/gpu/src/gpu/DrawWhite.slf @@ -0,0 +1,18 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw white +// +// Created by Sam Gateau on 5/30/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 +// + +out vec4 outFragColor; + +void main(void) { + outFragColor = vec4(1.0); +} diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp index 81500347fd..cc92719a06 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.cpp +++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp @@ -16,6 +16,8 @@ #include "DrawTransformUnitQuad_vert.h" #include "DrawTexcoordRectTransformUnitQuad_vert.h" #include "DrawViewportQuadTransformTexcoord_vert.h" +#include "DrawTransformVertexPosition_vert.h" +#include "DrawWhite_frag.h" #include "DrawTexture_frag.h" #include "DrawTextureOpaque_frag.h" #include "DrawColoredTexture_frag.h" @@ -26,6 +28,8 @@ ShaderPointer StandardShaderLib::_drawUnitQuadTexcoordVS; ShaderPointer StandardShaderLib::_drawTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawTexcoordRectTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawViewportQuadTransformTexcoordVS; +ShaderPointer StandardShaderLib::_drawTransformVertexPositionVS; +ShaderPointer StandardShaderLib::_drawWhitePS; ShaderPointer StandardShaderLib::_drawTexturePS; ShaderPointer StandardShaderLib::_drawTextureOpaquePS; ShaderPointer StandardShaderLib::_drawColoredTexturePS; @@ -84,6 +88,19 @@ ShaderPointer StandardShaderLib::getDrawViewportQuadTransformTexcoordVS() { } return _drawViewportQuadTransformTexcoordVS; } +ShaderPointer StandardShaderLib::getDrawTransformVertexPositionVS() { + if (!_drawTransformVertexPositionVS) { + _drawTransformVertexPositionVS = gpu::Shader::createVertex(std::string(DrawTransformVertexPosition_vert)); + } + return _drawTransformVertexPositionVS; +} + +ShaderPointer StandardShaderLib::getDrawWhitePS() { + if (!_drawWhitePS) { + _drawWhitePS = gpu::Shader::createPixel(std::string(DrawWhite_frag)); + } + return _drawWhitePS; +} ShaderPointer StandardShaderLib::getDrawTexturePS() { if (!_drawTexturePS) { diff --git a/libraries/gpu/src/gpu/StandardShaderLib.h b/libraries/gpu/src/gpu/StandardShaderLib.h index 12ea9045c2..677ad8c7a1 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.h +++ b/libraries/gpu/src/gpu/StandardShaderLib.h @@ -37,6 +37,11 @@ public: // Shader draws the unit quad in the full viewport clipPos = ([(-1,-1),(1,1)]) and transform the texcoord = [(0,0),(1,1)] by the model transform. static ShaderPointer getDrawViewportQuadTransformTexcoordVS(); + // Shader draw the fed vertex position and transform it by the full model transform stack (Model, View, Proj). + // simply output the world pos and the clip pos to the next stage + static ShaderPointer getDrawTransformVertexPositionVS(); + + static ShaderPointer getDrawWhitePS(); static ShaderPointer getDrawTexturePS(); static ShaderPointer getDrawTextureOpaquePS(); static ShaderPointer getDrawColoredTexturePS(); @@ -51,6 +56,9 @@ protected: static ShaderPointer _drawTransformUnitQuadVS; static ShaderPointer _drawTexcoordRectTransformUnitQuadVS; static ShaderPointer _drawViewportQuadTransformTexcoordVS; + static ShaderPointer _drawTransformVertexPositionVS; + + static ShaderPointer _drawWhitePS; static ShaderPointer _drawTexturePS; static ShaderPointer _drawTextureOpaquePS; static ShaderPointer _drawColoredTexturePS; diff --git a/libraries/model/src/model/Geometry.cpp b/libraries/model/src/model/Geometry.cpp index 16608ab63e..2525491460 100755 --- a/libraries/model/src/model/Geometry.cpp +++ b/libraries/model/src/model/Geometry.cpp @@ -241,6 +241,42 @@ void Mesh::forEach(std::function vertexFunc, } } +MeshPointer Mesh::createIndexedTriangles_P3F(uint32_t numVertices, uint32_t numIndices, const glm::vec3* vertices, const uint32_t* indices) { + MeshPointer mesh; + if (numVertices == 0) { return mesh; } + if (numIndices < 3) { return mesh; } + + mesh = std::make_shared(); + + // Vertex buffer + mesh->setVertexBuffer(gpu::BufferView(new gpu::Buffer(numVertices * sizeof(glm::vec3), (gpu::Byte*) vertices), gpu::Element::VEC3F_XYZ)); + + // trim down the indices to shorts if possible + if (numIndices < std::numeric_limits::max()) { + Indices16 shortIndicesVector; + int16_t* shortIndices = nullptr; + if (indices) { + shortIndicesVector.resize(numIndices); + for (int i = 0; i < numIndices; i++) { + shortIndicesVector[i] = indices[i]; + } + shortIndices = shortIndicesVector.data(); + } + + mesh->setIndexBuffer(gpu::BufferView(new gpu::Buffer(numIndices * sizeof(uint16_t), (gpu::Byte*) shortIndices), gpu::Element::INDEX_UINT16)); + } else { + + mesh->setIndexBuffer(gpu::BufferView(new gpu::Buffer(numIndices * sizeof(uint32_t), (gpu::Byte*) indices), gpu::Element::INDEX_INT32)); + } + + + std::vector parts; + parts.push_back(model::Mesh::Part(0, numIndices, 0, model::Mesh::TRIANGLES)); + mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); + + return mesh; +} + Geometry::Geometry() { } @@ -256,3 +292,5 @@ Geometry::~Geometry() { void Geometry::setMesh(const MeshPointer& mesh) { _mesh = mesh; } + + diff --git a/libraries/model/src/model/Geometry.h b/libraries/model/src/model/Geometry.h index 7ba3e83407..2375944f04 100755 --- a/libraries/model/src/model/Geometry.h +++ b/libraries/model/src/model/Geometry.h @@ -65,6 +65,9 @@ public: const gpu::BufferStream& getVertexStream() const { return _vertexStream; } // Index Buffer + using Indices16 = std::vector; + using Indices32 = std::vector; + void setIndexBuffer(const BufferView& buffer); const BufferView& getIndexBuffer() const { return _indexBuffer; } size_t getNumIndices() const { return _indexBuffer.getNumElements(); } @@ -127,6 +130,9 @@ public: std::function normalFunc, std::function indexFunc); + + static MeshPointer createIndexedTriangles_P3F(uint32_t numVertices, uint32_t numTriangles, const glm::vec3* vertices = nullptr, const uint32_t* indices = nullptr); + protected: gpu::Stream::FormatPointer _vertexFormat; diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index e1042912aa..9d839d6ee1 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -160,11 +160,11 @@ void DeferredLightingEffect::init() { lp->setAmbientIntensity(0.5f); - lp->setAmbientMap(_defaultSkyboxAmbientTexture); - auto irradianceSH = _defaultSkyboxAmbientTexture->getIrradiance(); - if (irradianceSH) { - lp->setAmbientSphere((*irradianceSH)); - } + lp->setAmbientMap(_defaultSkyboxAmbientTexture); + auto irradianceSH = _defaultSkyboxAmbientTexture->getIrradiance(); + if (irradianceSH) { + lp->setAmbientSphere((*irradianceSH)); + } } void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit) { diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index b844da8bbe..60fd6e2f64 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -85,12 +85,15 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren const auto deferredFramebuffer = prepareDeferredOutputs.getN(0); const auto lightingFramebuffer = prepareDeferredOutputs.getN(1); + // draw a stencil mask in hidden regions of the frmaebuffer. + // Render opaque objects in DeferredBuffer const auto opaqueInputs = DrawStateSortDeferred::Inputs(opaques, lightingModel).hasVarying(); task.addJob("DrawOpaqueDeferred", opaqueInputs, shapePlumber); // Once opaque is all rendered create stencil background task.addJob("DrawOpaqueStencil", deferredFramebuffer); + task.addJob("PrepareStencil", primaryFramebuffer); task.addJob("OpaqueRangeTimer", opaqueRangeTimer); @@ -469,6 +472,71 @@ void DrawBackgroundDeferred::run(const RenderContextPointer& renderContext, cons // std::static_pointer_cast(renderContext->jobConfig)->gpuTime = _gpuTimer.getAverage(); } +gpu::PipelinePointer PrepareStencil::getDrawStencilPipeline() { + if (!_drawStencilPipeline) { + const gpu::int8 STENCIL_OPAQUE = 1; + auto vs = gpu::StandardShaderLib::getDrawTransformVertexPositionVS(); + auto ps = gpu::StandardShaderLib::getDrawWhitePS(); + auto program = gpu::Shader::createProgram(vs, ps); + gpu::Shader::makeProgram((*program)); + + auto state = std::make_shared(); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_KEEP)); + state->setColorWriteMask(0); + + _drawStencilPipeline = gpu::Pipeline::create(program, state); + } + return _drawStencilPipeline; +} + +model::MeshPointer PrepareStencil::getMesh() { + if (!_mesh) { + + std::vector vertices { + { -1.0f, -1.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, + { 1.0f, 1.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, + { 1.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f } }; + + std::vector indices { 0, 7, 1, 1, 3, 2, 3, 5, 4, 5, 7, 6 }; + + _mesh = model::Mesh::createIndexedTriangles_P3F((uint32_t) vertices.size(), (uint32_t) indices.size(), vertices.data(), indices.data()); + + } + return _mesh; +} + + +void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { + assert(renderContext->args); + assert(renderContext->args->_context); + + RenderArgs* args = renderContext->args; + doInBatch(args->_context, [&](gpu::Batch& batch) { + args->_batch = &batch; + + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + + batch.resetViewTransform(); + batch.setModelTransform(Transform()); + glm::mat4 proj; + batch.setProjectionTransform(proj); + + batch.setPipeline(getDrawStencilPipeline()); + + auto mesh = getMesh(); + batch.setIndexBuffer(gpu::UINT32, (mesh->getIndexBuffer()._buffer), 0); + batch.setInputFormat((mesh->getVertexFormat())); + batch.setInputStream(0, mesh->getVertexStream()); + + // Draw + auto part = mesh->getPartBuffer().get(0); + batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex); + }); + args->_batch = nullptr; +} + void Blit::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { assert(renderContext->args); assert(renderContext->args->_context); @@ -538,3 +606,4 @@ void Blit::run(const RenderContextPointer& renderContext, const gpu::Framebuffer } }); } + diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 12ecd5ecaf..bba1b26404 100644 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -13,6 +13,7 @@ #define hifi_RenderDeferredTask_h #include +#include #include #include "LightingModel.h" @@ -185,6 +186,21 @@ protected: bool _opaquePass{ true }; }; +class PrepareStencil { +public: + using JobModel = render::Job::ModelI; + + void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& dstFramebuffer); +private: + gpu::PipelinePointer _drawStencilPipeline; + gpu::PipelinePointer getDrawStencilPipeline(); + + model::MeshPointer _mesh; + model::MeshPointer getMesh(); + +}; + + class Blit { public: using JobModel = render::Job::ModelI; From 2ad85c158aafaa3477ed75edd6bfa53d53edbac5 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 30 May 2017 17:11:56 -0700 Subject: [PATCH 36/91] more work on getting head routed through input system --- .../oculus/src/OculusControllerManager.cpp | 37 ++++++++++++++++--- plugins/oculus/src/OculusControllerManager.h | 9 ++++- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 6445c3c891..6042968ffc 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -230,14 +230,14 @@ void OculusControllerManager::TouchDevice::update(float deltaTime, const control _lastControllerPose[controller] = tracking.HandPoses[hand]; return; } - + if (_lostTracking[controller]) { if (currentTime > _regainTrackingDeadline[controller]) { _poseStateMap.erase(controller); _poseStateMap[controller].valid = false; return; } - + } else { quint64 deadlineToRegainTracking = currentTime + LOST_TRACKING_DELAY; _regainTrackingDeadline[controller] = deadlineToRegainTracking; @@ -245,6 +245,10 @@ void OculusControllerManager::TouchDevice::update(float deltaTime, const control } handleRotationForUntrackedHand(inputCalibrationData, hand, tracking.HandPoses[hand]); }); + + _poseStateMap.erase(controller::HEAD); + handleHeadPose(deltaTime, inputCalibrationData, tracking.HeadPose); + using namespace controller; // Axes const auto& inputState = _parent._inputState; @@ -269,7 +273,7 @@ void OculusControllerManager::TouchDevice::update(float deltaTime, const control if (inputState.Touches & pair.first) { _buttonPressedMap.insert(pair.second); } - } + } // Haptics { @@ -292,16 +296,36 @@ void OculusControllerManager::TouchDevice::focusOutEvent() { _buttonPressedMap.clear(); }; -void OculusControllerManager::TouchDevice::handlePose(float deltaTime, - const controller::InputCalibrationData& inputCalibrationData, ovrHandType hand, - const ovrPoseStatef& handPose) { +void OculusControllerManager::TouchDevice::handlePose(float deltaTime, + const controller::InputCalibrationData& inputCalibrationData, + ovrHandType hand, const ovrPoseStatef& handPose) { auto poseId = hand == ovrHand_Left ? controller::LEFT_HAND : controller::RIGHT_HAND; auto& pose = _poseStateMap[poseId]; pose = ovrControllerPoseToHandPose(hand, handPose); // transform into avatar frame glm::mat4 controllerToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat; pose = pose.transform(controllerToAvatar); +} +void OculusControllerManager::TouchDevice::handleHeadPose(float deltaTime, + const controller::InputCalibrationData& inputCalibrationData, + const ovrPoseStatef& headPose) { + auto poseId = controller::HEAD; + auto& pose = _poseStateMap[poseId]; + + pose.translation = toGlm(headPose.ThePose.Position); + pose.rotation = toGlm(headPose.ThePose.Orientation); + pose.angularVelocity = toGlm(headPose.AngularVelocity); + pose.velocity = toGlm(headPose.LinearVelocity); + pose.valid = true; + + qDebug() << "handleHeadPose" << pose.translation.x << pose.translation.y << pose.translation.z; + + // transform into avatar frame + glm::mat4 controllerToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat; + pose = pose.transform(controllerToAvatar); + + qDebug() << "handleHeadPose after" << pose.translation.x << pose.translation.y << pose.translation.z; } void OculusControllerManager::TouchDevice::handleRotationForUntrackedHand(const controller::InputCalibrationData& inputCalibrationData, @@ -382,6 +406,7 @@ controller::Input::NamedVector OculusControllerManager::TouchDevice::getAvailabl makePair(LEFT_HAND, "LeftHand"), makePair(RIGHT_HAND, "RightHand"), + makePair(HEAD, "Head"), makePair(LEFT_PRIMARY_THUMB_TOUCH, "LeftPrimaryThumbTouch"), makePair(LEFT_SECONDARY_THUMB_TOUCH, "LeftSecondaryThumbTouch"), diff --git a/plugins/oculus/src/OculusControllerManager.h b/plugins/oculus/src/OculusControllerManager.h index 77b40d3764..61f2241f4d 100644 --- a/plugins/oculus/src/OculusControllerManager.h +++ b/plugins/oculus/src/OculusControllerManager.h @@ -76,8 +76,13 @@ private: private: void stopHapticPulse(bool leftHand); - void handlePose(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, ovrHandType hand, const ovrPoseStatef& handPose); - void handleRotationForUntrackedHand(const controller::InputCalibrationData& inputCalibrationData, ovrHandType hand, const ovrPoseStatef& handPose); + void handlePose(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, + ovrHandType hand, const ovrPoseStatef& handPose); + void handleRotationForUntrackedHand(const controller::InputCalibrationData& inputCalibrationData, + ovrHandType hand, const ovrPoseStatef& handPose); + void handleHeadPose(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, + const ovrPoseStatef& headPose); + int _trackedControllers { 0 }; // perform an action when the TouchDevice mutex is acquired. From 32c5dac66af66ebfd805890d3206531c60854d5a Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Wed, 31 May 2017 00:55:28 -0700 Subject: [PATCH 37/91] Big cleanup of unecessary shaders and legacy from deferred lighting, and messing around with the stencil --- libraries/gpu/src/gpu/DrawVertexPosition.slv | 19 +++ libraries/gpu/src/gpu/StandardShaderLib.cpp | 10 ++ libraries/gpu/src/gpu/StandardShaderLib.h | 3 + .../src/DeferredLightingEffect.cpp | 66 +--------- .../render-utils/src/DeferredLightingEffect.h | 11 -- .../render-utils/src/RenderDeferredTask.cpp | 25 ++-- .../render-utils/src/RenderDeferredTask.h | 3 + .../render-utils/src/RenderPipelines.cpp | 1 + .../render-utils/src/directional_light.slf | 47 ------- .../src/directional_light_shadow.slf | 49 -------- libraries/render-utils/src/point_light.slf | 85 ------------- libraries/render-utils/src/spot_light.slf | 115 ------------------ 12 files changed, 49 insertions(+), 385 deletions(-) create mode 100644 libraries/gpu/src/gpu/DrawVertexPosition.slv delete mode 100644 libraries/render-utils/src/directional_light.slf delete mode 100644 libraries/render-utils/src/directional_light_shadow.slf delete mode 100644 libraries/render-utils/src/point_light.slf delete mode 100644 libraries/render-utils/src/spot_light.slf diff --git a/libraries/gpu/src/gpu/DrawVertexPosition.slv b/libraries/gpu/src/gpu/DrawVertexPosition.slv new file mode 100644 index 0000000000..b12280d577 --- /dev/null +++ b/libraries/gpu/src/gpu/DrawVertexPosition.slv @@ -0,0 +1,19 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw the fed vertex position, pass straight as clip pos +// Output the clip position +// +// Created by Sam Gateau on 5/30/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 +// + +layout(location = 0) in vec4 inPosition; + +void main(void) { + gl_Position = inPosition; +} diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp index cc92719a06..36ad548cfa 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.cpp +++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp @@ -16,6 +16,7 @@ #include "DrawTransformUnitQuad_vert.h" #include "DrawTexcoordRectTransformUnitQuad_vert.h" #include "DrawViewportQuadTransformTexcoord_vert.h" +#include "DrawVertexPosition_vert.h" #include "DrawTransformVertexPosition_vert.h" #include "DrawWhite_frag.h" #include "DrawTexture_frag.h" @@ -28,6 +29,7 @@ ShaderPointer StandardShaderLib::_drawUnitQuadTexcoordVS; ShaderPointer StandardShaderLib::_drawTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawTexcoordRectTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawViewportQuadTransformTexcoordVS; +ShaderPointer StandardShaderLib::_drawVertexPositionVS; ShaderPointer StandardShaderLib::_drawTransformVertexPositionVS; ShaderPointer StandardShaderLib::_drawWhitePS; ShaderPointer StandardShaderLib::_drawTexturePS; @@ -88,6 +90,14 @@ ShaderPointer StandardShaderLib::getDrawViewportQuadTransformTexcoordVS() { } return _drawViewportQuadTransformTexcoordVS; } + +ShaderPointer StandardShaderLib::getDrawVertexPositionVS() { + if (!_drawVertexPositionVS) { + _drawVertexPositionVS = gpu::Shader::createVertex(std::string(DrawVertexPosition_vert)); + } + return _drawVertexPositionVS; +} + ShaderPointer StandardShaderLib::getDrawTransformVertexPositionVS() { if (!_drawTransformVertexPositionVS) { _drawTransformVertexPositionVS = gpu::Shader::createVertex(std::string(DrawTransformVertexPosition_vert)); diff --git a/libraries/gpu/src/gpu/StandardShaderLib.h b/libraries/gpu/src/gpu/StandardShaderLib.h index 677ad8c7a1..485e5bbbf9 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.h +++ b/libraries/gpu/src/gpu/StandardShaderLib.h @@ -39,6 +39,7 @@ public: // Shader draw the fed vertex position and transform it by the full model transform stack (Model, View, Proj). // simply output the world pos and the clip pos to the next stage + static ShaderPointer getDrawVertexPositionVS(); static ShaderPointer getDrawTransformVertexPositionVS(); static ShaderPointer getDrawWhitePS(); @@ -56,6 +57,8 @@ protected: static ShaderPointer _drawTransformUnitQuadVS; static ShaderPointer _drawTexcoordRectTransformUnitQuadVS; static ShaderPointer _drawViewportQuadTransformTexcoordVS; + + static ShaderPointer _drawVertexPositionVS; static ShaderPointer _drawTransformVertexPositionVS; static ShaderPointer _drawWhitePS; diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 9d839d6ee1..025274e66d 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -27,18 +27,15 @@ #include "deferred_light_point_vert.h" #include "deferred_light_spot_vert.h" -#include "directional_light_frag.h" #include "directional_ambient_light_frag.h" #include "directional_skybox_light_frag.h" -#include "directional_light_shadow_frag.h" #include "directional_ambient_light_shadow_frag.h" #include "directional_skybox_light_shadow_frag.h" #include "local_lights_shading_frag.h" #include "local_lights_drawOutline_frag.h" -#include "point_light_frag.h" -#include "spot_light_frag.h" + using namespace render; @@ -82,48 +79,26 @@ enum DeferredShader_BufferSlot { }; static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations); -static void loadLightVolumeProgram(const char* vertSource, const char* fragSource, bool front, gpu::PipelinePointer& program, LightLocationsPtr& locations); - -const char no_light_frag[] = -R"SCRIBE( -out vec4 _fragColor; - -void main(void) { - _fragColor = vec4(1.0, 1.0, 1.0, 1.0); -} -)SCRIBE" -; void DeferredLightingEffect::init() { - _directionalLightLocations = std::make_shared(); _directionalAmbientSphereLightLocations = std::make_shared(); _directionalSkyboxLightLocations = std::make_shared(); - _directionalLightShadowLocations = std::make_shared(); _directionalAmbientSphereLightShadowLocations = std::make_shared(); _directionalSkyboxLightShadowLocations = std::make_shared(); _localLightLocations = std::make_shared(); _localLightOutlineLocations = std::make_shared(); - _pointLightLocations = std::make_shared(); - _spotLightLocations = std::make_shared(); - loadLightProgram(deferred_light_vert, directional_light_frag, false, _directionalLight, _directionalLightLocations); loadLightProgram(deferred_light_vert, directional_ambient_light_frag, false, _directionalAmbientSphereLight, _directionalAmbientSphereLightLocations); loadLightProgram(deferred_light_vert, directional_skybox_light_frag, false, _directionalSkyboxLight, _directionalSkyboxLightLocations); - loadLightProgram(deferred_light_vert, directional_light_shadow_frag, false, _directionalLightShadow, _directionalLightShadowLocations); loadLightProgram(deferred_light_vert, directional_ambient_light_shadow_frag, false, _directionalAmbientSphereLightShadow, _directionalAmbientSphereLightShadowLocations); loadLightProgram(deferred_light_vert, directional_skybox_light_shadow_frag, false, _directionalSkyboxLightShadow, _directionalSkyboxLightShadowLocations); loadLightProgram(deferred_light_vert, local_lights_shading_frag, true, _localLight, _localLightLocations); loadLightProgram(deferred_light_vert, local_lights_drawOutline_frag, true, _localLightOutline, _localLightOutlineLocations); - loadLightVolumeProgram(deferred_light_point_vert, no_light_frag, false, _pointLightBack, _pointLightLocations); - loadLightVolumeProgram(deferred_light_point_vert, no_light_frag, true, _pointLightFront, _pointLightLocations); - loadLightVolumeProgram(deferred_light_spot_vert, no_light_frag, false, _spotLightBack, _spotLightLocations); - loadLightVolumeProgram(deferred_light_spot_vert, no_light_frag, true, _spotLightFront, _spotLightLocations); - // Light Stage and clusters _lightStage = std::make_shared(); @@ -290,39 +265,6 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo } - -static void loadLightVolumeProgram(const char* vertSource, const char* fragSource, bool front, gpu::PipelinePointer& pipeline, LightLocationsPtr& locations) { - gpu::ShaderPointer program = makeLightProgram(vertSource, fragSource, locations); - - auto state = std::make_shared(); - - // Stencil test all the light passes for objects pixels only, not the background - - if (front) { - state->setCullMode(gpu::State::CULL_BACK); - state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_DECR, gpu::State::STENCIL_OP_KEEP)); - - // state->setDepthClampEnable(true); - // TODO: We should use DepthClamp and avoid changing geometry for inside /outside cases - // additive blending - // state->setBlendFunction(true, gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::ONE); - - //state->setColorWriteMask(true, true, true, false); - state->setColorWriteMask(false, false, false, false); - } else { - state->setCullMode(gpu::State::CULL_FRONT); - state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_KEEP)); - // additive blending - // state->setBlendFunction(true, gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::ONE); - // state->setColorWriteMask(true, true, true, false); - state->setColorWriteMask(false, false, false, false); - } - pipeline = gpu::Pipeline::create(program, state); - -} - void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light) { /* auto globalLight = _allocatedLights.front(); globalLight->setDirection(light->getDirection()); @@ -535,7 +477,7 @@ void PrepareDeferred::run(const RenderContextPointer& renderContext, const Input gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_COLOR1 | gpu::Framebuffer::BUFFER_COLOR2 | gpu::Framebuffer::BUFFER_COLOR3 | gpu::Framebuffer::BUFFER_DEPTH | gpu::Framebuffer::BUFFER_STENCIL, - vec4(vec3(0), 0), 1.0, 0.0, true); + vec4(vec3(0), 0), 1.0, 0, true); // For the rest of the rendering, bind the lighting model batch.setUniformBuffer(LIGHTING_MODEL_BUFFER_SLOT, lightingModel->getParametersBuffer()); @@ -619,8 +561,8 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, batch.setResourceTexture(SHADOW_MAP_UNIT, globalShadow->map); } - auto& program = deferredLightingEffect->_shadowMapEnabled ? deferredLightingEffect->_directionalLightShadow : deferredLightingEffect->_directionalLight; - LightLocationsPtr locations = deferredLightingEffect->_shadowMapEnabled ? deferredLightingEffect->_directionalLightShadowLocations : deferredLightingEffect->_directionalLightLocations; + auto& program = deferredLightingEffect->_directionalSkyboxLight; + LightLocationsPtr locations = deferredLightingEffect->_directionalSkyboxLightLocations; const auto& keyLight = deferredLightingEffect->_allocatedLights[deferredLightingEffect->_globalLights.front()]; // Setup the global directional pass pipeline diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 2f4f9901c3..c171973216 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -82,32 +82,21 @@ private: gpu::PipelinePointer _directionalSkyboxLight; gpu::PipelinePointer _directionalAmbientSphereLight; - gpu::PipelinePointer _directionalLight; gpu::PipelinePointer _directionalSkyboxLightShadow; gpu::PipelinePointer _directionalAmbientSphereLightShadow; - gpu::PipelinePointer _directionalLightShadow; gpu::PipelinePointer _localLight; gpu::PipelinePointer _localLightOutline; - gpu::PipelinePointer _pointLightBack; - gpu::PipelinePointer _pointLightFront; - gpu::PipelinePointer _spotLightBack; - gpu::PipelinePointer _spotLightFront; - LightLocationsPtr _directionalSkyboxLightLocations; LightLocationsPtr _directionalAmbientSphereLightLocations; - LightLocationsPtr _directionalLightLocations; LightLocationsPtr _directionalSkyboxLightShadowLocations; LightLocationsPtr _directionalAmbientSphereLightShadowLocations; - LightLocationsPtr _directionalLightShadowLocations; LightLocationsPtr _localLightLocations; LightLocationsPtr _localLightOutlineLocations; - LightLocationsPtr _pointLightLocations; - LightLocationsPtr _spotLightLocations; using Lights = std::vector; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 60fd6e2f64..0fbe35025d 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -85,7 +85,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren const auto deferredFramebuffer = prepareDeferredOutputs.getN(0); const auto lightingFramebuffer = prepareDeferredOutputs.getN(1); - // draw a stencil mask in hidden regions of the frmaebuffer. + // draw a stencil mask in hidden regions of the framebuffer. + task.addJob("PrepareStencil", primaryFramebuffer); // Render opaque objects in DeferredBuffer const auto opaqueInputs = DrawStateSortDeferred::Inputs(opaques, lightingModel).hasVarying(); @@ -93,7 +94,6 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren // Once opaque is all rendered create stencil background task.addJob("DrawOpaqueStencil", deferredFramebuffer); - task.addJob("PrepareStencil", primaryFramebuffer); task.addJob("OpaqueRangeTimer", opaqueRangeTimer); @@ -401,7 +401,7 @@ gpu::PipelinePointer DrawStencilDeferred::getOpaquePipeline() { auto state = std::make_shared(); state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setColorWriteMask(0); _opaquePipeline = gpu::Pipeline::create(program, state); @@ -410,6 +410,7 @@ gpu::PipelinePointer DrawStencilDeferred::getOpaquePipeline() { } void DrawStencilDeferred::run(const RenderContextPointer& renderContext, const DeferredFramebufferPointer& deferredFramebuffer) { + // return; assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); @@ -474,15 +475,14 @@ void DrawBackgroundDeferred::run(const RenderContextPointer& renderContext, cons gpu::PipelinePointer PrepareStencil::getDrawStencilPipeline() { if (!_drawStencilPipeline) { - const gpu::int8 STENCIL_OPAQUE = 1; - auto vs = gpu::StandardShaderLib::getDrawTransformVertexPositionVS(); + auto vs = gpu::StandardShaderLib::getDrawVertexPositionVS(); auto ps = gpu::StandardShaderLib::getDrawWhitePS(); auto program = gpu::Shader::createProgram(vs, ps); gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_KEEP)); - state->setColorWriteMask(0); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + // state->setColorWriteMask(0); _drawStencilPipeline = gpu::Pipeline::create(program, state); } @@ -499,9 +499,7 @@ model::MeshPointer PrepareStencil::getMesh() { { 1.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f } }; std::vector indices { 0, 7, 1, 1, 3, 2, 3, 5, 4, 5, 7, 6 }; - _mesh = model::Mesh::createIndexedTriangles_P3F((uint32_t) vertices.size(), (uint32_t) indices.size(), vertices.data(), indices.data()); - } return _mesh; } @@ -514,19 +512,14 @@ void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::F RenderArgs* args = renderContext->args; doInBatch(args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; + batch.enableStereo(false); batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); - - batch.resetViewTransform(); - batch.setModelTransform(Transform()); - glm::mat4 proj; - batch.setProjectionTransform(proj); batch.setPipeline(getDrawStencilPipeline()); auto mesh = getMesh(); - batch.setIndexBuffer(gpu::UINT32, (mesh->getIndexBuffer()._buffer), 0); + batch.setIndexBuffer(mesh->getIndexBuffer()); batch.setInputFormat((mesh->getVertexFormat())); batch.setInputStream(0, mesh->getVertexStream()); diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index bba1b26404..c978a5f9a3 100644 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -191,6 +191,9 @@ public: using JobModel = render::Job::ModelI; void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& dstFramebuffer); + + static const gpu::int8 STENCIL_MASK = 64; + private: gpu::PipelinePointer _drawStencilPipeline; gpu::PipelinePointer getDrawStencilPipeline(); diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index da264cbf7d..c83e5c5f34 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -330,6 +330,7 @@ void addPlumberPipeline(ShapePlumber& plumber, bool isWireframed = (i & 4); auto state = std::make_shared(); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::GREATER, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_INCR_SAT)); // Depth test depends on transparency state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL); diff --git a/libraries/render-utils/src/directional_light.slf b/libraries/render-utils/src/directional_light.slf deleted file mode 100644 index cda03b0779..0000000000 --- a/libraries/render-utils/src/directional_light.slf +++ /dev/null @@ -1,47 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// directional_light.frag -// fragment shader -// -// Created by Andrzej Kapolka on 9/3/14. -// Copyright 2016 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 -// - -<@include DeferredBufferRead.slh@> -<@include DeferredGlobalLight.slh@> - -<$declareEvalLightmappedColor()$> -<$declareEvalAmbientGlobalColor()$> - -in vec2 _texCoord0; -out vec4 _fragColor; - -void main(void) { - DeferredFrameTransform deferredTransform = getDeferredFrameTransform(); - DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); - - float shadowAttenuation = 1.0; - - if (frag.mode == FRAG_MODE_UNLIT) { - discard; - } else if (frag.mode == FRAG_MODE_LIGHTMAPPED) { - discard; - } else { - vec3 color = evalAmbientGlobalColor( - getViewInverse(), - shadowAttenuation, - frag.obscurance, - frag.position.xyz, - frag.normal, - frag.albedo, - frag.fresnel, - frag.metallic, - frag.roughness); - _fragColor = vec4(color, 1.0); - } -} diff --git a/libraries/render-utils/src/directional_light_shadow.slf b/libraries/render-utils/src/directional_light_shadow.slf deleted file mode 100644 index 7f98330f84..0000000000 --- a/libraries/render-utils/src/directional_light_shadow.slf +++ /dev/null @@ -1,49 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// directional_light_shadow.frag -// fragment shader -// -// Created by Zach Pomerantz on 1/18/2016. -// Copyright 2016 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 -// - -<@include Shadow.slh@> -<@include DeferredBufferRead.slh@> -<@include DeferredGlobalLight.slh@> - -<$declareEvalLightmappedColor()$> -<$declareEvalAmbientGlobalColor()$> - -in vec2 _texCoord0; -out vec4 _fragColor; - -void main(void) { - DeferredFrameTransform deferredTransform = getDeferredFrameTransform(); - DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); - - vec4 worldPos = getViewInverse() * vec4(frag.position.xyz, 1.0); - float shadowAttenuation = evalShadowAttenuation(worldPos); - - if (frag.mode == FRAG_MODE_UNLIT) { - discard; - } else if (frag.mode == FRAG_MODE_LIGHTMAPPED) { - discard; - } else { - vec3 color = evalAmbientGlobalColor( - getViewInverse(), - shadowAttenuation, - frag.obscurance, - frag.position.xyz, - frag.normal, - frag.albedo, - frag.fresnel, - frag.metallic, - frag.roughness); - _fragColor = vec4(color, 1.0); - } -} diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf deleted file mode 100644 index e646db5069..0000000000 --- a/libraries/render-utils/src/point_light.slf +++ /dev/null @@ -1,85 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// point_light.frag -// fragment shader -// -// Created by Sam Gateau on 9/18/15. -// Copyright 2014 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 -// - - -<$declareDeferredCurvature()$> - -// Everything about light -<@include model/Light.slh@> -<$declareLightBuffer()$> - -<@include LightingModel.slh@> - -<@include LightPoint.slh@> -<$declareLightingPoint(supportScattering)$> - - -uniform vec4 texcoordFrameTransform; - -in vec4 _texCoord0;!> -out vec4 _fragColor; - -void main(void) { - _fragColor = vec4(1.0, 1.0, 1.0, 1.0); - - -} diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf deleted file mode 100644 index 4cacff86c4..0000000000 --- a/libraries/render-utils/src/spot_light.slf +++ /dev/null @@ -1,115 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// spot_light.frag -// fragment shader -// -// Created by Sam Gateau on 9/18/15. -// Copyright 2014 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 -// - -// Everything about deferred buffer - - -<$declareDeferredCurvature()$> - -// Everything about light -<@include model/Light.slh@> -<$declareLightBuffer(256)$> -uniform lightIndexBuffer { - int lightIndex[256]; -}; -<@include LightingModel.slh@> - -<@include LightPoint.slh@> -<$declareLightingPoint(supportScattering)$> -<@include LightSpot.slh@> -<$declareLightingSpot(supportScattering)$> - -//uniform vec4 texcoordFrameTransform; -!> - - -//in vec4 _texCoord0; -//flat in int instanceID; -out vec4 _fragColor; - -void main(void) { - _fragColor = vec4(1.0, 1.0, 1.0, 1.0); - -// DeferredFrameTransform deferredTransform = getDeferredFrameTransform(); - - // Grab the fragment data from the uv - //vec2 texCoord = _texCoord0.st;/* / _texCoord0.q; - /*texCoord *= texcoordFrameTransform.zw; - texCoord += texcoordFrameTransform.xy;*/ - /* - vec4 fragPosition = unpackDeferredPositionFromZeye(texCoord); - DeferredFragment frag = unpackDeferredFragmentNoPosition(texCoord); - - if (frag.mode == FRAG_MODE_UNLIT) { - discard; - } - - - // frag.depthVal = depthValue; - frag.position = fragPosition; - - vec4 midNormalCurvature; - vec4 lowNormalCurvature; - if (frag.mode == FRAG_MODE_SCATTERING) { - unpackMidLowNormalCurvature(texCoord, midNormalCurvature, lowNormalCurvature); - } - - // Frag pos in world - mat4 invViewMat = getViewInverse(); - vec4 fragPos = invViewMat * fragPosition; - - // Frag to eye vec - vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); - vec3 fragEyeDir = normalize(fragEyeVector.xyz); - - int numLights = lightIndex[0]; - for (int i = 0; i < numLights; i++) { - // Need the light now - Light light = getLight(lightIndex[i + 1]); - bool isSpot = light_isSpot(light); - // Clip againgst the light volume and Make the Light vector going from fragment to light center in world space - vec4 fragLightVecLen2; - vec4 fragLightDirLen; - float cosSpotAngle; - if (isSpot) { - if (!clipFragToLightVolumeSpot(light, fragPos.xyz, fragLightVecLen2, fragLightDirLen, cosSpotAngle)) { - continue; - } - } else { - if (!clipFragToLightVolumePoint(light, fragPos.xyz, fragLightVecLen2)) { - continue; - } - } - - vec3 diffuse; - vec3 specular; - - if (isSpot) { - evalLightingSpot(diffuse, specular, light, - fragLightDirLen.xyzw, cosSpotAngle, fragEyeDir, frag.normal, frag.roughness, - frag.metallic, frag.fresnel, frag.albedo, 1.0, - frag.scattering, midNormalCurvature, lowNormalCurvature); - } else { - evalLightingPoint(diffuse, specular, light, - fragLightVecLen2.xyz, fragEyeDir, frag.normal, frag.roughness, - frag.metallic, frag.fresnel, frag.albedo, 1.0, - frag.scattering, midNormalCurvature, lowNormalCurvature); - } - - _fragColor.rgb += diffuse; - _fragColor.rgb += specular; - } - */ -} - From 58142817a12d132077515669953fd3c4087487df Mon Sep 17 00:00:00 2001 From: NeetBhagat Date: Wed, 31 May 2017 19:13:55 +0530 Subject: [PATCH 38/91] Resolve the review comments of @ZappoMan. --- interface/src/Application.cpp | 86 ++++++++++++++++++----------------- interface/src/Application.h | 14 ++---- 2 files changed, 49 insertions(+), 51 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b5733fa6f5..ac39f51d7e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -244,8 +244,8 @@ static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStanda Setting::Handle maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS); static const QString MARKETPLACE_CDN_HOSTNAME = "mpassets.highfidelity.com"; -static const int INTERVAL_TO_CHECK_HMD_MOUNTED_STATUS = 500; // milliseconds -static const QString OCULUS_RIFT_DISPLAY_PLUGIN_NAME = "Oculus Rift"; +static const int INTERVAL_TO_CHECK_HMD_WORN_STATUS = 500; // milliseconds +static const QString DISPLAY_PLUGIN_NAME_OCULUS_RIFT = "Oculus Rift"; static const QString DESKTOP_DISPLAY_PLUGIN_NAME = "Desktop"; const QHash Application::_acceptedExtensions { @@ -1341,19 +1341,38 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["active_display_plugin"] = getActiveDisplayPlugin()->getName(); properties["using_hmd"] = isHMDMode(); - if (isHMDPluginAvailable()) { - // Currently, autoswitch display mode support is only for Oculus Rift. - // If HMD Plugin is available and current display plugin is not HMD plugin - // then startHMDStandBySession to listen HMD Mounted status. - if (getActiveDisplayPlugin()->getName() != _hmdPluginName && - !_hmdPlugin->isStandBySessionActive()) { + _autoSwitchDisplayModeSupportedHMDPlugin = nullptr; + foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { + if (displayPlugin->isHmd() && + displayPlugin->getName() == DISPLAY_PLUGIN_NAME_OCULUS_RIFT) { + + // Currently auto switch display mode support is only for Oculus Rift + // To support other plugins, add a condition + // (|| displayPlugin->getName() == "Other HMD Display Plugin Name") + + _autoSwitchDisplayModeSupportedHMDPlugin = displayPlugin; + _autoSwitchDisplayModeSupportedHMDPluginName = + _autoSwitchDisplayModeSupportedHMDPlugin->getName(); + _previousHMDWornStatus = + _autoSwitchDisplayModeSupportedHMDPlugin->isDisplayVisible(); + qCDebug(interfaceapp) << "_autoSwitchModeSupportedPluginName::" + << _autoSwitchDisplayModeSupportedHMDPluginName; + break; + } + } + + if (_autoSwitchDisplayModeSupportedHMDPlugin != nullptr) { + // If HMD Plugin is available and current display plugin is not HMD plugin + // then startHMDStandBySession to poll HMD Worn status. + if (getActiveDisplayPlugin()->getName() != _autoSwitchDisplayModeSupportedHMDPluginName && + !_autoSwitchDisplayModeSupportedHMDPlugin->isStandBySessionActive()) { startHMDStandBySession(); } // Poll periodically to check whether the user has worn HMD or not. Switch Display mode accordingly. // If the user wears HMD then switch to VR mode. If the user removes HMD then switch to Desktop mode. - QTimer *switchDisplayModeTimer = new QTimer(this); - connect(switchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayMode())); - switchDisplayModeTimer->start(INTERVAL_TO_CHECK_HMD_MOUNTED_STATUS); + QTimer* autoSwitchDisplayModeTimer = new QTimer(this); + connect(autoSwitchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayMode())); + autoSwitchDisplayModeTimer->start(INTERVAL_TO_CHECK_HMD_WORN_STATUS); } auto glInfo = getGLContextData(); @@ -1585,9 +1604,10 @@ void Application::aboutToQuit() { } getActiveDisplayPlugin()->deactivate(); - if (_hmdPlugin && _hmdPlugin->isStandBySessionActive()) { - _hmdPlugin->endStandBySession(); - } + if (_autoSwitchDisplayModeSupportedHMDPlugin != nullptr + && _autoSwitchDisplayModeSupportedHMDPlugin->isStandBySessionActive()) { + _autoSwitchDisplayModeSupportedHMDPlugin->endStandBySession(); + } // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. DependencyManager::get()->hide("RunningScripts"); @@ -6752,48 +6772,30 @@ void Application::updateDisplayMode() { Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin"); } -bool Application::isHMDPluginAvailable() { - bool isHMDEnabledPluginAvailable = false; - auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); - // Currently, autoswitch display mode support is only for Oculus Rift. - foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { - if (displayPlugin->isHmd() && displayPlugin->getName() == OCULUS_RIFT_DISPLAY_PLUGIN_NAME) { - _hmdPlugin = displayPlugin; - _hmdPluginName = displayPlugin->getName(); - _hmdMountedStatus = displayPlugin->isDisplayVisible(); - isHMDEnabledPluginAvailable = true; - break; - } - } - return isHMDEnabledPluginAvailable; -} - void Application::switchDisplayMode() { - bool currentHMDMountedStatus = _hmdPlugin->isDisplayVisible(); - if (currentHMDMountedStatus != _hmdMountedStatus) { - // Switch to respective mode as soon as currenthmdMountedStatus changes - if (currentHMDMountedStatus == false && _hmdMountedStatus == true) { + bool currentHMDWornStatus = _autoSwitchDisplayModeSupportedHMDPlugin->isDisplayVisible(); + if (currentHMDWornStatus != _previousHMDWornStatus) { + // Switch to respective mode as soon as currentHMDWornStatus changes + if (currentHMDWornStatus == false && _previousHMDWornStatus == true) { qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; setActiveDisplayPlugin(DESKTOP_DISPLAY_PLUGIN_NAME); startHMDStandBySession(); } - if (currentHMDMountedStatus == true && _hmdMountedStatus == false) { + if (currentHMDWornStatus == true && _previousHMDWornStatus == false) { qCDebug(interfaceapp) << "Switching from Desktop to HMD mode"; endHMDStandBySession(); - setActiveDisplayPlugin(_hmdPluginName); + setActiveDisplayPlugin(_autoSwitchDisplayModeSupportedHMDPluginName); } } - _hmdMountedStatus = currentHMDMountedStatus; + _previousHMDWornStatus = currentHMDWornStatus; } -bool Application::startHMDStandBySession() { - bool isStandBySessionStarted = _hmdPlugin->startStandBySession(); - qCDebug(interfaceapp) << "startHMDStandBySession: " << isStandBySessionStarted; - return isStandBySessionStarted; +void Application::startHMDStandBySession() { + _autoSwitchDisplayModeSupportedHMDPlugin->startStandBySession(); } void Application::endHMDStandBySession() { - _hmdPlugin->endStandBySession(); + _autoSwitchDisplayModeSupportedHMDPlugin->endStandBySession(); } mat4 Application::getEyeProjection(int eye) const { diff --git a/interface/src/Application.h b/interface/src/Application.h index f19c2c9adf..e1fb37ef3a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -681,14 +681,10 @@ private: AudioInjector* _snapshotSoundInjector { nullptr }; SharedSoundPointer _snapshotSound; - - DisplayPluginPointer _hmdPlugin; // HMD Enabled Plugin - QString _hmdPluginName; - bool isHMDPluginAvailable(); - bool _hmdMountedStatus; // Check HMD Mounted status - bool startHMDStandBySession(); - void endHMDStandBySession(); + DisplayPluginPointer _autoSwitchDisplayModeSupportedHMDPlugin = nullptr; + QString _autoSwitchDisplayModeSupportedHMDPluginName; + bool _previousHMDWornStatus; + void startHMDStandBySession(); + void endHMDStandBySession(); }; - - #endif // hifi_Application_h From 7a47250aa7db257553711de94c7c2a7de1454246 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 31 May 2017 10:21:10 -0700 Subject: [PATCH 39/91] oops missed a comma --- interface/resources/controllers/oculus_touch.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/controllers/oculus_touch.json b/interface/resources/controllers/oculus_touch.json index 544c8bd5b8..03fc1cbefb 100644 --- a/interface/resources/controllers/oculus_touch.json +++ b/interface/resources/controllers/oculus_touch.json @@ -57,7 +57,7 @@ { "from": "OculusTouch.LeftThumbUp", "to": "Standard.LeftThumbUp" }, { "from": "OculusTouch.RightThumbUp", "to": "Standard.RightThumbUp" }, { "from": "OculusTouch.LeftIndexPoint", "to": "Standard.LeftIndexPoint" }, - { "from": "OculusTouch.RightIndexPoint", "to": "Standard.RightIndexPoint" } + { "from": "OculusTouch.RightIndexPoint", "to": "Standard.RightIndexPoint" }, { "from": "OculusTouch.Head", "to" : "Standard.Head", "when" : [ "Application.InHMD"] } ] From e37387f45c4e1f80ac431406dbd332fc0d8c7356 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 31 May 2017 14:01:09 -0700 Subject: [PATCH 40/91] sync --- interface/src/Application.cpp | 2 +- interface/src/avatar/MyAvatar.cpp | 18 +++++++++--------- interface/src/avatar/MySkeletonModel.cpp | 3 ++- .../src/scripting/HMDScriptingInterface.cpp | 3 ++- plugins/oculus/src/OculusControllerManager.cpp | 9 ++++----- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 17f9b03346..13c3605320 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3992,7 +3992,7 @@ void Application::updateMyAvatarLookAtPosition() { // I am not looking at anyone else, so just look forward if (isHMD) { glm::mat4 worldHMDMat = myAvatar->getSensorToWorldMatrix() * - (glm::mat4)myAvatar->getHeadControllerPoseInSensorFrame(); + (glm::mat4)myAvatar->getHeadControllerPoseInSensorFrame() * Matrices::Y_180; lookAtSpot = transformPoint(worldHMDMat, glm::vec3(0.0f, 0.0f, -TREE_SCALE)); } else { lookAtSpot = myAvatar->getHead()->getEyePosition() + diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 11c8c5b186..e2aadbc365 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2328,9 +2328,9 @@ glm::quat MyAvatar::getWorldBodyOrientation() const { glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { // HMD is in sensor space. - const glm::vec3 hmdPosition = getHeadControllerPoseInSensorFrame(); - const glm::quat hmdOrientation = getHeadControllerPoseInSensorFrame(); - const glm::quat hmdOrientationYawOnly = cancelOutRollAndPitch(hmdOrientation); + const glm::vec3 headPosition = getHeadControllerPoseInSensorFrame(); + const glm::quat headOrientation = (glm::quat)getHeadControllerPoseInSensorFrame() * Quaternions::Y_180; + const glm::quat headOrientationYawOnly = cancelOutRollAndPitch(headOrientation); const Rig& rig = _skeletonModel->getRig(); int rightEyeIndex = rig.indexOfJoint("RightEye"); @@ -2353,12 +2353,12 @@ glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { // eyeToNeck offset is relative full HMD orientation. // while neckToRoot offset is only relative to HMDs yaw. - // Y_180 is necessary because rig is z forward and hmdOrientation is -z forward - glm::vec3 eyeToNeck = hmdOrientation * Quaternions::Y_180 * (localNeck - localEyes); - glm::vec3 neckToRoot = hmdOrientationYawOnly * Quaternions::Y_180 * -localNeck; - glm::vec3 bodyPos = hmdPosition + eyeToNeck + neckToRoot; + // Y_180 is necessary because rig is z forward and headOrientation is -z forward + glm::vec3 eyeToNeck = headOrientation * Quaternions::Y_180 * (localNeck - localEyes); + glm::vec3 neckToRoot = headOrientationYawOnly * Quaternions::Y_180 * -localNeck; + glm::vec3 bodyPos = headPosition + eyeToNeck + neckToRoot; - return createMatFromQuatAndPos(hmdOrientationYawOnly, bodyPos); + return createMatFromQuatAndPos(headOrientationYawOnly, bodyPos); } glm::vec3 MyAvatar::getPositionForAudio() { @@ -2474,7 +2474,7 @@ bool MyAvatar::FollowHelper::shouldActivateRotation(const MyAvatar& myAvatar, co } else { const float FOLLOW_ROTATION_THRESHOLD = cosf(PI / 6.0f); // 30 degrees glm::vec2 bodyFacing = getFacingDir2D(currentBodyMatrix); - return glm::dot(myAvatar.getHeadControllerFacingMovingAverage(), bodyFacing) < FOLLOW_ROTATION_THRESHOLD; + return glm::dot(myAvatar.getHeadControllerFacingMovingAverage() * -1.0f, bodyFacing) < FOLLOW_ROTATION_THRESHOLD; } } diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 84e4a9ff83..20b9ee2850 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -59,7 +59,8 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { } else { if (qApp->isHMDMode()) { // get HMD position from sensor space into world space, and back into rig space - glm::mat4 worldHMDMat = myAvatar->getHeadControllerPoseInWorldFrame(); + // glm::mat4 worldHMDMat = myAvatar->getHeadControllerPoseInWorldFrame(); + glm::mat4 worldHMDMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); glm::mat4 rigToWorld = createMatFromQuatAndPos(getRotation(), getTranslation()); glm::mat4 worldToRig = glm::inverse(rigToWorld); glm::mat4 rigHMDMat = worldToRig * worldHMDMat; diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index d347b72d7b..ecc207a519 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -122,7 +122,8 @@ bool HMDScriptingInterface::getHUDLookAtPosition3D(glm::vec3& result) const { glm::mat4 HMDScriptingInterface::getWorldHMDMatrix() const { auto myAvatar = DependencyManager::get()->getMyAvatar(); - return myAvatar->getSensorToWorldMatrix() * (glm::mat4)myAvatar->getHeadControllerPoseInSensorFrame(); + // return myAvatar->getSensorToWorldMatrix() * (glm::mat4)myAvatar->getHeadControllerPoseInSensorFrame(); + return myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); } glm::vec3 HMDScriptingInterface::getPosition() const { diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 6042968ffc..0236ea1e62 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -19,6 +19,8 @@ #include #include +#include +#include #include @@ -313,19 +315,16 @@ void OculusControllerManager::TouchDevice::handleHeadPose(float deltaTime, auto poseId = controller::HEAD; auto& pose = _poseStateMap[poseId]; + static const glm::quat yFlip = glm::angleAxis(PI, Vectors::UNIT_Y); pose.translation = toGlm(headPose.ThePose.Position); - pose.rotation = toGlm(headPose.ThePose.Orientation); + pose.rotation = toGlm(headPose.ThePose.Orientation) * yFlip; pose.angularVelocity = toGlm(headPose.AngularVelocity); pose.velocity = toGlm(headPose.LinearVelocity); pose.valid = true; - qDebug() << "handleHeadPose" << pose.translation.x << pose.translation.y << pose.translation.z; - // transform into avatar frame glm::mat4 controllerToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat; pose = pose.transform(controllerToAvatar); - - qDebug() << "handleHeadPose after" << pose.translation.x << pose.translation.y << pose.translation.z; } void OculusControllerManager::TouchDevice::handleRotationForUntrackedHand(const controller::InputCalibrationData& inputCalibrationData, From 82d348a2efd87c39d321592ce7d66c184c5c4af1 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 31 May 2017 16:46:20 -0700 Subject: [PATCH 41/91] Stencil rejection is working, and more cleaning --- libraries/gpu/src/gpu/StandardShaderLib.cpp | 13 +- libraries/gpu/src/gpu/StandardShaderLib.h | 4 + libraries/model/src/model/Skybox.cpp | 2 +- .../src/procedural/ProceduralSkybox.cpp | 2 +- .../src/DeferredLightingEffect.cpp | 6 +- .../render-utils/src/RenderDeferredTask.cpp | 145 +----------------- .../render-utils/src/RenderDeferredTask.h | 48 ------ .../render-utils/src/RenderPipelines.cpp | 2 +- .../render-utils/src/StencilMaskPass.cpp | 123 +++++++++++++++ libraries/render-utils/src/StencilMaskPass.h | 50 ++++++ .../render-utils/src/SurfaceGeometryPass.cpp | 4 +- .../render-utils/src/drawOpaqueStencil.slf | 16 -- 12 files changed, 198 insertions(+), 217 deletions(-) create mode 100644 libraries/render-utils/src/StencilMaskPass.cpp create mode 100644 libraries/render-utils/src/StencilMaskPass.h delete mode 100644 libraries/render-utils/src/drawOpaqueStencil.slf diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp index 36ad548cfa..756070ff68 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.cpp +++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp @@ -18,6 +18,9 @@ #include "DrawViewportQuadTransformTexcoord_vert.h" #include "DrawVertexPosition_vert.h" #include "DrawTransformVertexPosition_vert.h" + +const char DrawNada_frag[] = "void main(void) {}"; // DrawNada is really simple... + #include "DrawWhite_frag.h" #include "DrawTexture_frag.h" #include "DrawTextureOpaque_frag.h" @@ -31,6 +34,7 @@ ShaderPointer StandardShaderLib::_drawTexcoordRectTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawViewportQuadTransformTexcoordVS; ShaderPointer StandardShaderLib::_drawVertexPositionVS; ShaderPointer StandardShaderLib::_drawTransformVertexPositionVS; +ShaderPointer StandardShaderLib::_drawNadaPS; ShaderPointer StandardShaderLib::_drawWhitePS; ShaderPointer StandardShaderLib::_drawTexturePS; ShaderPointer StandardShaderLib::_drawTextureOpaquePS; @@ -105,6 +109,13 @@ ShaderPointer StandardShaderLib::getDrawTransformVertexPositionVS() { return _drawTransformVertexPositionVS; } +ShaderPointer StandardShaderLib::getDrawNadaPS() { + if (!_drawNadaPS) { + _drawNadaPS = gpu::Shader::createPixel(std::string(DrawNada_frag)); + } + return _drawNadaPS; +} + ShaderPointer StandardShaderLib::getDrawWhitePS() { if (!_drawWhitePS) { _drawWhitePS = gpu::Shader::createPixel(std::string(DrawWhite_frag)); @@ -126,8 +137,6 @@ ShaderPointer StandardShaderLib::getDrawTextureOpaquePS() { return _drawTextureOpaquePS; } - - ShaderPointer StandardShaderLib::getDrawColoredTexturePS() { if (!_drawColoredTexturePS) { _drawColoredTexturePS = gpu::Shader::createPixel(std::string(DrawColoredTexture_frag)); diff --git a/libraries/gpu/src/gpu/StandardShaderLib.h b/libraries/gpu/src/gpu/StandardShaderLib.h index 485e5bbbf9..a21d4dea9a 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.h +++ b/libraries/gpu/src/gpu/StandardShaderLib.h @@ -42,6 +42,9 @@ public: static ShaderPointer getDrawVertexPositionVS(); static ShaderPointer getDrawTransformVertexPositionVS(); + // PShader does nothing, no really nothing, but still needed for defining a program triggering rasterization + static ShaderPointer getDrawNadaPS(); + static ShaderPointer getDrawWhitePS(); static ShaderPointer getDrawTexturePS(); static ShaderPointer getDrawTextureOpaquePS(); @@ -61,6 +64,7 @@ protected: static ShaderPointer _drawVertexPositionVS; static ShaderPointer _drawTransformVertexPositionVS; + static ShaderPointer _drawNadaPS; static ShaderPointer _drawWhitePS; static ShaderPointer _drawTexturePS; static ShaderPointer _drawTextureOpaquePS; diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 4901a3c61b..d327593573 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -97,7 +97,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky } auto skyState = std::make_shared(); - skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); thePipeline = gpu::Pipeline::create(skyShader, skyState); } diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index 0275a875ec..f5feb434fa 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -23,7 +23,7 @@ ProceduralSkybox::ProceduralSkybox() : model::Skybox() { _procedural._fragmentSource = skybox_frag; // Adjust the pipeline state for background using the stencil test _procedural.setDoesFade(false); - _procedural._opaqueState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + _procedural._opaqueState->setStencilTest(true, 0xFF, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } bool ProceduralSkybox::empty() { diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 025274e66d..04255fbb87 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -242,7 +242,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo state->setColorWriteMask(true, true, true, false); if (lightVolume) { - state->setStencilTest(true, 0x00, gpu::State::StencilTest(1, 0xFF, gpu::LESS_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0x00, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setCullMode(gpu::State::CULL_BACK); // state->setCullMode(gpu::State::CULL_FRONT); @@ -255,7 +255,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo } else { // Stencil test all the light passes for objects pixels only, not the background - state->setStencilTest(true, 0x00, gpu::State::StencilTest(0, 0x01, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0x00, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setCullMode(gpu::State::CULL_BACK); // additive blending @@ -477,7 +477,7 @@ void PrepareDeferred::run(const RenderContextPointer& renderContext, const Input gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_COLOR1 | gpu::Framebuffer::BUFFER_COLOR2 | gpu::Framebuffer::BUFFER_COLOR3 | gpu::Framebuffer::BUFFER_DEPTH | gpu::Framebuffer::BUFFER_STENCIL, - vec4(vec3(0), 0), 1.0, 0, true); + vec4(vec3(0), 0), 1.0, 1, true); // For the rest of the rendering, bind the lighting model batch.setUniformBuffer(LIGHTING_MODEL_BUFFER_SLOT, lightingModel->getParametersBuffer()); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 0fbe35025d..89b4b72944 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -27,6 +27,7 @@ #include #include "LightingModel.h" +#include "StencilMaskPass.h" #include "DebugDeferredBuffer.h" #include "DeferredFramebuffer.h" #include "DeferredLightingEffect.h" @@ -43,8 +44,6 @@ #include -#include "drawOpaqueStencil_frag.h" - using namespace render; extern void initOverlay3DPipelines(render::ShapePlumber& plumber); @@ -93,7 +92,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("DrawOpaqueDeferred", opaqueInputs, shapePlumber); // Once opaque is all rendered create stencil background - task.addJob("DrawOpaqueStencil", deferredFramebuffer); + task.addJob("DrawOpaqueStencil", primaryFramebuffer); task.addJob("OpaqueRangeTimer", opaqueRangeTimer); @@ -390,146 +389,6 @@ void DrawOverlay3D::run(const RenderContextPointer& renderContext, const Inputs& } } - -gpu::PipelinePointer DrawStencilDeferred::getOpaquePipeline() { - if (!_opaquePipeline) { - const gpu::int8 STENCIL_OPAQUE = 1; - auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); - auto ps = gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag)); - auto program = gpu::Shader::createProgram(vs, ps); - gpu::Shader::makeProgram((*program)); - - auto state = std::make_shared(); - state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); - state->setColorWriteMask(0); - - _opaquePipeline = gpu::Pipeline::create(program, state); - } - return _opaquePipeline; -} - -void DrawStencilDeferred::run(const RenderContextPointer& renderContext, const DeferredFramebufferPointer& deferredFramebuffer) { - // return; - assert(renderContext->args); - assert(renderContext->args->hasViewFrustum()); - - // from the touched pixel generate the stencil buffer - RenderArgs* args = renderContext->args; - doInBatch(args->_context, [&](gpu::Batch& batch) { - args->_batch = &batch; - - auto deferredFboColorDepthStencil = deferredFramebuffer->getDeferredFramebufferDepthColor(); - - - batch.enableStereo(false); - - batch.setFramebuffer(deferredFboColorDepthStencil); - batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); - - batch.setPipeline(getOpaquePipeline()); - - batch.draw(gpu::TRIANGLE_STRIP, 4); - batch.setResourceTexture(0, nullptr); - - }); - args->_batch = nullptr; -} - -void DrawBackgroundDeferred::run(const RenderContextPointer& renderContext, const Inputs& inputs) { - assert(renderContext->args); - assert(renderContext->args->hasViewFrustum()); - - const auto& inItems = inputs.get0(); - const auto& lightingModel = inputs.get1(); - if (!lightingModel->isBackgroundEnabled()) { - return; - } - - RenderArgs* args = renderContext->args; - doInBatch(args->_context, [&](gpu::Batch& batch) { - args->_batch = &batch; - // _gpuTimer.begin(batch); - - batch.enableSkybox(true); - - batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); - - glm::mat4 projMat; - Transform viewMat; - args->getViewFrustum().evalProjectionMatrix(projMat); - args->getViewFrustum().evalViewTransform(viewMat); - - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); - - renderItems(renderContext, inItems); - // _gpuTimer.end(batch); - }); - args->_batch = nullptr; - - // std::static_pointer_cast(renderContext->jobConfig)->gpuTime = _gpuTimer.getAverage(); -} - -gpu::PipelinePointer PrepareStencil::getDrawStencilPipeline() { - if (!_drawStencilPipeline) { - auto vs = gpu::StandardShaderLib::getDrawVertexPositionVS(); - auto ps = gpu::StandardShaderLib::getDrawWhitePS(); - auto program = gpu::Shader::createProgram(vs, ps); - gpu::Shader::makeProgram((*program)); - - auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); - // state->setColorWriteMask(0); - - _drawStencilPipeline = gpu::Pipeline::create(program, state); - } - return _drawStencilPipeline; -} - -model::MeshPointer PrepareStencil::getMesh() { - if (!_mesh) { - - std::vector vertices { - { -1.0f, -1.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, - { -1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, - { 1.0f, 1.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, - { 1.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f } }; - - std::vector indices { 0, 7, 1, 1, 3, 2, 3, 5, 4, 5, 7, 6 }; - _mesh = model::Mesh::createIndexedTriangles_P3F((uint32_t) vertices.size(), (uint32_t) indices.size(), vertices.data(), indices.data()); - } - return _mesh; -} - - -void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { - assert(renderContext->args); - assert(renderContext->args->_context); - - RenderArgs* args = renderContext->args; - doInBatch(args->_context, [&](gpu::Batch& batch) { - args->_batch = &batch; - batch.enableStereo(false); - - batch.setViewportTransform(args->_viewport); - - batch.setPipeline(getDrawStencilPipeline()); - - auto mesh = getMesh(); - batch.setIndexBuffer(mesh->getIndexBuffer()); - batch.setInputFormat((mesh->getVertexFormat())); - batch.setInputStream(0, mesh->getVertexStream()); - - // Draw - auto part = mesh->getPartBuffer().get(0); - batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex); - }); - args->_batch = nullptr; -} - void Blit::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { assert(renderContext->args); assert(renderContext->args->_context); diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index c978a5f9a3..fd7c5eb23b 100644 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -13,7 +13,6 @@ #define hifi_RenderDeferredTask_h #include -#include #include #include "LightingModel.h" @@ -121,35 +120,6 @@ protected: bool _stateSort; }; -class DeferredFramebuffer; -class DrawStencilDeferred { -public: - using JobModel = render::Job::ModelI>; - - void run(const render::RenderContextPointer& renderContext, const std::shared_ptr& deferredFramebuffer); - -protected: - gpu::PipelinePointer _opaquePipeline; - - gpu::PipelinePointer getOpaquePipeline(); -}; - -using DrawBackgroundDeferredConfig = render::GPUJobConfig; - -class DrawBackgroundDeferred { -public: - using Inputs = render::VaryingSet2 ; - - using Config = DrawBackgroundDeferredConfig; - using JobModel = render::Job::ModelI; - - void configure(const Config& config) {} - void run(const render::RenderContextPointer& renderContext, const Inputs& inputs); - -protected: - gpu::RangeTimerPointer _gpuTimer; -}; - class DrawOverlay3DConfig : public render::Job::Config { Q_OBJECT Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY numDrawnChanged) @@ -186,24 +156,6 @@ protected: bool _opaquePass{ true }; }; -class PrepareStencil { -public: - using JobModel = render::Job::ModelI; - - void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& dstFramebuffer); - - static const gpu::int8 STENCIL_MASK = 64; - -private: - gpu::PipelinePointer _drawStencilPipeline; - gpu::PipelinePointer getDrawStencilPipeline(); - - model::MeshPointer _mesh; - model::MeshPointer getMesh(); - -}; - - class Blit { public: using JobModel = render::Job::ModelI; diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index c83e5c5f34..9ca9187df8 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -330,7 +330,7 @@ void addPlumberPipeline(ShapePlumber& plumber, bool isWireframed = (i & 4); auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::GREATER, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_INCR_SAT)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(2, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_ZERO)); // Depth test depends on transparency state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL); diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp new file mode 100644 index 0000000000..612324a79b --- /dev/null +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -0,0 +1,123 @@ +// +// StencilMaskPass.cpp +// render-utils/src/ +// +// Created by Sam Gateau on 5/31/17. +// Copyright 2016 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 +// + +#include "StencilMaskPass.h" + +#include +#include +#include + + +#include + + +using namespace render; + +gpu::PipelinePointer DrawStencilDeferred::getOpaquePipeline() { + if (!_opaquePipeline) { + const gpu::int8 STENCIL_OPAQUE = 0; + auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); + auto ps = gpu::StandardShaderLib::getDrawNadaPS(); + auto program = gpu::Shader::createProgram(vs, ps); + gpu::Shader::makeProgram((*program)); + + auto state = std::make_shared(); + state->setDepthTest(true, false, gpu::LESS_EQUAL); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setColorWriteMask(0); + + _opaquePipeline = gpu::Pipeline::create(program, state); + } + return _opaquePipeline; +} + +void DrawStencilDeferred::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& deferredFramebuffer) { + return; + assert(renderContext->args); + assert(renderContext->args->hasViewFrustum()); + + // from the touched pixel generate the stencil buffer + RenderArgs* args = renderContext->args; + doInBatch(args->_context, [&](gpu::Batch& batch) { + args->_batch = &batch; + + batch.enableStereo(false); + + // batch.setFramebuffer(deferredFramebuffer); + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + + batch.setPipeline(getOpaquePipeline()); + + batch.draw(gpu::TRIANGLE_STRIP, 4); + batch.setResourceTexture(0, nullptr); + + }); + args->_batch = nullptr; +} + +gpu::PipelinePointer PrepareStencil::getDrawStencilPipeline() { + if (!_drawStencilPipeline) { + auto vs = gpu::StandardShaderLib::getDrawVertexPositionVS(); + auto ps = gpu::StandardShaderLib::getDrawWhitePS(); + auto program = gpu::Shader::createProgram(vs, ps); + gpu::Shader::makeProgram((*program)); + + auto state = std::make_shared(); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(2, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + // state->setColorWriteMask(0); + + _drawStencilPipeline = gpu::Pipeline::create(program, state); + } + return _drawStencilPipeline; +} + +model::MeshPointer PrepareStencil::getMesh() { + if (!_mesh) { + + std::vector vertices { + { -1.0f, -1.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, + { 1.0f, 1.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, + { 1.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f } }; + + std::vector indices { 0, 7, 1, 1, 3, 2, 3, 5, 4, 5, 7, 6 }; + _mesh = model::Mesh::createIndexedTriangles_P3F((uint32_t) vertices.size(), (uint32_t) indices.size(), vertices.data(), indices.data()); + } + return _mesh; +} + + +void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { + assert(renderContext->args); + assert(renderContext->args->_context); + + RenderArgs* args = renderContext->args; + doInBatch(args->_context, [&](gpu::Batch& batch) { + args->_batch = &batch; + batch.enableStereo(false); + + batch.setViewportTransform(args->_viewport); + + batch.setPipeline(getDrawStencilPipeline()); + + auto mesh = getMesh(); + batch.setIndexBuffer(mesh->getIndexBuffer()); + batch.setInputFormat((mesh->getVertexFormat())); + batch.setInputStream(0, mesh->getVertexStream()); + + // Draw + auto part = mesh->getPartBuffer().get(0); + batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex); + }); + args->_batch = nullptr; +} + diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h new file mode 100644 index 0000000000..bf21602462 --- /dev/null +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -0,0 +1,50 @@ +// +// StencilMaskPass.h +// render-utils/src/ +// +// Created by Sam Gateau on 5/31/17. +// Copyright 20154 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 +// +#pragma once +#ifndef hifi_StencilMaskPass_h +#define hifi_StencilMaskPass_h + +#include +#include +#include + + +class DrawStencilDeferred { +public: + using JobModel = render::Job::ModelI; + + void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& deferredFramebuffer); + +protected: + gpu::PipelinePointer _opaquePipeline; + + gpu::PipelinePointer getOpaquePipeline(); +}; + +class PrepareStencil { +public: + using JobModel = render::Job::ModelI; + + void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& dstFramebuffer); + + static const gpu::int8 STENCIL_MASK = 64; + +private: + gpu::PipelinePointer _drawStencilPipeline; + gpu::PipelinePointer getDrawStencilPipeline(); + + model::MeshPointer _mesh; + model::MeshPointer getMesh(); + +}; + + +#endif // hifi_StencilMaskPass_h diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index ef50960b7d..746c25daa5 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -224,7 +224,7 @@ const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); // Stencil test the curvature pass for objects pixels only, not the background - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setColorWriteMask(true, false, false, false); @@ -554,7 +554,7 @@ const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() { #ifdef USE_STENCIL_TEST // Stencil test the curvature pass for objects pixels only, not the background - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); #endif // Good to go add the brand new pipeline _curvaturePipeline = gpu::Pipeline::create(program, state); diff --git a/libraries/render-utils/src/drawOpaqueStencil.slf b/libraries/render-utils/src/drawOpaqueStencil.slf deleted file mode 100644 index 43e9c5c27a..0000000000 --- a/libraries/render-utils/src/drawOpaqueStencil.slf +++ /dev/null @@ -1,16 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// drawOpaqueStencil.frag -// fragment shader -// -// Created by Sam Gateau on 9/29/15. -// Copyright 2015 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 -// - -void main(void) { -} From b528c2fc60a70f9532644a11dbcc7eee8c74f851 Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Wed, 31 May 2017 19:33:14 -0700 Subject: [PATCH 42/91] Merged --- libraries/render-utils/src/DeferredLightingEffect.cpp | 5 +++-- libraries/render-utils/src/RenderPipelines.cpp | 3 ++- libraries/render-utils/src/StencilMaskPass.cpp | 7 +++---- libraries/render-utils/src/StencilMaskPass.h | 4 +++- libraries/render-utils/src/SurfaceGeometryPass.cpp | 6 +++--- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 04255fbb87..9f28240065 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -18,6 +18,7 @@ #include #include +#include "StencilMaskPass.h" #include "AbstractViewStateInterface.h" #include "GeometryCache.h" #include "TextureCache.h" @@ -242,7 +243,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo state->setColorWriteMask(true, true, true, false); if (lightVolume) { - state->setStencilTest(true, 0x00, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setCullMode(gpu::State::CULL_BACK); // state->setCullMode(gpu::State::CULL_FRONT); @@ -255,7 +256,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo } else { // Stencil test all the light passes for objects pixels only, not the background - state->setStencilTest(true, 0x00, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setCullMode(gpu::State::CULL_BACK); // additive blending diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index 9ca9187df8..be2bb0efbe 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -15,6 +15,7 @@ #include #include +#include "StencilMaskPass.h" #include "DeferredLightingEffect.h" #include "TextureCache.h" #include "render/DrawTask.h" @@ -330,7 +331,7 @@ void addPlumberPipeline(ShapePlumber& plumber, bool isWireframed = (i & 4); auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(2, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_ZERO)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_ZERO)); // Depth test depends on transparency state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL); diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index 612324a79b..6cdcfdf8d2 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -23,7 +23,6 @@ using namespace render; gpu::PipelinePointer DrawStencilDeferred::getOpaquePipeline() { if (!_opaquePipeline) { - const gpu::int8 STENCIL_OPAQUE = 0; auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); auto ps = gpu::StandardShaderLib::getDrawNadaPS(); auto program = gpu::Shader::createProgram(vs, ps); @@ -31,7 +30,7 @@ gpu::PipelinePointer DrawStencilDeferred::getOpaquePipeline() { auto state = std::make_shared(); state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setColorWriteMask(0); _opaquePipeline = gpu::Pipeline::create(program, state); @@ -67,12 +66,12 @@ void DrawStencilDeferred::run(const RenderContextPointer& renderContext, const g gpu::PipelinePointer PrepareStencil::getDrawStencilPipeline() { if (!_drawStencilPipeline) { auto vs = gpu::StandardShaderLib::getDrawVertexPositionVS(); - auto ps = gpu::StandardShaderLib::getDrawWhitePS(); + auto ps = gpu::StandardShaderLib::getDrawNadaPS(); auto program = gpu::Shader::createProgram(vs, ps); gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(2, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); // state->setColorWriteMask(0); _drawStencilPipeline = gpu::Pipeline::create(program, state); diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h index bf21602462..8c05a46efa 100644 --- a/libraries/render-utils/src/StencilMaskPass.h +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -35,7 +35,9 @@ public: void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& dstFramebuffer); - static const gpu::int8 STENCIL_MASK = 64; + static const gpu::int8 STENCIL_MASK = 2; + static const gpu::int8 STENCIL_BACKGROUND = 1; + static const gpu::int8 STENCIL_SCENE = 0; private: gpu::PipelinePointer _drawStencilPipeline; diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index 746c25daa5..a13bc2846e 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -14,7 +14,7 @@ #include #include - +#include "StencilMaskPass.h" const int DepthLinearPass_FrameTransformSlot = 0; const int DepthLinearPass_DepthMapSlot = 0; @@ -224,7 +224,7 @@ const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); // Stencil test the curvature pass for objects pixels only, not the background - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setColorWriteMask(true, false, false, false); @@ -554,7 +554,7 @@ const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() { #ifdef USE_STENCIL_TEST // Stencil test the curvature pass for objects pixels only, not the background - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); #endif // Good to go add the brand new pipeline _curvaturePipeline = gpu::Pipeline::create(program, state); From e02115bcda5b1e921847ad09e3022111ee8e3089 Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Wed, 31 May 2017 23:00:05 -0700 Subject: [PATCH 43/91] clearing up the stencil jobs --- .../render-utils/src/StencilMaskPass.cpp | 66 ++++++++++++------- libraries/render-utils/src/StencilMaskPass.h | 7 +- 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index 6cdcfdf8d2..3194dddb49 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -63,21 +63,7 @@ void DrawStencilDeferred::run(const RenderContextPointer& renderContext, const g args->_batch = nullptr; } -gpu::PipelinePointer PrepareStencil::getDrawStencilPipeline() { - if (!_drawStencilPipeline) { - auto vs = gpu::StandardShaderLib::getDrawVertexPositionVS(); - auto ps = gpu::StandardShaderLib::getDrawNadaPS(); - auto program = gpu::Shader::createProgram(vs, ps); - gpu::Shader::makeProgram((*program)); - auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); - // state->setColorWriteMask(0); - - _drawStencilPipeline = gpu::Pipeline::create(program, state); - } - return _drawStencilPipeline; -} model::MeshPointer PrepareStencil::getMesh() { if (!_mesh) { @@ -94,6 +80,37 @@ model::MeshPointer PrepareStencil::getMesh() { return _mesh; } +gpu::PipelinePointer PrepareStencil::getMeshStencilPipeline() { + if (!_meshStencilPipeline) { + auto vs = gpu::StandardShaderLib::getDrawVertexPositionVS(); + auto ps = gpu::StandardShaderLib::getDrawNadaPS(); + auto program = gpu::Shader::createProgram(vs, ps); + gpu::Shader::makeProgram((*program)); + + auto state = std::make_shared(); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + state->setColorWriteMask(0); + + _meshStencilPipeline = gpu::Pipeline::create(program, state); + } + return _meshStencilPipeline; +} + +gpu::PipelinePointer PrepareStencil::getPaintStencilPipeline() { + if (!_paintStencilPipeline) { + auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); + auto ps = gpu::StandardShaderLib::getDrawNadaPS(); + auto program = gpu::Shader::createProgram(vs, ps); + gpu::Shader::makeProgram((*program)); + + auto state = std::make_shared(); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + state->setColorWriteMask(0); + + _paintStencilPipeline = gpu::Pipeline::create(program, state); + } + return _paintStencilPipeline; +} void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { assert(renderContext->args); @@ -106,16 +123,21 @@ void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::F batch.setViewportTransform(args->_viewport); - batch.setPipeline(getDrawStencilPipeline()); + if (true) { + batch.setPipeline(getMeshStencilPipeline()); - auto mesh = getMesh(); - batch.setIndexBuffer(mesh->getIndexBuffer()); - batch.setInputFormat((mesh->getVertexFormat())); - batch.setInputStream(0, mesh->getVertexStream()); + auto mesh = getMesh(); + batch.setIndexBuffer(mesh->getIndexBuffer()); + batch.setInputFormat((mesh->getVertexFormat())); + batch.setInputStream(0, mesh->getVertexStream()); - // Draw - auto part = mesh->getPartBuffer().get(0); - batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex); + // Draw + auto part = mesh->getPartBuffer().get(0); + batch.drawIndexed(gpu::TRIANGLES, part._numIndices, part._startIndex); + } else { + batch.setPipeline(getPaintStencilPipeline()); + batch.draw(gpu::TRIANGLE_STRIP, 4); + } }); args->_batch = nullptr; } diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h index 8c05a46efa..0532e23fac 100644 --- a/libraries/render-utils/src/StencilMaskPass.h +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -40,8 +40,11 @@ public: static const gpu::int8 STENCIL_SCENE = 0; private: - gpu::PipelinePointer _drawStencilPipeline; - gpu::PipelinePointer getDrawStencilPipeline(); + gpu::PipelinePointer _meshStencilPipeline; + gpu::PipelinePointer getMeshStencilPipeline(); + + gpu::PipelinePointer _paintStencilPipeline; + gpu::PipelinePointer getPaintStencilPipeline(); model::MeshPointer _mesh; model::MeshPointer getMesh(); From c7c07b28e94bc9d0b6aa0ac767e39aacb84c0b8c Mon Sep 17 00:00:00 2001 From: NeetBhagat Date: Thu, 1 Jun 2017 12:14:54 +0530 Subject: [PATCH 44/91] Resolve the reviewed comments of @ZappoMan --- interface/src/Application.cpp | 8 +------- libraries/plugins/src/plugins/DisplayPlugin.h | 1 + plugins/oculus/src/OculusBaseDisplayPlugin.h | 1 + 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ac39f51d7e..b8bfff8c5f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -245,7 +245,6 @@ Setting::Handle maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTRE static const QString MARKETPLACE_CDN_HOSTNAME = "mpassets.highfidelity.com"; static const int INTERVAL_TO_CHECK_HMD_WORN_STATUS = 500; // milliseconds -static const QString DISPLAY_PLUGIN_NAME_OCULUS_RIFT = "Oculus Rift"; static const QString DESKTOP_DISPLAY_PLUGIN_NAME = "Desktop"; const QHash Application::_acceptedExtensions { @@ -1344,12 +1343,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _autoSwitchDisplayModeSupportedHMDPlugin = nullptr; foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { if (displayPlugin->isHmd() && - displayPlugin->getName() == DISPLAY_PLUGIN_NAME_OCULUS_RIFT) { - - // Currently auto switch display mode support is only for Oculus Rift - // To support other plugins, add a condition - // (|| displayPlugin->getName() == "Other HMD Display Plugin Name") - + displayPlugin->getSupportsAutoSwitch()) { _autoSwitchDisplayModeSupportedHMDPlugin = displayPlugin; _autoSwitchDisplayModeSupportedHMDPluginName = _autoSwitchDisplayModeSupportedHMDPlugin->getName(); diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 754c919fd4..297bdb2cca 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -200,6 +200,7 @@ public: virtual float newFramePresentRate() const { return -1.0f; } // Rate at which rendered frames are being skipped virtual float droppedFrameRate() const { return -1.0f; } + virtual bool getSupportsAutoSwitch() { return false; } // Hardware specific stats virtual QJsonObject getHardwareStats() const { return QJsonObject(); } diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h index 1f54742c2d..bfdcc5db1e 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -26,6 +26,7 @@ public: void resetSensors() override final; bool beginFrameRender(uint32_t frameIndex) override; float getTargetFrameRate() const override { return _hmdDesc.DisplayRefreshRate; } + bool getSupportsAutoSwitch() override final { return true; } protected: From ea6be93c9c872768cec0c88a029323027a10242c Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Thu, 1 Jun 2017 01:24:57 -0700 Subject: [PATCH 45/91] adding another flavor of the prepare stencil --- .../render-utils/src/StencilMaskPass.cpp | 5 +++-- libraries/render-utils/src/StencilMaskPass.h | 10 +++++++-- .../render-utils/src/stencil_drawMask.slf | 21 +++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 libraries/render-utils/src/stencil_drawMask.slf diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index 3194dddb49..358f772354 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -18,6 +18,7 @@ #include +#include "stencil_drawMask_frag.h" using namespace render; @@ -99,7 +100,7 @@ gpu::PipelinePointer PrepareStencil::getMeshStencilPipeline() { gpu::PipelinePointer PrepareStencil::getPaintStencilPipeline() { if (!_paintStencilPipeline) { auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); - auto ps = gpu::StandardShaderLib::getDrawNadaPS(); + auto ps = gpu::Shader::createPixel(std::string(stencil_drawMask_frag)); auto program = gpu::Shader::createProgram(vs, ps); gpu::Shader::makeProgram((*program)); @@ -123,7 +124,7 @@ void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::F batch.setViewportTransform(args->_viewport); - if (true) { + if (false) { batch.setPipeline(getMeshStencilPipeline()); auto mesh = getMesh(); diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h index 0532e23fac..d1de0cd1f4 100644 --- a/libraries/render-utils/src/StencilMaskPass.h +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -16,7 +16,6 @@ #include #include - class DrawStencilDeferred { public: using JobModel = render::Job::ModelI; @@ -31,7 +30,14 @@ protected: class PrepareStencil { public: - using JobModel = render::Job::ModelI; + class Config : public render::JobConfig { + public: + Config(bool enabled = true) : JobConfig(enabled) {} + }; + + using JobModel = render::Job::ModelI; + + void configure(const Config& config) {} void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& dstFramebuffer); diff --git a/libraries/render-utils/src/stencil_drawMask.slf b/libraries/render-utils/src/stencil_drawMask.slf new file mode 100644 index 0000000000..cc81fca677 --- /dev/null +++ b/libraries/render-utils/src/stencil_drawMask.slf @@ -0,0 +1,21 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// stencil_drawMask.slf +// fragment shader +// +// Created by Sam Gateau on 5/31/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 +// + +in vec2 varTexCoord0; + +void main(void) { + vec2 pos = varTexCoord0 * 2.0 - vec2(1.0); + pos.x = pos.x * (pos.x > 0.0 ? 2.0 : -2.0) - 1.0; + if (1.0 - dot(pos.xy, pos.xy) > 0.0 ) discard; +} From eca05d9c4281cc12187c77abb698f1332f7bf434 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 1 Jun 2017 10:57:53 -0700 Subject: [PATCH 46/91] more use of head input --- interface/src/avatar/MySkeletonModel.cpp | 3 +-- interface/src/scripting/HMDScriptingInterface.cpp | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 20b9ee2850..84e4a9ff83 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -59,8 +59,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { } else { if (qApp->isHMDMode()) { // get HMD position from sensor space into world space, and back into rig space - // glm::mat4 worldHMDMat = myAvatar->getHeadControllerPoseInWorldFrame(); - glm::mat4 worldHMDMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + glm::mat4 worldHMDMat = myAvatar->getHeadControllerPoseInWorldFrame(); glm::mat4 rigToWorld = createMatFromQuatAndPos(getRotation(), getTranslation()); glm::mat4 worldToRig = glm::inverse(rigToWorld); glm::mat4 rigHMDMat = worldToRig * worldHMDMat; diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index ecc207a519..1227f46eb6 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -122,8 +122,8 @@ bool HMDScriptingInterface::getHUDLookAtPosition3D(glm::vec3& result) const { glm::mat4 HMDScriptingInterface::getWorldHMDMatrix() const { auto myAvatar = DependencyManager::get()->getMyAvatar(); - // return myAvatar->getSensorToWorldMatrix() * (glm::mat4)myAvatar->getHeadControllerPoseInSensorFrame(); - return myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + // return myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + return myAvatar->getSensorToWorldMatrix() * myAvatar->getHeadControllerPoseInSensorFrame().getMatrix() * Matrices::Y_180; } glm::vec3 HMDScriptingInterface::getPosition() const { From 9c1e99fe3f9a353b5fbaa15ecaf892c19b0fc969 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 1 Jun 2017 13:06:22 -0700 Subject: [PATCH 47/91] Removing cruft and organizing the stencil config --- .../RenderableParticleEffectEntityItem.cpp | 3 + .../src/RenderablePolyLineEntityItem.cpp | 2 + .../src/RenderablePolyVoxEntityItem.cpp | 5 + .../src/RenderableShapeEntityItem.cpp | 2 + libraries/model/src/model/Skybox.cpp | 2 +- .../src/procedural/ProceduralSkybox.cpp | 2 +- .../render-utils/src/AntialiasingEffect.cpp | 4 + .../src/DeferredLightingEffect.cpp | 4 +- libraries/render-utils/src/GeometryCache.cpp | 20 ++++ libraries/render-utils/src/HitEffect.cpp | 94 ------------------- libraries/render-utils/src/HitEffect.h | 38 -------- libraries/render-utils/src/LightClusters.cpp | 2 + .../render-utils/src/StencilMaskPass.cpp | 63 ++++--------- libraries/render-utils/src/StencilMaskPass.h | 21 ++--- .../render-utils/src/SurfaceGeometryPass.cpp | 1 + .../render-utils/src/ToneMappingEffect.cpp | 3 +- libraries/render-utils/src/ZoneRenderer.cpp | 4 + libraries/render-utils/src/hit_effect.slf | 27 ------ libraries/render-utils/src/hit_effect.slv | 26 ----- 19 files changed, 74 insertions(+), 249 deletions(-) delete mode 100644 libraries/render-utils/src/HitEffect.cpp delete mode 100644 libraries/render-utils/src/HitEffect.h delete mode 100644 libraries/render-utils/src/hit_effect.slf delete mode 100644 libraries/render-utils/src/hit_effect.slv diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 34dc86d92a..d813a73773 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "EntitiesRendererLogging.h" @@ -292,6 +293,7 @@ void RenderableParticleEffectEntityItem::createPipelines() { state->setDepthTest(true, false, gpu::LESS_EQUAL); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + PrepareStencil::testMask(*state); auto vertShader = gpu::Shader::createVertex(std::string(untextured_particle_vert)); auto fragShader = gpu::Shader::createPixel(std::string(untextured_particle_frag)); @@ -305,6 +307,7 @@ void RenderableParticleEffectEntityItem::createPipelines() { state->setDepthTest(true, false, gpu::LESS_EQUAL); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + PrepareStencil::testMask(*state); auto vertShader = gpu::Shader::createVertex(std::string(textured_particle_vert)); auto fragShader = gpu::Shader::createPixel(std::string(textured_particle_frag)); diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index a34a1814b4..1e20956301 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -69,6 +70,7 @@ void RenderablePolyLineEntityItem::createPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setDepthTest(true, true, gpu::LESS_EQUAL); + PrepareStencil::testMask(*state); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index fd5346093b..7567566919 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -46,6 +46,9 @@ #endif #include "model/Geometry.h" + +#include "StencilMaskPass.h" + #include "EntityTreeRenderer.h" #include "polyvox_vert.h" #include "polyvox_frag.h" @@ -743,6 +746,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) { auto state = std::make_shared(); state->setCullMode(gpu::State::CULL_BACK); state->setDepthTest(true, true, gpu::LESS_EQUAL); + PrepareStencil::testMaskDrawShape(*state); _pipeline = gpu::Pipeline::create(program, state); @@ -750,6 +754,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) { wireframeState->setCullMode(gpu::State::CULL_BACK); wireframeState->setDepthTest(true, true, gpu::LESS_EQUAL); wireframeState->setFillMode(gpu::State::FILL_LINE); + PrepareStencil::testMaskDrawShape(*wireframeState); _wireframePipeline = gpu::Pipeline::create(program, wireframeState); } diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 1ad60bf7c6..27dd678d91 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -93,6 +94,7 @@ void RenderableShapeEntityItem::render(RenderArgs* args) { _procedural->_fragmentSource = simple_frag; _procedural->_opaqueState->setCullMode(gpu::State::CULL_NONE); _procedural->_opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL); + PrepareStencil::testMaskDrawShape(*_procedural->_opaqueState); _procedural->_opaqueState->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index d327593573..c47463666e 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -97,7 +97,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky } auto skyState = std::make_shared(); - skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + skyState->setStencilTest(true, 0x00, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); thePipeline = gpu::Pipeline::create(skyShader, skyState); } diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index f5feb434fa..eaacc5d851 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -23,7 +23,7 @@ ProceduralSkybox::ProceduralSkybox() : model::Skybox() { _procedural._fragmentSource = skybox_frag; // Adjust the pipeline state for background using the stencil test _procedural.setDoesFade(false); - _procedural._opaqueState->setStencilTest(true, 0xFF, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + _procedural._opaqueState->setStencilTest(true, 0x00, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } bool ProceduralSkybox::empty() { diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index cd378d4e5b..08f69d07d0 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -17,6 +17,7 @@ #include #include "AntialiasingEffect.h" +#include "StencilMaskPass.h" #include "TextureCache.h" #include "FramebufferCache.h" #include "DependencyManager.h" @@ -70,6 +71,8 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + PrepareStencil::testShape(*state); + state->setDepthTest(false, false, gpu::LESS_EQUAL); // Good to go add the brand new pipeline @@ -93,6 +96,7 @@ const gpu::PipelinePointer& Antialiasing::getBlendPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setDepthTest(false, false, gpu::LESS_EQUAL); + PrepareStencil::testShape(*state); // Good to go add the brand new pipeline _blendPipeline = gpu::Pipeline::create(program, state); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 9f28240065..36a9401d00 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -243,7 +243,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo state->setColorWriteMask(true, true, true, false); if (lightVolume) { - state->setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testShape(*state); state->setCullMode(gpu::State::CULL_BACK); // state->setCullMode(gpu::State::CULL_FRONT); @@ -256,7 +256,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo } else { // Stencil test all the light passes for objects pixels only, not the background - state->setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testShape(*state); state->setCullMode(gpu::State::CULL_BACK); // additive blending diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index f1c995b943..5755d5a031 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -24,6 +24,7 @@ #include "TextureCache.h" #include "RenderUtilsLogging.h" +#include "StencilMaskPass.h" #include "gpu/StandardShaderLib.h" @@ -1610,6 +1611,9 @@ void GeometryCache::renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + + PrepareStencil::testMask(*state); + gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("lineData"), LINE_DATA_SLOT)); gpu::Shader::makeProgram(*program, slotBindings); @@ -1663,11 +1667,14 @@ void GeometryCache::useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend) { // enable decal blend state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); + PrepareStencil::testMask(*state); _standardDrawPipeline = gpu::Pipeline::create(program, state); auto stateNoBlend = std::make_shared(); + PrepareStencil::testMaskDrawShape(*state); + auto noBlendPS = gpu::StandardShaderLib::getDrawTextureOpaquePS(); auto programNoBlend = gpu::Shader::createProgram(vs, noBlendPS); gpu::Shader::makeProgram((*programNoBlend)); @@ -1690,12 +1697,14 @@ void GeometryCache::useGridPipeline(gpu::Batch& batch, GridBuffer gridBuffer, bo auto stateLayered = std::make_shared(); stateLayered->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); + PrepareStencil::testMask(*stateLayered); _gridPipelineLayered = gpu::Pipeline::create(program, stateLayered); auto state = std::make_shared(stateLayered->getValues()); const float DEPTH_BIAS = 0.001f; state->setDepthBias(DEPTH_BIAS); state->setDepthTest(true, false, gpu::LESS_EQUAL); + PrepareStencil::testMaskDrawShape(*state); _gridPipeline = gpu::Pipeline::create(program, state); } @@ -1773,6 +1782,11 @@ static void buildWebShader(const std::string& vertShaderText, const std::string& state->setBlendFunction(blendEnable, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + if (blendEnable) { + PrepareStencil::testMaskBlendShape(*state); + } else { + PrepareStencil::testMaskDrawShape(*state); + } pipelinePointerOut = gpu::Pipeline::create(shaderPointerOut, state); } @@ -1858,6 +1872,12 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + if (config.isTransparent()) { + PrepareStencil::testMask(*state); + } else { + PrepareStencil::testMaskDrawShape(*state); + } + gpu::ShaderPointer program = (config.isUnlit()) ? _unlitShader : _simpleShader; gpu::PipelinePointer pipeline = gpu::Pipeline::create(program, state); _simplePrograms.insert(config, pipeline); diff --git a/libraries/render-utils/src/HitEffect.cpp b/libraries/render-utils/src/HitEffect.cpp deleted file mode 100644 index 319e94384f..0000000000 --- a/libraries/render-utils/src/HitEffect.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// -// HitEffect.cpp -// interface/src/renderer -// -// Created by Andrzej Kapolka on 7/14/13. -// Copyright 2013 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 -// - -// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL - - -#include - -#include -#include -#include - -#include "AbstractViewStateInterface.h" -#include "HitEffect.h" - -#include "TextureCache.h" -#include "DependencyManager.h" -#include "ViewFrustum.h" -#include "GeometryCache.h" - -#include - -#include "hit_effect_vert.h" -#include "hit_effect_frag.h" - - -HitEffect::HitEffect() { - _geometryId = DependencyManager::get()->allocateID(); -} - -HitEffect::~HitEffect() { - auto geometryCache = DependencyManager::get(); - if (_geometryId && geometryCache) { - geometryCache->releaseID(_geometryId); - } -} - -const gpu::PipelinePointer& HitEffect::getHitEffectPipeline() { - if (!_hitEffectPipeline) { - auto vs = gpu::Shader::createVertex(std::string(hit_effect_vert)); - auto ps = gpu::Shader::createPixel(std::string(hit_effect_frag)); - gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); - - - gpu::Shader::BindingSet slotBindings; - gpu::Shader::makeProgram(*program, slotBindings); - - - gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - - state->setDepthTest(false, false, gpu::LESS_EQUAL); - - // Blend on transparent - state->setBlendFunction(true, - gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); - - // Good to go add the brand new pipeline - _hitEffectPipeline = gpu::Pipeline::create(program, state); - } - return _hitEffectPipeline; -} - -void HitEffect::run(const render::RenderContextPointer& renderContext) { - assert(renderContext->args); - assert(renderContext->args->hasViewFrustum()); - RenderArgs* args = renderContext->args; - - gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { - - glm::mat4 projMat; - Transform viewMat; - args->getViewFrustum().evalProjectionMatrix(projMat); - args->getViewFrustum().evalViewTransform(viewMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); - batch.setModelTransform(Transform()); - - batch.setPipeline(getHitEffectPipeline()); - - static const glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f); - static const glm::vec2 bottomLeft(-1.0f, -1.0f); - static const glm::vec2 topRight(1.0f, 1.0f); - DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, color, _geometryId); - }); -} - diff --git a/libraries/render-utils/src/HitEffect.h b/libraries/render-utils/src/HitEffect.h deleted file mode 100644 index d025d2d980..0000000000 --- a/libraries/render-utils/src/HitEffect.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// hitEffect.h -// hifi -// -// Created by eric levin on 7/17/15. -// -// - -#ifndef hifi_hitEffect_h -#define hifi_hitEffect_h - -#include - -class HitEffectConfig : public render::Job::Config { - Q_OBJECT - Q_PROPERTY(bool enabled MEMBER enabled) -public: - HitEffectConfig() : render::Job::Config(false) {} -}; - -class HitEffect { -public: - using Config = HitEffectConfig; - using JobModel = render::Job::Model; - - HitEffect(); - ~HitEffect(); - void configure(const Config& config) {} - void run(const render::RenderContextPointer& renderContext); - - const gpu::PipelinePointer& getHitEffectPipeline(); - -private: - int _geometryId { 0 }; - gpu::PipelinePointer _hitEffectPipeline; -}; - -#endif diff --git a/libraries/render-utils/src/LightClusters.cpp b/libraries/render-utils/src/LightClusters.cpp index 4145264b2d..7e04b1c2a4 100644 --- a/libraries/render-utils/src/LightClusters.cpp +++ b/libraries/render-utils/src/LightClusters.cpp @@ -16,6 +16,8 @@ #include +#include "StencilMaskPass.h" + #include "lightClusters_drawGrid_vert.h" #include "lightClusters_drawGrid_frag.h" diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index 358f772354..44e7a571e8 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -22,50 +22,6 @@ using namespace render; -gpu::PipelinePointer DrawStencilDeferred::getOpaquePipeline() { - if (!_opaquePipeline) { - auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); - auto ps = gpu::StandardShaderLib::getDrawNadaPS(); - auto program = gpu::Shader::createProgram(vs, ps); - gpu::Shader::makeProgram((*program)); - - auto state = std::make_shared(); - state->setDepthTest(true, false, gpu::LESS_EQUAL); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); - state->setColorWriteMask(0); - - _opaquePipeline = gpu::Pipeline::create(program, state); - } - return _opaquePipeline; -} - -void DrawStencilDeferred::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& deferredFramebuffer) { - return; - assert(renderContext->args); - assert(renderContext->args->hasViewFrustum()); - - // from the touched pixel generate the stencil buffer - RenderArgs* args = renderContext->args; - doInBatch(args->_context, [&](gpu::Batch& batch) { - args->_batch = &batch; - - batch.enableStereo(false); - - // batch.setFramebuffer(deferredFramebuffer); - batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); - - batch.setPipeline(getOpaquePipeline()); - - batch.draw(gpu::TRIANGLE_STRIP, 4); - batch.setResourceTexture(0, nullptr); - - }); - args->_batch = nullptr; -} - - - model::MeshPointer PrepareStencil::getMesh() { if (!_mesh) { @@ -89,7 +45,7 @@ gpu::PipelinePointer PrepareStencil::getMeshStencilPipeline() { gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + drawMask(state); state->setColorWriteMask(0); _meshStencilPipeline = gpu::Pipeline::create(program, state); @@ -105,7 +61,7 @@ gpu::PipelinePointer PrepareStencil::getPaintStencilPipeline() { gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + drawMask(state); state->setColorWriteMask(0); _paintStencilPipeline = gpu::Pipeline::create(program, state); @@ -143,3 +99,18 @@ void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::F args->_batch = nullptr; } +void PrepareStencil::drawMask(gpu::State& state) { + state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); +} + +void PrepareStencil::testMask(gpu::State& state) { + state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); +} + +void PrepareStencil::testBackground(gpu::State& state) { + state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_BACKGROUND, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); +} + +void PrepareStencil::testMaskDrawShape(gpu::State& state) { + state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_ZERO)); +} \ No newline at end of file diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h index d1de0cd1f4..c65788ebf8 100644 --- a/libraries/render-utils/src/StencilMaskPass.h +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -16,18 +16,6 @@ #include #include -class DrawStencilDeferred { -public: - using JobModel = render::Job::ModelI; - - void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& deferredFramebuffer); - -protected: - gpu::PipelinePointer _opaquePipeline; - - gpu::PipelinePointer getOpaquePipeline(); -}; - class PrepareStencil { public: class Config : public render::JobConfig { @@ -43,7 +31,14 @@ public: static const gpu::int8 STENCIL_MASK = 2; static const gpu::int8 STENCIL_BACKGROUND = 1; - static const gpu::int8 STENCIL_SCENE = 0; + static const gpu::int8 STENCIL_SHAPE = 0; + + + static void drawMask(gpu::State& state); + static void testMask(gpu::State& state); + static void testBackground(gpu::State& state); + static void testMaskDrawShape(gpu::State& state); + private: gpu::PipelinePointer _meshStencilPipeline; diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index a13bc2846e..4b13fa2bf0 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -250,6 +250,7 @@ const gpu::PipelinePointer& LinearDepthPass::getDownsamplePipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setColorWriteMask(true, true, true, false); diff --git a/libraries/render-utils/src/ToneMappingEffect.cpp b/libraries/render-utils/src/ToneMappingEffect.cpp index d54481d246..df4e1e0e6a 100644 --- a/libraries/render-utils/src/ToneMappingEffect.cpp +++ b/libraries/render-utils/src/ToneMappingEffect.cpp @@ -15,7 +15,7 @@ #include #include - +#include "StencilMaskPass.h" #include "FramebufferCache.h" #include "toneMapping_frag.h" @@ -39,6 +39,7 @@ void ToneMappingEffect::init() { slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), ToneMappingEffect_LightingMapSlot)); gpu::Shader::makeProgram(*blitProgram, slotBindings); auto blitState = std::make_shared(); + blitState->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); blitState->setColorWriteMask(true, true, true, true); _blitLightBuffer = gpu::PipelinePointer(gpu::Pipeline::create(blitProgram, blitState)); } diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 3b4870fd3f..2fa6805cde 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -17,6 +17,7 @@ #include #include +#include "StencilMaskPass.h" #include "DeferredLightingEffect.h" #include "zone_drawKeyLight_frag.h" @@ -74,6 +75,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _keyLightPipeline = gpu::Pipeline::create(program, state); } @@ -95,6 +97,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getAmbientPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _ambientPipeline = gpu::Pipeline::create(program, state); } @@ -115,6 +118,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getBackgroundPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _backgroundPipeline = gpu::Pipeline::create(program, state); } diff --git a/libraries/render-utils/src/hit_effect.slf b/libraries/render-utils/src/hit_effect.slf deleted file mode 100644 index cc4484442f..0000000000 --- a/libraries/render-utils/src/hit_effect.slf +++ /dev/null @@ -1,27 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// - -// hit_effect.frag -// fragment shader -// -// Created by Eric Levin on 7/20 -// Copyright 2015 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 -// - - -<@include DeferredBufferWrite.slh@> - -in vec2 varQuadPosition; -out vec4 outFragColor; - -void main(void) { - vec2 center = vec2(0.0, 0.0); - float distFromCenter = distance( vec2(0.0, 0.0), varQuadPosition); - float alpha = mix(0.0, 0.5, pow(distFromCenter,5.)); - outFragColor = vec4(1.0, 0.0, 0.0, alpha); -} \ No newline at end of file diff --git a/libraries/render-utils/src/hit_effect.slv b/libraries/render-utils/src/hit_effect.slv deleted file mode 100644 index b9b0638f9e..0000000000 --- a/libraries/render-utils/src/hit_effect.slv +++ /dev/null @@ -1,26 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// hit_effect.vert -// vertex shader -// -// Created by Eric Levin on 7/20/15. -// Copyright 2015 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 -// - -<@include gpu/Inputs.slh@> - -<@include gpu/Transform.slh@> - -<$declareStandardTransform()$> - -out vec2 varQuadPosition; - -void main(void) { - varQuadPosition = inPosition.xy; - gl_Position = inPosition; -} \ No newline at end of file From ac6135387cf3a520851e4acc9d709c3c4ad6175c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 1 Jun 2017 13:37:16 -0700 Subject: [PATCH 48/91] display plugins are never head controllers --- interface/src/Application.cpp | 5 ----- interface/src/avatar/MySkeletonModel.cpp | 2 +- .../Basic2DWindowOpenGLDisplayPlugin.h | 2 -- .../display-plugins/hmd/DebugHmdDisplayPlugin.h | 2 -- .../src/display-plugins/hmd/HmdDisplayPlugin.h | 1 - .../stereo/InterleavedStereoDisplayPlugin.h | 2 -- .../stereo/SideBySideStereoDisplayPlugin.h | 2 -- libraries/plugins/src/plugins/DisplayPlugin.h | 1 - libraries/plugins/src/plugins/PluginUtils.cpp | 5 ----- plugins/oculus/src/OculusControllerManager.cpp | 14 ++++++++++++-- plugins/oculus/src/OculusControllerManager.h | 2 +- plugins/oculus/src/OculusDebugDisplayPlugin.h | 2 -- plugins/oculus/src/OculusDisplayPlugin.h | 2 -- plugins/openvr/src/OpenVrDisplayPlugin.h | 2 -- 14 files changed, 14 insertions(+), 30 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6d34de2b0e..aee829b624 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4865,11 +4865,6 @@ bool Application::isHeadControllerEnabled() const { return true; } } - foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { - if (displayPlugin->isActive() && displayPlugin->isHeadController()) { - return true; - } - } return false; } diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 84e4a9ff83..3721eea569 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -59,7 +59,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { } else { if (qApp->isHMDMode()) { // get HMD position from sensor space into world space, and back into rig space - glm::mat4 worldHMDMat = myAvatar->getHeadControllerPoseInWorldFrame(); + glm::mat4 worldHMDMat = myAvatar->getHeadControllerPoseInWorldFrame().getMatrix(); glm::mat4 rigToWorld = createMatFromQuatAndPos(getRotation(), getTranslation()); glm::mat4 worldToRig = glm::inverse(rigToWorld); glm::mat4 rigHMDMat = worldToRig * worldHMDMat; diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h index 8dc1d83c1b..f3dd50602c 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h @@ -26,8 +26,6 @@ public: virtual bool isThrottled() const override; - virtual bool isHeadController() const override { return false; } - protected: mutable bool _isThrottled = false; diff --git a/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h index a971c25bf6..55746e65eb 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h @@ -21,8 +21,6 @@ public: bool beginFrameRender(uint32_t frameIndex) override; float getTargetFrameRate() const override { return 90; } - virtual bool isHeadController() const override { return false; } - protected: void updatePresentPose() override; void hmdPresent() override {} diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h index 7dfd0fed1e..aaa6e347e0 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h @@ -25,7 +25,6 @@ class HmdDisplayPlugin : public OpenGLDisplayPlugin { public: ~HmdDisplayPlugin(); bool isHmd() const override final { return true; } - bool isHeadController() const override = 0; float getIPD() const override final { return _ipd; } glm::mat4 getEyeToHeadTransform(Eye eye) const override final { return _eyeOffsets[eye]; } glm::mat4 getEyeProjection(Eye eye, const glm::mat4& baseProjection) const override final { return _eyeProjections[eye]; } diff --git a/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h index 4834e6c542..debd340f24 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h @@ -17,8 +17,6 @@ public: grouping getGrouping() const override { return ADVANCED; } glm::uvec2 getRecommendedRenderSize() const override; - virtual bool isHeadController() const override { return false; } - protected: // initialize OpenGL context settings needed by the plugin void customizeContext() override; diff --git a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.h index aa65fc37e3..79bf2a9ecb 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.h @@ -19,8 +19,6 @@ public: virtual grouping getGrouping() const override { return ADVANCED; } virtual glm::uvec2 getRecommendedRenderSize() const override; - virtual bool isHeadController() const override { return false; } - private: static const QString NAME; }; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 549387b6a4..754c919fd4 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -135,7 +135,6 @@ public: virtual int getRequiredThreadCount() const { return 0; } virtual bool isHmd() const { return false; } - virtual bool isHeadController() const = 0; virtual int getHmdScreen() const { return -1; } /// By default, all HMDs are stereo virtual bool isStereo() const { return isHmd(); } diff --git a/libraries/plugins/src/plugins/PluginUtils.cpp b/libraries/plugins/src/plugins/PluginUtils.cpp index 4af77156e7..ce67f7c585 100644 --- a/libraries/plugins/src/plugins/PluginUtils.cpp +++ b/libraries/plugins/src/plugins/PluginUtils.cpp @@ -30,11 +30,6 @@ bool PluginUtils::isHeadControllerAvailable(const QString& pluginName) { return true; } } - for (auto& displayPlugin : PluginManager::getInstance()->getDisplayPlugins()) { - if (displayPlugin->isHeadController() && (pluginName.isEmpty() || displayPlugin->getName() == pluginName)) { - return true; - } - } return false; }; diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 0236ea1e62..60031a1179 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -210,10 +210,20 @@ void OculusControllerManager::RemoteDevice::focusOutEvent() { _buttonPressedMap.clear(); } +bool OculusControllerManager::isHeadController() const { + // this plugin is a head controller if the HMD is mounted. + ovrSessionStatus status; + + bool success = OVR_SUCCESS(ovr_GetSessionStatus(_session, &status)); + if (!success) { + return false; + } + return status.HmdMounted == ovrTrue; +} + void OculusControllerManager::TouchDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { _buttonPressedMap.clear(); - ovrSessionStatus status; - if (!OVR_SUCCESS(ovr_GetSessionStatus(_parent._session, &status)) || (ovrFalse == status.HmdMounted)) { + if (!_parent.isHeadController()) { // if the HMD isn't on someone's head, don't take input from the controllers return; } diff --git a/plugins/oculus/src/OculusControllerManager.h b/plugins/oculus/src/OculusControllerManager.h index 61f2241f4d..54237645eb 100644 --- a/plugins/oculus/src/OculusControllerManager.h +++ b/plugins/oculus/src/OculusControllerManager.h @@ -28,7 +28,7 @@ public: const QString getName() const override { return NAME; } bool isHandController() const override { return _touch != nullptr; } - bool isHeadController() const override { return true; } + bool isHeadController() const override; QStringList getSubdeviceNames() override; bool activate() override; diff --git a/plugins/oculus/src/OculusDebugDisplayPlugin.h b/plugins/oculus/src/OculusDebugDisplayPlugin.h index 1cc6bd0f8e..ec05cd92e2 100644 --- a/plugins/oculus/src/OculusDebugDisplayPlugin.h +++ b/plugins/oculus/src/OculusDebugDisplayPlugin.h @@ -15,8 +15,6 @@ public: grouping getGrouping() const override { return DEVELOPER; } bool isSupported() const override; - bool isHeadController() const override { return false; } - protected: void hmdPresent() override {} bool isHmdMounted() const override { return true; } diff --git a/plugins/oculus/src/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h index a4978a984e..9209fd373e 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.h +++ b/plugins/oculus/src/OculusDisplayPlugin.h @@ -24,8 +24,6 @@ public: virtual QJsonObject getHardwareStats() const; - bool isHeadController() const override { return true; } - protected: QThread::Priority getPresentPriority() override { return QThread::TimeCriticalPriority; } diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h index 9856c27c50..01e02c9892 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.h +++ b/plugins/openvr/src/OpenVrDisplayPlugin.h @@ -58,8 +58,6 @@ public: // Possibly needs an additional thread for VR submission int getRequiredThreadCount() const override; - bool isHeadController() const override { return true; } - protected: bool internalActivate() override; void internalDeactivate() override; From 552b69bb1c6aefc0cf7303da62f70a14e99e2c4f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 1 Jun 2017 13:47:19 -0700 Subject: [PATCH 49/91] cleanups --- interface/src/avatar/MyAvatar.cpp | 1 + interface/src/scripting/HMDScriptingInterface.cpp | 3 +-- .../src/display-plugins/hmd/DebugHmdDisplayPlugin.h | 1 + plugins/hifiKinect/src/KinectPlugin.cpp | 10 +--------- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5723751631..ef2e53cbb9 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1889,6 +1889,7 @@ void MyAvatar::updateOrientation(float deltaTime) { // these angles will be in radians // ... so they need to be converted to degrees before we do math... glm::vec3 euler = glm::eulerAngles(localOrientation) * DEGREES_PER_RADIAN; + Head* head = getHead(); head->setBaseYaw(YAW(euler)); head->setBasePitch(PITCH(euler)); diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index 1227f46eb6..883a6e758e 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -122,8 +122,7 @@ bool HMDScriptingInterface::getHUDLookAtPosition3D(glm::vec3& result) const { glm::mat4 HMDScriptingInterface::getWorldHMDMatrix() const { auto myAvatar = DependencyManager::get()->getMyAvatar(); - // return myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - return myAvatar->getSensorToWorldMatrix() * myAvatar->getHeadControllerPoseInSensorFrame().getMatrix() * Matrices::Y_180; + return myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); } glm::vec3 HMDScriptingInterface::getPosition() const { diff --git a/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h index 55746e65eb..9bb82b1836 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h @@ -21,6 +21,7 @@ public: bool beginFrameRender(uint32_t frameIndex) override; float getTargetFrameRate() const override { return 90; } + protected: void updatePresentPose() override; void hmdPresent() override {} diff --git a/plugins/hifiKinect/src/KinectPlugin.cpp b/plugins/hifiKinect/src/KinectPlugin.cpp index 834ee1ea2e..92c578e9aa 100644 --- a/plugins/hifiKinect/src/KinectPlugin.cpp +++ b/plugins/hifiKinect/src/KinectPlugin.cpp @@ -286,15 +286,7 @@ bool KinectPlugin::isHandController() const { } bool KinectPlugin::isHeadController() const { - bool sensorAvailable = false; -#ifdef HAVE_KINECT - if (_kinectSensor) { - BOOLEAN sensorIsAvailable = FALSE; - HRESULT hr = _kinectSensor->get_IsAvailable(&sensorIsAvailable); - sensorAvailable = SUCCEEDED(hr) && (sensorIsAvailable == TRUE); - } -#endif - return _enabled && _initialized && sensorAvailable; + return isHandController(); } From f45db99149946bc61a97034e98af77c97da367ac Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 1 Jun 2017 14:35:53 -0700 Subject: [PATCH 50/91] for the moment, vive input plugin isn't a head-controller unless the HMD is being worn --- plugins/openvr/src/ViveControllerManager.cpp | 5 +++++ plugins/openvr/src/ViveControllerManager.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 53500a3353..11d390fca4 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -138,6 +138,11 @@ void ViveControllerManager::deactivate() { _registeredWithInputMapper = false; } +bool ViveControllerManager::isHeadController() const { + vr::EDeviceActivityLevel activityLevel = _system->GetTrackedDeviceActivityLevel(vr::k_unTrackedDeviceIndex_Hmd); + return activityLevel == vr::k_EDeviceActivityLevel_UserInteraction; +} + void ViveControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { if (!_system) { diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index 6532540285..0fdd04fdfb 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -41,7 +41,7 @@ public: const QString getName() const override { return NAME; } bool isHandController() const override { return true; } - bool isHeadController() const override { return true; } + bool isHeadController() const override; bool activate() override; void deactivate() override; From 7d21ab88b0add448700fe4cca4c5dacb2b5a19c8 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 1 Jun 2017 16:14:59 -0700 Subject: [PATCH 51/91] add some saftey checks. cleanups --- interface/src/Application.cpp | 12 +++++++++--- interface/src/avatar/MyAvatar.cpp | 5 ++--- plugins/oculus/src/OculusControllerManager.cpp | 6 ++++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index aee829b624..8d20cbe715 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4423,7 +4423,9 @@ void Application::update(float deltaTime) { myAvatar->setSpineControllerPosesInSensorFrame(hipsPose.transform(avatarToSensorMatrix), spine2Pose.transform(avatarToSensorMatrix)); controller::Pose headPose = userInputMapper->getPoseState(controller::Action::HEAD); - myAvatar->setHeadControllerPoseInSensorFrame(headPose.transform(avatarToSensorMatrix)); + if (headPose.isValid()) { + myAvatar->setHeadControllerPoseInSensorFrame(headPose.transform(avatarToSensorMatrix)); + } controller::Pose leftArmPose = userInputMapper->getPoseState(controller::Action::LEFT_ARM); controller::Pose rightArmPose = userInputMapper->getPoseState(controller::Action::RIGHT_ARM); @@ -4859,9 +4861,13 @@ bool Application::isHMDMode() const { } bool Application::isHeadControllerEnabled() const { - const InputPluginList& inputPlugins = PluginManager::getInstance()->getInputPlugins(); + auto pluginManager = PluginManager::getInstance(); + if (!pluginManager) { + return false; + } + const InputPluginList& inputPlugins = pluginManager->getInputPlugins(); for (auto& ip : inputPlugins) { - if (ip->isActive() && ip->isHeadController()) { + if (ip && ip->isActive() && ip->isHeadController()) { return true; } } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ef2e53cbb9..c26cdf0b01 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2328,7 +2328,6 @@ glm::quat MyAvatar::getWorldBodyOrientation() const { // old school meat hook style glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { - // HMD is in sensor space. const glm::vec3 headPosition = getHeadControllerPoseInSensorFrame().translation; const glm::quat headOrientation = getHeadControllerPoseInSensorFrame().rotation * Quaternions::Y_180; const glm::quat headOrientationYawOnly = cancelOutRollAndPitch(headOrientation); @@ -2352,8 +2351,8 @@ glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { // apply simplistic head/neck model // figure out where the avatar body should be by applying offsets from the avatar's neck & head joints. - // eyeToNeck offset is relative full HMD orientation. - // while neckToRoot offset is only relative to HMDs yaw. + // eyeToNeck offset is relative to head's full orientation, + // while neckToRoot offset is only relative to head's yaw. // Y_180 is necessary because rig is z forward and headOrientation is -z forward glm::vec3 eyeToNeck = headOrientation * Quaternions::Y_180 * (localNeck - localEyes); glm::vec3 neckToRoot = headOrientationYawOnly * Quaternions::Y_180 * -localNeck; diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 60031a1179..ff3e614077 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -221,8 +221,11 @@ bool OculusControllerManager::isHeadController() const { return status.HmdMounted == ovrTrue; } -void OculusControllerManager::TouchDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { +void OculusControllerManager::TouchDevice::update(float deltaTime, + const controller::InputCalibrationData& inputCalibrationData) { _buttonPressedMap.clear(); + _poseStateMap.erase(controller::HEAD); + if (!_parent.isHeadController()) { // if the HMD isn't on someone's head, don't take input from the controllers return; @@ -258,7 +261,6 @@ void OculusControllerManager::TouchDevice::update(float deltaTime, const control handleRotationForUntrackedHand(inputCalibrationData, hand, tracking.HandPoses[hand]); }); - _poseStateMap.erase(controller::HEAD); handleHeadPose(deltaTime, inputCalibrationData, tracking.HeadPose); using namespace controller; From 27664756de05b4b8ac96cc3fdb9d81e24450b6b1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 1 Jun 2017 16:37:04 -0700 Subject: [PATCH 52/91] with vive head-puck, isHeadController is true, even when HMD isn't mounted --- plugins/openvr/src/ViveControllerManager.cpp | 3 +++ plugins/openvr/src/ViveControllerManager.h | 1 + 2 files changed, 4 insertions(+) diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 2f2278ae82..abff0770a7 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -165,6 +165,9 @@ void ViveControllerManager::deactivate() { } bool ViveControllerManager::isHeadController() const { + if (_inputDevice && _inputDevice->isHeadController()) { + return true; + } vr::EDeviceActivityLevel activityLevel = _system->GetTrackedDeviceActivityLevel(vr::k_unTrackedDeviceIndex_Hmd); return activityLevel == vr::k_EDeviceActivityLevel_UserInteraction; } diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index b06ba5bf89..d03818ea34 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -55,6 +55,7 @@ private: class InputDevice : public controller::InputDevice { public: InputDevice(vr::IVRSystem*& system); + bool isHeadController() const { return _overrideHead; } private: // Device functions controller::Input::NamedVector getAvailableInputs() const override; From c5e9551bab387b854ae71915b38e6494cf583754 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 1 Jun 2017 18:05:18 -0700 Subject: [PATCH 53/91] more cleanup --- libraries/render-utils/src/GeometryCache.cpp | 2 +- libraries/render-utils/src/RenderDeferredTask.cpp | 4 ---- libraries/render-utils/src/StencilMaskPass.cpp | 8 ++++++-- libraries/render-utils/src/StencilMaskPass.h | 1 + libraries/render-utils/src/SurfaceGeometryPass.cpp | 4 ++-- libraries/render-utils/src/ToneMappingEffect.cpp | 2 +- libraries/render-utils/src/ZoneRenderer.cpp | 6 +++--- 7 files changed, 14 insertions(+), 13 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 5755d5a031..cd87cfdb3d 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -1783,7 +1783,7 @@ static void buildWebShader(const std::string& vertShaderText, const std::string& gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); if (blendEnable) { - PrepareStencil::testMaskBlendShape(*state); + PrepareStencil::testMask(*state); } else { PrepareStencil::testMaskDrawShape(*state); } diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 89b4b72944..1b99fe92ee 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -33,7 +33,6 @@ #include "DeferredLightingEffect.h" #include "SurfaceGeometryPass.h" #include "FramebufferCache.h" -#include "HitEffect.h" #include "TextureCache.h" #include "ZoneRenderer.h" @@ -91,9 +90,6 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren const auto opaqueInputs = DrawStateSortDeferred::Inputs(opaques, lightingModel).hasVarying(); task.addJob("DrawOpaqueDeferred", opaqueInputs, shapePlumber); - // Once opaque is all rendered create stencil background - task.addJob("DrawOpaqueStencil", primaryFramebuffer); - task.addJob("OpaqueRangeTimer", opaqueRangeTimer); diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index 44e7a571e8..7a13a2d759 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -45,7 +45,7 @@ gpu::PipelinePointer PrepareStencil::getMeshStencilPipeline() { gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - drawMask(state); + drawMask(*state); state->setColorWriteMask(0); _meshStencilPipeline = gpu::Pipeline::create(program, state); @@ -61,7 +61,7 @@ gpu::PipelinePointer PrepareStencil::getPaintStencilPipeline() { gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - drawMask(state); + drawMask(*state); state->setColorWriteMask(0); _paintStencilPipeline = gpu::Pipeline::create(program, state); @@ -113,4 +113,8 @@ void PrepareStencil::testBackground(gpu::State& state) { void PrepareStencil::testMaskDrawShape(gpu::State& state) { state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_ZERO)); +} + +void PrepareStencil::testShape(gpu::State& state) { + state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_SHAPE, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } \ No newline at end of file diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h index c65788ebf8..d7d6ee448b 100644 --- a/libraries/render-utils/src/StencilMaskPass.h +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -38,6 +38,7 @@ public: static void testMask(gpu::State& state); static void testBackground(gpu::State& state); static void testMaskDrawShape(gpu::State& state); + static void testShape(gpu::State& state); private: diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index 4b13fa2bf0..de04c31622 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -224,7 +224,7 @@ const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); // Stencil test the curvature pass for objects pixels only, not the background - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testShape(*state); state->setColorWriteMask(true, false, false, false); @@ -250,7 +250,7 @@ const gpu::PipelinePointer& LinearDepthPass::getDownsamplePipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testShape(*state); state->setColorWriteMask(true, true, true, false); diff --git a/libraries/render-utils/src/ToneMappingEffect.cpp b/libraries/render-utils/src/ToneMappingEffect.cpp index df4e1e0e6a..62ae9147f3 100644 --- a/libraries/render-utils/src/ToneMappingEffect.cpp +++ b/libraries/render-utils/src/ToneMappingEffect.cpp @@ -39,7 +39,7 @@ void ToneMappingEffect::init() { slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), ToneMappingEffect_LightingMapSlot)); gpu::Shader::makeProgram(*blitProgram, slotBindings); auto blitState = std::make_shared(); - blitState->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testShape(*blitState); blitState->setColorWriteMask(true, true, true, true); _blitLightBuffer = gpu::PipelinePointer(gpu::Pipeline::create(blitProgram, blitState)); } diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 2fa6805cde..b72e4eac69 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -75,7 +75,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testMask(*state); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _keyLightPipeline = gpu::Pipeline::create(program, state); } @@ -97,7 +97,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getAmbientPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testMask(*state); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _ambientPipeline = gpu::Pipeline::create(program, state); } @@ -118,7 +118,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getBackgroundPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testMask(*state); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _backgroundPipeline = gpu::Pipeline::create(program, state); } From 4a419f2d07a4a796834929b85d7aa49dfa24972f Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 1 Jun 2017 18:25:24 -0700 Subject: [PATCH 54/91] Merging with upstream --- libraries/render-utils/src/RenderPipelines.cpp | 2 +- libraries/render-utils/src/StencilMaskPass.cpp | 6 +++--- libraries/render-utils/src/SurfaceGeometryPass.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index be2bb0efbe..42ed0bdad9 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -331,7 +331,7 @@ void addPlumberPipeline(ShapePlumber& plumber, bool isWireframed = (i & 4); auto state = std::make_shared(); - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_ZERO)); + PrepareStencil::testMaskDrawShape(*state); // Depth test depends on transparency state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL); diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index 7a13a2d759..d8a4afbc43 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -104,11 +104,11 @@ void PrepareStencil::drawMask(gpu::State& state) { } void PrepareStencil::testMask(gpu::State& state) { - state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } void PrepareStencil::testBackground(gpu::State& state) { - state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_BACKGROUND, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_BACKGROUND, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } void PrepareStencil::testMaskDrawShape(gpu::State& state) { @@ -116,5 +116,5 @@ void PrepareStencil::testMaskDrawShape(gpu::State& state) { } void PrepareStencil::testShape(gpu::State& state) { - state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_SHAPE, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SHAPE, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } \ No newline at end of file diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index de04c31622..b0c0aa6358 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -555,7 +555,7 @@ const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() { #ifdef USE_STENCIL_TEST // Stencil test the curvature pass for objects pixels only, not the background - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SCENE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + PrepareStencil::testMask(*state); #endif // Good to go add the brand new pipeline _curvaturePipeline = gpu::Pipeline::create(program, state); From f9aa400b951e2a9e18c809973fd434780786393b Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Fri, 2 Jun 2017 00:22:38 -0700 Subject: [PATCH 55/91] Refining the stencil configuration and triggering only in hmd mode --- interface/src/Application.cpp | 3 +++ libraries/model/src/model/Skybox.cpp | 2 +- .../src/procedural/ProceduralSkybox.cpp | 2 +- .../render-utils/src/AntialiasingEffect.cpp | 4 ++-- libraries/render-utils/src/StencilMaskPass.cpp | 17 +++++++++-------- .../render-utils/src/SurfaceGeometryPass.cpp | 2 +- .../render-utils/src/ToneMappingEffect.cpp | 2 +- libraries/render-utils/src/stencil_drawMask.slf | 4 +++- libraries/shared/src/RenderArgs.h | 8 ++++---- tests/shaders/src/main.cpp | 11 ----------- 10 files changed, 25 insertions(+), 30 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8c6bea0905..f232f8c956 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2185,6 +2185,9 @@ void Application::paintGL() { }); renderArgs._context->setStereoProjections(eyeProjections); renderArgs._context->setStereoViews(eyeOffsets); + + // Configure the type of display / stereo + renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); } renderArgs._blitFramebuffer = finalFramebuffer; displaySide(&renderArgs, _myCamera); diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index c47463666e..d327593573 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -97,7 +97,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky } auto skyState = std::make_shared(); - skyState->setStencilTest(true, 0x00, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); thePipeline = gpu::Pipeline::create(skyShader, skyState); } diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index eaacc5d851..f5feb434fa 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -23,7 +23,7 @@ ProceduralSkybox::ProceduralSkybox() : model::Skybox() { _procedural._fragmentSource = skybox_frag; // Adjust the pipeline state for background using the stencil test _procedural.setDoesFade(false); - _procedural._opaqueState->setStencilTest(true, 0x00, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + _procedural._opaqueState->setStencilTest(true, 0xFF, gpu::State::StencilTest(1, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } bool ProceduralSkybox::empty() { diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index 08f69d07d0..139f1ae091 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -71,7 +71,7 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - PrepareStencil::testShape(*state); + PrepareStencil::testMask(*state); state->setDepthTest(false, false, gpu::LESS_EQUAL); @@ -96,7 +96,7 @@ const gpu::PipelinePointer& Antialiasing::getBlendPipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setDepthTest(false, false, gpu::LESS_EQUAL); - PrepareStencil::testShape(*state); + PrepareStencil::testMask(*state); // Good to go add the brand new pipeline _blendPipeline = gpu::Pipeline::create(program, state); diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index d8a4afbc43..dcd994763f 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -70,12 +70,14 @@ gpu::PipelinePointer PrepareStencil::getPaintStencilPipeline() { } void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { - assert(renderContext->args); - assert(renderContext->args->_context); - RenderArgs* args = renderContext->args; + + // Only draw the stencil mask if in HMD mode. + if (args->_displayMode != RenderArgs::STEREO_HMD) { + return; + } + doInBatch(args->_context, [&](gpu::Batch& batch) { - args->_batch = &batch; batch.enableStereo(false); batch.setViewportTransform(args->_viewport); @@ -96,7 +98,6 @@ void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::F batch.draw(gpu::TRIANGLE_STRIP, 4); } }); - args->_batch = nullptr; } void PrepareStencil::drawMask(gpu::State& state) { @@ -104,11 +105,11 @@ void PrepareStencil::drawMask(gpu::State& state) { } void PrepareStencil::testMask(gpu::State& state) { - state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_MASK, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } void PrepareStencil::testBackground(gpu::State& state) { - state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_BACKGROUND, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_BACKGROUND, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } void PrepareStencil::testMaskDrawShape(gpu::State& state) { @@ -116,5 +117,5 @@ void PrepareStencil::testMaskDrawShape(gpu::State& state) { } void PrepareStencil::testShape(gpu::State& state) { - state.setStencilTest(true, 0xFF, gpu::State::StencilTest(PrepareStencil::STENCIL_SHAPE, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + state.setStencilTest(true, 0x00, gpu::State::StencilTest(PrepareStencil::STENCIL_SHAPE, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } \ No newline at end of file diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index b0c0aa6358..1941766353 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -555,7 +555,7 @@ const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() { #ifdef USE_STENCIL_TEST // Stencil test the curvature pass for objects pixels only, not the background - PrepareStencil::testMask(*state); + PrepareStencil::testShape(*state); #endif // Good to go add the brand new pipeline _curvaturePipeline = gpu::Pipeline::create(program, state); diff --git a/libraries/render-utils/src/ToneMappingEffect.cpp b/libraries/render-utils/src/ToneMappingEffect.cpp index 62ae9147f3..7a3d868236 100644 --- a/libraries/render-utils/src/ToneMappingEffect.cpp +++ b/libraries/render-utils/src/ToneMappingEffect.cpp @@ -39,7 +39,7 @@ void ToneMappingEffect::init() { slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), ToneMappingEffect_LightingMapSlot)); gpu::Shader::makeProgram(*blitProgram, slotBindings); auto blitState = std::make_shared(); - PrepareStencil::testShape(*blitState); + PrepareStencil::testMask(*blitState); blitState->setColorWriteMask(true, true, true, true); _blitLightBuffer = gpu::PipelinePointer(gpu::Pipeline::create(blitProgram, blitState)); } diff --git a/libraries/render-utils/src/stencil_drawMask.slf b/libraries/render-utils/src/stencil_drawMask.slf index cc81fca677..3eedeecb82 100644 --- a/libraries/render-utils/src/stencil_drawMask.slf +++ b/libraries/render-utils/src/stencil_drawMask.slf @@ -14,8 +14,10 @@ in vec2 varTexCoord0; +float aspectRatio = 0.95; + void main(void) { vec2 pos = varTexCoord0 * 2.0 - vec2(1.0); - pos.x = pos.x * (pos.x > 0.0 ? 2.0 : -2.0) - 1.0; + pos.x = aspectRatio * (pos.x * (pos.x > 0.0 ? 2.0 : -2.0) - 1.0); if (1.0 - dot(pos.xy, pos.xy) > 0.0 ) discard; } diff --git a/libraries/shared/src/RenderArgs.h b/libraries/shared/src/RenderArgs.h index f44d736e1a..d4d88c26a8 100644 --- a/libraries/shared/src/RenderArgs.h +++ b/libraries/shared/src/RenderArgs.h @@ -76,7 +76,7 @@ public: class RenderArgs { public: enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE, MIRROR_RENDER_MODE }; - enum RenderSide { MONO, STEREO_LEFT, STEREO_RIGHT }; + enum DisplayMode { MONO, STEREO_MONITOR, STEREO_HMD }; enum DebugFlags { RENDER_DEBUG_NONE = 0, RENDER_DEBUG_HULLS = 1 @@ -87,7 +87,7 @@ public: float sizeScale = 1.0f, int boundaryLevelAdjust = 0, RenderMode renderMode = DEFAULT_RENDER_MODE, - RenderSide renderSide = MONO, + DisplayMode displayMode = MONO, DebugFlags debugFlags = RENDER_DEBUG_NONE, gpu::Batch* batch = nullptr) : _context(context), @@ -95,7 +95,7 @@ public: _sizeScale(sizeScale), _boundaryLevelAdjust(boundaryLevelAdjust), _renderMode(renderMode), - _renderSide(renderSide), + _displayMode(displayMode), _debugFlags(debugFlags), _batch(batch) { } @@ -121,7 +121,7 @@ public: float _sizeScale = 1.0f; int _boundaryLevelAdjust = 0; RenderMode _renderMode = DEFAULT_RENDER_MODE; - RenderSide _renderSide = MONO; + DisplayMode _displayMode = MONO; DebugFlags _debugFlags = RENDER_DEBUG_NONE; gpu::Batch* _batch = nullptr; diff --git a/tests/shaders/src/main.cpp b/tests/shaders/src/main.cpp index 8a239f0728..d10ab1ddbe 100644 --- a/tests/shaders/src/main.cpp +++ b/tests/shaders/src/main.cpp @@ -31,13 +31,9 @@ #include #include -#include #include #include -#include -#include - #include #include @@ -66,9 +62,6 @@ #include #include -#include -#include - #include #include @@ -155,11 +148,8 @@ void QTestWindow::draw() { testShaderBuild(simple_vert, simple_frag); testShaderBuild(simple_vert, simple_textured_frag); testShaderBuild(simple_vert, simple_textured_unlit_frag); - testShaderBuild(deferred_light_vert, directional_light_frag); testShaderBuild(deferred_light_vert, directional_ambient_light_frag); testShaderBuild(deferred_light_vert, directional_skybox_light_frag); - testShaderBuild(deferred_light_point_vert, point_light_frag); - testShaderBuild(deferred_light_spot_vert, spot_light_frag); testShaderBuild(standardTransformPNTC_vert, standardDrawTexture_frag); testShaderBuild(standardTransformPNTC_vert, DrawTextureOpaque_frag); @@ -190,7 +180,6 @@ void QTestWindow::draw() { testShaderBuild(ambient_occlusion_vert, ambient_occlusion_frag); testShaderBuild(ambient_occlusion_vert, occlusion_blend_frag); */ - testShaderBuild(hit_effect_vert, hit_effect_frag); testShaderBuild(overlay3D_vert, overlay3D_frag); From 6228ff19bf2c9315b6edc01747a985301421e436 Mon Sep 17 00:00:00 2001 From: NeetBhagat Date: Fri, 2 Jun 2017 14:37:17 +0530 Subject: [PATCH 56/91] Resolve the reviewed comments of @ZappoMan --- interface/src/Application.cpp | 26 +++++++++---------- interface/src/Application.h | 2 +- .../display-plugins/OpenGLDisplayPlugin.cpp | 3 ++- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8384204fb9..a3787847db 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1349,16 +1349,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _autoSwitchDisplayModeSupportedHMDPlugin->getName(); _previousHMDWornStatus = _autoSwitchDisplayModeSupportedHMDPlugin->isDisplayVisible(); - qCDebug(interfaceapp) << "_autoSwitchModeSupportedPluginName::" - << _autoSwitchDisplayModeSupportedHMDPluginName; break; } } - if (_autoSwitchDisplayModeSupportedHMDPlugin != nullptr) { - // If HMD Plugin is available and current display plugin is not HMD plugin - // then startHMDStandBySession to poll HMD Worn status. - if (getActiveDisplayPlugin()->getName() != _autoSwitchDisplayModeSupportedHMDPluginName && + if (_autoSwitchDisplayModeSupportedHMDPlugin) { + if (getActiveDisplayPlugin() != _autoSwitchDisplayModeSupportedHMDPlugin && !_autoSwitchDisplayModeSupportedHMDPlugin->isStandBySessionActive()) { startHMDStandBySession(); } @@ -1600,7 +1596,7 @@ void Application::aboutToQuit() { } getActiveDisplayPlugin()->deactivate(); - if (_autoSwitchDisplayModeSupportedHMDPlugin != nullptr + if (_autoSwitchDisplayModeSupportedHMDPlugin && _autoSwitchDisplayModeSupportedHMDPlugin->isStandBySessionActive()) { _autoSwitchDisplayModeSupportedHMDPlugin->endStandBySession(); } @@ -6769,18 +6765,20 @@ void Application::updateDisplayMode() { } void Application::switchDisplayMode() { + if (!_autoSwitchDisplayModeSupportedHMDPlugin) { + return; + } bool currentHMDWornStatus = _autoSwitchDisplayModeSupportedHMDPlugin->isDisplayVisible(); if (currentHMDWornStatus != _previousHMDWornStatus) { - // Switch to respective mode as soon as currentHMDWornStatus changes - if (currentHMDWornStatus == false && _previousHMDWornStatus == true) { - qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; - setActiveDisplayPlugin(DESKTOP_DISPLAY_PLUGIN_NAME); - startHMDStandBySession(); - } - if (currentHMDWornStatus == true && _previousHMDWornStatus == false) { + // Switch to respective mode as soon as currentHMDWornStatus changes + if (currentHMDWornStatus) { qCDebug(interfaceapp) << "Switching from Desktop to HMD mode"; endHMDStandBySession(); setActiveDisplayPlugin(_autoSwitchDisplayModeSupportedHMDPluginName); + } else { + qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; + setActiveDisplayPlugin(DESKTOP_DISPLAY_PLUGIN_NAME); + startHMDStandBySession(); } } _previousHMDWornStatus = currentHMDWornStatus; diff --git a/interface/src/Application.h b/interface/src/Application.h index e1fb37ef3a..4cd47ada58 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -681,7 +681,7 @@ private: AudioInjector* _snapshotSoundInjector { nullptr }; SharedSoundPointer _snapshotSound; - DisplayPluginPointer _autoSwitchDisplayModeSupportedHMDPlugin = nullptr; + DisplayPluginPointer _autoSwitchDisplayModeSupportedHMDPlugin; QString _autoSwitchDisplayModeSupportedHMDPluginName; bool _previousHMDWornStatus; void startHMDStandBySession(); diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 3bdf9a672c..fbdc1ad71e 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -315,6 +315,7 @@ bool OpenGLDisplayPlugin::activate() { if (isHmd() && (getHmdScreen() >= 0)) { _container->showDisplayPluginsTools(); } + return Parent::activate(); } @@ -347,7 +348,7 @@ bool OpenGLDisplayPlugin::startStandBySession() { void OpenGLDisplayPlugin::endStandBySession() { deactivateStandBySession(); - return Parent::endStandBySession(); + Parent::endStandBySession(); } void OpenGLDisplayPlugin::customizeContext() { From f5d732f3329132b5b604242261ec785c08be7f6b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 31 May 2017 19:00:41 -0700 Subject: [PATCH 57/91] initial version of the ClosureEventSender using std::thread --- interface/src/Application.cpp | 6 ++ interface/src/Application.h | 3 + interface/src/main.cpp | 7 ++ .../src/networking/ClosureEventSender.cpp | 71 +++++++++++++++++++ interface/src/networking/ClosureEventSender.h | 35 +++++++++ libraries/networking/src/AccountManager.cpp | 1 - libraries/networking/src/AccountManager.h | 1 + .../networking/src/UserActivityLogger.cpp | 2 - libraries/networking/src/UserActivityLogger.h | 2 + 9 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 interface/src/networking/ClosureEventSender.cpp create mode 100644 interface/src/networking/ClosureEventSender.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 46c4c0bd4e..297ee943fa 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -144,6 +144,7 @@ #include "InterfaceLogging.h" #include "LODManager.h" #include "ModelPackager.h" +#include "networking/ClosureEventSender.h" #include "networking/HFWebEngineProfile.h" #include "networking/HFTabletWebEngineProfile.h" #include "networking/FileTypeProfile.h" @@ -534,6 +535,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); return previousSessionCrashed; } @@ -1568,6 +1570,10 @@ void Application::aboutToQuit() { getActiveDisplayPlugin()->deactivate(); + // use the ClosureEventSender via an std::thread (to not use QThread while the application is going down) + // to send an event that says the user asked for the app to close + _userQuitThread = std::thread { &ClosureEventSender::sendQuitStart, DependencyManager::get() }; + // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. DependencyManager::get()->hide("RunningScripts"); diff --git a/interface/src/Application.h b/interface/src/Application.h index 9cf03f1cef..23673399f6 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -13,6 +13,7 @@ #define hifi_Application_h #include +#include #include #include @@ -680,6 +681,8 @@ private: FileScriptingInterface* _fileDownload; AudioInjector* _snapshotSoundInjector { nullptr }; SharedSoundPointer _snapshotSound; + + std::thread _userQuitThread; }; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 49517eb38e..68525dfd1e 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -30,6 +30,7 @@ #include "InterfaceLogging.h" #include "UserActivityLogger.h" #include "MainWindow.h" +#include "networking/ClosureEventSender.h" #ifdef HAS_BUGSPLAT #include @@ -267,6 +268,12 @@ int main(int argc, const char* argv[]) { Application::shutdownPlugins(); + if (UserActivityLogger::getInstance().isEnabled()) { + // send a quit finished event here to indicate that this session closed cleanly + std::thread quitCompleteThread { &::ClosureEventSender::sendQuitFinish, DependencyManager::get() }; + quitCompleteThread.join(); + } + qCDebug(interfaceapp, "Normal exit."); #if !defined(DEBUG) && !defined(Q_OS_LINUX) // HACK: exit immediately (don't handle shutdown callbacks) for Release build diff --git a/interface/src/networking/ClosureEventSender.cpp b/interface/src/networking/ClosureEventSender.cpp new file mode 100644 index 0000000000..f514fa17b6 --- /dev/null +++ b/interface/src/networking/ClosureEventSender.cpp @@ -0,0 +1,71 @@ +// +// ClosureEventSender.cpp +// interface/src/networking +// +// Created by Stephen Birarda on 5/31/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 +// + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ClosureEventSender.h" + +QNetworkRequest createNetworkRequest() { + + QNetworkRequest request; + + QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; + requestURL.setPath(USER_ACTIVITY_URL); + + request.setUrl(requestURL); + + auto accountManager = DependencyManager::get(); + + if (accountManager->hasValidAccessToken()) { + request.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER, + accountManager->getAccountInfo().getAccessToken().authorizationHeaderValue()); + } + + request.setRawHeader(METAVERSE_SESSION_ID_HEADER, + uuidStringWithoutCurlyBraces(accountManager->getSessionID()).toLocal8Bit()); + + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + return request; +} + +QByteArray postDataForAction(QString action) { + return QString("{\"action\": \"" + action + "\"}").toUtf8(); +} + +QNetworkReply* replyForAction(QString action) { + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + return networkAccessManager.post(createNetworkRequest(), postDataForAction(action)); +} + +void ClosureEventSender::sendQuitStart() { + + QNetworkReply* reply = replyForAction("quit_start"); + + QEventLoop loop; + QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); +} + +void ClosureEventSender::sendQuitFinish() { + QNetworkReply* reply = replyForAction("quit_finish"); + + QEventLoop loop; + QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); +} diff --git a/interface/src/networking/ClosureEventSender.h b/interface/src/networking/ClosureEventSender.h new file mode 100644 index 0000000000..dc726fc386 --- /dev/null +++ b/interface/src/networking/ClosureEventSender.h @@ -0,0 +1,35 @@ +// +// ClosureEventSender.h +// interface/src/networking +// +// Created by Stephen Birarda on 5/31/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 +// + +#ifndef hifi_ClosureEventSender_h +#define hifi_ClosureEventSender_h + +#include +#include + +#include + +class ClosureEventSender : public Dependency { + SINGLETON_DEPENDENCY + +public: + void setSessionID(QUuid sessionID) { _sessionID = sessionID; } + + void sendQuitStart(); + void sendQuitFinish(); + void sendCrashEvent(); + +private: + QUuid _sessionID; + QString _accessToken; +}; + +#endif // hifi_ClosureEventSender_h diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 6266ad0f89..2457d0ac42 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -45,7 +45,6 @@ Q_DECLARE_METATYPE(QNetworkAccessManager::Operation) Q_DECLARE_METATYPE(JSONCallbackParameters) const QString ACCOUNTS_GROUP = "accounts"; -static const auto METAVERSE_SESSION_ID_HEADER = QString("HFM-SessionID").toLocal8Bit(); JSONCallbackParameters::JSONCallbackParameters(QObject* jsonCallbackReceiver, const QString& jsonCallbackMethod, QObject* errorCallbackReceiver, const QString& errorCallbackMethod, diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index dd2216957f..bd452646f6 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -52,6 +52,7 @@ namespace AccountManagerAuth { Q_DECLARE_METATYPE(AccountManagerAuth::Type); const QByteArray ACCESS_TOKEN_AUTHORIZATION_HEADER = "Authorization"; +const auto METAVERSE_SESSION_ID_HEADER = QString("HFM-SessionID").toLocal8Bit(); using UserAgentGetter = std::function; diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index e2dd110cfd..28117c0933 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -20,8 +20,6 @@ #include #include "AddressManager.h" -static const QString USER_ACTIVITY_URL = "/api/v1/user_activities"; - UserActivityLogger& UserActivityLogger::getInstance() { static UserActivityLogger sharedInstance; return sharedInstance; diff --git a/libraries/networking/src/UserActivityLogger.h b/libraries/networking/src/UserActivityLogger.h index b41960a8ad..9fad498b86 100644 --- a/libraries/networking/src/UserActivityLogger.h +++ b/libraries/networking/src/UserActivityLogger.h @@ -22,6 +22,8 @@ #include #include "AddressManager.h" +const QString USER_ACTIVITY_URL = "/api/v1/user_activities"; + class UserActivityLogger : public QObject { Q_OBJECT From 40dfcb1e6e5e8d18f8285d2e52ad14ea3f8cbfc2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 1 Jun 2017 10:43:47 -0700 Subject: [PATCH 58/91] send quit event during shutdown on thread, with timeout --- interface/src/Application.cpp | 21 +++++++-- interface/src/Application.h | 3 -- interface/src/main.cpp | 8 ---- .../src/networking/ClosureEventSender.cpp | 43 +++++++++++++------ interface/src/networking/ClosureEventSender.h | 22 +++++++--- 5 files changed, 64 insertions(+), 33 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 297ee943fa..a637f9414b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -11,6 +11,8 @@ #include "Application.h" +#include + #include #include #include @@ -1570,9 +1572,13 @@ void Application::aboutToQuit() { getActiveDisplayPlugin()->deactivate(); - // use the ClosureEventSender via an std::thread (to not use QThread while the application is going down) - // to send an event that says the user asked for the app to close - _userQuitThread = std::thread { &ClosureEventSender::sendQuitStart, DependencyManager::get() }; + // use the ClosureEventSender via a QThread to send an event that says the user asked for the app to close + auto closureEventSender = DependencyManager::get(); + QThread* closureEventThread = new QThread(this); + closureEventSender->moveToThread(closureEventThread); + // sendQuitEventAsync will bail immediately if the UserActivityLogger is not enabled + connect(closureEventThread, &QThread::started, closureEventSender.data(), &ClosureEventSender::sendQuitEventAsync); + closureEventThread->start(); // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. DependencyManager::get()->hide("RunningScripts"); @@ -1738,6 +1744,15 @@ Application::~Application() { _window->deleteLater(); + // make sure that the quit event has finished sending before we take the application down + auto closureEventSender = DependencyManager::get(); + while (!closureEventSender->hasFinishedQuitEvent() && !closureEventSender->hasTimedOutQuitEvent()) { + // yield so we're not spinning + std::this_thread::yield(); + } + // quit the thread used by the closure event sender + closureEventSender->thread()->quit(); + // Can't log to file passed this point, FileLogger about to be deleted qInstallMessageHandler(LogHandler::verboseMessageHandler); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 23673399f6..9cf03f1cef 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -13,7 +13,6 @@ #define hifi_Application_h #include -#include #include #include @@ -681,8 +680,6 @@ private: FileScriptingInterface* _fileDownload; AudioInjector* _snapshotSoundInjector { nullptr }; SharedSoundPointer _snapshotSound; - - std::thread _userQuitThread; }; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 68525dfd1e..63738d2d91 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -24,13 +24,11 @@ #include #include - #include "AddressManager.h" #include "Application.h" #include "InterfaceLogging.h" #include "UserActivityLogger.h" #include "MainWindow.h" -#include "networking/ClosureEventSender.h" #ifdef HAS_BUGSPLAT #include @@ -268,12 +266,6 @@ int main(int argc, const char* argv[]) { Application::shutdownPlugins(); - if (UserActivityLogger::getInstance().isEnabled()) { - // send a quit finished event here to indicate that this session closed cleanly - std::thread quitCompleteThread { &::ClosureEventSender::sendQuitFinish, DependencyManager::get() }; - quitCompleteThread.join(); - } - qCDebug(interfaceapp, "Normal exit."); #if !defined(DEBUG) && !defined(Q_OS_LINUX) // HACK: exit immediately (don't handle shutdown callbacks) for Release build diff --git a/interface/src/networking/ClosureEventSender.cpp b/interface/src/networking/ClosureEventSender.cpp index f514fa17b6..238629b809 100644 --- a/interface/src/networking/ClosureEventSender.cpp +++ b/interface/src/networking/ClosureEventSender.cpp @@ -9,14 +9,15 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include #include #include -#include #include #include #include #include +#include #include #include @@ -43,11 +44,13 @@ QNetworkRequest createNetworkRequest() { request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + request.setPriority(QNetworkRequest::HighPriority); + return request; } QByteArray postDataForAction(QString action) { - return QString("{\"action\": \"" + action + "\"}").toUtf8(); + return QString("{\"action_name\": \"" + action + "\"}").toUtf8(); } QNetworkReply* replyForAction(QString action) { @@ -55,17 +58,33 @@ QNetworkReply* replyForAction(QString action) { return networkAccessManager.post(createNetworkRequest(), postDataForAction(action)); } -void ClosureEventSender::sendQuitStart() { - - QNetworkReply* reply = replyForAction("quit_start"); - - QEventLoop loop; - QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); +void ClosureEventSender::sendQuitEventAsync() { + if (UserActivityLogger::getInstance().isEnabled()) { + QNetworkReply* reply = replyForAction("quit"); + connect(reply, &QNetworkReply::finished, this, &ClosureEventSender::handleQuitEventFinished); + _quitEventStartTimestamp = QDateTime::currentMSecsSinceEpoch(); + } else { + _hasFinishedQuitEvent = true; + } } -void ClosureEventSender::sendQuitFinish() { - QNetworkReply* reply = replyForAction("quit_finish"); +void ClosureEventSender::handleQuitEventFinished() { + _hasFinishedQuitEvent = true; - QEventLoop loop; - QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); + auto reply = qobject_cast(sender()); + if (reply->error() == QNetworkReply::NoError) { + qCDebug(networking) << "Quit event sent successfully"; + } else { + qCDebug(networking) << "Failed to send quit event -" << reply->errorString(); + } + + reply->deleteLater(); } + +bool ClosureEventSender::hasTimedOutQuitEvent() { + const int CLOSURE_EVENT_TIMEOUT_MS = 5000; + return _quitEventStartTimestamp != 0 + && QDateTime::currentMSecsSinceEpoch() - _quitEventStartTimestamp > CLOSURE_EVENT_TIMEOUT_MS; +} + + diff --git a/interface/src/networking/ClosureEventSender.h b/interface/src/networking/ClosureEventSender.h index dc726fc386..be2daca12b 100644 --- a/interface/src/networking/ClosureEventSender.h +++ b/interface/src/networking/ClosureEventSender.h @@ -12,24 +12,32 @@ #ifndef hifi_ClosureEventSender_h #define hifi_ClosureEventSender_h +#include + #include #include #include -class ClosureEventSender : public Dependency { +class ClosureEventSender : public QObject, public Dependency { + Q_OBJECT SINGLETON_DEPENDENCY public: - void setSessionID(QUuid sessionID) { _sessionID = sessionID; } + void sendCrashEventSync(); - void sendQuitStart(); - void sendQuitFinish(); - void sendCrashEvent(); + bool hasTimedOutQuitEvent(); + bool hasFinishedQuitEvent() { return _hasFinishedQuitEvent; } + +public slots: + void sendQuitEventAsync(); + +private slots: + void handleQuitEventFinished(); private: - QUuid _sessionID; - QString _accessToken; + std::atomic _hasFinishedQuitEvent { false }; + std::atomic _quitEventStartTimestamp; }; #endif // hifi_ClosureEventSender_h From ecc697dbe1a467b6448a3b3af77eca645d0de35c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 1 Jun 2017 13:40:50 -0700 Subject: [PATCH 59/91] remove crash event definition for now --- interface/src/networking/ClosureEventSender.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/networking/ClosureEventSender.h b/interface/src/networking/ClosureEventSender.h index be2daca12b..ea07e55c84 100644 --- a/interface/src/networking/ClosureEventSender.h +++ b/interface/src/networking/ClosureEventSender.h @@ -24,8 +24,6 @@ class ClosureEventSender : public QObject, public Dependency { SINGLETON_DEPENDENCY public: - void sendCrashEventSync(); - bool hasTimedOutQuitEvent(); bool hasFinishedQuitEvent() { return _hasFinishedQuitEvent; } From e3d8229abe032dc997522d4b5e7a0784d577acc4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 1 Jun 2017 17:52:01 -0700 Subject: [PATCH 60/91] rename ClosureEventSender to CloseEventSender --- interface/src/Application.cpp | 18 +++++++++--------- ...ureEventSender.cpp => CloseEventSender.cpp} | 12 ++++++------ ...ClosureEventSender.h => CloseEventSender.h} | 10 +++++----- 3 files changed, 20 insertions(+), 20 deletions(-) rename interface/src/networking/{ClosureEventSender.cpp => CloseEventSender.cpp} (88%) rename interface/src/networking/{ClosureEventSender.h => CloseEventSender.h} (79%) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a637f9414b..41b0bcaf04 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -146,7 +146,7 @@ #include "InterfaceLogging.h" #include "LODManager.h" #include "ModelPackager.h" -#include "networking/ClosureEventSender.h" +#include "networking/CloseEventSender.h" #include "networking/HFWebEngineProfile.h" #include "networking/HFTabletWebEngineProfile.h" #include "networking/FileTypeProfile.h" @@ -537,7 +537,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); - DependencyManager::set(); + DependencyManager::set(); return previousSessionCrashed; } @@ -1572,12 +1572,12 @@ void Application::aboutToQuit() { getActiveDisplayPlugin()->deactivate(); - // use the ClosureEventSender via a QThread to send an event that says the user asked for the app to close - auto closureEventSender = DependencyManager::get(); + // use the CloseEventSender via a QThread to send an event that says the user asked for the app to close + auto closeEventSender = DependencyManager::get(); QThread* closureEventThread = new QThread(this); - closureEventSender->moveToThread(closureEventThread); + closeEventSender->moveToThread(closureEventThread); // sendQuitEventAsync will bail immediately if the UserActivityLogger is not enabled - connect(closureEventThread, &QThread::started, closureEventSender.data(), &ClosureEventSender::sendQuitEventAsync); + connect(closureEventThread, &QThread::started, closeEventSender.data(), &CloseEventSender::sendQuitEventAsync); closureEventThread->start(); // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. @@ -1745,13 +1745,13 @@ Application::~Application() { _window->deleteLater(); // make sure that the quit event has finished sending before we take the application down - auto closureEventSender = DependencyManager::get(); - while (!closureEventSender->hasFinishedQuitEvent() && !closureEventSender->hasTimedOutQuitEvent()) { + auto closeEventSender = DependencyManager::get(); + while (!closeEventSender->hasFinishedQuitEvent() && !closeEventSender->hasTimedOutQuitEvent()) { // yield so we're not spinning std::this_thread::yield(); } // quit the thread used by the closure event sender - closureEventSender->thread()->quit(); + closeEventSender->thread()->quit(); // Can't log to file passed this point, FileLogger about to be deleted qInstallMessageHandler(LogHandler::verboseMessageHandler); diff --git a/interface/src/networking/ClosureEventSender.cpp b/interface/src/networking/CloseEventSender.cpp similarity index 88% rename from interface/src/networking/ClosureEventSender.cpp rename to interface/src/networking/CloseEventSender.cpp index 238629b809..8c3d6ae888 100644 --- a/interface/src/networking/ClosureEventSender.cpp +++ b/interface/src/networking/CloseEventSender.cpp @@ -1,5 +1,5 @@ // -// ClosureEventSender.cpp +// CloseEventSender.cpp // interface/src/networking // // Created by Stephen Birarda on 5/31/17. @@ -21,7 +21,7 @@ #include #include -#include "ClosureEventSender.h" +#include "CloseEventSender.h" QNetworkRequest createNetworkRequest() { @@ -58,17 +58,17 @@ QNetworkReply* replyForAction(QString action) { return networkAccessManager.post(createNetworkRequest(), postDataForAction(action)); } -void ClosureEventSender::sendQuitEventAsync() { +void CloseEventSender::sendQuitEventAsync() { if (UserActivityLogger::getInstance().isEnabled()) { QNetworkReply* reply = replyForAction("quit"); - connect(reply, &QNetworkReply::finished, this, &ClosureEventSender::handleQuitEventFinished); + connect(reply, &QNetworkReply::finished, this, &CloseEventSender::handleQuitEventFinished); _quitEventStartTimestamp = QDateTime::currentMSecsSinceEpoch(); } else { _hasFinishedQuitEvent = true; } } -void ClosureEventSender::handleQuitEventFinished() { +void CloseEventSender::handleQuitEventFinished() { _hasFinishedQuitEvent = true; auto reply = qobject_cast(sender()); @@ -81,7 +81,7 @@ void ClosureEventSender::handleQuitEventFinished() { reply->deleteLater(); } -bool ClosureEventSender::hasTimedOutQuitEvent() { +bool CloseEventSender::hasTimedOutQuitEvent() { const int CLOSURE_EVENT_TIMEOUT_MS = 5000; return _quitEventStartTimestamp != 0 && QDateTime::currentMSecsSinceEpoch() - _quitEventStartTimestamp > CLOSURE_EVENT_TIMEOUT_MS; diff --git a/interface/src/networking/ClosureEventSender.h b/interface/src/networking/CloseEventSender.h similarity index 79% rename from interface/src/networking/ClosureEventSender.h rename to interface/src/networking/CloseEventSender.h index ea07e55c84..05e6f81ad4 100644 --- a/interface/src/networking/ClosureEventSender.h +++ b/interface/src/networking/CloseEventSender.h @@ -1,5 +1,5 @@ // -// ClosureEventSender.h +// CloseEventSender.h // interface/src/networking // // Created by Stephen Birarda on 5/31/17. @@ -9,8 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_ClosureEventSender_h -#define hifi_ClosureEventSender_h +#ifndef hifi_CloseEventSender_h +#define hifi_CloseEventSender_h #include @@ -19,7 +19,7 @@ #include -class ClosureEventSender : public QObject, public Dependency { +class CloseEventSender : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY @@ -38,4 +38,4 @@ private: std::atomic _quitEventStartTimestamp; }; -#endif // hifi_ClosureEventSender_h +#endif // hifi_CloseEventSender_h From d89febac7197d7e840150bc62ef3118167981572 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 1 Jun 2017 17:57:23 -0700 Subject: [PATCH 61/91] use a sleep instead of a yield waiting for close event --- interface/src/Application.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 41b0bcaf04..27c158322d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -11,6 +11,7 @@ #include "Application.h" +#include #include #include @@ -1747,8 +1748,8 @@ Application::~Application() { // make sure that the quit event has finished sending before we take the application down auto closeEventSender = DependencyManager::get(); while (!closeEventSender->hasFinishedQuitEvent() && !closeEventSender->hasTimedOutQuitEvent()) { - // yield so we're not spinning - std::this_thread::yield(); + // sleep a little so we're not spinning at 100% + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } // quit the thread used by the closure event sender closeEventSender->thread()->quit(); From 9088e288e09c02184eb60932398f83967d7677bd Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 2 Jun 2017 13:57:53 -0700 Subject: [PATCH 62/91] don't worry about head controller being enabled, just check to see if head pose is valid --- interface/src/Application.cpp | 18 +------------- interface/src/Application.h | 1 - interface/src/avatar/MyAvatar.cpp | 8 +++++-- interface/src/avatar/MySkeletonModel.cpp | 24 +++++++------------ .../oculus/src/OculusControllerManager.cpp | 20 +++++++++------- plugins/oculus/src/OculusControllerManager.h | 3 ++- plugins/openvr/src/ViveControllerManager.cpp | 4 ++-- plugins/openvr/src/ViveControllerManager.h | 5 ++-- 8 files changed, 33 insertions(+), 50 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 673813b0db..35a8f65c06 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4429,9 +4429,7 @@ void Application::update(float deltaTime) { myAvatar->setSpineControllerPosesInSensorFrame(hipsPose.transform(avatarToSensorMatrix), spine2Pose.transform(avatarToSensorMatrix)); controller::Pose headPose = userInputMapper->getPoseState(controller::Action::HEAD); - if (headPose.isValid()) { - myAvatar->setHeadControllerPoseInSensorFrame(headPose.transform(avatarToSensorMatrix)); - } + myAvatar->setHeadControllerPoseInSensorFrame(headPose.transform(avatarToSensorMatrix)); controller::Pose leftArmPose = userInputMapper->getPoseState(controller::Action::LEFT_ARM); controller::Pose rightArmPose = userInputMapper->getPoseState(controller::Action::RIGHT_ARM); @@ -4867,20 +4865,6 @@ bool Application::isHMDMode() const { return getActiveDisplayPlugin()->isHmd(); } -bool Application::isHeadControllerEnabled() const { - auto pluginManager = PluginManager::getInstance(); - if (!pluginManager) { - return false; - } - const InputPluginList& inputPlugins = pluginManager->getInputPlugins(); - for (auto& ip : inputPlugins) { - if (ip && ip->isActive() && ip->isHeadController()) { - return true; - } - } - return false; -} - float Application::getTargetFrameRate() const { return getActiveDisplayPlugin()->getTargetFrameRate(); } QRect Application::getDesirableApplicationGeometry() const { diff --git a/interface/src/Application.h b/interface/src/Application.h index ec3792ea75..9cf03f1cef 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -248,7 +248,6 @@ public: // rendering of several elements depend on that // TODO: carry that information on the Camera as a setting virtual bool isHMDMode() const override; - bool isHeadControllerEnabled() const; glm::mat4 getHMDSensorPose() const; glm::mat4 getEyeOffset(int eye) const; glm::mat4 getEyeProjection(int eye) const; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c26cdf0b01..7e998b11c0 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -641,9 +641,13 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { // Ignore unreasonable HMD sensor data return; } + _hmdSensorPosition = newHmdSensorPosition; _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); - _headControllerFacing = getFacingDir2D(_headControllerPoseInSensorFrameCache.get().rotation); + auto headPose = _headControllerPoseInSensorFrameCache.get(); + if (headPose.isValid()) { + _headControllerFacing = getFacingDir2D(headPose.rotation); + } } void MyAvatar::updateJointFromController(controller::Action poseKey, ThreadSafeValueCache& matrixCache) { @@ -1884,7 +1888,7 @@ void MyAvatar::updateOrientation(float deltaTime) { getHead()->setBasePitch(getHead()->getBasePitch() + getDriveKey(PITCH) * _pitchSpeed * deltaTime); - if (qApp->isHeadControllerEnabled()) { + if (getHeadControllerPoseInAvatarFrame().isValid()) { glm::quat localOrientation = getHeadControllerPoseInAvatarFrame().rotation; // these angles will be in radians // ... so they need to be converted to degrees before we do math... diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 3721eea569..e74df4cf0f 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -52,26 +52,18 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { // input action is the highest priority source for head orientation. auto avatarHeadPose = myAvatar->getHeadControllerPoseInAvatarFrame(); if (avatarHeadPose.isValid()) { - glm::mat4 rigHeadMat = Matrices::Y_180 * createMatFromQuatAndPos(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); + glm::mat4 rigHeadMat = Matrices::Y_180 * + createMatFromQuatAndPos(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); headParams.rigHeadPosition = extractTranslation(rigHeadMat); headParams.rigHeadOrientation = glmExtractRotation(rigHeadMat); headParams.headEnabled = true; } else { - if (qApp->isHMDMode()) { - // get HMD position from sensor space into world space, and back into rig space - glm::mat4 worldHMDMat = myAvatar->getHeadControllerPoseInWorldFrame().getMatrix(); - glm::mat4 rigToWorld = createMatFromQuatAndPos(getRotation(), getTranslation()); - glm::mat4 worldToRig = glm::inverse(rigToWorld); - glm::mat4 rigHMDMat = worldToRig * worldHMDMat; - _rig.computeHeadFromHMD(AnimPose(rigHMDMat), headParams.rigHeadPosition, headParams.rigHeadOrientation); - headParams.headEnabled = true; - } else { - // even though full head IK is disabled, the rig still needs the head orientation to rotate the head up and down in desktop mode. - // preMult 180 is necessary to convert from avatar to rig coordinates. - // postMult 180 is necessary to convert head from -z forward to z forward. - headParams.rigHeadOrientation = Quaternions::Y_180 * head->getFinalOrientationInLocalFrame() * Quaternions::Y_180; - headParams.headEnabled = false; - } + // even though full head IK is disabled, the rig still needs the head orientation to rotate the head up and + // down in desktop mode. + // preMult 180 is necessary to convert from avatar to rig coordinates. + // postMult 180 is necessary to convert head from -z forward to z forward. + headParams.rigHeadOrientation = Quaternions::Y_180 * head->getFinalOrientationInLocalFrame() * Quaternions::Y_180; + headParams.headEnabled = false; } auto avatarHipsPose = myAvatar->getHipsControllerPoseInAvatarFrame(); diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index ff3e614077..4b7873c86d 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -210,10 +210,8 @@ void OculusControllerManager::RemoteDevice::focusOutEvent() { _buttonPressedMap.clear(); } -bool OculusControllerManager::isHeadController() const { - // this plugin is a head controller if the HMD is mounted. +bool OculusControllerManager::isHeadControllerMounted() const { ovrSessionStatus status; - bool success = OVR_SUCCESS(ovr_GetSessionStatus(_session, &status)); if (!success) { return false; @@ -224,12 +222,12 @@ bool OculusControllerManager::isHeadController() const { void OculusControllerManager::TouchDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { _buttonPressedMap.clear(); - _poseStateMap.erase(controller::HEAD); + // _poseStateMap.erase(controller::HEAD); - if (!_parent.isHeadController()) { - // if the HMD isn't on someone's head, don't take input from the controllers - return; - } + // if (!_parent.isHeadControllerMounted()) { + // // if the HMD isn't on someone's head, don't take input from the controllers + // return; + // } int numTrackedControllers = 0; quint64 currentTime = usecTimestampNow(); @@ -261,7 +259,11 @@ void OculusControllerManager::TouchDevice::update(float deltaTime, handleRotationForUntrackedHand(inputCalibrationData, hand, tracking.HandPoses[hand]); }); - handleHeadPose(deltaTime, inputCalibrationData, tracking.HeadPose); + if (_parent.isHeadControllerMounted()) { + handleHeadPose(deltaTime, inputCalibrationData, tracking.HeadPose); + } else { + _poseStateMap[controller::HEAD].valid = false; + } using namespace controller; // Axes diff --git a/plugins/oculus/src/OculusControllerManager.h b/plugins/oculus/src/OculusControllerManager.h index 54237645eb..69187f94a6 100644 --- a/plugins/oculus/src/OculusControllerManager.h +++ b/plugins/oculus/src/OculusControllerManager.h @@ -28,7 +28,8 @@ public: const QString getName() const override { return NAME; } bool isHandController() const override { return _touch != nullptr; } - bool isHeadController() const override; + bool isHeadController() const override { return true; } + bool isHeadControllerMounted() const; QStringList getSubdeviceNames() override; bool activate() override; diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index abff0770a7..b5fa7cadad 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -164,8 +164,8 @@ void ViveControllerManager::deactivate() { _registeredWithInputMapper = false; } -bool ViveControllerManager::isHeadController() const { - if (_inputDevice && _inputDevice->isHeadController()) { +bool ViveControllerManager::isHeadControllerMounted() const { + if (_inputDevice && _inputDevice->isHeadControllerMounted()) { return true; } vr::EDeviceActivityLevel activityLevel = _system->GetTrackedDeviceActivityLevel(vr::k_unTrackedDeviceIndex_Hmd); diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index d03818ea34..35ad2df359 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -41,7 +41,8 @@ public: const QString getName() const override { return NAME; } bool isHandController() const override { return true; } - bool isHeadController() const override; + bool isHeadController() const override { return true; } + bool isHeadControllerMounted() const; bool activate() override; void deactivate() override; @@ -55,7 +56,7 @@ private: class InputDevice : public controller::InputDevice { public: InputDevice(vr::IVRSystem*& system); - bool isHeadController() const { return _overrideHead; } + bool isHeadControllerMounted() const { return _overrideHead; } private: // Device functions controller::Input::NamedVector getAvailableInputs() const override; From f9e1f028882492fc5a5e9ccc17416660e69cdfb4 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 2 Jun 2017 14:59:27 -0700 Subject: [PATCH 63/91] protect _text member of Text3DOverlay with mutex --- interface/src/ui/overlays/Text3DOverlay.cpp | 19 +++++++++++++++---- interface/src/ui/overlays/Text3DOverlay.h | 13 +++++++------ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 2e2d586abc..d7e4edb197 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -23,12 +23,13 @@ const float LINE_SCALE_RATIO = 1.2f; QString const Text3DOverlay::TYPE = "text3d"; -Text3DOverlay::Text3DOverlay() { +Text3DOverlay::Text3DOverlay() : _mutex() { _textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); _geometryId = DependencyManager::get()->allocateID(); } Text3DOverlay::Text3DOverlay(const Text3DOverlay* text3DOverlay) : + _mutex(), Billboard3DOverlay(text3DOverlay), _text(text3DOverlay->_text), _backgroundColor(text3DOverlay->_backgroundColor), @@ -51,6 +52,16 @@ Text3DOverlay::~Text3DOverlay() { } } +const QString Text3DOverlay::getText() const { + QMutexLocker lock(&_mutex); + return _text; +} + +void Text3DOverlay::setText(const QString& text) { + QMutexLocker lock(&_mutex); + _text = text; +} + xColor Text3DOverlay::getBackgroundColor() { if (_colorPulse == 0.0f) { return _backgroundColor; @@ -125,7 +136,7 @@ void Text3DOverlay::render(RenderArgs* args) { // FIXME: Factor out textRenderer so that Text3DOverlay overlay parts can be grouped by pipeline // for a gpu performance increase. Currently, // Text renderer sets its own pipeline, - _textRenderer->draw(batch, 0, 0, _text, textColor, glm::vec2(-1.0f), getDrawInFront()); + _textRenderer->draw(batch, 0, 0, getText(), textColor, glm::vec2(-1.0f), getDrawInFront()); // so before we continue, we must reset the pipeline batch.setPipeline(args->_pipeline->pipeline); args->_pipeline->prepare(batch); @@ -188,7 +199,7 @@ void Text3DOverlay::setProperties(const QVariantMap& properties) { QVariant Text3DOverlay::getProperty(const QString& property) { if (property == "text") { - return _text; + return getText(); } if (property == "textAlpha") { return _textAlpha; @@ -231,7 +242,7 @@ QSizeF Text3DOverlay::textSize(const QString& text) const { return QSizeF(extents.x, extents.y) * pointToWorldScale; } -bool Text3DOverlay::findRayIntersection(const glm::vec3 &origin, const glm::vec3 &direction, float &distance, +bool Text3DOverlay::findRayIntersection(const glm::vec3 &origin, const glm::vec3 &direction, float &distance, BoxFace &face, glm::vec3& surfaceNormal) { Transform transform = getTransform(); applyTransformTo(transform, true); diff --git a/interface/src/ui/overlays/Text3DOverlay.h b/interface/src/ui/overlays/Text3DOverlay.h index 5ba4fe5939..e7b09c9040 100644 --- a/interface/src/ui/overlays/Text3DOverlay.h +++ b/interface/src/ui/overlays/Text3DOverlay.h @@ -12,14 +12,14 @@ #define hifi_Text3DOverlay_h #include - +#include #include "Billboard3DOverlay.h" class TextRenderer3D; class Text3DOverlay : public Billboard3DOverlay { Q_OBJECT - + public: static QString const TYPE; virtual QString getType() const override { return TYPE; } @@ -34,7 +34,7 @@ public: virtual const render::ShapeKey getShapeKey() override; // getters - const QString& getText() const { return _text; } + const QString getText() const; float getLineHeight() const { return _lineHeight; } float getLeftMargin() const { return _leftMargin; } float getTopMargin() const { return _topMargin; } @@ -45,7 +45,7 @@ public: float getBackgroundAlpha() { return getAlpha(); } // setters - void setText(const QString& text) { _text = text; } + void setText(const QString& text); void setTextAlpha(float alpha) { _textAlpha = alpha; } void setLineHeight(float value) { _lineHeight = value; } void setLeftMargin(float margin) { _leftMargin = margin; } @@ -58,15 +58,16 @@ public: QSizeF textSize(const QString& test) const; // Meters - virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, + virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, glm::vec3& surfaceNormal) override; virtual Text3DOverlay* createClone() const override; private: TextRenderer3D* _textRenderer = nullptr; - + QString _text; + mutable QMutex _mutex; // used to make get/setText threadsafe, mutable so can be used in const functions xColor _backgroundColor = xColor { 0, 0, 0 }; float _textAlpha { 1.0f }; float _lineHeight { 1.0f }; From 3359a0a794f276efd12286c21ea67cdaca8ca593 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 2 Jun 2017 15:29:20 -0700 Subject: [PATCH 64/91] work on fixing some head to eye offsets. MyHead::getHmdOrientation to MyHead::getHeadOrientation --- interface/src/Application.cpp | 8 +-- interface/src/avatar/MyAvatar.cpp | 50 ++++++++++--------- interface/src/avatar/MyHead.cpp | 17 ++++--- interface/src/avatar/MyHead.h | 2 +- .../oculus/src/OculusControllerManager.cpp | 27 ++++++---- 5 files changed, 57 insertions(+), 47 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9245c58760..55666d521e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2091,7 +2091,7 @@ void Application::paintGL() { _myCamera.setOrientation(glm::quat_cast(camMat)); } else { _myCamera.setPosition(myAvatar->getDefaultEyePosition()); - _myCamera.setOrientation(myAvatar->getMyHead()->getCameraOrientation()); + _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); } } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { if (isHMDMode()) { @@ -4047,9 +4047,9 @@ void Application::updateMyAvatarLookAtPosition() { } else { // I am not looking at anyone else, so just look forward if (isHMD) { - glm::mat4 worldHMDMat = myAvatar->getSensorToWorldMatrix() * - myAvatar->getHeadControllerPoseInSensorFrame().getMatrix() * Matrices::Y_180; - lookAtSpot = transformPoint(worldHMDMat, glm::vec3(0.0f, 0.0f, -TREE_SCALE)); + glm::mat4 worldHeadMat = myAvatar->getSensorToWorldMatrix() * + myAvatar->getHeadControllerPoseInSensorFrame().getMatrix(); + lookAtSpot = transformPoint(worldHeadMat, glm::vec3(0.0f, 0.0f, TREE_SCALE)); } else { lookAtSpot = myAvatar->getHead()->getEyePosition() + (myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 7e998b11c0..826a6a00ac 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -644,9 +644,12 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { _hmdSensorPosition = newHmdSensorPosition; _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); + // _headControllerFacing = getFacingDir2D(_hmdSensorOrientation); auto headPose = _headControllerPoseInSensorFrameCache.get(); if (headPose.isValid()) { _headControllerFacing = getFacingDir2D(headPose.rotation); + } else { + _headControllerFacing = glm::vec2(1.0f, 0.0f); } } @@ -1481,12 +1484,12 @@ void MyAvatar::updateMotors() { if (_motionBehaviors & AVATAR_MOTION_ACTION_MOTOR_ENABLED) { if (_characterController.getState() == CharacterController::State::Hover || _characterController.computeCollisionGroup() == BULLET_COLLISION_GROUP_COLLISIONLESS) { - motorRotation = getMyHead()->getCameraOrientation(); + motorRotation = getMyHead()->getHeadOrientation(); } else { // non-hovering = walking: follow camera twist about vertical but not lift // so we decompose camera's rotation and store the twist part in motorRotation glm::quat liftRotation; - swingTwistDecomposition(getMyHead()->getCameraOrientation(), _worldUpDirection, liftRotation, motorRotation); + swingTwistDecomposition(getMyHead()->getHeadOrientation(), _worldUpDirection, liftRotation, motorRotation); } const float DEFAULT_MOTOR_TIMESCALE = 0.2f; const float INVALID_MOTOR_TIMESCALE = 1.0e6f; @@ -1500,7 +1503,7 @@ void MyAvatar::updateMotors() { } if (_motionBehaviors & AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED) { if (_scriptedMotorFrame == SCRIPTED_MOTOR_CAMERA_FRAME) { - motorRotation = getMyHead()->getCameraOrientation() * glm::angleAxis(PI, Vectors::UNIT_Y); + motorRotation = getMyHead()->getHeadOrientation() * glm::angleAxis(PI, Vectors::UNIT_Y); } else if (_scriptedMotorFrame == SCRIPTED_MOTOR_AVATAR_FRAME) { motorRotation = getOrientation() * glm::angleAxis(PI, Vectors::UNIT_Y); } else { @@ -1849,7 +1852,7 @@ void MyAvatar::updateOrientation(float deltaTime) { if (getCharacterController()->getState() == CharacterController::State::Hover) { // This is the direction the user desires to fly in. - glm::vec3 desiredFacing = getMyHead()->getCameraOrientation() * Vectors::UNIT_Z; + glm::vec3 desiredFacing = getMyHead()->getHeadOrientation() * Vectors::UNIT_Z; desiredFacing.y = 0.0f; // This is our reference frame, it is captured when the user begins to move. @@ -1888,8 +1891,9 @@ void MyAvatar::updateOrientation(float deltaTime) { getHead()->setBasePitch(getHead()->getBasePitch() + getDriveKey(PITCH) * _pitchSpeed * deltaTime); - if (getHeadControllerPoseInAvatarFrame().isValid()) { - glm::quat localOrientation = getHeadControllerPoseInAvatarFrame().rotation; + auto headPose = getHeadControllerPoseInAvatarFrame(); + if (headPose.isValid()) { + glm::quat localOrientation = headPose.rotation; // these angles will be in radians // ... so they need to be converted to degrees before we do math... glm::vec3 euler = glm::eulerAngles(localOrientation) * DEGREES_PER_RADIAN; @@ -2003,11 +2007,14 @@ void MyAvatar::updatePosition(float deltaTime) { } // capture the head rotation, in sensor space, when the user first indicates they would like to move/fly. - if (!_hoverReferenceCameraFacingIsCaptured && (fabs(getDriveKey(TRANSLATE_Z)) > 0.1f || fabs(getDriveKey(TRANSLATE_X)) > 0.1f)) { + if (!_hoverReferenceCameraFacingIsCaptured && + (fabs(getDriveKey(TRANSLATE_Z)) > 0.1f || fabs(getDriveKey(TRANSLATE_X)) > 0.1f)) { _hoverReferenceCameraFacingIsCaptured = true; // transform the camera facing vector into sensor space. - _hoverReferenceCameraFacing = transformVectorFast(glm::inverse(_sensorToWorldMatrix), getMyHead()->getCameraOrientation() * Vectors::UNIT_Z); - } else if (_hoverReferenceCameraFacingIsCaptured && (fabs(getDriveKey(TRANSLATE_Z)) <= 0.1f && fabs(getDriveKey(TRANSLATE_X)) <= 0.1f)) { + _hoverReferenceCameraFacing = transformVectorFast(glm::inverse(_sensorToWorldMatrix), + getMyHead()->getHeadOrientation() * Vectors::UNIT_Z); + } else if (_hoverReferenceCameraFacingIsCaptured && + (fabs(getDriveKey(TRANSLATE_Z)) <= 0.1f && fabs(getDriveKey(TRANSLATE_X)) <= 0.1f)) { _hoverReferenceCameraFacingIsCaptured = false; } } @@ -2332,35 +2339,32 @@ glm::quat MyAvatar::getWorldBodyOrientation() const { // old school meat hook style glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { + // HMD is in sensor space. const glm::vec3 headPosition = getHeadControllerPoseInSensorFrame().translation; const glm::quat headOrientation = getHeadControllerPoseInSensorFrame().rotation * Quaternions::Y_180; const glm::quat headOrientationYawOnly = cancelOutRollAndPitch(headOrientation); const Rig& rig = _skeletonModel->getRig(); - int rightEyeIndex = rig.indexOfJoint("RightEye"); - int leftEyeIndex = rig.indexOfJoint("LeftEye"); + int headIndex = rig.indexOfJoint("Head"); int neckIndex = rig.indexOfJoint("Neck"); int hipsIndex = rig.indexOfJoint("Hips"); - glm::vec3 rigMiddleEyePos = DEFAULT_AVATAR_MIDDLE_EYE_POS; - if (leftEyeIndex >= 0 && rightEyeIndex >= 0) { - rigMiddleEyePos = (rig.getAbsoluteDefaultPose(leftEyeIndex).trans() + rig.getAbsoluteDefaultPose(rightEyeIndex).trans()) / 2.0f; - } + glm::vec3 rigHeadPos = headIndex != -1 ? rig.getAbsoluteDefaultPose(headIndex).trans() : DEFAULT_AVATAR_HEAD_POS; glm::vec3 rigNeckPos = neckIndex != -1 ? rig.getAbsoluteDefaultPose(neckIndex).trans() : DEFAULT_AVATAR_NECK_POS; glm::vec3 rigHipsPos = hipsIndex != -1 ? rig.getAbsoluteDefaultPose(hipsIndex).trans() : DEFAULT_AVATAR_HIPS_POS; - glm::vec3 localEyes = (rigMiddleEyePos - rigHipsPos); + glm::vec3 localHead = (rigHeadPos - rigHipsPos); glm::vec3 localNeck = (rigNeckPos - rigHipsPos); // apply simplistic head/neck model // figure out where the avatar body should be by applying offsets from the avatar's neck & head joints. - // eyeToNeck offset is relative to head's full orientation, - // while neckToRoot offset is only relative to head's yaw. - // Y_180 is necessary because rig is z forward and headOrientation is -z forward - glm::vec3 eyeToNeck = headOrientation * Quaternions::Y_180 * (localNeck - localEyes); - glm::vec3 neckToRoot = headOrientationYawOnly * Quaternions::Y_180 * -localNeck; - glm::vec3 bodyPos = headPosition + eyeToNeck + neckToRoot; + // eyeToNeck offset is relative full HMD orientation. + // while neckToRoot offset is only relative to HMDs yaw. + // Y_180 is necessary because rig is z forward and hmdOrientation is -z forward + glm::vec3 headToNeck = headOrientation * Quaternions::Y_180 * (localNeck - localHead); + glm::vec3 neckToRoot = headOrientationYawOnly * Quaternions::Y_180 * -localNeck; + glm::vec3 bodyPos = headPosition + headToNeck + neckToRoot; return createMatFromQuatAndPos(headOrientationYawOnly, bodyPos); } @@ -2478,7 +2482,7 @@ bool MyAvatar::FollowHelper::shouldActivateRotation(const MyAvatar& myAvatar, co } else { const float FOLLOW_ROTATION_THRESHOLD = cosf(PI / 6.0f); // 30 degrees glm::vec2 bodyFacing = getFacingDir2D(currentBodyMatrix); - return glm::dot(myAvatar.getHeadControllerFacingMovingAverage() * -1.0f, bodyFacing) < FOLLOW_ROTATION_THRESHOLD; + return glm::dot(-myAvatar.getHeadControllerFacingMovingAverage(), bodyFacing) < FOLLOW_ROTATION_THRESHOLD; } } diff --git a/interface/src/avatar/MyHead.cpp b/interface/src/avatar/MyHead.cpp index f02aefec5b..9f2d080cd6 100644 --- a/interface/src/avatar/MyHead.cpp +++ b/interface/src/avatar/MyHead.cpp @@ -26,19 +26,20 @@ using namespace std; MyHead::MyHead(MyAvatar* owningAvatar) : Head(owningAvatar) { } -glm::quat MyHead::getCameraOrientation() const { - // NOTE: Head::getCameraOrientation() is not used for orienting the camera "view" while in Oculus mode, so +glm::quat MyHead::getHeadOrientation() const { + // NOTE: Head::getHeadOrientation() is not used for orienting the camera "view" while in Oculus mode, so // you may wonder why this code is here. This method will be called while in Oculus mode to determine how // to change the driving direction while in Oculus mode. It is used to support driving toward where you're // head is looking. Note that in oculus mode, your actual camera view and where your head is looking is not // always the same. - if (qApp->isHMDMode()) { - MyAvatar* myAvatar = static_cast(_owningAvatar); - return glm::quat_cast(myAvatar->getSensorToWorldMatrix()) * myAvatar->getHMDSensorOrientation(); - } else { - Avatar* owningAvatar = static_cast(_owningAvatar); - return owningAvatar->getWorldAlignedOrientation() * glm::quat(glm::radians(glm::vec3(_basePitch, 0.0f, 0.0f))); + + MyAvatar* myAvatar = static_cast(_owningAvatar); + auto headPose = myAvatar->getHeadControllerPoseInWorldFrame(); + if (headPose.isValid()) { + return headPose.rotation * Quaternions::Y_180; } + + return myAvatar->getWorldAlignedOrientation() * glm::quat(glm::radians(glm::vec3(_basePitch, 0.0f, 0.0f))); } void MyHead::simulate(float deltaTime) { diff --git a/interface/src/avatar/MyHead.h b/interface/src/avatar/MyHead.h index 097415153c..c999311b80 100644 --- a/interface/src/avatar/MyHead.h +++ b/interface/src/avatar/MyHead.h @@ -18,7 +18,7 @@ public: explicit MyHead(MyAvatar* owningAvatar); /// \return orientationBody * orientationBasePitch - glm::quat getCameraOrientation() const; + glm::quat getHeadOrientation() const; void simulate(float deltaTime) override; private: diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 4b7873c86d..dee9f1082e 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -326,19 +326,24 @@ void OculusControllerManager::TouchDevice::handlePose(float deltaTime, void OculusControllerManager::TouchDevice::handleHeadPose(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, const ovrPoseStatef& headPose) { - auto poseId = controller::HEAD; - auto& pose = _poseStateMap[poseId]; + glm::mat4 mat = createMatFromQuatAndPos(toGlm(headPose.ThePose.Orientation), + toGlm(headPose.ThePose.Position)); + + //perform a 180 flip to make the HMD face the +z instead of -z, beacuse the head faces +z + glm::mat4 matYFlip = mat * Matrices::Y_180; + controller::Pose pose(extractTranslation(matYFlip), + glmExtractRotation(matYFlip), + toGlm(headPose.LinearVelocity), // XXX * matYFlip ? + toGlm(headPose.AngularVelocity)); + + glm::mat4 sensorToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat; + glm::mat4 defaultHeadOffset = glm::inverse(inputCalibrationData.defaultCenterEyeMat) * + inputCalibrationData.defaultHeadMat; + + controller::Pose hmdHeadPose = pose.transform(sensorToAvatar); - static const glm::quat yFlip = glm::angleAxis(PI, Vectors::UNIT_Y); - pose.translation = toGlm(headPose.ThePose.Position); - pose.rotation = toGlm(headPose.ThePose.Orientation) * yFlip; - pose.angularVelocity = toGlm(headPose.AngularVelocity); - pose.velocity = toGlm(headPose.LinearVelocity); pose.valid = true; - - // transform into avatar frame - glm::mat4 controllerToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat; - pose = pose.transform(controllerToAvatar); + _poseStateMap[controller::HEAD] = hmdHeadPose.postTransform(defaultHeadOffset); } void OculusControllerManager::TouchDevice::handleRotationForUntrackedHand(const controller::InputCalibrationData& inputCalibrationData, From 9b34abeb40f200a708285e3f6d8ae76103510ca4 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 2 Jun 2017 15:43:29 -0700 Subject: [PATCH 65/91] oops initializer order... --- interface/src/ui/overlays/Text3DOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index d7e4edb197..9df8d2beb9 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -29,9 +29,9 @@ Text3DOverlay::Text3DOverlay() : _mutex() { } Text3DOverlay::Text3DOverlay(const Text3DOverlay* text3DOverlay) : - _mutex(), Billboard3DOverlay(text3DOverlay), _text(text3DOverlay->_text), + _mutex(), _backgroundColor(text3DOverlay->_backgroundColor), _textAlpha(text3DOverlay->_textAlpha), _lineHeight(text3DOverlay->_lineHeight), From 12cbc206d2fc94f87e0df6916f27cf81df6b0a0e Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 2 Jun 2017 15:59:15 -0700 Subject: [PATCH 66/91] cr feedback --- interface/src/ui/overlays/Text3DOverlay.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 9df8d2beb9..ebc28ca86a 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -23,7 +23,7 @@ const float LINE_SCALE_RATIO = 1.2f; QString const Text3DOverlay::TYPE = "text3d"; -Text3DOverlay::Text3DOverlay() : _mutex() { +Text3DOverlay::Text3DOverlay() { _textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); _geometryId = DependencyManager::get()->allocateID(); } @@ -31,7 +31,6 @@ Text3DOverlay::Text3DOverlay() : _mutex() { Text3DOverlay::Text3DOverlay(const Text3DOverlay* text3DOverlay) : Billboard3DOverlay(text3DOverlay), _text(text3DOverlay->_text), - _mutex(), _backgroundColor(text3DOverlay->_backgroundColor), _textAlpha(text3DOverlay->_textAlpha), _lineHeight(text3DOverlay->_lineHeight), From 9654e007a6833a6e0ef1bc74982fe41b5640385b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 2 Jun 2017 16:31:08 -0700 Subject: [PATCH 67/91] most input plugins are not head or hand controllers --- .../input-plugins/src/input-plugins/KeyboardMouseDevice.h | 3 --- libraries/input-plugins/src/input-plugins/TouchscreenDevice.h | 3 --- libraries/plugins/src/plugins/InputPlugin.h | 4 ++-- plugins/hifiNeuron/src/NeuronPlugin.h | 3 --- plugins/hifiSdl2/src/SDL2Manager.h | 2 -- plugins/hifiSixense/src/SixenseManager.h | 3 +-- 6 files changed, 3 insertions(+), 15 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h index a0e216c904..b94acb8b71 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h @@ -70,9 +70,6 @@ public: bool isSupported() const override { return true; } const QString getName() const override { return NAME; } - bool isHandController() const override { return false; } - bool isHeadController() const override { return false; } - void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h index 926f9dbdca..02dcbe4664 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h @@ -39,9 +39,6 @@ public: virtual bool isSupported() const override; virtual const QString getName() const override { return NAME; } - bool isHandController() const override { return false; } - bool isHeadController() const override { return false; } - virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; diff --git a/libraries/plugins/src/plugins/InputPlugin.h b/libraries/plugins/src/plugins/InputPlugin.h index 0519ed776d..2a4737b5a1 100644 --- a/libraries/plugins/src/plugins/InputPlugin.h +++ b/libraries/plugins/src/plugins/InputPlugin.h @@ -24,7 +24,7 @@ public: // Some input plugins are comprised of multiple subdevices (SDL2, for instance). // If an input plugin is only a single device, it will only return it's primary name. virtual QStringList getSubdeviceNames() { return { getName() }; }; - virtual bool isHandController() const = 0; - virtual bool isHeadController() const = 0; + virtual bool isHandController() const { return false; } + virtual bool isHeadController() const { return false; } }; diff --git a/plugins/hifiNeuron/src/NeuronPlugin.h b/plugins/hifiNeuron/src/NeuronPlugin.h index 41c2322465..34d084160f 100644 --- a/plugins/hifiNeuron/src/NeuronPlugin.h +++ b/plugins/hifiNeuron/src/NeuronPlugin.h @@ -25,9 +25,6 @@ class NeuronPlugin : public InputPlugin { public: friend void FrameDataReceivedCallback(void* context, void* sender, _BvhDataHeaderEx* header, float* data); - bool isHandController() const override { return false; } - bool isHeadController() const override { return false; } - // Plugin functions virtual void init() override; virtual bool isSupported() const override; diff --git a/plugins/hifiSdl2/src/SDL2Manager.h b/plugins/hifiSdl2/src/SDL2Manager.h index d2bbe8265e..9cb4d268c0 100644 --- a/plugins/hifiSdl2/src/SDL2Manager.h +++ b/plugins/hifiSdl2/src/SDL2Manager.h @@ -27,8 +27,6 @@ public: const QString getName() const override { return NAME; } QStringList getSubdeviceNames() override; - bool isHandController() const override { return false; } - bool isHeadController() const override { return false; } void init() override; void deinit() override; diff --git a/plugins/hifiSixense/src/SixenseManager.h b/plugins/hifiSixense/src/SixenseManager.h index 889f6c3bad..5b2c140868 100644 --- a/plugins/hifiSixense/src/SixenseManager.h +++ b/plugins/hifiSixense/src/SixenseManager.h @@ -33,8 +33,7 @@ public: // Sixense always seems to initialize even if the hydras are not present. Is there // a way we can properly detect whether the hydras are present? - bool isHandController() const override { return false; } - bool isHeadController() const override { return false; } + // bool isHandController() const override { return true; } virtual bool activate() override; virtual void deactivate() override; From f70702beb7a63618a515a33a825db2bcec32f5e0 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 2 Jun 2017 17:54:41 -0700 Subject: [PATCH 68/91] Introducing debug flags --- .../render-utils/src/StencilMaskPass.cpp | 11 ++++++--- libraries/render-utils/src/StencilMaskPass.h | 24 +++++++++++++++---- .../render-utils/src/ToneMappingEffect.cpp | 1 - 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/libraries/render-utils/src/StencilMaskPass.cpp b/libraries/render-utils/src/StencilMaskPass.cpp index dcd994763f..2374f24211 100644 --- a/libraries/render-utils/src/StencilMaskPass.cpp +++ b/libraries/render-utils/src/StencilMaskPass.cpp @@ -22,6 +22,11 @@ using namespace render; +void PrepareStencil::configure(const Config& config) { + _maskMode = config.maskMode; + _forceDraw = config.forceDraw; +} + model::MeshPointer PrepareStencil::getMesh() { if (!_mesh) { @@ -72,8 +77,8 @@ gpu::PipelinePointer PrepareStencil::getPaintStencilPipeline() { void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { RenderArgs* args = renderContext->args; - // Only draw the stencil mask if in HMD mode. - if (args->_displayMode != RenderArgs::STEREO_HMD) { + // Only draw the stencil mask if in HMD mode or not forced. + if (!_forceDraw && (args->_displayMode != RenderArgs::STEREO_HMD)) { return; } @@ -82,7 +87,7 @@ void PrepareStencil::run(const RenderContextPointer& renderContext, const gpu::F batch.setViewportTransform(args->_viewport); - if (false) { + if (_maskMode < 0) { batch.setPipeline(getMeshStencilPipeline()); auto mesh = getMesh(); diff --git a/libraries/render-utils/src/StencilMaskPass.h b/libraries/render-utils/src/StencilMaskPass.h index d7d6ee448b..01601d1ae6 100644 --- a/libraries/render-utils/src/StencilMaskPass.h +++ b/libraries/render-utils/src/StencilMaskPass.h @@ -16,16 +16,28 @@ #include #include +class PrepareStencilConfig : public render::Job::Config { + Q_OBJECT + Q_PROPERTY(int maskMode MEMBER maskMode NOTIFY dirty) + Q_PROPERTY(bool forceDraw MEMBER forceDraw NOTIFY dirty) + +public: + PrepareStencilConfig(bool enabled = true) : JobConfig(enabled) {} + + int maskMode { 0 }; + bool forceDraw { false }; + +signals: + void dirty(); +}; + class PrepareStencil { public: - class Config : public render::JobConfig { - public: - Config(bool enabled = true) : JobConfig(enabled) {} - }; + using Config = PrepareStencilConfig; using JobModel = render::Job::ModelI; - void configure(const Config& config) {} + void configure(const Config& config); void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& dstFramebuffer); @@ -51,6 +63,8 @@ private: model::MeshPointer _mesh; model::MeshPointer getMesh(); + int _maskMode { 0 }; + bool _forceDraw { false }; }; diff --git a/libraries/render-utils/src/ToneMappingEffect.cpp b/libraries/render-utils/src/ToneMappingEffect.cpp index 7a3d868236..ce41cf16fa 100644 --- a/libraries/render-utils/src/ToneMappingEffect.cpp +++ b/libraries/render-utils/src/ToneMappingEffect.cpp @@ -39,7 +39,6 @@ void ToneMappingEffect::init() { slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), ToneMappingEffect_LightingMapSlot)); gpu::Shader::makeProgram(*blitProgram, slotBindings); auto blitState = std::make_shared(); - PrepareStencil::testMask(*blitState); blitState->setColorWriteMask(true, true, true, true); _blitLightBuffer = gpu::PipelinePointer(gpu::Pipeline::create(blitProgram, blitState)); } From 52c60b35df8d68c945f86c3d5c281b499c6e9ae6 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 2 Jun 2017 09:50:23 -0700 Subject: [PATCH 69/91] Add startup_sent_to user activity event --- interface/src/Application.cpp | 36 +++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 27c158322d..bf578fb28e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2404,15 +2404,16 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { // Check HMD use (may be technically available without being in use) bool hasHMD = PluginUtils::isHMDAvailable(); - bool isUsingHMD = hasHMD && hasHandControllers && _displayPlugin->isHmd(); + bool isUsingHMD = _displayPlugin->isHmd(); + bool isUsingHMDAndHandControllers = hasHMD && hasHandControllers && isUsingHMD; Setting::Handle tutorialComplete{ "tutorialComplete", false }; Setting::Handle firstRun{ Settings::firstRun, true }; bool isTutorialComplete = tutorialComplete.get(); - bool shouldGoToTutorial = isUsingHMD && hasTutorialContent && !isTutorialComplete; + bool shouldGoToTutorial = isUsingHMDAndHandControllers && hasTutorialContent && !isTutorialComplete; - qCDebug(interfaceapp) << "HMD:" << hasHMD << ", Hand Controllers: " << hasHandControllers << ", Using HMD: " << isUsingHMD; + qCDebug(interfaceapp) << "HMD:" << hasHMD << ", Hand Controllers: " << hasHandControllers << ", Using HMD: " << isUsingHMDAndHandControllers; qCDebug(interfaceapp) << "Tutorial version:" << contentVersion << ", sufficient:" << hasTutorialContent << ", complete:" << isTutorialComplete << ", should go:" << shouldGoToTutorial; @@ -2426,10 +2427,18 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { const QString TUTORIAL_PATH = "/tutorial_begin"; + static const QString SENT_TO_TUTORIAL = "tutorial"; + static const QString SENT_TO_PREVIOUS_LOCATION = "previous_location"; + static const QString SENT_TO_ENTRY = "entry"; + static const QString SENT_TO_SANDBOX = "sandbox"; + + QString sentTo; + if (shouldGoToTutorial) { if (sandboxIsRunning) { qCDebug(interfaceapp) << "Home sandbox appears to be running, going to Home."; DependencyManager::get()->goToLocalSandbox(TUTORIAL_PATH); + sentTo = SENT_TO_TUTORIAL; } else { qCDebug(interfaceapp) << "Home sandbox does not appear to be running, going to Entry."; if (firstRun.get()) { @@ -2437,8 +2446,10 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { } if (addressLookupString.isEmpty()) { DependencyManager::get()->goToEntry(); + sentTo = SENT_TO_ENTRY; } else { DependencyManager::get()->loadSettings(addressLookupString); + sentTo = SENT_TO_PREVIOUS_LOCATION; } } } else { @@ -2451,23 +2462,40 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { // If this is a first run we short-circuit the address passed in if (isFirstRun) { - if (isUsingHMD) { + if (isUsingHMDAndHandControllers) { if (sandboxIsRunning) { qCDebug(interfaceapp) << "Home sandbox appears to be running, going to Home."; DependencyManager::get()->goToLocalSandbox(); + sentTo = SENT_TO_SANDBOX; } else { qCDebug(interfaceapp) << "Home sandbox does not appear to be running, going to Entry."; DependencyManager::get()->goToEntry(); + sentTo = SENT_TO_ENTRY; } } else { DependencyManager::get()->goToEntry(); + sentTo = SENT_TO_ENTRY; } } else { qCDebug(interfaceapp) << "Not first run... going to" << qPrintable(addressLookupString.isEmpty() ? QString("previous location") : addressLookupString); DependencyManager::get()->loadSettings(addressLookupString); + sentTo = SENT_TO_PREVIOUS_LOCATION; } } + UserActivityLogger::getInstance().logAction("startup_sent_to", { + { "sent_to", sentTo }, + { "sandbox_is_running", sandboxIsRunning }, + { "has_hmd", hasHMD }, + { "has_hand_controllers", hasHandControllers }, + { "is_using_hmd", isUsingHMD }, + { "is_using_hmd_and_hand_controllers", isUsingHMDAndHandControllers }, + { "content_version", contentVersion }, + { "is_tutorial_complete", isTutorialComplete }, + { "has_tutorial_content", hasTutorialContent }, + { "should_go_to_tutorial", shouldGoToTutorial } + }); + _connectionMonitor.init(); // After all of the constructor is completed, then set firstRun to false. From 7da73d0ff11832b66ed8a5e81e0e650391da4ae1 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 2 Jun 2017 18:01:40 -0700 Subject: [PATCH 70/91] teleport.js should still function on avatars with no feet. --- scripts/system/controllers/teleport.js | 52 ++++++++------------------ 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/scripts/system/controllers/teleport.js b/scripts/system/controllers/teleport.js index dcbcaeb621..d6248fc6e0 100644 --- a/scripts/system/controllers/teleport.js +++ b/scripts/system/controllers/teleport.js @@ -366,45 +366,25 @@ function Teleporter() { } // related to repositioning the avatar after you teleport +var FOOT_JOINT_NAMES = ["RightToe_End", "RightToeBase", "RightFoot"]; +var DEFAULT_ROOT_TO_FOOT_OFFSET = 0.5; function getAvatarFootOffset() { - var data = getJointData(); - var upperLeg, lowerLeg, foot, toe, toeTop; - data.forEach(function(d) { - var jointName = d.joint; - if (jointName === "RightUpLeg") { - upperLeg = d.translation.y; - } else if (jointName === "RightLeg") { - lowerLeg = d.translation.y; - } else if (jointName === "RightFoot") { - foot = d.translation.y; - } else if (jointName === "RightToeBase") { - toe = d.translation.y; - } else if (jointName === "RightToe_End") { - toeTop = d.translation.y; + // find a valid foot jointIndex + var footJointIndex = -1; + var i, l = FOOT_JOINT_NAMES.length; + for (i = 0; i < l; i++) { + footJointIndex = MyAvatar.getJointIndex(FOOT_JOINT_NAMES[i]); + if (footJointIndex != -1) { + break; } - }); - - var offset = upperLeg + lowerLeg + foot + toe + toeTop; - offset = offset / 100; - return offset; -} - -function getJointData() { - var allJointData = []; - var jointNames = MyAvatar.jointNames; - jointNames.forEach(function(joint, index) { - var translation = MyAvatar.getJointTranslation(index); - var rotation = MyAvatar.getJointRotation(index); - allJointData.push({ - joint: joint, - index: index, - translation: translation, - rotation: rotation - }); - }); - - return allJointData; + } + if (footJointIndex != -1) { + // default vertical offset from foot to avatar root. + return -MyAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(footJointIndex).y; + } else { + return DEFAULT_ROOT_TO_FOOT_OFFSET; + } } var leftPad = new ThumbPad('left'); From d38a396e9d8b67e976646595e20dd856e4460893 Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Sat, 3 Jun 2017 08:59:47 -0700 Subject: [PATCH 71/91] Fixing warning --- libraries/model/src/model/Geometry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/model/src/model/Geometry.cpp b/libraries/model/src/model/Geometry.cpp index 2525491460..f88c8233ea 100755 --- a/libraries/model/src/model/Geometry.cpp +++ b/libraries/model/src/model/Geometry.cpp @@ -257,7 +257,7 @@ MeshPointer Mesh::createIndexedTriangles_P3F(uint32_t numVertices, uint32_t numI int16_t* shortIndices = nullptr; if (indices) { shortIndicesVector.resize(numIndices); - for (int i = 0; i < numIndices; i++) { + for (uint32_t i = 0; i < numIndices; i++) { shortIndicesVector[i] = indices[i]; } shortIndices = shortIndicesVector.data(); From 024499bdc440acd1112946935244af1b6b5fc79d Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Sun, 4 Jun 2017 12:59:15 -0700 Subject: [PATCH 72/91] Optimized NVTT library with fast gamma conversion --- cmake/externals/nvtt/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/externals/nvtt/CMakeLists.txt b/cmake/externals/nvtt/CMakeLists.txt index 0e1c240c77..91e63e6324 100644 --- a/cmake/externals/nvtt/CMakeLists.txt +++ b/cmake/externals/nvtt/CMakeLists.txt @@ -8,8 +8,8 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://s3.amazonaws.com/hifi-public/dependencies/nvtt-win-2.1.0.zip - URL_MD5 3ea6eeadbcc69071acf9c49ba565760e + URL http://s3.amazonaws.com/hifi-public/dependencies/nvtt-win-2.1.0.hifi.zip + URL_MD5 907f2c683e2bcf8b8089576ec38747b4 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" @@ -29,8 +29,8 @@ else () ExternalProject_Add( ${EXTERNAL_NAME} - URL http://hifi-public.s3.amazonaws.com/dependencies/nvidia-texture-tools-2.1.0.zip - URL_MD5 81b8fa6a9ee3f986088eb6e2215d6a57 + URL http://hifi-public.s3.amazonaws.com/dependencies/nvidia-texture-tools-2.1.0.hifi.zip + URL_MD5 cda96482825225511d3effabbc1ddc7e CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DNVTT_SHARED=1 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= LOG_DOWNLOAD 1 LOG_CONFIGURE 1 From 347104204e40ff2f2939ea67db3f36f2128f4e51 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 31 May 2017 09:56:39 -0700 Subject: [PATCH 73/91] fix StorageTests on linux --- tests/shared/src/StorageTests.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/shared/src/StorageTests.cpp b/tests/shared/src/StorageTests.cpp index fa538f6911..48e6b91900 100644 --- a/tests/shared/src/StorageTests.cpp +++ b/tests/shared/src/StorageTests.cpp @@ -8,6 +8,8 @@ #include "StorageTests.h" +#include + QTEST_MAIN(StorageTests) using namespace storage; @@ -32,8 +34,8 @@ void StorageTests::testConversion() { QFileInfo fileInfo(_testFile); QCOMPARE(fileInfo.exists(), false); } - StoragePointer storagePointer = std::make_unique(_testData.size(), _testData.data()); - QCOMPARE(storagePointer->size(), (quint64)_testData.size()); + StoragePointer storagePointer = std::unique_ptr(new MemoryStorage(_testData.size(), _testData.data())); + QCOMPARE(storagePointer->size(), _testData.size()); QCOMPARE(memcmp(_testData.data(), storagePointer->data(), _testData.size()), 0); // Convert to a file storagePointer = storagePointer->toFileStorage(_testFile); @@ -42,12 +44,12 @@ void StorageTests::testConversion() { QCOMPARE(fileInfo.exists(), true); QCOMPARE(fileInfo.size(), (qint64)_testData.size()); } - QCOMPARE(storagePointer->size(), (quint64)_testData.size()); + QCOMPARE(storagePointer->size(), _testData.size()); QCOMPARE(memcmp(_testData.data(), storagePointer->data(), _testData.size()), 0); // Convert to memory storagePointer = storagePointer->toMemoryStorage(); - QCOMPARE(storagePointer->size(), (quint64)_testData.size()); + QCOMPARE(storagePointer->size(), _testData.size()); QCOMPARE(memcmp(_testData.data(), storagePointer->data(), _testData.size()), 0); { // ensure the file is unaffected @@ -58,13 +60,13 @@ void StorageTests::testConversion() { // truncate the data as a new memory object auto newSize = _testData.size() / 2; - storagePointer = std::make_unique(newSize, storagePointer->data()); - QCOMPARE(storagePointer->size(), (quint64)newSize); + storagePointer = std::unique_ptr(new MemoryStorage(newSize, storagePointer->data())); + QCOMPARE(storagePointer->size(), newSize); QCOMPARE(memcmp(_testData.data(), storagePointer->data(), newSize), 0); // Convert back to file storagePointer = storagePointer->toFileStorage(_testFile); - QCOMPARE(storagePointer->size(), (quint64)newSize); + QCOMPARE(storagePointer->size(), newSize); QCOMPARE(memcmp(_testData.data(), storagePointer->data(), newSize), 0); { // ensure the file is truncated From 81764f0f7165167480804decfe93062dd4d97683 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 31 May 2017 09:57:54 -0700 Subject: [PATCH 74/91] fix GLMHelpers::generateBasisVectors() --- libraries/shared/src/GLMHelpers.cpp | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 70237e8ff6..10c73d6c6a 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -49,7 +49,7 @@ const mat4 Matrices::Z_180 { createMatFromQuatAndPos(Quaternions::Z_180, Vectors glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float proportion) { float cosa = q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w; float ox = q2.x, oy = q2.y, oz = q2.z, ow = q2.w, s0, s1; - + // adjust signs if necessary if (cosa < 0.0f) { cosa = -cosa; @@ -58,19 +58,19 @@ glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float proportion) { oz = -oz; ow = -ow; } - + // calculate coefficients; if the angle is too close to zero, we must fall back // to linear interpolation if ((1.0f - cosa) > EPSILON) { float angle = acosf(cosa), sina = sinf(angle); s0 = sinf((1.0f - proportion) * angle) / sina; s1 = sinf(proportion * angle) / sina; - + } else { s0 = 1.0f - proportion; s1 = proportion; } - + return glm::normalize(glm::quat(s0 * q1.w + s1 * ow, s0 * q1.x + s1 * ox, s0 * q1.y + s1 * oy, s0 * q1.z + s1 * oz)); } @@ -105,10 +105,10 @@ int unpackFloatVec3FromSignedTwoByteFixed(const unsigned char* sourceBuffer, glm int packFloatAngleToTwoByte(unsigned char* buffer, float degrees) { const float ANGLE_CONVERSION_RATIO = (std::numeric_limits::max() / 360.0f); - + uint16_t angleHolder = floorf((degrees + 180.0f) * ANGLE_CONVERSION_RATIO); memcpy(buffer, &angleHolder, sizeof(uint16_t)); - + return sizeof(uint16_t); } @@ -125,7 +125,7 @@ int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput quatParts[1] = floorf((quatNormalized.y + 1.0f) * QUAT_PART_CONVERSION_RATIO); quatParts[2] = floorf((quatNormalized.z + 1.0f) * QUAT_PART_CONVERSION_RATIO); quatParts[3] = floorf((quatNormalized.w + 1.0f) * QUAT_PART_CONVERSION_RATIO); - + memcpy(buffer, &quatParts, sizeof(quatParts)); return sizeof(quatParts); } @@ -133,12 +133,12 @@ int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput int unpackOrientationQuatFromBytes(const unsigned char* buffer, glm::quat& quatOutput) { uint16_t quatParts[4]; memcpy(&quatParts, buffer, sizeof(quatParts)); - + quatOutput.x = ((quatParts[0] / (float) std::numeric_limits::max()) * 2.0f) - 1.0f; quatOutput.y = ((quatParts[1] / (float) std::numeric_limits::max()) * 2.0f) - 1.0f; quatOutput.z = ((quatParts[2] / (float) std::numeric_limits::max()) * 2.0f) - 1.0f; quatOutput.w = ((quatParts[3] / (float) std::numeric_limits::max()) * 2.0f) - 1.0f; - + return sizeof(quatParts); } @@ -235,7 +235,7 @@ glm::vec3 safeEulerAngles(const glm::quat& q) { atan2f(q.y * q.z + q.x * q.w, 0.5f - (q.x * q.x + q.y * q.y)), asinf(sy), atan2f(q.x * q.y + q.z * q.w, 0.5f - (q.y * q.y + q.z * q.z))); - + } else { // not a unique solution; x + z = atan2(-m21, m11) eulers = glm::vec3( @@ -250,7 +250,7 @@ glm::vec3 safeEulerAngles(const glm::quat& q) { PI_OVER_TWO, -atan2f(q.x * q.w - q.y * q.z, 0.5f - (q.x * q.x + q.z * q.z))); } - + // adjust so that z, rather than y, is in [-pi/2, pi/2] if (eulers.z < -PI_OVER_TWO) { if (eulers.x < 0.0f) { @@ -265,7 +265,7 @@ glm::vec3 safeEulerAngles(const glm::quat& q) { eulers.y -= PI; } eulers.z += PI; - + } else if (eulers.z > PI_OVER_TWO) { if (eulers.x < 0.0f) { eulers.x += PI; @@ -320,7 +320,7 @@ glm::quat extractRotation(const glm::mat4& matrix, bool assumeOrthogonal) { for (int i = 0; i < 10; i++) { // store the results of the previous iteration glm::mat3 previous = upper; - + // compute average of the matrix with its inverse transpose float sd00 = previous[1][1] * previous[2][2] - previous[2][1] * previous[1][2]; float sd10 = previous[0][1] * previous[2][2] - previous[2][1] * previous[0][2]; @@ -334,15 +334,15 @@ glm::quat extractRotation(const glm::mat4& matrix, bool assumeOrthogonal) { upper[0][0] = +sd00 * hrdet + previous[0][0] * 0.5f; upper[1][0] = -sd10 * hrdet + previous[1][0] * 0.5f; upper[2][0] = +sd20 * hrdet + previous[2][0] * 0.5f; - + upper[0][1] = -(previous[1][0] * previous[2][2] - previous[2][0] * previous[1][2]) * hrdet + previous[0][1] * 0.5f; upper[1][1] = +(previous[0][0] * previous[2][2] - previous[2][0] * previous[0][2]) * hrdet + previous[1][1] * 0.5f; upper[2][1] = -(previous[0][0] * previous[1][2] - previous[1][0] * previous[0][2]) * hrdet + previous[2][1] * 0.5f; - + upper[0][2] = +(previous[1][0] * previous[2][1] - previous[2][0] * previous[1][1]) * hrdet + previous[0][2] * 0.5f; upper[1][2] = -(previous[0][0] * previous[2][1] - previous[2][0] * previous[0][1]) * hrdet + previous[1][2] * 0.5f; upper[2][2] = +(previous[0][0] * previous[1][1] - previous[1][0] * previous[0][1]) * hrdet + previous[2][2] * 0.5f; - + // compute the difference; if it's small enough, we're done glm::mat3 diff = upper - previous; if (diff[0][0] * diff[0][0] + diff[1][0] * diff[1][0] + diff[2][0] * diff[2][0] + diff[0][1] * diff[0][1] + @@ -352,7 +352,7 @@ glm::quat extractRotation(const glm::mat4& matrix, bool assumeOrthogonal) { } } } - + // now that we have a nice orthogonal matrix, we can extract the rotation quaternion // using the method described in http://en.wikipedia.org/wiki/Rotation_matrix#Conversions float x2 = fabs(1.0f + upper[0][0] - upper[1][1] - upper[2][2]); @@ -473,7 +473,7 @@ glm::mat4 createMatFromScaleQuatAndPos(const glm::vec3& scale, const glm::quat& glm::vec4(zAxis, 0.0f), glm::vec4(trans, 1.0f)); } -// cancel out roll +// cancel out roll glm::quat cancelOutRoll(const glm::quat& q) { glm::vec3 forward = q * Vectors::FRONT; return glm::quat_cast(glm::inverse(glm::lookAt(Vectors::ZERO, forward, Vectors::UP))); @@ -540,15 +540,15 @@ void generateBasisVectors(const glm::vec3& primaryAxis, const glm::vec3& seconda // if secondaryAxis is parallel with the primaryAxis, pick another axis. const float EPSILON = 1.0e-4f; - if (fabsf(fabsf(glm::dot(uAxisOut, secondaryAxis)) - 1.0f) > EPSILON) { + if (fabsf(fabsf(glm::dot(uAxisOut, secondaryAxis)) - 1.0f) < EPSILON) { // pick a better secondaryAxis. normSecondary = glm::vec3(1.0f, 0.0f, 0.0f); - if (fabsf(fabsf(glm::dot(uAxisOut, secondaryAxis)) - 1.0f) > EPSILON) { + if (fabsf(fabsf(glm::dot(uAxisOut, secondaryAxis)) - 1.0f) < EPSILON) { normSecondary = glm::vec3(0.0f, 1.0f, 0.0f); } } - wAxisOut = glm::normalize(glm::cross(uAxisOut, secondaryAxis)); + wAxisOut = glm::normalize(glm::cross(uAxisOut, normSecondary)); vAxisOut = glm::cross(wAxisOut, uAxisOut); } From 1621d31a8e38b3ea72e8972bd9b27fcea9e5cfee Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 31 May 2017 09:58:58 -0700 Subject: [PATCH 75/91] cleanup usage of GLMHelpers::generateBasisVectors() --- libraries/animation/src/Rig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index add3a461af..4a22aa1df1 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1137,7 +1137,7 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm glm::vec3 headUp = headQuat * Vectors::UNIT_Y; glm::vec3 z, y, x; generateBasisVectors(lookAtVector, headUp, z, y, x); - glm::mat3 m(glm::cross(y, z), y, z); + glm::mat3 m(-x, y, z); glm::quat desiredQuat = glm::normalize(glm::quat_cast(m)); glm::quat deltaQuat = desiredQuat * glm::inverse(headQuat); From 506f522802245d2421c21030b7e1217c384f02a0 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 31 May 2017 09:59:14 -0700 Subject: [PATCH 76/91] use correct format for float literals --- libraries/render-utils/src/AnimDebugDraw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index 162745e76f..4f7f9ef5c4 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -260,7 +260,7 @@ static void addLink(const AnimPose& rootPose, const AnimPose& pose, const AnimPo // there is room, so lets draw a nice bone glm::vec3 uAxis, vAxis, wAxis; - generateBasisVectors(boneAxis0, glm::vec3(1, 0, 0), uAxis, vAxis, wAxis); + generateBasisVectors(boneAxis0, glm::vec3(1.0f, 0.0f, 0.0f), uAxis, vAxis, wAxis); glm::vec3 boneBaseCorners[NUM_BASE_CORNERS]; boneBaseCorners[0] = pose0 * ((uAxis * radius) + (vAxis * radius) + (wAxis * radius)); From 205e5d730927a3852cf914bcedfcc94e3f4549c2 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 31 May 2017 11:24:36 -0700 Subject: [PATCH 77/91] add unit tests and fix final bugs --- libraries/shared/src/GLMHelpers.cpp | 7 ++- tests/shared/src/GLMHelpersTests.cpp | 74 ++++++++++++++++++++++++++++ tests/shared/src/GLMHelpersTests.h | 1 + 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 10c73d6c6a..7ebaa11da6 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -538,12 +538,11 @@ void generateBasisVectors(const glm::vec3& primaryAxis, const glm::vec3& seconda uAxisOut = glm::normalize(primaryAxis); glm::vec3 normSecondary = glm::normalize(secondaryAxis); - // if secondaryAxis is parallel with the primaryAxis, pick another axis. + // if normSecondary is parallel with the primaryAxis, pick another secondary. const float EPSILON = 1.0e-4f; - if (fabsf(fabsf(glm::dot(uAxisOut, secondaryAxis)) - 1.0f) < EPSILON) { - // pick a better secondaryAxis. + if (fabsf(fabsf(glm::dot(uAxisOut, normSecondary)) - 1.0f) < EPSILON) { normSecondary = glm::vec3(1.0f, 0.0f, 0.0f); - if (fabsf(fabsf(glm::dot(uAxisOut, secondaryAxis)) - 1.0f) < EPSILON) { + if (fabsf(fabsf(glm::dot(uAxisOut, normSecondary)) - 1.0f) < EPSILON) { normSecondary = glm::vec3(0.0f, 1.0f, 0.0f); } } diff --git a/tests/shared/src/GLMHelpersTests.cpp b/tests/shared/src/GLMHelpersTests.cpp index b4af4729a3..83a294ee1d 100644 --- a/tests/shared/src/GLMHelpersTests.cpp +++ b/tests/shared/src/GLMHelpersTests.cpp @@ -140,3 +140,77 @@ void GLMHelpersTests::testSimd() { } qDebug() << "Done "; } + +void GLMHelpersTests::testGenerateBasisVectors() { + { // very simple case: primary along X, secondary is linear combination of X and Y + glm::vec3 u(1.0f, 0.0f, 0.0f); + glm::vec3 v(1.0f, 1.0f, 0.0f); + glm::vec3 w; + + generateBasisVectors(u, v, u, v, w); + + QCOMPARE_WITH_ABS_ERROR(u, Vectors::UNIT_X, EPSILON); + QCOMPARE_WITH_ABS_ERROR(v, Vectors::UNIT_Y, EPSILON); + QCOMPARE_WITH_ABS_ERROR(w, Vectors::UNIT_Z, EPSILON); + } + + { // point primary along Y instead of X + glm::vec3 u(0.0f, 1.0f, 0.0f); + glm::vec3 v(1.0f, 1.0f, 0.0f); + glm::vec3 w; + + generateBasisVectors(u, v, u, v, w); + + QCOMPARE_WITH_ABS_ERROR(u, Vectors::UNIT_Y, EPSILON); + QCOMPARE_WITH_ABS_ERROR(v, Vectors::UNIT_X, EPSILON); + QCOMPARE_WITH_ABS_ERROR(w, -Vectors::UNIT_Z, EPSILON); + } + + { // pass bad data (both vectors along Y). The helper will guess X for secondary. + glm::vec3 u(0.0f, 1.0f, 0.0f); + glm::vec3 v(0.0f, 1.0f, 0.0f); + glm::vec3 w; + + generateBasisVectors(u, v, u, v, w); + + QCOMPARE_WITH_ABS_ERROR(u, Vectors::UNIT_Y, EPSILON); + QCOMPARE_WITH_ABS_ERROR(v, Vectors::UNIT_X, EPSILON); + QCOMPARE_WITH_ABS_ERROR(w, -Vectors::UNIT_Z, EPSILON); + } + + { // pass bad data (both vectors along X). The helper will guess X for secondary, fail, then guess Y. + glm::vec3 u(1.0f, 0.0f, 0.0f); + glm::vec3 v(1.0f, 0.0f, 0.0f); + glm::vec3 w; + + generateBasisVectors(u, v, u, v, w); + + QCOMPARE_WITH_ABS_ERROR(u, Vectors::UNIT_X, EPSILON); + QCOMPARE_WITH_ABS_ERROR(v, Vectors::UNIT_Y, EPSILON); + QCOMPARE_WITH_ABS_ERROR(w, Vectors::UNIT_Z, EPSILON); + } + + { // general case for arbitrary rotation + float angle = 1.234f; + glm::vec3 axis = glm::normalize(glm::vec3(1.0f, 2.0f, 3.0f)); + glm::quat rotation = glm::angleAxis(angle, axis); + + // expected values + glm::vec3 x = rotation * Vectors::UNIT_X; + glm::vec3 y = rotation * Vectors::UNIT_Y; + glm::vec3 z = rotation * Vectors::UNIT_Z; + + // primary is along x + // secondary is linear combination of x and y + // tertiary is unknown + glm::vec3 u = 1.23f * x; + glm::vec3 v = 2.34f * x + 3.45f * y; + glm::vec3 w; + + generateBasisVectors(u, v, u, v, w); + + QCOMPARE_WITH_ABS_ERROR(u, x, EPSILON); + QCOMPARE_WITH_ABS_ERROR(v, y, EPSILON); + QCOMPARE_WITH_ABS_ERROR(w, z, EPSILON); + } +} diff --git a/tests/shared/src/GLMHelpersTests.h b/tests/shared/src/GLMHelpersTests.h index acc7b533f5..030f2d477f 100644 --- a/tests/shared/src/GLMHelpersTests.h +++ b/tests/shared/src/GLMHelpersTests.h @@ -21,6 +21,7 @@ private slots: void testEulerDecomposition(); void testSixByteOrientationCompression(); void testSimd(); + void testGenerateBasisVectors(); }; float getErrorDifference(const float& a, const float& b); From 6970576bb8e8fd8b6a95cb0aa672f5e1ef2e2982 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 31 May 2017 11:51:35 -0700 Subject: [PATCH 78/91] use helper constants in helper code --- libraries/shared/src/GLMHelpers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 7ebaa11da6..394517aac4 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -541,9 +541,9 @@ void generateBasisVectors(const glm::vec3& primaryAxis, const glm::vec3& seconda // if normSecondary is parallel with the primaryAxis, pick another secondary. const float EPSILON = 1.0e-4f; if (fabsf(fabsf(glm::dot(uAxisOut, normSecondary)) - 1.0f) < EPSILON) { - normSecondary = glm::vec3(1.0f, 0.0f, 0.0f); + normSecondary = Vectors::UNIT_X; if (fabsf(fabsf(glm::dot(uAxisOut, normSecondary)) - 1.0f) < EPSILON) { - normSecondary = glm::vec3(0.0f, 1.0f, 0.0f); + normSecondary = Vectors::UNIT_Y; } } From 27669d44a7458e270abb5209599e2fa126fb4391 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 5 Jun 2017 08:58:40 -0700 Subject: [PATCH 79/91] in deriveBodyFromHMDSensor, avoid using invalid head pose --- interface/src/avatar/MyAvatar.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 826a6a00ac..64914a7ec1 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2338,10 +2338,13 @@ glm::quat MyAvatar::getWorldBodyOrientation() const { // old school meat hook style glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { - - // HMD is in sensor space. - const glm::vec3 headPosition = getHeadControllerPoseInSensorFrame().translation; - const glm::quat headOrientation = getHeadControllerPoseInSensorFrame().rotation * Quaternions::Y_180; + glm::vec3 headPosition; + glm::quat headOrientation; + auto headPose = getHeadControllerPoseInSensorFrame(); + if (headPose.isValid()) { + headPosition = getHeadControllerPoseInSensorFrame().translation; + headOrientation = getHeadControllerPoseInSensorFrame().rotation * Quaternions::Y_180; + } const glm::quat headOrientationYawOnly = cancelOutRollAndPitch(headOrientation); const Rig& rig = _skeletonModel->getRig(); From 793ed1313d7b83c87248d529f38c6da77e1883e5 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Jun 2017 10:30:52 -0700 Subject: [PATCH 80/91] change variable name for more readable code --- libraries/animation/src/Rig.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 4a22aa1df1..2d37213c7a 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1135,9 +1135,9 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm } glm::vec3 headUp = headQuat * Vectors::UNIT_Y; - glm::vec3 z, y, x; - generateBasisVectors(lookAtVector, headUp, z, y, x); - glm::mat3 m(-x, y, z); + glm::vec3 z, y, zCrossY; + generateBasisVectors(lookAtVector, headUp, z, y, zCrossY); + glm::mat3 m(-zCrossY, y, z); glm::quat desiredQuat = glm::normalize(glm::quat_cast(m)); glm::quat deltaQuat = desiredQuat * glm::inverse(headQuat); From 45db8c3befd31102e98069127b7df4a4985e1ebc Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Mon, 5 Jun 2017 11:18:54 -0700 Subject: [PATCH 81/91] Rebase optimizations on NVTT 2.1.0 instead of master --- cmake/externals/nvtt/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/nvtt/CMakeLists.txt b/cmake/externals/nvtt/CMakeLists.txt index 91e63e6324..fa9d7b5ea1 100644 --- a/cmake/externals/nvtt/CMakeLists.txt +++ b/cmake/externals/nvtt/CMakeLists.txt @@ -9,7 +9,7 @@ if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} URL http://s3.amazonaws.com/hifi-public/dependencies/nvtt-win-2.1.0.hifi.zip - URL_MD5 907f2c683e2bcf8b8089576ec38747b4 + URL_MD5 10da01cf601f88f6dc12a6bc13c89136 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" @@ -30,7 +30,7 @@ else () ExternalProject_Add( ${EXTERNAL_NAME} URL http://hifi-public.s3.amazonaws.com/dependencies/nvidia-texture-tools-2.1.0.hifi.zip - URL_MD5 cda96482825225511d3effabbc1ddc7e + URL_MD5 5794b950f8b265a9a41b2839b3bf7ebb CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DNVTT_SHARED=1 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= LOG_DOWNLOAD 1 LOG_CONFIGURE 1 From 3ab67cf27ed459cd7f19f38c24d53acee64784ab Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 5 Jun 2017 11:44:27 -0700 Subject: [PATCH 82/91] fix forward gaze in HMD while not looking at anyone --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5b9e46f549..c83ca9b2ff 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4060,7 +4060,7 @@ void Application::updateMyAvatarLookAtPosition() { if (isHMD) { glm::mat4 worldHeadMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHeadControllerPoseInSensorFrame().getMatrix(); - lookAtSpot = transformPoint(worldHeadMat, glm::vec3(0.0f, 0.0f, TREE_SCALE)); + lookAtSpot = transformPoint(worldHeadMat, glm::vec3(0.0f, 0.0f, -TREE_SCALE)); } else { lookAtSpot = myAvatar->getHead()->getEyePosition() + (myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); From 995fe11c05437f54e9a3eed78e809ac3dbb060c0 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Mon, 5 Jun 2017 14:03:20 -0700 Subject: [PATCH 83/91] Migrate to single QML engine --- interface/resources/qml/Browser.qml | 6 +- interface/resources/qml/TabletBrowser.qml | 6 +- .../qml/controls-uit/BaseWebView.qml | 3 - .../qml/controls/TabletWebScreen.qml | 6 +- .../resources/qml/controls/TabletWebView.qml | 6 +- .../resources/qml/controls/WebEntityView.qml | 6 +- interface/resources/qml/controls/WebView.qml | 6 +- interface/resources/qml/hifi/Desktop.qml | 6 - .../resources/qml/hifi/tablet/EditTabView.qml | 1 - .../resources/qml/hifi/tablet/TabletMenu.qml | 1 - .../resources/qml/hifi/tablet/TabletRoot.qml | 1 - interface/src/Application.cpp | 120 ++++++------- interface/src/ui/overlays/Web3DOverlay.cpp | 63 ++++--- .../src/RenderableWebEntityItem.cpp | 8 +- libraries/gl/CMakeLists.txt | 2 +- libraries/gl/src/gl/OffscreenQmlSurface.cpp | 163 ++++++++++++------ libraries/gl/src/gl/OffscreenQmlSurface.h | 5 +- .../gl/src/gl/OffscreenQmlSurfaceCache.cpp | 1 - libraries/networking/CMakeLists.txt | 2 +- .../networking/src}/FileTypeProfile.cpp | 0 .../networking/src}/FileTypeProfile.h | 0 .../src}/FileTypeRequestInterceptor.cpp | 0 .../src}/FileTypeRequestInterceptor.h | 0 .../src}/HFTabletWebEngineProfile.cpp | 1 + .../src}/HFTabletWebEngineProfile.h | 0 .../HFTabletWebEngineRequestInterceptor.cpp | 2 +- .../HFTabletWebEngineRequestInterceptor.h | 0 .../networking/src}/HFWebEngineProfile.cpp | 1 + .../networking/src}/HFWebEngineProfile.h | 0 .../src}/HFWebEngineRequestInterceptor.cpp | 2 +- .../src}/HFWebEngineRequestInterceptor.h | 0 .../networking/src}/RequestFilters.cpp | 2 +- .../networking/src}/RequestFilters.h | 0 libraries/ui/src/OffscreenUi.cpp | 16 +- libraries/ui/src/VrMenu.cpp | 2 +- 35 files changed, 223 insertions(+), 215 deletions(-) rename {interface/src/networking => libraries/networking/src}/FileTypeProfile.cpp (100%) rename {interface/src/networking => libraries/networking/src}/FileTypeProfile.h (100%) rename {interface/src/networking => libraries/networking/src}/FileTypeRequestInterceptor.cpp (100%) rename {interface/src/networking => libraries/networking/src}/FileTypeRequestInterceptor.h (100%) rename {interface/src/networking => libraries/networking/src}/HFTabletWebEngineProfile.cpp (95%) rename {interface/src/networking => libraries/networking/src}/HFTabletWebEngineProfile.h (100%) rename {interface/src/networking => libraries/networking/src}/HFTabletWebEngineRequestInterceptor.cpp (98%) rename {interface/src/networking => libraries/networking/src}/HFTabletWebEngineRequestInterceptor.h (100%) rename {interface/src/networking => libraries/networking/src}/HFWebEngineProfile.cpp (94%) rename {interface/src/networking => libraries/networking/src}/HFWebEngineProfile.h (100%) rename {interface/src/networking => libraries/networking/src}/HFWebEngineRequestInterceptor.cpp (95%) rename {interface/src/networking => libraries/networking/src}/HFWebEngineRequestInterceptor.h (100%) rename {interface/src/networking => libraries/networking/src}/RequestFilters.cpp (98%) rename {interface/src/networking => libraries/networking/src}/RequestFilters.h (100%) diff --git a/interface/resources/qml/Browser.qml b/interface/resources/qml/Browser.qml index 47fb610469..4f7639dd0e 100644 --- a/interface/resources/qml/Browser.qml +++ b/interface/resources/qml/Browser.qml @@ -2,7 +2,6 @@ import QtQuick 2.5 import QtQuick.Controls 1.2 import QtWebChannel 1.0 import QtWebEngine 1.2 -import FileTypeProfile 1.0 import "controls-uit" import "styles" as HifiStyles @@ -209,6 +208,7 @@ ScrollingWindow { WebView { id: webview url: "https://highfidelity.com/" + profile: FileTypeProfile; property alias eventBridgeWrapper: eventBridgeWrapper @@ -218,10 +218,6 @@ ScrollingWindow { property var eventBridge; } - profile: FileTypeProfile { - id: webviewProfile - storageName: "qmlWebEngine" - } webChannel.registeredObjects: [eventBridgeWrapper] diff --git a/interface/resources/qml/TabletBrowser.qml b/interface/resources/qml/TabletBrowser.qml index ee4d05a701..d89aa8626f 100644 --- a/interface/resources/qml/TabletBrowser.qml +++ b/interface/resources/qml/TabletBrowser.qml @@ -8,7 +8,6 @@ import "controls-uit" as HifiControls import "styles" as HifiStyles import "styles-uit" import "windows" -import HFTabletWebEngineProfile 1.0 Item { id: root @@ -47,10 +46,7 @@ Item { width: parent.width height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height : parent.height - profile: HFTabletWebEngineProfile { - id: webviewTabletProfile - storageName: "qmlTabletWebEngine" - } + profile: HFTabletWebEngineProfile; property string userScriptUrl: "" diff --git a/interface/resources/qml/controls-uit/BaseWebView.qml b/interface/resources/qml/controls-uit/BaseWebView.qml index 670aea71aa..3ca57f03bf 100644 --- a/interface/resources/qml/controls-uit/BaseWebView.qml +++ b/interface/resources/qml/controls-uit/BaseWebView.qml @@ -10,13 +10,10 @@ import QtQuick 2.5 import QtWebEngine 1.2 -import HFWebEngineProfile 1.0 WebEngineView { id: root - // profile: desktop.browserProfile - Component.onCompleted: { console.log("Connecting JS messaging to Hifi Logging") // Ensure the JS from the web-engine makes it to our logging diff --git a/interface/resources/qml/controls/TabletWebScreen.qml b/interface/resources/qml/controls/TabletWebScreen.qml index 93ded724a1..0b265f6fbb 100644 --- a/interface/resources/qml/controls/TabletWebScreen.qml +++ b/interface/resources/qml/controls/TabletWebScreen.qml @@ -2,7 +2,6 @@ import QtQuick 2.5 import QtWebEngine 1.1 import QtWebChannel 1.0 import "../controls-uit" as HiFiControls -import HFTabletWebEngineProfile 1.0 Item { property alias url: root.url @@ -39,10 +38,7 @@ Item { width: parent.width height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height : parent.height - profile: HFTabletWebEngineProfile { - id: webviewProfile - storageName: "qmlTabletWebEngine" - } + profile: HFTabletWebEngineProfile; property string userScriptUrl: "" diff --git a/interface/resources/qml/controls/TabletWebView.qml b/interface/resources/qml/controls/TabletWebView.qml index 215ac68ac0..3b23cbc19e 100644 --- a/interface/resources/qml/controls/TabletWebView.qml +++ b/interface/resources/qml/controls/TabletWebView.qml @@ -2,7 +2,6 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import QtWebEngine 1.2 import QtWebChannel 1.0 -import HFTabletWebEngineProfile 1.0 import "../controls-uit" as HiFiControls import "../styles" as HifiStyles import "../styles-uit" @@ -150,10 +149,7 @@ Item { width: parent.width height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height - web.headerHeight : parent.height - web.headerHeight anchors.top: buttons.bottom - profile: HFTabletWebEngineProfile { - id: webviewTabletProfile - storageName: "qmlTabletWebEngine" - } + profile: HFTabletWebEngineProfile; property string userScriptUrl: "" diff --git a/interface/resources/qml/controls/WebEntityView.qml b/interface/resources/qml/controls/WebEntityView.qml index a3d5fe903b..3bd6aad053 100644 --- a/interface/resources/qml/controls/WebEntityView.qml +++ b/interface/resources/qml/controls/WebEntityView.qml @@ -10,13 +10,9 @@ import QtQuick 2.5 import "." -import FileTypeProfile 1.0 WebView { - viewProfile: FileTypeProfile { - id: webviewProfile - storageName: "qmlWebEngine" - } + viewProfile: FileTypeProfile; urlTag: "noDownload=true"; } diff --git a/interface/resources/qml/controls/WebView.qml b/interface/resources/qml/controls/WebView.qml index 06766fa6ef..d08562eea3 100644 --- a/interface/resources/qml/controls/WebView.qml +++ b/interface/resources/qml/controls/WebView.qml @@ -2,7 +2,6 @@ import QtQuick 2.5 import QtWebEngine 1.1 import QtWebChannel 1.0 import "../controls-uit" as HiFiControls -import HFWebEngineProfile 1.0 Item { property alias url: root.url @@ -39,10 +38,7 @@ Item { width: parent.width height: keyboardEnabled && keyboardRaised ? parent.height - keyboard.height : parent.height - profile: HFWebEngineProfile { - id: webviewProfile - storageName: "qmlWebEngine" - } + profile: HFWebEngineProfile; property string userScriptUrl: "" diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml index 7857eda3c2..ea9ec2f6c9 100644 --- a/interface/resources/qml/hifi/Desktop.qml +++ b/interface/resources/qml/hifi/Desktop.qml @@ -2,7 +2,6 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import QtWebEngine 1.1; import Qt.labs.settings 1.0 -import HFWebEngineProfile 1.0 import "../desktop" as OriginalDesktop import ".." @@ -27,11 +26,6 @@ OriginalDesktop.Desktop { property alias toolWindow: toolWindow ToolWindow { id: toolWindow } - property var browserProfile: HFWebEngineProfile { - id: webviewProfile - storageName: "qmlWebEngine" - } - Action { text: "Open Browser" shortcut: "Ctrl+B" diff --git a/interface/resources/qml/hifi/tablet/EditTabView.qml b/interface/resources/qml/hifi/tablet/EditTabView.qml index 35f2b82f0f..d084f1c7b3 100644 --- a/interface/resources/qml/hifi/tablet/EditTabView.qml +++ b/interface/resources/qml/hifi/tablet/EditTabView.qml @@ -5,7 +5,6 @@ import QtWebChannel 1.0 import QtQuick.Controls.Styles 1.4 import "../../controls" import "../toolbars" -import HFWebEngineProfile 1.0 import QtGraphicalEffects 1.0 import "../../controls-uit" as HifiControls import "../../styles-uit" diff --git a/interface/resources/qml/hifi/tablet/TabletMenu.qml b/interface/resources/qml/hifi/tablet/TabletMenu.qml index af36f72c82..62b61d129b 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenu.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenu.qml @@ -4,7 +4,6 @@ import QtQuick.Controls 1.4 import QtQml 2.2 import QtWebChannel 1.0 import QtWebEngine 1.1 -import HFWebEngineProfile 1.0 import "." diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index 97c8854c86..e7654d9ff1 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -1,7 +1,6 @@ import QtQuick 2.0 import Hifi 1.0 import QtQuick.Controls 1.4 -import HFTabletWebEngineProfile 1.0 import "../../dialogs" import "../../controls" diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 851c07c501..d6475c4b00 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -148,9 +148,6 @@ #include "LODManager.h" #include "ModelPackager.h" #include "networking/CloseEventSender.h" -#include "networking/HFWebEngineProfile.h" -#include "networking/HFTabletWebEngineProfile.h" -#include "networking/FileTypeProfile.h" #include "scripting/TestScriptingInterface.h" #include "scripting/AccountScriptingInterface.h" #include "scripting/AssetMappingsScriptingInterface.h" @@ -1852,14 +1849,10 @@ void Application::initializeUi() { UpdateDialog::registerType(); qmlRegisterType("Hifi", 1, 0, "Preference"); - qmlRegisterType("HFWebEngineProfile", 1, 0, "HFWebEngineProfile"); - qmlRegisterType("HFTabletWebEngineProfile", 1, 0, "HFTabletWebEngineProfile"); - qmlRegisterType("FileTypeProfile", 1, 0, "FileTypeProfile"); - auto offscreenUi = DependencyManager::get(); offscreenUi->create(_glWidget->qglContext()); - auto rootContext = offscreenUi->getRootContext(); + auto surfaceContext = offscreenUi->getSurfaceContext(); offscreenUi->setProxyWindow(_window->windowHandle()); offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); @@ -1871,7 +1864,7 @@ void Application::initializeUi() { // do better detection in the offscreen UI of what has focus offscreenUi->setNavigationFocused(false); - auto engine = rootContext->engine(); + auto engine = surfaceContext->engine(); connect(engine, &QQmlEngine::quit, [] { qApp->quit(); }); @@ -1880,79 +1873,78 @@ void Application::initializeUi() { // For some reason there is already an "Application" object in the QML context, // though I can't find it. Hence, "ApplicationInterface" - rootContext->setContextProperty("ApplicationInterface", this); - rootContext->setContextProperty("Audio", DependencyManager::get().data()); - rootContext->setContextProperty("AudioStats", DependencyManager::get()->getStats().data()); - rootContext->setContextProperty("AudioScope", DependencyManager::get().data()); + surfaceContext->setContextProperty("Audio", DependencyManager::get().data()); + surfaceContext->setContextProperty("AudioStats", DependencyManager::get()->getStats().data()); + surfaceContext->setContextProperty("AudioScope", DependencyManager::get().data()); - rootContext->setContextProperty("Controller", DependencyManager::get().data()); - rootContext->setContextProperty("Entities", DependencyManager::get().data()); + surfaceContext->setContextProperty("Controller", DependencyManager::get().data()); + surfaceContext->setContextProperty("Entities", DependencyManager::get().data()); _fileDownload = new FileScriptingInterface(engine); - rootContext->setContextProperty("File", _fileDownload); + surfaceContext->setContextProperty("File", _fileDownload); connect(_fileDownload, &FileScriptingInterface::unzipResult, this, &Application::handleUnzip); - rootContext->setContextProperty("MyAvatar", getMyAvatar().get()); - rootContext->setContextProperty("Messages", DependencyManager::get().data()); - rootContext->setContextProperty("Recording", DependencyManager::get().data()); - rootContext->setContextProperty("Preferences", DependencyManager::get().data()); - rootContext->setContextProperty("AddressManager", DependencyManager::get().data()); - rootContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); - rootContext->setContextProperty("Rates", new RatesScriptingInterface(this)); - rootContext->setContextProperty("pathToFonts", "../../"); + surfaceContext->setContextProperty("MyAvatar", getMyAvatar().get()); + surfaceContext->setContextProperty("Messages", DependencyManager::get().data()); + surfaceContext->setContextProperty("Recording", DependencyManager::get().data()); + surfaceContext->setContextProperty("Preferences", DependencyManager::get().data()); + surfaceContext->setContextProperty("AddressManager", DependencyManager::get().data()); + surfaceContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); + surfaceContext->setContextProperty("Rates", new RatesScriptingInterface(this)); - rootContext->setContextProperty("TREE_SCALE", TREE_SCALE); - rootContext->setContextProperty("Quat", new Quat()); - rootContext->setContextProperty("Vec3", new Vec3()); - rootContext->setContextProperty("Uuid", new ScriptUUID()); - rootContext->setContextProperty("Assets", DependencyManager::get().data()); + surfaceContext->setContextProperty("TREE_SCALE", TREE_SCALE); + // FIXME Quat and Vec3 won't work with QJSEngine used by QML + surfaceContext->setContextProperty("Quat", new Quat()); + surfaceContext->setContextProperty("Vec3", new Vec3()); + surfaceContext->setContextProperty("Uuid", new ScriptUUID()); + surfaceContext->setContextProperty("Assets", DependencyManager::get().data()); - rootContext->setContextProperty("AvatarList", DependencyManager::get().data()); - rootContext->setContextProperty("Users", DependencyManager::get().data()); + surfaceContext->setContextProperty("AvatarList", DependencyManager::get().data()); + surfaceContext->setContextProperty("Users", DependencyManager::get().data()); - rootContext->setContextProperty("UserActivityLogger", DependencyManager::get().data()); + surfaceContext->setContextProperty("UserActivityLogger", DependencyManager::get().data()); - rootContext->setContextProperty("Camera", &_myCamera); + surfaceContext->setContextProperty("Camera", &_myCamera); #if defined(Q_OS_MAC) || defined(Q_OS_WIN) - rootContext->setContextProperty("SpeechRecognizer", DependencyManager::get().data()); + surfaceContext->setContextProperty("SpeechRecognizer", DependencyManager::get().data()); #endif - rootContext->setContextProperty("Overlays", &_overlays); - rootContext->setContextProperty("Window", DependencyManager::get().data()); - rootContext->setContextProperty("MenuInterface", MenuScriptingInterface::getInstance()); - rootContext->setContextProperty("Stats", Stats::getInstance()); - rootContext->setContextProperty("Settings", SettingsScriptingInterface::getInstance()); - rootContext->setContextProperty("ScriptDiscoveryService", DependencyManager::get().data()); - rootContext->setContextProperty("AudioDevice", AudioDeviceScriptingInterface::getInstance()); - rootContext->setContextProperty("AvatarBookmarks", DependencyManager::get().data()); - rootContext->setContextProperty("LocationBookmarks", DependencyManager::get().data()); + surfaceContext->setContextProperty("Overlays", &_overlays); + surfaceContext->setContextProperty("Window", DependencyManager::get().data()); + surfaceContext->setContextProperty("MenuInterface", MenuScriptingInterface::getInstance()); + surfaceContext->setContextProperty("Stats", Stats::getInstance()); + surfaceContext->setContextProperty("Settings", SettingsScriptingInterface::getInstance()); + surfaceContext->setContextProperty("ScriptDiscoveryService", DependencyManager::get().data()); + surfaceContext->setContextProperty("AudioDevice", AudioDeviceScriptingInterface::getInstance()); + surfaceContext->setContextProperty("AvatarBookmarks", DependencyManager::get().data()); + surfaceContext->setContextProperty("LocationBookmarks", DependencyManager::get().data()); // Caches - rootContext->setContextProperty("AnimationCache", DependencyManager::get().data()); - rootContext->setContextProperty("TextureCache", DependencyManager::get().data()); - rootContext->setContextProperty("ModelCache", DependencyManager::get().data()); - rootContext->setContextProperty("SoundCache", DependencyManager::get().data()); + surfaceContext->setContextProperty("AnimationCache", DependencyManager::get().data()); + surfaceContext->setContextProperty("TextureCache", DependencyManager::get().data()); + surfaceContext->setContextProperty("ModelCache", DependencyManager::get().data()); + surfaceContext->setContextProperty("SoundCache", DependencyManager::get().data()); - rootContext->setContextProperty("Account", AccountScriptingInterface::getInstance()); - rootContext->setContextProperty("Tablet", DependencyManager::get().data()); - rootContext->setContextProperty("DialogsManager", _dialogsManagerScriptingInterface); - rootContext->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance()); - rootContext->setContextProperty("FaceTracker", DependencyManager::get().data()); - rootContext->setContextProperty("AvatarManager", DependencyManager::get().data()); - rootContext->setContextProperty("UndoStack", &_undoStackScriptingInterface); - rootContext->setContextProperty("LODManager", DependencyManager::get().data()); - rootContext->setContextProperty("Paths", DependencyManager::get().data()); - rootContext->setContextProperty("HMD", DependencyManager::get().data()); - rootContext->setContextProperty("Scene", DependencyManager::get().data()); - rootContext->setContextProperty("Render", _renderEngine->getConfiguration().get()); - rootContext->setContextProperty("Reticle", getApplicationCompositor().getReticleInterface()); - rootContext->setContextProperty("Snapshot", DependencyManager::get().data()); + surfaceContext->setContextProperty("Account", AccountScriptingInterface::getInstance()); + surfaceContext->setContextProperty("Tablet", DependencyManager::get().data()); + surfaceContext->setContextProperty("DialogsManager", _dialogsManagerScriptingInterface); + surfaceContext->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance()); + surfaceContext->setContextProperty("FaceTracker", DependencyManager::get().data()); + surfaceContext->setContextProperty("AvatarManager", DependencyManager::get().data()); + surfaceContext->setContextProperty("UndoStack", &_undoStackScriptingInterface); + surfaceContext->setContextProperty("LODManager", DependencyManager::get().data()); + surfaceContext->setContextProperty("Paths", DependencyManager::get().data()); + surfaceContext->setContextProperty("HMD", DependencyManager::get().data()); + surfaceContext->setContextProperty("Scene", DependencyManager::get().data()); + surfaceContext->setContextProperty("Render", _renderEngine->getConfiguration().get()); + surfaceContext->setContextProperty("Reticle", getApplicationCompositor().getReticleInterface()); + surfaceContext->setContextProperty("Snapshot", DependencyManager::get().data()); - rootContext->setContextProperty("ApplicationCompositor", &getApplicationCompositor()); + surfaceContext->setContextProperty("ApplicationCompositor", &getApplicationCompositor()); - rootContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); + surfaceContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { - rootContext->setContextProperty("Steam", new SteamScriptingInterface(engine, steamClient.get())); + surfaceContext->setContextProperty("Steam", new SteamScriptingInterface(engine, steamClient.get())); } diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 75c793bf77..e26a641206 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -135,7 +135,7 @@ Web3DOverlay::~Web3DOverlay() { void Web3DOverlay::update(float deltatime) { if (_webSurface) { // update globalPosition - _webSurface->getRootContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); + _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); } } @@ -163,57 +163,56 @@ void Web3DOverlay::loadSourceURL() { _webSurface->resume(); _webSurface->getRootItem()->setProperty("url", _url); _webSurface->getRootItem()->setProperty("scriptURL", _scriptURL); - _webSurface->getRootContext()->setContextProperty("ApplicationInterface", qApp); } else { _webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath())); _webSurface->load(_url, [&](QQmlContext* context, QObject* obj) {}); _webSurface->resume(); - _webSurface->getRootContext()->setContextProperty("Users", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("HMD", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("UserActivityLogger", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("Preferences", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("Vec3", new Vec3()); - _webSurface->getRootContext()->setContextProperty("Quat", new Quat()); - _webSurface->getRootContext()->setContextProperty("MyAvatar", DependencyManager::get()->getMyAvatar().get()); - _webSurface->getRootContext()->setContextProperty("Entities", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("Snapshot", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Users", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("HMD", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("UserActivityLogger", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Preferences", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Vec3", new Vec3()); + _webSurface->getSurfaceContext()->setContextProperty("Quat", new Quat()); + _webSurface->getSurfaceContext()->setContextProperty("MyAvatar", DependencyManager::get()->getMyAvatar().get()); + _webSurface->getSurfaceContext()->setContextProperty("Entities", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Snapshot", DependencyManager::get().data()); if (_webSurface->getRootItem() && _webSurface->getRootItem()->objectName() == "tabletRoot") { auto tabletScriptingInterface = DependencyManager::get(); auto flags = tabletScriptingInterface->getFlags(); - _webSurface->getRootContext()->setContextProperty("offscreenFlags", flags); - _webSurface->getRootContext()->setContextProperty("AddressManager", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("Account", AccountScriptingInterface::getInstance()); - _webSurface->getRootContext()->setContextProperty("AudioStats", DependencyManager::get()->getStats().data()); - _webSurface->getRootContext()->setContextProperty("HMD", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("fileDialogHelper", new FileDialogHelper()); - _webSurface->getRootContext()->setContextProperty("MyAvatar", DependencyManager::get()->getMyAvatar().get()); - _webSurface->getRootContext()->setContextProperty("ScriptDiscoveryService", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("Tablet", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("Assets", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("LODManager", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("OctreeStats", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("DCModel", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("AudioDevice", AudioDeviceScriptingInterface::getInstance()); - _webSurface->getRootContext()->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); - _webSurface->getRootContext()->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance()); - _webSurface->getRootContext()->setContextProperty("AvatarList", DependencyManager::get().data()); - _webSurface->getRootContext()->setContextProperty("DialogsManager", DialogsManagerScriptingInterface::getInstance()); + _webSurface->getSurfaceContext()->setContextProperty("offscreenFlags", flags); + _webSurface->getSurfaceContext()->setContextProperty("AddressManager", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Account", AccountScriptingInterface::getInstance()); + _webSurface->getSurfaceContext()->setContextProperty("AudioStats", DependencyManager::get()->getStats().data()); + _webSurface->getSurfaceContext()->setContextProperty("HMD", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("fileDialogHelper", new FileDialogHelper()); + _webSurface->getSurfaceContext()->setContextProperty("MyAvatar", DependencyManager::get()->getMyAvatar().get()); + _webSurface->getSurfaceContext()->setContextProperty("ScriptDiscoveryService", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Tablet", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("Assets", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("LODManager", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("OctreeStats", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("DCModel", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("AudioDevice", AudioDeviceScriptingInterface::getInstance()); + _webSurface->getSurfaceContext()->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); + _webSurface->getSurfaceContext()->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance()); + _webSurface->getSurfaceContext()->setContextProperty("AvatarList", DependencyManager::get().data()); + _webSurface->getSurfaceContext()->setContextProperty("DialogsManager", DialogsManagerScriptingInterface::getInstance()); - _webSurface->getRootContext()->setContextProperty("pathToFonts", "../../"); + _webSurface->getSurfaceContext()->setContextProperty("pathToFonts", "../../"); tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface->getRootItem(), _webSurface.data()); // mark the TabletProxy object as cpp ownership. QObject* tablet = tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"); - _webSurface->getRootContext()->engine()->setObjectOwnership(tablet, QQmlEngine::CppOwnership); + _webSurface->getSurfaceContext()->engine()->setObjectOwnership(tablet, QQmlEngine::CppOwnership); // Override min fps for tablet UI, for silky smooth scrolling setMaxFPS(90); } } - _webSurface->getRootContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); + _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); } void Web3DOverlay::setMaxFPS(uint8_t maxFPS) { diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 0d286c46eb..3b3480443d 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -127,7 +127,7 @@ bool RenderableWebEntityItem::buildWebSurface(QSharedPointer _webSurface->resume(); _webSurface->getRootItem()->setProperty("url", _sourceUrl); - _webSurface->getRootContext()->setContextProperty("desktop", QVariant()); + _webSurface->getSurfaceContext()->setContextProperty("desktop", QVariant()); // FIXME - Keyboard HMD only: Possibly add "HMDinfo" object to context for WebView.qml. // forward web events to EntityScriptingInterface @@ -271,7 +271,7 @@ void RenderableWebEntityItem::loadSourceURL() { }); _webSurface->getRootItem()->setProperty("url", _sourceUrl); - _webSurface->getRootContext()->setContextProperty("desktop", QVariant()); + _webSurface->getSurfaceContext()->setContextProperty("desktop", QVariant()); } else { _contentType = qmlContent; @@ -284,7 +284,7 @@ void RenderableWebEntityItem::loadSourceURL() { _webSurface->getRootItem(), _webSurface.data()); } } - _webSurface->getRootContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); + _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); } @@ -420,7 +420,7 @@ void RenderableWebEntityItem::update(const quint64& now) { if (_webSurface) { // update globalPosition - _webSurface->getRootContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); + _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); } auto interval = now - _lastRenderTime; diff --git a/libraries/gl/CMakeLists.txt b/libraries/gl/CMakeLists.txt index 3e2097e89e..fd3197410b 100644 --- a/libraries/gl/CMakeLists.txt +++ b/libraries/gl/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME gl) setup_hifi_library(OpenGL Qml Quick) -link_hifi_libraries(shared) +link_hifi_libraries(shared networking) target_opengl() diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.cpp b/libraries/gl/src/gl/OffscreenQmlSurface.cpp index 3bbd26e010..65c311424f 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.cpp +++ b/libraries/gl/src/gl/OffscreenQmlSurface.cpp @@ -33,6 +33,9 @@ #include #include #include +#include +#include +#include #include "OffscreenGLCanvas.h" #include "GLHelpers.h" @@ -41,6 +44,7 @@ Q_LOGGING_CATEGORY(trace_render_qml, "trace.render.qml") Q_LOGGING_CATEGORY(trace_render_qml_gl, "trace.render.qml.gl") +Q_LOGGING_CATEGORY(offscreenFocus, "hifi.offscreen.focus") struct TextureSet { // The number of surfaces with this size @@ -254,8 +258,72 @@ QNetworkAccessManager* QmlNetworkAccessManagerFactory::create(QObject* parent) { return new QmlNetworkAccessManager(parent); } -Q_DECLARE_LOGGING_CATEGORY(offscreenFocus) -Q_LOGGING_CATEGORY(offscreenFocus, "hifi.offscreen.focus") +static QQmlEngine* globalEngine { nullptr }; +static size_t globalEngineRefCount { 0 }; + +QString getEventBridgeJavascript() { + // FIXME: Refactor with similar code in RenderableWebEntityItem + QString javaScriptToInject; + QFile webChannelFile(":qtwebchannel/qwebchannel.js"); + QFile createGlobalEventBridgeFile(PathUtils::resourcesPath() + "/html/createGlobalEventBridge.js"); + if (webChannelFile.open(QFile::ReadOnly | QFile::Text) && + createGlobalEventBridgeFile.open(QFile::ReadOnly | QFile::Text)) { + QString webChannelStr = QTextStream(&webChannelFile).readAll(); + QString createGlobalEventBridgeStr = QTextStream(&createGlobalEventBridgeFile).readAll(); + javaScriptToInject = webChannelStr + createGlobalEventBridgeStr; + } else { + qCWarning(glLogging) << "Unable to find qwebchannel.js or createGlobalEventBridge.js"; + } + return javaScriptToInject; +} + + +QQmlEngine* acquireEngine(QQuickWindow* window) { + Q_ASSERT(QThread::currentThread() == qApp->thread()); + if (!globalEngine) { + Q_ASSERT(0 == globalEngineRefCount); + globalEngine = new QQmlEngine(); + globalEngine->setNetworkAccessManagerFactory(new QmlNetworkAccessManagerFactory); + + auto importList = globalEngine->importPathList(); + importList.insert(importList.begin(), PathUtils::resourcesPath()); + globalEngine->setImportPathList(importList); + for (const auto& path : importList) { + qDebug() << path; + } + + if (!globalEngine->incubationController()) { + globalEngine->setIncubationController(window->incubationController()); + } + auto rootContext = globalEngine->rootContext(); + rootContext->setContextProperty("GL", ::getGLContextData()); + rootContext->setContextProperty("urlHandler", new UrlHandler()); + rootContext->setContextProperty("resourceDirectoryUrl", QUrl::fromLocalFile(PathUtils::resourcesPath())); + rootContext->setContextProperty("pathToFonts", "../../"); + rootContext->setContextProperty("ApplicationInterface", qApp); + auto javaScriptToInject = getEventBridgeJavascript(); + if (!javaScriptToInject.isEmpty()) { + rootContext->setContextProperty("eventBridgeJavaScriptToInject", QVariant(javaScriptToInject)); + } + rootContext->setContextProperty("FileTypeProfile", new FileTypeProfile(rootContext)); + rootContext->setContextProperty("HFWebEngineProfile", new HFWebEngineProfile(rootContext)); + rootContext->setContextProperty("HFTabletWebEngineProfile", new HFTabletWebEngineProfile(rootContext)); + + + } + + ++globalEngineRefCount; + return globalEngine; +} + +void releaseEngine() { + Q_ASSERT(QThread::currentThread() == qApp->thread()); + Q_ASSERT(0 != globalEngineRefCount); + if (0 == --globalEngineRefCount) { + globalEngine->deleteLater(); + globalEngine = nullptr; + } +} void OffscreenQmlSurface::cleanup() { _canvas->makeCurrent(); @@ -294,6 +362,7 @@ void OffscreenQmlSurface::render() { GLuint texture = offscreenTextures.getNextTexture(_size); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo); glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _renderControl->render(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, texture); @@ -362,8 +431,8 @@ OffscreenQmlSurface::~OffscreenQmlSurface() { _canvas->deleteLater(); _rootItem->deleteLater(); _qmlComponent->deleteLater(); - _qmlEngine->deleteLater(); _quickWindow->deleteLater(); + releaseEngine(); } void OffscreenQmlSurface::onAboutToQuit() { @@ -375,6 +444,8 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) { qCDebug(glLogging) << "Building QML surface"; _renderControl = new QMyQuickRenderControl(); + connect(_renderControl, &QQuickRenderControl::renderRequested, this, [this] { _render = true; }); + connect(_renderControl, &QQuickRenderControl::sceneChanged, this, [this] { _render = _polish = true; }); QQuickWindow::setDefaultAlphaBuffer(true); @@ -385,7 +456,7 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) { // so we wait until after its ctor to move object/context to this thread. _quickWindow = new QQuickWindow(_renderControl); _quickWindow->setColor(QColor(255, 255, 255, 0)); - _quickWindow->setFlags(_quickWindow->flags() | static_cast(Qt::WA_TranslucentBackground)); + _quickWindow->setClearBeforeRendering(false); _renderControl->_renderWindow = _proxyWindow; @@ -398,32 +469,20 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) { connect(_quickWindow, &QQuickWindow::focusObjectChanged, this, &OffscreenQmlSurface::onFocusObjectChanged); // Create a QML engine. - _qmlEngine = new QQmlEngine; + auto qmlEngine = acquireEngine(_quickWindow); + _qmlContext = new QQmlContext(qmlEngine->rootContext()); - _qmlEngine->setNetworkAccessManagerFactory(new QmlNetworkAccessManagerFactory); + _qmlContext->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow())); + _qmlContext->setContextProperty("globalEventBridge", this); + _qmlContext->setContextProperty("webEntity", this); - auto importList = _qmlEngine->importPathList(); - importList.insert(importList.begin(), PathUtils::resourcesPath()); - _qmlEngine->setImportPathList(importList); - if (!_qmlEngine->incubationController()) { - _qmlEngine->setIncubationController(_quickWindow->incubationController()); - } + _qmlComponent = new QQmlComponent(qmlEngine); - // FIXME - _glData = ::getGLContextData(); // Initialize JSON structure so that it can be filled in later and then used in QML. - _qmlEngine->rootContext()->setContextProperty("GL", _glData); - _qmlEngine->rootContext()->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow())); - _qmlComponent = new QQmlComponent(_qmlEngine); - - - connect(_renderControl, &QQuickRenderControl::renderRequested, this, [this] { _render = true; }); - connect(_renderControl, &QQuickRenderControl::sceneChanged, this, [this] { _render = _polish = true; }); if (!_canvas->makeCurrent()) { qWarning("Failed to make context current for QML Renderer"); return; } - _glData = ::getGLContextData(); _renderControl->initialize(_canvas->getContext()); // When Quick says there is a need to render, we will not render immediately. Instead, @@ -433,11 +492,6 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) { _updateTimer.setTimerType(Qt::PreciseTimer); _updateTimer.setInterval(MIN_TIMER_MS); // 5ms, Qt::PreciseTimer required _updateTimer.start(); - - auto rootContext = getRootContext(); - rootContext->setContextProperty("urlHandler", new UrlHandler()); - rootContext->setContextProperty("resourceDirectoryUrl", QUrl::fromLocalFile(PathUtils::resourcesPath())); - rootContext->setContextProperty("pathToFonts", "../../"); } static uvec2 clampSize(const uvec2& size, uint32_t maxDimension) { @@ -460,7 +514,7 @@ void OffscreenQmlSurface::resize(const QSize& newSize_, bool forceResize) { return; } - _qmlEngine->rootContext()->setContextProperty("surfaceSize", newSize); + _qmlContext->setContextProperty("surfaceSize", newSize); if (_rootItem) { _rootItem->setSize(newSize); @@ -520,14 +574,19 @@ QQuickItem* OffscreenQmlSurface::getRootItem() { } void OffscreenQmlSurface::setBaseUrl(const QUrl& baseUrl) { - _qmlEngine->setBaseUrl(baseUrl); + _qmlContext->setBaseUrl(baseUrl); } QObject* OffscreenQmlSurface::load(const QUrl& qmlSource, std::function f) { // Synchronous loading may take a while; restart the deadlock timer QMetaObject::invokeMethod(qApp, "updateHeartbeat", Qt::DirectConnection); - _qmlComponent->loadUrl(qmlSource, QQmlComponent::PreferSynchronous); + if ((qmlSource.isRelative() && !qmlSource.isEmpty()) || qmlSource.scheme() == QLatin1String("file")) { + _qmlComponent->loadUrl(_qmlContext->resolvedUrl(qmlSource), QQmlComponent::PreferSynchronous); + } else { + _qmlComponent->loadUrl(qmlSource, QQmlComponent::PreferSynchronous); + } + if (_qmlComponent->isLoading()) { connect(_qmlComponent, &QQmlComponent::statusChanged, this, @@ -541,10 +600,22 @@ QObject* OffscreenQmlSurface::load(const QUrl& qmlSource, std::functionengine()->clearComponentCache(); + _qmlContext->engine()->clearComponentCache(); } QObject* OffscreenQmlSurface::finishQmlLoad(std::function f) { +#if 0 + if (!_rootItem) { + QQmlComponent component(_qmlContext->engine()); + component.setData(R"QML( +import QtQuick 2.0 +import QtWebChannel 1.0 +Item { Component.onCompleted: globalEventBridge.WebChannel.id = "globalEventBridge"; } +)QML", QUrl()); + QObject *helper = component.create(_qmlContext); + qDebug() << "Created helper"; + } +#endif disconnect(_qmlComponent, &QQmlComponent::statusChanged, this, 0); if (_qmlComponent->isError()) { QList errorList = _qmlComponent->errors(); @@ -554,21 +625,8 @@ QObject* OffscreenQmlSurface::finishQmlLoad(std::functionbeginCreate(newContext); + QObject* newObject = _qmlComponent->beginCreate(_qmlContext); if (_qmlComponent->isError()) { QList errorList = _qmlComponent->errors(); foreach(const QQmlError& error, errorList) @@ -579,12 +637,10 @@ QObject* OffscreenQmlSurface::finishQmlLoad(std::functionsetObjectOwnership(this, QQmlEngine::CppOwnership); + _qmlContext->engine()->setObjectOwnership(this, QQmlEngine::CppOwnership); newObject->setProperty("eventBridge", QVariant::fromValue(this)); - newContext->setContextProperty("eventBridgeJavaScriptToInject", QVariant(javaScriptToInject)); - - f(newContext, newObject); + f(_qmlContext, newObject); _qmlComponent->completeCreate(); @@ -735,7 +791,7 @@ bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* even mouseEvent->screenPos(), mouseEvent->button(), mouseEvent->buttons(), mouseEvent->modifiers()); if (event->type() == QEvent::MouseMove) { - _qmlEngine->rootContext()->setContextProperty("lastMousePosition", transformedPos); + _qmlContext->setContextProperty("lastMousePosition", transformedPos); } mappedEvent.ignore(); if (QCoreApplication::sendEvent(_quickWindow, &mappedEvent)) { @@ -762,9 +818,6 @@ void OffscreenQmlSurface::resume() { if (getRootItem()) { getRootItem()->setProperty("eventBridge", QVariant::fromValue(this)); } - if (getRootContext()) { - getRootContext()->setContextProperty("webEntity", this); - } } bool OffscreenQmlSurface::isPaused() const { @@ -790,8 +843,8 @@ QSize OffscreenQmlSurface::size() const { return _quickWindow->geometry().size(); } -QQmlContext* OffscreenQmlSurface::getRootContext() { - return _qmlEngine->rootContext(); +QQmlContext* OffscreenQmlSurface::getSurfaceContext() { + return _qmlContext; } Q_DECLARE_METATYPE(std::function); diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.h b/libraries/gl/src/gl/OffscreenQmlSurface.h index efd35fce8b..2a078d2b4f 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.h +++ b/libraries/gl/src/gl/OffscreenQmlSurface.h @@ -73,7 +73,7 @@ public: QQuickItem* getRootItem(); QQuickWindow* getWindow(); QObject* getEventHandler(); - QQmlContext* getRootContext(); + QQmlContext* getSurfaceContext(); QPointF mapToVirtualScreen(const QPointF& originalPoint, QObject* originalWidget); bool eventFilter(QObject* originalDestination, QEvent* event) override; @@ -133,11 +133,10 @@ private slots: private: QQuickWindow* _quickWindow { nullptr }; QMyQuickRenderControl* _renderControl{ nullptr }; - QQmlEngine* _qmlEngine { nullptr }; + QQmlContext* _qmlContext { nullptr }; QQmlComponent* _qmlComponent { nullptr }; QQuickItem* _rootItem { nullptr }; OffscreenGLCanvas* _canvas { nullptr }; - QJsonObject _glData; QTimer _updateTimer; uint32_t _fbo { 0 }; diff --git a/libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp b/libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp index ad370a1f43..c047738e77 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp +++ b/libraries/gl/src/gl/OffscreenQmlSurfaceCache.cpp @@ -49,7 +49,6 @@ QSharedPointer OffscreenQmlSurfaceCache::buildSurface(const surface->create(currentContext); surface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); surface->load(rootSource); - surface->getRootContext()->setContextProperty("ApplicationInterface", qApp); surface->resize(QSize(100, 100)); currentContext->makeCurrent(currentSurface); return surface; diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index 288e98d5a5..ff9a05b959 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -1,5 +1,5 @@ set(TARGET_NAME networking) -setup_hifi_library(Network) +setup_hifi_library(Network WebEngine) link_hifi_libraries(shared) target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/includes") diff --git a/interface/src/networking/FileTypeProfile.cpp b/libraries/networking/src/FileTypeProfile.cpp similarity index 100% rename from interface/src/networking/FileTypeProfile.cpp rename to libraries/networking/src/FileTypeProfile.cpp diff --git a/interface/src/networking/FileTypeProfile.h b/libraries/networking/src/FileTypeProfile.h similarity index 100% rename from interface/src/networking/FileTypeProfile.h rename to libraries/networking/src/FileTypeProfile.h diff --git a/interface/src/networking/FileTypeRequestInterceptor.cpp b/libraries/networking/src/FileTypeRequestInterceptor.cpp similarity index 100% rename from interface/src/networking/FileTypeRequestInterceptor.cpp rename to libraries/networking/src/FileTypeRequestInterceptor.cpp diff --git a/interface/src/networking/FileTypeRequestInterceptor.h b/libraries/networking/src/FileTypeRequestInterceptor.h similarity index 100% rename from interface/src/networking/FileTypeRequestInterceptor.h rename to libraries/networking/src/FileTypeRequestInterceptor.h diff --git a/interface/src/networking/HFTabletWebEngineProfile.cpp b/libraries/networking/src/HFTabletWebEngineProfile.cpp similarity index 95% rename from interface/src/networking/HFTabletWebEngineProfile.cpp rename to libraries/networking/src/HFTabletWebEngineProfile.cpp index 46634299bb..a3e3906497 100644 --- a/interface/src/networking/HFTabletWebEngineProfile.cpp +++ b/libraries/networking/src/HFTabletWebEngineProfile.cpp @@ -19,6 +19,7 @@ HFTabletWebEngineProfile::HFTabletWebEngineProfile(QObject* parent) : QQuickWebE static const QString WEB_ENGINE_USER_AGENT = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36"; setHttpUserAgent(WEB_ENGINE_USER_AGENT); + setStorageName(QML_WEB_ENGINE_NAME); auto requestInterceptor = new HFTabletWebEngineRequestInterceptor(this); setRequestInterceptor(requestInterceptor); diff --git a/interface/src/networking/HFTabletWebEngineProfile.h b/libraries/networking/src/HFTabletWebEngineProfile.h similarity index 100% rename from interface/src/networking/HFTabletWebEngineProfile.h rename to libraries/networking/src/HFTabletWebEngineProfile.h diff --git a/interface/src/networking/HFTabletWebEngineRequestInterceptor.cpp b/libraries/networking/src/HFTabletWebEngineRequestInterceptor.cpp similarity index 98% rename from interface/src/networking/HFTabletWebEngineRequestInterceptor.cpp rename to libraries/networking/src/HFTabletWebEngineRequestInterceptor.cpp index fd79fc1cb6..6ee8589615 100644 --- a/interface/src/networking/HFTabletWebEngineRequestInterceptor.cpp +++ b/libraries/networking/src/HFTabletWebEngineRequestInterceptor.cpp @@ -11,7 +11,7 @@ #include "HFTabletWebEngineRequestInterceptor.h" #include -#include +#include "AccountManager.h" bool isTabletAuthableHighFidelityURL(const QUrl& url) { static const QStringList HF_HOSTS = { diff --git a/interface/src/networking/HFTabletWebEngineRequestInterceptor.h b/libraries/networking/src/HFTabletWebEngineRequestInterceptor.h similarity index 100% rename from interface/src/networking/HFTabletWebEngineRequestInterceptor.h rename to libraries/networking/src/HFTabletWebEngineRequestInterceptor.h diff --git a/interface/src/networking/HFWebEngineProfile.cpp b/libraries/networking/src/HFWebEngineProfile.cpp similarity index 94% rename from interface/src/networking/HFWebEngineProfile.cpp rename to libraries/networking/src/HFWebEngineProfile.cpp index 6b377fa900..a69d4d653b 100644 --- a/interface/src/networking/HFWebEngineProfile.cpp +++ b/libraries/networking/src/HFWebEngineProfile.cpp @@ -20,6 +20,7 @@ HFWebEngineProfile::HFWebEngineProfile(QObject* parent) : { static const QString WEB_ENGINE_USER_AGENT = "Chrome/48.0 (HighFidelityInterface)"; setHttpUserAgent(WEB_ENGINE_USER_AGENT); + setStorageName(QML_WEB_ENGINE_STORAGE_NAME); // we use the HFWebEngineRequestInterceptor to make sure that web requests are authenticated for the interface user auto requestInterceptor = new HFWebEngineRequestInterceptor(this); diff --git a/interface/src/networking/HFWebEngineProfile.h b/libraries/networking/src/HFWebEngineProfile.h similarity index 100% rename from interface/src/networking/HFWebEngineProfile.h rename to libraries/networking/src/HFWebEngineProfile.h diff --git a/interface/src/networking/HFWebEngineRequestInterceptor.cpp b/libraries/networking/src/HFWebEngineRequestInterceptor.cpp similarity index 95% rename from interface/src/networking/HFWebEngineRequestInterceptor.cpp rename to libraries/networking/src/HFWebEngineRequestInterceptor.cpp index 59897d427f..eaf0de7245 100644 --- a/interface/src/networking/HFWebEngineRequestInterceptor.cpp +++ b/libraries/networking/src/HFWebEngineRequestInterceptor.cpp @@ -13,7 +13,7 @@ #include -#include +#include "AccountManager.h" #include "RequestFilters.h" void HFWebEngineRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo& info) { diff --git a/interface/src/networking/HFWebEngineRequestInterceptor.h b/libraries/networking/src/HFWebEngineRequestInterceptor.h similarity index 100% rename from interface/src/networking/HFWebEngineRequestInterceptor.h rename to libraries/networking/src/HFWebEngineRequestInterceptor.h diff --git a/interface/src/networking/RequestFilters.cpp b/libraries/networking/src/RequestFilters.cpp similarity index 98% rename from interface/src/networking/RequestFilters.cpp rename to libraries/networking/src/RequestFilters.cpp index fedde94f15..3e72b8a8bd 100644 --- a/interface/src/networking/RequestFilters.cpp +++ b/libraries/networking/src/RequestFilters.cpp @@ -14,7 +14,7 @@ #include -#include +#include "AccountManager.h" namespace { diff --git a/interface/src/networking/RequestFilters.h b/libraries/networking/src/RequestFilters.h similarity index 100% rename from interface/src/networking/RequestFilters.h rename to libraries/networking/src/RequestFilters.h diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 84812b4f60..a80105293b 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -91,14 +91,14 @@ QObject* OffscreenUi::getFlags() { void OffscreenUi::create(QOpenGLContext* context) { OffscreenQmlSurface::create(context); - auto rootContext = getRootContext(); + auto myContext = getSurfaceContext(); - rootContext->setContextProperty("OffscreenUi", this); - rootContext->setContextProperty("offscreenFlags", offscreenFlags = new OffscreenFlags()); - rootContext->setContextProperty("fileDialogHelper", new FileDialogHelper()); + myContext->setContextProperty("OffscreenUi", this); + myContext->setContextProperty("offscreenFlags", offscreenFlags = new OffscreenFlags()); + myContext->setContextProperty("fileDialogHelper", new FileDialogHelper()); auto tabletScriptingInterface = DependencyManager::get(); TabletProxy* tablet = tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"); - rootContext->engine()->setObjectOwnership(tablet, QQmlEngine::CppOwnership); + myContext->engine()->setObjectOwnership(tablet, QQmlEngine::CppOwnership); } void OffscreenUi::show(const QUrl& url, const QString& name, std::function f) { @@ -547,14 +547,14 @@ void OffscreenUi::createDesktop(const QUrl& url) { } #ifdef DEBUG - getRootContext()->setContextProperty("DebugQML", QVariant(true)); + getSurfaceContext()->setContextProperty("DebugQML", QVariant(true)); #else - getRootContext()->setContextProperty("DebugQML", QVariant(false)); + getSurfaceContext()->setContextProperty("DebugQML", QVariant(false)); #endif _desktop = dynamic_cast(load(url)); Q_ASSERT(_desktop); - getRootContext()->setContextProperty("desktop", _desktop); + getSurfaceContext()->setContextProperty("desktop", _desktop); _toolWindow = _desktop->findChild("ToolWindow"); diff --git a/libraries/ui/src/VrMenu.cpp b/libraries/ui/src/VrMenu.cpp index 878514dd41..3959e950e9 100644 --- a/libraries/ui/src/VrMenu.cpp +++ b/libraries/ui/src/VrMenu.cpp @@ -115,7 +115,7 @@ private: VrMenu::VrMenu(OffscreenUi* parent) : QObject(parent) { _rootMenu = parent->getRootItem()->findChild("rootMenu"); - parent->getRootContext()->setContextProperty("rootMenu", _rootMenu); + parent->getSurfaceContext()->setContextProperty("rootMenu", _rootMenu); } QObject* VrMenu::findMenuObject(const QString& menuOption) { From 9fcc1e15b8bcbd65c8fd80f42e9c65f1f25332c1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 5 Jun 2017 15:52:47 -0700 Subject: [PATCH 84/91] remove some cruft --- .../avatars-renderer/src/avatars-renderer/Head.cpp | 12 ------------ .../avatars-renderer/src/avatars-renderer/Head.h | 3 --- libraries/avatars/src/HeadData.h | 3 --- 3 files changed, 18 deletions(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Head.cpp b/libraries/avatars-renderer/src/avatars-renderer/Head.cpp index 96ecd86ff4..b8a559027b 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Head.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Head.cpp @@ -304,18 +304,6 @@ glm::quat Head::getEyeRotation(const glm::vec3& eyePosition) const { return rotationBetween(orientation * IDENTITY_FORWARD, lookAtDelta + glm::length(lookAtDelta) * _saccade) * orientation; } -void Head::setFinalPitch(float finalPitch) { - _deltaPitch = glm::clamp(finalPitch, MIN_HEAD_PITCH, MAX_HEAD_PITCH) - _basePitch; -} - -void Head::setFinalYaw(float finalYaw) { - _deltaYaw = glm::clamp(finalYaw, MIN_HEAD_YAW, MAX_HEAD_YAW) - _baseYaw; -} - -void Head::setFinalRoll(float finalRoll) { - _deltaRoll = glm::clamp(finalRoll, MIN_HEAD_ROLL, MAX_HEAD_ROLL) - _baseRoll; -} - float Head::getFinalYaw() const { return glm::clamp(_baseYaw + _deltaYaw, MIN_HEAD_YAW, MAX_HEAD_YAW); } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Head.h b/libraries/avatars-renderer/src/avatars-renderer/Head.h index c5902285b9..e3c8d7d2b5 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Head.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Head.h @@ -71,9 +71,6 @@ public: void setDeltaRoll(float roll) { _deltaRoll = roll; } float getDeltaRoll() const { return _deltaRoll; } - virtual void setFinalYaw(float finalYaw) override; - virtual void setFinalPitch(float finalPitch) override; - virtual void setFinalRoll(float finalRoll) override; virtual float getFinalPitch() const override; virtual float getFinalYaw() const override; virtual float getFinalRoll() const override; diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index 0bb38c1dad..c15714bd73 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -45,9 +45,6 @@ public: float getBaseRoll() const { return _baseRoll; } void setBaseRoll(float roll) { _baseRoll = glm::clamp(roll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); } - virtual void setFinalYaw(float finalYaw) { _baseYaw = finalYaw; } - virtual void setFinalPitch(float finalPitch) { _basePitch = finalPitch; } - virtual void setFinalRoll(float finalRoll) { _baseRoll = finalRoll; } virtual float getFinalYaw() const { return _baseYaw; } virtual float getFinalPitch() const { return _basePitch; } virtual float getFinalRoll() const { return _baseRoll; } From 7a276f027fb7e2c957b8b3caf188cb5275606eb3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 5 Jun 2017 15:53:01 -0700 Subject: [PATCH 85/91] fix orientation used for 3d audio --- interface/src/avatar/MyAvatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 64914a7ec1..158e55ab5c 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1893,7 +1893,7 @@ void MyAvatar::updateOrientation(float deltaTime) { auto headPose = getHeadControllerPoseInAvatarFrame(); if (headPose.isValid()) { - glm::quat localOrientation = headPose.rotation; + glm::quat localOrientation = headPose.rotation * Quaternions::Y_180; // these angles will be in radians // ... so they need to be converted to degrees before we do math... glm::vec3 euler = glm::eulerAngles(localOrientation) * DEGREES_PER_RADIAN; From 90d241ca3c643ff5d0adec8afc5dbd4de83200b6 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 6 Jun 2017 09:10:46 -0700 Subject: [PATCH 86/91] Account for avatar scale --- scripts/system/controllers/teleport.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/controllers/teleport.js b/scripts/system/controllers/teleport.js index d6248fc6e0..b058ec670f 100644 --- a/scripts/system/controllers/teleport.js +++ b/scripts/system/controllers/teleport.js @@ -383,7 +383,7 @@ function getAvatarFootOffset() { // default vertical offset from foot to avatar root. return -MyAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(footJointIndex).y; } else { - return DEFAULT_ROOT_TO_FOOT_OFFSET; + return DEFAULT_ROOT_TO_FOOT_OFFSET * MyAvatar.scale; } } From ad1ee973243fe55389044226a51dac32f9ac071f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 6 Jun 2017 09:50:40 -0700 Subject: [PATCH 87/91] remove cruft --- plugins/oculus/src/OculusControllerManager.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index dee9f1082e..6f7be26554 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -222,12 +222,6 @@ bool OculusControllerManager::isHeadControllerMounted() const { void OculusControllerManager::TouchDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { _buttonPressedMap.clear(); - // _poseStateMap.erase(controller::HEAD); - - // if (!_parent.isHeadControllerMounted()) { - // // if the HMD isn't on someone's head, don't take input from the controllers - // return; - // } int numTrackedControllers = 0; quint64 currentTime = usecTimestampNow(); From c3621d7c325c634d2b53e09eec78641b4ed0454f Mon Sep 17 00:00:00 2001 From: NeetBhagat Date: Tue, 6 Jun 2017 22:31:14 +0530 Subject: [PATCH 88/91] Resolved two issues: 1) While in HMD mode -> open Tablet -> Click Desktop. Desktop mode will be on. 2) Menu sync problem while switching modes. --- interface/src/Application.cpp | 13 +++++++------ interface/src/Application.h | 2 +- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 6 +++--- .../src/display-plugins/OpenGLDisplayPlugin.h | 4 ++-- libraries/plugins/src/plugins/Plugin.h | 14 +++++++------- plugins/oculus/src/OculusBaseDisplayPlugin.cpp | 4 +--- plugins/oculus/src/OculusBaseDisplayPlugin.h | 2 +- 7 files changed, 22 insertions(+), 23 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c681f99ee2..314c51a4f2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1360,7 +1360,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo if (_autoSwitchDisplayModeSupportedHMDPlugin) { if (getActiveDisplayPlugin() != _autoSwitchDisplayModeSupportedHMDPlugin && - !_autoSwitchDisplayModeSupportedHMDPlugin->isStandBySessionActive()) { + !_autoSwitchDisplayModeSupportedHMDPlugin->isSessionActive()) { startHMDStandBySession(); } // Poll periodically to check whether the user has worn HMD or not. Switch Display mode accordingly. @@ -1602,8 +1602,8 @@ void Application::aboutToQuit() { getActiveDisplayPlugin()->deactivate(); if (_autoSwitchDisplayModeSupportedHMDPlugin - && _autoSwitchDisplayModeSupportedHMDPlugin->isStandBySessionActive()) { - _autoSwitchDisplayModeSupportedHMDPlugin->endStandBySession(); + && _autoSwitchDisplayModeSupportedHMDPlugin->isSessionActive()) { + _autoSwitchDisplayModeSupportedHMDPlugin->endSession(); } // use the CloseEventSender via a QThread to send an event that says the user asked for the app to close auto closeEventSender = DependencyManager::get(); @@ -6827,13 +6827,14 @@ void Application::switchDisplayMode() { // Switch to respective mode as soon as currentHMDWornStatus changes if (currentHMDWornStatus) { qCDebug(interfaceapp) << "Switching from Desktop to HMD mode"; - endHMDStandBySession(); + endHMDSession(); setActiveDisplayPlugin(_autoSwitchDisplayModeSupportedHMDPluginName); } else { qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; setActiveDisplayPlugin(DESKTOP_DISPLAY_PLUGIN_NAME); startHMDStandBySession(); } + emit activeDisplayPluginChanged(); } _previousHMDWornStatus = currentHMDWornStatus; } @@ -6842,8 +6843,8 @@ void Application::startHMDStandBySession() { _autoSwitchDisplayModeSupportedHMDPlugin->startStandBySession(); } -void Application::endHMDStandBySession() { - _autoSwitchDisplayModeSupportedHMDPlugin->endStandBySession(); +void Application::endHMDSession() { + _autoSwitchDisplayModeSupportedHMDPlugin->endSession(); } mat4 Application::getEyeProjection(int eye) const { diff --git a/interface/src/Application.h b/interface/src/Application.h index 4cd47ada58..46e5e882a4 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -685,6 +685,6 @@ private: QString _autoSwitchDisplayModeSupportedHMDPluginName; bool _previousHMDWornStatus; void startHMDStandBySession(); - void endHMDStandBySession(); + void endHMDSession(); }; #endif // hifi_Application_h diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index fbdc1ad71e..bfd158ffb5 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -346,9 +346,9 @@ bool OpenGLDisplayPlugin::startStandBySession() { return Parent::startStandBySession(); } -void OpenGLDisplayPlugin::endStandBySession() { - deactivateStandBySession(); - Parent::endStandBySession(); +void OpenGLDisplayPlugin::endSession() { + deactivateSession(); + Parent::endSession(); } void OpenGLDisplayPlugin::customizeContext() { diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 9681158c55..10a7558398 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -43,7 +43,7 @@ public: bool activate() override final; void deactivate() override final; bool startStandBySession() override final; - void endStandBySession() override final; + void endSession() override final; bool eventFilter(QObject* receiver, QEvent* event) override; bool isDisplayVisible() const override { return true; } @@ -104,7 +104,7 @@ protected: // Returns true on successful activation of standby session virtual bool activateStandBySession() { return true; } - virtual void deactivateStandBySession() {} + virtual void deactivateSession() {} // Plugin specific functionality to send the composed scene to the output window or device virtual void internalPresent(); diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index 11ea79186a..2d4a24a1fe 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -54,16 +54,16 @@ public: return _active; } virtual bool startStandBySession() { - _standbysessionstatus = true; - return _standbysessionstatus; + _sessionStatus = true; + return _sessionStatus; } - virtual void endStandBySession() { - _standbysessionstatus = false; + virtual void endSession() { + _sessionStatus = false; } - virtual bool isStandBySessionActive() { - return _standbysessionstatus; + virtual bool isSessionActive() { + return _sessionStatus; } /** @@ -85,7 +85,7 @@ signals: protected: bool _active { false }; - bool _standbysessionstatus { false }; + bool _sessionStatus { false }; PluginContainer* _container { nullptr }; static const char* UNKNOWN_PLUGIN_ID; diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index df98abf408..93f4787f0f 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -123,8 +123,6 @@ bool OculusBaseDisplayPlugin::internalActivate() { void OculusBaseDisplayPlugin::internalDeactivate() { Parent::internalDeactivate(); - releaseOculusSession(); - _session = nullptr; } bool OculusBaseDisplayPlugin::activateStandBySession() { @@ -134,7 +132,7 @@ bool OculusBaseDisplayPlugin::activateStandBySession() { } return true; } -void OculusBaseDisplayPlugin::deactivateStandBySession() { +void OculusBaseDisplayPlugin::deactivateSession() { releaseOculusSession(); _session = nullptr; } diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h index bfdcc5db1e..5230b11681 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -35,7 +35,7 @@ protected: bool internalActivate() override; void internalDeactivate() override; bool activateStandBySession() override; - void deactivateStandBySession() override; + void deactivateSession() override; void updatePresentPose() override; protected: From 40823bf5827526f6aae65bd89718c624bf63a724 Mon Sep 17 00:00:00 2001 From: seefo Date: Tue, 6 Jun 2017 10:11:46 -0700 Subject: [PATCH 89/91] Updated Windows build guide's markdown --- BUILD_WIN.md | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/BUILD_WIN.md b/BUILD_WIN.md index 311dfd9267..7c3f18592a 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -1,5 +1,7 @@ This is a stand-alone guide for creating your first High Fidelity build for Windows 64-bit. +## Building High Fidelity + ### Step 1. Installing Visual Studio 2013 If you don't already have the Community or Professional edition of Visual Studio 2013, download and install [Visual Studio Community 2013](https://www.visualstudio.com/en-us/news/releasenotes/vs2013-community-vs). You do not need to install any of the optional components when going through the installer. @@ -18,8 +20,8 @@ Keep the default components checked when going through the installer. ### Step 4. Setting Qt Environment Variable -Go to "Control Panel > System > Advanced System Settings > Environment Variables > New..." (or search “Environment Variables” in Start Search). -* Set "Variable name": QT_CMAKE_PREFIX_PATH +Go to `Control Panel > System > Advanced System Settings > Environment Variables > New...` (or search “Environment Variables” in Start Search). +* Set "Variable name": `QT_CMAKE_PREFIX_PATH` * Set "Variable value": `%QT_DIR%\5.6\msvc2013_64\lib\cmake` ### Step 5. Installing OpenSSL @@ -29,34 +31,36 @@ Download and install the [Win64 OpenSSL v1.0.2L Installer](https://slproweb.com/ ### Step 6. Running CMake to Generate Build Files Run Command Prompt from Start and run the following commands: - cd "%HIFI_DIR%" - mkdir build - cd build - cmake .. -G "Visual Studio 12 Win64" + +> cd "%HIFI_DIR%" +> mkdir build +> cd build +> cmake .. -G "Visual Studio 12 Win64" + -Where %HIFI_DIR% is the directory for the highfidelity repository. +Where `%HIFI_DIR%` is the directory for the highfidelity repository. ### Step 7. Making a Build -Open '%HIFI_DIR%\build\hifi.sln' using Visual Studio. +Open `%HIFI_DIR%\build\hifi.sln` using Visual Studio. Change the Solution Configuration (next to the green play button) from "Debug" to "Release" for best performance. -Run Build > Build Solution. +Run `Build > Build Solution`. ### Step 8. Testing Interface Create another environment variable (see Step #4) -* Set "Variable name": _NO_DEBUG_HEAP -* Set "Variable value": 1 +* Set "Variable name": `_NO_DEBUG_HEAP` +* Set "Variable value": `1` -In Visual Studio, right+click "interface" under the Apps folder in Solution Explorer and select "Set as Startup Project". Run Debug > Start Debugging. +In Visual Studio, right+click "interface" under the Apps folder in Solution Explorer and select "Set as Startup Project". Run `Debug > Start Debugging`. Now, you should have a full build of High Fidelity and be able to run the Interface using Visual Studio. Please check our [Docs](https://wiki.highfidelity.com/wiki/Main_Page) for more information regarding the programming workflow. -Note: You can also run Interface by launching it from command line or File Explorer from %HIFI_DIR%\build\interface\Release\interface.exe +Note: You can also run Interface by launching it from command line or File Explorer from `%HIFI_DIR%\build\interface\Release\interface.exe` -### Troubleshooting +## Troubleshooting For any problems after Step #6, first try this: * Delete your locally cloned copy of the highfidelity repository @@ -66,16 +70,16 @@ For any problems after Step #6, first try this: #### CMake gives you the same error message repeatedly after the build fails -Remove `CMakeCache.txt` found in the '%HIFI_DIR%\build' directory +Remove `CMakeCache.txt` found in the `%HIFI_DIR%\build` directory. #### nmake cannot be found Make sure nmake.exe is located at the following path: + C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin If not, add the directory where nmake is located to the PATH environment variable. #### Qt is throwing an error -Make sure you have the correct version (5.6.2) installed and 'QT_CMAKE_PREFIX_PATH' environment variable is set correctly. - +Make sure you have the correct version (5.6.2) installed and `QT_CMAKE_PREFIX_PATH` environment variable is set correctly. From aa13812e3fcb48453c78955b91ed07650e1043d3 Mon Sep 17 00:00:00 2001 From: seefo Date: Tue, 6 Jun 2017 15:20:26 -0700 Subject: [PATCH 90/91] Fixed multiline in BUILD_WIN.md --- BUILD_WIN.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/BUILD_WIN.md b/BUILD_WIN.md index 7c3f18592a..818a176f75 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -31,12 +31,12 @@ Download and install the [Win64 OpenSSL v1.0.2L Installer](https://slproweb.com/ ### Step 6. Running CMake to Generate Build Files Run Command Prompt from Start and run the following commands: - -> cd "%HIFI_DIR%" -> mkdir build -> cd build -> cmake .. -G "Visual Studio 12 Win64" - +```` +cd "%HIFI_DIR%" +mkdir build +cd build +cmake .. -G "Visual Studio 12 Win64" +```` Where `%HIFI_DIR%` is the directory for the highfidelity repository. From 69520ff3db0f7b37bf34710f68b174e8d4f2fe23 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 7 Jun 2017 10:28:02 -0700 Subject: [PATCH 91/91] pull from upstream, code review --- interface/src/avatar/MyAvatar.cpp | 11 +---------- interface/src/avatar/MyAvatar.h | 4 ---- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 158e55ab5c..9e01d59f4f 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -417,7 +417,7 @@ void MyAvatar::update(float deltaTime) { } #ifdef DEBUG_DRAW_HMD_MOVING_AVERAGE - glm::vec3 p = transformPoint(getSensorToWorldMatrix(), getHeadControllerPoseInAvatarFrame() + + glm::vec3 p = transformPoint(getSensorToWorldMatrix(), getHeadControllerPoseInAvatarFrame() * glm::vec3(_headControllerFacingMovingAverage.x, 0.0f, _headControllerFacingMovingAverage.y)); DebugDraw::getInstance().addMarker("facing-avg", getOrientation(), p, glm::vec4(1.0f)); p = transformPoint(getSensorToWorldMatrix(), getHMDSensorPosition() + @@ -644,7 +644,6 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { _hmdSensorPosition = newHmdSensorPosition; _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); - // _headControllerFacing = getFacingDir2D(_hmdSensorOrientation); auto headPose = _headControllerPoseInSensorFrameCache.get(); if (headPose.isValid()) { _headControllerFacing = getFacingDir2D(headPose.rotation); @@ -2328,14 +2327,6 @@ bool MyAvatar::isDriveKeyDisabled(DriveKeys key) const { } } -glm::vec3 MyAvatar::getWorldBodyPosition() const { - return transformPoint(_sensorToWorldMatrix, extractTranslation(_bodySensorMatrix)); -} - -glm::quat MyAvatar::getWorldBodyOrientation() const { - return glm::quat_cast(_sensorToWorldMatrix * _bodySensorMatrix); -} - // old school meat hook style glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { glm::vec3 headPosition; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index babe47a2bc..f828a48636 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -564,10 +564,6 @@ signals: private: - glm::vec3 getWorldBodyPosition() const; - glm::quat getWorldBodyOrientation() const; - - virtual QByteArray toByteArrayStateful(AvatarDataDetail dataDetail) override; void simulate(float deltaTime);