From b7cdca75b7ed403c212b2f05b3b937718c2738f9 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 24 Nov 2015 16:12:04 -0600 Subject: [PATCH 01/78] Checkpoint towards integrated delivery --- assignment-client/CMakeLists.txt | 1 + cmake/macros/ConsolidateStackComponents.cmake | 9 +++++++++ ...e.cmake => PackageLibrariesForDeployment.cmake} | 2 +- domain-server/CMakeLists.txt | 1 + stack-manager/CMakeLists.txt | 14 +++++++++----- 5 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 cmake/macros/ConsolidateStackComponents.cmake rename cmake/macros/{CopyDllsBesideWindowsExecutable.cmake => PackageLibrariesForDeployment.cmake} (98%) diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index 58f200b0fe..3064e97d70 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -11,3 +11,4 @@ link_hifi_libraries( include_application_version() package_libraries_for_deployment() +consolidate_stack_components() \ No newline at end of file diff --git a/cmake/macros/ConsolidateStackComponents.cmake b/cmake/macros/ConsolidateStackComponents.cmake new file mode 100644 index 0000000000..2b2fe9a691 --- /dev/null +++ b/cmake/macros/ConsolidateStackComponents.cmake @@ -0,0 +1,9 @@ +macro(CONSOLIDATE_STACK_COMPONENTS) + + # Copy all the output for this target into the common deployment location + add_custom_command( + TARGET ${TARGET_NAME} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy_directory $ ${CMAKE_BINARY_DIR}/full-stack-deployment + ) + +endmacro() \ No newline at end of file diff --git a/cmake/macros/CopyDllsBesideWindowsExecutable.cmake b/cmake/macros/PackageLibrariesForDeployment.cmake similarity index 98% rename from cmake/macros/CopyDllsBesideWindowsExecutable.cmake rename to cmake/macros/PackageLibrariesForDeployment.cmake index 9330515a62..bb0b268dd4 100644 --- a/cmake/macros/CopyDllsBesideWindowsExecutable.cmake +++ b/cmake/macros/PackageLibrariesForDeployment.cmake @@ -1,5 +1,5 @@ # -# CopyDllsBesideWindowsExecutable.cmake +# PackageLibrariesForDeployment.cmake # cmake/macros # # Copyright 2015 High Fidelity, Inc. diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index 1f9280a899..2200916765 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -38,3 +38,4 @@ endif (UNIX) include_application_version() package_libraries_for_deployment() +consolidate_stack_components() \ No newline at end of file diff --git a/stack-manager/CMakeLists.txt b/stack-manager/CMakeLists.txt index e70fefc6e0..35b4f091a7 100644 --- a/stack-manager/CMakeLists.txt +++ b/stack-manager/CMakeLists.txt @@ -1,16 +1,19 @@ set(TARGET_NAME "stack-manager") set(BUILD_BUNDLE YES) setup_hifi_project(Widgets Gui Svg Core Network WebKitWidgets) +add_dependencies(${TARGET_NAME} assignment-client domain-server) if (WIN32) target_zlib() endif () target_quazip() -set_target_properties( - ${TARGET_NAME} PROPERTIES - EXCLUDE_FROM_ALL TRUE -) +if (UNIX) + set_target_properties( + ${TARGET_NAME} PROPERTIES + EXCLUDE_FROM_ALL TRUE + ) +endif (UNIX) if (DEFINED ENV{JOB_ID}) set(PR_BUILD "false") @@ -45,4 +48,5 @@ if (APPLE) set(SM_SRCS ${SM_SRCS} "${CMAKE_CURRENT_SOURCE_DIR}/assets/icon.icns") endif () -package_libraries_for_deployment() \ No newline at end of file +package_libraries_for_deployment() +consolidate_stack_components() \ No newline at end of file From 766f0dbd32561a791a2d7a43365d2364e1f8af30 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Fri, 27 Nov 2015 14:04:33 -0600 Subject: [PATCH 02/78] Have stack manager use bundled stack --- CMakeLists.txt | 15 ++ cmake/templates/FixupBundlePostBuild.cmake.in | 2 +- interface/CMakeLists.txt | 2 +- stack-manager/CMakeLists.txt | 1 + stack-manager/src/AppDelegate.cpp | 232 +----------------- stack-manager/src/AppDelegate.h | 7 - stack-manager/src/GlobalData.cpp | 19 +- stack-manager/src/GlobalData.h | 1 + 8 files changed, 25 insertions(+), 254 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e95974383..d5f615949c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -221,3 +221,18 @@ if (HIFI_MEMORY_DEBUGGING) MESSAGE("-- Memory debugging is enabled") endif (UNIX) endif () + +set(CPACK_PACKAGE_NAME "High Fidelity") +set(CPACK_PACKAGE_VENDOR "High Fidelity, Inc") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "High Fidelity Interface and Stack") +set(CPACK_PACKAGE_VERSION "${BUILD_SEQ}") +set(CPACK_PACKAGE_VERSION_MAJOR "${BUILD_SEQ}") +set(CPACK_PACKAGE_VERSION_MINOR "0") +set(CPACK_PACKAGE_VERSION_PATCH "0") +set(CPACK_PACKAGE_INSTALL_DIRECTORY "High Fidelity") + +if (WIN32) + install(DIRECTORY ${CMAKE_BINARY_DIR}/full-stack-deployment/ DESTINATION "./") +endif (WIN32) + +include(CPack) \ No newline at end of file diff --git a/cmake/templates/FixupBundlePostBuild.cmake.in b/cmake/templates/FixupBundlePostBuild.cmake.in index ee686a6967..6e3ad9723b 100644 --- a/cmake/templates/FixupBundlePostBuild.cmake.in +++ b/cmake/templates/FixupBundlePostBuild.cmake.in @@ -53,4 +53,4 @@ else() endif() file(GLOB RUNTIME_PLUGINS "${BUNDLE_PLUGIN_DIR}/*.${PLUGIN_EXTENSION}") -fixup_bundle("${BUNDLE_EXECUTABLE}" "${RUNTIME_PLUGINS}" "@FIXUP_LIBS@") \ No newline at end of file +fixup_bundle("${BUNDLE_EXECUTABLE}" "${RUNTIME_PLUGINS}" "@FIXUP_LIBS@") diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 3357b57858..091cad56ab 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -194,7 +194,6 @@ else (APPLE) # link target to external libraries if (WIN32) - # target_link_libraries(${TARGET_NAME} wsock32.lib Winmm.lib) target_link_libraries(${TARGET_NAME} wsock32.lib Winmm.lib) else (WIN32) # Nothing else required on linux apparently @@ -202,3 +201,4 @@ else (APPLE) endif (APPLE) package_libraries_for_deployment() +consolidate_stack_components() diff --git a/stack-manager/CMakeLists.txt b/stack-manager/CMakeLists.txt index 35b4f091a7..520beb6893 100644 --- a/stack-manager/CMakeLists.txt +++ b/stack-manager/CMakeLists.txt @@ -2,6 +2,7 @@ set(TARGET_NAME "stack-manager") set(BUILD_BUNDLE YES) setup_hifi_project(Widgets Gui Svg Core Network WebKitWidgets) add_dependencies(${TARGET_NAME} assignment-client domain-server) +include_application_version() if (WIN32) target_zlib() diff --git a/stack-manager/src/AppDelegate.cpp b/stack-manager/src/AppDelegate.cpp index ea9310a2d8..6b350af117 100644 --- a/stack-manager/src/AppDelegate.cpp +++ b/stack-manager/src/AppDelegate.cpp @@ -81,10 +81,6 @@ void myMessageHandler(QtMsgType type, const QMessageLogContext &context, const Q AppDelegate::AppDelegate(int argc, char* argv[]) : QApplication(argc, argv), - _qtReady(false), - _dsReady(false), - _dsResourcesReady(false), - _acReady(false), _domainServerProcess(NULL), _acMonitorProcess(NULL), _domainServerName("localhost") @@ -115,14 +111,15 @@ AppDelegate::AppDelegate(int argc, char* argv[]) : _window = new MainWindow(); - createExecutablePath(); - downloadLatestExecutablesAndRequirements(); - _checkVersionTimer.setInterval(0); connect(&_checkVersionTimer, SIGNAL(timeout()), this, SLOT(checkVersion())); _checkVersionTimer.start(); connect(this, &QApplication::aboutToQuit, this, &AppDelegate::stopStack); + + _window->setRequirementsLastChecked(QDateTime::currentDateTime().toString()); + _window->show(); + toggleStack(true); } AppDelegate::~AppDelegate() { @@ -427,227 +424,6 @@ void AppDelegate::handleContentSetDownloadFinished() { emit domainAddressChanged(); } -void AppDelegate::onFileSuccessfullyInstalled(const QUrl& url) { - if (url == GlobalData::getInstance().getRequirementsURL()) { - _qtReady = true; - } else if (url == GlobalData::getInstance().getAssignmentClientURL()) { - _acReady = true; - } else if (url == GlobalData::getInstance().getDomainServerURL()) { - _dsReady = true; - } else if (url == GlobalData::getInstance().getDomainServerResourcesURL()) { - _dsResourcesReady = true; - } - - if (_qtReady && _acReady && _dsReady && _dsResourcesReady) { - _window->setRequirementsLastChecked(QDateTime::currentDateTime().toString()); - _window->show(); - toggleStack(true); - } -} - -void AppDelegate::createExecutablePath() { - QDir launchDir(GlobalData::getInstance().getClientsLaunchPath()); - QDir resourcesDir(GlobalData::getInstance().getClientsResourcesPath()); - QDir logsDir(GlobalData::getInstance().getLogsPath()); - if (!launchDir.exists()) { - if (QDir().mkpath(launchDir.absolutePath())) { - qDebug() << "Successfully created directory: " - << launchDir.absolutePath(); - } else { - qCritical() << "Failed to create directory: " - << launchDir.absolutePath(); - } - } - if (!resourcesDir.exists()) { - if (QDir().mkpath(resourcesDir.absolutePath())) { - qDebug() << "Successfully created directory: " - << resourcesDir.absolutePath(); - } else { - qCritical() << "Failed to create directory: " - << resourcesDir.absolutePath(); - } - } - if (!logsDir.exists()) { - if (QDir().mkpath(logsDir.absolutePath())) { - qDebug() << "Successfully created directory: " - << logsDir.absolutePath(); - } else { - qCritical() << "Failed to create directory: " - << logsDir.absolutePath(); - } - } -} - -void AppDelegate::downloadLatestExecutablesAndRequirements() { - // Check if Qt is already installed - if (GlobalData::getInstance().getPlatform() == "mac") { - if (QDir(GlobalData::getInstance().getClientsLaunchPath() + "QtCore.framework").exists()) { - _qtReady = true; - } - } else if (GlobalData::getInstance().getPlatform() == "win") { - if (QFileInfo(GlobalData::getInstance().getClientsLaunchPath() + "Qt5Core.dll").exists()) { - _qtReady = true; - } - } else { // linux - if (QFileInfo(GlobalData::getInstance().getClientsLaunchPath() + "libQt5Core.so.5").exists()) { - _qtReady = true; - } - } - - - QFile reqZipFile(GlobalData::getInstance().getRequirementsZipPath()); - QByteArray reqZipData; - if (reqZipFile.open(QIODevice::ReadOnly)) { - reqZipData = reqZipFile.readAll(); - reqZipFile.close(); - } - QFile resZipFile(GlobalData::getInstance().getDomainServerResourcesZipPath()); - QByteArray resZipData; - if (resZipFile.open(QIODevice::ReadOnly)) { - resZipData = resZipFile.readAll(); - resZipFile.close(); - } - - QDir resourcesDir(GlobalData::getInstance().getClientsResourcesPath()); - if (!(resourcesDir.entryInfoList(QDir::AllEntries).size() < 3)) { - _dsResourcesReady = true; - } - - // if the user has set hifiBuildDirectory, don't attempt to download the domain-server or assignement-client - if (GlobalData::getInstance().isGetHifiBuildDirectorySet()) { - _dsReady = true; - _acReady = true; - } else { - QByteArray dsData; - QFile dsFile(GlobalData::getInstance().getDomainServerExecutablePath()); - if (dsFile.open(QIODevice::ReadOnly)) { - dsData = dsFile.readAll(); - dsFile.close(); - } - QByteArray acData; - QFile acFile(GlobalData::getInstance().getAssignmentClientExecutablePath()); - if (acFile.open(QIODevice::ReadOnly)) { - acData = acFile.readAll(); - acFile.close(); - } - - QNetworkRequest acReq(QUrl(GlobalData::getInstance().getAssignmentClientMD5URL())); - QNetworkReply* acReply = _manager->get(acReq); - QEventLoop acLoop; - connect(acReply, SIGNAL(finished()), &acLoop, SLOT(quit())); - acLoop.exec(); - QByteArray acMd5Data = acReply->readAll().trimmed(); - if (GlobalData::getInstance().getPlatform() == "win") { - // fix for reading the MD5 hash from Windows-generated - // binary data of the MD5 hash - QTextStream stream(acMd5Data); - stream >> acMd5Data; - } - - // fix for Mac and Linux network accessibility - if (acMd5Data.size() == 0) { - // network is not accessible - qDebug() << "Could not connect to the internet."; - _window->show(); - return; - } - - qDebug() << "AC MD5: " << acMd5Data; - if (acMd5Data.toLower() == QCryptographicHash::hash(acData, QCryptographicHash::Md5).toHex()) { - _acReady = true; - } - - - QNetworkRequest dsReq(QUrl(GlobalData::getInstance().getDomainServerMD5URL())); - QNetworkReply* dsReply = _manager->get(dsReq); - QEventLoop dsLoop; - connect(dsReply, SIGNAL(finished()), &dsLoop, SLOT(quit())); - dsLoop.exec(); - QByteArray dsMd5Data = dsReply->readAll().trimmed(); - if (GlobalData::getInstance().getPlatform() == "win") { - // fix for reading the MD5 hash from Windows generated - // binary data of the MD5 hash - QTextStream stream(dsMd5Data); - stream >> dsMd5Data; - } - qDebug() << "DS MD5: " << dsMd5Data; - if (dsMd5Data.toLower() == QCryptographicHash::hash(dsData, QCryptographicHash::Md5).toHex()) { - _dsReady = true; - } - } - - if (_qtReady) { - // check MD5 of requirements.zip only if Qt is found - QNetworkRequest reqZipReq(QUrl(GlobalData::getInstance().getRequirementsMD5URL())); - QNetworkReply* reqZipReply = _manager->get(reqZipReq); - QEventLoop reqZipLoop; - connect(reqZipReply, SIGNAL(finished()), &reqZipLoop, SLOT(quit())); - reqZipLoop.exec(); - QByteArray reqZipMd5Data = reqZipReply->readAll().trimmed(); - if (GlobalData::getInstance().getPlatform() == "win") { - // fix for reading the MD5 hash from Windows generated - // binary data of the MD5 hash - QTextStream stream(reqZipMd5Data); - stream >> reqZipMd5Data; - } - qDebug() << "Requirements ZIP MD5: " << reqZipMd5Data; - if (reqZipMd5Data.toLower() != QCryptographicHash::hash(reqZipData, QCryptographicHash::Md5).toHex()) { - _qtReady = false; - } - } - - if (_dsResourcesReady) { - // check MD5 of resources.zip only if Domain Server - // resources are installed - QNetworkRequest resZipReq(QUrl(GlobalData::getInstance().getDomainServerResourcesMD5URL())); - QNetworkReply* resZipReply = _manager->get(resZipReq); - QEventLoop resZipLoop; - connect(resZipReply, SIGNAL(finished()), &resZipLoop, SLOT(quit())); - resZipLoop.exec(); - QByteArray resZipMd5Data = resZipReply->readAll().trimmed(); - if (GlobalData::getInstance().getPlatform() == "win") { - // fix for reading the MD5 hash from Windows generated - // binary data of the MD5 hash - QTextStream stream(resZipMd5Data); - stream >> resZipMd5Data; - } - qDebug() << "Domain Server Resources ZIP MD5: " << resZipMd5Data; - if (resZipMd5Data.toLower() != QCryptographicHash::hash(resZipData, QCryptographicHash::Md5).toHex()) { - _dsResourcesReady = false; - } - } - - DownloadManager* downloadManager = 0; - if (!_qtReady || !_acReady || !_dsReady || !_dsResourcesReady) { - // initialise DownloadManager - downloadManager = new DownloadManager(_manager); - downloadManager->setWindowModality(Qt::ApplicationModal); - connect(downloadManager, SIGNAL(fileSuccessfullyInstalled(QUrl)), - SLOT(onFileSuccessfullyInstalled(QUrl))); - downloadManager->show(); - } else { - _window->setRequirementsLastChecked(QDateTime::currentDateTime().toString()); - _window->show(); - toggleStack(true); - } - - if (!_qtReady) { - downloadManager->downloadFile(GlobalData::getInstance().getRequirementsURL()); - } - - if (!_acReady) { - downloadManager->downloadFile(GlobalData::getInstance().getAssignmentClientURL()); - } - - if (!_dsReady) { - downloadManager->downloadFile(GlobalData::getInstance().getDomainServerURL()); - } - - if (!_dsResourcesReady) { - downloadManager->downloadFile(GlobalData::getInstance().getDomainServerResourcesURL()); - } -} - void AppDelegate::checkVersion() { QNetworkRequest latestVersionRequest((QUrl(CHECK_BUILDS_URL))); latestVersionRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); diff --git a/stack-manager/src/AppDelegate.h b/stack-manager/src/AppDelegate.h index 1d4728b7ce..ebcb8ce904 100644 --- a/stack-manager/src/AppDelegate.h +++ b/stack-manager/src/AppDelegate.h @@ -53,7 +53,6 @@ signals: void indexPathChangeResponse(bool wasSuccessful); void stackStateChanged(bool isOn); private slots: - void onFileSuccessfullyInstalled(const QUrl& url); void requestDomainServerID(); void handleDomainIDReply(); void handleDomainGetReply(); @@ -64,16 +63,10 @@ private slots: private: void parseCommandLine(); - void createExecutablePath(); - void downloadLatestExecutablesAndRequirements(); void changeDomainServerIndexPath(const QString& newPath); QNetworkAccessManager* _manager; - bool _qtReady; - bool _dsReady; - bool _dsResourcesReady; - bool _acReady; BackgroundProcess* _domainServerProcess; BackgroundProcess* _acMonitorProcess; QHash _scriptProcesses; diff --git a/stack-manager/src/GlobalData.cpp b/stack-manager/src/GlobalData.cpp index ecc5ed520d..3078b3b24a 100644 --- a/stack-manager/src/GlobalData.cpp +++ b/stack-manager/src/GlobalData.cpp @@ -32,11 +32,8 @@ GlobalData::GlobalData() { _resourcePath = "resources/"; _assignmentClientExecutable = "assignment-client"; _domainServerExecutable = "domain-server"; - QString applicationSupportDirectory = QStandardPaths::writableLocation(QStandardPaths::DataLocation); - if (PR_BUILD) { - applicationSupportDirectory += "/pr-binaries"; - } - + QString applicationSupportDirectory = QCoreApplication::applicationDirPath(); + _clientsLaunchPath = QDir::toNativeSeparators(applicationSupportDirectory + "/"); _clientsResourcePath = QDir::toNativeSeparators(applicationSupportDirectory + "/" + _resourcePath); @@ -49,18 +46,6 @@ GlobalData::GlobalData() { _domainServerExecutablePath.append(".exe"); } - _requirementsURL = urlBase + "/binaries/" + _platform + "/requirements/requirements.zip"; - _requirementsZipPath = _clientsLaunchPath + "requirements.zip"; - _requirementsMD5URL = urlBase + "/binaries/" + _platform + "/requirements/requirements.md5"; - _assignmentClientURL = urlBase + "/binaries/" + _platform + "/assignment-client" + (_platform == "win" ? "/assignment-client.exe" : "/assignment-client"); - _domainServerResourcesURL = urlBase + "/binaries/" + _platform + "/domain-server/resources.zip"; - _domainServerResourcesZipPath = _clientsLaunchPath + "resources.zip"; - _domainServerResourcesMD5URL = urlBase + "/binaries/" + _platform + "/domain-server/resources.md5"; - _domainServerURL = urlBase + "/binaries/" + _platform + "/domain-server" + (_platform == "win" ? "/domain-server.exe" : "/domain-server"); - - _assignmentClientMD5URL = urlBase + "/binaries/" + _platform + "/assignment-client/assignment-client.md5"; - _domainServerMD5URL = urlBase + "/binaries/" + _platform + "/domain-server/domain-server.md5"; - _defaultDomain = "localhost"; _logsPath = QDir::toNativeSeparators(_clientsLaunchPath + "logs/"); _availableAssignmentTypes.insert("audio-mixer", 0); diff --git a/stack-manager/src/GlobalData.h b/stack-manager/src/GlobalData.h index 58c9a93526..a8687f31d2 100644 --- a/stack-manager/src/GlobalData.h +++ b/stack-manager/src/GlobalData.h @@ -9,6 +9,7 @@ #ifndef hifi_GlobalData_h #define hifi_GlobalData_h +#include #include #include From a37262465f60bc932bb63311ff9d26b17db1c157 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Fri, 27 Nov 2015 14:23:38 -0600 Subject: [PATCH 03/78] Creating icons --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d5f615949c..dc11d28a2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -230,6 +230,8 @@ set(CPACK_PACKAGE_VERSION_MAJOR "${BUILD_SEQ}") set(CPACK_PACKAGE_VERSION_MINOR "0") set(CPACK_PACKAGE_VERSION_PATCH "0") set(CPACK_PACKAGE_INSTALL_DIRECTORY "High Fidelity") +set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Interface.lnk' '$INSTDIR\\\\interface.exe'") +set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\StacK Manager.lnk' '$INSTDIR\\\\stack-manager.exe'") if (WIN32) install(DIRECTORY ${CMAKE_BINARY_DIR}/full-stack-deployment/ DESTINATION "./") From 5822386702d04ee5e048417c91c3e6d95d22af11 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 30 Nov 2015 08:56:30 -0600 Subject: [PATCH 04/78] Checkpoint --- CMakeLists.txt | 32 +++++++++++-------- cmake/macros/ConsolidateStackComponents.cmake | 2 ++ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc11d28a2e..500c27791b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -222,19 +222,23 @@ if (HIFI_MEMORY_DEBUGGING) endif (UNIX) endif () -set(CPACK_PACKAGE_NAME "High Fidelity") -set(CPACK_PACKAGE_VENDOR "High Fidelity, Inc") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "High Fidelity Interface and Stack") -set(CPACK_PACKAGE_VERSION "${BUILD_SEQ}") -set(CPACK_PACKAGE_VERSION_MAJOR "${BUILD_SEQ}") -set(CPACK_PACKAGE_VERSION_MINOR "0") -set(CPACK_PACKAGE_VERSION_PATCH "0") -set(CPACK_PACKAGE_INSTALL_DIRECTORY "High Fidelity") -set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Interface.lnk' '$INSTDIR\\\\interface.exe'") -set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\StacK Manager.lnk' '$INSTDIR\\\\stack-manager.exe'") +include_application_version() -if (WIN32) - install(DIRECTORY ${CMAKE_BINARY_DIR}/full-stack-deployment/ DESTINATION "./") -endif (WIN32) +if (DEFINED ENV{ghprbPullId}) + set(CPACK_PACKAGE_NAME "High Fidelity - Test Build") + set(CPACK_PACKAGE_VENDOR "High Fidelity, Inc") + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "High Fidelity Interface and Stack") + set(CPACK_PACKAGE_VERSION "${BUILD_SEQ}") + set(CPACK_PACKAGE_VERSION_MAJOR "${BUILD_SEQ}") + set(CPACK_PACKAGE_VERSION_MINOR "0") + set(CPACK_PACKAGE_VERSION_PATCH "0") + set(CPACK_PACKAGE_INSTALL_DIRECTORY "High Fidelity - Test Build") + set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Interface.lnk' '$INSTDIR\\\\interface.exe'") + set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\StacK Manager.lnk' '$INSTDIR\\\\stack-manager.exe'") -include(CPack) \ No newline at end of file + if (WIN32) + install(DIRECTORY ${CMAKE_BINARY_DIR}/full-stack-deployment/ DESTINATION "./") + endif (WIN32) + + include(CPack) +endif () \ No newline at end of file diff --git a/cmake/macros/ConsolidateStackComponents.cmake b/cmake/macros/ConsolidateStackComponents.cmake index 2b2fe9a691..50a1f5e48a 100644 --- a/cmake/macros/ConsolidateStackComponents.cmake +++ b/cmake/macros/ConsolidateStackComponents.cmake @@ -1,9 +1,11 @@ macro(CONSOLIDATE_STACK_COMPONENTS) + if (DEFINED ENV{ghprbPullId}) # Copy all the output for this target into the common deployment location add_custom_command( TARGET ${TARGET_NAME} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_directory $ ${CMAKE_BINARY_DIR}/full-stack-deployment ) + endif () endmacro() \ No newline at end of file From 4e186409221b2adbc9ace33c1b7101796ca63a71 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 30 Nov 2015 10:07:11 -0600 Subject: [PATCH 05/78] Some fixes --- CMakeLists.txt | 6 +++--- cmake/macros/IncludeApplicationVersion.cmake | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 500c27791b..47368a0f4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -225,16 +225,16 @@ endif () include_application_version() if (DEFINED ENV{ghprbPullId}) - set(CPACK_PACKAGE_NAME "High Fidelity - Test Build") + set(CPACK_PACKAGE_NAME "High Fidelity") set(CPACK_PACKAGE_VENDOR "High Fidelity, Inc") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "High Fidelity Interface and Stack") set(CPACK_PACKAGE_VERSION "${BUILD_SEQ}") set(CPACK_PACKAGE_VERSION_MAJOR "${BUILD_SEQ}") set(CPACK_PACKAGE_VERSION_MINOR "0") set(CPACK_PACKAGE_VERSION_PATCH "0") - set(CPACK_PACKAGE_INSTALL_DIRECTORY "High Fidelity - Test Build") + set(CPACK_PACKAGE_INSTALL_DIRECTORY "High Fidelity-${BUILD_SEQ}") set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Interface.lnk' '$INSTDIR\\\\interface.exe'") - set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\StacK Manager.lnk' '$INSTDIR\\\\stack-manager.exe'") + set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Stack Manager.lnk' '$INSTDIR\\\\stack-manager.exe'") if (WIN32) install(DIRECTORY ${CMAKE_BINARY_DIR}/full-stack-deployment/ DESTINATION "./") diff --git a/cmake/macros/IncludeApplicationVersion.cmake b/cmake/macros/IncludeApplicationVersion.cmake index 96137294a7..a2993efbd2 100644 --- a/cmake/macros/IncludeApplicationVersion.cmake +++ b/cmake/macros/IncludeApplicationVersion.cmake @@ -13,7 +13,7 @@ macro(INCLUDE_APPLICATION_VERSION) if (DEFINED ENV{JOB_ID}) set (BUILD_SEQ $ENV{JOB_ID}) elseif (DEFINED ENV{ghprbPullId}) - set (BUILD_SEQ "PR: $ENV{ghprbPullId} - Commit: $ENV{ghprbActualCommit}") + set (BUILD_SEQ "PR.$ENV{ghprbPullId}") else () set(BUILD_SEQ "dev") endif () From ca8cd13c4876775843ee941d2b057e5f4fd9c084 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 1 Dec 2015 12:32:31 -0600 Subject: [PATCH 06/78] Checkpoint --- cmake/macros/ConsolidateStackComponents.cmake | 2 +- cmake/modules/FindOpenSSL.cmake | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cmake/macros/ConsolidateStackComponents.cmake b/cmake/macros/ConsolidateStackComponents.cmake index 50a1f5e48a..2a991e5d03 100644 --- a/cmake/macros/ConsolidateStackComponents.cmake +++ b/cmake/macros/ConsolidateStackComponents.cmake @@ -1,6 +1,6 @@ macro(CONSOLIDATE_STACK_COMPONENTS) - if (DEFINED ENV{ghprbPullId}) + if (DEFINED ENV{ghprbPullId} AND WIN32) # Copy all the output for this target into the common deployment location add_custom_command( TARGET ${TARGET_NAME} POST_BUILD diff --git a/cmake/modules/FindOpenSSL.cmake b/cmake/modules/FindOpenSSL.cmake index 2142322687..2a15cf7929 100644 --- a/cmake/modules/FindOpenSSL.cmake +++ b/cmake/modules/FindOpenSSL.cmake @@ -107,7 +107,7 @@ if (WIN32 AND NOT CYGWIN) select_library_configurations(SSL_EAY) set(OPENSSL_LIBRARIES ${SSL_EAY_LIBRARY} ${LIB_EAY_LIBRARY}) - + find_path(OPENSSL_DLL_PATH NAMES ssleay32.dll PATH_SUFFIXES "bin" ${_OPENSSL_ROOT_HINTS_AND_PATHS}) elseif (MINGW) @@ -250,8 +250,18 @@ else () ) endif () + + message(STATUS "++++++++++++++++++++++++++++") + message(STATUS "${OPENSSL_LIBRARIES}") + message(STATUS "${OPENSSL_DLL_PATH}") if (WIN32) add_paths_to_fixup_libs(${OPENSSL_DLL_PATH}) + if (DEFINED ENV{ghprbPullId}) + add_custom_command( + TARGET ${TARGET_NAME} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy ${OPENSSL_DLL_PATH}/ssleay32.dll ${CMAKE_BINARY_DIR}/full-stack-deployment + ) + endif () endif () mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES OPENSSL_SEARCH_DIRS) From c786789c4cd11996b63bd4cea2ead9eabaf05597 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Wed, 2 Dec 2015 12:43:25 -0600 Subject: [PATCH 07/78] Changes for SSL and icons --- CMakeLists.txt | 15 ++++++++-- cmake/macros/ConsolidateStackComponents.cmake | 28 +++++++++++++++---- cmake/macros/IncludeApplicationVersion.cmake | 7 ++++- cmake/modules/FindOpenSSL.cmake | 11 ++++---- 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 47368a0f4e..4b44f81d2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -224,7 +224,16 @@ endif () include_application_version() -if (DEFINED ENV{ghprbPullId}) +if (DEFINED DEPLOY_PACKAGE AND DEPLOY_PACKAGE) + message(STATUS "+++++ Package for deployment will be generated on this build +++++") + + file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/full-stack-deployment) + + set (ICONPATH_INTERFACE "$INSTDIR/${PATH_INSTALL_DATA}/interface.ico") + set (ICONPATH_STACK_MANAGER "$INSTDIR/${PATH_INSTALL_DATA}/stack-manager.ico") + string (REPLACE "/" "\\\\" ICONPATH_INTERFACE ${ICONPATH_INTERFACE}) + string (REPLACE "/" "\\\\" ICONPATH_STACK_MANAGER ${ICONPATH_STACK_MANAGER}) + set(CPACK_PACKAGE_NAME "High Fidelity") set(CPACK_PACKAGE_VENDOR "High Fidelity, Inc") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "High Fidelity Interface and Stack") @@ -233,8 +242,8 @@ if (DEFINED ENV{ghprbPullId}) set(CPACK_PACKAGE_VERSION_MINOR "0") set(CPACK_PACKAGE_VERSION_PATCH "0") set(CPACK_PACKAGE_INSTALL_DIRECTORY "High Fidelity-${BUILD_SEQ}") - set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Interface.lnk' '$INSTDIR\\\\interface.exe'") - set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Stack Manager.lnk' '$INSTDIR\\\\stack-manager.exe'") + set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Interface.lnk' '$INSTDIR\\\\interface.exe' '${ICONPATH_INTERFACE}'") + set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Stack Manager.lnk' '$INSTDIR\\\\stack-manager.exe' '${ICONPATH_STACK_MANAGER}'") if (WIN32) install(DIRECTORY ${CMAKE_BINARY_DIR}/full-stack-deployment/ DESTINATION "./") diff --git a/cmake/macros/ConsolidateStackComponents.cmake b/cmake/macros/ConsolidateStackComponents.cmake index 2a991e5d03..4bcc777751 100644 --- a/cmake/macros/ConsolidateStackComponents.cmake +++ b/cmake/macros/ConsolidateStackComponents.cmake @@ -1,11 +1,27 @@ macro(CONSOLIDATE_STACK_COMPONENTS) - if (DEFINED ENV{ghprbPullId} AND WIN32) - # Copy all the output for this target into the common deployment location - add_custom_command( - TARGET ${TARGET_NAME} POST_BUILD - COMMAND "${CMAKE_COMMAND}" -E copy_directory $ ${CMAKE_BINARY_DIR}/full-stack-deployment - ) + if (DEFINED DEPLOY_PACKAGE AND DEPLOY_PACKAGE AND WIN32) + + # Copy all the output for this target into the common deployment location + add_custom_command( + TARGET ${TARGET_NAME} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy_directory $ ${CMAKE_BINARY_DIR}/full-stack-deployment + ) + + # Copy icon files for interface and stack manager + if (TARGET_NAME STREQUAL "interface" OR TARGET_NAME STREQUAL "stack-manager") + if (TARGET_NAME STREQUAL "interface") + set (ICON_FILE_PATH "${PROJECT_SOURCE_DIR}/icon/interface.ico") + set (ICON_DESTINATION_NAME "interface.ico") + elseif (TARGET_NAME STREQUAL "stack-manager") + set (ICON_FILE_PATH "${PROJECT_SOURCE_DIR}/assets/icon.ico") + set (ICON_DESTINATION_NAME "stack-manager.ico") + endif () + add_custom_command( + TARGET ${TARGET_NAME} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy ${ICON_FILE_PATH} ${CMAKE_BINARY_DIR}/full-stack-deployment/${ICON_DESTINATION_NAME} + ) + endif () endif () endmacro() \ No newline at end of file diff --git a/cmake/macros/IncludeApplicationVersion.cmake b/cmake/macros/IncludeApplicationVersion.cmake index a2993efbd2..a91aad6acc 100644 --- a/cmake/macros/IncludeApplicationVersion.cmake +++ b/cmake/macros/IncludeApplicationVersion.cmake @@ -10,10 +10,15 @@ # macro(INCLUDE_APPLICATION_VERSION) + # + # We are relying on Jenkins defined environment variables to determine the origin of this build + # and will only package if this is a PR or Release build if (DEFINED ENV{JOB_ID}) + set (DEPLOY_PACKAGE 1) set (BUILD_SEQ $ENV{JOB_ID}) elseif (DEFINED ENV{ghprbPullId}) - set (BUILD_SEQ "PR.$ENV{ghprbPullId}") + set (DEPLOY_PACKAGE 1) + set (BUILD_SEQ "PR-$ENV{ghprbPullId}") else () set(BUILD_SEQ "dev") endif () diff --git a/cmake/modules/FindOpenSSL.cmake b/cmake/modules/FindOpenSSL.cmake index 2a15cf7929..9d9557ad9e 100644 --- a/cmake/modules/FindOpenSSL.cmake +++ b/cmake/modules/FindOpenSSL.cmake @@ -250,16 +250,15 @@ else () ) endif () - - message(STATUS "++++++++++++++++++++++++++++") - message(STATUS "${OPENSSL_LIBRARIES}") - message(STATUS "${OPENSSL_DLL_PATH}") if (WIN32) add_paths_to_fixup_libs(${OPENSSL_DLL_PATH}) - if (DEFINED ENV{ghprbPullId}) + # + # For some reason fixup misses the following DLL and only copies libeay32. There's gotta be a better way to handle this + # but for now resorting to the following interm solution + if (DEFINED DEPLOY_PACKAGE AND DEPLOY_PACKAGE) add_custom_command( TARGET ${TARGET_NAME} POST_BUILD - COMMAND "${CMAKE_COMMAND}" -E copy ${OPENSSL_DLL_PATH}/ssleay32.dll ${CMAKE_BINARY_DIR}/full-stack-deployment + COMMAND "${CMAKE_COMMAND}" -E copy ${OPENSSL_DLL_PATH}/ssleay32.dll ${CMAKE_BINARY_DIR}/full-stack-deployment/ ) endif () endif () From 252086ea483f32f5097170c9fe11ec3abe2e975c Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Wed, 2 Dec 2015 12:48:58 -0600 Subject: [PATCH 08/78] indentation fixes --- stack-manager/src/AppDelegate.cpp | 6 +++--- stack-manager/src/GlobalData.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/stack-manager/src/AppDelegate.cpp b/stack-manager/src/AppDelegate.cpp index 6b350af117..3e65406bc5 100644 --- a/stack-manager/src/AppDelegate.cpp +++ b/stack-manager/src/AppDelegate.cpp @@ -117,9 +117,9 @@ AppDelegate::AppDelegate(int argc, char* argv[]) : connect(this, &QApplication::aboutToQuit, this, &AppDelegate::stopStack); - _window->setRequirementsLastChecked(QDateTime::currentDateTime().toString()); - _window->show(); - toggleStack(true); + _window->setRequirementsLastChecked(QDateTime::currentDateTime().toString()); + _window->show(); + toggleStack(true); } AppDelegate::~AppDelegate() { diff --git a/stack-manager/src/GlobalData.cpp b/stack-manager/src/GlobalData.cpp index 3078b3b24a..bc2f3e3482 100644 --- a/stack-manager/src/GlobalData.cpp +++ b/stack-manager/src/GlobalData.cpp @@ -32,7 +32,7 @@ GlobalData::GlobalData() { _resourcePath = "resources/"; _assignmentClientExecutable = "assignment-client"; _domainServerExecutable = "domain-server"; - QString applicationSupportDirectory = QCoreApplication::applicationDirPath(); + QString applicationSupportDirectory = QCoreApplication::applicationDirPath(); _clientsLaunchPath = QDir::toNativeSeparators(applicationSupportDirectory + "/"); _clientsResourcePath = QDir::toNativeSeparators(applicationSupportDirectory + "/" + _resourcePath); From 8ae05d8490f3c00c3b22089e63ade4b0a2213efe Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 2 Dec 2015 16:40:41 -0800 Subject: [PATCH 09/78] Plugins target frame rate and period. --- .../display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp | 3 ++- .../src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h | 6 ++++++ .../src/display-plugins/openvr/OpenVrDisplayPlugin.h | 5 +++++ libraries/plugins/src/plugins/DisplayPlugin.h | 2 ++ plugins/oculus/src/OculusDisplayPlugin.h | 5 +++++ plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h | 5 +++++ 6 files changed, 25 insertions(+), 1 deletion(-) diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 9366ec4403..b0dffbb7bc 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -139,7 +139,8 @@ void Basic2DWindowOpenGLDisplayPlugin::updateFramerate() { } else if (FRAMERATE_30 == actionText) { _framerateTarget = 30; } - } + } + _inverseFrameRate = _framerateTarget ? 1.0f / (float) _framerateTarget : 1.0f / TARGET_FRAMERATE_Basic2DWindowOpenGL; // not truncated int newInterval = getDesiredInterval(); qDebug() << newInterval; diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h index f4655ab79f..f6052f82ca 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h @@ -9,6 +9,8 @@ #include "WindowOpenGLDisplayPlugin.h" +#define TARGET_FRAMERATE_Basic2DWindowOpenGL 60.0f + class QScreen; class Basic2DWindowOpenGLDisplayPlugin : public WindowOpenGLDisplayPlugin { Q_OBJECT @@ -16,6 +18,9 @@ class Basic2DWindowOpenGLDisplayPlugin : public WindowOpenGLDisplayPlugin { public: virtual const QString & getName() const override; + virtual float getTargetFrameRate() { return _framerateTarget ? (float) _framerateTarget : TARGET_FRAMERATE_Basic2DWindowOpenGL; } + virtual float getTargetFramePeriod() { return _inverseFrameRate; } + virtual void activate() override; virtual void deactivate() override; @@ -33,4 +38,5 @@ private: QScreen* getFullscreenTarget(); uint32_t _framerateTarget{ 0 }; int _fullscreenTarget{ -1 }; + float _inverseFrameRate{ 1.0f }; //seconds }; diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h index 15d37d9de8..6116cd2283 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h @@ -14,12 +14,17 @@ #include "../WindowOpenGLDisplayPlugin.h" +#define TARGET_RATE_OpenVr 90.0f; // FIXME: get from sdk tracked device property? This number is vive-only. + class OpenVrDisplayPlugin : public WindowOpenGLDisplayPlugin { public: virtual bool isSupported() const override; virtual const QString & getName() const override; virtual bool isHmd() const override { return true; } + virtual float getTargetFrameRate() { return TARGET_RATE_OpenVr; } + virtual float getTargetFramePeriod() { return 1.0f / TARGET_RATE_OpenVr; } + virtual void activate() override; virtual void deactivate() override; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 5b00391f09..ea6060010e 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -57,6 +57,8 @@ public: /// By default, all HMDs are stereo virtual bool isStereo() const { return isHmd(); } virtual bool isThrottled() const { return false; } + virtual float getTargetFrameRate() { return 0.0f; } + virtual float getTargetFramePeriod() { return 0.0f; } // Rendering support diff --git a/plugins/oculus/src/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h index c1224ecf3a..62cdf35fc7 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.h +++ b/plugins/oculus/src/OculusDisplayPlugin.h @@ -12,12 +12,17 @@ struct SwapFramebufferWrapper; using SwapFboPtr = QSharedPointer; +#define TARGET_RATE_Oculus 75.0f; + class OculusDisplayPlugin : public OculusBaseDisplayPlugin { public: virtual void activate() override; virtual void deactivate() override; virtual const QString & getName() const override; + virtual float getTargetFrameRate() { return TARGET_RATE_Oculus; } + virtual float getTargetFramePeriod() { return 1.0f / TARGET_RATE_Oculus; } + protected: virtual void display(GLuint finalTexture, const glm::uvec2& sceneSize) override; virtual void customizeContext() override; diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h index 6e3f864aee..ca45e201f4 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h @@ -13,6 +13,8 @@ #include +#define TARGET_RATE_OculusLegacy 75.0f; + class OculusLegacyDisplayPlugin : public WindowOpenGLDisplayPlugin { public: OculusLegacyDisplayPlugin(); @@ -25,6 +27,9 @@ public: virtual bool eventFilter(QObject* receiver, QEvent* event) override; virtual int getHmdScreen() const override; + virtual float getTargetFrameRate() { return TARGET_RATE_OculusLegacy; } + virtual float getTargetFramePeriod() { return 1.0f / TARGET_RATE_OculusLegacy; } + // Stereo specific methods virtual bool isHmd() const override { return true; } virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const override; From 53bfcd17e2537c7930faa3221ab1c74de5a2a482 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 2 Dec 2015 16:41:16 -0800 Subject: [PATCH 10/78] Use plugins data for Application frame rate/period. --- interface/src/Application.cpp | 2 ++ interface/src/Application.h | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ef10ad4464..94aa3949cc 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3246,6 +3246,8 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node bool Application::isHMDMode() const { return getActiveDisplayPlugin()->isHmd(); } +float Application::getTargetFrameRate() { return getActiveDisplayPlugin()->getTargetFrameRate(); } +float Application::getTargetFramePeriod() { return getActiveDisplayPlugin()->getTargetFramePeriod(); } QRect Application::getDesirableApplicationGeometry() { QRect applicationGeometry = getWindow()->geometry(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 730158c689..adef152ac5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -159,10 +159,8 @@ public: bool isForeground() const { return _isForeground; } float getFps() const { return _fps; } - float const HMD_TARGET_FRAME_RATE = 75.0f; - float const DESKTOP_TARGET_FRAME_RATE = 60.0f; - float getTargetFrameRate() { return isHMDMode() ? HMD_TARGET_FRAME_RATE : DESKTOP_TARGET_FRAME_RATE; } - float getTargetFramePeriod() { return isHMDMode() ? 1.0f / HMD_TARGET_FRAME_RATE : 1.0f / DESKTOP_TARGET_FRAME_RATE; } // same as 1/getTargetFrameRate, but w/compile-time division + float getTargetFrameRate(); // frames/second + float getTargetFramePeriod(); // seconds float getLastInstanteousFps() const { return _lastInstantaneousFps; } float getLastPaintWait() const { return _lastPaintWait; }; float getLastDeducedNonVSyncFps() const { return _lastDeducedNonVSyncFps; } From ed86a880832d988e05b33b2c8e2b7739e309274b Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 2 Dec 2015 21:48:06 -0800 Subject: [PATCH 11/78] Make various forms of throttling more consistent and give it a chance of actually reaching target. --- .../Basic2DWindowOpenGLDisplayPlugin.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index b0dffbb7bc..ea8ffe1e2f 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -90,12 +90,8 @@ void Basic2DWindowOpenGLDisplayPlugin::display(GLuint sceneTexture, const glm::u int Basic2DWindowOpenGLDisplayPlugin::getDesiredInterval() const { - static const int THROTTLED_PAINT_TIMER_DELAY_MS = MSECS_PER_SECOND / 15; static const int ULIMIITED_PAINT_TIMER_DELAY_MS = 1; int result = ULIMIITED_PAINT_TIMER_DELAY_MS; - if (_isThrottled) { - result = THROTTLED_PAINT_TIMER_DELAY_MS; - } if (0 != _framerateTarget) { result = MSECS_PER_SECOND / _framerateTarget; } @@ -139,12 +135,18 @@ void Basic2DWindowOpenGLDisplayPlugin::updateFramerate() { } else if (FRAMERATE_30 == actionText) { _framerateTarget = 30; } + } else if (_isThrottled) { + _framerateTarget = 15; } _inverseFrameRate = _framerateTarget ? 1.0f / (float) _framerateTarget : 1.0f / TARGET_FRAMERATE_Basic2DWindowOpenGL; // not truncated int newInterval = getDesiredInterval(); + if (_framerateTarget) { // For any target other than vsync, we have little hope of achieving it with timer alone: + const int ALLOWANCE_FOR_DISPLAY_FINISHFRAME_AND_TIMER = 3; // ideally a windowed average of qApp->getLastPaintWait and then some, but not worth the complexity + newInterval -= ALLOWANCE_FOR_DISPLAY_FINISHFRAME_AND_TIMER; // Otherwise, any controller expecting us to hit "target" will always be disappointed. + } qDebug() << newInterval; - _timer.start(getDesiredInterval()); + _timer.start(newInterval); } // FIXME target the screen the window is currently on From a989b926b054fce73e694221646c2c8c385a5db0 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 3 Dec 2015 11:28:26 -0800 Subject: [PATCH 12/78] isVSynchronized, and proper override declarations. --- .../display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp | 9 +++++---- .../display-plugins/Basic2DWindowOpenGLDisplayPlugin.h | 5 +++-- .../src/display-plugins/openvr/OpenVrDisplayPlugin.h | 4 ++-- libraries/plugins/src/plugins/DisplayPlugin.h | 1 + plugins/oculus/src/OculusDisplayPlugin.h | 4 ++-- plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h | 4 ++-- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index ea8ffe1e2f..c0af5609ee 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -113,6 +113,9 @@ bool Basic2DWindowOpenGLDisplayPlugin::isThrottled() const { return shouldThrottle; } +bool Basic2DWindowOpenGLDisplayPlugin::isVSynchronized() const { + return (_framerateTarget == 0) && (!_vsyncAction || _vsyncAction->isChecked()); +} void Basic2DWindowOpenGLDisplayPlugin::updateFramerate() { QAction* checkedFramerate{ nullptr }; @@ -141,10 +144,8 @@ void Basic2DWindowOpenGLDisplayPlugin::updateFramerate() { _inverseFrameRate = _framerateTarget ? 1.0f / (float) _framerateTarget : 1.0f / TARGET_FRAMERATE_Basic2DWindowOpenGL; // not truncated int newInterval = getDesiredInterval(); - if (_framerateTarget) { // For any target other than vsync, we have little hope of achieving it with timer alone: - const int ALLOWANCE_FOR_DISPLAY_FINISHFRAME_AND_TIMER = 3; // ideally a windowed average of qApp->getLastPaintWait and then some, but not worth the complexity - newInterval -= ALLOWANCE_FOR_DISPLAY_FINISHFRAME_AND_TIMER; // Otherwise, any controller expecting us to hit "target" will always be disappointed. - } + // Note: when not isVSynchronized, we are often not likely to hit target with a newInterval timer. + // We could try subtracting an allowance for qApp->getLastPaintWait() and qt timer machinery, but that starts getting complicated. qDebug() << newInterval; _timer.start(newInterval); } diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h index f6052f82ca..45d2545a94 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h @@ -18,8 +18,8 @@ class Basic2DWindowOpenGLDisplayPlugin : public WindowOpenGLDisplayPlugin { public: virtual const QString & getName() const override; - virtual float getTargetFrameRate() { return _framerateTarget ? (float) _framerateTarget : TARGET_FRAMERATE_Basic2DWindowOpenGL; } - virtual float getTargetFramePeriod() { return _inverseFrameRate; } + virtual float getTargetFrameRate() override { return _framerateTarget ? (float) _framerateTarget : TARGET_FRAMERATE_Basic2DWindowOpenGL; } + virtual float getTargetFramePeriod() override { return _inverseFrameRate; } virtual void activate() override; virtual void deactivate() override; @@ -27,6 +27,7 @@ public: virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize) override; virtual bool isThrottled() const override; + virtual bool isVSynchronized() const override; protected: int getDesiredInterval() const; diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h index 6116cd2283..390ab4b539 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h @@ -22,8 +22,8 @@ public: virtual const QString & getName() const override; virtual bool isHmd() const override { return true; } - virtual float getTargetFrameRate() { return TARGET_RATE_OpenVr; } - virtual float getTargetFramePeriod() { return 1.0f / TARGET_RATE_OpenVr; } + virtual float getTargetFrameRate() override { return TARGET_RATE_OpenVr; } + virtual float getTargetFramePeriod() override { return 1.0f / TARGET_RATE_OpenVr; } virtual void activate() override; virtual void deactivate() override; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index ea6060010e..729b62f124 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -57,6 +57,7 @@ public: /// By default, all HMDs are stereo virtual bool isStereo() const { return isHmd(); } virtual bool isThrottled() const { return false; } + virtual bool isVSynchronized() const { return true; } // false when throttled or run by non vsync timer virtual float getTargetFrameRate() { return 0.0f; } virtual float getTargetFramePeriod() { return 0.0f; } diff --git a/plugins/oculus/src/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h index 62cdf35fc7..febfd5b08e 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.h +++ b/plugins/oculus/src/OculusDisplayPlugin.h @@ -20,8 +20,8 @@ public: virtual void deactivate() override; virtual const QString & getName() const override; - virtual float getTargetFrameRate() { return TARGET_RATE_Oculus; } - virtual float getTargetFramePeriod() { return 1.0f / TARGET_RATE_Oculus; } + virtual float getTargetFrameRate() override { return TARGET_RATE_Oculus; } + virtual float getTargetFramePeriod() override { return 1.0f / TARGET_RATE_Oculus; } protected: virtual void display(GLuint finalTexture, const glm::uvec2& sceneSize) override; diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h index ca45e201f4..d0840d3a72 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h @@ -27,8 +27,8 @@ public: virtual bool eventFilter(QObject* receiver, QEvent* event) override; virtual int getHmdScreen() const override; - virtual float getTargetFrameRate() { return TARGET_RATE_OculusLegacy; } - virtual float getTargetFramePeriod() { return 1.0f / TARGET_RATE_OculusLegacy; } + virtual float getTargetFrameRate() override { return TARGET_RATE_OculusLegacy; } + virtual float getTargetFramePeriod() override { return 1.0f / TARGET_RATE_OculusLegacy; } // Stereo specific methods virtual bool isHmd() const override { return true; } From 375211e13b454d64fc7b2d8a33c915119cc5b043 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 3 Dec 2015 11:29:13 -0800 Subject: [PATCH 13/78] Use isVSynchronized in controller. --- interface/src/Application.cpp | 1 + interface/src/Application.h | 1 + interface/src/avatar/AvatarManager.cpp | 22 +++++++++++++++------- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 94aa3949cc..921c126ce6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3248,6 +3248,7 @@ bool Application::isHMDMode() const { } float Application::getTargetFrameRate() { return getActiveDisplayPlugin()->getTargetFrameRate(); } float Application::getTargetFramePeriod() { return getActiveDisplayPlugin()->getTargetFramePeriod(); } +bool Application::isVSynchronized() const { return getActiveDisplayPlugin()->isVSynchronized(); } QRect Application::getDesirableApplicationGeometry() { QRect applicationGeometry = getWindow()->geometry(); diff --git a/interface/src/Application.h b/interface/src/Application.h index adef152ac5..5c952f462e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -124,6 +124,7 @@ public: PickRay computePickRay() const; bool isThrottleRendering() const; + bool isVSynchronized() const; Camera* getCamera() { return &_myCamera; } // Represents the current view frustum of the avatar. diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index e094f2e263..0ee07d15ec 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -146,13 +146,21 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { PerformanceTimer perfTimer("otherAvatars"); - _renderDistanceController.setMeasuredValueSetpoint(qApp->getTargetFrameRate()); // No problem updating in flight. - // The PID controller raises the controlled value when the measured value goes up. - // The measured value is frame rate. When the controlled value (1 / render cutoff distance) - // goes up, the render cutoff distance gets closer, the number of rendered avatars is less, and frame rate - // goes up. - const float deduced = qApp->getLastDeducedNonVSyncFps(); - const float distance = 1.0f / _renderDistanceController.update(deduced, deltaTime); + float distance; + if (qApp->isVSynchronized()) { + _renderDistanceController.setMeasuredValueSetpoint(qApp->getTargetFrameRate()); // No problem updating in flight. + // The PID controller raises the controlled value when the measured value goes up. + // The measured value is frame rate. When the controlled value (1 / render cutoff distance) + // goes up, the render cutoff distance gets closer, the number of rendered avatars is less, and frame rate + // goes up. + const float deduced = qApp->getLastDeducedNonVSyncFps(); + distance = 1.0f / _renderDistanceController.update(deduced, deltaTime); + } else { + // We could keep the controller running when not vsync'd, if getLastDeducedNonVSyncFps is still meaningful. + // But the basic 2d controller doesn't try to adjust the timer for qt load or getLastPaintWait, so running the + // Here we choose to just use the maximum render cutoff distance if: throttled, running without vsync, or 30-60 "fixed" targets. + distance = 1.0f / _renderDistanceController.getControlledValueLowLimit(); + } _renderDistanceAverage.updateAverage(distance); _renderDistance = _renderDistanceAverage.getAverage(); int renderableCount = 0; From 30bbc82c245ddd357bb3f54abd9046f0c9f63a05 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 3 Dec 2015 13:00:07 -0800 Subject: [PATCH 14/78] Restore throttling interval code. --- .../display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index c0af5609ee..8633628fef 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -88,10 +88,15 @@ void Basic2DWindowOpenGLDisplayPlugin::display(GLuint sceneTexture, const glm::u WindowOpenGLDisplayPlugin::display(sceneTexture, sceneSize); } - +#define THROTTLED_FRAMERATE 15 int Basic2DWindowOpenGLDisplayPlugin::getDesiredInterval() const { static const int ULIMIITED_PAINT_TIMER_DELAY_MS = 1; int result = ULIMIITED_PAINT_TIMER_DELAY_MS; + // This test wouldn't be necessary if we could depend on updateFramerate setting _framerateTarget. + // Alas, that gets complicated: isThrottled() is const and other stuff depends on it. + if (_isThrottled) { + result = MSECS_PER_SECOND / THROTTLED_FRAMERATE; + } if (0 != _framerateTarget) { result = MSECS_PER_SECOND / _framerateTarget; } @@ -139,7 +144,7 @@ void Basic2DWindowOpenGLDisplayPlugin::updateFramerate() { _framerateTarget = 30; } } else if (_isThrottled) { - _framerateTarget = 15; + _framerateTarget = (float) THROTTLED_FRAMERATE; } _inverseFrameRate = _framerateTarget ? 1.0f / (float) _framerateTarget : 1.0f / TARGET_FRAMERATE_Basic2DWindowOpenGL; // not truncated From f5b25791f466402549cdaaa066d1519854ad0532 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Thu, 3 Dec 2015 13:39:41 -0800 Subject: [PATCH 15/78] When throttling starts, we won't have noticed, so change test. --- .../src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 8633628fef..b3719265ea 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -119,7 +119,7 @@ bool Basic2DWindowOpenGLDisplayPlugin::isThrottled() const { } bool Basic2DWindowOpenGLDisplayPlugin::isVSynchronized() const { - return (_framerateTarget == 0) && (!_vsyncAction || _vsyncAction->isChecked()); + return (_framerateTarget == 0) && !_isThrottled; } void Basic2DWindowOpenGLDisplayPlugin::updateFramerate() { From df413c0b14a1f87b221f021ba83997e470a920a8 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 7 Dec 2015 09:31:06 -0800 Subject: [PATCH 16/78] Temporary debugging aids. --- libraries/shared/src/PIDController.cpp | 10 ++++++---- libraries/shared/src/PIDController.h | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/libraries/shared/src/PIDController.cpp b/libraries/shared/src/PIDController.cpp index a853553b89..36c670e66d 100644 --- a/libraries/shared/src/PIDController.cpp +++ b/libraries/shared/src/PIDController.cpp @@ -14,7 +14,7 @@ #include "SharedLogging.h" #include "PIDController.h" -float PIDController::update(float measuredValue, float dt, bool resetAccumulator) { +float PIDController::update(float measuredValue, float dt, bool resetAccumulator, float fixme1, float fixme2) { const float error = getMeasuredValueSetpoint() - measuredValue; // Sign is the direction we want measuredValue to go. Positive means go higher. const float p = getKP() * error; // term is Proportional to error @@ -32,7 +32,7 @@ float PIDController::update(float measuredValue, float dt, bool resetAccumulator getControlledValueHighLimit()); if (getIsLogging()) { // if logging/reporting - updateHistory(measuredValue, dt, error, accumulatedError, changeInError, p, i, d, computedValue); + updateHistory(measuredValue, dt, error, accumulatedError, changeInError, p, i, d, computedValue, fixme1, fixme2); } Q_ASSERT(!isnan(computedValue)); @@ -43,7 +43,7 @@ float PIDController::update(float measuredValue, float dt, bool resetAccumulator } // Just for logging/reporting. Used when picking/verifying the operational parameters. -void PIDController::updateHistory(float measuredValue, float dt, float error, float accumulatedError, float changeInError, float p, float i, float d, float computedValue) { +void PIDController::updateHistory(float measuredValue, float dt, float error, float accumulatedError, float changeInError, float p, float i, float d, float computedValue, float fixme1, float fixme2) { // Don't report each update(), as the I/O messes with the results a lot. // Instead, add to history, and then dump out at once when full. // Typically, the first few values reported in each batch should be ignored. @@ -59,16 +59,18 @@ void PIDController::updateHistory(float measuredValue, float dt, float error, fl next.i = i; next.d = d; next.computed = computedValue; + next.fixme1 = fixme1; next.fixme2 = fixme2; if (_history.size() == _history.capacity()) { // report when buffer is full reportHistory(); _history.resize(0); } } void PIDController::reportHistory() { - qCDebug(shared) << _label << "measured dt FIXME || error accumulated changed || p i d controlled"; + qCDebug(shared) << _label << "measured dt || error accumulated changed || p i d controlled"; for (int i = 0; i < _history.size(); i++) { Row& row = _history[i]; qCDebug(shared) << row.measured << row.dt << + row.fixme1 << row.fixme2 << "||" << row.error << row.accumulated << row.changed << "||" << row.p << row.i << row.d << row.computed << 1.0f/row.computed; } diff --git a/libraries/shared/src/PIDController.h b/libraries/shared/src/PIDController.h index 0b2411530a..24e619b13b 100644 --- a/libraries/shared/src/PIDController.h +++ b/libraries/shared/src/PIDController.h @@ -28,7 +28,7 @@ class PIDController { public: // These are the main interfaces: void setMeasuredValueSetpoint(float newValue) { _measuredValueSetpoint = newValue; } - float update(float measuredValue, float dt, bool resetAccumulator = false); // returns the new computedValue + float update(float measuredValue, float dt, bool resetAccumulator = false, float fixme1=0, float fixme2=0); // returns the new computedValue void setHistorySize(QString label = QString(""), int size = 0) { _history.reserve(size); _history.resize(0); _label = label; } // non-empty does logging bool getIsLogging() { return _history.capacity(); } @@ -64,10 +64,11 @@ public: float i; float d; float computed; + float fixme1; float fixme2; }; protected: void reportHistory(); - void updateHistory(float measured, float dt, float error, float accumulatedError, float changeInErro, float p, float i, float d, float computedValue); + void updateHistory(float measured, float dt, float error, float accumulatedError, float changeInErro, float p, float i, float d, float computedValue, float fixme1, float fixme2); float _measuredValueSetpoint { 0.0f }; float _controlledValueLowLimit { 0.0f }; float _controlledValueHighLimit { std::numeric_limits::max() }; From 34de4d67d80f6e9337d3f28ce6bc3dcf29ffcfba Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 7 Dec 2015 09:32:12 -0800 Subject: [PATCH 17/78] DisplayPlugin::getLastSynchronizedElapsed --- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 6 ++++++ .../src/display-plugins/OpenGLDisplayPlugin.h | 4 ++++ libraries/plugins/src/plugins/DisplayPlugin.h | 1 + 3 files changed, 11 insertions(+) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index d306c23dc0..4668f8ba1a 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -156,8 +156,10 @@ OpenGLDisplayPlugin::OpenGLDisplayPlugin() { _container->releaseOverlayTexture(texture); }); + _synchronizedTimer.start(); connect(&_timer, &QTimer::timeout, this, [&] { if (_active && _sceneTextureEscrow.depth() <= 1) { + _synchronizedTimer.start(); emit requestRender(); } }); @@ -279,6 +281,10 @@ void OpenGLDisplayPlugin::submitOverlayTexture(GLuint sceneTexture, const glm::u } void OpenGLDisplayPlugin::updateTextures() { + const qint64 elapsed =_synchronizedTimer.elapsed(); + if (elapsed != 0) { + _lastSynchronizedElapsed = elapsed; + } _currentSceneTexture = _sceneTextureEscrow.fetchAndRelease(_currentSceneTexture); _currentOverlayTexture = _overlayTextureEscrow.fetchAndRelease(_currentOverlayTexture); } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index ef78374994..4577777034 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -10,6 +10,7 @@ #include "DisplayPlugin.h" #include +#include #include #include @@ -30,6 +31,7 @@ public: virtual void submitSceneTexture(uint32_t frameIndex, uint32_t sceneTexture, const glm::uvec2& sceneSize) override; virtual void submitOverlayTexture(uint32_t overlayTexture, const glm::uvec2& overlaySize) override; virtual float presentRate() override; + virtual qint64 getLastSynchronizedElapsed() { return _lastSynchronizedElapsed; } virtual glm::uvec2 getRecommendedRenderSize() const override { return getSurfacePixels(); @@ -68,6 +70,8 @@ protected: virtual void internalPresent(); mutable QTimer _timer; + QElapsedTimer _synchronizedTimer; + qint64 _lastSynchronizedElapsed { 0 }; ProgramPtr _program; ShapeWrapperPtr _plane; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 83afbc9402..6fc6062214 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -58,6 +58,7 @@ public: /// By default, all HMDs are stereo virtual bool isStereo() const { return isHmd(); } virtual bool isThrottled() const { return false; } + virtual qint64 getLastSynchronizedElapsed() { return 0; } // Rendering support From 1d4cc7c9847bbf615b40e9647e7a13e564e6f181 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 7 Dec 2015 10:01:46 -0800 Subject: [PATCH 18/78] Checkpoint exploring use of getLastSynchronizedElapsed and fixing paintWait (which may go away). --- interface/src/Application.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9e98b51442..3af0e6d39b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1126,9 +1126,9 @@ void Application::paintGL() { // Time between previous paintGL call and this one, which can vary not only with vSync misses, but also with QT timing. // We're using this as a proxy for the time between vsync and displayEnd, below. (Not exact, but tends to be the same over time.) // This is not the same as update(deltaTime), because the latter attempts to throttle to 60hz and also clamps to 1/4 second. - const float actualPeriod = diff / (float)USECS_PER_SECOND; // same as 1/instantaneousFps but easier for compiler to optimize + //const float actualPeriod = diff / (float)USECS_PER_SECOND; // same as 1/instantaneousFps but easier for compiler to optimize // Note that _lastPaintWait (stored at end of last call) is for the same paint cycle. - float deducedNonVSyncPeriod = actualPeriod - _lastPaintWait + _marginForDeducedFramePeriod; // plus a some non-zero time for machinery we can't measure + float deducedNonVSyncPeriod = (float) getActiveDisplayPlugin()->getLastSynchronizedElapsed() / (float) MSECS_PER_SECOND; /*actualPeriod - _lastPaintWait + _marginForDeducedFramePeriod; // plus a some non-zero time for machinery we can't measure // We don't know how much time to allow for that, but if we went over the target period, we know it's at least the portion // of paintWait up to the next vSync. This gives us enough of a penalty so that when actualPeriod crosses two cycles, // the key part (and not an exagerated part) of _lastPaintWait is accounted for. @@ -1136,7 +1136,7 @@ void Application::paintGL() { if (_lastPaintWait > EPSILON && actualPeriod > targetPeriod) { // Don't use C++ remainder(). It's authors are mathematically insane. deducedNonVSyncPeriod += fmod(actualPeriod, _lastPaintWait); - } + }*/ _lastDeducedNonVSyncFps = 1.0f / deducedNonVSyncPeriod; _lastInstantaneousFps = instantaneousFps; @@ -1375,6 +1375,7 @@ void Application::paintGL() { } // deliver final composited scene to the display plugin + uint64_t displayStart = usecTimestampNow(); { PROFILE_RANGE(__FUNCTION__ "/pluginOutput"); PerformanceTimer perfTimer("pluginOutput"); @@ -1396,7 +1397,6 @@ void Application::paintGL() { Q_ASSERT(!_lockedFramebufferMap.contains(finalTexture)); _lockedFramebufferMap[finalTexture] = scratchFramebuffer; - uint64_t displayStart = usecTimestampNow(); Q_ASSERT(QOpenGLContext::currentContext() == _offscreenContext->getContext()); { PROFILE_RANGE(__FUNCTION__ "/pluginSubmitScene"); @@ -1404,10 +1404,6 @@ void Application::paintGL() { displayPlugin->submitSceneTexture(_frameCount, finalTexture, toGlm(size)); } Q_ASSERT(QOpenGLContext::currentContext() == _offscreenContext->getContext()); - - uint64_t displayEnd = usecTimestampNow(); - const float displayPeriodUsec = (float)(displayEnd - displayStart); // usecs - _lastPaintWait = displayPeriodUsec / (float)USECS_PER_SECOND; } { @@ -1418,6 +1414,9 @@ void Application::paintGL() { batch.resetStages(); }); } + uint64_t displayEnd = usecTimestampNow(); + const float displayPeriodUsec = (float)(displayEnd - displayStart); // usecs + _lastPaintWait = displayPeriodUsec / (float)USECS_PER_SECOND; } void Application::runTests() { From 17ecf9b6b70e027ecd9656bbea59418bfbc029ec Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 7 Dec 2015 11:26:56 -0800 Subject: [PATCH 19/78] debugging --- interface/src/avatar/AvatarManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 7aa5073921..35b5db7946 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -111,7 +111,7 @@ void AvatarManager::init() { _renderDistanceController.setKP(0.0008f); // Usually about 0.6 of largest that doesn't oscillate when other parameters 0. _renderDistanceController.setKI(0.0006f); // Big enough to bring us to target with the above KP. _renderDistanceController.setKD(0.000001f); // A touch of kd increases the speed by which we get there. - + a_renderDistanceController.setHistorySize("av", 240); //FIXME } void AvatarManager::updateMyAvatar(float deltaTime) { @@ -152,7 +152,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { // goes up, the render cutoff distance gets closer, the number of rendered avatars is less, and frame rate // goes up. const float deduced = qApp->getLastDeducedNonVSyncFps(); - const float distance = 1.0f / _renderDistanceController.update(deduced, deltaTime); + const float distance = 1.0f / _renderDistanceController.update(deduced, deltaTime, false, qApp->getLastPaintWait(), qApp->getLastInstanteousFps()); _renderDistanceAverage.updateAverage(distance); _renderDistance = _renderDistanceAverage.getAverage(); int renderableCount = 0; From e9f21b4dba79fa8e81c22b4c2d110449f23735dc Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 7 Dec 2015 11:30:10 -0800 Subject: [PATCH 20/78] make lights parented to flashlight instead of updated in loop --- examples/toybox/flashlight/flashlight.js | 47 ++++++++++-------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/examples/toybox/flashlight/flashlight.js b/examples/toybox/flashlight/flashlight.js index 8911c0ecd8..2640ff0bff 100644 --- a/examples/toybox/flashlight/flashlight.js +++ b/examples/toybox/flashlight/flashlight.js @@ -25,7 +25,7 @@ //we are creating lights that we don't want to get stranded so lets make sure that we can get rid of them var startTime = Date.now(); //if you're going to be using this in a dungeon or something and holding it for a long time, increase this lifetime value. - var LIFETIME = 25; + var LIFETIME = 100; var MSEC_PER_SEC = 1000.0; // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember @@ -85,9 +85,16 @@ this.hand = 'LEFT'; }, - startNearGrab: function() { + startNearGrab: function(entityID) { + print('id on grab',entityID) if (!this.hasSpotlight) { + print('CREATING LIGHTS', this.entityID) + var modelProperties = Entities.getEntityProperties(this.entityID, ['position', 'rotation']); + var lightTransform = evalLightWorldTransform(modelProperties.position, modelProperties.rotation); + var glowLightTransform = glowLightWorldTransform(modelProperties.position, modelProperties.rotation); + + //this light casts the beam this.spotlight = Entities.addEntity({ type: "Light", @@ -97,6 +104,7 @@ y: 2, z: 20 }, + parentID: this.entityID, color: { red: 255, green: 255, @@ -105,7 +113,9 @@ intensity: 2, exponent: 0.3, cutoff: 20, - lifetime: LIFETIME + lifetime: LIFETIME, + position: lightTransform.p, + rotation: lightTransform.q, }); //this light creates the effect of a bulb at the end of the flashlight @@ -116,6 +126,7 @@ y: 0.25, z: 0.25 }, + parentID: this.entityID, isSpotlight: false, color: { red: 255, @@ -123,8 +134,11 @@ blue: 255 }, exponent: 0, + lifetime: LIFETIME, cutoff: 90, // in degrees - lifetime: LIFETIME + position: glowLightTransform.p, + rotation: glowLightTransform.q, + }); this.hasSpotlight = true; @@ -142,7 +156,6 @@ //only set the active hand once -- if we always read the current hand, our 'holding' hand will get overwritten this.setWhichHand(); } else { - this.updateLightPositions(); this.changeLightWithTriggerPressure(this.whichHand); } }, @@ -159,29 +172,7 @@ this.lightOn = false; } }, - - updateLightPositions: function() { - var modelProperties = Entities.getEntityProperties(this.entityID, ['position', 'rotation']); - - //move the two lights along the vectors we set above - var lightTransform = evalLightWorldTransform(modelProperties.position, modelProperties.rotation); - var glowLightTransform = glowLightWorldTransform(modelProperties.position, modelProperties.rotation); - - //move them with the entity model - Entities.editEntity(this.spotlight, { - position: lightTransform.p, - rotation: lightTransform.q, - lifetime: (Date.now() - startTime) / MSEC_PER_SEC + LIFETIME - }); - - Entities.editEntity(this.glowLight, { - position: glowLightTransform.p, - rotation: glowLightTransform.q, - lifetime: (Date.now() - startTime) / MSEC_PER_SEC + LIFETIME - }); - - }, - + changeLightWithTriggerPressure: function(flashLightHand) { if (flashLightHand === 'LEFT') { From 27ce0a36d3e6f6fcc0c21155443bc73d6ad853fa Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 7 Dec 2015 12:20:06 -0800 Subject: [PATCH 21/78] cleanup logging --- examples/toybox/flashlight/flashlight.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/toybox/flashlight/flashlight.js b/examples/toybox/flashlight/flashlight.js index 2640ff0bff..251ca71b7a 100644 --- a/examples/toybox/flashlight/flashlight.js +++ b/examples/toybox/flashlight/flashlight.js @@ -86,10 +86,8 @@ }, startNearGrab: function(entityID) { - print('id on grab',entityID) if (!this.hasSpotlight) { - print('CREATING LIGHTS', this.entityID) var modelProperties = Entities.getEntityProperties(this.entityID, ['position', 'rotation']); var lightTransform = evalLightWorldTransform(modelProperties.position, modelProperties.rotation); var glowLightTransform = glowLightWorldTransform(modelProperties.position, modelProperties.rotation); From 8683bb5002915c05645b9dacbebe6fc24dd19307 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Mon, 7 Dec 2015 13:05:30 -0800 Subject: [PATCH 22/78] New reverb parameters --- examples/utilities/tools/reverbTest.js | 60 +++++--- libraries/audio-client/src/AudioClient.cpp | 74 ++++++---- libraries/audio/src/AudioEffectOptions.cpp | 149 ++++++++++++-------- libraries/audio/src/AudioEffectOptions.h | 154 +++++++++++++-------- 4 files changed, 277 insertions(+), 160 deletions(-) diff --git a/examples/utilities/tools/reverbTest.js b/examples/utilities/tools/reverbTest.js index 32c28a993f..2b08073ae0 100644 --- a/examples/utilities/tools/reverbTest.js +++ b/examples/utilities/tools/reverbTest.js @@ -12,31 +12,57 @@ Script.include("cookies.js"); var audioOptions = new AudioEffectOptions({ - maxRoomSize: 50, + bandwidth: 10000, + preDelay: 20, + lateDelay: 0, + reverbTime: 2, + earlyDiffusion: 100, + lateDiffusion: 100, roomSize: 50, - reverbTime: 4, - damping: 0.50, - inputBandwidth: 0.8, - earlyLevel: 0, - tailLevel: 0, - dryLevel: -6, - wetLevel: -6 + density: 100, + bassMult: 1.5, + bassFreq: 250, + highGain: -6, + highFreq: 3000, + modRate: 2.3, + modDepth: 50, + earlyGain: 0, + lateGain: 0, + earlyMixLeft: 20, + earlyMixRight: 20, + lateMixLeft: 90, + lateMixRight: 90, + wetDryMix: 50, }); AudioDevice.setReverbOptions(audioOptions); AudioDevice.setReverb(true); print("Reverb is ON."); -var panel = new Panel(10, 200); +var panel = new Panel(10, 150); var parameters = [ - { name: "roomSize", min: 0, max: 100, units: " feet" }, - { name: "reverbTime", min: 0, max: 10, units: " sec" }, - { name: "damping", min: 0, max: 1, units: " " }, - { name: "inputBandwidth", min: 0, max: 1, units: " " }, - { name: "earlyLevel", min: -48, max: 0, units: " dB" }, - { name: "tailLevel", min: -48, max: 0, units: " dB" }, - { name: "wetLevel", min: -48, max: 0, units: " dB" }, + { name: "bandwidth", min: 1000, max: 12000, units: " Hz" }, + { name: "preDelay", min: 0, max: 333, units: " ms" }, + { name: "lateDelay", min: 0, max: 166, units: " ms" }, + { name: "reverbTime", min: 0.1, max: 10, units: " seconds" }, + { name: "earlyDiffusion", min: 0, max: 100, units: " percent" }, + { name: "lateDiffusion", min: 0, max: 100, units: " percent" }, + { name: "roomSize", min: 0, max: 100, units: " percent" }, + { name: "density", min: 0, max: 100, units: " percent" }, + { name: "bassMult", min: 0.1, max: 4, units: " ratio" }, + { name: "bassFreq", min: 10, max: 500, units: " Hz" }, + { name: "highGain", min: -24, max: 0, units: " dB" }, + { name: "highFreq", min: 1000, max: 12000, units: " Hz" }, + { name: "modRate", min: 0.1, max: 10, units: " Hz" }, + { name: "modDepth", min: 0, max: 100, units: " percent" }, + { name: "earlyGain", min: -96, max: 24, units: " dB" }, + { name: "lateGain", min: -96, max: 24, units: " dB" }, + { name: "earlyMixLeft", min: 0, max: 100, units: " percent" }, + { name: "earlyMixRight", min: 0, max: 100, units: " percent" }, + { name: "lateMixLeft", min: 0, max: 100, units: " percent" }, + { name: "lateMixRight", min: 0, max: 100, units: " percent" }, + { name: "wetDryMix", min: 0, max: 100, units: " percent" }, ] function setter(name) { @@ -48,7 +74,7 @@ function getter(name) { } function displayer(units) { - return function(value) { return (value).toFixed(1) + units; }; + return function(value) { return (value).toFixed(1) + units; } } // create a slider for each parameter diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index b141c70272..23e00c85cd 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -541,26 +541,40 @@ bool AudioClient::switchOutputToAudioDevice(const QString& outputDeviceName) { void AudioClient::configureReverb() { ReverbParameters p; - _listenerReverb.getParameters(&p); - - // for now, reuse the gverb parameters p.sampleRate = _outputFormat.sampleRate(); - p.roomSize = _reverbOptions->getRoomSize(); + + p.bandwidth = _reverbOptions->getBandwidth(); + p.preDelay = _reverbOptions->getPreDelay(); + p.lateDelay = _reverbOptions->getLateDelay(); p.reverbTime = _reverbOptions->getReverbTime(); - p.highGain = -24.0f * (1.0f - _reverbOptions->getDamping()); - p.bandwidth = 10000.0f * _reverbOptions->getInputBandwidth(); - p.earlyGain = _reverbOptions->getEarlyLevel(); - p.lateGain = _reverbOptions->getTailLevel(); - p.wetDryMix = 100.0f * powf(10.0f, _reverbOptions->getWetLevel() * (1/20.0f)); + p.earlyDiffusion = _reverbOptions->getEarlyDiffusion(); + p.lateDiffusion = _reverbOptions->getLateDiffusion(); + p.roomSize = _reverbOptions->getRoomSize(); + p.density = _reverbOptions->getDensity(); + p.bassMult = _reverbOptions->getBassMult(); + p.bassFreq = _reverbOptions->getBassFreq(); + p.highGain = _reverbOptions->getHighGain(); + p.highFreq = _reverbOptions->getHighFreq(); + p.modRate = _reverbOptions->getModRate(); + p.modDepth = _reverbOptions->getModDepth(); + p.earlyGain = _reverbOptions->getEarlyGain(); + p.lateGain = _reverbOptions->getLateGain(); + p.earlyMixLeft = _reverbOptions->getEarlyMixLeft(); + p.earlyMixRight = _reverbOptions->getEarlyMixRight(); + p.lateMixLeft = _reverbOptions->getLateMixLeft(); + p.lateMixRight = _reverbOptions->getLateMixRight(); + p.wetDryMix = _reverbOptions->getWetDryMix(); + _listenerReverb.setParameters(&p); - // used for adding self-reverb to loopback audio + // used only for adding self-reverb to loopback audio p.wetDryMix = 100.0f; p.preDelay = 0.0f; p.earlyGain = -96.0f; // disable ER - p.lateGain -= 12.0f; // quieter than listener reverb + p.lateGain -= 12.0f; // quieter than listener reverb p.lateMixLeft = 0.0f; p.lateMixRight = 0.0f; + _sourceReverb.setParameters(&p); } @@ -572,10 +586,10 @@ void AudioClient::updateReverbOptions() { _zoneReverbOptions.setReverbTime(_receivedAudioStream.getRevebTime()); reverbChanged = true; } - if (_zoneReverbOptions.getWetLevel() != _receivedAudioStream.getWetLevel()) { - _zoneReverbOptions.setWetLevel(_receivedAudioStream.getWetLevel()); - reverbChanged = true; - } + //if (_zoneReverbOptions.getWetLevel() != _receivedAudioStream.getWetLevel()) { + // _zoneReverbOptions.setWetLevel(_receivedAudioStream.getWetLevel()); + // reverbChanged = true; + //} if (_reverbOptions != &_zoneReverbOptions) { _reverbOptions = &_zoneReverbOptions; @@ -602,17 +616,27 @@ void AudioClient::setReverb(bool reverb) { void AudioClient::setReverbOptions(const AudioEffectOptions* options) { // Save the new options - _scriptReverbOptions.setMaxRoomSize(options->getMaxRoomSize()); - _scriptReverbOptions.setRoomSize(options->getRoomSize()); + _scriptReverbOptions.setBandwidth(options->getBandwidth()); + _scriptReverbOptions.setPreDelay(options->getPreDelay()); + _scriptReverbOptions.setLateDelay(options->getLateDelay()); _scriptReverbOptions.setReverbTime(options->getReverbTime()); - _scriptReverbOptions.setDamping(options->getDamping()); - _scriptReverbOptions.setSpread(options->getSpread()); - _scriptReverbOptions.setInputBandwidth(options->getInputBandwidth()); - _scriptReverbOptions.setEarlyLevel(options->getEarlyLevel()); - _scriptReverbOptions.setTailLevel(options->getTailLevel()); - - _scriptReverbOptions.setDryLevel(options->getDryLevel()); - _scriptReverbOptions.setWetLevel(options->getWetLevel()); + _scriptReverbOptions.setEarlyDiffusion(options->getEarlyDiffusion()); + _scriptReverbOptions.setLateDiffusion(options->getLateDiffusion()); + _scriptReverbOptions.setRoomSize(options->getRoomSize()); + _scriptReverbOptions.setDensity(options->getDensity()); + _scriptReverbOptions.setBassMult(options->getBassMult()); + _scriptReverbOptions.setBassFreq(options->getBassFreq()); + _scriptReverbOptions.setHighGain(options->getHighGain()); + _scriptReverbOptions.setHighFreq(options->getHighFreq()); + _scriptReverbOptions.setModRate(options->getModRate()); + _scriptReverbOptions.setModDepth(options->getModDepth()); + _scriptReverbOptions.setEarlyGain(options->getEarlyGain()); + _scriptReverbOptions.setLateGain(options->getLateGain()); + _scriptReverbOptions.setEarlyMixLeft(options->getEarlyMixLeft()); + _scriptReverbOptions.setEarlyMixRight(options->getEarlyMixRight()); + _scriptReverbOptions.setLateMixLeft(options->getLateMixLeft()); + _scriptReverbOptions.setLateMixRight(options->getLateMixRight()); + _scriptReverbOptions.setWetDryMix(options->getWetDryMix()); if (_reverbOptions == &_scriptReverbOptions) { // Apply them to the reverb instances diff --git a/libraries/audio/src/AudioEffectOptions.cpp b/libraries/audio/src/AudioEffectOptions.cpp index a61213d9c4..792799b776 100644 --- a/libraries/audio/src/AudioEffectOptions.cpp +++ b/libraries/audio/src/AudioEffectOptions.cpp @@ -10,58 +10,76 @@ #include "AudioEffectOptions.h" -static const QString MAX_ROOM_SIZE_HANDLE = "maxRoomSize"; -static const QString ROOM_SIZE_HANDLE = "roomSize"; +static const QString BANDWIDTH_HANDLE = "bandwidth"; +static const QString PRE_DELAY_HANDLE = "preDelay"; +static const QString LATE_DELAY_HANDLE = "lateDelay"; static const QString REVERB_TIME_HANDLE = "reverbTime"; -static const QString DAMPIMG_HANDLE = "damping"; -static const QString SPREAD_HANDLE = "spread"; -static const QString INPUT_BANDWIDTH_HANDLE = "inputBandwidth"; -static const QString EARLY_LEVEL_HANDLE = "earlyLevel"; -static const QString TAIL_LEVEL_HANDLE = "tailLevel"; -static const QString DRY_LEVEL_HANDLE = "dryLevel"; -static const QString WET_LEVEL_HANDLE = "wetLevel"; +static const QString EARLY_DIFFUSION_HANDLE = "earlyDiffusion"; +static const QString LATE_DIFFUSION_HANDLE = "lateDiffusion"; +static const QString ROOM_SIZE_HANDLE = "roomSize"; +static const QString DENSITY_HANDLE = "density"; +static const QString BASS_MULT_HANDLE = "bassMult"; +static const QString BASS_FREQ_HANDLE = "bassFreq"; +static const QString HIGH_GAIN_HANDLE = "highGain"; +static const QString HIGH_FREQ_HANDLE = "highFreq"; +static const QString MOD_RATE_HANDLE = "modRate"; +static const QString MOD_DEPTH_HANDLE = "modDepth"; +static const QString EARLY_GAIN_HANDLE = "earlyGain"; +static const QString LATE_GAIN_HANDLE = "lateGain"; +static const QString EARLY_MIX_LEFT_HANDLE = "earlyMixLeft"; +static const QString EARLY_MIX_RIGHT_HANDLE = "earlyMixRight"; +static const QString LATE_MIX_LEFT_HANDLE = "lateMixLeft"; +static const QString LATE_MIX_RIGHT_HANDLE = "lateMixRight"; +static const QString WET_DRY_MIX_HANDLE = "wetDryMix"; -AudioEffectOptions::AudioEffectOptions(QScriptValue arguments) : - _maxRoomSize(50.0f), - _roomSize(50.0f), - _reverbTime(4.0f), - _damping(0.5f), - _spread(15.0f), - _inputBandwidth(0.75f), - _earlyLevel(-12.0f), - _tailLevel(-18.0f), - _dryLevel(0.0f), - _wetLevel(0.0f) { - if (arguments.property(MAX_ROOM_SIZE_HANDLE).isNumber()) { - _maxRoomSize = arguments.property(MAX_ROOM_SIZE_HANDLE).toNumber(); - } - if (arguments.property(ROOM_SIZE_HANDLE).isNumber()) { - _roomSize = arguments.property(ROOM_SIZE_HANDLE).toNumber(); - } - if (arguments.property(REVERB_TIME_HANDLE).isNumber()) { - _reverbTime = arguments.property(REVERB_TIME_HANDLE).toNumber(); - } - if (arguments.property(DAMPIMG_HANDLE).isNumber()) { - _damping = arguments.property(DAMPIMG_HANDLE).toNumber(); - } - if (arguments.property(SPREAD_HANDLE).isNumber()) { - _spread = arguments.property(SPREAD_HANDLE).toNumber(); - } - if (arguments.property(INPUT_BANDWIDTH_HANDLE).isNumber()) { - _inputBandwidth = arguments.property(INPUT_BANDWIDTH_HANDLE).toNumber(); - } - if (arguments.property(EARLY_LEVEL_HANDLE).isNumber()) { - _earlyLevel = arguments.property(EARLY_LEVEL_HANDLE).toNumber(); - } - if (arguments.property(TAIL_LEVEL_HANDLE).isNumber()) { - _tailLevel = arguments.property(TAIL_LEVEL_HANDLE).toNumber(); - } - if (arguments.property(DRY_LEVEL_HANDLE).isNumber()) { - _dryLevel = arguments.property(DRY_LEVEL_HANDLE).toNumber(); - } - if (arguments.property(WET_LEVEL_HANDLE).isNumber()) { - _wetLevel = arguments.property(WET_LEVEL_HANDLE).toNumber(); - } +static const float BANDWIDTH_DEFAULT = 10000.0f; +static const float PRE_DELAY_DEFAULT = 20.0f; +static const float LATE_DELAY_DEFAULT = 0.0f; +static const float REVERB_TIME_DEFAULT = 2.0f; +static const float EARLY_DIFFUSION_DEFAULT = 100.0f; +static const float LATE_DIFFUSION_DEFAULT = 100.0f; +static const float ROOM_SIZE_DEFAULT = 50.0f; +static const float DENSITY_DEFAULT = 100.0f; +static const float BASS_MULT_DEFAULT = 1.5f; +static const float BASS_FREQ_DEFAULT = 250.0f; +static const float HIGH_GAIN_DEFAULT = -6.0f; +static const float HIGH_FREQ_DEFAULT = 3000.0f; +static const float MOD_RATE_DEFAULT = 2.3f; +static const float MOD_DEPTH_DEFAULT = 50.0f; +static const float EARLY_GAIN_DEFAULT = 0.0f; +static const float LATE_GAIN_DEFAULT = 0.0f; +static const float EARLY_MIX_LEFT_DEFAULT = 20.0f; +static const float EARLY_MIX_RIGHT_DEFAULT = 20.0f; +static const float LATE_MIX_LEFT_DEFAULT = 90.0f; +static const float LATE_MIX_RIGHT_DEFAULT = 90.0f; +static const float WET_DRY_MIX_DEFAULT = 50.0f; + +static void setOption(QScriptValue arguments, const QString name, float default, float& var) { + var = arguments.property(name).isNumber() ? arguments.property(name).toNumber() : default; +} + +AudioEffectOptions::AudioEffectOptions(QScriptValue arguments) { + setOption(arguments, BANDWIDTH_HANDLE, BANDWIDTH_DEFAULT, _bandwidth); + setOption(arguments, PRE_DELAY_HANDLE, PRE_DELAY_DEFAULT, _preDelay); + setOption(arguments, LATE_DELAY_HANDLE, LATE_DELAY_DEFAULT, _lateDelay); + setOption(arguments, REVERB_TIME_HANDLE, REVERB_TIME_DEFAULT, _reverbTime); + setOption(arguments, EARLY_DIFFUSION_HANDLE, EARLY_DIFFUSION_DEFAULT, _earlyDiffusion); + setOption(arguments, LATE_DIFFUSION_HANDLE, LATE_DIFFUSION_DEFAULT, _lateDiffusion); + setOption(arguments, ROOM_SIZE_HANDLE, ROOM_SIZE_DEFAULT, _roomSize); + setOption(arguments, DENSITY_HANDLE, DENSITY_DEFAULT, _density); + setOption(arguments, BASS_MULT_HANDLE, BASS_MULT_DEFAULT, _bassMult); + setOption(arguments, BASS_FREQ_HANDLE, BASS_FREQ_DEFAULT, _bassFreq); + setOption(arguments, HIGH_GAIN_HANDLE, HIGH_GAIN_DEFAULT, _highGain); + setOption(arguments, HIGH_FREQ_HANDLE, HIGH_FREQ_DEFAULT, _highFreq); + setOption(arguments, MOD_RATE_HANDLE, MOD_RATE_DEFAULT, _modRate); + setOption(arguments, MOD_DEPTH_HANDLE, MOD_DEPTH_DEFAULT, _modDepth); + setOption(arguments, EARLY_GAIN_HANDLE, EARLY_GAIN_DEFAULT, _earlyGain); + setOption(arguments, LATE_GAIN_HANDLE, LATE_GAIN_DEFAULT, _lateGain); + setOption(arguments, EARLY_MIX_LEFT_HANDLE, EARLY_MIX_LEFT_DEFAULT, _earlyMixLeft); + setOption(arguments, EARLY_MIX_RIGHT_HANDLE, EARLY_MIX_RIGHT_DEFAULT, _earlyMixRight); + setOption(arguments, LATE_MIX_LEFT_HANDLE, LATE_MIX_LEFT_DEFAULT, _lateMixLeft); + setOption(arguments, LATE_MIX_RIGHT_HANDLE, LATE_MIX_RIGHT_DEFAULT, _lateMixRight); + setOption(arguments, WET_DRY_MIX_HANDLE, WET_DRY_MIX_DEFAULT, _wetDryMix); } AudioEffectOptions::AudioEffectOptions(const AudioEffectOptions &other) : QObject() { @@ -69,17 +87,28 @@ AudioEffectOptions::AudioEffectOptions(const AudioEffectOptions &other) : QObjec } AudioEffectOptions& AudioEffectOptions::operator=(const AudioEffectOptions &other) { - _maxRoomSize = other._maxRoomSize; - _roomSize = other._roomSize; + _bandwidth = other._bandwidth; + _preDelay = other._preDelay; + _lateDelay = other._lateDelay; _reverbTime = other._reverbTime; - _damping = other._damping; - _spread = other._spread; - _inputBandwidth = other._inputBandwidth; - _earlyLevel = other._earlyLevel; - _tailLevel = other._tailLevel; - _dryLevel = other._dryLevel; - _wetLevel = other._wetLevel; - + _earlyDiffusion = other._earlyDiffusion; + _lateDiffusion = other._lateDiffusion; + _roomSize = other._roomSize; + _density = other._density; + _bassMult = other._bassMult; + _bassFreq = other._bassFreq; + _highGain = other._highGain; + _highFreq = other._highFreq; + _modRate = other._modRate; + _modDepth = other._modDepth; + _earlyGain = other._earlyGain; + _lateGain = other._lateGain; + _earlyMixLeft = other._earlyMixLeft; + _earlyMixRight = other._earlyMixRight; + _lateMixLeft = other._lateMixLeft; + _lateMixRight = other._lateMixRight; + _wetDryMix = other._wetDryMix; + return *this; } diff --git a/libraries/audio/src/AudioEffectOptions.h b/libraries/audio/src/AudioEffectOptions.h index be5e1cca5e..9a65301473 100644 --- a/libraries/audio/src/AudioEffectOptions.h +++ b/libraries/audio/src/AudioEffectOptions.h @@ -15,32 +15,30 @@ #include #include -#include "AudioReverb.h" - class AudioEffectOptions : public QObject { Q_OBJECT - // Meters Square - Q_PROPERTY(float maxRoomSize READ getMaxRoomSize WRITE setMaxRoomSize) - Q_PROPERTY(float roomSize READ getRoomSize WRITE setRoomSize) - - // Seconds + Q_PROPERTY(float bandwidth READ getBandwidth WRITE setBandwidth) + Q_PROPERTY(float preDelay READ getPreDelay WRITE setPreDelay) + Q_PROPERTY(float lateDelay READ getLateDelay WRITE setLateDelay) Q_PROPERTY(float reverbTime READ getReverbTime WRITE setReverbTime) - - // Ratio between 0 and 1 - Q_PROPERTY(float damping READ getDamping WRITE setDamping) - - // (?) Does not appear to be set externally very often - Q_PROPERTY(float spread READ getSpread WRITE setSpread) - - // Ratio between 0 and 1 - Q_PROPERTY(float inputBandwidth READ getInputBandwidth WRITE setInputBandwidth) - - // in dB - Q_PROPERTY(float earlyLevel READ getEarlyLevel WRITE setEarlyLevel) - Q_PROPERTY(float tailLevel READ getTailLevel WRITE setTailLevel) - Q_PROPERTY(float dryLevel READ getDryLevel WRITE setDryLevel) - Q_PROPERTY(float wetLevel READ getWetLevel WRITE setWetLevel) + Q_PROPERTY(float earlyDiffusion READ getEarlyDiffusion WRITE setEarlyDiffusion) + Q_PROPERTY(float lateDiffusion READ getLateDiffusion WRITE setLateDiffusion) + Q_PROPERTY(float roomSize READ getRoomSize WRITE setRoomSize) + Q_PROPERTY(float density READ getDensity WRITE setDensity) + Q_PROPERTY(float bassMult READ getBassMult WRITE setBassMult) + Q_PROPERTY(float bassFreq READ getBassFreq WRITE setBassFreq) + Q_PROPERTY(float highGain READ getHighGain WRITE setHighGain) + Q_PROPERTY(float highFreq READ getHighFreq WRITE setHighFreq) + Q_PROPERTY(float modRate READ getModRate WRITE setModRate) + Q_PROPERTY(float modDepth READ getModDepth WRITE setModDepth) + Q_PROPERTY(float earlyGain READ getEarlyGain WRITE setEarlyGain) + Q_PROPERTY(float lateGain READ getLateGain WRITE setLateGain) + Q_PROPERTY(float earlyMixLeft READ getEarlyMixLeft WRITE setEarlyMixLeft) + Q_PROPERTY(float earlyMixRight READ getEarlyMixRight WRITE setEarlyMixRight) + Q_PROPERTY(float lateMixLeft READ getLateMixLeft WRITE setLateMixLeft) + Q_PROPERTY(float lateMixRight READ getLateMixRight WRITE setLateMixRight) + Q_PROPERTY(float wetDryMix READ getWetDryMix WRITE setWetDryMix) public: AudioEffectOptions(QScriptValue arguments = QScriptValue()); @@ -49,60 +47,100 @@ public: static QScriptValue constructor(QScriptContext* context, QScriptEngine* engine); - float getRoomSize() const { return _roomSize; } - void setRoomSize(float roomSize ) { _roomSize = roomSize; } + float getBandwidth() const { return _bandwidth; } + void setBandwidth(float bandwidth) { _bandwidth = bandwidth; } - float getMaxRoomSize() const { return _maxRoomSize; } - void setMaxRoomSize(float maxRoomSize ) { _maxRoomSize = maxRoomSize; } + float getPreDelay() const { return _preDelay; } + void setPreDelay(float preDelay) { _preDelay = preDelay; } + + float getLateDelay() const { return _lateDelay; } + void setLateDelay(float lateDelay) { _lateDelay = lateDelay; } float getReverbTime() const { return _reverbTime; } - void setReverbTime(float reverbTime ) { _reverbTime = reverbTime; } + void setReverbTime(float reverbTime) { _reverbTime = reverbTime; } - float getDamping() const { return _damping; } - void setDamping(float damping ) { _damping = damping; } + float getEarlyDiffusion() const { return _earlyDiffusion; } + void setEarlyDiffusion(float earlyDiffusion) { _earlyDiffusion = earlyDiffusion; } - float getSpread() const { return _spread; } - void setSpread(float spread ) { _spread = spread; } + float getLateDiffusion() const { return _lateDiffusion; } + void setLateDiffusion(float lateDiffusion) { _lateDiffusion = lateDiffusion; } - float getInputBandwidth() const { return _inputBandwidth; } - void setInputBandwidth(float inputBandwidth ) { _inputBandwidth = inputBandwidth; } + float getRoomSize() const { return _roomSize; } + void setRoomSize(float roomSize) { _roomSize = roomSize; } - float getEarlyLevel() const { return _earlyLevel; } - void setEarlyLevel(float earlyLevel ) { _earlyLevel = earlyLevel; } + float getDensity() const { return _density; } + void setDensity(float density) { _density = density; } - float getTailLevel() const { return _tailLevel; } - void setTailLevel(float tailLevel ) { _tailLevel = tailLevel; } + float getBassMult() const { return _bassMult; } + void setBassMult(float bassMult) { _bassMult = bassMult; } - float getDryLevel() const { return _dryLevel; } - void setDryLevel(float dryLevel) { _dryLevel = dryLevel; } + float getBassFreq() const { return _bassFreq; } + void setBassFreq(float bassFreq) { _bassFreq = bassFreq; } - float getWetLevel() const { return _wetLevel; } - void setWetLevel(float wetLevel) { _wetLevel = wetLevel; } + float getHighGain() const { return _highGain; } + void setHighGain(float highGain) { _highGain = highGain; } + + float getHighFreq() const { return _highFreq; } + void setHighFreq(float highFreq) { _highFreq = highFreq; } + + float getModRate() const { return _modRate; } + void setModRate(float modRate) { _modRate = modRate; } + + float getModDepth() const { return _modDepth; } + void setModDepth(float modDepth) { _modDepth = modDepth; } + + float getEarlyGain() const { return _earlyGain; } + void setEarlyGain(float earlyGain) { _earlyGain = earlyGain; } + + float getLateGain() const { return _lateGain; } + void setLateGain(float lateGain) { _lateGain = lateGain; } + + float getEarlyMixLeft() const { return _earlyMixLeft; } + void setEarlyMixLeft(float earlyMixLeft) { _earlyMixLeft = earlyMixLeft; } + + float getEarlyMixRight() const { return _earlyMixRight; } + void setEarlyMixRight(float earlyMixRight) { _earlyMixRight = earlyMixRight; } + + float getLateMixLeft() const { return _lateMixLeft; } + void setLateMixLeft(float lateMixLeft) { _lateMixLeft = lateMixLeft; } + + float getLateMixRight() const { return _lateMixRight; } + void setLateMixRight(float lateMixRight) { _lateMixRight = lateMixRight; } + + float getWetDryMix() const { return _wetDryMix; } + void setWetDryMix(float wetDryMix) { _wetDryMix = wetDryMix; } private: - // http://wiki.audacityteam.org/wiki/GVerb#Instant_Reverberb_settings + float _bandwidth; // [20, 24000] Hz - // Meters Square - float _maxRoomSize; - float _roomSize; + float _preDelay; // [0, 333] ms + float _lateDelay; // [0, 166] ms - // Seconds - float _reverbTime; + float _reverbTime; // [0.1, 100] seconds - // Ratio between 0 and 1 - float _damping; + float _earlyDiffusion; // [0, 100] percent + float _lateDiffusion; // [0, 100] percent - // ? (Does not appear to be set externally very often) - float _spread; + float _roomSize; // [0, 100] percent + float _density; // [0, 100] percent - // Ratio between 0 and 1 - float _inputBandwidth; + float _bassMult; // [0.1, 10] ratio + float _bassFreq; // [10, 500] Hz + float _highGain; // [-24, 0] dB + float _highFreq; // [1000, 12000] Hz - // dB - float _earlyLevel; - float _tailLevel; - float _dryLevel; - float _wetLevel; + float _modRate; // [0.1, 10] Hz + float _modDepth; // [0, 100] percent + + float _earlyGain; // [-96, +24] dB + float _lateGain; // [-96, +24] dB + + float _earlyMixLeft; // [0, 100] percent + float _earlyMixRight; // [0, 100] percent + float _lateMixLeft; // [0, 100] percent + float _lateMixRight; // [0, 100] percent + + float _wetDryMix; // [0, 100] percent }; #endif // hifi_AudioEffectOptions_h From 90ef92c79b95285db630c10c0edabc15a1f6ae42 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Mon, 7 Dec 2015 13:34:55 -0800 Subject: [PATCH 23/78] Fix slider layout --- examples/utilities/tools/reverbTest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/utilities/tools/reverbTest.js b/examples/utilities/tools/reverbTest.js index 2b08073ae0..a7a6bad9d7 100644 --- a/examples/utilities/tools/reverbTest.js +++ b/examples/utilities/tools/reverbTest.js @@ -39,7 +39,7 @@ AudioDevice.setReverbOptions(audioOptions); AudioDevice.setReverb(true); print("Reverb is ON."); -var panel = new Panel(10, 150); +var panel = new Panel(10, 160); var parameters = [ { name: "bandwidth", min: 1000, max: 12000, units: " Hz" }, From 86db12acae1c8eaf93674dbe1d76c6d75a2becfe Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Mon, 7 Dec 2015 14:03:11 -0800 Subject: [PATCH 24/78] Fix naming clash with reserved word --- libraries/audio/src/AudioEffectOptions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/audio/src/AudioEffectOptions.cpp b/libraries/audio/src/AudioEffectOptions.cpp index 792799b776..758875e896 100644 --- a/libraries/audio/src/AudioEffectOptions.cpp +++ b/libraries/audio/src/AudioEffectOptions.cpp @@ -54,8 +54,8 @@ static const float LATE_MIX_LEFT_DEFAULT = 90.0f; static const float LATE_MIX_RIGHT_DEFAULT = 90.0f; static const float WET_DRY_MIX_DEFAULT = 50.0f; -static void setOption(QScriptValue arguments, const QString name, float default, float& var) { - var = arguments.property(name).isNumber() ? arguments.property(name).toNumber() : default; +static void setOption(QScriptValue arguments, const QString name, float defaultValue, float& variable) { + variable = arguments.property(name).isNumber() ? arguments.property(name).toNumber() : defaultValue; } AudioEffectOptions::AudioEffectOptions(QScriptValue arguments) { From 2974241796d847e1a5c13fa7ab54d50918d04a93 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Mon, 7 Dec 2015 15:49:29 -0800 Subject: [PATCH 25/78] typo --- interface/src/avatar/AvatarManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 35b5db7946..0f96ca9af0 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -111,7 +111,7 @@ void AvatarManager::init() { _renderDistanceController.setKP(0.0008f); // Usually about 0.6 of largest that doesn't oscillate when other parameters 0. _renderDistanceController.setKI(0.0006f); // Big enough to bring us to target with the above KP. _renderDistanceController.setKD(0.000001f); // A touch of kd increases the speed by which we get there. - a_renderDistanceController.setHistorySize("av", 240); //FIXME + _renderDistanceController.setHistorySize("av", 240); //FIXME } void AvatarManager::updateMyAvatar(float deltaTime) { From b007617c8555dca32206fe1c69f26abfd2fe6b13 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Mon, 7 Dec 2015 16:56:59 -0800 Subject: [PATCH 26/78] Remove unneeded DisplayPlugin stuff. --- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 6 ------ .../src/display-plugins/OpenGLDisplayPlugin.h | 4 ---- 2 files changed, 10 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index b010414396..8e02077600 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -151,7 +151,6 @@ OpenGLDisplayPlugin::OpenGLDisplayPlugin() { _container->releaseOverlayTexture(texture); }); - _synchronizedTimer.start(); connect(&_timer, &QTimer::timeout, this, [&] { #ifdef Q_OS_MAC // On Mac, QT thread timing is such that we can miss one or even two cycles quite often, giving a render rate (including update/simulate) @@ -161,7 +160,6 @@ OpenGLDisplayPlugin::OpenGLDisplayPlugin() { #else if (_active && _sceneTextureEscrow.depth() < 1) { #endif - _synchronizedTimer.start(); emit requestRender(); } }); @@ -283,10 +281,6 @@ void OpenGLDisplayPlugin::submitOverlayTexture(GLuint sceneTexture, const glm::u } void OpenGLDisplayPlugin::updateTextures() { - const qint64 elapsed =_synchronizedTimer.elapsed(); - if (elapsed != 0) { - _lastSynchronizedElapsed = elapsed; - } _currentSceneTexture = _sceneTextureEscrow.fetchAndRelease(_currentSceneTexture); _currentOverlayTexture = _overlayTextureEscrow.fetchAndRelease(_currentOverlayTexture); } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 4577777034..ef78374994 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -10,7 +10,6 @@ #include "DisplayPlugin.h" #include -#include #include #include @@ -31,7 +30,6 @@ public: virtual void submitSceneTexture(uint32_t frameIndex, uint32_t sceneTexture, const glm::uvec2& sceneSize) override; virtual void submitOverlayTexture(uint32_t overlayTexture, const glm::uvec2& overlaySize) override; virtual float presentRate() override; - virtual qint64 getLastSynchronizedElapsed() { return _lastSynchronizedElapsed; } virtual glm::uvec2 getRecommendedRenderSize() const override { return getSurfacePixels(); @@ -70,8 +68,6 @@ protected: virtual void internalPresent(); mutable QTimer _timer; - QElapsedTimer _synchronizedTimer; - qint64 _lastSynchronizedElapsed { 0 }; ProgramPtr _program; ShapeWrapperPtr _plane; From 9512c3f73da0033a6c094606bd6bb824c60e4b7f Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Mon, 7 Dec 2015 16:58:59 -0800 Subject: [PATCH 27/78] Debugging. Please enter the commit message for your changes. Lines starting --- interface/src/Application.cpp | 19 +++++++++---------- interface/src/Application.h | 1 + interface/src/avatar/Avatar.cpp | 4 ++-- interface/src/avatar/AvatarManager.cpp | 21 +++++++++++++++++---- libraries/shared/src/PIDController.cpp | 2 +- 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6e4f3de649..521921faea 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1117,6 +1117,8 @@ void Application::paintGL() { _inPaint = true; Finally clearFlagLambda([this] { _inPaint = false; }); + _lastPaintWait = (float)(now - _paintWaitStart) / (float)USECS_PER_SECOND; + _lastInstantaneousFps = instantaneousFps; // Some LOD-like controls need to know a smoothly varying "potential" frame rate that doesn't // include time waiting for vsync, and which can report a number above target if we've got the headroom. // For example, if we're shooting for 75fps and paintWait is 3.3333ms (= 75% * 13.33ms), our deducedNonVSyncFps @@ -1126,20 +1128,20 @@ void Application::paintGL() { // Time between previous paintGL call and this one, which can vary not only with vSync misses, but also with QT timing. // We're using this as a proxy for the time between vsync and displayEnd, below. (Not exact, but tends to be the same over time.) // This is not the same as update(deltaTime), because the latter attempts to throttle to 60hz and also clamps to 1/4 second. - //const float actualPeriod = diff / (float)USECS_PER_SECOND; // same as 1/instantaneousFps but easier for compiler to optimize +/* const float actualPeriod = diff / (float)USECS_PER_SECOND; // same as 1/instantaneousFps but easier for compiler to optimize // Note that _lastPaintWait (stored at end of last call) is for the same paint cycle. - float deducedNonVSyncPeriod = (float) getActiveDisplayPlugin()->getLastSynchronizedElapsed() / (float) MSECS_PER_SECOND; /*actualPeriod - _lastPaintWait + _marginForDeducedFramePeriod; // plus a some non-zero time for machinery we can't measure + float deducedNonVSyncPeriod = actualPeriod - _lastPaintWait + _marginForDeducedFramePeriod; // plus a some non-zero time for machinery we can't measure // We don't know how much time to allow for that, but if we went over the target period, we know it's at least the portion // of paintWait up to the next vSync. This gives us enough of a penalty so that when actualPeriod crosses two cycles, // the key part (and not an exagerated part) of _lastPaintWait is accounted for. const float targetPeriod = getTargetFramePeriod(); if (_lastPaintWait > EPSILON && actualPeriod > targetPeriod) { // Don't use C++ remainder(). It's authors are mathematically insane. - deducedNonVSyncPeriod += fmod(actualPeriod, _lastPaintWait); - }*/ + deducedNonVSyncPeriod += fmod(targetPeriod, _lastPaintWait); + } _lastDeducedNonVSyncFps = 1.0f / deducedNonVSyncPeriod; - _lastInstantaneousFps = instantaneousFps; - + */ + auto displayPlugin = getActiveDisplayPlugin(); // FIXME not needed anymore? _offscreenContext->makeCurrent(); @@ -1375,7 +1377,6 @@ void Application::paintGL() { } // deliver final composited scene to the display plugin - uint64_t displayStart = usecTimestampNow(); { PROFILE_RANGE(__FUNCTION__ "/pluginOutput"); PerformanceTimer perfTimer("pluginOutput"); @@ -1415,9 +1416,7 @@ void Application::paintGL() { batch.resetStages(); }); } - uint64_t displayEnd = usecTimestampNow(); - const float displayPeriodUsec = (float)(displayEnd - displayStart); // usecs - _lastPaintWait = displayPeriodUsec / (float)USECS_PER_SECOND; + _paintWaitStart = usecTimestampNow(); } void Application::runTests() { diff --git a/interface/src/Application.h b/interface/src/Application.h index ce33f051ef..197d9a7a60 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -443,6 +443,7 @@ private: QElapsedTimer _lastTimeUpdated; float _lastInstantaneousFps { 0.0f }; float _lastPaintWait { 0.0f }; + uint64_t _paintWaitStart { 0 }; float _lastDeducedNonVSyncFps { 0.0f }; float _marginForDeducedFramePeriod{ 0.002f }; // 2ms, adjustable diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 2c8d970336..4558e6046d 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -174,14 +174,14 @@ void Avatar::simulate(float deltaTime) { _shouldSkipRender = false; _skeletonModel.setVisibleInScene(true, qApp->getMain3DScene()); if (!isControllerLogging) { // Test for isMyAvatar is prophylactic. Never occurs in current code. - qCDebug(interfaceapp) << "Rerendering" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for distance" << renderDistance; + //qCDebug(interfaceapp) << "Rerendering" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for distance" << renderDistance; } } } else if (distance > renderDistance * (1.0f + SKIP_HYSTERESIS_PROPORTION)) { _shouldSkipRender = true; _skeletonModel.setVisibleInScene(false, qApp->getMain3DScene()); if (!isControllerLogging) { - qCDebug(interfaceapp) << "Unrendering" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for distance" << renderDistance; + //qCDebug(interfaceapp) << "Unrendering" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for distance" << renderDistance; } } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index ba483a80ca..0b5551555c 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -111,7 +111,7 @@ void AvatarManager::init() { _renderDistanceController.setKP(0.0008f); // Usually about 0.6 of largest that doesn't oscillate when other parameters 0. _renderDistanceController.setKI(0.0006f); // Big enough to bring us to target with the above KP. _renderDistanceController.setKD(0.000001f); // A touch of kd increases the speed by which we get there. - _renderDistanceController.setHistorySize("av", 240); //FIXME + //_renderDistanceController.setHistorySize("av", 240); //FIXME } void AvatarManager::updateMyAvatar(float deltaTime) { @@ -130,7 +130,7 @@ void AvatarManager::updateMyAvatar(float deltaTime) { _lastSendAvatarDataTime = now; } } - +#include "InterfaceLogging.h" void AvatarManager::updateOtherAvatars(float deltaTime) { // lock the hash for read to check the size QReadLocker lock(&_hashLock); @@ -151,8 +151,21 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { // The measured value is frame rate. When the controlled value (1 / render cutoff distance) // goes up, the render cutoff distance gets closer, the number of rendered avatars is less, and frame rate // goes up. - const float deduced = qApp->getLastDeducedNonVSyncFps(); - const float distance = 1.0f / _renderDistanceController.update(deduced, deltaTime, false, qApp->getLastPaintWait(), qApp->getLastInstanteousFps()); + const float targetFps = 60.0f; + const float instantaneousFps = qApp->getLastInstanteousFps(); + const float paintWait = qApp->getLastPaintWait(); + const float actual = 1.0f / instantaneousFps; + const float firstAdjusted = actual - paintWait + 0.002f; + const float machinery = (paintWait > 0.0001f) ? fmod(1.0f / targetFps, paintWait) : 0.0f; + const float secondAdjusted = firstAdjusted + machinery; + const float deduced = 1.0f / secondAdjusted; + qCDebug(interfaceapp) << "dump " << instantaneousFps << (1000.0f * paintWait) + << "(" << paintWait << actual + << "(" << firstAdjusted << machinery << secondAdjusted + << ")" << deduced << ")"; + + //const float deduced = qApp->getLastDeducedNonVSyncFps(); + const float distance = 1.0f / _renderDistanceController.update(deduced, deltaTime, false, paintWait, instantaneousFps); _renderDistanceAverage.updateAverage(distance); _renderDistance = _renderDistanceAverage.getAverage(); int renderableCount = 0; diff --git a/libraries/shared/src/PIDController.cpp b/libraries/shared/src/PIDController.cpp index 36c670e66d..3607c281ec 100644 --- a/libraries/shared/src/PIDController.cpp +++ b/libraries/shared/src/PIDController.cpp @@ -70,7 +70,7 @@ void PIDController::reportHistory() { for (int i = 0; i < _history.size(); i++) { Row& row = _history[i]; qCDebug(shared) << row.measured << row.dt << - row.fixme1 << row.fixme2 << + (row.fixme1 * 1000.0f) << (row.fixme2) << "||" << row.error << row.accumulated << row.changed << "||" << row.p << row.i << row.d << row.computed << 1.0f/row.computed; } From faec4639b1d8b93f090799b80f084f8f7ac0fc25 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 8 Dec 2015 09:14:40 -0800 Subject: [PATCH 28/78] cap --- interface/src/avatar/AvatarManager.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 0b5551555c..b101c106a2 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -111,7 +111,7 @@ void AvatarManager::init() { _renderDistanceController.setKP(0.0008f); // Usually about 0.6 of largest that doesn't oscillate when other parameters 0. _renderDistanceController.setKI(0.0006f); // Big enough to bring us to target with the above KP. _renderDistanceController.setKD(0.000001f); // A touch of kd increases the speed by which we get there. - //_renderDistanceController.setHistorySize("av", 240); //FIXME + _renderDistanceController.setHistorySize("av", 240); //FIXME } void AvatarManager::updateMyAvatar(float deltaTime) { @@ -155,17 +155,23 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { const float instantaneousFps = qApp->getLastInstanteousFps(); const float paintWait = qApp->getLastPaintWait(); const float actual = 1.0f / instantaneousFps; - const float firstAdjusted = actual - paintWait + 0.002f; - const float machinery = (paintWait > 0.0001f) ? fmod(1.0f / targetFps, paintWait) : 0.0f; + const float target = 1.0f / targetFps; + const float firstAdjusted = actual - paintWait /*+ 0.002f*/; + const float machinery = (paintWait > target) ? fmod(paintWait, target) : 0.0f; const float secondAdjusted = firstAdjusted + machinery; const float deduced = 1.0f / secondAdjusted; - qCDebug(interfaceapp) << "dump " << instantaneousFps << (1000.0f * paintWait) + const float modulus = (instantaneousFps >= targetFps) ? + (1.0f + floor(instantaneousFps / targetFps)) : + (1.0f / floor(targetFps / instantaneousFps)); + const float cap = modulus * targetFps; + const float capped = glm::min(cap, deduced); + /*qCDebug(interfaceapp) << "dump " << instantaneousFps << (1000.0f * paintWait) << "(" << paintWait << actual << "(" << firstAdjusted << machinery << secondAdjusted - << ")" << deduced << ")"; + << ")" << deduced << ")";*/ //const float deduced = qApp->getLastDeducedNonVSyncFps(); - const float distance = 1.0f / _renderDistanceController.update(deduced, deltaTime, false, paintWait, instantaneousFps); + const float distance = 1.0f / _renderDistanceController.update(capped, deltaTime, false, paintWait, instantaneousFps); _renderDistanceAverage.updateAverage(distance); _renderDistance = _renderDistanceAverage.getAverage(); int renderableCount = 0; From 44d740ef571148912ce233c63bb1e8d7c76d5f73 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 8 Dec 2015 09:22:02 -0800 Subject: [PATCH 29/78] Remove unused variable 'addr' --- libraries/networking/src/PacketReceiver.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 7e91a42a64..a162ba72c8 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -297,7 +297,6 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer recei emit dataReceived(matchingNode->getType(), receivedMessage->getSize()); matchingNode->recordBytesReceived(receivedMessage->getSize()); Node* n = matchingNode.data(); - auto addr = n->getActiveSocket(); QMetaMethod metaMethod = listener.method; From 71c266bc00e6e997eae0eba898efd65d99abc222 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 8 Dec 2015 09:22:17 -0800 Subject: [PATCH 30/78] Fix order of initializion in ReceivedMessage --- libraries/networking/src/ReceivedMessage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/ReceivedMessage.cpp b/libraries/networking/src/ReceivedMessage.cpp index f383257520..651b856923 100644 --- a/libraries/networking/src/ReceivedMessage.cpp +++ b/libraries/networking/src/ReceivedMessage.cpp @@ -22,8 +22,8 @@ static const int HEAD_DATA_SIZE = 512; ReceivedMessage::ReceivedMessage(const NLPacketList& packetList) : _data(packetList.getMessage()), _headData(_data.mid(0, HEAD_DATA_SIZE)), - _sourceID(packetList.getSourceID()), _numPackets(packetList.getNumPackets()), + _sourceID(packetList.getSourceID()), _packetType(packetList.getType()), _packetVersion(packetList.getVersion()), _senderSockAddr(packetList.getSenderSockAddr()), @@ -34,8 +34,8 @@ ReceivedMessage::ReceivedMessage(const NLPacketList& packetList) ReceivedMessage::ReceivedMessage(NLPacket& packet) : _data(packet.readAll()), _headData(_data.mid(0, HEAD_DATA_SIZE)), - _sourceID(packet.getSourceID()), _numPackets(1), + _sourceID(packet.getSourceID()), _packetType(packet.getType()), _packetVersion(packet.getVersion()), _senderSockAddr(packet.getSenderSockAddr()), From 0759462df714c865e897da07a42e99b9c65c008e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 8 Dec 2015 09:38:23 -0800 Subject: [PATCH 31/78] Remove unused variable in PacketReceiver --- libraries/networking/src/PacketReceiver.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index a162ba72c8..530efc5fb3 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -296,7 +296,6 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer recei if (matchingNode) { emit dataReceived(matchingNode->getType(), receivedMessage->getSize()); matchingNode->recordBytesReceived(receivedMessage->getSize()); - Node* n = matchingNode.data(); QMetaMethod metaMethod = listener.method; From 22a1ee83e6381bd753697d9deb4acfa9ba2c8381 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 8 Dec 2015 10:39:04 -0800 Subject: [PATCH 32/78] ignore parenting properties --- examples/particle_explorer/main.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 32ec12b640..a2a112d8e5 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -74,7 +74,9 @@ var keysToIgnore = [ 'shapeType', 'isEmitting', 'sittingPoints', - 'originalTextures' + 'originalTextures', + 'parentJointIndex', + 'parentID' ]; var individualKeys = []; From eeebe0622851ee5e6090143e66b728838524527c Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 8 Dec 2015 10:54:42 -0800 Subject: [PATCH 33/78] Using CPACK_PACKAGE_EXECUTABLES instead of CPACK_NSIS_CREATE_ICONS_EXTRE --- CMakeLists.txt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b44f81d2f..9e47d38067 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -229,10 +229,10 @@ if (DEFINED DEPLOY_PACKAGE AND DEPLOY_PACKAGE) file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/full-stack-deployment) - set (ICONPATH_INTERFACE "$INSTDIR/${PATH_INSTALL_DATA}/interface.ico") - set (ICONPATH_STACK_MANAGER "$INSTDIR/${PATH_INSTALL_DATA}/stack-manager.ico") - string (REPLACE "/" "\\\\" ICONPATH_INTERFACE ${ICONPATH_INTERFACE}) - string (REPLACE "/" "\\\\" ICONPATH_STACK_MANAGER ${ICONPATH_STACK_MANAGER}) + set(ICONPATH_INTERFACE "$INSTDIR/${PATH_INSTALL_DATA}/interface.ico") + set(ICONPATH_STACK_MANAGER "$INSTDIR/${PATH_INSTALL_DATA}/stack-manager.ico") + string(REPLACE "/" "\\\\" ICONPATH_INTERFACE ${ICONPATH_INTERFACE}) + string(REPLACE "/" "\\\\" ICONPATH_STACK_MANAGER ${ICONPATH_STACK_MANAGER}) set(CPACK_PACKAGE_NAME "High Fidelity") set(CPACK_PACKAGE_VENDOR "High Fidelity, Inc") @@ -242,8 +242,10 @@ if (DEFINED DEPLOY_PACKAGE AND DEPLOY_PACKAGE) set(CPACK_PACKAGE_VERSION_MINOR "0") set(CPACK_PACKAGE_VERSION_PATCH "0") set(CPACK_PACKAGE_INSTALL_DIRECTORY "High Fidelity-${BUILD_SEQ}") - set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Interface.lnk' '$INSTDIR\\\\interface.exe' '${ICONPATH_INTERFACE}'") - set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Stack Manager.lnk' '$INSTDIR\\\\stack-manager.exe' '${ICONPATH_STACK_MANAGER}'") + set(CPACK_PACKAGE_EXECUTABLES + stack-manager "Stack Manager" + interface "Interface" + ) if (WIN32) install(DIRECTORY ${CMAKE_BINARY_DIR}/full-stack-deployment/ DESTINATION "./") From 011a43d5f214243e00b3feee613d6028299f977e Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 8 Dec 2015 11:08:22 -0800 Subject: [PATCH 34/78] Add sphere and cube triangle counts to displayed stats --- .../src/RenderableBoxEntityItem.cpp | 5 ++++- .../src/RenderableSphereEntityItem.cpp | 4 +++- libraries/render-utils/src/GeometryCache.cpp | 14 ++++++++++++++ libraries/render-utils/src/GeometryCache.h | 3 +++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp b/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp index 588f17d959..54fe491c46 100644 --- a/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp @@ -41,6 +41,7 @@ void RenderableBoxEntityItem::render(RenderArgs* args) { Q_ASSERT(getType() == EntityTypes::Box); Q_ASSERT(args->_batch); + if (!_procedural) { _procedural.reset(new Procedural(this->getUserData())); _procedural->_vertexSource = simple_vert; @@ -64,4 +65,6 @@ void RenderableBoxEntityItem::render(RenderArgs* args) { } else { DependencyManager::get()->renderSolidCubeInstance(batch, getTransformToCenter(), cubeColor); } -}; + static const auto triCount = DependencyManager::get()->getCubeTriangleCount(); + args->_details._trianglesRendered += triCount; +} diff --git a/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp b/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp index 2bdcfc19ad..8768e41a07 100644 --- a/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp @@ -71,4 +71,6 @@ void RenderableSphereEntityItem::render(RenderArgs* args) { batch.setModelTransform(Transform()); DependencyManager::get()->renderSolidSphereInstance(batch, modelTransform, sphereColor); } -}; + static const auto triCount = DependencyManager::get()->getSphereTriangleCount(); + args->_details._trianglesRendered += triCount; +} diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 75b3b91c10..b9fdcd95a4 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -214,6 +214,19 @@ VertexVector tesselate(const VertexVector& startingTriangles, int count) { return triangles; } +size_t GeometryCache::getShapeTriangleCount(Shape shape) { + return _shapes[shape]._indexCount / VERTICES_PER_TRIANGLE; +} + +size_t GeometryCache::getSphereTriangleCount() { + return getShapeTriangleCount(Sphere); +} + +size_t GeometryCache::getCubeTriangleCount() { + return getShapeTriangleCount(Cube); +} + + // FIXME solids need per-face vertices, but smooth shaded // components do not. Find a way to support using draw elements // or draw arrays as appropriate @@ -1727,3 +1740,4 @@ void GeometryCache::useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend) { batch.setPipeline(_standardDrawPipeline); } } + diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index aa1593db78..c408115011 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -151,16 +151,19 @@ public: void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer); void renderShape(gpu::Batch& batch, Shape shape); void renderWireShape(gpu::Batch& batch, Shape shape); + size_t getShapeTriangleCount(Shape shape); void renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer); void renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer); void renderCube(gpu::Batch& batch); void renderWireCube(gpu::Batch& batch); + size_t getCubeTriangleCount(); void renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer); void renderWireSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer); void renderSphere(gpu::Batch& batch); void renderWireSphere(gpu::Batch& batch); + size_t getSphereTriangleCount(); void renderGrid(gpu::Batch& batch, int xDivisions, int yDivisions, const glm::vec4& color); void renderGrid(gpu::Batch& batch, int x, int y, int width, int height, int rows, int cols, const glm::vec4& color, int id = UNKNOWN_ID); From 4dbfd3bfd936702e58ac90cc102d7df8bd4fe5a8 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 8 Dec 2015 10:49:10 -0800 Subject: [PATCH 35/78] Fix concurrency issues for bools in ScriptEngine Several member variables were unsafely being accessed from multiple threads. Making these variables std::atomic makes this safe. --- libraries/script-engine/src/ScriptEngine.cpp | 2 +- libraries/script-engine/src/ScriptEngine.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 3306659c80..daadb0e394 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -183,7 +183,7 @@ void ScriptEngine::runInThread() { QSet ScriptEngine::_allKnownScriptEngines; QMutex ScriptEngine::_allScriptsMutex; -bool ScriptEngine::_stoppingAllScripts = false; +std::atomic ScriptEngine::_stoppingAllScripts = false; void ScriptEngine::stopAllScripts(QObject* application) { _allScriptsMutex.lock(); diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 90b99d46fd..82b91aed2e 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -166,8 +166,8 @@ signals: protected: QString _scriptContents; QString _parentURL; - bool _isFinished { false }; - bool _isRunning { false }; + std::atomic _isFinished { false }; + std::atomic _isRunning { false }; int _evaluatesPending { 0 }; bool _isInitialized { false }; QHash _timerFunctionMap; @@ -206,7 +206,7 @@ protected: static QSet _allKnownScriptEngines; static QMutex _allScriptsMutex; - static bool _stoppingAllScripts; + static std::atomic _stoppingAllScripts; }; #endif // hifi_ScriptEngine_h \ No newline at end of file From cc6d30fe6f867080e61901588a023add803fecb7 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 8 Dec 2015 13:06:10 -0800 Subject: [PATCH 36/78] Fix to path setting in shortcuts --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e47d38067..ab88e9e46a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,6 +242,7 @@ if (DEFINED DEPLOY_PACKAGE AND DEPLOY_PACKAGE) set(CPACK_PACKAGE_VERSION_MINOR "0") set(CPACK_PACKAGE_VERSION_PATCH "0") set(CPACK_PACKAGE_INSTALL_DIRECTORY "High Fidelity-${BUILD_SEQ}") + set(CPACK_NSIS_EXECUTABLES_DIRECTORY ".") set(CPACK_PACKAGE_EXECUTABLES stack-manager "Stack Manager" interface "Interface" @@ -252,4 +253,4 @@ if (DEFINED DEPLOY_PACKAGE AND DEPLOY_PACKAGE) endif (WIN32) include(CPack) -endif () \ No newline at end of file +endif () From 9062cca8c474d83f33bc6fecfcd0a5c2e7e583ff Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 8 Dec 2015 13:33:15 -0800 Subject: [PATCH 37/78] Restoring --- interface/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 1adb00fe5f..3db23e4d36 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -201,7 +201,7 @@ else (APPLE) # link target to external libraries if (WIN32) - target_link_libraries(${TARGET_NAME} wsock32.lib Winmm.lib) + #target_link_libraries(${TARGET_NAME} wsock32.lib Winmm.lib) else (WIN32) # Nothing else required on linux apparently endif() From 164439b3037af5628b381a3526a9ef074030aa17 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 8 Dec 2015 13:53:39 -0800 Subject: [PATCH 38/78] don't enable physics until an entire scene has been received from the entity server and until nearby (to MyAvatar) entities are ready --- interface/src/Application.cpp | 36 +++++++++++++++++++++++++++++++++-- interface/src/Application.h | 2 ++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c0cfbda15b..4a97fd6275 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -195,6 +195,8 @@ static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-commands.html"; static const unsigned int THROTTLED_SIM_FRAMERATE = 15; static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SIM_FRAMERATE; +static const float PHYSICS_READY_RANGE = 3.0f; // how far from avatar to check for entities that aren't ready for simulation + #ifndef __APPLE__ static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); #else @@ -2905,7 +2907,7 @@ void Application::update(float deltaTime) { _avatarUpdate->synchronousProcess(); - { + if (_physicsEnabled) { PerformanceTimer perfTimer("physics"); static VectorOfMotionStates motionStates; @@ -3893,6 +3895,31 @@ void Application::trackIncomingOctreePacket(ReceivedMessage& message, SharedNode } } +bool Application::nearbyEntitiesAreReadyForPhysics() { + // this is used to avoid the following scenario: + // A table has some items sitting on top of it. The items are at rest, meaning they aren't active in bullet. + // Someone logs in close to the table. They receive information about the items on the table before they + // receive information about the table. The items are very close to the avatar's capsule, so they become + // activated in bullet. This causes them to fall to the floor, because the table's shape isn't yet in bullet. + EntityTreePointer entityTree = _entities.getTree(); + if (!entityTree) { + return false; + } + + QVector entities; + entityTree->withReadLock([&] { + AABox box(getMyAvatar()->getPosition() - glm::vec3(PHYSICS_READY_RANGE), glm::vec3(2 * PHYSICS_READY_RANGE)); + entityTree->findEntities(box, entities); + }); + + foreach (EntityItemPointer entity, entities) { + if (!entity->isReadyToComputeShape()) { + return false; + } + } + return true; +} + int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer sendingNode) { // But, also identify the sender, and keep track of the contained jurisdiction root for this server @@ -3938,7 +3965,12 @@ int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer }); }); - + if (!_physicsEnabled && nearbyEntitiesAreReadyForPhysics()) { + // These stats packets are sent in between full sends of a scene. + // We keep physics disabled until we've recieved a full scene and everything near the avatar in that + // scene is ready to compute its collision shape. + _physicsEnabled = true; + } return statsMessageLength; } diff --git a/interface/src/Application.h b/interface/src/Application.h index ce33f051ef..27df7835e6 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -395,6 +395,7 @@ private: bool importSVOFromURL(const QString& urlString); + bool nearbyEntitiesAreReadyForPhysics(); int processOctreeStats(ReceivedMessage& message, SharedNodePointer sendingNode); void trackIncomingOctreePacket(ReceivedMessage& message, SharedNodePointer sendingNode, bool wasStatsPacket); @@ -564,6 +565,7 @@ private: bool _isForeground = true; // starts out assumed to be in foreground bool _inPaint = false; bool _isGLInitialized { false }; + bool _physicsEnabled { false }; }; #endif // hifi_Application_h From c462bda86cb221aa7b8e5329f93367a42399d3d7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 8 Dec 2015 14:01:18 -0800 Subject: [PATCH 39/78] disable physics when moving to a new domain --- interface/src/Application.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4a97fd6275..eee1ea7226 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3788,6 +3788,8 @@ void Application::domainChanged(const QString& domainHostname) { updateWindowTitle(); clearDomainOctreeDetails(); _domainConnectionRefusals.clear(); + // disable physics until we have enough information about our new location to not cause craziness. + _physicsEnabled = false; } void Application::handleDomainConnectionDeniedPacket(QSharedPointer message) { From 9ba5670c7611f8c09ff44bf47658778c735018e8 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 8 Dec 2015 14:20:19 -0800 Subject: [PATCH 40/78] Fix --- interface/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 4332ae24be..0baf709082 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -194,7 +194,7 @@ else (APPLE) # link target to external libraries if (WIN32) - #target_link_libraries(${TARGET_NAME} wsock32.lib Winmm.lib) + target_link_libraries(${TARGET_NAME} wsock32.lib Winmm.lib) else (WIN32) # Nothing else required on linux apparently endif() From 987b8d3334a1136dbce95122159a98650f4216b7 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 8 Dec 2015 14:34:25 -0800 Subject: [PATCH 41/78] fix bad simulation ownership when using edit.js --- libraries/entities/src/EntityItem.cpp | 123 ++++++++++---------------- libraries/entities/src/EntityItem.h | 2 +- 2 files changed, 50 insertions(+), 75 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 51ade5b46e..5235cb6db0 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -628,71 +628,50 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef bool weOwnSimulation = _simulationOwner.matchesValidID(myNodeID); - if (args.bitstreamVersion >= VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE) { - // pack SimulationOwner and terse update properties near each other + // pack SimulationOwner and terse update properties near each other - // NOTE: the server is authoritative for changes to simOwnerID so we always unpack ownership data - // even when we would otherwise ignore the rest of the packet. + // NOTE: the server is authoritative for changes to simOwnerID so we always unpack ownership data + // even when we would otherwise ignore the rest of the packet. - if (propertyFlags.getHasProperty(PROP_SIMULATION_OWNER)) { + if (propertyFlags.getHasProperty(PROP_SIMULATION_OWNER)) { - QByteArray simOwnerData; - int bytes = OctreePacketData::unpackDataFromBytes(dataAt, simOwnerData); - SimulationOwner newSimOwner; - newSimOwner.fromByteArray(simOwnerData); - dataAt += bytes; - bytesRead += bytes; + QByteArray simOwnerData; + int bytes = OctreePacketData::unpackDataFromBytes(dataAt, simOwnerData); + SimulationOwner newSimOwner; + newSimOwner.fromByteArray(simOwnerData); + dataAt += bytes; + bytesRead += bytes; - if (wantTerseEditLogging() && _simulationOwner != newSimOwner) { - qCDebug(entities) << "sim ownership for" << getDebugName() << "is now" << newSimOwner; - } - if (_simulationOwner.set(newSimOwner)) { - _dirtyFlags |= Simulation::DIRTY_SIMULATOR_ID; - } + if (wantTerseEditLogging() && _simulationOwner != newSimOwner) { + qCDebug(entities) << "sim ownership for" << getDebugName() << "is now" << newSimOwner; } - { // When we own the simulation we don't accept updates to the entity's transform/velocities - // but since we're using macros below we have to temporarily modify overwriteLocalData. - bool oldOverwrite = overwriteLocalData; - overwriteLocalData = overwriteLocalData && !weOwnSimulation; - READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePosition); - READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, updateRotation); - READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, updateVelocity); - READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocity); - READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, setAcceleration); - overwriteLocalData = oldOverwrite; + if (_simulationOwner.set(newSimOwner)) { + _dirtyFlags |= Simulation::DIRTY_SIMULATOR_ID; } - - READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, updateDimensions); - READ_ENTITY_PROPERTY(PROP_DENSITY, float, updateDensity); - READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, updateGravity); - - READ_ENTITY_PROPERTY(PROP_DAMPING, float, updateDamping); - READ_ENTITY_PROPERTY(PROP_RESTITUTION, float, updateRestitution); - READ_ENTITY_PROPERTY(PROP_FRICTION, float, updateFriction); - READ_ENTITY_PROPERTY(PROP_LIFETIME, float, updateLifetime); - READ_ENTITY_PROPERTY(PROP_SCRIPT, QString, setScript); - READ_ENTITY_PROPERTY(PROP_SCRIPT_TIMESTAMP, quint64, setScriptTimestamp); - READ_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, glm::vec3, setRegistrationPoint); - } else { - // legacy order of packing here - // TODO: purge this logic in a few months from now (2015.07) - READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePosition); - READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, updateDimensions); - READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, updateRotation); - READ_ENTITY_PROPERTY(PROP_DENSITY, float, updateDensity); - READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, updateVelocity); - READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, updateGravity); - READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, setAcceleration); - - READ_ENTITY_PROPERTY(PROP_DAMPING, float, updateDamping); - READ_ENTITY_PROPERTY(PROP_RESTITUTION, float, updateRestitution); - READ_ENTITY_PROPERTY(PROP_FRICTION, float, updateFriction); - READ_ENTITY_PROPERTY(PROP_LIFETIME, float, updateLifetime); - READ_ENTITY_PROPERTY(PROP_SCRIPT, QString, setScript); - READ_ENTITY_PROPERTY(PROP_SCRIPT_TIMESTAMP, quint64, setScriptTimestamp); - READ_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, glm::vec3, setRegistrationPoint); - READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocity); } + { // When we own the simulation we don't accept updates to the entity's transform/velocities + // but since we're using macros below we have to temporarily modify overwriteLocalData. + bool oldOverwrite = overwriteLocalData; + overwriteLocalData = overwriteLocalData && !weOwnSimulation; + READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePosition); + READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, updateRotation); + READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, updateVelocity); + READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocity); + READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, setAcceleration); + overwriteLocalData = oldOverwrite; + } + + READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, updateDimensions); + READ_ENTITY_PROPERTY(PROP_DENSITY, float, updateDensity); + READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, updateGravity); + + READ_ENTITY_PROPERTY(PROP_DAMPING, float, updateDamping); + READ_ENTITY_PROPERTY(PROP_RESTITUTION, float, updateRestitution); + READ_ENTITY_PROPERTY(PROP_FRICTION, float, updateFriction); + READ_ENTITY_PROPERTY(PROP_LIFETIME, float, updateLifetime); + READ_ENTITY_PROPERTY(PROP_SCRIPT, QString, setScript); + READ_ENTITY_PROPERTY(PROP_SCRIPT_TIMESTAMP, quint64, setScriptTimestamp); + READ_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, glm::vec3, setRegistrationPoint); READ_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, float, updateAngularDamping); READ_ENTITY_PROPERTY(PROP_VISIBLE, bool, setVisible); @@ -701,17 +680,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef READ_ENTITY_PROPERTY(PROP_LOCKED, bool, setLocked); READ_ENTITY_PROPERTY(PROP_USER_DATA, QString, setUserData); - if (args.bitstreamVersion < VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE) { - // this code for when there is only simulatorID and no simulation priority - - // we always accept the server's notion of simulatorID, so we fake overwriteLocalData as true - // before we try to READ_ENTITY_PROPERTY it - bool temp = overwriteLocalData; - overwriteLocalData = true; - READ_ENTITY_PROPERTY(PROP_SIMULATION_OWNER, QUuid, updateSimulatorID); - overwriteLocalData = temp; - } - if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_MARKETPLACE_ID) { READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID); } @@ -1104,7 +1072,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) { bool somethingChanged = false; // these affect TerseUpdate properties - SET_ENTITY_PROPERTY_FROM_PROPERTIES(simulationOwner, setSimulationOwner); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(simulationOwner, updateSimulationOwner); SET_ENTITY_PROPERTY_FROM_PROPERTIES(position, updatePosition); SET_ENTITY_PROPERTY_FROM_PROPERTIES(rotation, updateRotation); SET_ENTITY_PROPERTY_FROM_PROPERTIES(velocity, updateVelocity); @@ -1324,6 +1292,13 @@ void EntityItem::updatePosition(const glm::vec3& value) { } if (getLocalPosition() != value) { setLocalPosition(value); + _dirtyFlags |= Simulation::DIRTY_POSITION; + forEachDescendant([&](SpatiallyNestablePointer object) { + if (object->getNestableType() == NestableTypes::Entity) { + EntityItemPointer entity = std::static_pointer_cast(object); + entity->_dirtyFlags |= Simulation::DIRTY_POSITION; + } + }); } } @@ -1496,12 +1471,12 @@ void EntityItem::setSimulationOwner(const SimulationOwner& owner) { _simulationOwner.set(owner); } -void EntityItem::updateSimulatorID(const QUuid& value) { - if (wantTerseEditLogging() && _simulationOwner.getID() != value) { - qCDebug(entities) << "sim ownership for" << getDebugName() << "is now" << value; +void EntityItem::updateSimulationOwner(const SimulationOwner& owner) { + if (wantTerseEditLogging() && _simulationOwner != owner) { + qCDebug(entities) << "sim ownership for" << getDebugName() << "is now" << owner; } - if (_simulationOwner.setID(value)) { + if (_simulationOwner.set(owner)) { _dirtyFlags |= Simulation::DIRTY_SIMULATOR_ID; } } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 761208cb06..f94fc6e3c7 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -288,7 +288,7 @@ public: quint8 getSimulationPriority() const { return _simulationOwner.getPriority(); } QUuid getSimulatorID() const { return _simulationOwner.getID(); } - void updateSimulatorID(const QUuid& value); + void updateSimulationOwner(const SimulationOwner& owner); void clearSimulationOwnership(); const QString& getMarketplaceID() const { return _marketplaceID; } From 5b41d4da1caae89d6517c2d6641405994cb7b0c0 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Tue, 8 Dec 2015 15:30:23 -0800 Subject: [PATCH 42/78] Snapshot of "working" version. --- interface/src/Application.cpp | 9 +++++++-- interface/src/avatar/AvatarManager.cpp | 17 +++++++---------- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 3 ++- .../src/display-plugins/OpenGLDisplayPlugin.h | 3 +++ libraries/plugins/src/plugins/DisplayPlugin.h | 2 +- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1718389a5f..9de395dc57 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1086,6 +1086,7 @@ void Application::paintGL() { // update fps moving average uint64_t now = usecTimestampNow(); + qint64 sinceSync = getActiveDisplayPlugin()->getTimeSinceSync(); static uint64_t lastPaintBegin{ now }; uint64_t diff = now - lastPaintBegin; float instantaneousFps = 0.0f; @@ -1122,8 +1123,8 @@ void Application::paintGL() { _inPaint = true; Finally clearFlagLambda([this] { _inPaint = false; }); - _lastPaintWait = (float)(now - _paintWaitStart) / (float)USECS_PER_SECOND; - _lastInstantaneousFps = instantaneousFps; + //_lastPaintWait = (float)(now - _paintWaitStart) / (float)USECS_PER_SECOND; + //_lastInstantaneousFps = instantaneousFps; // Some LOD-like controls need to know a smoothly varying "potential" frame rate that doesn't // include time waiting for vsync, and which can report a number above target if we've got the headroom. // For example, if we're shooting for 75fps and paintWait is 3.3333ms (= 75% * 13.33ms), our deducedNonVSyncFps @@ -1422,6 +1423,10 @@ void Application::paintGL() { }); } _paintWaitStart = usecTimestampNow(); + _lastPaintWait = (float)sinceSync / (float)MSECS_PER_SECOND; + _lastInstantaneousFps = instantaneousFps; + _lastDeducedNonVSyncFps = 1.0f / (((_paintWaitStart - now) / (float)USECS_PER_SECOND) + ((float)sinceSync / (float)MSECS_PER_SECOND)); + // qCDebug(interfaceapp) << "pw/now/sync" << _paintWaitStart << now << sinceSync << "period" << (((_paintWaitStart - now) / (float)USECS_PER_SECOND) + ((float)sinceSync / (float)MSECS_PER_SECOND)) << "hz" << _lastDeducedNonVSyncFps; } void Application::runTests() { diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index b101c106a2..c0485bdebb 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -154,24 +154,21 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { const float targetFps = 60.0f; const float instantaneousFps = qApp->getLastInstanteousFps(); const float paintWait = qApp->getLastPaintWait(); - const float actual = 1.0f / instantaneousFps; + const float deduced = qApp->getLastDeducedNonVSyncFps(); + /*const float actual = 1.0f / instantaneousFps; const float target = 1.0f / targetFps; - const float firstAdjusted = actual - paintWait /*+ 0.002f*/; - const float machinery = (paintWait > target) ? fmod(paintWait, target) : 0.0f; - const float secondAdjusted = firstAdjusted + machinery; - const float deduced = 1.0f / secondAdjusted; const float modulus = (instantaneousFps >= targetFps) ? - (1.0f + floor(instantaneousFps / targetFps)) : - (1.0f / floor(targetFps / instantaneousFps)); + (1.0f + floor(instantaneousFps / targetFps)) : + (1.0f / floor(targetFps / instantaneousFps)); const float cap = modulus * targetFps; - const float capped = glm::min(cap, deduced); + const float deduced = instantaneousFps + ((cap - instantaneousFps) * (paintWait / target));*/ /*qCDebug(interfaceapp) << "dump " << instantaneousFps << (1000.0f * paintWait) << "(" << paintWait << actual << "(" << firstAdjusted << machinery << secondAdjusted - << ")" << deduced << ")";*/ + << ")" << deduced << modulus << cap << capped << ")";*/ //const float deduced = qApp->getLastDeducedNonVSyncFps(); - const float distance = 1.0f / _renderDistanceController.update(capped, deltaTime, false, paintWait, instantaneousFps); + const float distance = 1.0f / _renderDistanceController.update(deduced, deltaTime, false, paintWait, instantaneousFps); _renderDistanceAverage.updateAverage(distance); _renderDistance = _renderDistanceAverage.getAverage(); int renderableCount = 0; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 9a0db0ad97..b59ac24b52 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -168,8 +168,9 @@ OpenGLDisplayPlugin::OpenGLDisplayPlugin() { // This is likely to be mooted by further planned changes. if (_active && _sceneTextureEscrow.depth() <= 1) { #else - if (_active && _sceneTextureEscrow.depth() < 1) { + if (_active && _sceneTextureEscrow.depth() <= 1) { #endif + _sinceSync.start(); emit requestRender(); } }); diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index ef78374994..4231c8ff7f 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -10,6 +10,7 @@ #include "DisplayPlugin.h" #include +#include #include #include @@ -40,6 +41,7 @@ public: } virtual QImage getScreenshot() const override; + virtual quint64 getTimeSinceSync() { return _sinceSync.elapsed(); } protected: friend class PresentThread; @@ -82,6 +84,7 @@ protected: GLTextureEscrow _sceneTextureEscrow; bool _vsyncSupported { false }; + QElapsedTimer _sinceSync; }; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 6fc6062214..c2e10dcc02 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -58,7 +58,7 @@ public: /// By default, all HMDs are stereo virtual bool isStereo() const { return isHmd(); } virtual bool isThrottled() const { return false; } - virtual qint64 getLastSynchronizedElapsed() { return 0; } + virtual quint64 getTimeSinceSync() { return 0; } // Rendering support From 2604b4965061075c7aede8163469ad263bae473a Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 8 Dec 2015 15:35:43 -0800 Subject: [PATCH 43/78] Fix occasional crashes switching from the Oculus plugin --- .../display-plugins/OpenGLDisplayPlugin.cpp | 30 ++++++++++++++----- .../src/display-plugins/OpenGLDisplayPlugin.h | 11 ++++++- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 9a0db0ad97..80710e9b96 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -54,6 +54,7 @@ public: } virtual void run() override { + OpenGLDisplayPlugin* currentPlugin{ nullptr }; Q_ASSERT(_context); while (!_shutdown) { if (_pendingMainThreadOperation) { @@ -81,12 +82,13 @@ public: // Check if we have a new plugin to activate if (_newPlugin != nullptr) { // Deactivate the old plugin - if (_activePlugin != nullptr) { - _activePlugin->uncustomizeContext(); + if (currentPlugin != nullptr) { + currentPlugin->uncustomizeContext(); + currentPlugin->enableDeactivate(); } _newPlugin->customizeContext(); - _activePlugin = _newPlugin; + currentPlugin = _newPlugin; _newPlugin = nullptr; } _context->doneCurrent(); @@ -94,20 +96,21 @@ public: } // If there's no active plugin, just sleep - if (_activePlugin == nullptr) { + if (currentPlugin == nullptr) { QThread::usleep(100); continue; } // take the latest texture and present it _context->makeCurrent(); - _activePlugin->present(); + currentPlugin->present(); _context->doneCurrent(); } _context->makeCurrent(); - if (_activePlugin) { - _activePlugin->uncustomizeContext(); + if (currentPlugin) { + currentPlugin->uncustomizeContext(); + currentPlugin->enableDeactivate(); } _context->doneCurrent(); _context->moveToThread(qApp->thread()); @@ -147,7 +150,6 @@ private: bool _finishedMainThreadOperation { false }; QThread* _mainThread { nullptr }; OpenGLDisplayPlugin* _newPlugin { nullptr }; - OpenGLDisplayPlugin* _activePlugin { nullptr }; QGLContext* _context { nullptr }; }; @@ -208,11 +210,16 @@ void OpenGLDisplayPlugin::stop() { } void OpenGLDisplayPlugin::deactivate() { + { + Lock lock(_mutex); + _deactivateWait.wait(lock, [&]{ return _uncustomized; }); + } _timer.stop(); DisplayPlugin::deactivate(); } void OpenGLDisplayPlugin::customizeContext() { + _uncustomized = false; auto presentThread = DependencyManager::get(); Q_ASSERT(thread() == presentThread->thread()); @@ -233,6 +240,7 @@ void OpenGLDisplayPlugin::uncustomizeContext() { _plane.reset(); } + // Pressing Alt (and Meta) key alone activates the menubar because its style inherits the // SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to // receive keyPress events for the Alt (and Meta) key in a reliable manner. @@ -380,3 +388,9 @@ QImage OpenGLDisplayPlugin::getScreenshot() const { }); return result; } + +void OpenGLDisplayPlugin::enableDeactivate() { + Lock lock(_mutex); + _uncustomized = true; + _deactivateWait.notify_one(); +} \ No newline at end of file diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index ef78374994..88ccddc125 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -9,6 +9,8 @@ #include "DisplayPlugin.h" +#include + #include #include @@ -18,8 +20,9 @@ class OpenGLDisplayPlugin : public DisplayPlugin { protected: - using Mutex = std::recursive_mutex; + using Mutex = std::mutex; using Lock = std::unique_lock; + using Condition = std::condition_variable; public: OpenGLDisplayPlugin(); virtual void activate() override; @@ -82,6 +85,12 @@ protected: GLTextureEscrow _sceneTextureEscrow; bool _vsyncSupported { false }; + +private: + void enableDeactivate(); + Condition _deactivateWait; + bool _uncustomized{ false }; + }; From 32e4967ee0a66e8b2f9eba8a06e53b5d553b0d19 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Tue, 8 Dec 2015 16:38:05 -0800 Subject: [PATCH 44/78] cleanup --- interface/src/Application.cpp | 37 ++++--------------- interface/src/Application.h | 10 +---- interface/src/avatar/Avatar.cpp | 4 +- interface/src/avatar/AvatarManager.cpp | 23 ++---------- .../display-plugins/OpenGLDisplayPlugin.cpp | 3 +- .../src/display-plugins/OpenGLDisplayPlugin.h | 3 -- libraries/plugins/src/plugins/DisplayPlugin.h | 1 - libraries/shared/src/PIDController.cpp | 8 ++-- libraries/shared/src/PIDController.h | 5 +-- 9 files changed, 20 insertions(+), 74 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f56231ada8..78882342df 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1086,7 +1086,6 @@ void Application::paintGL() { // update fps moving average uint64_t now = usecTimestampNow(); - qint64 sinceSync = getActiveDisplayPlugin()->getTimeSinceSync(); static uint64_t lastPaintBegin{ now }; uint64_t diff = now - lastPaintBegin; float instantaneousFps = 0.0f; @@ -1123,31 +1122,6 @@ void Application::paintGL() { _inPaint = true; Finally clearFlagLambda([this] { _inPaint = false; }); - //_lastPaintWait = (float)(now - _paintWaitStart) / (float)USECS_PER_SECOND; - //_lastInstantaneousFps = instantaneousFps; - // Some LOD-like controls need to know a smoothly varying "potential" frame rate that doesn't - // include time waiting for vsync, and which can report a number above target if we've got the headroom. - // For example, if we're shooting for 75fps and paintWait is 3.3333ms (= 75% * 13.33ms), our deducedNonVSyncFps - // would be 100fps. In principle, a paintWait of zero would have deducedNonVSyncFps=75. - // Here we make a guess for deducedNonVSyncFps = 1 / deducedNonVSyncPeriod. - // - // Time between previous paintGL call and this one, which can vary not only with vSync misses, but also with QT timing. - // We're using this as a proxy for the time between vsync and displayEnd, below. (Not exact, but tends to be the same over time.) - // This is not the same as update(deltaTime), because the latter attempts to throttle to 60hz and also clamps to 1/4 second. -/* const float actualPeriod = diff / (float)USECS_PER_SECOND; // same as 1/instantaneousFps but easier for compiler to optimize - // Note that _lastPaintWait (stored at end of last call) is for the same paint cycle. - float deducedNonVSyncPeriod = actualPeriod - _lastPaintWait + _marginForDeducedFramePeriod; // plus a some non-zero time for machinery we can't measure - // We don't know how much time to allow for that, but if we went over the target period, we know it's at least the portion - // of paintWait up to the next vSync. This gives us enough of a penalty so that when actualPeriod crosses two cycles, - // the key part (and not an exagerated part) of _lastPaintWait is accounted for. - const float targetPeriod = getTargetFramePeriod(); - if (_lastPaintWait > EPSILON && actualPeriod > targetPeriod) { - // Don't use C++ remainder(). It's authors are mathematically insane. - deducedNonVSyncPeriod += fmod(targetPeriod, _lastPaintWait); - } - _lastDeducedNonVSyncFps = 1.0f / deducedNonVSyncPeriod; - */ - auto displayPlugin = getActiveDisplayPlugin(); // FIXME not needed anymore? _offscreenContext->makeCurrent(); @@ -1422,11 +1396,14 @@ void Application::paintGL() { batch.resetStages(); }); } - _paintWaitStart = usecTimestampNow(); - _lastPaintWait = (float)sinceSync / (float)MSECS_PER_SECOND; + + // Some LOD-like controls need to know a smoothly varying "potential" frame rate that doesn't + // include time waiting for sync, and which can report a number above target if we've got the headroom. + // In my tests, the following is mostly less than 0.5ms, and never more than 3ms. I don't think its worth measuring during runtime. + static const float paintWaitAndQTTimerAllowance = 0.001; // seconds + // Store both values now for use by next cycle. _lastInstantaneousFps = instantaneousFps; - _lastDeducedNonVSyncFps = 1.0f / (((_paintWaitStart - now) / (float)USECS_PER_SECOND) + ((float)sinceSync / (float)MSECS_PER_SECOND)); - // qCDebug(interfaceapp) << "pw/now/sync" << _paintWaitStart << now << sinceSync << "period" << (((_paintWaitStart - now) / (float)USECS_PER_SECOND) + ((float)sinceSync / (float)MSECS_PER_SECOND)) << "hz" << _lastDeducedNonVSyncFps; + _lastUnsynchronizedFps = 1.0f / (((usecTimestampNow() - now) / (float)USECS_PER_SECOND) + paintWaitAndQTTimerAllowance); } void Application::runTests() { diff --git a/interface/src/Application.h b/interface/src/Application.h index 197d9a7a60..17d609ee0c 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -163,11 +163,8 @@ public: float const HMD_TARGET_FRAME_RATE = 75.0f; float const DESKTOP_TARGET_FRAME_RATE = 60.0f; float getTargetFrameRate() { return isHMDMode() ? HMD_TARGET_FRAME_RATE : DESKTOP_TARGET_FRAME_RATE; } - float getTargetFramePeriod() { return isHMDMode() ? 1.0f / HMD_TARGET_FRAME_RATE : 1.0f / DESKTOP_TARGET_FRAME_RATE; } // same as 1/getTargetFrameRate, but w/compile-time division float getLastInstanteousFps() const { return _lastInstantaneousFps; } - float getLastPaintWait() const { return _lastPaintWait; }; - float getLastDeducedNonVSyncFps() const { return _lastDeducedNonVSyncFps; } - void setMarginForDeducedFramePeriod(float newValue) { _marginForDeducedFramePeriod = newValue; } + float getLastUnsynchronizedFps() const { return _lastUnsynchronizedFps; } float getFieldOfView() { return _fieldOfView.get(); } void setFieldOfView(float fov); @@ -442,10 +439,7 @@ private: QElapsedTimer _timerStart; QElapsedTimer _lastTimeUpdated; float _lastInstantaneousFps { 0.0f }; - float _lastPaintWait { 0.0f }; - uint64_t _paintWaitStart { 0 }; - float _lastDeducedNonVSyncFps { 0.0f }; - float _marginForDeducedFramePeriod{ 0.002f }; // 2ms, adjustable + float _lastUnsynchronizedFps { 0.0f }; ShapeManager _shapeManager; PhysicalEntitySimulation _entitySimulation; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index e3b7cd5735..e2b92cc06f 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -174,14 +174,14 @@ void Avatar::simulate(float deltaTime) { _shouldSkipRender = false; _skeletonModel.setVisibleInScene(true, qApp->getMain3DScene()); if (!isControllerLogging) { // Test for isMyAvatar is prophylactic. Never occurs in current code. - //qCDebug(interfaceapp) << "Rerendering" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for distance" << renderDistance; + qCDebug(interfaceapp) << "Rerendering" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for distance" << renderDistance; } } } else if (distance > renderDistance * (1.0f + SKIP_HYSTERESIS_PROPORTION)) { _shouldSkipRender = true; _skeletonModel.setVisibleInScene(false, qApp->getMain3DScene()); if (!isControllerLogging) { - //qCDebug(interfaceapp) << "Unrendering" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for distance" << renderDistance; + qCDebug(interfaceapp) << "Unrendering" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for distance" << renderDistance; } } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index c0485bdebb..59af6b18df 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -111,7 +111,6 @@ void AvatarManager::init() { _renderDistanceController.setKP(0.0008f); // Usually about 0.6 of largest that doesn't oscillate when other parameters 0. _renderDistanceController.setKI(0.0006f); // Big enough to bring us to target with the above KP. _renderDistanceController.setKD(0.000001f); // A touch of kd increases the speed by which we get there. - _renderDistanceController.setHistorySize("av", 240); //FIXME } void AvatarManager::updateMyAvatar(float deltaTime) { @@ -130,7 +129,7 @@ void AvatarManager::updateMyAvatar(float deltaTime) { _lastSendAvatarDataTime = now; } } -#include "InterfaceLogging.h" + void AvatarManager::updateOtherAvatars(float deltaTime) { // lock the hash for read to check the size QReadLocker lock(&_hashLock); @@ -151,24 +150,8 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { // The measured value is frame rate. When the controlled value (1 / render cutoff distance) // goes up, the render cutoff distance gets closer, the number of rendered avatars is less, and frame rate // goes up. - const float targetFps = 60.0f; - const float instantaneousFps = qApp->getLastInstanteousFps(); - const float paintWait = qApp->getLastPaintWait(); - const float deduced = qApp->getLastDeducedNonVSyncFps(); - /*const float actual = 1.0f / instantaneousFps; - const float target = 1.0f / targetFps; - const float modulus = (instantaneousFps >= targetFps) ? - (1.0f + floor(instantaneousFps / targetFps)) : - (1.0f / floor(targetFps / instantaneousFps)); - const float cap = modulus * targetFps; - const float deduced = instantaneousFps + ((cap - instantaneousFps) * (paintWait / target));*/ - /*qCDebug(interfaceapp) << "dump " << instantaneousFps << (1000.0f * paintWait) - << "(" << paintWait << actual - << "(" << firstAdjusted << machinery << secondAdjusted - << ")" << deduced << modulus << cap << capped << ")";*/ - - //const float deduced = qApp->getLastDeducedNonVSyncFps(); - const float distance = 1.0f / _renderDistanceController.update(deduced, deltaTime, false, paintWait, instantaneousFps); + const float deduced = qApp->getLastUnsynchronizedFps(); + const float distance = 1.0f / _renderDistanceController.update(deduced, deltaTime); _renderDistanceAverage.updateAverage(distance); _renderDistance = _renderDistanceAverage.getAverage(); int renderableCount = 0; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index b59ac24b52..9a0db0ad97 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -168,9 +168,8 @@ OpenGLDisplayPlugin::OpenGLDisplayPlugin() { // This is likely to be mooted by further planned changes. if (_active && _sceneTextureEscrow.depth() <= 1) { #else - if (_active && _sceneTextureEscrow.depth() <= 1) { + if (_active && _sceneTextureEscrow.depth() < 1) { #endif - _sinceSync.start(); emit requestRender(); } }); diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 4231c8ff7f..ef78374994 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -10,7 +10,6 @@ #include "DisplayPlugin.h" #include -#include #include #include @@ -41,7 +40,6 @@ public: } virtual QImage getScreenshot() const override; - virtual quint64 getTimeSinceSync() { return _sinceSync.elapsed(); } protected: friend class PresentThread; @@ -84,7 +82,6 @@ protected: GLTextureEscrow _sceneTextureEscrow; bool _vsyncSupported { false }; - QElapsedTimer _sinceSync; }; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index c2e10dcc02..83afbc9402 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -58,7 +58,6 @@ public: /// By default, all HMDs are stereo virtual bool isStereo() const { return isHmd(); } virtual bool isThrottled() const { return false; } - virtual quint64 getTimeSinceSync() { return 0; } // Rendering support diff --git a/libraries/shared/src/PIDController.cpp b/libraries/shared/src/PIDController.cpp index 3607c281ec..78aa31e4c7 100644 --- a/libraries/shared/src/PIDController.cpp +++ b/libraries/shared/src/PIDController.cpp @@ -14,7 +14,7 @@ #include "SharedLogging.h" #include "PIDController.h" -float PIDController::update(float measuredValue, float dt, bool resetAccumulator, float fixme1, float fixme2) { +float PIDController::update(float measuredValue, float dt, bool resetAccumulator) { const float error = getMeasuredValueSetpoint() - measuredValue; // Sign is the direction we want measuredValue to go. Positive means go higher. const float p = getKP() * error; // term is Proportional to error @@ -32,7 +32,7 @@ float PIDController::update(float measuredValue, float dt, bool resetAccumulator getControlledValueHighLimit()); if (getIsLogging()) { // if logging/reporting - updateHistory(measuredValue, dt, error, accumulatedError, changeInError, p, i, d, computedValue, fixme1, fixme2); + updateHistory(measuredValue, dt, error, accumulatedError, changeInError, p, i, d, computedValue); } Q_ASSERT(!isnan(computedValue)); @@ -43,7 +43,7 @@ float PIDController::update(float measuredValue, float dt, bool resetAccumulator } // Just for logging/reporting. Used when picking/verifying the operational parameters. -void PIDController::updateHistory(float measuredValue, float dt, float error, float accumulatedError, float changeInError, float p, float i, float d, float computedValue, float fixme1, float fixme2) { +void PIDController::updateHistory(float measuredValue, float dt, float error, float accumulatedError, float changeInError, float p, float i, float d, float computedValue) { // Don't report each update(), as the I/O messes with the results a lot. // Instead, add to history, and then dump out at once when full. // Typically, the first few values reported in each batch should be ignored. @@ -59,7 +59,6 @@ void PIDController::updateHistory(float measuredValue, float dt, float error, fl next.i = i; next.d = d; next.computed = computedValue; - next.fixme1 = fixme1; next.fixme2 = fixme2; if (_history.size() == _history.capacity()) { // report when buffer is full reportHistory(); _history.resize(0); @@ -70,7 +69,6 @@ void PIDController::reportHistory() { for (int i = 0; i < _history.size(); i++) { Row& row = _history[i]; qCDebug(shared) << row.measured << row.dt << - (row.fixme1 * 1000.0f) << (row.fixme2) << "||" << row.error << row.accumulated << row.changed << "||" << row.p << row.i << row.d << row.computed << 1.0f/row.computed; } diff --git a/libraries/shared/src/PIDController.h b/libraries/shared/src/PIDController.h index 24e619b13b..0b2411530a 100644 --- a/libraries/shared/src/PIDController.h +++ b/libraries/shared/src/PIDController.h @@ -28,7 +28,7 @@ class PIDController { public: // These are the main interfaces: void setMeasuredValueSetpoint(float newValue) { _measuredValueSetpoint = newValue; } - float update(float measuredValue, float dt, bool resetAccumulator = false, float fixme1=0, float fixme2=0); // returns the new computedValue + float update(float measuredValue, float dt, bool resetAccumulator = false); // returns the new computedValue void setHistorySize(QString label = QString(""), int size = 0) { _history.reserve(size); _history.resize(0); _label = label; } // non-empty does logging bool getIsLogging() { return _history.capacity(); } @@ -64,11 +64,10 @@ public: float i; float d; float computed; - float fixme1; float fixme2; }; protected: void reportHistory(); - void updateHistory(float measured, float dt, float error, float accumulatedError, float changeInErro, float p, float i, float d, float computedValue, float fixme1, float fixme2); + void updateHistory(float measured, float dt, float error, float accumulatedError, float changeInErro, float p, float i, float d, float computedValue); float _measuredValueSetpoint { 0.0f }; float _controlledValueLowLimit { 0.0f }; float _controlledValueHighLimit { std::numeric_limits::max() }; From e77f2e8ac47defd8aad70a3e385eabd45e2f2c2d Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 8 Dec 2015 16:49:50 -0800 Subject: [PATCH 45/78] Pass correct frame index into Oculus SDK --- plugins/oculus/src/OculusDisplayPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp index 8846b8a6a6..e6eae2cf02 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -230,7 +230,7 @@ void OculusDisplayPlugin::internalPresent() { viewScaleDesc.HmdToEyeViewOffset[1] = _eyeOffsets[1]; ovrLayerHeader* layers = &_sceneLayer.Header; - ovrResult result = ovr_SubmitFrame(_hmd, 0, &viewScaleDesc, &layers, 1); + ovrResult result = ovr_SubmitFrame(_hmd, frameIndex, &viewScaleDesc, &layers, 1); if (!OVR_SUCCESS(result)) { qDebug() << result; } From 8c109fd6238cf60e99fbe5e101786013e8bac356 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 8 Dec 2015 17:21:43 -0800 Subject: [PATCH 46/78] move raw bullet code from interface to physics lib --- interface/src/avatar/MyAvatar.cpp | 4 +- .../src/avatar/MyCharacterController.cpp | 329 +----------------- interface/src/avatar/MyCharacterController.h | 75 +--- libraries/physics/src/CharacterController.cpp | 329 +++++++++++++++++- libraries/physics/src/CharacterController.h | 85 ++++- 5 files changed, 405 insertions(+), 417 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6637331b64..34821e6737 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1058,7 +1058,7 @@ void MyAvatar::rebuildSkeletonBody() { void MyAvatar::prepareForPhysicsSimulation() { relayDriveKeysToCharacterController(); _characterController.setTargetVelocity(getTargetVelocity()); - _characterController.setAvatarPositionAndOrientation(getPosition(), getOrientation()); + _characterController.setPositionAndOrientation(getPosition(), getOrientation()); if (qApp->isHMDMode()) { updateHMDFollowVelocity(); } else if (_followSpeed > 0.0f) { @@ -1071,7 +1071,7 @@ void MyAvatar::prepareForPhysicsSimulation() { void MyAvatar::harvestResultsFromPhysicsSimulation() { glm::vec3 position = getPosition(); glm::quat orientation = getOrientation(); - _characterController.getAvatarPositionAndOrientation(position, orientation); + _characterController.getPositionAndOrientation(position, orientation); nextAttitude(position, orientation); if (_followSpeed > 0.0f) { adjustSensorTransform(); diff --git a/interface/src/avatar/MyCharacterController.cpp b/interface/src/avatar/MyCharacterController.cpp index e8f686da6f..23d601e58e 100644 --- a/interface/src/avatar/MyCharacterController.cpp +++ b/interface/src/avatar/MyCharacterController.cpp @@ -11,255 +11,25 @@ #include "MyCharacterController.h" -#include -#include -#include -#include - -#include -#include -#include +#include #include "MyAvatar.h" -const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f); -const float DEFAULT_GRAVITY = -5.0f; -const float JUMP_SPEED = 3.5f; - -const float MAX_FALL_HEIGHT = 20.0f; - // TODO: improve walking up steps // TODO: make avatars able to walk up and down steps/slopes // TODO: make avatars stand on steep slope // TODO: make avatars not snag on low ceilings -// helper class for simple ray-traces from character -class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback { -public: - ClosestNotMe(btRigidBody* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0f, 0.0f, 0.0f), btVector3(0.0f, 0.0f, 0.0f)) { - _me = me; - } - virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) { - if (rayResult.m_collisionObject == _me) { - return 1.0f; - } - return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace); - } -protected: - btRigidBody* _me; -}; - MyCharacterController::MyCharacterController(MyAvatar* avatar) { - _halfHeight = 1.0f; assert(avatar); _avatar = avatar; - - _enabled = false; - - _floorDistance = MAX_FALL_HEIGHT; - - _walkVelocity.setValue(0.0f, 0.0f, 0.0f); - _followVelocity.setValue(0.0f, 0.0f, 0.0f); - _jumpSpeed = JUMP_SPEED; - _isOnGround = false; - _isJumping = false; - _isFalling = false; - _isHovering = true; - _isPushingUp = false; - _jumpToHoverStart = 0; - _followTime = 0.0f; - - _pendingFlags = PENDING_FLAG_UPDATE_SHAPE; updateShapeIfNecessary(); } MyCharacterController::~MyCharacterController() { } -void MyCharacterController::preStep(btCollisionWorld* collisionWorld) { - // trace a ray straight down to see if we're standing on the ground - const btTransform& xform = _rigidBody->getWorldTransform(); - - // rayStart is at center of bottom sphere - btVector3 rayStart = xform.getOrigin() - _halfHeight * _currentUp; - - // rayEnd is some short distance outside bottom sphere - const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius; - btScalar rayLength = _radius + FLOOR_PROXIMITY_THRESHOLD; - btVector3 rayEnd = rayStart - rayLength * _currentUp; - - // scan down for nearby floor - ClosestNotMe rayCallback(_rigidBody); - rayCallback.m_closestHitFraction = 1.0f; - collisionWorld->rayTest(rayStart, rayEnd, rayCallback); - if (rayCallback.hasHit()) { - _floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius; - } -} - -void MyCharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) { - btVector3 actualVelocity = _rigidBody->getLinearVelocity(); - btScalar actualSpeed = actualVelocity.length(); - - btVector3 desiredVelocity = _walkVelocity; - btScalar desiredSpeed = desiredVelocity.length(); - - const btScalar MIN_UP_PUSH = 0.1f; - if (desiredVelocity.dot(_currentUp) < MIN_UP_PUSH) { - _isPushingUp = false; - } - - const btScalar MIN_SPEED = 0.001f; - if (_isHovering) { - if (desiredSpeed < MIN_SPEED) { - if (actualSpeed < MIN_SPEED) { - _rigidBody->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f)); - } else { - const btScalar HOVER_BRAKING_TIMESCALE = 0.1f; - btScalar tau = glm::max(dt / HOVER_BRAKING_TIMESCALE, 1.0f); - _rigidBody->setLinearVelocity((1.0f - tau) * actualVelocity); - } - } else { - const btScalar HOVER_ACCELERATION_TIMESCALE = 0.1f; - btScalar tau = dt / HOVER_ACCELERATION_TIMESCALE; - _rigidBody->setLinearVelocity(actualVelocity - tau * (actualVelocity - desiredVelocity)); - } - } else { - if (onGround()) { - // walking on ground - if (desiredSpeed < MIN_SPEED) { - if (actualSpeed < MIN_SPEED) { - _rigidBody->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f)); - } else { - const btScalar HOVER_BRAKING_TIMESCALE = 0.1f; - btScalar tau = dt / HOVER_BRAKING_TIMESCALE; - _rigidBody->setLinearVelocity((1.0f - tau) * actualVelocity); - } - } else { - // TODO: modify desiredVelocity using floor normal - const btScalar WALK_ACCELERATION_TIMESCALE = 0.1f; - btScalar tau = dt / WALK_ACCELERATION_TIMESCALE; - btVector3 velocityCorrection = tau * (desiredVelocity - actualVelocity); - // subtract vertical component - velocityCorrection -= velocityCorrection.dot(_currentUp) * _currentUp; - _rigidBody->setLinearVelocity(actualVelocity + velocityCorrection); - } - } else { - // transitioning to flying - btVector3 velocityCorrection = desiredVelocity - actualVelocity; - const btScalar FLY_ACCELERATION_TIMESCALE = 0.2f; - btScalar tau = dt / FLY_ACCELERATION_TIMESCALE; - if (!_isPushingUp) { - // actually falling --> compute a different velocity attenuation factor - const btScalar FALL_ACCELERATION_TIMESCALE = 2.0f; - tau = dt / FALL_ACCELERATION_TIMESCALE; - // zero vertical component - velocityCorrection -= velocityCorrection.dot(_currentUp) * _currentUp; - } - _rigidBody->setLinearVelocity(actualVelocity + tau * velocityCorrection); - } - } - - // Rather than add _followVelocity to the velocity of the RigidBody, we explicitly teleport - // the RigidBody forward according to the formula: distance = rate * time - if (_followVelocity.length2() > 0.0f) { - btTransform bodyTransform = _rigidBody->getWorldTransform(); - bodyTransform.setOrigin(bodyTransform.getOrigin() + dt * _followVelocity); - _rigidBody->setWorldTransform(bodyTransform); - } - _followTime += dt; -} - -void MyCharacterController::jump() { - // check for case where user is holding down "jump" key... - // we'll eventually tansition to "hover" - if (!_isJumping) { - if (!_isHovering) { - _jumpToHoverStart = usecTimestampNow(); - _pendingFlags |= PENDING_FLAG_JUMP; - } - } else { - quint64 now = usecTimestampNow(); - const quint64 JUMP_TO_HOVER_PERIOD = 75 * (USECS_PER_SECOND / 100); - if (now - _jumpToHoverStart > JUMP_TO_HOVER_PERIOD) { - _isPushingUp = true; - setHovering(true); - } - } -} - -bool MyCharacterController::onGround() const { - const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius; - return _floorDistance < FLOOR_PROXIMITY_THRESHOLD; -} - -void MyCharacterController::setHovering(bool hover) { - if (hover != _isHovering) { - _isHovering = hover; - _isJumping = false; - - if (_rigidBody) { - if (hover) { - _rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f)); - } else { - _rigidBody->setGravity(DEFAULT_GRAVITY * _currentUp); - } - } - } -} - -void MyCharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) { - _boxScale = scale; - - float x = _boxScale.x; - float z = _boxScale.z; - float radius = 0.5f * sqrtf(0.5f * (x * x + z * z)); - float halfHeight = 0.5f * _boxScale.y - radius; - float MIN_HALF_HEIGHT = 0.1f; - if (halfHeight < MIN_HALF_HEIGHT) { - halfHeight = MIN_HALF_HEIGHT; - } - - // compare dimensions - float radiusDelta = glm::abs(radius - _radius); - float heightDelta = glm::abs(halfHeight - _halfHeight); - if (radiusDelta < FLT_EPSILON && heightDelta < FLT_EPSILON) { - // shape hasn't changed --> nothing to do - } else { - if (_dynamicsWorld) { - // must REMOVE from world prior to shape update - _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION; - } - _pendingFlags |= PENDING_FLAG_UPDATE_SHAPE; - // only need to ADD back when we happen to be enabled - if (_enabled) { - _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION; - } - } - - // it's ok to change offset immediately -- there are no thread safety issues here - _shapeLocalOffset = corner + 0.5f * _boxScale; -} - -void MyCharacterController::setEnabled(bool enabled) { - if (enabled != _enabled) { - if (enabled) { - // Don't bother clearing REMOVE bit since it might be paired with an UPDATE_SHAPE bit. - // Setting the ADD bit here works for all cases so we don't even bother checking other bits. - _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION; - } else { - if (_dynamicsWorld) { - _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION; - } - _pendingFlags &= ~ PENDING_FLAG_ADD_TO_SIMULATION; - _isOnGround = false; - } - setHovering(true); - _enabled = enabled; - } -} - void MyCharacterController::updateShapeIfNecessary() { if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { _pendingFlags &= ~ PENDING_FLAG_UPDATE_SHAPE; @@ -300,7 +70,7 @@ void MyCharacterController::updateShapeIfNecessary() { if (_isHovering) { _rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f)); } else { - _rigidBody->setGravity(DEFAULT_GRAVITY * _currentUp); + _rigidBody->setGravity(DEFAULT_CHARACTER_GRAVITY * _currentUp); } //_rigidBody->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT); } else { @@ -309,98 +79,3 @@ void MyCharacterController::updateShapeIfNecessary() { } } -void MyCharacterController::updateUpAxis(const glm::quat& rotation) { - btVector3 oldUp = _currentUp; - _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS); - if (!_isHovering) { - const btScalar MIN_UP_ERROR = 0.01f; - if (oldUp.distance(_currentUp) > MIN_UP_ERROR) { - _rigidBody->setGravity(DEFAULT_GRAVITY * _currentUp); - } - } -} - -void MyCharacterController::setAvatarPositionAndOrientation( - const glm::vec3& position, - const glm::quat& orientation) { - // TODO: update gravity if up has changed - updateUpAxis(orientation); - - btQuaternion bodyOrientation = glmToBullet(orientation); - btVector3 bodyPosition = glmToBullet(position + orientation * _shapeLocalOffset); - _avatarBodyTransform = btTransform(bodyOrientation, bodyPosition); -} - -void MyCharacterController::getAvatarPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const { - if (_enabled && _rigidBody) { - const btTransform& avatarTransform = _rigidBody->getWorldTransform(); - rotation = bulletToGLM(avatarTransform.getRotation()); - position = bulletToGLM(avatarTransform.getOrigin()) - rotation * _shapeLocalOffset; - } -} - -void MyCharacterController::setTargetVelocity(const glm::vec3& velocity) { - //_walkVelocity = glmToBullet(_avatarData->getTargetVelocity()); - _walkVelocity = glmToBullet(velocity); -} - -void MyCharacterController::setFollowVelocity(const glm::vec3& velocity) { - _followVelocity = glmToBullet(velocity); -} - -glm::vec3 MyCharacterController::getLinearVelocity() const { - glm::vec3 velocity(0.0f); - if (_rigidBody) { - velocity = bulletToGLM(_rigidBody->getLinearVelocity()); - } - return velocity; -} - -void MyCharacterController::preSimulation() { - if (_enabled && _dynamicsWorld) { - // slam body to where it is supposed to be - _rigidBody->setWorldTransform(_avatarBodyTransform); - - // scan for distant floor - // rayStart is at center of bottom sphere - btVector3 rayStart = _avatarBodyTransform.getOrigin() - _halfHeight * _currentUp; - - // rayEnd is straight down MAX_FALL_HEIGHT - btScalar rayLength = _radius + MAX_FALL_HEIGHT; - btVector3 rayEnd = rayStart - rayLength * _currentUp; - - ClosestNotMe rayCallback(_rigidBody); - rayCallback.m_closestHitFraction = 1.0f; - _dynamicsWorld->rayTest(rayStart, rayEnd, rayCallback); - if (rayCallback.hasHit()) { - _floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius; - const btScalar MIN_HOVER_HEIGHT = 3.0f; - if (_isHovering && _floorDistance < MIN_HOVER_HEIGHT && !_isPushingUp) { - setHovering(false); - } - // TODO: use collision events rather than ray-trace test to disable jumping - const btScalar JUMP_PROXIMITY_THRESHOLD = 0.1f * _radius; - if (_floorDistance < JUMP_PROXIMITY_THRESHOLD) { - _isJumping = false; - } - } else { - _floorDistance = FLT_MAX; - setHovering(true); - } - - if (_pendingFlags & PENDING_FLAG_JUMP) { - _pendingFlags &= ~ PENDING_FLAG_JUMP; - if (onGround()) { - _isJumping = true; - btVector3 velocity = _rigidBody->getLinearVelocity(); - velocity += _jumpSpeed * _currentUp; - _rigidBody->setLinearVelocity(velocity); - } - } - } - _followTime = 0.0f; -} - -void MyCharacterController::postSimulation() { - // postSimulation() exists for symmetry and just in case we need to do something here later -} diff --git a/interface/src/avatar/MyCharacterController.h b/interface/src/avatar/MyCharacterController.h index 82aa958309..39f0f99917 100644 --- a/interface/src/avatar/MyCharacterController.h +++ b/interface/src/avatar/MyCharacterController.h @@ -13,12 +13,8 @@ #ifndef hifi_MyCharacterController_h #define hifi_MyCharacterController_h -#include -#include - -#include #include -#include +//#include class btCollisionShape; class MyAvatar; @@ -28,79 +24,10 @@ public: MyCharacterController(MyAvatar* avatar); ~MyCharacterController (); - // TODO: implement these when needed - virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) override { assert(false); } - virtual void reset(btCollisionWorld* collisionWorld) override { } - virtual void warp(const btVector3& origin) override { } - virtual void debugDraw(btIDebugDraw* debugDrawer) override { } - virtual void setUpInterpolate(bool value) override { } - - // overrides from btCharacterControllerInterface - virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTime) override { - preStep(collisionWorld); - playerStep(collisionWorld, deltaTime); - } - virtual void preStep(btCollisionWorld* collisionWorld) override; - virtual void playerStep(btCollisionWorld* collisionWorld, btScalar dt) override; - virtual bool canJump() const override { assert(false); return false; } // never call this - virtual void jump() override; // call this every frame the jump button is pressed - virtual bool onGround() const override; - - // overrides from CharacterController - virtual void preSimulation() override; - virtual void postSimulation() override; - - bool isHovering() const { return _isHovering; } - void setHovering(bool enabled); - - void setEnabled(bool enabled); - bool isEnabled() const { return _enabled && _dynamicsWorld; } - - void setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale); - virtual void updateShapeIfNecessary() override; - void setAvatarPositionAndOrientation( const glm::vec3& position, const glm::quat& orientation); - void getAvatarPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const; - - void setTargetVelocity(const glm::vec3& velocity); - void setFollowVelocity(const glm::vec3& velocity); - float getFollowTime() const { return _followTime; } - - glm::vec3 getLinearVelocity() const; - protected: - void updateUpAxis(const glm::quat& rotation); - -protected: - btVector3 _currentUp; - btVector3 _walkVelocity; - btVector3 _followVelocity; - btTransform _avatarBodyTransform; - - glm::vec3 _shapeLocalOffset; - glm::vec3 _boxScale; // used to compute capsule shape - - quint64 _jumpToHoverStart; - MyAvatar* _avatar { nullptr }; - - btScalar _halfHeight; - btScalar _radius; - - btScalar _floorDistance; - - btScalar _gravity; - - btScalar _jumpSpeed; - btScalar _followTime; - - bool _enabled; - bool _isOnGround; - bool _isJumping; - bool _isFalling; - bool _isHovering; - bool _isPushingUp; }; #endif // hifi_MyCharacterController_h diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 8da9541387..ba3a59f69d 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -11,8 +11,55 @@ #include "CharacterController.h" +#include + +#include "BulletUtil.h" #include "PhysicsCollisionGroups.h" +const btVector3 LOCAL_UP_AXIS(0.0f, 1.0f, 0.0f); +const float JUMP_SPEED = 3.5f; +const float MAX_FALL_HEIGHT = 20.0f; + + +// helper class for simple ray-traces from character +class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback { +public: + ClosestNotMe(btRigidBody* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0f, 0.0f, 0.0f), btVector3(0.0f, 0.0f, 0.0f)) { + _me = me; + } + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) { + if (rayResult.m_collisionObject == _me) { + return 1.0f; + } + return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace); + } +protected: + btRigidBody* _me; +}; + + +CharacterController::CharacterController() { + _halfHeight = 1.0f; + + _enabled = false; + + _floorDistance = MAX_FALL_HEIGHT; + + _walkVelocity.setValue(0.0f, 0.0f, 0.0f); + _followVelocity.setValue(0.0f, 0.0f, 0.0f); + _jumpSpeed = JUMP_SPEED; + _isOnGround = false; + _isJumping = false; + _isFalling = false; + _isHovering = true; + _isPushingUp = false; + _jumpToHoverStart = 0; + _followTime = 0.0f; + + _pendingFlags = PENDING_FLAG_UPDATE_SHAPE; + +} + bool CharacterController::needsRemoval() const { return ((_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION) == PENDING_FLAG_REMOVE_FROM_SIMULATION); } @@ -23,7 +70,7 @@ bool CharacterController::needsAddition() const { void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { if (_dynamicsWorld != world) { - if (_dynamicsWorld) { + if (_dynamicsWorld) { if (_rigidBody) { _dynamicsWorld->removeRigidBody(_rigidBody); _dynamicsWorld->removeAction(this); @@ -48,5 +95,283 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { } else { _pendingFlags &= ~PENDING_FLAG_REMOVE_FROM_SIMULATION; } -} +} +void CharacterController::preStep(btCollisionWorld* collisionWorld) { + // trace a ray straight down to see if we're standing on the ground + const btTransform& xform = _rigidBody->getWorldTransform(); + + // rayStart is at center of bottom sphere + btVector3 rayStart = xform.getOrigin() - _halfHeight * _currentUp; + + // rayEnd is some short distance outside bottom sphere + const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius; + btScalar rayLength = _radius + FLOOR_PROXIMITY_THRESHOLD; + btVector3 rayEnd = rayStart - rayLength * _currentUp; + + // scan down for nearby floor + ClosestNotMe rayCallback(_rigidBody); + rayCallback.m_closestHitFraction = 1.0f; + collisionWorld->rayTest(rayStart, rayEnd, rayCallback); + if (rayCallback.hasHit()) { + _floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius; + } +} + +void CharacterController::playerStep(btCollisionWorld* dynaWorld, btScalar dt) { + btVector3 actualVelocity = _rigidBody->getLinearVelocity(); + btScalar actualSpeed = actualVelocity.length(); + + btVector3 desiredVelocity = _walkVelocity; + btScalar desiredSpeed = desiredVelocity.length(); + + const btScalar MIN_UP_PUSH = 0.1f; + if (desiredVelocity.dot(_currentUp) < MIN_UP_PUSH) { + _isPushingUp = false; + } + + const btScalar MIN_SPEED = 0.001f; + if (_isHovering) { + if (desiredSpeed < MIN_SPEED) { + if (actualSpeed < MIN_SPEED) { + _rigidBody->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f)); + } else { + const btScalar HOVER_BRAKING_TIMESCALE = 0.1f; + btScalar tau = glm::max(dt / HOVER_BRAKING_TIMESCALE, 1.0f); + _rigidBody->setLinearVelocity((1.0f - tau) * actualVelocity); + } + } else { + const btScalar HOVER_ACCELERATION_TIMESCALE = 0.1f; + btScalar tau = dt / HOVER_ACCELERATION_TIMESCALE; + _rigidBody->setLinearVelocity(actualVelocity - tau * (actualVelocity - desiredVelocity)); + } + } else { + if (onGround()) { + // walking on ground + if (desiredSpeed < MIN_SPEED) { + if (actualSpeed < MIN_SPEED) { + _rigidBody->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f)); + } else { + const btScalar HOVER_BRAKING_TIMESCALE = 0.1f; + btScalar tau = dt / HOVER_BRAKING_TIMESCALE; + _rigidBody->setLinearVelocity((1.0f - tau) * actualVelocity); + } + } else { + // TODO: modify desiredVelocity using floor normal + const btScalar WALK_ACCELERATION_TIMESCALE = 0.1f; + btScalar tau = dt / WALK_ACCELERATION_TIMESCALE; + btVector3 velocityCorrection = tau * (desiredVelocity - actualVelocity); + // subtract vertical component + velocityCorrection -= velocityCorrection.dot(_currentUp) * _currentUp; + _rigidBody->setLinearVelocity(actualVelocity + velocityCorrection); + } + } else { + // transitioning to flying + btVector3 velocityCorrection = desiredVelocity - actualVelocity; + const btScalar FLY_ACCELERATION_TIMESCALE = 0.2f; + btScalar tau = dt / FLY_ACCELERATION_TIMESCALE; + if (!_isPushingUp) { + // actually falling --> compute a different velocity attenuation factor + const btScalar FALL_ACCELERATION_TIMESCALE = 2.0f; + tau = dt / FALL_ACCELERATION_TIMESCALE; + // zero vertical component + velocityCorrection -= velocityCorrection.dot(_currentUp) * _currentUp; + } + _rigidBody->setLinearVelocity(actualVelocity + tau * velocityCorrection); + } + } + + // Rather than add _followVelocity to the velocity of the RigidBody, we explicitly teleport + // the RigidBody forward according to the formula: distance = rate * time + if (_followVelocity.length2() > 0.0f) { + btTransform bodyTransform = _rigidBody->getWorldTransform(); + bodyTransform.setOrigin(bodyTransform.getOrigin() + dt * _followVelocity); + _rigidBody->setWorldTransform(bodyTransform); + } + _followTime += dt; +} + +void CharacterController::jump() { + // check for case where user is holding down "jump" key... + // we'll eventually tansition to "hover" + if (!_isJumping) { + if (!_isHovering) { + _jumpToHoverStart = usecTimestampNow(); + _pendingFlags |= PENDING_FLAG_JUMP; + } + } else { + quint64 now = usecTimestampNow(); + const quint64 JUMP_TO_HOVER_PERIOD = 75 * (USECS_PER_SECOND / 100); + if (now - _jumpToHoverStart > JUMP_TO_HOVER_PERIOD) { + _isPushingUp = true; + setHovering(true); + } + } +} + +bool CharacterController::onGround() const { + const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius; + return _floorDistance < FLOOR_PROXIMITY_THRESHOLD; +} + +void CharacterController::setHovering(bool hover) { + if (hover != _isHovering) { + _isHovering = hover; + _isJumping = false; + + if (_rigidBody) { + if (hover) { + _rigidBody->setGravity(btVector3(0.0f, 0.0f, 0.0f)); + } else { + _rigidBody->setGravity(DEFAULT_CHARACTER_GRAVITY * _currentUp); + } + } + } +} + +void CharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale) { + _boxScale = scale; + + float x = _boxScale.x; + float z = _boxScale.z; + float radius = 0.5f * sqrtf(0.5f * (x * x + z * z)); + float halfHeight = 0.5f * _boxScale.y - radius; + float MIN_HALF_HEIGHT = 0.1f; + if (halfHeight < MIN_HALF_HEIGHT) { + halfHeight = MIN_HALF_HEIGHT; + } + + // compare dimensions + float radiusDelta = glm::abs(radius - _radius); + float heightDelta = glm::abs(halfHeight - _halfHeight); + if (radiusDelta < FLT_EPSILON && heightDelta < FLT_EPSILON) { + // shape hasn't changed --> nothing to do + } else { + if (_dynamicsWorld) { + // must REMOVE from world prior to shape update + _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION; + } + _pendingFlags |= PENDING_FLAG_UPDATE_SHAPE; + // only need to ADD back when we happen to be enabled + if (_enabled) { + _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION; + } + } + + // it's ok to change offset immediately -- there are no thread safety issues here + _shapeLocalOffset = corner + 0.5f * _boxScale; +} + +void CharacterController::setEnabled(bool enabled) { + if (enabled != _enabled) { + if (enabled) { + // Don't bother clearing REMOVE bit since it might be paired with an UPDATE_SHAPE bit. + // Setting the ADD bit here works for all cases so we don't even bother checking other bits. + _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION; + } else { + if (_dynamicsWorld) { + _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION; + } + _pendingFlags &= ~ PENDING_FLAG_ADD_TO_SIMULATION; + _isOnGround = false; + } + setHovering(true); + _enabled = enabled; + } +} + +void CharacterController::updateUpAxis(const glm::quat& rotation) { + btVector3 oldUp = _currentUp; + _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS); + if (!_isHovering) { + const btScalar MIN_UP_ERROR = 0.01f; + if (oldUp.distance(_currentUp) > MIN_UP_ERROR) { + _rigidBody->setGravity(DEFAULT_CHARACTER_GRAVITY * _currentUp); + } + } +} + +void CharacterController::setPositionAndOrientation( + const glm::vec3& position, + const glm::quat& orientation) { + // TODO: update gravity if up has changed + updateUpAxis(orientation); + + btQuaternion bodyOrientation = glmToBullet(orientation); + btVector3 bodyPosition = glmToBullet(position + orientation * _shapeLocalOffset); + _characterBodyTransform = btTransform(bodyOrientation, bodyPosition); +} + +void CharacterController::getPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const { + if (_enabled && _rigidBody) { + const btTransform& avatarTransform = _rigidBody->getWorldTransform(); + rotation = bulletToGLM(avatarTransform.getRotation()); + position = bulletToGLM(avatarTransform.getOrigin()) - rotation * _shapeLocalOffset; + } +} + +void CharacterController::setTargetVelocity(const glm::vec3& velocity) { + //_walkVelocity = glmToBullet(_avatarData->getTargetVelocity()); + _walkVelocity = glmToBullet(velocity); +} + +void CharacterController::setFollowVelocity(const glm::vec3& velocity) { + _followVelocity = glmToBullet(velocity); +} + +glm::vec3 CharacterController::getLinearVelocity() const { + glm::vec3 velocity(0.0f); + if (_rigidBody) { + velocity = bulletToGLM(_rigidBody->getLinearVelocity()); + } + return velocity; +} + +void CharacterController::preSimulation() { + if (_enabled && _dynamicsWorld) { + // slam body to where it is supposed to be + _rigidBody->setWorldTransform(_characterBodyTransform); + + // scan for distant floor + // rayStart is at center of bottom sphere + btVector3 rayStart = _characterBodyTransform.getOrigin() - _halfHeight * _currentUp; + + // rayEnd is straight down MAX_FALL_HEIGHT + btScalar rayLength = _radius + MAX_FALL_HEIGHT; + btVector3 rayEnd = rayStart - rayLength * _currentUp; + + ClosestNotMe rayCallback(_rigidBody); + rayCallback.m_closestHitFraction = 1.0f; + _dynamicsWorld->rayTest(rayStart, rayEnd, rayCallback); + if (rayCallback.hasHit()) { + _floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius; + const btScalar MIN_HOVER_HEIGHT = 3.0f; + if (_isHovering && _floorDistance < MIN_HOVER_HEIGHT && !_isPushingUp) { + setHovering(false); + } + // TODO: use collision events rather than ray-trace test to disable jumping + const btScalar JUMP_PROXIMITY_THRESHOLD = 0.1f * _radius; + if (_floorDistance < JUMP_PROXIMITY_THRESHOLD) { + _isJumping = false; + } + } else { + _floorDistance = FLT_MAX; + setHovering(true); + } + + if (_pendingFlags & PENDING_FLAG_JUMP) { + _pendingFlags &= ~ PENDING_FLAG_JUMP; + if (onGround()) { + _isJumping = true; + btVector3 velocity = _rigidBody->getLinearVelocity(); + velocity += _jumpSpeed * _currentUp; + _rigidBody->setLinearVelocity(velocity); + } + } + } + _followTime = 0.0f; +} + +void CharacterController::postSimulation() { + // postSimulation() exists for symmetry and just in case we need to do something here later +} diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index e9e6f1328e..6edbabdab8 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -17,11 +17,14 @@ #include #include +#include + const uint32_t PENDING_FLAG_ADD_TO_SIMULATION = 1U << 0; const uint32_t PENDING_FLAG_REMOVE_FROM_SIMULATION = 1U << 1; const uint32_t PENDING_FLAG_UPDATE_SHAPE = 1U << 2; const uint32_t PENDING_FLAG_JUMP = 1U << 3; +const float DEFAULT_CHARACTER_GRAVITY = -5.0f; class btRigidBody; class btCollisionWorld; @@ -29,31 +32,89 @@ class btDynamicsWorld; class CharacterController : public btCharacterControllerInterface { public: + CharacterController(); + virtual ~CharacterController() {} + bool needsRemoval() const; bool needsAddition() const; void setDynamicsWorld(btDynamicsWorld* world); btCollisionObject* getCollisionObject() { return _rigidBody; } virtual void updateShapeIfNecessary() = 0; - virtual void preSimulation() = 0; - virtual void postSimulation() = 0; + // overrides from btCharacterControllerInterface virtual void setWalkDirection(const btVector3 &walkDirection) { assert(false); } + virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) override { assert(false); } + virtual void reset(btCollisionWorld* collisionWorld) override { } + virtual void warp(const btVector3& origin) override { } + virtual void debugDraw(btIDebugDraw* debugDrawer) override { } + virtual void setUpInterpolate(bool value) override { } + virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTime) override { + preStep(collisionWorld); + playerStep(collisionWorld, deltaTime); + } + virtual void preStep(btCollisionWorld *collisionWorld) override; + virtual void playerStep(btCollisionWorld *collisionWorld, btScalar dt) override; + virtual bool canJump() const override { assert(false); return false; } // never call this + virtual void jump() override; + virtual bool onGround() const; + + void preSimulation(); + void postSimulation(); + + void setPositionAndOrientation( const glm::vec3& position, const glm::quat& orientation); + void getPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const; + + void setTargetVelocity(const glm::vec3& velocity); + void setFollowVelocity(const glm::vec3& velocity); + float getFollowTime() const { return _followTime; } + + glm::vec3 getLinearVelocity() const; + + bool isHovering() const { return _isHovering; } + void setHovering(bool enabled); + + void setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale); + + void setEnabled(bool enabled); + bool isEnabled() const { return _enabled && _dynamicsWorld; } - /* these from btCharacterControllerInterface remain to be overridden - virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) = 0; - virtual void reset() = 0; - virtual void warp(const btVector3 &origin) = 0; - virtual void preStep(btCollisionWorld *collisionWorld) = 0; - virtual void playerStep(btCollisionWorld *collisionWorld, btScalar dt) = 0; - virtual bool canJump() const = 0; - virtual void jump() = 0; - virtual bool onGround() const = 0; - */ protected: + void updateUpAxis(const glm::quat& rotation); + +protected: + btVector3 _currentUp; + btVector3 _walkVelocity; + btVector3 _followVelocity; + btTransform _characterBodyTransform; + + glm::vec3 _shapeLocalOffset; + + glm::vec3 _boxScale; // used to compute capsule shape + + quint64 _jumpToHoverStart; + + btScalar _halfHeight; + btScalar _radius; + + btScalar _floorDistance; + + btScalar _gravity; + + btScalar _jumpSpeed; + btScalar _followTime; + + bool _enabled; + bool _isOnGround; + bool _isJumping; + bool _isFalling; + bool _isHovering; + bool _isPushingUp; + btDynamicsWorld* _dynamicsWorld { nullptr }; btRigidBody* _rigidBody { nullptr }; uint32_t _pendingFlags { 0 }; + }; #endif // hifi_CharacterControllerInterface_h From 1d65cbce882525243d5be7f54e70484058493e93 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Tue, 8 Dec 2015 18:08:57 -0800 Subject: [PATCH 47/78] Remove unneeded getTargetFramePeriod and isVSynchronized. --- interface/src/Application.cpp | 2 -- interface/src/Application.h | 1 - interface/src/avatar/AvatarManager.cpp | 6 ++---- .../display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp | 7 ------- .../src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h | 3 --- .../src/display-plugins/openvr/OpenVrDisplayPlugin.h | 1 - libraries/plugins/src/plugins/DisplayPlugin.h | 2 -- plugins/oculus/src/OculusDisplayPlugin.h | 1 - plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h | 1 - 9 files changed, 2 insertions(+), 22 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 24fd1d1ac9..e01899726a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3235,8 +3235,6 @@ bool Application::isHMDMode() const { return getActiveDisplayPlugin()->isHmd(); } float Application::getTargetFrameRate() { return getActiveDisplayPlugin()->getTargetFrameRate(); } -float Application::getTargetFramePeriod() { return getActiveDisplayPlugin()->getTargetFramePeriod(); } -bool Application::isVSynchronized() const { return getActiveDisplayPlugin()->isVSynchronized(); } QRect Application::getDesirableApplicationGeometry() { QRect applicationGeometry = getWindow()->geometry(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 0678477aaa..122b6ea3ae 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -124,7 +124,6 @@ public: PickRay computePickRay() const; bool isThrottleRendering() const; - bool isVSynchronized() const; Camera* getCamera() { return &_myCamera; } // Represents the current view frustum of the avatar. diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index dff6893bef..7c1a52f1b3 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -146,7 +146,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { PerformanceTimer perfTimer("otherAvatars"); float distance; - if (qApp->isVSynchronized()) { + if (!qApp->isThrottleRendering()) { _renderDistanceController.setMeasuredValueSetpoint(qApp->getTargetFrameRate()); // No problem updating in flight. // The PID controller raises the controlled value when the measured value goes up. // The measured value is frame rate. When the controlled value (1 / render cutoff distance) @@ -155,9 +155,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { const float deduced = qApp->getLastUnsynchronizedFps(); distance = 1.0f / _renderDistanceController.update(deduced, deltaTime); } else { - // We could keep the controller running when not vsync'd, if getLastDeducedNonVSyncFps is still meaningful. - // But the basic 2d controller doesn't try to adjust the timer for qt load or getLastPaintWait, so running the - // Here we choose to just use the maximum render cutoff distance if: throttled, running without vsync, or 30-60 "fixed" targets. + // Here we choose to just use the maximum render cutoff distance if throttled. distance = 1.0f / _renderDistanceController.getControlledValueLowLimit(); } _renderDistanceAverage.updateAverage(distance); diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 97e12643a9..9139a9dcc9 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -113,10 +113,6 @@ bool Basic2DWindowOpenGLDisplayPlugin::isThrottled() const { return shouldThrottle; } -bool Basic2DWindowOpenGLDisplayPlugin::isVSynchronized() const { - return (_framerateTarget == 0) && !_isThrottled; -} - void Basic2DWindowOpenGLDisplayPlugin::updateFramerate() { QAction* checkedFramerate{ nullptr }; foreach(auto action, _framerateActions) { @@ -141,11 +137,8 @@ void Basic2DWindowOpenGLDisplayPlugin::updateFramerate() { } else if (_isThrottled) { _framerateTarget = (float) THROTTLED_FRAMERATE; } - _inverseFrameRate = _framerateTarget ? 1.0f / (float) _framerateTarget : 1.0f / TARGET_FRAMERATE_Basic2DWindowOpenGL; // not truncated int newInterval = getDesiredInterval(); - // Note: when not isVSynchronized, we are often not likely to hit target with a newInterval timer. - // We could try subtracting an allowance for qApp->getLastPaintWait() and qt timer machinery, but that starts getting complicated. qDebug() << newInterval; _timer.start(newInterval); } diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h index bd5359e141..59c0e4e759 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h @@ -21,7 +21,6 @@ public: virtual const QString & getName() const override; virtual float getTargetFrameRate() override { return _framerateTarget ? (float) _framerateTarget : TARGET_FRAMERATE_Basic2DWindowOpenGL; } - virtual float getTargetFramePeriod() override { return _inverseFrameRate; } virtual void activate() override; @@ -30,7 +29,6 @@ public: virtual void internalPresent() override; virtual bool isThrottled() const override; - virtual bool isVSynchronized() const override; protected: int getDesiredInterval() const; @@ -44,6 +42,5 @@ private: QAction* _vsyncAction { nullptr }; uint32_t _framerateTarget { 0 }; int _fullscreenTarget{ -1 }; - float _inverseFrameRate{ 1.0f }; //seconds bool _wantVsync { true }; }; diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h index feb5c0716c..2b51c53d58 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h @@ -23,7 +23,6 @@ public: virtual bool isHmd() const override { return true; } virtual float getTargetFrameRate() override { return TARGET_RATE_OpenVr; } - virtual float getTargetFramePeriod() override { return 1.0f / TARGET_RATE_OpenVr; } virtual void activate() override; virtual void deactivate() override; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 5352cf9a87..7f3b38e4a2 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -58,9 +58,7 @@ public: /// By default, all HMDs are stereo virtual bool isStereo() const { return isHmd(); } virtual bool isThrottled() const { return false; } - virtual bool isVSynchronized() const { return true; } // false when throttled or run by non vsync timer virtual float getTargetFrameRate() { return 0.0f; } - virtual float getTargetFramePeriod() { return 0.0f; } // Rendering support diff --git a/plugins/oculus/src/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h index 47b41b08b6..071dca0258 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.h +++ b/plugins/oculus/src/OculusDisplayPlugin.h @@ -21,7 +21,6 @@ public: virtual void setEyeRenderPose(uint32_t frameIndex, Eye eye, const glm::mat4& pose) override final; virtual float getTargetFrameRate() override { return TARGET_RATE_Oculus; } - virtual float getTargetFramePeriod() override { return 1.0f / TARGET_RATE_Oculus; } protected: virtual void internalPresent() override; diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h index 67efcc6575..7fe721fc45 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h @@ -28,7 +28,6 @@ public: virtual int getHmdScreen() const override; virtual float getTargetFrameRate() override { return TARGET_RATE_OculusLegacy; } - virtual float getTargetFramePeriod() override { return 1.0f / TARGET_RATE_OculusLegacy; } // Stereo specific methods virtual bool isHmd() const override { return true; } From 446ca8236f58dadd1c7cbbb208a665075c9dee28 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 9 Dec 2015 11:25:44 -0800 Subject: [PATCH 48/78] disable physics disabler --- 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 eee1ea7226..1a03cad62a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2907,7 +2907,7 @@ void Application::update(float deltaTime) { _avatarUpdate->synchronousProcess(); - if (_physicsEnabled) { + if (true || _physicsEnabled) { PerformanceTimer perfTimer("physics"); static VectorOfMotionStates motionStates; From 65bc6aa37114fc3fcd9a6a9437ee3df2a702283e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 8 Dec 2015 10:48:11 -0800 Subject: [PATCH 49/78] Fix left hand grab --- examples/controllers/handControllerGrab.js | 43 ++++++++++++++++------ interface/src/avatar/AvatarActionHold.cpp | 4 +- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 138240f5d6..07894b46d1 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -202,31 +202,41 @@ function entityIsGrabbedByOther(entityID) { } function getSpatialOffsetPosition(hand, spatialKey) { + var position = Vec3.ZERO; + if (hand !== RIGHT_HAND && spatialKey.leftRelativePosition) { - return spatialKey.leftRelativePosition; + position = spatialKey.leftRelativePosition; } if (hand === RIGHT_HAND && spatialKey.rightRelativePosition) { - return spatialKey.rightRelativePosition; + position = spatialKey.rightRelativePosition; } if (spatialKey.relativePosition) { - return spatialKey.relativePosition; + position = spatialKey.relativePosition; } - return Vec3.ZERO; + return position; } +var yFlip = Quat.angleAxis(180, Vec3.UNIT_Y); function getSpatialOffsetRotation(hand, spatialKey) { + var rotation = Quat.IDENTITY; + if (hand !== RIGHT_HAND && spatialKey.leftRelativeRotation) { - return spatialKey.leftRelativeRotation; + rotation = spatialKey.leftRelativeRotation; } if (hand === RIGHT_HAND && spatialKey.rightRelativeRotation) { - return spatialKey.rightRelativeRotation; + rotation = spatialKey.rightRelativeRotation; } if (spatialKey.relativeRotation) { - return spatialKey.relativeRotation; + rotation = spatialKey.relativeRotation; } - return Quat.IDENTITY; + // Flip left hand + if (hand !== RIGHT_HAND) { + rotation = Quat.multiply(yFlip, rotation); + } + + return rotation; } function MyController(hand) { @@ -254,6 +264,7 @@ function MyController(hand) { this.overlayLine = null; + this.ignoreIK = false; this.offsetPosition = Vec3.ZERO; this.offsetRotation = Quat.IDENTITY; @@ -853,9 +864,12 @@ function MyController(hand) { if (this.state != STATE_NEAR_GRABBING && grabbableData.spatialKey) { // if an object is "equipped" and has a spatialKey, use it. + this.ignoreIK = grabbableData.spatialKey.ignoreIK ? grabbableData.spatialKey.ignoreIK : false; this.offsetPosition = getSpatialOffsetPosition(this.hand, grabbableData.spatialKey); this.offsetRotation = getSpatialOffsetRotation(this.hand, grabbableData.spatialKey); } else { + this.ignoreIK = false; + var objectRotation = grabbedProperties.rotation; this.offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); @@ -872,7 +886,8 @@ function MyController(hand) { relativeRotation: this.offsetRotation, ttl: ACTION_TTL, kinematic: NEAR_GRABBING_KINEMATIC, - kinematicSetVelocity: true + kinematicSetVelocity: true, + ignoreIK: this.ignoreIK }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; @@ -956,7 +971,8 @@ function MyController(hand) { relativeRotation: this.offsetRotation, ttl: ACTION_TTL, kinematic: NEAR_GRABBING_KINEMATIC, - kinematicSetVelocity: true + kinematicSetVelocity: true, + ignoreIK: this.ignoreIK }); this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); } @@ -982,6 +998,7 @@ function MyController(hand) { // use a spring to pull the object to where it will be when equipped var relativeRotation = getSpatialOffsetRotation(this.hand, grabbableData.spatialKey); var relativePosition = getSpatialOffsetPosition(this.hand, grabbableData.spatialKey); + var ignoreIK = grabbableData.spatialKey.ignoreIK ? grabbableData.spatialKey.ignoreIK : false; var handRotation = this.getHandRotation(); var handPosition = this.getHandPosition(); var targetRotation = Quat.multiply(handRotation, relativeRotation); @@ -996,7 +1013,8 @@ function MyController(hand) { linearTimeScale: EQUIP_SPRING_TIMEFRAME, targetRotation: targetRotation, angularTimeScale: EQUIP_SPRING_TIMEFRAME, - ttl: ACTION_TTL + ttl: ACTION_TTL, + ignoreIK: ignoreIK }); if (this.equipSpringID === NULL_ACTION_ID) { this.equipSpringID = null; @@ -1009,7 +1027,8 @@ function MyController(hand) { linearTimeScale: EQUIP_SPRING_TIMEFRAME, targetRotation: targetRotation, angularTimeScale: EQUIP_SPRING_TIMEFRAME, - ttl: ACTION_TTL + ttl: ACTION_TTL, + ignoreIK: ignoreIK }); } diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index fab838aa68..c2eea69a17 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -85,8 +85,8 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { QList holdActions = ownerEntity->getActionsOfType(ACTION_TYPE_HOLD); foreach (EntityActionPointer action, holdActions) { std::shared_ptr holdAction = std::static_pointer_cast(action); - glm::quat rotationForAction; - glm::vec3 positionForAction; + glm::quat rotationForAction { Quaternions::IDENTITY }; + glm::vec3 positionForAction { Vectors::ZERO }; std::shared_ptr holdingAvatar = holdAction->getTarget(rotationForAction, positionForAction); if (holdingAvatar) { holdCount ++; From 4ee5bf316a98f982db5993a77b881dd9fc9bf21d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 8 Dec 2015 10:48:30 -0800 Subject: [PATCH 50/78] Fix bow offsets --- examples/toybox/bow/bow.js | 14 +++++++------- examples/toybox/bow/createBow.js | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/toybox/bow/bow.js b/examples/toybox/bow/bow.js index 90199fb70f..a5bada779f 100644 --- a/examples/toybox/bow/bow.js +++ b/examples/toybox/bow/bow.js @@ -67,15 +67,15 @@ } var BOW_SPATIAL_KEY = { - leftRelativePosition: { - x: 0.05, - y: 0.06, - z: -0.05 + leftRelativePosition: { + x: -0.02, + y: 0.08, + z: 0.09 }, rightRelativePosition: { - x: -0.05, - y: 0.06, - z: -0.05 + x: 0.02, + y: 0.08, + z: 0.09 }, relativeRotation: Quat.fromPitchYawRollDegrees(0, 90, -90) } diff --git a/examples/toybox/bow/createBow.js b/examples/toybox/bow/createBow.js index 9a9ed98c20..4f0cddfc0d 100644 --- a/examples/toybox/bow/createBow.js +++ b/examples/toybox/bow/createBow.js @@ -49,14 +49,14 @@ var bow = Entities.addEntity({ invertSolidWhileHeld: true, spatialKey: { leftRelativePosition: { - x: 0.05, - y: 0.06, - z: -0.05 + x: -0.02, + y: 0.08, + z: 0.09 }, - rightRelativePosition: { - x: -0.05, - y: 0.06, - z: -0.05 + relativePosition: { + x: 0.02, + y: 0.08, + z: 0.09 }, relativeRotation: Quat.fromPitchYawRollDegrees(0, 90, -90) } From 17daff920c959422c1753092d7c18aec7373439d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 8 Dec 2015 11:21:04 -0800 Subject: [PATCH 51/78] Fix all entities using relative grab pos/rot --- examples/toybox/bow/bow.js | 32 ++++++------------------ examples/toybox/bubblewand/createWand.js | 9 +++++-- examples/toybox/pistol/createPistol.js | 6 ++--- 3 files changed, 17 insertions(+), 30 deletions(-) diff --git a/examples/toybox/bow/bow.js b/examples/toybox/bow/bow.js index a5bada779f..f0128acc77 100644 --- a/examples/toybox/bow/bow.js +++ b/examples/toybox/bow/bow.js @@ -66,21 +66,6 @@ max2: 15 } - var BOW_SPATIAL_KEY = { - leftRelativePosition: { - x: -0.02, - y: 0.08, - z: 0.09 - }, - rightRelativePosition: { - x: 0.02, - y: 0.08, - z: 0.09 - }, - relativeRotation: Quat.fromPitchYawRollDegrees(0, 90, -90) - } - - var USE_DEBOUNCE = false; var TRIGGER_CONTROLS = [ @@ -168,11 +153,9 @@ var handToDisable = this.initialHand === 'right' ? 'left' : 'right'; Messages.sendMessage('Hifi-Hand-Disabler', handToDisable); - setEntityCustomData('grabbableKey', this.entityID, { - grabbable: false, - invertSolidWhileHeld: true, - spatialKey: BOW_SPATIAL_KEY - }); + var data = getEntityCustomData('grabbableKey', this.entityID, {}); + data.grabbable = false; + setEntityCustomData('grabbableKey', this.entityID, data); }, continueNearGrab: function() { @@ -226,11 +209,10 @@ this.isGrabbed = false; this.stringDrawn = false; this.deleteStrings(); - setEntityCustomData('grabbableKey', this.entityID, { - grabbable: true, - invertSolidWhileHeld: true, - spatialKey: BOW_SPATIAL_KEY - }); + + var data = getEntityCustomData('grabbableKey', this.entityID, {}); + data.grabbable = true; + setEntityCustomData('grabbableKey', this.entityID, data); Entities.deleteEntity(this.preNotchString); Entities.deleteEntity(this.arrow); this.aiming = false; diff --git a/examples/toybox/bubblewand/createWand.js b/examples/toybox/bubblewand/createWand.js index 6b4f9717ec..efd86b046f 100644 --- a/examples/toybox/bubblewand/createWand.js +++ b/examples/toybox/bubblewand/createWand.js @@ -53,8 +53,13 @@ var wand = Entities.addEntity({ y: 0.1, z: 0 }, - relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 90) + relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, -90) } } }) -}); \ No newline at end of file +}); + +function scriptEnding() { + Entities.deleteEntity(wand); +} +Script.scriptEnding.connect(scriptEnding); diff --git a/examples/toybox/pistol/createPistol.js b/examples/toybox/pistol/createPistol.js index d804150cbe..693c53b9b4 100644 --- a/examples/toybox/pistol/createPistol.js +++ b/examples/toybox/pistol/createPistol.js @@ -28,10 +28,10 @@ var pistol = Entities.addEntity({ spatialKey: { relativePosition: { x: 0, - y: 0, - z: 0 + y: 0.05, + z: -0.08 }, - relativeRotation: Quat.fromPitchYawRollDegrees(45, 90, 0) + relativeRotation: Quat.fromPitchYawRollDegrees(90, 90, 0) }, invertSolidWhileHeld: true } From 5574f4736b368af38542b35c3cc370b72f39364a Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 9 Dec 2015 14:26:49 -0800 Subject: [PATCH 52/78] CR --- interface/src/avatar/AvatarActionHold.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index c2eea69a17..fab838aa68 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -85,8 +85,8 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { QList holdActions = ownerEntity->getActionsOfType(ACTION_TYPE_HOLD); foreach (EntityActionPointer action, holdActions) { std::shared_ptr holdAction = std::static_pointer_cast(action); - glm::quat rotationForAction { Quaternions::IDENTITY }; - glm::vec3 positionForAction { Vectors::ZERO }; + glm::quat rotationForAction; + glm::vec3 positionForAction; std::shared_ptr holdingAvatar = holdAction->getTarget(rotationForAction, positionForAction); if (holdingAvatar) { holdCount ++; From 4bfce768ca68951d44d2f973d1bd408f46b5133c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 9 Dec 2015 14:48:33 -0800 Subject: [PATCH 53/78] Add locks around read/writes of _scriptEnginesHash --- interface/src/Application.cpp | 113 +++++++++++++++++++++++----------- interface/src/Application.h | 1 + 2 files changed, 77 insertions(+), 37 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0b29cdc892..8655d6b77e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4259,10 +4259,13 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser QUrl scriptUrl(scriptFilename); const QString& scriptURLString = scriptUrl.toString(); - if (_scriptEnginesHash.contains(scriptURLString) && loadScriptFromEditor - && !_scriptEnginesHash[scriptURLString]->isFinished()) { + { + QReadLocker lock(&_scriptEnginesHashLock); + if (_scriptEnginesHash.contains(scriptURLString) && loadScriptFromEditor + && !_scriptEnginesHash[scriptURLString]->isFinished()) { - return _scriptEnginesHash[scriptURLString]; + return _scriptEnginesHash[scriptURLString]; + } } ScriptEngine* scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface); @@ -4302,7 +4305,11 @@ void Application::reloadScript(const QString& scriptName, bool isUserLoaded) { void Application::handleScriptEngineLoaded(const QString& scriptFilename) { ScriptEngine* scriptEngine = qobject_cast(sender()); - _scriptEnginesHash.insertMulti(scriptFilename, scriptEngine); + { + QWriteLocker lock(&_scriptEnginesHashLock); + _scriptEnginesHash.insertMulti(scriptFilename, scriptEngine); + } + _runningScriptsWidget->setRunningScripts(getRunningScripts()); UserActivityLogger::getInstance().loadedScript(scriptFilename); @@ -4317,55 +4324,86 @@ void Application::handleScriptLoadError(const QString& scriptFilename) { QMessageBox::warning(getWindow(), "Error Loading Script", scriptFilename + " failed to load."); } -void Application::scriptFinished(const QString& scriptName) { - const QString& scriptURLString = QUrl(scriptName).toString(); - QHash::iterator it = _scriptEnginesHash.find(scriptURLString); - if (it != _scriptEnginesHash.end()) { - _scriptEnginesHash.erase(it); - _runningScriptsWidget->scriptStopped(scriptName); - _runningScriptsWidget->setRunningScripts(getRunningScripts()); - } +QStringList Application::getRunningScripts() { + QReadLocker lock(&_scriptEnginesHashLock); + return _scriptEnginesHash.keys(); } -void Application::stopAllScripts(bool restart) { - if (restart) { - // Delete all running scripts from cache so that they are re-downloaded when they are restarted - auto scriptCache = DependencyManager::get(); - for (QHash::const_iterator it = _scriptEnginesHash.constBegin(); - it != _scriptEnginesHash.constEnd(); it++) { - if (!it.value()->isFinished()) { - scriptCache->deleteScript(it.key()); +ScriptEngine* Application::getScriptEngine(const QString& scriptHash) { + QReadLocker lock(&_scriptEnginesHashLock); + return _scriptEnginesHash.value(scriptHash, nullptr); +} + +void Application::scriptFinished(const QString& scriptName, ScriptEngine* engine) { + bool removed = false; + { + QWriteLocker lock(&_scriptEnginesHashLock); + const QString& scriptURLString = QUrl(scriptName).toString(); + for (auto it = _scriptEnginesHash.find(scriptURLString); it != _scriptEnginesHash.end(); ++it) { + if (it.value() == engine) { + _scriptEnginesHash.erase(it); + removed = true; + break; } } } + postLambdaEvent([this, scriptName]() { + _runningScriptsWidget->scriptStopped(scriptName); + _runningScriptsWidget->setRunningScripts(getRunningScripts()); + }); +} - // Stop and possibly restart all currently running scripts - for (QHash::const_iterator it = _scriptEnginesHash.constBegin(); +void Application::stopAllScripts(bool restart) { + { + QReadLocker lock(&_scriptEnginesHashLock); + + if (restart) { + // Delete all running scripts from cache so that they are re-downloaded when they are restarted + auto scriptCache = DependencyManager::get(); + for (QHash::const_iterator it = _scriptEnginesHash.constBegin(); it != _scriptEnginesHash.constEnd(); it++) { - if (it.value()->isFinished()) { - continue; + if (!it.value()->isFinished()) { + scriptCache->deleteScript(it.key()); + } + } } - if (restart && it.value()->isUserLoaded()) { - connect(it.value(), SIGNAL(finished(const QString&)), SLOT(reloadScript(const QString&))); + + // Stop and possibly restart all currently running scripts + for (QHash::const_iterator it = _scriptEnginesHash.constBegin(); + it != _scriptEnginesHash.constEnd(); it++) { + if (it.value()->isFinished()) { + continue; + } + if (restart && it.value()->isUserLoaded()) { + connect(it.value(), &ScriptEngine::finished, this, [this](QString scriptName, ScriptEngine* engine) { + reloadScript(scriptName); + }); + } + QMetaObject::invokeMethod(it.value(), "stop"); + //it.value()->stop(); + qCDebug(interfaceapp) << "stopping script..." << it.key(); } - it.value()->stop(); - qCDebug(interfaceapp) << "stopping script..." << it.key(); } getMyAvatar()->clearScriptableSettings(); } bool Application::stopScript(const QString& scriptHash, bool restart) { bool stoppedScript = false; - if (_scriptEnginesHash.contains(scriptHash)) { - ScriptEngine* scriptEngine = _scriptEnginesHash[scriptHash]; - if (restart) { - auto scriptCache = DependencyManager::get(); - scriptCache->deleteScript(QUrl(scriptHash)); - connect(scriptEngine, SIGNAL(finished(const QString&)), SLOT(reloadScript(const QString&))); + { + QReadLocker lock(&_scriptEnginesHashLock); + if (_scriptEnginesHash.contains(scriptHash)) { + ScriptEngine* scriptEngine = _scriptEnginesHash[scriptHash]; + if (restart) { + auto scriptCache = DependencyManager::get(); + scriptCache->deleteScript(QUrl(scriptHash)); + connect(scriptEngine, &ScriptEngine::finished, this, [this](QString scriptName, ScriptEngine* engine) { + reloadScript(scriptName); + }); + } + scriptEngine->stop(); + stoppedScript = true; + qCDebug(interfaceapp) << "stopping script..." << scriptHash; } - scriptEngine->stop(); - stoppedScript = true; - qCDebug(interfaceapp) << "stopping script..." << scriptHash; } if (_scriptEnginesHash.empty()) { getMyAvatar()->clearScriptableSettings(); @@ -4384,6 +4422,7 @@ void Application::reloadOneScript(const QString& scriptName) { } void Application::loadDefaultScripts() { + QReadLocker lock(&_scriptEnginesHashLock); if (!_scriptEnginesHash.contains(DEFAULT_SCRIPTS_JS_URL)) { loadScript(DEFAULT_SCRIPTS_JS_URL); } diff --git a/interface/src/Application.h b/interface/src/Application.h index ce33f051ef..2f4e33e52d 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -505,6 +505,7 @@ private: TouchEvent _lastTouchEvent; + QReadWriteLock _scriptEnginesHashLock; RunningScriptsWidget* _runningScriptsWidget; QHash _scriptEnginesHash; bool _runningScriptsWidgetWasVisible; From fc6a78d9ef74483a861aea122fee0885c674628f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 9 Dec 2015 14:49:05 -0800 Subject: [PATCH 54/78] Update scriptFinished signal to be a DirectConnection --- interface/src/Application.cpp | 2 +- interface/src/Application.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8655d6b77e..740b0062f0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4013,7 +4013,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("Clipboard", clipboardScriptable); connect(scriptEngine, SIGNAL(finished(const QString&)), clipboardScriptable, SLOT(deleteLater())); - connect(scriptEngine, SIGNAL(finished(const QString&)), this, SLOT(scriptFinished(const QString&))); + connect(scriptEngine, &ScriptEngine::finished, this, &Application::scriptFinished, Qt::DirectConnection); connect(scriptEngine, SIGNAL(loadScript(const QString&, bool)), this, SLOT(loadScript(const QString&, bool))); connect(scriptEngine, SIGNAL(reloadScript(const QString&, bool)), this, SLOT(reloadScript(const QString&, bool))); diff --git a/interface/src/Application.h b/interface/src/Application.h index 2f4e33e52d..0d5b920c10 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -202,8 +202,8 @@ public: NodeToJurisdictionMap& getEntityServerJurisdictions() { return _entityServerJurisdictions; } - QStringList getRunningScripts() { return _scriptEnginesHash.keys(); } - ScriptEngine* getScriptEngine(const QString& scriptHash) { return _scriptEnginesHash.value(scriptHash, NULL); } + QStringList getRunningScripts(); + ScriptEngine* getScriptEngine(const QString& scriptHash); float getRenderResolutionScale() const; @@ -336,7 +336,7 @@ private slots: void loadSettings(); void saveSettings(); - void scriptFinished(const QString& scriptName); + void scriptFinished(const QString& scriptName, ScriptEngine* engine); void saveScripts(); void reloadScript(const QString& scriptName, bool isUserLoaded = true); From e7a1550b64e831a9b0eb820d277c72e324c8b189 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 9 Dec 2015 14:50:09 -0800 Subject: [PATCH 55/78] Update ScriptEngine::finished to include --- libraries/script-engine/src/ScriptEngine.cpp | 4 ++-- libraries/script-engine/src/ScriptEngine.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index daadb0e394..42287bbea7 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -183,7 +183,7 @@ void ScriptEngine::runInThread() { QSet ScriptEngine::_allKnownScriptEngines; QMutex ScriptEngine::_allScriptsMutex; -std::atomic ScriptEngine::_stoppingAllScripts = false; +std::atomic ScriptEngine::_stoppingAllScripts { false }; void ScriptEngine::stopAllScripts(QObject* application) { _allScriptsMutex.lock(); @@ -752,7 +752,7 @@ void ScriptEngine::run() { } if (_wantSignals) { - emit finished(_fileNameString); + emit finished(_fileNameString, this); } _isRunning = false; diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 82b91aed2e..f8da05135a 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -153,7 +153,7 @@ signals: void errorLoadingScript(const QString& scriptFilename); void update(float deltaTime); void scriptEnding(); - void finished(const QString& fileNameString); + void finished(const QString& fileNameString, ScriptEngine* engine); void cleanupMenuItem(const QString& menuItemString); void printedMessage(const QString& message); void errorMessage(const QString& message); From a21e07327d4da97256411cb6be691f13cedb8af2 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 9 Dec 2015 14:50:30 -0800 Subject: [PATCH 56/78] Update ScriptEngine::stop() to always run on its thread --- libraries/script-engine/src/ScriptEngine.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 42287bbea7..e06fe2b209 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -775,6 +775,10 @@ void ScriptEngine::stopAllTimers() { void ScriptEngine::stop() { if (!_isFinished) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "stop"); + return; + } _isFinished = true; if (_wantSignals) { emit runningStateChanged(); From 5f60aeef2217e5fc1e3be0da0754a80982f933a4 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 9 Dec 2015 14:50:48 -0800 Subject: [PATCH 57/78] Update ScriptEngine::_isUserLoaded to be atomic --- libraries/script-engine/src/ScriptEngine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index f8da05135a..67a206d673 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -193,7 +193,7 @@ protected: Quat _quatLibrary; Vec3 _vec3Library; ScriptUUID _uuidLibrary; - bool _isUserLoaded { false }; + std::atomic _isUserLoaded { false }; bool _isReloading { false }; ArrayBufferClass* _arrayBufferClass; From a57a2792a4b7bfc49e1a3eb74e3718be70d6466b Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 9 Dec 2015 15:17:06 -0800 Subject: [PATCH 58/78] SixenseManager: Added debug draw options These debug draw options were added to help debug rare intermittent issues with configuration the hydra and the Avatar arm IK. --- .../src/input-plugins/SixenseManager.cpp | 61 ++++++++++++++++++- .../src/input-plugins/SixenseManager.h | 4 ++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp index 5dd0248224..3b08c218a2 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp +++ b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -48,6 +49,8 @@ const QString MENU_PARENT = "Avatar"; const QString MENU_NAME = "Sixense"; const QString MENU_PATH = MENU_PARENT + ">" + MENU_NAME; const QString TOGGLE_SMOOTH = "Smooth Sixense Movement"; +const QString SHOW_DEBUG_RAW = "Debug Draw Raw Data"; +const QString SHOW_DEBUG_CALIBRATED = "Debug Draw Calibrated Data"; bool SixenseManager::isSupported() const { #ifdef HAVE_SIXENSE @@ -72,6 +75,14 @@ void SixenseManager::activate() { [this] (bool clicked) { setSixenseFilter(clicked); }, true, true); + _container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, SHOW_DEBUG_RAW, + [this] (bool clicked) { _inputDevice->setDebugDrawRaw(clicked); }, + true, false); + + _container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, SHOW_DEBUG_CALIBRATED, + [this] (bool clicked) { _inputDevice->setDebugDrawCalibrated(clicked); }, + true, false); + auto userInputMapper = DependencyManager::get(); userInputMapper->registerDevice(_inputDevice); @@ -149,6 +160,9 @@ void SixenseManager::InputDevice::update(float deltaTime, bool jointsCaptured) { // we only support two controllers SixenseControllerData controllers[2]; + // store the raw controller data for debug rendering + controller::Pose rawPoses[2]; + int numActiveControllers = 0; for (int i = 0; i < maxControllers && numActiveControllers < 2; i++) { if (!sixenseIsControllerEnabled(i)) { @@ -175,7 +189,7 @@ void SixenseManager::InputDevice::update(float deltaTime, bool jointsCaptured) { // Rotation of Palm glm::quat rotation(data->rot_quat[3], data->rot_quat[0], data->rot_quat[1], data->rot_quat[2]); handlePoseEvent(deltaTime, position, rotation, left); - + rawPoses[i] = controller::Pose(position, rotation, glm::vec3(0), glm::quat()); } else { _poseStateMap.clear(); _collectedSamples.clear(); @@ -197,9 +211,54 @@ void SixenseManager::InputDevice::update(float deltaTime, bool jointsCaptured) { _axisStateMap[axisState.first] = 0.0f; } } + + if (_debugDrawCalibrated) { + auto poseIter = _poseStateMap.find(controller::StandardPoseChannel::LEFT_HAND); + if (poseIter != _poseStateMap.end() && poseIter->second.isValid()) { + DebugDraw::getInstance().addMyAvatarMarker("SIXENSE_CALIBRATED_LEFT", poseIter->second.rotation, poseIter->second.translation, glm::vec4(1)); + } else { + DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_CALIBRATED_LEFT"); + } + poseIter = _poseStateMap.find(controller::StandardPoseChannel::RIGHT_HAND); + if (poseIter != _poseStateMap.end() && poseIter->second.isValid()) { + DebugDraw::getInstance().addMyAvatarMarker("SIXENSE_CALIBRATED_RIGHT", poseIter->second.rotation, poseIter->second.translation, glm::vec4(1)); + } else { + DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_CALIBRATED_RIGHT"); + } + } + + if (_debugDrawRaw) { + if (rawPoses[0].isValid()) { + DebugDraw::getInstance().addMyAvatarMarker("SIXENSE_RAW_LEFT", rawPoses[0].rotation, rawPoses[0].translation, glm::vec4(1)); + } else { + DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_RAW_LEFT"); + } + if (rawPoses[1].isValid()) { + DebugDraw::getInstance().addMyAvatarMarker("SIXENSE_RAW_RIGHT", rawPoses[1].rotation, rawPoses[1].translation, glm::vec4(1)); + } else { + DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_RAW_RIGHT"); + } + } + #endif // HAVE_SIXENSE } +void SixenseManager::InputDevice::setDebugDrawRaw(bool flag) { + _debugDrawRaw = flag; + if (!flag) { + DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_RAW_LEFT"); + DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_RAW_RIGHT"); + } +} + +void SixenseManager::InputDevice::setDebugDrawCalibrated(bool flag) { + _debugDrawCalibrated = flag; + if (!flag) { + DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_CALIBRATED_LEFT"); + DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_CALIBRATED_RIGHT"); + } +} + #ifdef HAVE_SIXENSE // the calibration sequence is: diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.h b/libraries/input-plugins/src/input-plugins/SixenseManager.h index 348a7a4590..b6bf4b24c0 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.h +++ b/libraries/input-plugins/src/input-plugins/SixenseManager.h @@ -60,6 +60,8 @@ private: class InputDevice : public controller::InputDevice { public: InputDevice() : controller::InputDevice("Hydra") {} + void setDebugDrawRaw(bool flag); + void setDebugDrawCalibrated(bool flag); private: // Device functions virtual controller::Input::NamedVector getAvailableInputs() const override; @@ -82,6 +84,8 @@ private: float _lastDistance; bool _requestReset { false }; + bool _debugDrawRaw { false }; + bool _debugDrawCalibrated { false }; // these are measured values used to compute the calibration results quint64 _lockExpiry; glm::vec3 _averageLeft; From 270cfe8af7a63efebf603e908da887bb7fd32def Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 9 Dec 2015 15:22:44 -0800 Subject: [PATCH 59/78] coding standards --- 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 78882342df..a0842ca678 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1400,7 +1400,7 @@ void Application::paintGL() { // Some LOD-like controls need to know a smoothly varying "potential" frame rate that doesn't // include time waiting for sync, and which can report a number above target if we've got the headroom. // In my tests, the following is mostly less than 0.5ms, and never more than 3ms. I don't think its worth measuring during runtime. - static const float paintWaitAndQTTimerAllowance = 0.001; // seconds + const float paintWaitAndQTTimerAllowance = 0.001f; // seconds // Store both values now for use by next cycle. _lastInstantaneousFps = instantaneousFps; _lastUnsynchronizedFps = 1.0f / (((usecTimestampNow() - now) / (float)USECS_PER_SECOND) + paintWaitAndQTTimerAllowance); From ad0865171b53ca9030cf6875ae8afced602a2b39 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 9 Dec 2015 15:52:30 -0800 Subject: [PATCH 60/78] Fix unused variable in scriptFinished --- interface/src/Application.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 740b0062f0..d648537155 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4347,10 +4347,12 @@ void Application::scriptFinished(const QString& scriptName, ScriptEngine* engine } } } - postLambdaEvent([this, scriptName]() { - _runningScriptsWidget->scriptStopped(scriptName); - _runningScriptsWidget->setRunningScripts(getRunningScripts()); - }); + if (removed) { + postLambdaEvent([this, scriptName]() { + _runningScriptsWidget->scriptStopped(scriptName); + _runningScriptsWidget->setRunningScripts(getRunningScripts()); + }); + } } void Application::stopAllScripts(bool restart) { From acb43e18d0a2c6b18b71c2081dd331a10fcfb68e Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 9 Dec 2015 15:54:49 -0800 Subject: [PATCH 61/78] coding standards --- .../src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h | 2 +- .../src/display-plugins/openvr/OpenVrDisplayPlugin.h | 2 +- plugins/oculus/src/OculusDisplayPlugin.h | 2 +- plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h index 59c0e4e759..e3633b5fe8 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h @@ -9,7 +9,7 @@ #include "WindowOpenGLDisplayPlugin.h" -#define TARGET_FRAMERATE_Basic2DWindowOpenGL 60.0f +const float TARGET_FRAMERATE_Basic2DWindowOpenGL = 60.0f; class QScreen; class QAction; diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h index 2b51c53d58..d07add7ea5 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h @@ -14,7 +14,7 @@ #include "../WindowOpenGLDisplayPlugin.h" -#define TARGET_RATE_OpenVr 90.0f; // FIXME: get from sdk tracked device property? This number is vive-only. +const float TARGET_RATE_OpenVr = 90.0f; // FIXME: get from sdk tracked device property? This number is vive-only. class OpenVrDisplayPlugin : public WindowOpenGLDisplayPlugin { public: diff --git a/plugins/oculus/src/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h index 071dca0258..03c9ba7511 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.h +++ b/plugins/oculus/src/OculusDisplayPlugin.h @@ -12,7 +12,7 @@ struct SwapFramebufferWrapper; using SwapFboPtr = QSharedPointer; -#define TARGET_RATE_Oculus 75.0f; +const float TARGET_RATE_Oculus = 75.0f; class OculusDisplayPlugin : public OculusBaseDisplayPlugin { public: diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h index 7fe721fc45..d3e68585df 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h @@ -13,7 +13,7 @@ #include -#define TARGET_RATE_OculusLegacy 75.0f; +const float TARGET_RATE_OculusLegacy = 75.0f; class OculusLegacyDisplayPlugin : public WindowOpenGLDisplayPlugin { public: From 3b372fd897aa9b4c011216037201c6c35ff92491 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 9 Dec 2015 16:12:34 -0800 Subject: [PATCH 62/78] coding standards --- .../Basic2DWindowOpenGLDisplayPlugin.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 9139a9dcc9..5beadffb1e 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -83,17 +83,16 @@ void Basic2DWindowOpenGLDisplayPlugin::internalPresent() { } WindowOpenGLDisplayPlugin::internalPresent(); } -#define THROTTLED_FRAMERATE 15 +const uint32_t THROTTLED_FRAMERATE = 15; int Basic2DWindowOpenGLDisplayPlugin::getDesiredInterval() const { static const int ULIMIITED_PAINT_TIMER_DELAY_MS = 1; int result = ULIMIITED_PAINT_TIMER_DELAY_MS; - // This test wouldn't be necessary if we could depend on updateFramerate setting _framerateTarget. - // Alas, that gets complicated: isThrottled() is const and other stuff depends on it. - if (_isThrottled) { - result = MSECS_PER_SECOND / THROTTLED_FRAMERATE; - } if (0 != _framerateTarget) { result = MSECS_PER_SECOND / _framerateTarget; + } else if (_isThrottled) { + // This test wouldn't be necessary if we could depend on updateFramerate setting _framerateTarget. + // Alas, that gets complicated: isThrottled() is const and other stuff depends on it. + result = MSECS_PER_SECOND / THROTTLED_FRAMERATE; } qDebug() << "New interval " << result; @@ -135,7 +134,7 @@ void Basic2DWindowOpenGLDisplayPlugin::updateFramerate() { _framerateTarget = 30; } } else if (_isThrottled) { - _framerateTarget = (float) THROTTLED_FRAMERATE; + _framerateTarget = THROTTLED_FRAMERATE; } int newInterval = getDesiredInterval(); From 978d39b7f4f29a8db11c6fff19021d12da0b8e3f Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 18 Nov 2015 15:20:29 -0800 Subject: [PATCH 63/78] Moving OpenVR to external plugin and updating to latest version --- cmake/externals/openvr/CMakeLists.txt | 5 +- .../src/display-plugins/DisplayPlugin.cpp | 12 +- .../display-plugins/OpenGLDisplayPlugin.cpp | 9 +- .../src/display-plugins/OpenGLDisplayPlugin.h | 2 +- libraries/input-plugins/CMakeLists.txt | 12 +- .../src/input-plugins/InputPlugin.cpp | 2 - libraries/script-engine/src/ScriptEngine.cpp | 2 +- plugins/openvr/CMakeLists.txt | 25 +++++ .../openvr/src}/OpenVrDisplayPlugin.cpp | 103 +++++++++--------- .../openvr/src}/OpenVrDisplayPlugin.h | 11 +- .../openvr/src}/OpenVrHelpers.cpp | 25 ++--- .../openvr/src}/OpenVrHelpers.h | 5 - plugins/openvr/src/OpenVrProvider.cpp | 60 ++++++++++ .../openvr/src}/ViveControllerManager.cpp | 27 ++--- .../openvr/src}/ViveControllerManager.h | 2 +- plugins/openvr/src/plugin.json | 1 + 16 files changed, 175 insertions(+), 128 deletions(-) create mode 100644 plugins/openvr/CMakeLists.txt rename {libraries/display-plugins/src/display-plugins/openvr => plugins/openvr/src}/OpenVrDisplayPlugin.cpp (65%) rename {libraries/display-plugins/src/display-plugins/openvr => plugins/openvr/src}/OpenVrDisplayPlugin.h (84%) rename {libraries/display-plugins/src/display-plugins/openvr => plugins/openvr/src}/OpenVrHelpers.cpp (80%) rename {libraries/display-plugins/src/display-plugins/openvr => plugins/openvr/src}/OpenVrHelpers.h (89%) create mode 100644 plugins/openvr/src/OpenVrProvider.cpp rename {libraries/input-plugins/src/input-plugins => plugins/openvr/src}/ViveControllerManager.cpp (97%) rename {libraries/input-plugins/src/input-plugins => plugins/openvr/src}/ViveControllerManager.h (98%) create mode 100644 plugins/openvr/src/plugin.json diff --git a/cmake/externals/openvr/CMakeLists.txt b/cmake/externals/openvr/CMakeLists.txt index f9d0ef5a71..9ef95b17da 100644 --- a/cmake/externals/openvr/CMakeLists.txt +++ b/cmake/externals/openvr/CMakeLists.txt @@ -7,9 +7,8 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) ExternalProject_Add( ${EXTERNAL_NAME} - #URL https://github.com/ValveSoftware/openvr/archive/0.9.1.zip - URL http://hifi-public.s3.amazonaws.com/dependencies/openvr-0.9.1.zip - URL_MD5 f986f5a6815e9454c53c5bf58ce02fdc + URL https://github.com/ValveSoftware/openvr/archive/v0.9.12.zip + URL_MD5 c08dced68ce4e341e1467e6814ae419d CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp index 6c34612e8c..08368597d0 100644 --- a/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp @@ -14,8 +14,6 @@ #include "stereo/InterleavedStereoDisplayPlugin.h" #include "Basic2DWindowOpenGLDisplayPlugin.h" -#include "openvr/OpenVrDisplayPlugin.h" - const QString& DisplayPlugin::MENU_PATH() { static const QString value = "Display"; return value; @@ -25,22 +23,14 @@ const QString& DisplayPlugin::MENU_PATH() { DisplayPluginList getDisplayPlugins() { DisplayPlugin* PLUGIN_POOL[] = { new Basic2DWindowOpenGLDisplayPlugin(), - new NullDisplayPlugin(), #ifdef DEBUG + new NullDisplayPlugin(), #endif - // Stereo modes - // SBS left/right new SideBySideStereoDisplayPlugin(), // Interleaved left/right new InterleavedStereoDisplayPlugin(), - - // HMDs -//#ifdef Q_OS_WIN -// // SteamVR SDK -// new OpenVrDisplayPlugin(), -//#endif nullptr }; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 80710e9b96..db7acf8bf1 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -103,8 +104,12 @@ public: // take the latest texture and present it _context->makeCurrent(); - currentPlugin->present(); - _context->doneCurrent(); + if (QOpenGLContext::currentContext() == _context->contextHandle()) { + _activePlugin->present(); + _context->doneCurrent(); + } else { + qWarning() << "Makecurrent failed"; + } } _context->makeCurrent(); diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 88ccddc125..72211056d9 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -74,7 +74,7 @@ protected: ProgramPtr _program; ShapeWrapperPtr _plane; - Mutex _mutex; + mutable Mutex _mutex; SimpleMovingAverage _usecsPerFrame { 10 }; QMap _sceneTextureToFrameIndexMap; diff --git a/libraries/input-plugins/CMakeLists.txt b/libraries/input-plugins/CMakeLists.txt index 0e21d4a40c..b81554511d 100644 --- a/libraries/input-plugins/CMakeLists.txt +++ b/libraries/input-plugins/CMakeLists.txt @@ -1,15 +1,5 @@ set(TARGET_NAME input-plugins) setup_hifi_library() -link_hifi_libraries(shared plugins controllers script-engine render-utils) +link_hifi_libraries(shared plugins controllers) GroupSources("src/input-plugins") - -if (WIN32) - add_dependency_external_projects(OpenVR) - find_package(OpenVR REQUIRED) - target_include_directories(${TARGET_NAME} PRIVATE ${OPENVR_INCLUDE_DIRS}) - target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES}) -endif() - -target_sdl2() -target_sixense() diff --git a/libraries/input-plugins/src/input-plugins/InputPlugin.cpp b/libraries/input-plugins/src/input-plugins/InputPlugin.cpp index 6db35572b5..4b79572a07 100644 --- a/libraries/input-plugins/src/input-plugins/InputPlugin.cpp +++ b/libraries/input-plugins/src/input-plugins/InputPlugin.cpp @@ -15,7 +15,6 @@ #include "KeyboardMouseDevice.h" #include "SDL2Manager.h" #include "SixenseManager.h" -#include "ViveControllerManager.h" // TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class InputPluginList getInputPlugins() { @@ -23,7 +22,6 @@ InputPluginList getInputPlugins() { new KeyboardMouseDevice(), new SDL2Manager(), new SixenseManager(), - new ViveControllerManager(), nullptr }; diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 3306659c80..a075b0a91d 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -82,7 +82,7 @@ void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) { } Q_DECLARE_METATYPE(controller::InputController*) -static int inputControllerPointerId = qRegisterMetaType(); +//static int inputControllerPointerId = qRegisterMetaType(); QScriptValue inputControllerToScriptValue(QScriptEngine *engine, controller::InputController* const &in) { return engine->newQObject(in); diff --git a/plugins/openvr/CMakeLists.txt b/plugins/openvr/CMakeLists.txt new file mode 100644 index 0000000000..e7fab5903d --- /dev/null +++ b/plugins/openvr/CMakeLists.txt @@ -0,0 +1,25 @@ +# +# Created by Bradley Austin Davis on 2015/11/18 +# 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 +# + +if (WIN32) + # we're using static GLEW, so define GLEW_STATIC + add_definitions(-DGLEW_STATIC) + set(TARGET_NAME openvr) + setup_hifi_plugin(OpenGL Script Qml Widgets) + link_hifi_libraries(shared gl networking controllers + plugins display-plugins input-plugins script-engine + render-utils model gpu render model-networking fbx) + + include_hifi_library_headers(octree) + + add_dependency_external_projects(OpenVR) + find_package(OpenVR REQUIRED) + target_include_directories(${TARGET_NAME} PRIVATE ${OPENVR_INCLUDE_DIRS}) + target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES}) + +endif() \ No newline at end of file diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp similarity index 65% rename from libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp rename to plugins/openvr/src/OpenVrDisplayPlugin.cpp index 68a711a847..58f7536856 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -7,24 +7,23 @@ // #include "OpenVrDisplayPlugin.h" -#if defined(Q_OS_WIN) - #include #include +#include #include -#include #include #include +#include +#include + #include #include #include #include "OpenVrHelpers.h" -#include "GLMHelpers.h" -#include Q_DECLARE_LOGGING_CATEGORY(displayplugins) Q_LOGGING_CATEGORY(displayplugins, "hifi.displayplugins") @@ -41,12 +40,11 @@ vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount]; mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount]; static mat4 _sensorResetMat; static uvec2 _windowSize; -static ivec2 _windowPosition; static uvec2 _renderTargetSize; struct PerEyeData { - uvec2 _viewportOrigin; - uvec2 _viewportSize; + //uvec2 _viewportOrigin; + //uvec2 _viewportSize; mat4 _projectionMatrix; mat4 _eyeOffset; mat4 _pose; @@ -89,36 +87,17 @@ void OpenVrDisplayPlugin::activate() { } Q_ASSERT(_hmd); - _hmd->GetWindowBounds(&_windowPosition.x, &_windowPosition.y, &_windowSize.x, &_windowSize.y); _hmd->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y); // Recommended render target size is per-eye, so double the X size for // left + right eyes _renderTargetSize.x *= 2; openvr_for_each_eye([&](vr::Hmd_Eye eye) { PerEyeData& eyeData = _eyesData[eye]; - _hmd->GetEyeOutputViewport(eye, - &eyeData._viewportOrigin.x, &eyeData._viewportOrigin.y, - &eyeData._viewportSize.x, &eyeData._viewportSize.y); eyeData._projectionMatrix = toGlm(_hmd->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, vr::API_OpenGL)); eyeData._eyeOffset = toGlm(_hmd->GetEyeToHeadTransform(eye)); }); - - - vr::HmdError eError = vr::HmdError_None; - _compositor = (vr::IVRCompositor*)vr::VR_GetGenericInterface(vr::IVRCompositor_Version, &eError); - Q_ASSERT(eError == vr::HmdError_None); + _compositor = vr::VRCompositor(); Q_ASSERT(_compositor); - - _compositor->SetGraphicsDevice(vr::Compositor_DeviceType_OpenGL, NULL); - - uint32_t unSize = _compositor->GetLastError(NULL, 0); - if (unSize > 1) { - char* buffer = new char[unSize]; - _compositor->GetLastError(buffer, unSize); - printf("Compositor - %s\n", buffer); - delete[] buffer; - } - Q_ASSERT(unSize <= 1); WindowOpenGLDisplayPlugin::activate(); } @@ -132,6 +111,16 @@ void OpenVrDisplayPlugin::deactivate() { WindowOpenGLDisplayPlugin::deactivate(); } +void OpenVrDisplayPlugin::customizeContext() { + static std::once_flag once; + std::call_once(once, []{ + glewExperimental = true; + GLenum err = glewInit(); + glGetError(); + }); + WindowOpenGLDisplayPlugin::customizeContext(); +} + uvec2 OpenVrDisplayPlugin::getRecommendedRenderSize() const { return _renderTargetSize; } @@ -153,33 +142,41 @@ glm::mat4 OpenVrDisplayPlugin::getEyeToHeadTransform(Eye eye) const { } glm::mat4 OpenVrDisplayPlugin::getHeadPose(uint32_t frameIndex) const { - return _trackedDevicePoseMat4[0]; + glm::mat4 result; + { + Lock lock(_mutex); + result = _trackedDevicePoseMat4[0]; + + } + return result; } -void OpenVrDisplayPlugin::customizeContext() { - WindowOpenGLDisplayPlugin::customizeContext(); + +void OpenVrDisplayPlugin::submitSceneTexture(uint32_t frameIndex, uint32_t sceneTexture, const glm::uvec2& sceneSize) { + WindowOpenGLDisplayPlugin::submitSceneTexture(frameIndex, sceneTexture, sceneSize); } -//void OpenVrDisplayPlugin::display(uint32_t frameIndex, uint32_t finalTexture, const glm::uvec2& sceneSize) { -// // Flip y-axis since GL UV coords are backwards. -// static vr::Compositor_TextureBounds leftBounds{ 0, 1, 0.5f, 0 }; -// static vr::Compositor_TextureBounds rightBounds{ 0.5f, 1, 1, 0 }; -// _compositor->Submit(vr::Eye_Left, (void*)finalTexture, &leftBounds); -// _compositor->Submit(vr::Eye_Right, (void*)finalTexture, &rightBounds); -// glFinish(); -//} - -//void OpenVrDisplayPlugin::finishFrame() { -//// swapBuffers(); -// doneCurrent(); -// _compositor->WaitGetPoses(_trackedDevicePose, vr::k_unMaxTrackedDeviceCount); -// for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) { -// _trackedDevicePoseMat4[i] = _sensorResetMat * toGlm(_trackedDevicePose[i].mDeviceToAbsoluteTracking); -// } -// openvr_for_each_eye([&](vr::Hmd_Eye eye) { -// _eyesData[eye]._pose = _trackedDevicePoseMat4[0]; -// }); -//}; - -#endif +void OpenVrDisplayPlugin::internalPresent() { + // Flip y-axis since GL UV coords are backwards. + static vr::VRTextureBounds_t leftBounds{ 0, 0, 0.5f, 1 }; + static vr::VRTextureBounds_t rightBounds{ 0.5f, 0, 1, 1 }; + vr::Texture_t texture{ (void*)_currentSceneTexture, vr::API_OpenGL, vr::ColorSpace_Auto }; + { + Lock lock(_mutex); + _compositor->Submit(vr::Eye_Left, &texture, &leftBounds); + _compositor->Submit(vr::Eye_Right, &texture, &rightBounds); + } + glFinish(); + { + Lock lock(_mutex); + _compositor->WaitGetPoses(_trackedDevicePose, vr::k_unMaxTrackedDeviceCount, nullptr, 0); + for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) { + _trackedDevicePoseMat4[i] = _sensorResetMat * toGlm(_trackedDevicePose[i].mDeviceToAbsoluteTracking); + } + openvr_for_each_eye([&](vr::Hmd_Eye eye) { + _eyesData[eye]._pose = _trackedDevicePoseMat4[0]; + }); + } + //WindowOpenGLDisplayPlugin::internalPresent(); +} diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h similarity index 84% rename from libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h rename to plugins/openvr/src/OpenVrDisplayPlugin.h index c8887276b7..4b5639d52b 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h +++ b/plugins/openvr/src/OpenVrDisplayPlugin.h @@ -9,10 +9,9 @@ #include -#if defined(Q_OS_WIN) #include -#include "../WindowOpenGLDisplayPlugin.h" +#include class OpenVrDisplayPlugin : public WindowOpenGLDisplayPlugin { public: @@ -23,6 +22,8 @@ public: virtual void activate() override; virtual void deactivate() override; + virtual void customizeContext() override; + virtual glm::uvec2 getRecommendedRenderSize() const override; virtual glm::uvec2 getRecommendedUiSize() const override { return uvec2(1920, 1080); } @@ -32,15 +33,13 @@ public: virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override; virtual glm::mat4 getHeadPose(uint32_t frameIndex) const override; + virtual void submitSceneTexture(uint32_t frameIndex, uint32_t sceneTexture, const glm::uvec2& sceneSize) override; protected: -// virtual void display(uint32_t frameIndex, uint32_t finalTexture, const glm::uvec2& sceneSize) override; - virtual void customizeContext() override; + virtual void internalPresent() override; private: vr::IVRSystem* _hmd { nullptr }; static const QString NAME; }; -#endif - diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.cpp b/plugins/openvr/src/OpenVrHelpers.cpp similarity index 80% rename from libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.cpp rename to plugins/openvr/src/OpenVrHelpers.cpp index f8e810beaf..7020fcb40d 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.cpp +++ b/plugins/openvr/src/OpenVrHelpers.cpp @@ -7,14 +7,15 @@ // #include "OpenVrHelpers.h" -#if defined(Q_OS_WIN) - -#include - #include #include -#include "../Logging.h" +#include +#include +#include + + +Q_DECLARE_LOGGING_CATEGORY(displayplugins) using Mutex = std::mutex; using Lock = std::unique_lock; @@ -30,13 +31,13 @@ vr::IVRSystem* acquireOpenVrSystem() { if (hmdPresent) { Lock lock(mutex); if (!activeHmd) { - qCDebug(displayPlugins) << "openvr: No vr::IVRSystem instance active, building"; - vr::HmdError eError = vr::HmdError_None; + qCDebug(displayplugins) << "openvr: No vr::IVRSystem instance active, building"; + vr::EVRInitError eError = vr::VRInitError_None; activeHmd = vr::VR_Init(&eError); - qCDebug(displayPlugins) << "openvr display: HMD is " << activeHmd << " error is " << eError; + qCDebug(displayplugins) << "openvr display: HMD is " << activeHmd << " error is " << eError; } if (activeHmd) { - qCDebug(displayPlugins) << "openvr: incrementing refcount"; + qCDebug(displayplugins) << "openvr: incrementing refcount"; ++refCount; } } @@ -46,10 +47,10 @@ vr::IVRSystem* acquireOpenVrSystem() { void releaseOpenVrSystem() { if (activeHmd) { Lock lock(mutex); - qDebug() << "openvr: decrementing refcount"; + qCDebug(displayplugins) << "openvr: decrementing refcount"; --refCount; if (0 == refCount) { - qDebug() << "openvr: zero refcount, deallocate VR system"; + qCDebug(displayplugins) << "openvr: zero refcount, deallocate VR system"; // Avoid spamming the VR system with activate/deactivate calls at system startup by // putting in a delay before we destory the shutdown the VR subsystem @@ -71,5 +72,3 @@ void releaseOpenVrSystem() { } } } - -#endif diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.h b/plugins/openvr/src/OpenVrHelpers.h similarity index 89% rename from libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.h rename to plugins/openvr/src/OpenVrHelpers.h index 3e445d90ba..513e1702d2 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrHelpers.h +++ b/plugins/openvr/src/OpenVrHelpers.h @@ -7,9 +7,6 @@ // #pragma once -#include - -#if defined(Q_OS_WIN) #include #include #include @@ -18,5 +15,3 @@ vr::IVRSystem* acquireOpenVrSystem(); void releaseOpenVrSystem(); -#endif - diff --git a/plugins/openvr/src/OpenVrProvider.cpp b/plugins/openvr/src/OpenVrProvider.cpp new file mode 100644 index 0000000000..66227a9543 --- /dev/null +++ b/plugins/openvr/src/OpenVrProvider.cpp @@ -0,0 +1,60 @@ +// +// Created by Bradley Austin Davis on 2015/10/25 +// 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 + +#include +#include +#include + +#include + +#include "OpenVrDisplayPlugin.h" +#include "ViveControllerManager.h" + +class OpenVrProvider : public QObject, public DisplayProvider, InputProvider +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DisplayProvider_iid FILE "plugin.json") + Q_INTERFACES(DisplayProvider) + Q_PLUGIN_METADATA(IID InputProvider_iid FILE "plugin.json") + Q_INTERFACES(InputProvider) + +public: + OpenVrProvider(QObject* parent = nullptr) : QObject(parent) {} + virtual ~OpenVrProvider() {} + + virtual DisplayPluginList getDisplayPlugins() override { + static std::once_flag once; + std::call_once(once, [&] { + DisplayPluginPointer plugin(new OpenVrDisplayPlugin()); + if (plugin->isSupported()) { + _displayPlugins.push_back(plugin); + } + }); + return _displayPlugins; + } + + virtual InputPluginList getInputPlugins() override { + static std::once_flag once; + std::call_once(once, [&] { + InputPluginPointer plugin(new ViveControllerManager()); + if (plugin->isSupported()) { + _inputPlugins.push_back(plugin); + } + }); + return _inputPlugins; + } + + +private: + DisplayPluginList _displayPlugins; + InputPluginList _inputPlugins; +}; + +#include "OpenVrProvider.moc" diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp similarity index 97% rename from libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp rename to plugins/openvr/src/ViveControllerManager.cpp index 5315152cea..39056cd46f 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -26,10 +25,10 @@ #include -#ifdef Q_OS_WIN +#include "OpenVrHelpers.h" + extern vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount]; extern mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount]; -#endif vr::IVRSystem* acquireOpenVrSystem(); void releaseOpenVrSystem(); @@ -39,7 +38,7 @@ static const float CONTROLLER_LENGTH_OFFSET = 0.0762f; // three inches static const glm::vec3 CONTROLLER_OFFSET = glm::vec3(CONTROLLER_LENGTH_OFFSET / 2.0f, CONTROLLER_LENGTH_OFFSET / 2.0f, CONTROLLER_LENGTH_OFFSET * 2.0f); -static const QString CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b"; +static const char* CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b"; static const QString MENU_PARENT = "Avatar"; static const QString MENU_NAME = "Vive Controllers"; @@ -49,19 +48,14 @@ static const QString RENDER_CONTROLLERS = "Render Hand Controllers"; const QString ViveControllerManager::NAME = "OpenVR"; bool ViveControllerManager::isSupported() const { -#ifdef Q_OS_WIN auto hmd = acquireOpenVrSystem(); bool success = hmd != nullptr; releaseOpenVrSystem(); return success; -#else - return false; -#endif } void ViveControllerManager::activate() { InputPlugin::activate(); -#ifdef Q_OS_WIN _container->addMenu(MENU_PATH); _container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, RENDER_CONTROLLERS, [this] (bool clicked) { this->setRenderControllers(clicked); }, @@ -72,8 +66,11 @@ void ViveControllerManager::activate() { } Q_ASSERT(_hmd); + auto renderModels = vr::VRRenderModels(); + vr::RenderModel_t model; - if (!_hmd->LoadRenderModel(CONTROLLER_MODEL_STRING.toStdString().c_str(), &model)) { + /* + if (!_hmd->LoadRenderModel(CONTROLLER_MODEL_STRING, &model)) { qDebug() << QString("Unable to load render model %1\n").arg(CONTROLLER_MODEL_STRING); } else { model::Mesh* mesh = new model::Mesh(); @@ -118,7 +115,7 @@ void ViveControllerManager::activate() { _modelLoaded = true; _renderControllers = true; } -#endif + */ // unregister with UserInputMapper auto userInputMapper = DependencyManager::get(); @@ -129,7 +126,6 @@ void ViveControllerManager::activate() { void ViveControllerManager::deactivate() { InputPlugin::deactivate(); -#ifdef Q_OS_WIN _container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS); _container->removeMenu(MENU_PATH); @@ -139,7 +135,6 @@ void ViveControllerManager::deactivate() { } _inputDevice->_poseStateMap.clear(); -#endif // unregister with UserInputMapper auto userInputMapper = DependencyManager::get(); @@ -225,7 +220,6 @@ void ViveControllerManager::pluginUpdate(float deltaTime, bool jointsCaptured) { } void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCaptured) { -#ifdef Q_OS_WIN _poseStateMap.clear(); _buttonPressedMap.clear(); @@ -276,7 +270,6 @@ void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCapt } _trackedControllers = numTrackedControllers; -#endif } void ViveControllerManager::InputDevice::focusOutEvent() { @@ -286,7 +279,6 @@ void ViveControllerManager::InputDevice::focusOutEvent() { // These functions do translation from the Steam IDs to the standard controller IDs void ViveControllerManager::InputDevice::handleAxisEvent(uint32_t axis, float x, float y, bool left) { -#ifdef Q_OS_WIN //FIX ME? It enters here every frame: probably we want to enter only if an event occurs axis += vr::k_EButton_Axis0; using namespace controller; @@ -296,12 +288,10 @@ void ViveControllerManager::InputDevice::handleAxisEvent(uint32_t axis, float x, } else if (axis == vr::k_EButton_SteamVR_Trigger) { _axisStateMap[left ? LT : RT] = x; } -#endif } // These functions do translation from the Steam IDs to the standard controller IDs void ViveControllerManager::InputDevice::handleButtonEvent(uint32_t button, bool pressed, bool left) { -#ifdef Q_OS_WIN if (!pressed) { return; } @@ -319,7 +309,6 @@ void ViveControllerManager::InputDevice::handleButtonEvent(uint32_t button, bool //FIX ME: not able to ovrewrite the behaviour of this button _buttonPressedMap.insert(left ? controller::LEFT_SECONDARY_THUMB : controller::RIGHT_SECONDARY_THUMB); } -#endif } void ViveControllerManager::InputDevice::handlePoseEvent(const mat4& mat, bool left) { diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h similarity index 98% rename from libraries/input-plugins/src/input-plugins/ViveControllerManager.h rename to plugins/openvr/src/ViveControllerManager.h index 02bdecb10a..077aec7fc3 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -20,7 +20,7 @@ #include #include #include -#include "InputPlugin.h" +#include #include #include diff --git a/plugins/openvr/src/plugin.json b/plugins/openvr/src/plugin.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/plugins/openvr/src/plugin.json @@ -0,0 +1 @@ +{} From b4c272aaa13c1f44beb2b6a9592e59171063aea3 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Wed, 9 Dec 2015 17:28:45 -0800 Subject: [PATCH 64/78] sam just left --- .../src/RenderableParticleEffectEntityItem.cpp | 11 +++++++---- libraries/script-engine/src/ScriptEngine.cpp | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 43c6373147..74c26c91d4 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -60,8 +60,7 @@ public: void setTexture(gpu::TexturePointer texture) { _texture = texture; } const gpu::TexturePointer& getTexture() const { return _texture; } - bool getVisibleFlag() const { return _visibleFlag; } - void setVisibleFlag(bool visibleFlag) { _visibleFlag = visibleFlag; } + bool getVisibleFlag() const { return _entity->isVisible(); } void render(RenderArgs* args) const { assert(_pipeline); @@ -91,7 +90,7 @@ protected: gpu::BufferPointer _vertexBuffer; gpu::BufferPointer _indexBuffer; gpu::TexturePointer _texture; - bool _visibleFlag = true; + }; namespace render { @@ -111,7 +110,11 @@ namespace render { template <> void payloadRender(const ParticlePayload::Pointer& payload, RenderArgs* args) { - payload->render(args); + if (args) { + if (payload && payload->getVisibleFlag()) { + payload->render(args); + } + } } } diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 3306659c80..a075b0a91d 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -82,7 +82,7 @@ void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) { } Q_DECLARE_METATYPE(controller::InputController*) -static int inputControllerPointerId = qRegisterMetaType(); +//static int inputControllerPointerId = qRegisterMetaType(); QScriptValue inputControllerToScriptValue(QScriptEngine *engine, controller::InputController* const &in) { return engine->newQObject(in); From fd5fb3096f2eacaeddf98977be9caa06ab258c7b Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 8 Dec 2015 17:55:46 -0800 Subject: [PATCH 65/78] Disabling OpenVR plugin --- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 2 +- plugins/openvr/CMakeLists.txt | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index db7acf8bf1..880e4a16b3 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -105,7 +105,7 @@ public: // take the latest texture and present it _context->makeCurrent(); if (QOpenGLContext::currentContext() == _context->contextHandle()) { - _activePlugin->present(); + currentPlugin->present(); _context->doneCurrent(); } else { qWarning() << "Makecurrent failed"; diff --git a/plugins/openvr/CMakeLists.txt b/plugins/openvr/CMakeLists.txt index e7fab5903d..c3c4771276 100644 --- a/plugins/openvr/CMakeLists.txt +++ b/plugins/openvr/CMakeLists.txt @@ -6,7 +6,10 @@ # See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html # -if (WIN32) +# OpenVR is disabled until a) it works with threaded present and +# b) it doesn't interfere with Oculus SDK 0.8 +if (FALSE) +#if (WIN32) # we're using static GLEW, so define GLEW_STATIC add_definitions(-DGLEW_STATIC) set(TARGET_NAME openvr) @@ -21,5 +24,4 @@ if (WIN32) find_package(OpenVR REQUIRED) target_include_directories(${TARGET_NAME} PRIVATE ${OPENVR_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES}) - -endif() \ No newline at end of file +endif() From 1644bda9080983237524dea8d5db6636976af1aa Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 8 Dec 2015 14:21:14 -0800 Subject: [PATCH 66/78] Migrate to latest Oculus SDK (0.8) --- cmake/externals/LibOVR/CMakeLists.txt | 11 ++- .../oculus/src/OculusBaseDisplayPlugin.cpp | 71 ++++++++++--------- plugins/oculus/src/OculusBaseDisplayPlugin.h | 8 +-- plugins/oculus/src/OculusDisplayPlugin.cpp | 51 ++++++------- 4 files changed, 70 insertions(+), 71 deletions(-) diff --git a/cmake/externals/LibOVR/CMakeLists.txt b/cmake/externals/LibOVR/CMakeLists.txt index 8d13882d48..a98745b404 100644 --- a/cmake/externals/LibOVR/CMakeLists.txt +++ b/cmake/externals/LibOVR/CMakeLists.txt @@ -15,17 +15,16 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) # 0.6 public # URL http://static.oculus.com/sdk-downloads/0.6.0.1/Public/1435190862/ovr_sdk_win_0.6.0.1.zip # URL_MD5 4b3ef825f9a1d6d3035c9f6820687da9 -# 0.7 alpha -# URL https://s3.amazonaws.com/static.oculus.com/sdk-downloads/0.7.0.0/Public/Alpha/ovr_sdk_win_0.7.0.0_RC1.zip -# URL_MD5 a562bb9d117087b2cf9d86653ea70fd8 - +# 0.8 public +# URL http://static.oculus.com/sdk-downloads/0.8.0.0/Public/1445451746/ovr_sdk_win_0.8.0.0.zip +# URL_MD5 54944b03b95149d6010f84eb701b9647 if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://static.oculus.com/sdk-downloads/0.6.0.1/Public/1435190862/ovr_sdk_win_0.6.0.1.zip - URL_MD5 4b3ef825f9a1d6d3035c9f6820687da9 + URL http://static.oculus.com/sdk-downloads/0.8.0.0/Public/1445451746/ovr_sdk_win_0.8.0.0.zip + URL_MD5 54944b03b95149d6010f84eb701b9647 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index 7c057c7152..d6811c3529 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -20,9 +20,7 @@ glm::mat4 OculusBaseDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseP } void OculusBaseDisplayPlugin::resetSensors() { -#if (OVR_MAJOR_VERSION >= 6) - ovr_RecenterPose(_hmd); -#endif + ovr_RecenterPose(_session); } glm::mat4 OculusBaseDisplayPlugin::getEyeToHeadTransform(Eye eye) const { @@ -30,27 +28,39 @@ glm::mat4 OculusBaseDisplayPlugin::getEyeToHeadTransform(Eye eye) const { } glm::mat4 OculusBaseDisplayPlugin::getHeadPose(uint32_t frameIndex) const { -#if (OVR_MAJOR_VERSION >= 6) - auto frameTiming = ovr_GetFrameTiming(_hmd, frameIndex); - auto trackingState = ovr_GetTrackingState(_hmd, frameTiming.DisplayMidpointSeconds); + static uint32_t lastFrameSeen = 0; + auto displayTime = ovr_GetPredictedDisplayTime(_session, frameIndex); + auto trackingState = ovr_GetTrackingState(_session, displayTime, frameIndex > lastFrameSeen); + if (frameIndex > lastFrameSeen) { + lastFrameSeen = frameIndex; + } return toGlm(trackingState.HeadPose.ThePose); -#endif } bool OculusBaseDisplayPlugin::isSupported() const { -#if (OVR_MAJOR_VERSION >= 6) if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { return false; } - bool result = false; - if (ovrHmd_Detect() > 0) { - result = true; + + ovrSession session { nullptr }; + ovrGraphicsLuid luid; + auto result = ovr_Create(&session, &luid); + if (!OVR_SUCCESS(result)) { + ovrErrorInfo error; + ovr_GetLastErrorInfo(&error); + ovr_Shutdown(); + return false; } + + auto hmdDesc = ovr_GetHmdDesc(session); + if (hmdDesc.Type == ovrHmd_None) { + ovr_Destroy(session); + ovr_Shutdown(); + return false; + } + ovr_Shutdown(); - return result; -#else - return false; -#endif + return true; } // DLL based display plugins MUST initialize GLEW inside the DLL code. @@ -69,28 +79,22 @@ void OculusBaseDisplayPlugin::deinit() { void OculusBaseDisplayPlugin::activate() { WindowOpenGLDisplayPlugin::activate(); -#if (OVR_MAJOR_VERSION >= 6) if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { qFatal("Could not init OVR"); } -#if (OVR_MAJOR_VERSION == 6) - if (!OVR_SUCCESS(ovr_Create(0, &_hmd))) { -#elif (OVR_MAJOR_VERSION == 7) - if (!OVR_SUCCESS(ovr_Create(&_hmd, &_luid))) { -#endif - Q_ASSERT(false); + if (!OVR_SUCCESS(ovr_Create(&_session, &_luid))) { qFatal("Failed to acquire HMD"); } - _hmdDesc = ovr_GetHmdDesc(_hmd); + _hmdDesc = ovr_GetHmdDesc(_session); - _ipd = ovr_GetFloat(_hmd, OVR_KEY_IPD, _ipd); + _ipd = ovr_GetFloat(_session, OVR_KEY_IPD, _ipd); glm::uvec2 eyeSizes[2]; ovr_for_each_eye([&](ovrEyeType eye) { _eyeFovs[eye] = _hmdDesc.DefaultEyeFov[eye]; - ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovr_GetRenderDesc(_hmd, eye, _eyeFovs[eye]); + ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovr_GetRenderDesc(_session, eye, _eyeFovs[eye]); ovrMatrix4f ovrPerspectiveProjection = ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded); _eyeProjections[eye] = toGlm(ovrPerspectiveProjection); @@ -100,7 +104,7 @@ void OculusBaseDisplayPlugin::activate() { _compositeEyeProjections[eye] = toGlm(ovrPerspectiveProjection); _eyeOffsets[eye] = erd.HmdToEyeViewOffset; - eyeSizes[eye] = toGlm(ovr_GetFovTextureSize(_hmd, eye, erd.Fov, 1.0f)); + eyeSizes[eye] = toGlm(ovr_GetFovTextureSize(_session, eye, erd.Fov, 1.0f)); }); ovrFovPort combined = _eyeFovs[Left]; combined.LeftTan = std::max(_eyeFovs[Left].LeftTan, _eyeFovs[Right].LeftTan); @@ -115,34 +119,33 @@ void OculusBaseDisplayPlugin::activate() { eyeSizes[0].x + eyeSizes[1].x, std::max(eyeSizes[0].y, eyeSizes[1].y)); - if (!OVR_SUCCESS(ovr_ConfigureTracking(_hmd, + if (!OVR_SUCCESS(ovr_ConfigureTracking(_session, ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) { qFatal("Could not attach to sensor device"); } - // Parent class relies on our _hmd intialization, so it must come after that. + // Parent class relies on our _session intialization, so it must come after that. memset(&_sceneLayer, 0, sizeof(ovrLayerEyeFov)); _sceneLayer.Header.Type = ovrLayerType_EyeFov; _sceneLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; ovr_for_each_eye([&](ovrEyeType eye) { ovrFovPort & fov = _sceneLayer.Fov[eye] = _eyeRenderDescs[eye].Fov; - ovrSizei & size = _sceneLayer.Viewport[eye].Size = ovr_GetFovTextureSize(_hmd, eye, fov, 1.0f); + ovrSizei & size = _sceneLayer.Viewport[eye].Size = ovr_GetFovTextureSize(_session, eye, fov, 1.0f); _sceneLayer.Viewport[eye].Pos = { eye == ovrEye_Left ? 0 : size.w, 0 }; }); - if (!OVR_SUCCESS(ovr_ConfigureTracking(_hmd, + if (!OVR_SUCCESS(ovr_ConfigureTracking(_session, ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) { qFatal("Could not attach to sensor device"); } -#endif } void OculusBaseDisplayPlugin::deactivate() { WindowOpenGLDisplayPlugin::deactivate(); #if (OVR_MAJOR_VERSION >= 6) - ovr_Destroy(_hmd); - _hmd = nullptr; + ovr_Destroy(_session); + _session = nullptr; ovr_Shutdown(); #endif } @@ -151,7 +154,7 @@ void OculusBaseDisplayPlugin::deactivate() { float OculusBaseDisplayPlugin::getIPD() const { float result = OVR_DEFAULT_IPD; #if (OVR_MAJOR_VERSION >= 6) - result = ovr_GetFloat(_hmd, OVR_KEY_IPD, result); + result = ovr_GetFloat(_session, OVR_KEY_IPD, result); #endif return result; } diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h index 711be6aa5e..1a26c6958b 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -43,17 +43,13 @@ protected: mat4 _compositeEyeProjections[2]; uvec2 _desiredFramebufferSize; -#if (OVR_MAJOR_VERSION >= 6) - ovrHmd _hmd; + ovrSession _session; + ovrGraphicsLuid _luid; float _ipd{ OVR_DEFAULT_IPD }; ovrEyeRenderDesc _eyeRenderDescs[2]; ovrFovPort _eyeFovs[2]; ovrHmdDesc _hmdDesc; ovrLayerEyeFov _sceneLayer; -#endif -#if (OVR_MAJOR_VERSION == 7) - ovrGraphicsLuid _luid; -#endif }; #if (OVR_MAJOR_VERSION == 6) diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp index e6eae2cf02..c8fb0ba080 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -23,12 +23,16 @@ // ovr_CreateMirrorTextureGL, etc template struct RiftFramebufferWrapper : public FramebufferWrapper { - ovrHmd hmd; - RiftFramebufferWrapper(const ovrHmd & hmd) : hmd(hmd) { + ovrSession session; + RiftFramebufferWrapper(const ovrSession& session) : session(session) { color = 0; depth = 0; }; + ~RiftFramebufferWrapper() { + destroyColor(); + } + void Resize(const uvec2 & size) { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oglplus::GetName(fbo)); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); @@ -39,6 +43,9 @@ struct RiftFramebufferWrapper : public FramebufferWrapper { } protected: + virtual void destroyColor() { + } + virtual void initDepth() override final { } }; @@ -53,12 +60,6 @@ struct SwapFramebufferWrapper : public RiftFramebufferWrapperCurrentIndex; @@ -66,13 +67,17 @@ struct SwapFramebufferWrapper : public RiftFramebufferWrapper { MirrorFramebufferWrapper(const ovrHmd & hmd) : RiftFramebufferWrapper(hmd) { } - virtual ~MirrorFramebufferWrapper() { +private: + virtual void destroyColor() override { if (color) { - ovr_DestroyMirrorTexture(hmd, (ovrTexture*)color); + ovr_DestroyMirrorTexture(session, (ovrTexture*)color); color = nullptr; } } -private: void initColor() override { - if (color) { - ovr_DestroyMirrorTexture(hmd, (ovrTexture*)color); - color = nullptr; - } - ovrResult result = ovr_CreateMirrorTextureGL(hmd, GL_RGBA, size.x, size.y, (ovrTexture**)&color); + destroyColor(); + ovrResult result = ovr_CreateMirrorTextureGL(session, GL_SRGB8_ALPHA8, size.x, size.y, (ovrTexture**)&color); Q_ASSERT(OVR_SUCCESS(result)); } @@ -154,8 +156,7 @@ void OculusDisplayPlugin::activate() { void OculusDisplayPlugin::customizeContext() { OculusBaseDisplayPlugin::customizeContext(); -#if (OVR_MAJOR_VERSION >= 6) - _sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_hmd)); + _sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_session)); _sceneFbo->Init(getRecommendedRenderSize()); // We're rendering both eyes to the same texture, so only one of the @@ -163,7 +164,7 @@ void OculusDisplayPlugin::customizeContext() { _sceneLayer.ColorTexture[0] = _sceneFbo->color; // not needed since the structure was zeroed on init, but explicit _sceneLayer.ColorTexture[1] = nullptr; -#endif + enableVsync(false); // Only enable mirroring if we know vsync is disabled _enablePreview = !isVsyncEnabled(); @@ -177,7 +178,6 @@ void OculusDisplayPlugin::uncustomizeContext() { } void OculusDisplayPlugin::internalPresent() { -#if (OVR_MAJOR_VERSION >= 6) if (!_currentSceneTexture) { return; } @@ -206,8 +206,10 @@ void OculusDisplayPlugin::internalPresent() { auto size = _sceneFbo->size; Context::Viewport(size.x, size.y); glBindTexture(GL_TEXTURE_2D, _currentSceneTexture); + //glEnable(GL_FRAMEBUFFER_SRGB); GLenum err = glGetError(); drawUnitQuad(); + //glDisable(GL_FRAMEBUFFER_SRGB); }); uint32_t frameIndex { 0 }; @@ -230,13 +232,12 @@ void OculusDisplayPlugin::internalPresent() { viewScaleDesc.HmdToEyeViewOffset[1] = _eyeOffsets[1]; ovrLayerHeader* layers = &_sceneLayer.Header; - ovrResult result = ovr_SubmitFrame(_hmd, frameIndex, &viewScaleDesc, &layers, 1); + ovrResult result = ovr_SubmitFrame(_session, frameIndex, &viewScaleDesc, &layers, 1); if (!OVR_SUCCESS(result)) { qDebug() << result; } } _sceneFbo->Increment(); -#endif /* The swapbuffer call here is only required if we want to mirror the content to the screen. From e9f529bf12d300050892eae9f16b5de81ca14d9c Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 9 Dec 2015 17:59:56 -0800 Subject: [PATCH 67/78] Entities: Removed Start Automatically property from Animation Group There is an issue when startAutomatically was set to true and animationPlaying was set to false. This would cause clients to play the animation when they connected to the entity server, even though the server was not. --- examples/html/entityProperties.html | 9 ------- .../entities/src/AnimationPropertyGroup.cpp | 26 ------------------- .../entities/src/AnimationPropertyGroup.h | 1 - .../entities/src/EntityItemProperties.cpp | 1 - libraries/entities/src/ModelEntityItem.cpp | 5 ---- libraries/entities/src/ModelEntityItem.h | 3 --- .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 1 + 8 files changed, 2 insertions(+), 46 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 186b2ee828..ff72e95313 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -298,7 +298,6 @@ var elModelAnimationLastFrame = document.getElementById("property-model-animation-last-frame"); var elModelAnimationLoop = document.getElementById("property-model-animation-loop"); var elModelAnimationHold = document.getElementById("property-model-animation-hold"); - var elModelAnimationStartAutomatically = document.getElementById("property-model-animation-start-automatically"); var elModelTextures = document.getElementById("property-model-textures"); var elModelOriginalTextures = document.getElementById("property-model-original-textures"); @@ -532,7 +531,6 @@ elModelAnimationLastFrame.value = properties.animation.lastFrame; elModelAnimationLoop.checked = properties.animation.loop; elModelAnimationHold.checked = properties.animation.hold; - elModelAnimationStartAutomatically.checked = properties.animation.startAutomatically; elModelTextures.value = properties.textures; elModelOriginalTextures.value = properties.originalTextures; } else if (properties.type == "Web") { @@ -785,7 +783,6 @@ elModelAnimationLastFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'lastFrame')); elModelAnimationLoop.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'loop')); elModelAnimationHold.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'hold')); - elModelAnimationStartAutomatically.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'startAutomatically')); elModelTextures.addEventListener('change', createEmitTextPropertyUpdateFunction('textures')); @@ -1348,12 +1345,6 @@ -
- Animation Start Automatically - - - -
Textures
diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index f9d8c07443..ef89128e30 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -29,7 +29,6 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame, _animationLoop->getFirstFrame); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame, _animationLoop->getLastFrame); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold, _animationLoop->getHold); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically, _animationLoop->getStartAutomatically); } else { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, Animation, animation, FPS, fps); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, CurrentFrame, currentFrame); @@ -38,7 +37,6 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically); } } @@ -58,7 +56,6 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, _animationLoop->setFirstFrame); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, _animationLoop->setLastFrame); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, _animationLoop->setHold); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, _animationLoop->setStartAutomatically); // legacy property support COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, _animationLoop->setFPS, _animationLoop->getFPS); @@ -73,7 +70,6 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, setFirstFrame); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, setLastFrame); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, setHold); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, setStartAutomatically); // legacy property support COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, setFPS, getFPS); @@ -95,7 +91,6 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { float lastFrame = _animationLoop ? _animationLoop->getLastFrame() : getLastFrame(); bool loop = _animationLoop ? _animationLoop->getLoop() : getLoop(); bool hold = _animationLoop ? _animationLoop->getHold() : getHold(); - bool startAutomatically = _animationLoop ? _animationLoop->getStartAutomatically() : getStartAutomatically(); QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); QJsonObject settingsAsJsonObject = settingsAsJson.object(); @@ -130,10 +125,6 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { running = settingsMap["hold"].toBool(); } - if (settingsMap.contains("startAutomatically")) { - running = settingsMap["startAutomatically"].toBool(); - } - if (_animationLoop) { _animationLoop->setFPS(fps); _animationLoop->setCurrentFrame(currentFrame); @@ -142,7 +133,6 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { _animationLoop->setLastFrame(lastFrame); _animationLoop->setLoop(loop); _animationLoop->setHold(hold); - _animationLoop->setStartAutomatically(startAutomatically); } else { setFPS(fps); setCurrentFrame(currentFrame); @@ -151,7 +141,6 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { setLastFrame(lastFrame); setLoop(loop); setHold(hold); - setStartAutomatically(startAutomatically); } } @@ -194,7 +183,6 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically()); } else { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame()); @@ -203,7 +191,6 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); } return true; @@ -226,7 +213,6 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, _animationLoop->setFirstFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold); - READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically); } else { READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame); @@ -235,7 +221,6 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); - READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); } DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_URL, URL); @@ -246,7 +231,6 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FIRST_FRAME, FirstFrame); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LAST_FRAME, LastFrame); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_HOLD, Hold); - DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically); processedBytes += bytesRead; @@ -273,7 +257,6 @@ EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FIRST_FRAME, firstFrame); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LAST_FRAME, lastFrame); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_HOLD, hold); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_START_AUTOMATICALLY, startAutomatically); return changedProperties; } @@ -288,7 +271,6 @@ void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) con COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, _animationLoop->getFirstFrame); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, _animationLoop->getLastFrame); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, _animationLoop->getHold); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, _animationLoop->getStartAutomatically); } else { COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, getFPS); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, CurrentFrame, getCurrentFrame); @@ -297,7 +279,6 @@ void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) con COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, getFirstFrame); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, getLastFrame); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, getHold); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, getStartAutomatically); } } @@ -313,7 +294,6 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, _animationLoop->setFirstFrame); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, _animationLoop->setLastFrame); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, _animationLoop->setHold); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, _animationLoop->setStartAutomatically); } else { SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, setFPS); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, CurrentFrame, currentFrame, setCurrentFrame); @@ -322,7 +302,6 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, setFirstFrame); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, setLastFrame); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, setHold); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, setStartAutomatically); } return somethingChanged; @@ -339,7 +318,6 @@ EntityPropertyFlags AnimationPropertyGroup::getEntityProperties(EncodeBitstreamP requestedProperties += PROP_ANIMATION_FIRST_FRAME; requestedProperties += PROP_ANIMATION_LAST_FRAME; requestedProperties += PROP_ANIMATION_HOLD; - requestedProperties += PROP_ANIMATION_START_AUTOMATICALLY; return requestedProperties; } @@ -363,7 +341,6 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically()); } else { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame()); @@ -372,7 +349,6 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); } } @@ -395,7 +371,6 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, _animationLoop->setFirstFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold); - READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically); } else { READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame); @@ -404,7 +379,6 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); - READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); } return bytesRead; diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index 8c40b0c036..8e85d8bc99 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -80,7 +80,6 @@ public: DEFINE_PROPERTY(PROP_ANIMATION_FIRST_FRAME, FirstFrame, firstFrame, float, 0.0f); // was animationSettings.firstFrame DEFINE_PROPERTY(PROP_ANIMATION_LAST_FRAME, LastFrame, lastFrame, float, AnimationLoop::MAXIMUM_POSSIBLE_FRAME); // was animationSettings.lastFrame DEFINE_PROPERTY(PROP_ANIMATION_HOLD, Hold, hold, bool, false); // was animationSettings.hold - DEFINE_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically, startAutomatically, bool, false); // was animationSettings.startAutomatically protected: void setFromOldAnimationSettings(const QString& value); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index d040f785da..2e785519da 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -747,7 +747,6 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame); ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame); ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold); - ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically); ADD_GROUP_PROPERTY_TO_MAP(PROP_ATMOSPHERE_CENTER, Atmosphere, atmosphere, Center, center); ADD_GROUP_PROPERTY_TO_MAP(PROP_ATMOSPHERE_INNER_RADIUS, Atmosphere, atmosphere, InnerRadius, innerRadius); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index b0b0e7c76a..d96814ff04 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -384,11 +384,6 @@ void ModelEntityItem::setAnimationSettings(const QString& value) { setAnimationHold(hold); } - if (settingsMap.contains("startAutomatically")) { - bool startAutomatically = settingsMap["startAutomatically"].toBool(); - setAnimationStartAutomatically(startAutomatically); - } - _dirtyFlags |= Simulation::DIRTY_UPDATEABLE; } diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index cbd54f7168..2b8121c2f6 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -97,9 +97,6 @@ public: void setAnimationHold(bool hold) { _animationLoop.setHold(hold); } bool getAnimationHold() const { return _animationLoop.getHold(); } - void setAnimationStartAutomatically(bool startAutomatically) { _animationLoop.setStartAutomatically(startAutomatically); } - bool getAnimationStartAutomatically() const { return _animationLoop.getStartAutomatically(); } - void setAnimationFirstFrame(float firstFrame) { _animationLoop.setFirstFrame(firstFrame); } float getAnimationFirstFrame() const { return _animationLoop.getFirstFrame(); } diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 93fbe7acdc..81aae796c1 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -41,7 +41,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: - return VERSION_ENTITIES_HAVE_PARENTS; + return VERSION_ENTITITES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP; case PacketType::AvatarData: case PacketType::BulkAvatarData: return 17; diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index cd7b9a113c..ba48c4ccf1 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -161,5 +161,6 @@ const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP_BIS = 48; const PacketVersion VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING = 49; const PacketVersion VERSION_ENTITIES_POLYLINE_TEXTURE = 50; const PacketVersion VERSION_ENTITIES_HAVE_PARENTS = 51; +const PacketVersion VERSION_ENTITITES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP = 52; #endif // hifi_PacketHeaders_h From 9e99bff25016f0c2739d9ed2599b4ac701be845a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 9 Dec 2015 18:09:55 -0800 Subject: [PATCH 68/78] fix avatar upward drift after shape change --- libraries/physics/src/CharacterController.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index ba3a59f69d..44d4269e0e 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -80,9 +80,13 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { if (world && _rigidBody) { _dynamicsWorld = world; _pendingFlags &= ~PENDING_FLAG_JUMP; + // Before adding the RigidBody to the world we must save its oldGravity to the side + // because adding an object to the world will overwrite it with the default gravity. + btVector3 oldGravity = _rigidBody->getGravity(); _dynamicsWorld->addRigidBody(_rigidBody, COLLISION_GROUP_MY_AVATAR, COLLISION_MASK_MY_AVATAR); _dynamicsWorld->addAction(this); - //reset(_dynamicsWorld); + // restore gravity settings + _rigidBody->setGravity(oldGravity); } } if (_dynamicsWorld) { From 4e93f3ae81d1320b00e702a11ea69569d2ccbae1 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Wed, 9 Dec 2015 18:26:13 -0800 Subject: [PATCH 69/78] respect visibility yay --- .../src/RenderableParticleEffectEntityItem.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 74c26c91d4..edbfb6158c 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -60,8 +60,6 @@ public: void setTexture(gpu::TexturePointer texture) { _texture = texture; } const gpu::TexturePointer& getTexture() const { return _texture; } - bool getVisibleFlag() const { return _entity->isVisible(); } - void render(RenderArgs* args) const { assert(_pipeline); @@ -80,23 +78,23 @@ public: auto numIndices = _indexBuffer->getSize() / sizeof(uint16_t); batch.drawIndexed(gpu::TRIANGLES, numIndices); } + + EntityItemPointer _entity; protected: - EntityItemPointer _entity; Transform _modelTransform; AABox _bound; gpu::PipelinePointer _pipeline; gpu::Stream::FormatPointer _vertexFormat; gpu::BufferPointer _vertexBuffer; gpu::BufferPointer _indexBuffer; - gpu::TexturePointer _texture; - + gpu::TexturePointer _texture; }; namespace render { template <> const ItemKey payloadGetKey(const ParticlePayload::Pointer& payload) { - if (payload->getVisibleFlag()) { + if (payload->_entity->getVisible()) { return ItemKey::Builder::transparentShape(); } else { return ItemKey::Builder().withInvisible().build(); @@ -110,11 +108,10 @@ namespace render { template <> void payloadRender(const ParticlePayload::Pointer& payload, RenderArgs* args) { - if (args) { - if (payload && payload->getVisibleFlag()) { - payload->render(args); - } + if (payload->_entity->getVisible()) { + payload->render(args); } + } } From 9ecb2b22770c25e421c80302b4b112c951ec9569 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Wed, 9 Dec 2015 18:27:45 -0800 Subject: [PATCH 70/78] uncomment sams change to scriptengine --- libraries/script-engine/src/ScriptEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index a075b0a91d..3306659c80 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -82,7 +82,7 @@ void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) { } Q_DECLARE_METATYPE(controller::InputController*) -//static int inputControllerPointerId = qRegisterMetaType(); +static int inputControllerPointerId = qRegisterMetaType(); QScriptValue inputControllerToScriptValue(QScriptEngine *engine, controller::InputController* const &in) { return engine->newQObject(in); From 3499b452f81225bc5961abebebe52773107fa445 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Thu, 10 Dec 2015 09:02:13 -0800 Subject: [PATCH 71/78] add back SDL and Sixense --- libraries/input-plugins/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/input-plugins/CMakeLists.txt b/libraries/input-plugins/CMakeLists.txt index b81554511d..af7cc3daa0 100644 --- a/libraries/input-plugins/CMakeLists.txt +++ b/libraries/input-plugins/CMakeLists.txt @@ -3,3 +3,6 @@ setup_hifi_library() link_hifi_libraries(shared plugins controllers) GroupSources("src/input-plugins") + +target_sdl2() +target_sixense() From d731875c5b8ac454115255bb266e6cb3ab4e36e2 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 10 Dec 2015 09:58:53 -0800 Subject: [PATCH 72/78] Fix dependencies for Linux builds. --- libraries/input-plugins/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/input-plugins/CMakeLists.txt b/libraries/input-plugins/CMakeLists.txt index af7cc3daa0..101a6c8016 100644 --- a/libraries/input-plugins/CMakeLists.txt +++ b/libraries/input-plugins/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME input-plugins) setup_hifi_library() -link_hifi_libraries(shared plugins controllers) +link_hifi_libraries(shared plugins controllers script-engine) GroupSources("src/input-plugins") From dd011e8bc4c72ecb9578666f7d369bba0793cb00 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 10 Dec 2015 10:05:01 -0800 Subject: [PATCH 73/78] Freakin' xcode ^S. --- libraries/input-plugins/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/input-plugins/CMakeLists.txt b/libraries/input-plugins/CMakeLists.txt index 101a6c8016..d2cf96c7f8 100644 --- a/libraries/input-plugins/CMakeLists.txt +++ b/libraries/input-plugins/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME input-plugins) setup_hifi_library() -link_hifi_libraries(shared plugins controllers script-engine) +link_hifi_libraries(shared plugins controllers script-engine) GroupSources("src/input-plugins") From 5053fcd11320530ce893bc581c96f74ebde90aee Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Thu, 10 Dec 2015 10:19:13 -0800 Subject: [PATCH 74/78] Fix unix builds --- libraries/input-plugins/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/input-plugins/CMakeLists.txt b/libraries/input-plugins/CMakeLists.txt index af7cc3daa0..d2cf96c7f8 100644 --- a/libraries/input-plugins/CMakeLists.txt +++ b/libraries/input-plugins/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME input-plugins) setup_hifi_library() -link_hifi_libraries(shared plugins controllers) +link_hifi_libraries(shared plugins controllers script-engine) GroupSources("src/input-plugins") From 645695d5d546676d8963a9e3aa685c984923afcf Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 18 Nov 2015 15:20:29 -0800 Subject: [PATCH 75/78] Moving sixense to external plugin --- .../ControllerScriptingInterface.cpp | 3 -- interface/src/ui/ApplicationCompositor.cpp | 1 - interface/src/ui/PreferencesDialog.cpp | 1 - libraries/input-plugins/CMakeLists.txt | 1 - .../src/input-plugins/InputPlugin.cpp | 2 - plugins/hifiSixense/CMakeLists.txt | 12 +++++ .../hifiSixense/src}/SixenseManager.cpp | 6 ++- .../hifiSixense/src}/SixenseManager.h | 2 +- plugins/hifiSixense/src/SixenseProvider.cpp | 45 +++++++++++++++++++ .../hifiSixense/src}/SixenseSupportOSX.cpp | 3 +- plugins/hifiSixense/src/plugin.json | 1 + 11 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 plugins/hifiSixense/CMakeLists.txt rename {libraries/input-plugins/src/input-plugins => plugins/hifiSixense/src}/SixenseManager.cpp (99%) rename {libraries/input-plugins/src/input-plugins => plugins/hifiSixense/src}/SixenseManager.h (99%) create mode 100644 plugins/hifiSixense/src/SixenseProvider.cpp rename {libraries/input-plugins/src/input-plugins => plugins/hifiSixense/src}/SixenseSupportOSX.cpp (99%) create mode 100644 plugins/hifiSixense/src/plugin.json diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index 11053154b6..3bcf8bb311 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -20,9 +20,6 @@ #include "Application.h" #include "devices/MotionTracker.h" -// TODO: this needs to be removed, as well as any related controller-specific information -#include - void ControllerScriptingInterface::handleMetaEvent(HFMetaEvent* event) { if (event->type() == HFActionEvent::startType()) { emit actionStartEvent(static_cast(*event)); diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index 4cee190a47..f4dbdd3bc0 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -26,7 +26,6 @@ #include "Tooltip.h" #include "Application.h" -#include // TODO: any references to sixense should be removed here #include diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index a25f868172..9a995263cd 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -16,7 +16,6 @@ #include #include #include -#include // TODO: This should be replaced with InputDevice/InputPlugin, or something similar #include #include "Application.h" diff --git a/libraries/input-plugins/CMakeLists.txt b/libraries/input-plugins/CMakeLists.txt index d2cf96c7f8..592f1fcc84 100644 --- a/libraries/input-plugins/CMakeLists.txt +++ b/libraries/input-plugins/CMakeLists.txt @@ -5,4 +5,3 @@ link_hifi_libraries(shared plugins controllers script-engine) GroupSources("src/input-plugins") target_sdl2() -target_sixense() diff --git a/libraries/input-plugins/src/input-plugins/InputPlugin.cpp b/libraries/input-plugins/src/input-plugins/InputPlugin.cpp index 4b79572a07..d226797e95 100644 --- a/libraries/input-plugins/src/input-plugins/InputPlugin.cpp +++ b/libraries/input-plugins/src/input-plugins/InputPlugin.cpp @@ -14,14 +14,12 @@ #include "KeyboardMouseDevice.h" #include "SDL2Manager.h" -#include "SixenseManager.h" // TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class InputPluginList getInputPlugins() { InputPlugin* PLUGIN_POOL[] = { new KeyboardMouseDevice(), new SDL2Manager(), - new SixenseManager(), nullptr }; diff --git a/plugins/hifiSixense/CMakeLists.txt b/plugins/hifiSixense/CMakeLists.txt new file mode 100644 index 0000000000..c790f6f14d --- /dev/null +++ b/plugins/hifiSixense/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Created by Bradley Austin Davis on 2015/11/18 +# 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 +# + +set(TARGET_NAME hifiSixense) +setup_hifi_plugin(Script Qml Widgets) +link_hifi_libraries(shared controllers plugins input-plugins) +target_sixense() diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp b/plugins/hifiSixense/src/SixenseManager.cpp similarity index 99% rename from libraries/input-plugins/src/input-plugins/SixenseManager.cpp rename to plugins/hifiSixense/src/SixenseManager.cpp index 3b08c218a2..93329d768e 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp +++ b/plugins/hifiSixense/src/SixenseManager.cpp @@ -27,9 +27,11 @@ #include #include #include -#include -#include "InputPluginsLogging.h" +#include + +Q_DECLARE_LOGGING_CATEGORY(inputplugins) +Q_LOGGING_CATEGORY(inputplugins, "hifi.inputplugins") static const unsigned int BUTTON_0 = 1U << 0; // the skinny button between 1 and 2 static const unsigned int BUTTON_1 = 1U << 5; diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.h b/plugins/hifiSixense/src/SixenseManager.h similarity index 99% rename from libraries/input-plugins/src/input-plugins/SixenseManager.h rename to plugins/hifiSixense/src/SixenseManager.h index b6bf4b24c0..5cd4dc2451 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.h +++ b/plugins/hifiSixense/src/SixenseManager.h @@ -17,7 +17,7 @@ #include #include -#include "InputPlugin.h" +#include struct _sixenseControllerData; using SixenseControllerData = _sixenseControllerData; diff --git a/plugins/hifiSixense/src/SixenseProvider.cpp b/plugins/hifiSixense/src/SixenseProvider.cpp new file mode 100644 index 0000000000..2958e47848 --- /dev/null +++ b/plugins/hifiSixense/src/SixenseProvider.cpp @@ -0,0 +1,45 @@ +// +// Created by Bradley Austin Davis on 2015/10/25 +// 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 + +#include +#include +#include + +#include +#include + +#include "SixenseManager.h" + +class SixenseProvider : public QObject, public InputProvider +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID InputProvider_iid FILE "plugin.json") + Q_INTERFACES(InputProvider) + +public: + SixenseProvider(QObject* parent = nullptr) : QObject(parent) {} + virtual ~SixenseProvider() {} + + virtual InputPluginList getInputPlugins() override { + static std::once_flag once; + std::call_once(once, [&] { + InputPluginPointer plugin(new SixenseManager()); + if (plugin->isSupported()) { + _inputPlugins.push_back(plugin); + } + }); + return _inputPlugins; + } + +private: + InputPluginList _inputPlugins; +}; + +#include "SixenseProvider.moc" diff --git a/libraries/input-plugins/src/input-plugins/SixenseSupportOSX.cpp b/plugins/hifiSixense/src/SixenseSupportOSX.cpp similarity index 99% rename from libraries/input-plugins/src/input-plugins/SixenseSupportOSX.cpp rename to plugins/hifiSixense/src/SixenseSupportOSX.cpp index f6cec5d67f..85e0f3fe48 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseSupportOSX.cpp +++ b/plugins/hifiSixense/src/SixenseSupportOSX.cpp @@ -17,8 +17,7 @@ #include #include - -#include "InputPluginsLogging.h" +#include #ifndef SIXENSE_LIB_FILENAME #define SIXENSE_LIB_FILENAME QCoreApplication::applicationDirPath() + "/../Frameworks/libsixense_x64" diff --git a/plugins/hifiSixense/src/plugin.json b/plugins/hifiSixense/src/plugin.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/plugins/hifiSixense/src/plugin.json @@ -0,0 +1 @@ +{} From 6f29d9e7b8ac889fbd47aaba9aa4225a75366a12 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 8 Dec 2015 17:30:26 -0800 Subject: [PATCH 76/78] Use strongly typed enum instead of nested alias --- libraries/avatars/src/AvatarData.cpp | 2 +- libraries/entities/src/EntityItem.cpp | 6 +++--- libraries/entities/src/EntityTree.cpp | 4 ++-- libraries/shared/src/SpatiallyNestable.cpp | 2 +- libraries/shared/src/SpatiallyNestable.h | 17 +++++++---------- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 3f2cd92dbc..d241df7e0e 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -47,7 +47,7 @@ const QString AvatarData::FRAME_NAME = "com.highfidelity.recording.AvatarData"; static std::once_flag frameTypeRegistration; AvatarData::AvatarData() : - SpatiallyNestable(NestableTypes::Avatar, QUuid()), + SpatiallyNestable(NestableType::Avatar, QUuid()), _handPosition(0.0f), _targetScale(1.0f), _handState(0), diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index d089427abb..f74cdedb9d 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -36,7 +36,7 @@ int EntityItem::_maxActionsDataSize = 800; quint64 EntityItem::_rememberDeletedActionTime = 20 * USECS_PER_SECOND; EntityItem::EntityItem(const EntityItemID& entityItemID) : - SpatiallyNestable(NestableTypes::Entity, entityItemID), + SpatiallyNestable(NestableType::Entity, entityItemID), _type(EntityTypes::Unknown), _lastSimulated(0), _lastUpdated(0), @@ -1294,7 +1294,7 @@ void EntityItem::updatePosition(const glm::vec3& value) { setLocalPosition(value); _dirtyFlags |= Simulation::DIRTY_POSITION; forEachDescendant([&](SpatiallyNestablePointer object) { - if (object->getNestableType() == NestableTypes::Entity) { + if (object->getNestableType() == NestableType::Entity) { EntityItemPointer entity = std::static_pointer_cast(object); entity->_dirtyFlags |= Simulation::DIRTY_POSITION; } @@ -1317,7 +1317,7 @@ void EntityItem::updateRotation(const glm::quat& rotation) { setLocalOrientation(rotation); _dirtyFlags |= Simulation::DIRTY_ROTATION; forEachDescendant([&](SpatiallyNestablePointer object) { - if (object->getNestableType() == NestableTypes::Entity) { + if (object->getNestableType() == NestableType::Entity) { EntityItemPointer entity = std::static_pointer_cast(object); entity->_dirtyFlags |= Simulation::DIRTY_ROTATION; entity->_dirtyFlags |= Simulation::DIRTY_POSITION; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index abad1e5cd1..8d0962f662 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -219,7 +219,7 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI // if the entity has children, run UpdateEntityOperator on them. If the children have children, recurse QQueue toProcess; foreach (SpatiallyNestablePointer child, entity->getChildren()) { - if (child && child->getNestableType() == NestableTypes::Entity) { + if (child && child->getNestableType() == NestableType::Entity) { toProcess.enqueue(child); } } @@ -232,7 +232,7 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI childEntity, newChildBBRelProperties); recurseTreeWithOperator(&theChildOperator); foreach (SpatiallyNestablePointer childChild, childEntity->getChildren()) { - if (childChild && childChild->getNestableType() == NestableTypes::Entity) { + if (childChild && childChild->getNestableType() == NestableType::Entity) { toProcess.enqueue(childChild); } } diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index bde788f6ff..98d127cc1e 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -15,7 +15,7 @@ #include "SpatiallyNestable.h" -SpatiallyNestable::SpatiallyNestable(NestableTypes::NestableType nestableType, QUuid id) : +SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) : _nestableType(nestableType), _id(id), _transform() { diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index e656957912..7a43e2a563 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -25,17 +25,14 @@ using SpatiallyNestableWeakConstPointer = std::weak_ptr using SpatiallyNestablePointer = std::shared_ptr; using SpatiallyNestableConstPointer = std::shared_ptr; -class NestableTypes { -public: - using NestableType = enum NestableType_t { - Entity, - Avatar - }; +enum class NestableType { + Entity, + Avatar }; class SpatiallyNestable : public std::enable_shared_from_this { public: - SpatiallyNestable(NestableTypes::NestableType nestableType, QUuid id); + SpatiallyNestable(NestableType nestableType, QUuid id); virtual ~SpatiallyNestable() { } virtual const QUuid& getID() const { return _id; } @@ -88,17 +85,17 @@ public: virtual void setLocalScale(const glm::vec3& scale); QList getChildren() const; - NestableTypes::NestableType getNestableType() const { return _nestableType; } + NestableType getNestableType() const { return _nestableType; } // this object's frame virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const; virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const { assert(false); return glm::quat(); } virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const { assert(false); return glm::vec3(); } - + SpatiallyNestablePointer getThisPointer() const; protected: - NestableTypes::NestableType _nestableType; // EntityItem or an AvatarData + const NestableType _nestableType; // EntityItem or an AvatarData QUuid _id; QUuid _parentID; // what is this thing's transform relative to? quint16 _parentJointIndex { 0 }; // which joint of the parent is this relative to? From 739e184b526f9a16a25ea07d243701e8bc4f3399 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 10 Dec 2015 11:19:11 -0800 Subject: [PATCH 77/78] Fix attachments jitter --- interface/src/Application.cpp | 1 + interface/src/avatar/Avatar.cpp | 1 - interface/src/avatar/Avatar.h | 4 +--- interface/src/avatar/MyAvatar.cpp | 5 ----- 4 files changed, 2 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1a03cad62a..b3385a3744 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2963,6 +2963,7 @@ void Application::update(float deltaTime) { } myAvatar->harvestResultsFromPhysicsSimulation(); + myAvatar->simulateAttachments(deltaTime); } } diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index e2b92cc06f..218d679898 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -200,7 +200,6 @@ void Avatar::simulate(float deltaTime) { PerformanceTimer perfTimer("skeleton"); _skeletonModel.getRig()->copyJointsFromJointData(_jointData); _skeletonModel.simulate(deltaTime, _hasNewJointRotations || _hasNewJointTranslations); - simulateAttachments(deltaTime); locationChanged(); // joints changed, so if there are any children, update them. _hasNewJointRotations = false; _hasNewJointTranslations = false; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 99a4fc52a9..09685c318e 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -69,6 +69,7 @@ public: void init(); void simulate(float deltaTime); + void simulateAttachments(float deltaTime); virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition); @@ -87,7 +88,6 @@ public: bool isInitialized() const { return _initialized; } SkeletonModel& getSkeletonModel() { return _skeletonModel; } const SkeletonModel& getSkeletonModel() const { return _skeletonModel; } - const QVector& getAttachmentModels() const { return _attachmentModels; } glm::vec3 getChestPosition() const; float getAvatarScale() const { return getScale().y; } const Head* getHead() const { return static_cast(_headData); } @@ -217,8 +217,6 @@ protected: virtual bool shouldRenderHead(const RenderArgs* renderArgs) const; virtual void fixupModelsInScene(); - void simulateAttachments(float deltaTime); - virtual void updateJointMappings(); render::ItemID _renderItemID; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6637331b64..29f81ae47e 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -323,11 +323,6 @@ void MyAvatar::simulate(float deltaTime) { return; } - { - PerformanceTimer perfTimer("attachments"); - simulateAttachments(deltaTime); - } - { PerformanceTimer perfTimer("joints"); // copy out the skeleton joints from the model From c5f5e8de60d84f5f8930ac5fc032b88d1e8b8de8 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Thu, 10 Dec 2015 11:43:18 -0800 Subject: [PATCH 78/78] Trying to fix build problem --- interface/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 0baf709082..87cf1a384c 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -100,6 +100,15 @@ else() add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM}) endif() +# These are external plugins, but we need to do the 'add dependency' here so that their +# binary directories get added to the fixup path +add_dependency_external_projects(sixense) +add_dependency_external_projects(sdl2) +if (WIN32) + add_dependency_external_projects(OpenVR) +endif() + + # disable /OPT:REF and /OPT:ICF for the Debug builds # This will prevent the following linker warnings # LINK : warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:ICF' specification