From 061f182fab4a8f72e046021cec93a3a41ac22f82 Mon Sep 17 00:00:00 2001 From: Mika Impola Date: Wed, 21 May 2014 00:02:59 +0300 Subject: [PATCH 01/49] Initialise lisencing manager after we have enabled Visage. --- interface/src/devices/Visage.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/interface/src/devices/Visage.cpp b/interface/src/devices/Visage.cpp index 119d89654a..70cdaf2b01 100644 --- a/interface/src/devices/Visage.cpp +++ b/interface/src/devices/Visage.cpp @@ -41,14 +41,8 @@ Visage::Visage() : _headOrigin(DEFAULT_HEAD_ORIGIN) { #ifdef HAVE_VISAGE -#ifdef WIN32 - QByteArray licensePath = Application::resourcesPath().toLatin1() + "visage"; -#else - QByteArray licensePath = Application::resourcesPath().toLatin1() + "visage/license.vlc"; -#endif - initializeLicenseManager(licensePath.data()); - _tracker = new VisageTracker2(Application::resourcesPath().toLatin1() + "visage/tracker.cfg"); - _data = new FaceData(); + _tracker = NULL; + _data = NULL; #endif } @@ -179,6 +173,19 @@ void Visage::setEnabled(bool enabled) { return; } if ((_enabled = enabled)) { + if(_tracker == NULL && _data == NULL){ + + #ifdef WIN32 + QByteArray licensePath = Application::resourcesPath().toLatin1() + "visage"; + #else + QByteArray licensePath = Application::resourcesPath().toLatin1() + "visage/license.vlc"; + #endif + + initializeLicenseManager(licensePath.data()); + _tracker = new VisageTracker2(Application::resourcesPath().toLatin1() + "visage/tracker.cfg"); + _data = new FaceData(); + } + _tracker->trackFromCam(); } else { _tracker->stop(); From 9dde480bb2936b4087fda8cd54dca971803d7b0d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 20 May 2014 10:35:04 -0700 Subject: [PATCH 02/49] don't look for GnuTLS from cmake --- animation-server/CMakeLists.txt | 15 +--------- assignment-client/CMakeLists.txt | 11 +------ cmake/modules/FindGnuTLS.cmake | 41 -------------------------- domain-server/CMakeLists.txt | 13 ++------ interface/CMakeLists.txt | 9 +----- libraries/animation/CMakeLists.txt | 9 +----- libraries/audio/CMakeLists.txt | 13 +------- libraries/avatars/CMakeLists.txt | 11 +------ libraries/fbx/CMakeLists.txt | 13 ++------ libraries/metavoxels/CMakeLists.txt | 10 +------ libraries/models/CMakeLists.txt | 12 ++------ libraries/networking/CMakeLists.txt | 9 +----- libraries/octree/CMakeLists.txt | 13 ++------ libraries/particles/CMakeLists.txt | 12 ++------ libraries/script-engine/CMakeLists.txt | 10 ++----- libraries/voxels/CMakeLists.txt | 13 ++------ voxel-edit/CMakeLists.txt | 10 +------ 17 files changed, 28 insertions(+), 196 deletions(-) delete mode 100644 cmake/modules/FindGnuTLS.cmake diff --git a/animation-server/CMakeLists.txt b/animation-server/CMakeLists.txt index 5d9f3604bc..d8fa8d97b2 100644 --- a/animation-server/CMakeLists.txt +++ b/animation-server/CMakeLists.txt @@ -30,17 +30,4 @@ link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") # link the hifi networking library -link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") - -find_package(GnuTLS REQUIRED) - -# include the GnuTLS dir -include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") - -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - -# link GnuTLS -target_link_libraries(${TARGET_NAME} "${GNUTLS_LIBRARY}") \ No newline at end of file +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") \ No newline at end of file diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index 6436ffbd75..a088c04ffb 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -37,15 +37,6 @@ link_hifi_library(animation ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(script-engine ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") -find_package(GnuTLS REQUIRED) - -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - -include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") - if (UNIX) target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS}) endif (UNIX) @@ -54,4 +45,4 @@ IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) -target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script "${GNUTLS_LIBRARY}") +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) diff --git a/cmake/modules/FindGnuTLS.cmake b/cmake/modules/FindGnuTLS.cmake deleted file mode 100644 index 0e1899864b..0000000000 --- a/cmake/modules/FindGnuTLS.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# -# FindGnuTLS.cmake -# -# Try to find the GnuTLS library -# -# You can provide a GNUTLS_ROOT_DIR which contains lib and include directories -# -# Once done this will define -# -# GNUTLS_FOUND - system found GnuTLS -# GNUTLS_INCLUDE_DIR - the GnuTLS include directory -# GNUTLS_LIBRARY - Link this to use GnuTLS -# -# Created on 3/31/2014 by Stephen Birarda -# Copyright (c) 2014 High Fidelity -# -# Distributed under the Apache License, Version 2.0. -# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -# - -if (GNUTLS_LIBRARY AND GNUTLS_INCLUDE_DIRS) - # in cache already - set(GNUTLS_FOUND TRUE) -else () - set(GNUTLS_SEARCH_DIRS "${GNUTLS_ROOT_DIR}" "$ENV{HIFI_LIB_DIR}/gnutls") - - find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h PATH_SUFFIXES include HINTS ${GNUTLS_SEARCH_DIRS}) - - find_library(GNUTLS_LIBRARY NAMES gnutls libgnutls libgnutls-28 PATH_SUFFIXES lib HINTS ${GNUTLS_SEARCH_DIRS}) - - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(GNUTLS DEFAULT_MSG GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY) - - if (WIN32 AND NOT GNUTLS_FOUND) - message(STATUS "If you're generating a MSVC environment, you'll need to run the command") - message(STATUS "$GnuTLS-DIR\\bin>lib /def:libgnutls-28.def") - message(STATUS "From the MSVC command prompt to generate the .lib file and copy it into") - message(STATUS "the GnuTLS lib folder. Replace $GnuTLS-DIR in the command with the directory") - message(STATUS "containing GnuTLS.") - endif () -endif () diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index 4736c2438b..d1f923f4d2 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -17,7 +17,6 @@ include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") find_package(Qt5Network REQUIRED) -find_package(GnuTLS REQUIRED) include(${MACRO_DIR}/SetupHifiProject.cmake) @@ -38,17 +37,9 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") -# include the GnuTLS dir -include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") - -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) -# link QtNetwork and GnuTLS -target_link_libraries(${TARGET_NAME} Qt5::Network "${GNUTLS_LIBRARY}") \ No newline at end of file +# link QtNetwork +target_link_libraries(${TARGET_NAME} Qt5::Network) \ No newline at end of file diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index b95c0e7b38..67b993d6c9 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -69,7 +69,6 @@ foreach(EXTERNAL_SOURCE_SUBDIR ${EXTERNAL_SOURCE_SUBDIRS}) endforeach(EXTERNAL_SOURCE_SUBDIR) find_package(Qt5 COMPONENTS Core Gui Multimedia Network OpenGL Script Svg WebKit WebKitWidgets Xml UiTools) -find_package(GnuTLS REQUIRED) # grab the ui files in resources/ui file (GLOB_RECURSE QT_UI_FILES ui/*.ui) @@ -212,14 +211,9 @@ endif (QXMPP_FOUND AND NOT DISABLE_QXMPP) # include headers for interface and InterfaceConfig. include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes") -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - # include external library headers # use system flag so warnings are supressed -include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") +include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}") target_link_libraries( ${TARGET_NAME} @@ -227,7 +221,6 @@ target_link_libraries( "${ZLIB_LIBRARIES}" Qt5::Core Qt5::Gui Qt5::Multimedia Qt5::Network Qt5::OpenGL Qt5::Script Qt5::Svg Qt5::WebKit Qt5::WebKitWidgets Qt5::Xml Qt5::UiTools - "${GNUTLS_LIBRARY}" ) # assume we are using a Qt build without bearer management diff --git a/libraries/animation/CMakeLists.txt b/libraries/animation/CMakeLists.txt index 36088ba4bd..35ceb22395 100644 --- a/libraries/animation/CMakeLists.txt +++ b/libraries/animation/CMakeLists.txt @@ -26,12 +26,5 @@ link_hifi_library(fbx ${TARGET_NAME} "${ROOT_DIR}") # link ZLIB find_package(ZLIB) -find_package(GnuTLS REQUIRED) -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" "${GNUTLS_LIBRARY}" Qt5::Widgets) +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) diff --git a/libraries/audio/CMakeLists.txt b/libraries/audio/CMakeLists.txt index d946ae5b34..0bf0ba9904 100644 --- a/libraries/audio/CMakeLists.txt +++ b/libraries/audio/CMakeLists.txt @@ -21,15 +21,4 @@ include_glm(${TARGET_NAME} "${ROOT_DIR}") include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") -link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") - -# link GnuTLS -find_package(GnuTLS REQUIRED) - -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - -include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") -target_link_libraries(${TARGET_NAME} "${GNUTLS_LIBRARY}") \ No newline at end of file +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") \ No newline at end of file diff --git a/libraries/avatars/CMakeLists.txt b/libraries/avatars/CMakeLists.txt index 3fa1ebcfe2..9816282dda 100644 --- a/libraries/avatars/CMakeLists.txt +++ b/libraries/avatars/CMakeLists.txt @@ -28,13 +28,4 @@ link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") -find_package(GnuTLS REQUIRED) - -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - - -include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") -target_link_libraries(${TARGET_NAME} Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Script) \ No newline at end of file diff --git a/libraries/fbx/CMakeLists.txt b/libraries/fbx/CMakeLists.txt index 10dd3f49f5..9ce234bbd4 100644 --- a/libraries/fbx/CMakeLists.txt +++ b/libraries/fbx/CMakeLists.txt @@ -24,15 +24,8 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") -# link ZLIB and GnuTLS +# link ZLIB find_package(ZLIB) -find_package(GnuTLS REQUIRED) -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - - -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets "${GNUTLS_LIBRARY}") +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) diff --git a/libraries/metavoxels/CMakeLists.txt b/libraries/metavoxels/CMakeLists.txt index e2a90cb085..7a8319815a 100644 --- a/libraries/metavoxels/CMakeLists.txt +++ b/libraries/metavoxels/CMakeLists.txt @@ -27,12 +27,4 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") -find_package(GnuTLS REQUIRED) - -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - -include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") -target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) \ No newline at end of file diff --git a/libraries/models/CMakeLists.txt b/libraries/models/CMakeLists.txt index 1e70942872..7833349319 100644 --- a/libraries/models/CMakeLists.txt +++ b/libraries/models/CMakeLists.txt @@ -33,14 +33,8 @@ link_hifi_library(animation ${TARGET_NAME} "${ROOT_DIR}") # for streamable link_hifi_library(metavoxels ${TARGET_NAME} "${ROOT_DIR}") -# link ZLIB and GnuTLS +# link ZLIB find_package(ZLIB) -find_package(GnuTLS REQUIRED) -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets "${GNUTLS_LIBRARY}") +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) \ No newline at end of file diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index 6d805cae6c..f93ba2e5cf 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -11,7 +11,6 @@ set(TARGET_NAME networking) project(${TARGET_NAME}) find_package(Qt5 COMPONENTS Network) -find_package(GnuTLS REQUIRED) include(${MACRO_DIR}/SetupHifiLibrary.cmake) setup_hifi_library(${TARGET_NAME}) @@ -20,10 +19,4 @@ setup_hifi_library(${TARGET_NAME}) include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - -include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") -target_link_libraries(${TARGET_NAME} Qt5::Network "${GNUTLS_LIBRARY}") \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Network) \ No newline at end of file diff --git a/libraries/octree/CMakeLists.txt b/libraries/octree/CMakeLists.txt index 88554ed5f8..985b3fdba7 100644 --- a/libraries/octree/CMakeLists.txt +++ b/libraries/octree/CMakeLists.txt @@ -24,15 +24,8 @@ include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") -# link ZLIB and GnuTLS +# link ZLIB find_package(ZLIB) -find_package(GnuTLS REQUIRED) -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - - -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets "${GNUTLS_LIBRARY}") \ No newline at end of file +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) \ No newline at end of file diff --git a/libraries/particles/CMakeLists.txt b/libraries/particles/CMakeLists.txt index 8cd2f30012..7f42854b93 100644 --- a/libraries/particles/CMakeLists.txt +++ b/libraries/particles/CMakeLists.txt @@ -27,14 +27,8 @@ link_hifi_library(fbx ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(animation ${TARGET_NAME} "${ROOT_DIR}") -# link ZLIB and GnuTLS +# link ZLIB find_package(ZLIB) -find_package(GnuTLS REQUIRED) -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets "${GNUTLS_LIBRARY}") +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) diff --git a/libraries/script-engine/CMakeLists.txt b/libraries/script-engine/CMakeLists.txt index 0374ad570c..ac56f335e1 100644 --- a/libraries/script-engine/CMakeLists.txt +++ b/libraries/script-engine/CMakeLists.txt @@ -31,12 +31,6 @@ link_hifi_library(animation ${TARGET_NAME} "${ROOT_DIR}") # link ZLIB find_package(ZLIB) -find_package(GnuTLS REQUIRED) -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" "${GNUTLS_LIBRARY}" Qt5::Widgets) +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) diff --git a/libraries/voxels/CMakeLists.txt b/libraries/voxels/CMakeLists.txt index bdba388594..dd1020b4d7 100644 --- a/libraries/voxels/CMakeLists.txt +++ b/libraries/voxels/CMakeLists.txt @@ -26,15 +26,8 @@ link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") -# link ZLIB and GnuTLS +# link ZLIB find_package(ZLIB) -find_package(GnuTLS REQUIRED) -# add a definition for ssize_t so that windows doesn't bail on gnutls.h -if (WIN32) - add_definitions(-Dssize_t=long) -endif () - - -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" "${GNUTLS_LIBRARY}" Qt5::Widgets Qt5::Script) \ No newline at end of file +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets Qt5::Script) \ No newline at end of file diff --git a/voxel-edit/CMakeLists.txt b/voxel-edit/CMakeLists.txt index cc0a122bf0..ce3c542691 100644 --- a/voxel-edit/CMakeLists.txt +++ b/voxel-edit/CMakeLists.txt @@ -34,16 +34,8 @@ link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") # link in the hifi networking library link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") -# link GnuTLS -find_package(GnuTLS REQUIRED) - IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) - - # add a definition for ssize_t so that windows doesn't bail on gnutls.h - add_definitions(-Dssize_t=long) ENDIF(WIN32) -include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") - -target_link_libraries(${TARGET_NAME} Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Script) \ No newline at end of file From f1581ef8239a61ea008ca0f10fbb6c99b963fcca Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 20 May 2014 10:47:11 -0700 Subject: [PATCH 03/49] remove dependency on GnuTLS for later replacement with OpenSSL --- assignment-client/src/AssignmentClient.cpp | 6 - assignment-client/src/AssignmentClient.h | 1 - domain-server/src/DTLSServerSession.cpp | 18 -- domain-server/src/DTLSServerSession.h | 24 --- domain-server/src/DomainServer.cpp | 195 ++---------------- domain-server/src/DomainServer.h | 11 - interface/src/Application.cpp | 7 +- interface/src/ui/OAuthWebViewHandler.cpp | 27 ++- .../networking/src/DTLSClientSession.cpp | 83 -------- libraries/networking/src/DTLSClientSession.h | 30 --- libraries/networking/src/DTLSSession.cpp | 145 ------------- libraries/networking/src/DTLSSession.h | 44 ---- libraries/networking/src/DomainHandler.cpp | 57 +---- libraries/networking/src/DomainHandler.h | 9 - libraries/networking/src/DummyDTLSSession.cpp | 31 --- libraries/networking/src/DummyDTLSSession.h | 34 --- libraries/networking/src/NodeList.cpp | 41 +--- libraries/networking/src/NodeList.h | 2 - 18 files changed, 47 insertions(+), 718 deletions(-) delete mode 100644 domain-server/src/DTLSServerSession.cpp delete mode 100644 domain-server/src/DTLSServerSession.h delete mode 100644 libraries/networking/src/DTLSClientSession.cpp delete mode 100644 libraries/networking/src/DTLSClientSession.h delete mode 100644 libraries/networking/src/DTLSSession.cpp delete mode 100644 libraries/networking/src/DTLSSession.h delete mode 100644 libraries/networking/src/DummyDTLSSession.cpp delete mode 100644 libraries/networking/src/DummyDTLSSession.h diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index ff876596b0..d8383ccd48 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -39,8 +39,6 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : QCoreApplication(argc, argv), _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME) { - DTLSClientSession::globalInit(); - setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); setApplicationName("assignment-client"); @@ -106,10 +104,6 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : this, &AssignmentClient::handleAuthenticationRequest); } -AssignmentClient::~AssignmentClient() { - DTLSClientSession::globalDeinit(); -} - void AssignmentClient::sendAssignmentRequest() { if (!_currentAssignment) { NodeList::getInstance()->sendAssignment(_requestAssignment); diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 2df9f4ca40..9834402dbf 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -21,7 +21,6 @@ class AssignmentClient : public QCoreApplication { public: AssignmentClient(int &argc, char **argv); static const SharedAssignmentPointer& getCurrentAssignment() { return _currentAssignment; } - ~AssignmentClient(); private slots: void sendAssignmentRequest(); void readPendingDatagrams(); diff --git a/domain-server/src/DTLSServerSession.cpp b/domain-server/src/DTLSServerSession.cpp deleted file mode 100644 index a80c54ee02..0000000000 --- a/domain-server/src/DTLSServerSession.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// -// DTLSServerSession.cpp -// domain-server/src -// -// Created by Stephen Birarda on 2014-04-01. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "DTLSServerSession.h" - -DTLSServerSession::DTLSServerSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : - DTLSSession(GNUTLS_SERVER, dtlsSocket, destinationSocket) -{ - -} \ No newline at end of file diff --git a/domain-server/src/DTLSServerSession.h b/domain-server/src/DTLSServerSession.h deleted file mode 100644 index 5fdc602df7..0000000000 --- a/domain-server/src/DTLSServerSession.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// DTLSServerSession.h -// domain-server/src -// -// Created by Stephen Birarda on 2014-04-01. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_DTLSServerSession_h -#define hifi_DTLSServerSession_h - -#include - -#include - -class DTLSServerSession : public DTLSSession { -public: - DTLSServerSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); -}; - -#endif // hifi_DTLSServerSession_h diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index d9927f3833..fa8a26b259 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -28,7 +28,6 @@ #include #include "DomainServerNodeData.h" -#include "DummyDTLSSession.h" #include "DomainServer.h" @@ -39,18 +38,12 @@ DomainServer::DomainServer(int argc, char* argv[]) : _allAssignments(), _unfulfilledAssignments(), _isUsingDTLS(false), - _x509Credentials(NULL), - _dhParams(NULL), - _priorityCache(NULL), - _dtlsSessions(), _oauthProviderURL(), _oauthClientID(), _hostname(), _networkReplyUUIDMap(), _sessionAuthenticationHash() { - gnutls_global_init(); - setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); setApplicationName("domain-server"); @@ -64,31 +57,10 @@ DomainServer::DomainServer(int argc, char* argv[]) : qDebug() << "Setting up LimitedNodeList and assignments."; setupNodeListAndAssignments(); - if (_isUsingDTLS) { - LimitedNodeList* nodeList = LimitedNodeList::getInstance(); - - // connect our socket to read datagrams received on the DTLS socket - connect(&nodeList->getDTLSSocket(), &QUdpSocket::readyRead, this, &DomainServer::readAvailableDTLSDatagrams); - } - _networkAccessManager = new QNetworkAccessManager(this); } } -DomainServer::~DomainServer() { - if (_x509Credentials) { - gnutls_certificate_free_credentials(*_x509Credentials); - gnutls_priority_deinit(*_priorityCache); - gnutls_dh_params_deinit(*_dhParams); - - delete _x509Credentials; - delete _priorityCache; - delete _dhParams; - delete _cookieKey; - } - gnutls_global_deinit(); -} - bool DomainServer::optionallyReadX509KeyAndCertificate() { const QString X509_CERTIFICATE_OPTION = "cert"; const QString X509_PRIVATE_KEY_OPTION = "key"; @@ -100,28 +72,28 @@ bool DomainServer::optionallyReadX509KeyAndCertificate() { if (!certPath.isEmpty() && !keyPath.isEmpty()) { // the user wants to use DTLS to encrypt communication with nodes // let's make sure we can load the key and certificate - _x509Credentials = new gnutls_certificate_credentials_t; - gnutls_certificate_allocate_credentials(_x509Credentials); +// _x509Credentials = new gnutls_certificate_credentials_t; +// gnutls_certificate_allocate_credentials(_x509Credentials); QString keyPassphraseString = QProcessEnvironment::systemEnvironment().value(X509_KEY_PASSPHRASE_ENV); qDebug() << "Reading certificate file at" << certPath << "for DTLS."; qDebug() << "Reading key file at" << keyPath << "for DTLS."; - int gnutlsReturn = gnutls_certificate_set_x509_key_file2(*_x509Credentials, - certPath.toLocal8Bit().constData(), - keyPath.toLocal8Bit().constData(), - GNUTLS_X509_FMT_PEM, - keyPassphraseString.toLocal8Bit().constData(), - 0); +// int gnutlsReturn = gnutls_certificate_set_x509_key_file2(*_x509Credentials, +// certPath.toLocal8Bit().constData(), +// keyPath.toLocal8Bit().constData(), +// GNUTLS_X509_FMT_PEM, +// keyPassphraseString.toLocal8Bit().constData(), +// 0); +// +// if (gnutlsReturn < 0) { +// qDebug() << "Unable to load certificate or key file." << "Error" << gnutlsReturn << "- domain-server will now quit."; +// QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); +// return false; +// } - if (gnutlsReturn < 0) { - qDebug() << "Unable to load certificate or key file." << "Error" << gnutlsReturn << "- domain-server will now quit."; - QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); - return false; - } - - qDebug() << "Successfully read certificate and private key."; +// qDebug() << "Successfully read certificate and private key."; // we need to also pass this certificate and private key to the HTTPS manager // this is used for Oauth callbacks when authorizing users against a data server @@ -176,39 +148,6 @@ bool DomainServer::optionallySetupOAuth() { return true; } -bool DomainServer::optionallySetupDTLS() { - if (_x509Credentials) { - qDebug() << "Generating Diffie-Hellman parameters."; - - // generate Diffie-Hellman parameters - // When short bit length is used, it might be wise to regenerate parameters often. - int dhBits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); - - _dhParams = new gnutls_dh_params_t; - gnutls_dh_params_init(_dhParams); - gnutls_dh_params_generate2(*_dhParams, dhBits); - - qDebug() << "Successfully generated Diffie-Hellman parameters."; - - // set the D-H paramters on the X509 credentials - gnutls_certificate_set_dh_params(*_x509Credentials, *_dhParams); - - // setup the key used for cookie verification - _cookieKey = new gnutls_datum_t; - gnutls_key_generate(_cookieKey, GNUTLS_COOKIE_KEY_SIZE); - - _priorityCache = new gnutls_priority_t; - const char DTLS_PRIORITY_STRING[] = "PERFORMANCE:-VERS-TLS-ALL:+VERS-DTLS1.2:%SERVER_PRECEDENCE"; - gnutls_priority_init(_priorityCache, DTLS_PRIORITY_STRING, NULL); - - _isUsingDTLS = true; - - qDebug() << "Initial DTLS setup complete."; - } - - return true; -} - void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { const QString CUSTOM_PORT_OPTION = "port"; @@ -552,8 +491,8 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif if (nodeInterestList.size() > 0) { - DTLSServerSession* dtlsSession = _isUsingDTLS ? _dtlsSessions[senderSockAddr] : NULL; - int dataMTU = dtlsSession ? (int)gnutls_dtls_get_data_mtu(*dtlsSession->getGnuTLSSession()) : MAX_PACKET_SIZE; +// DTLSServerSession* dtlsSession = _isUsingDTLS ? _dtlsSessions[senderSockAddr] : NULL; + int dataMTU = MAX_PACKET_SIZE; if (nodeData->isAuthenticated()) { // if this authenticated node has any interest types, send back those nodes as well @@ -589,11 +528,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif // we need to break here and start a new packet // so send the current one - if (!dtlsSession) { - nodeList->writeDatagram(broadcastPacket, node, senderSockAddr); - } else { - dtlsSession->writeDatagram(broadcastPacket); - } + nodeList->writeDatagram(broadcastPacket, node, senderSockAddr); // reset the broadcastPacket structure broadcastPacket.resize(numBroadcastPacketLeadBytes); @@ -607,11 +542,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif } // always write the last broadcastPacket - if (!dtlsSession) { - nodeList->writeDatagram(broadcastPacket, node, senderSockAddr); - } else { - dtlsSession->writeDatagram(broadcastPacket); - } + nodeList->writeDatagram(broadcastPacket, node, senderSockAddr); } } @@ -689,86 +620,6 @@ void DomainServer::readAvailableDatagrams() { } } -void DomainServer::readAvailableDTLSDatagrams() { - LimitedNodeList* nodeList = LimitedNodeList::getInstance(); - - QUdpSocket& dtlsSocket = nodeList->getDTLSSocket(); - - static sockaddr senderSockAddr; - static socklen_t sockAddrSize = sizeof(senderSockAddr); - - while (dtlsSocket.hasPendingDatagrams()) { - // check if we have an active DTLS session for this sender - QByteArray peekDatagram(dtlsSocket.pendingDatagramSize(), 0); - - recvfrom(dtlsSocket.socketDescriptor(), peekDatagram.data(), dtlsSocket.pendingDatagramSize(), - MSG_PEEK, &senderSockAddr, &sockAddrSize); - - HifiSockAddr senderHifiSockAddr(&senderSockAddr); - DTLSServerSession* existingSession = _dtlsSessions.value(senderHifiSockAddr); - - if (existingSession) { - if (!existingSession->completedHandshake()) { - // check if we have completed handshake with this user - int handshakeReturn = gnutls_handshake(*existingSession->getGnuTLSSession()); - - if (handshakeReturn == 0) { - existingSession->setCompletedHandshake(true); - } else if (gnutls_error_is_fatal(handshakeReturn)) { - // this was a fatal error handshaking, so remove this session - qDebug() << "Fatal error -" << gnutls_strerror(handshakeReturn) << "- during DTLS handshake with" - << senderHifiSockAddr; - _dtlsSessions.remove(senderHifiSockAddr); - } - } else { - // pull the data from this user off the stack and process it - int receivedBytes = gnutls_record_recv(*existingSession->getGnuTLSSession(), - peekDatagram.data(), peekDatagram.size()); - if (receivedBytes > 0) { - processDatagram(peekDatagram.left(receivedBytes), senderHifiSockAddr); - } else if (gnutls_error_is_fatal(receivedBytes)) { - qDebug() << "Fatal error -" << gnutls_strerror(receivedBytes) << "- during DTLS handshake with" - << senderHifiSockAddr; - } - } - } else { - // first we verify the cookie - // see http://gnutls.org/manual/html_node/DTLS-sessions.html for why this is required - gnutls_dtls_prestate_st prestate; - memset(&prestate, 0, sizeof(prestate)); - int cookieValid = gnutls_dtls_cookie_verify(_cookieKey, &senderSockAddr, sizeof(senderSockAddr), - peekDatagram.data(), peekDatagram.size(), &prestate); - - if (cookieValid < 0) { - // the cookie sent by the client was not valid - // send a valid one - DummyDTLSSession tempServerSession(LimitedNodeList::getInstance()->getDTLSSocket(), senderHifiSockAddr); - - gnutls_dtls_cookie_send(_cookieKey, &senderSockAddr, sizeof(senderSockAddr), &prestate, - &tempServerSession, DTLSSession::socketPush); - - // acutally pull the peeked data off the network stack so that it gets discarded - dtlsSocket.readDatagram(peekDatagram.data(), peekDatagram.size()); - } else { - // cookie valid but no existing session - set up a new session now - DTLSServerSession* newServerSession = new DTLSServerSession(LimitedNodeList::getInstance()->getDTLSSocket(), - senderHifiSockAddr); - gnutls_session_t* gnutlsSession = newServerSession->getGnuTLSSession(); - - gnutls_priority_set(*gnutlsSession, *_priorityCache); - gnutls_credentials_set(*gnutlsSession, GNUTLS_CRD_CERTIFICATE, *_x509Credentials); - gnutls_dtls_prestate_set(*gnutlsSession, &prestate); - - // handshake to begin the session - gnutls_handshake(*gnutlsSession); - - qDebug() << "Beginning DTLS session with node at" << senderHifiSockAddr; - _dtlsSessions[senderHifiSockAddr] = newServerSession; - } - } - } -} - void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) { LimitedNodeList* nodeList = LimitedNodeList::getInstance(); @@ -1210,14 +1061,6 @@ void DomainServer::nodeKilled(SharedNodePointer node) { reinterpret_cast(otherNode->getLinkedData())->getSessionSecretHash().remove(node->getUUID()); } } - - if (_isUsingDTLS) { - // check if we need to remove a DTLS session from our in-memory hash - DTLSServerSession* existingSession = _dtlsSessions.take(nodeData->getSendingSockAddr()); - if (existingSession) { - delete existingSession; - } - } } } diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 4c0f9447ea..32d53281f1 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -26,15 +26,12 @@ #include #include -#include "DTLSServerSession.h" - typedef QSharedPointer SharedAssignmentPointer; class DomainServer : public QCoreApplication, public HTTPSRequestHandler { Q_OBJECT public: DomainServer(int argc, char* argv[]); - ~DomainServer(); bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url); bool handleHTTPSRequest(HTTPSConnection* connection, const QUrl& url); @@ -50,11 +47,9 @@ public slots: private slots: void readAvailableDatagrams(); - void readAvailableDTLSDatagrams(); private: void setupNodeListAndAssignments(const QUuid& sessionUUID = QUuid::createUuid()); bool optionallySetupOAuth(); - bool optionallySetupDTLS(); bool optionallyReadX509KeyAndCertificate(); void processDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr); @@ -96,12 +91,6 @@ private: QVariantMap _argumentVariantMap; bool _isUsingDTLS; - gnutls_certificate_credentials_t* _x509Credentials; - gnutls_dh_params_t* _dhParams; - gnutls_datum_t* _cookieKey; - gnutls_priority_t* _priorityCache; - - QHash _dtlsSessions; QNetworkAccessManager* _networkAccessManager; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 487965b3ec..47ad9af638 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -173,10 +173,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _previousScriptLocation(), _runningScriptsWidget(new RunningScriptsWidget(_window)), _runningScriptsWidgetWasVisible(false) -{ - // init GnuTLS for DTLS with domain-servers - DTLSClientSession::globalInit(); - +{ // read the ApplicationInfo.ini file for Name/Version/Domain information QSettings applicationInfo(Application::resourcesPath() + "info/ApplicationInfo.ini", QSettings::IniFormat); @@ -431,8 +428,6 @@ Application::~Application() { delete _glWidget; AccountManager::getInstance().destroy(); - - DTLSClientSession::globalDeinit(); } void Application::saveSettings() { diff --git a/interface/src/ui/OAuthWebViewHandler.cpp b/interface/src/ui/OAuthWebViewHandler.cpp index 83d900cd5c..e93321212c 100644 --- a/interface/src/ui/OAuthWebViewHandler.cpp +++ b/interface/src/ui/OAuthWebViewHandler.cpp @@ -28,12 +28,35 @@ OAuthWebViewHandler::OAuthWebViewHandler() : } +const char HIGH_FIDELITY_CA[] = "-----BEGIN CERTIFICATE-----\n" + "MIID6TCCA1KgAwIBAgIJANlfRkRD9A8bMA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD\n" + "VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5j\n" + "aXNjbzEbMBkGA1UEChMSSGlnaCBGaWRlbGl0eSwgSW5jMRMwEQYDVQQLEwpPcGVy\n" + "YXRpb25zMRgwFgYDVQQDEw9oaWdoZmlkZWxpdHkuaW8xIjAgBgkqhkiG9w0BCQEW\n" + "E29wc0BoaWdoZmlkZWxpdHkuaW8wHhcNMTQwMzI4MjIzMzM1WhcNMjQwMzI1MjIz\n" + "MzM1WjCBqjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNV\n" + "BAcTDVNhbiBGcmFuY2lzY28xGzAZBgNVBAoTEkhpZ2ggRmlkZWxpdHksIEluYzET\n" + "MBEGA1UECxMKT3BlcmF0aW9uczEYMBYGA1UEAxMPaGlnaGZpZGVsaXR5LmlvMSIw\n" + "IAYJKoZIhvcNAQkBFhNvcHNAaGlnaGZpZGVsaXR5LmlvMIGfMA0GCSqGSIb3DQEB\n" + "AQUAA4GNADCBiQKBgQDyo1euYiPPEdnvDZnIjWrrP230qUKMSj8SWoIkbTJF2hE8\n" + "2eP3YOgbgSGBzZ8EJBxIOuNmj9g9Eg6691hIKFqy5W0BXO38P04Gg+pVBvpHFGBi\n" + "wpqGbfsjaUDuYmBeJRcMO0XYkLCRQG+lAQNHoFDdItWAJfC3FwtP3OCDnz8cNwID\n" + "AQABo4IBEzCCAQ8wHQYDVR0OBBYEFCSv2kmiGg6VFMnxXzLDNP304cPAMIHfBgNV\n" + "HSMEgdcwgdSAFCSv2kmiGg6VFMnxXzLDNP304cPAoYGwpIGtMIGqMQswCQYDVQQG\n" + "EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNj\n" + "bzEbMBkGA1UEChMSSGlnaCBGaWRlbGl0eSwgSW5jMRMwEQYDVQQLEwpPcGVyYXRp\n" + "b25zMRgwFgYDVQQDEw9oaWdoZmlkZWxpdHkuaW8xIjAgBgkqhkiG9w0BCQEWE29w\n" + "c0BoaWdoZmlkZWxpdHkuaW+CCQDZX0ZEQ/QPGzAMBgNVHRMEBTADAQH/MA0GCSqG\n" + "SIb3DQEBBQUAA4GBAEkQl3p+lH5vuoCNgyfa67nL0MsBEt+5RSBOgjwCjjASjzou\n" + "FTv5w0he2OypgMQb8i/BYtS1lJSFqjPJcSM1Salzrm3xDOK5pOXJ7h6SQLPDVEyf\n" + "Hy2/9d/to+99+SOUlvfzfgycgjOc+s/AV7Y+GBd7uzGxUdrN4egCZW1F6/mH\n" + "-----END CERTIFICATE-----\n"; + void OAuthWebViewHandler::addHighFidelityRootCAToSSLConfig() { QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration(); // add the High Fidelity root CA to the list of trusted CA certificates - QByteArray highFidelityCACertificate(reinterpret_cast(DTLSSession::highFidelityCADatum()->data), - DTLSSession::highFidelityCADatum()->size); + QByteArray highFidelityCACertificate(HIGH_FIDELITY_CA, sizeof(HIGH_FIDELITY_CA)); sslConfig.setCaCertificates(sslConfig.caCertificates() + QSslCertificate::fromData(highFidelityCACertificate)); // set the modified configuration diff --git a/libraries/networking/src/DTLSClientSession.cpp b/libraries/networking/src/DTLSClientSession.cpp deleted file mode 100644 index 72384fbd10..0000000000 --- a/libraries/networking/src/DTLSClientSession.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// -// DTLSClientSession.cpp -// libraries/networking/src -// -// Created by Stephen Birarda on 2014-04-01. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "DomainHandler.h" - -#include "DTLSClientSession.h" - -gnutls_certificate_credentials_t DTLSClientSession::_x509CACredentials; - -void DTLSClientSession::globalInit() { - static bool initialized = false; - - if (!initialized) { - gnutls_global_init(); - gnutls_certificate_allocate_credentials(&_x509CACredentials); - - gnutls_certificate_set_x509_trust_mem(_x509CACredentials, DTLSSession::highFidelityCADatum(), GNUTLS_X509_FMT_PEM); - gnutls_certificate_set_verify_function(_x509CACredentials, DTLSClientSession::verifyServerCertificate); - } -} - -void DTLSClientSession::globalDeinit() { - gnutls_certificate_free_credentials(_x509CACredentials); - - gnutls_global_deinit(); -} - -int DTLSClientSession::verifyServerCertificate(gnutls_session_t session) { - unsigned int verifyStatus = 0; - - // grab the hostname from the domain handler that this session is associated with - DomainHandler* domainHandler = reinterpret_cast(gnutls_session_get_ptr(session)); - qDebug() << "Checking for" << domainHandler->getHostname() << "from cert."; - - int certReturn = gnutls_certificate_verify_peers3(session, - domainHandler->getHostname().toLocal8Bit().constData(), - &verifyStatus); - - if (certReturn < 0) { - return GNUTLS_E_CERTIFICATE_ERROR; - } - - gnutls_certificate_type_t typeReturn = gnutls_certificate_type_get(session); - - gnutls_datum_t printOut; - - certReturn = gnutls_certificate_verification_status_print(verifyStatus, typeReturn, &printOut, 0); - - if (certReturn < 0) { - return GNUTLS_E_CERTIFICATE_ERROR; - } - - qDebug() << "Gnutls certificate verification status:" << reinterpret_cast(printOut.data); - -#ifdef WIN32 - free(printOut.data); -#else - gnutls_free(printOut.data); -#endif - - if (verifyStatus != 0) { - qDebug() << "Server provided certificate for DTLS is not trusted. Can not complete handshake."; - return GNUTLS_E_CERTIFICATE_ERROR; - } else { - // certificate is valid, continue handshaking as normal - return 0; - } -} - -DTLSClientSession::DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : - DTLSSession(GNUTLS_CLIENT, dtlsSocket, destinationSocket) -{ - gnutls_priority_set_direct(_gnutlsSession, "PERFORMANCE", NULL); - gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, _x509CACredentials); -} \ No newline at end of file diff --git a/libraries/networking/src/DTLSClientSession.h b/libraries/networking/src/DTLSClientSession.h deleted file mode 100644 index eeca1aaa68..0000000000 --- a/libraries/networking/src/DTLSClientSession.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// DTLSClientSession.h -// libraries/networking/src -// -// Created by Stephen Birarda on 2014-04-01. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_DTLSClientSession_h -#define hifi_DTLSClientSession_h - -#include "DTLSSession.h" - -class DTLSClientSession : public DTLSSession { -public: - DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); - - static void globalInit(); - static void globalDeinit(); - - static int verifyServerCertificate(gnutls_session_t session); - - static gnutls_certificate_credentials_t _x509CACredentials; - static bool _wasGloballyInitialized; -}; - -#endif // hifi_DTLSClientSession_h diff --git a/libraries/networking/src/DTLSSession.cpp b/libraries/networking/src/DTLSSession.cpp deleted file mode 100644 index f0649e4fc8..0000000000 --- a/libraries/networking/src/DTLSSession.cpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// DTLSSession.cpp -// libraries/networking/src -// -// Created by Stephen Birarda on 2014-04-01. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include - -#include "NodeList.h" -#include "DTLSSession.h" - -int DTLSSession::socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms) { - DTLSSession* session = static_cast(ptr); - QUdpSocket& dtlsSocket = session->_dtlsSocket; - - if (dtlsSocket.hasPendingDatagrams()) { - // peek the data on stack to see if it belongs to this session - static sockaddr senderSockAddr; - static socklen_t sockAddrSize = sizeof(senderSockAddr); - - QByteArray peekDatagram(dtlsSocket.pendingDatagramSize(), 0); - - recvfrom(dtlsSocket.socketDescriptor(), peekDatagram.data(), dtlsSocket.pendingDatagramSize(), - MSG_PEEK, &senderSockAddr, &sockAddrSize); - - if (HifiSockAddr(&senderSockAddr) == session->_destinationSocket) { - // there is data for this session ready to be read - return 1; - } else { - // the next data from the dtlsSocket is not for this session - return 0; - } - } else { - // no data available on the dtlsSocket - return 0; - } -} - -ssize_t DTLSSession::socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size) { - DTLSSession* session = static_cast(ptr); - QUdpSocket& dtlsSocket = session->_dtlsSocket; - - HifiSockAddr pulledSockAddr; - qint64 bytesReceived = dtlsSocket.readDatagram(reinterpret_cast(buffer), size, - pulledSockAddr.getAddressPointer(), pulledSockAddr.getPortPointer()); - if (bytesReceived == -1) { - // no data to pull, return -1 -#if DTLS_VERBOSE_DEBUG - qDebug() << "Received no data on call to readDatagram"; -#endif - return bytesReceived; - } - - if (pulledSockAddr == session->_destinationSocket) { - // bytes received from the correct sender, return number of bytes received - -#if DTLS_VERBOSE_DEBUG - qDebug() << "Received" << bytesReceived << "on DTLS socket from" << pulledSockAddr; -#endif - - return bytesReceived; - } - - // we pulled a packet not matching this session, so output that - qDebug() << "Denied connection from" << pulledSockAddr; - - gnutls_transport_set_errno(session->_gnutlsSession, GNUTLS_E_AGAIN); - return -1; -} - -gnutls_datum_t* DTLSSession::highFidelityCADatum() { - static gnutls_datum_t hifiCADatum; - static bool datumInitialized = false; - - static unsigned char HIGHFIDELITY_ROOT_CA_CERT[] = - "-----BEGIN CERTIFICATE-----\n" - "MIID6TCCA1KgAwIBAgIJANlfRkRD9A8bMA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD\n" - "VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5j\n" - "aXNjbzEbMBkGA1UEChMSSGlnaCBGaWRlbGl0eSwgSW5jMRMwEQYDVQQLEwpPcGVy\n" - "YXRpb25zMRgwFgYDVQQDEw9oaWdoZmlkZWxpdHkuaW8xIjAgBgkqhkiG9w0BCQEW\n" - "E29wc0BoaWdoZmlkZWxpdHkuaW8wHhcNMTQwMzI4MjIzMzM1WhcNMjQwMzI1MjIz\n" - "MzM1WjCBqjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNV\n" - "BAcTDVNhbiBGcmFuY2lzY28xGzAZBgNVBAoTEkhpZ2ggRmlkZWxpdHksIEluYzET\n" - "MBEGA1UECxMKT3BlcmF0aW9uczEYMBYGA1UEAxMPaGlnaGZpZGVsaXR5LmlvMSIw\n" - "IAYJKoZIhvcNAQkBFhNvcHNAaGlnaGZpZGVsaXR5LmlvMIGfMA0GCSqGSIb3DQEB\n" - "AQUAA4GNADCBiQKBgQDyo1euYiPPEdnvDZnIjWrrP230qUKMSj8SWoIkbTJF2hE8\n" - "2eP3YOgbgSGBzZ8EJBxIOuNmj9g9Eg6691hIKFqy5W0BXO38P04Gg+pVBvpHFGBi\n" - "wpqGbfsjaUDuYmBeJRcMO0XYkLCRQG+lAQNHoFDdItWAJfC3FwtP3OCDnz8cNwID\n" - "AQABo4IBEzCCAQ8wHQYDVR0OBBYEFCSv2kmiGg6VFMnxXzLDNP304cPAMIHfBgNV\n" - "HSMEgdcwgdSAFCSv2kmiGg6VFMnxXzLDNP304cPAoYGwpIGtMIGqMQswCQYDVQQG\n" - "EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNj\n" - "bzEbMBkGA1UEChMSSGlnaCBGaWRlbGl0eSwgSW5jMRMwEQYDVQQLEwpPcGVyYXRp\n" - "b25zMRgwFgYDVQQDEw9oaWdoZmlkZWxpdHkuaW8xIjAgBgkqhkiG9w0BCQEWE29w\n" - "c0BoaWdoZmlkZWxpdHkuaW+CCQDZX0ZEQ/QPGzAMBgNVHRMEBTADAQH/MA0GCSqG\n" - "SIb3DQEBBQUAA4GBAEkQl3p+lH5vuoCNgyfa67nL0MsBEt+5RSBOgjwCjjASjzou\n" - "FTv5w0he2OypgMQb8i/BYtS1lJSFqjPJcSM1Salzrm3xDOK5pOXJ7h6SQLPDVEyf\n" - "Hy2/9d/to+99+SOUlvfzfgycgjOc+s/AV7Y+GBd7uzGxUdrN4egCZW1F6/mH\n" - "-----END CERTIFICATE-----\n"; - - if (!datumInitialized) { - hifiCADatum.data = HIGHFIDELITY_ROOT_CA_CERT; - hifiCADatum.size = sizeof(HIGHFIDELITY_ROOT_CA_CERT); - } - - return &hifiCADatum; -} - -DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : - DummyDTLSSession(dtlsSocket, destinationSocket), - _completedHandshake(false) -{ - gnutls_init(&_gnutlsSession, end | GNUTLS_DATAGRAM | GNUTLS_NONBLOCK); - - // see http://gnutls.org/manual/html_node/Datagram-TLS-API.html#gnutls_005fdtls_005fset_005fmtu - const unsigned int DTLS_MAX_MTU = 1452; - gnutls_dtls_set_mtu(_gnutlsSession, DTLS_MAX_MTU); - - const unsigned int DTLS_HANDSHAKE_RETRANSMISSION_TIMEOUT = DOMAIN_SERVER_CHECK_IN_MSECS; - const unsigned int DTLS_TOTAL_CONNECTION_TIMEOUT = 2 * NODE_SILENCE_THRESHOLD_MSECS; - gnutls_dtls_set_timeouts(_gnutlsSession, DTLS_HANDSHAKE_RETRANSMISSION_TIMEOUT, DTLS_TOTAL_CONNECTION_TIMEOUT); - - gnutls_transport_set_ptr(_gnutlsSession, this); - gnutls_transport_set_push_function(_gnutlsSession, DummyDTLSSession::socketPush); - gnutls_transport_set_pull_function(_gnutlsSession, socketPull); - gnutls_transport_set_pull_timeout_function(_gnutlsSession, socketPullTimeout); -} - -DTLSSession::~DTLSSession() { - gnutls_deinit(_gnutlsSession); -} - -void DTLSSession::setCompletedHandshake(bool completedHandshake) { - _completedHandshake = completedHandshake; - qDebug() << "Completed DTLS handshake with" << _destinationSocket; -} - -qint64 DTLSSession::writeDatagram(const QByteArray& datagram) { - // we don't need to put a hash in this packet, so just send it off - return gnutls_record_send(_gnutlsSession, datagram.data(), datagram.size()); -} \ No newline at end of file diff --git a/libraries/networking/src/DTLSSession.h b/libraries/networking/src/DTLSSession.h deleted file mode 100644 index 9e9542e147..0000000000 --- a/libraries/networking/src/DTLSSession.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// DTLSSession.h -// libraries/networking/src -// -// Created by Stephen Birarda on 2014-04-01. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_DTLSSession_h -#define hifi_DTLSSession_h - -#include - -#include - -#include "DummyDTLSSession.h" -#include "HifiSockAddr.h" - -class DTLSSession : public DummyDTLSSession { - Q_OBJECT -public: - DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); - ~DTLSSession(); - - static int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms); - static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size); - - static gnutls_datum_t* highFidelityCADatum(); - - qint64 writeDatagram(const QByteArray& datagram); - - gnutls_session_t* getGnuTLSSession() { return &_gnutlsSession; } - - bool completedHandshake() const { return _completedHandshake; } - void setCompletedHandshake(bool completedHandshake); -protected: - gnutls_session_t _gnutlsSession; - bool _completedHandshake; -}; - -#endif // hifi_DTLSSession_h diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 6c2fb0274a..859af50070 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -22,16 +22,11 @@ DomainHandler::DomainHandler(QObject* parent) : _sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)), _assignmentUUID(), _isConnected(false), - _dtlsSession(NULL), _handshakeTimer(NULL) { } -DomainHandler::~DomainHandler() { - delete _dtlsSession; -} - void DomainHandler::clearConnectionInfo() { _uuid = QUuid(); _isConnected = false; @@ -41,38 +36,12 @@ void DomainHandler::clearConnectionInfo() { delete _handshakeTimer; _handshakeTimer = NULL; } - - delete _dtlsSession; - _dtlsSession = NULL; } void DomainHandler::reset() { clearConnectionInfo(); _hostname = QString(); _sockAddr.setAddress(QHostAddress::Null); - - delete _dtlsSession; - _dtlsSession = NULL; -} - -const unsigned int DTLS_HANDSHAKE_INTERVAL_MSECS = 100; - -void DomainHandler::initializeDTLSSession() { - if (!_dtlsSession) { - _dtlsSession = new DTLSClientSession(NodeList::getInstance()->getDTLSSocket(), _sockAddr); - - gnutls_session_set_ptr(*_dtlsSession->getGnuTLSSession(), this); - - // start a timer to complete the handshake process - _handshakeTimer = new QTimer(this); - connect(_handshakeTimer, &QTimer::timeout, this, &DomainHandler::completeDTLSHandshake); - - // start the handshake right now - completeDTLSHandshake(); - - // start the timer to finish off the handshake - _handshakeTimer->start(DTLS_HANDSHAKE_INTERVAL_MSECS); - } } void DomainHandler::setSockAddr(const HifiSockAddr& sockAddr, const QString& hostname) { @@ -120,30 +89,6 @@ void DomainHandler::setHostname(const QString& hostname) { } } -void DomainHandler::completeDTLSHandshake() { - int handshakeReturn = gnutls_handshake(*_dtlsSession->getGnuTLSSession()); - - if (handshakeReturn == 0) { - // we've shaken hands, so we're good to go now - _dtlsSession->setCompletedHandshake(true); - - _handshakeTimer->stop(); - delete _handshakeTimer; - _handshakeTimer = NULL; - - // emit a signal so NodeList can handle incoming DTLS packets - emit completedDTLSHandshake(); - - } else if (gnutls_error_is_fatal(handshakeReturn)) { - // this was a fatal error handshaking, so remove this session - qDebug() << "Fatal error -" << gnutls_strerror(handshakeReturn) - << "- during DTLS handshake with DS at" - << qPrintable((_hostname.isEmpty() ? _sockAddr.getAddress().toString() : _hostname)); - - clearConnectionInfo(); - } -} - void DomainHandler::completedHostnameLookup(const QHostInfo& hostInfo) { for (int i = 0; i < hostInfo.addresses().size(); i++) { if (hostInfo.addresses()[i].protocol() == QAbstractSocket::IPv4Protocol) { @@ -179,5 +124,5 @@ void DomainHandler::parseDTLSRequirementPacket(const QByteArray& dtlsRequirement _sockAddr.setPort(dtlsPort); - initializeDTLSSession(); +// initializeDTLSSession(); } \ No newline at end of file diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 599f6d4a0f..782332f06a 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -18,7 +18,6 @@ #include #include -#include "DTLSClientSession.h" #include "HifiSockAddr.h" const QString DEFAULT_DOMAIN_HOSTNAME = "sandbox.highfidelity.io"; @@ -32,7 +31,6 @@ class DomainHandler : public QObject { Q_OBJECT public: DomainHandler(QObject* parent = 0); - ~DomainHandler(); void clearConnectionInfo(); @@ -56,29 +54,22 @@ public: bool isConnected() const { return _isConnected; } void setIsConnected(bool isConnected); - DTLSClientSession* getDTLSSession() { return _dtlsSession; } - void parseDTLSRequirementPacket(const QByteArray& dtlsRequirementPacket); private slots: - void completeDTLSHandshake(); void completedHostnameLookup(const QHostInfo& hostInfo); signals: void hostnameChanged(const QString& hostname); void connectedToDomain(const QString& hostname); - void completedDTLSHandshake(); - void DTLSConnectionLost(); private: void reset(); - void initializeDTLSSession(); QUuid _uuid; QString _hostname; HifiSockAddr _sockAddr; QUuid _assignmentUUID; bool _isConnected; - DTLSClientSession* _dtlsSession; QTimer* _handshakeTimer; }; diff --git a/libraries/networking/src/DummyDTLSSession.cpp b/libraries/networking/src/DummyDTLSSession.cpp deleted file mode 100644 index a42e3f1599..0000000000 --- a/libraries/networking/src/DummyDTLSSession.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// -// DummyDTLSSession.cpp -// libraries/networking/src -// -// Created by Stephen Birarda on 2014-04-04. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "DummyDTLSSession.h" - -ssize_t DummyDTLSSession::socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size) { - DummyDTLSSession* session = static_cast(ptr); - QUdpSocket& dtlsSocket = session->_dtlsSocket; - -#if DTLS_VERBOSE_DEBUG - qDebug() << "Pushing a message of size" << size << "to" << session->_destinationSocket; -#endif - - return dtlsSocket.writeDatagram(reinterpret_cast(buffer), size, - session->_destinationSocket.getAddress(), session->_destinationSocket.getPort()); -} - -DummyDTLSSession::DummyDTLSSession(QUdpSocket& dtlsSocket, const HifiSockAddr& destinationSocket) : - _dtlsSocket(dtlsSocket), - _destinationSocket(destinationSocket) -{ - -} \ No newline at end of file diff --git a/libraries/networking/src/DummyDTLSSession.h b/libraries/networking/src/DummyDTLSSession.h deleted file mode 100644 index 352b2c23e2..0000000000 --- a/libraries/networking/src/DummyDTLSSession.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// DummyDTLSSession.h -// libraries/networking/src -// -// Created by Stephen Birarda on 2014-04-04. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_DummyDTLSSession_h -#define hifi_DummyDTLSSession_h - -#include - -#include - -#include "HifiSockAddr.h" - -#define DTLS_VERBOSE_DEBUG 0 - -class DummyDTLSSession : public QObject { - Q_OBJECT -public: - DummyDTLSSession(QUdpSocket& dtlsSocket, const HifiSockAddr& destinationSocket); - - static ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size); -protected: - QUdpSocket& _dtlsSocket; - HifiSockAddr _destinationSocket; -}; - -#endif // hifi_DummyDTLSSession_h diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index e3d113a1b5..eea9845f16 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -68,9 +68,6 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned // clear our NodeList when logout is requested connect(&AccountManager::getInstance(), &AccountManager::logoutComplete , this, &NodeList::reset); - - // perform a function when DTLS handshake is completed - connect(&_domainHandler, &DomainHandler::completedDTLSHandshake, this, &NodeList::completedDTLSHandshake); } qint64 NodeList::sendStatsToDomainServer(const QJsonObject& statsObject) { @@ -117,30 +114,6 @@ void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer& } } -void NodeList::completedDTLSHandshake() { - // at this point, we've got a DTLS socket - // make this NodeList the handler of DTLS packets - connect(_dtlsSocket, &QUdpSocket::readyRead, this, &NodeList::processAvailableDTLSDatagrams); -} - -void NodeList::processAvailableDTLSDatagrams() { - while (_dtlsSocket->hasPendingDatagrams()) { - QByteArray dtlsPacket(_dtlsSocket->pendingDatagramSize(), 0); - - // pull the data from this user off the stack and process it - int receivedBytes = gnutls_record_recv(*_domainHandler.getDTLSSession()->getGnuTLSSession(), - dtlsPacket.data(), dtlsPacket.size()); - if (receivedBytes > 0) { - // successful data receive, hand this off to processNodeData - processNodeData(_domainHandler.getSockAddr(), dtlsPacket.left(receivedBytes)); - } else if (gnutls_error_is_fatal(receivedBytes)) { - qDebug() << "Fatal error -" << gnutls_strerror(receivedBytes) << "- receiving DTLS packet from domain-server."; - } else { - qDebug() << "non fatal receive" << receivedBytes; - } - } -} - void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet) { switch (packetTypeForPacket(packet)) { case PacketTypeDomainList: { @@ -365,19 +338,9 @@ void NodeList::sendDomainServerCheckIn() { // send a STUN request to figure it out sendSTUNRequest(); } else if (!_domainHandler.getIP().isNull()) { - - DTLSClientSession* dtlsSession = _domainHandler.getDTLSSession(); + bool isUsingDTLS = false; - if (dtlsSession) { - if (!dtlsSession->completedHandshake()) { - // if the handshake process is not complete then we can't check in, so return - return; - } else { - isUsingDTLS = true; - } - } - PacketType domainPacketType = !_domainHandler.isConnected() ? PacketTypeDomainConnectRequest : PacketTypeDomainListRequest; @@ -405,8 +368,6 @@ void NodeList::sendDomainServerCheckIn() { if (!isUsingDTLS) { writeDatagram(domainServerPacket, _domainHandler.getSockAddr(), QUuid()); - } else { - dtlsSession->writeDatagram(domainServerPacket); } const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5; diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index c55f08e7f0..c1d5189c6d 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -83,8 +83,6 @@ public slots: void reset(); void sendDomainServerCheckIn(); void pingInactiveNodes(); - void completedDTLSHandshake(); - void processAvailableDTLSDatagrams(); signals: void limitOfSilentDomainCheckInsReached(); private: From bf859c01683665e3df05be9bdf5a5752b9e37eab Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 20 May 2014 10:56:34 -0700 Subject: [PATCH 04/49] remove GnuTLS include across repo --- domain-server/src/DomainServer.cpp | 2 -- libraries/networking/src/DomainHandler.cpp | 2 -- libraries/networking/src/NodeList.cpp | 2 -- 3 files changed, 6 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index fa8a26b259..f6af63fd7a 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -18,8 +18,6 @@ #include #include -#include - #include #include #include diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 859af50070..95689f8e82 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -9,8 +9,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include - #include "NodeList.h" #include "PacketHeaders.h" diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index eea9845f16..ebd33ef132 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -15,8 +15,6 @@ #include #include -#include - #include "AccountManager.h" #include "Assignment.h" #include "HifiSockAddr.h" From 97b67e83c5df6975452bc1784a1b45b5f43dba78 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 20 May 2014 11:26:20 -0700 Subject: [PATCH 05/49] remove more gnutls includes --- assignment-client/src/AssignmentClient.cpp | 2 -- domain-server/src/DomainServer.h | 2 -- libraries/networking/src/LimitedNodeList.h | 2 -- libraries/networking/src/NodeList.h | 2 -- 4 files changed, 8 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index d8383ccd48..b3a92f2f54 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -13,8 +13,6 @@ #include #include -#include - #include #include #include diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 32d53281f1..71809d9e16 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -20,8 +20,6 @@ #include #include -#include - #include #include #include diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 2a98dc536f..a4bc8022bf 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -27,8 +27,6 @@ #include #include -#include - #include "DomainHandler.h" #include "Node.h" diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index c1d5189c6d..af0bfeb368 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -27,8 +27,6 @@ #include #include -#include - #include "DomainHandler.h" #include "LimitedNodeList.h" #include "Node.h" From f351399d088153fb8b19d16b21d78eb190754dd4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 20 May 2014 11:56:06 -0700 Subject: [PATCH 06/49] put back ssize_t definition --- animation-server/CMakeLists.txt | 7 ++++++- assignment-client/CMakeLists.txt | 5 +++++ domain-server/CMakeLists.txt | 7 ++++++- interface/CMakeLists.txt | 3 +++ libraries/animation/CMakeLists.txt | 5 +++++ libraries/audio/CMakeLists.txt | 7 ++++++- libraries/avatars/CMakeLists.txt | 7 ++++++- libraries/fbx/CMakeLists.txt | 5 +++++ libraries/metavoxels/CMakeLists.txt | 7 ++++++- libraries/models/CMakeLists.txt | 7 ++++++- libraries/networking/CMakeLists.txt | 7 ++++++- libraries/octree/CMakeLists.txt | 7 ++++++- libraries/particles/CMakeLists.txt | 5 +++++ libraries/script-engine/CMakeLists.txt | 5 +++++ libraries/voxels/CMakeLists.txt | 7 ++++++- voxel-edit/CMakeLists.txt | 7 ++++++- 16 files changed, 88 insertions(+), 10 deletions(-) diff --git a/animation-server/CMakeLists.txt b/animation-server/CMakeLists.txt index d8fa8d97b2..42516d2f86 100644 --- a/animation-server/CMakeLists.txt +++ b/animation-server/CMakeLists.txt @@ -30,4 +30,9 @@ link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") # link the hifi networking library -link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") \ No newline at end of file +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index a088c04ffb..873ae761ca 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -46,3 +46,8 @@ IF (WIN32) ENDIF(WIN32) target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index d1f923f4d2..f9bbeb31fc 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -42,4 +42,9 @@ IF (WIN32) ENDIF(WIN32) # link QtNetwork -target_link_libraries(${TARGET_NAME} Qt5::Network) \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Network) + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 67b993d6c9..cf203c41d9 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -285,6 +285,9 @@ else (APPLE) # we're using static GLEW, so define GLEW_STATIC add_definitions(-DGLEW_STATIC) + # add a definition for ssize_t so that windows doesn't bail + add_definitions(-Dssize_t=long) + target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARY}" wsock32.lib opengl32.lib) endif() endif (APPLE) diff --git a/libraries/animation/CMakeLists.txt b/libraries/animation/CMakeLists.txt index 35ceb22395..1e33f50659 100644 --- a/libraries/animation/CMakeLists.txt +++ b/libraries/animation/CMakeLists.txt @@ -28,3 +28,8 @@ link_hifi_library(fbx ${TARGET_NAME} "${ROOT_DIR}") find_package(ZLIB) target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file diff --git a/libraries/audio/CMakeLists.txt b/libraries/audio/CMakeLists.txt index 0bf0ba9904..60636ba051 100644 --- a/libraries/audio/CMakeLists.txt +++ b/libraries/audio/CMakeLists.txt @@ -21,4 +21,9 @@ include_glm(${TARGET_NAME} "${ROOT_DIR}") include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") -link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") \ No newline at end of file +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file diff --git a/libraries/avatars/CMakeLists.txt b/libraries/avatars/CMakeLists.txt index 9816282dda..fc398fc33d 100644 --- a/libraries/avatars/CMakeLists.txt +++ b/libraries/avatars/CMakeLists.txt @@ -28,4 +28,9 @@ link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") -target_link_libraries(${TARGET_NAME} Qt5::Script) \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Script) + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file diff --git a/libraries/fbx/CMakeLists.txt b/libraries/fbx/CMakeLists.txt index 9ce234bbd4..bc5ac3b3c4 100644 --- a/libraries/fbx/CMakeLists.txt +++ b/libraries/fbx/CMakeLists.txt @@ -29,3 +29,8 @@ find_package(ZLIB) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file diff --git a/libraries/metavoxels/CMakeLists.txt b/libraries/metavoxels/CMakeLists.txt index 7a8319815a..79c07c6c47 100644 --- a/libraries/metavoxels/CMakeLists.txt +++ b/libraries/metavoxels/CMakeLists.txt @@ -27,4 +27,9 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") -target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file diff --git a/libraries/models/CMakeLists.txt b/libraries/models/CMakeLists.txt index 7833349319..06578371cc 100644 --- a/libraries/models/CMakeLists.txt +++ b/libraries/models/CMakeLists.txt @@ -37,4 +37,9 @@ link_hifi_library(metavoxels ${TARGET_NAME} "${ROOT_DIR}") find_package(ZLIB) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) \ No newline at end of file +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index f93ba2e5cf..fdd2d5830a 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -19,4 +19,9 @@ setup_hifi_library(${TARGET_NAME}) include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") -target_link_libraries(${TARGET_NAME} Qt5::Network) \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Network) + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file diff --git a/libraries/octree/CMakeLists.txt b/libraries/octree/CMakeLists.txt index 985b3fdba7..5988b4b058 100644 --- a/libraries/octree/CMakeLists.txt +++ b/libraries/octree/CMakeLists.txt @@ -28,4 +28,9 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") find_package(ZLIB) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) \ No newline at end of file +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file diff --git a/libraries/particles/CMakeLists.txt b/libraries/particles/CMakeLists.txt index 7f42854b93..dbf2995293 100644 --- a/libraries/particles/CMakeLists.txt +++ b/libraries/particles/CMakeLists.txt @@ -32,3 +32,8 @@ find_package(ZLIB) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file diff --git a/libraries/script-engine/CMakeLists.txt b/libraries/script-engine/CMakeLists.txt index ac56f335e1..d0d05df286 100644 --- a/libraries/script-engine/CMakeLists.txt +++ b/libraries/script-engine/CMakeLists.txt @@ -34,3 +34,8 @@ find_package(ZLIB) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file diff --git a/libraries/voxels/CMakeLists.txt b/libraries/voxels/CMakeLists.txt index dd1020b4d7..51b83bb650 100644 --- a/libraries/voxels/CMakeLists.txt +++ b/libraries/voxels/CMakeLists.txt @@ -30,4 +30,9 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") find_package(ZLIB) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets Qt5::Script) \ No newline at end of file +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets Qt5::Script) + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file diff --git a/voxel-edit/CMakeLists.txt b/voxel-edit/CMakeLists.txt index ce3c542691..6ebf23efba 100644 --- a/voxel-edit/CMakeLists.txt +++ b/voxel-edit/CMakeLists.txt @@ -38,4 +38,9 @@ IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) -target_link_libraries(${TARGET_NAME} Qt5::Script) \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Script) + +# add a definition for ssize_t so that windows doesn't bail +if (WIN32) + add_definitions(-Dssize_t=long) +endif () \ No newline at end of file From de7c05cb2dda4936f7af3245e485d072486936de Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 21 May 2014 15:30:50 -0700 Subject: [PATCH 07/49] More animation controls. --- interface/src/avatar/MyAvatar.cpp | 19 ++++++++++++++++--- interface/src/avatar/MyAvatar.h | 4 ++-- interface/src/renderer/Model.cpp | 24 +++++++++++++++++------- interface/src/renderer/Model.h | 12 ++++++++++++ interface/src/ui/AnimationsDialog.cpp | 27 +++++++++++++++++++++++++++ interface/src/ui/AnimationsDialog.h | 6 ++++++ 6 files changed, 80 insertions(+), 12 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index be88a80b90..3f40bbc8ed 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -441,10 +441,12 @@ void MyAvatar::removeAnimationHandle(const AnimationHandlePointer& handle) { _animationHandles.removeOne(handle); } -void MyAvatar::startAnimation(const QString& url, float fps, float priority, bool loop, const QStringList& maskedJoints) { +void MyAvatar::startAnimation(const QString& url, float fps, float priority, + bool loop, bool hold, int firstFrame, int lastFrame, const QStringList& maskedJoints) { if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "startAnimation", Q_ARG(const QString&, url), - Q_ARG(float, fps), Q_ARG(float, priority), Q_ARG(bool, loop), Q_ARG(const QStringList&, maskedJoints)); + QMetaObject::invokeMethod(this, "startAnimation", Q_ARG(const QString&, url), Q_ARG(float, fps), + Q_ARG(float, priority), Q_ARG(bool, loop), Q_ARG(bool, hold), Q_ARG(int, firstFrame), + Q_ARG(int, lastFrame), Q_ARG(const QStringList&, maskedJoints)); return; } AnimationHandlePointer handle = _skeletonModel.createAnimationHandle(); @@ -452,6 +454,9 @@ void MyAvatar::startAnimation(const QString& url, float fps, float priority, boo handle->setFPS(fps); handle->setPriority(priority); handle->setLoop(loop); + handle->setHold(hold); + handle->setFirstFrame(firstFrame); + handle->setLastFrame(lastFrame); handle->setMaskedJoints(maskedJoints); handle->start(); } @@ -514,6 +519,10 @@ void MyAvatar::saveData(QSettings* settings) { settings->setValue("url", pointer->getURL()); settings->setValue("fps", pointer->getFPS()); settings->setValue("priority", pointer->getPriority()); + settings->setValue("loop", pointer->getLoop()); + settings->setValue("hold", pointer->getHold()); + settings->setValue("firstFrame", pointer->getFirstFrame()); + settings->setValue("lastFrame", pointer->getLastFrame()); settings->setValue("maskedJoints", pointer->getMaskedJoints()); } settings->endArray(); @@ -581,6 +590,10 @@ void MyAvatar::loadData(QSettings* settings) { handle->setURL(settings->value("url").toUrl()); handle->setFPS(loadSetting(settings, "fps", 30.0f)); handle->setPriority(loadSetting(settings, "priority", 1.0f)); + handle->setLoop(settings->value("loop", true).toBool()); + handle->setHold(settings->value("hold", false).toBool()); + handle->setFirstFrame(settings->value("firstFrame", 0).toInt()); + handle->setLastFrame(settings->value("lastFrame", INT_MAX).toInt()); handle->setMaskedJoints(settings->value("maskedJoints").toStringList()); } settings->endArray(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 9d6f22264f..fcbb2103d1 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -67,8 +67,8 @@ public: void removeAnimationHandle(const AnimationHandlePointer& handle); /// Allows scripts to run animations. - Q_INVOKABLE void startAnimation(const QString& url, float fps = 30.0f, - float priority = 1.0f, bool loop = false, const QStringList& maskedJoints = QStringList()); + Q_INVOKABLE void startAnimation(const QString& url, float fps = 30.0f, float priority = 1.0f, bool loop = false, + bool hold = false, int firstFrame = 0, int lastFrame = INT_MAX, const QStringList& maskedJoints = QStringList()); /// Stops an animation as identified by a URL. Q_INVOKABLE void stopAnimation(const QString& url); diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 900d7ff951..5b81de2c1f 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1694,7 +1694,7 @@ void AnimationHandle::setRunning(bool running) { if (!_model->_runningAnimations.contains(_self)) { insertSorted(_model->_runningAnimations, _self); } - _frameIndex = 0.0f; + _frameIndex = _firstFrame; } else { _model->_runningAnimations.removeOne(_self); @@ -1706,7 +1706,10 @@ AnimationHandle::AnimationHandle(Model* model) : _model(model), _fps(30.0f), _priority(1.0f), + _firstFrame(0), + _lastFrame(INT_MAX), _loop(false), + _hold(false), _running(false) { } @@ -1737,10 +1740,11 @@ void AnimationHandle::simulate(float deltaTime) { stop(); return; } - int ceilFrameIndex = (int)glm::ceil(_frameIndex); - if (!_loop && ceilFrameIndex >= animationGeometry.animationFrames.size()) { + int lastFrameIndex = qMin(_lastFrame, animationGeometry.animationFrames.size() - 1); + int firstFrameIndex = qMin(_firstFrame, lastFrameIndex); + if ((!_loop && _frameIndex >= lastFrameIndex) || firstFrameIndex == lastFrameIndex) { // passed the end; apply the last frame - const FBXAnimationFrame& frame = animationGeometry.animationFrames.last(); + const FBXAnimationFrame& frame = animationGeometry.animationFrames.at(lastFrameIndex); for (int i = 0; i < _jointMappings.size(); i++) { int mapping = _jointMappings.at(i); if (mapping != -1) { @@ -1750,14 +1754,20 @@ void AnimationHandle::simulate(float deltaTime) { } } } - stop(); + if (!_hold) { + stop(); + } return; } + int frameCount = lastFrameIndex - firstFrameIndex + 1; + _frameIndex = firstFrameIndex + glm::mod(qMax(_frameIndex - firstFrameIndex, 0.0f), (float)frameCount); + qDebug() << _frameIndex; + // blend between the closest two frames const FBXAnimationFrame& ceilFrame = animationGeometry.animationFrames.at( - ceilFrameIndex % animationGeometry.animationFrames.size()); + firstFrameIndex + ((int)glm::ceil(_frameIndex) - firstFrameIndex) % frameCount); const FBXAnimationFrame& floorFrame = animationGeometry.animationFrames.at( - (int)glm::floor(_frameIndex) % animationGeometry.animationFrames.size()); + firstFrameIndex + ((int)glm::floor(_frameIndex) - firstFrameIndex) % frameCount); float frameFraction = glm::fract(_frameIndex); for (int i = 0; i < _jointMappings.size(); i++) { int mapping = _jointMappings.at(i); diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 59ec50cac1..979dc6c601 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -393,6 +393,15 @@ public: void setLoop(bool loop) { _loop = loop; } bool getLoop() const { return _loop; } + void setHold(bool hold) { _hold = hold; } + bool getHold() const { return _hold; } + + void setFirstFrame(int firstFrame) { _firstFrame = firstFrame; } + int getFirstFrame() const { return _firstFrame; } + + void setLastFrame(int lastFrame) { _lastFrame = lastFrame; } + int getLastFrame() const { return _lastFrame; } + void setMaskedJoints(const QStringList& maskedJoints); const QStringList& getMaskedJoints() const { return _maskedJoints; } @@ -416,7 +425,10 @@ private: QUrl _url; float _fps; float _priority; + int _firstFrame; + int _lastFrame; bool _loop; + bool _hold; QStringList _maskedJoints; bool _running; QVector _jointMappings; diff --git a/interface/src/ui/AnimationsDialog.cpp b/interface/src/ui/AnimationsDialog.cpp index 29837f67be..f30c98cce7 100644 --- a/interface/src/ui/AnimationsDialog.cpp +++ b/interface/src/ui/AnimationsDialog.cpp @@ -9,6 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include #include #include #include @@ -107,6 +108,24 @@ AnimationPanel::AnimationPanel(AnimationsDialog* dialog, const AnimationHandlePo maskedJointBox->addWidget(_chooseMaskedJoints = new QPushButton("Choose")); connect(_chooseMaskedJoints, SIGNAL(clicked(bool)), SLOT(chooseMaskedJoints())); + layout->addRow("Loop:", _loop = new QCheckBox()); + _loop->setChecked(handle->getLoop()); + connect(_loop, SIGNAL(toggled(bool)), SLOT(updateHandle())); + + layout->addRow("Hold:", _hold = new QCheckBox()); + _hold->setChecked(handle->getHold()); + connect(_hold, SIGNAL(toggled(bool)), SLOT(updateHandle())); + + layout->addRow("First Frame:", _firstFrame = new QSpinBox()); + _firstFrame->setMaximum(INT_MAX); + _firstFrame->setValue(handle->getFirstFrame()); + connect(_firstFrame, SIGNAL(valueChanged(int)), SLOT(updateHandle())); + + layout->addRow("Last Frame:", _lastFrame = new QSpinBox()); + _lastFrame->setMaximum(INT_MAX); + _lastFrame->setValue(handle->getLastFrame()); + connect(_lastFrame, SIGNAL(valueChanged(int)), SLOT(updateHandle())); + QPushButton* remove = new QPushButton("Delete"); layout->addRow(remove); connect(remove, SIGNAL(clicked(bool)), SLOT(removeHandle())); @@ -149,7 +168,15 @@ void AnimationPanel::updateHandle() { _handle->setURL(_url->text()); _handle->setFPS(_fps->value()); _handle->setPriority(_priority->value()); + _handle->setLoop(_loop->isChecked()); + _handle->setHold(_hold->isChecked()); + _handle->setFirstFrame(_firstFrame->value()); + _handle->setLastFrame(_lastFrame->value()); _handle->setMaskedJoints(_maskedJoints->text().split(QRegExp("\\s*,\\s*"))); + + if ((_loop->isChecked() || _hold->isChecked()) && !_handle->isRunning()) { + _handle->start(); + } } void AnimationPanel::removeHandle() { diff --git a/interface/src/ui/AnimationsDialog.h b/interface/src/ui/AnimationsDialog.h index 7693a1da97..8b0f6cd257 100644 --- a/interface/src/ui/AnimationsDialog.h +++ b/interface/src/ui/AnimationsDialog.h @@ -17,9 +17,11 @@ #include "avatar/MyAvatar.h" +class QCheckBox; class QDoubleSpinner; class QLineEdit; class QPushButton; +class QSpinBox; class QVBoxLayout; /// Allows users to edit the avatar animations. @@ -64,6 +66,10 @@ private: QLineEdit* _url; QDoubleSpinBox* _fps; QDoubleSpinBox* _priority; + QCheckBox* _loop; + QCheckBox* _hold; + QSpinBox* _firstFrame; + QSpinBox* _lastFrame; QLineEdit* _maskedJoints; QPushButton* _chooseMaskedJoints; bool _applying; From 2eee9a32ac4d38da9b18dd5433a38ec36a8dc944 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 21 May 2014 15:39:12 -0700 Subject: [PATCH 08/49] Removed debugging line. --- interface/src/renderer/Model.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 5b81de2c1f..5d0f571b5b 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1761,7 +1761,6 @@ void AnimationHandle::simulate(float deltaTime) { } int frameCount = lastFrameIndex - firstFrameIndex + 1; _frameIndex = firstFrameIndex + glm::mod(qMax(_frameIndex - firstFrameIndex, 0.0f), (float)frameCount); - qDebug() << _frameIndex; // blend between the closest two frames const FBXAnimationFrame& ceilFrame = animationGeometry.animationFrames.at( From 4036f929c956c8a5124de81699d58d073430f20d Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 22 May 2014 10:31:30 -0700 Subject: [PATCH 09/49] Stopped access violation when erasing particles. --- .../src/particles/ParticleTreeRenderer.cpp | 4 +++- libraries/particles/src/ParticleTreeElement.cpp | 17 ++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/interface/src/particles/ParticleTreeRenderer.cpp b/interface/src/particles/ParticleTreeRenderer.cpp index 38ef9c8516..781fc2bfc8 100644 --- a/interface/src/particles/ParticleTreeRenderer.cpp +++ b/interface/src/particles/ParticleTreeRenderer.cpp @@ -127,5 +127,7 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element, RenderArgs* arg } void ParticleTreeRenderer::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) { - static_cast(_tree)->processEraseMessage(dataByteArray, sourceNode); + if (_tree->tryLockForWrite()) { + static_cast(_tree)->processEraseMessage(dataByteArray, sourceNode); + } } diff --git a/libraries/particles/src/ParticleTreeElement.cpp b/libraries/particles/src/ParticleTreeElement.cpp index b6e59eb0ab..2a617380fc 100644 --- a/libraries/particles/src/ParticleTreeElement.cpp +++ b/libraries/particles/src/ParticleTreeElement.cpp @@ -20,8 +20,9 @@ ParticleTreeElement::ParticleTreeElement(unsigned char* octalCode) : OctreeEleme ParticleTreeElement::~ParticleTreeElement() { _voxelMemoryUsage -= sizeof(ParticleTreeElement); - delete _particles; + QList* tmpParticles = _particles; _particles = NULL; + delete tmpParticles; } // This will be called primarily on addChildAt(), which means we're adding a child of our @@ -277,12 +278,14 @@ const Particle* ParticleTreeElement::getParticleWithID(uint32_t id) const { bool ParticleTreeElement::removeParticleWithID(uint32_t id) { bool foundParticle = false; - uint16_t numberOfParticles = _particles->size(); - for (uint16_t i = 0; i < numberOfParticles; i++) { - if ((*_particles)[i].getID() == id) { - foundParticle = true; - _particles->removeAt(i); - break; + if (_particles) { + uint16_t numberOfParticles = _particles->size(); + for (uint16_t i = 0; i < numberOfParticles; i++) { + if ((*_particles)[i].getID() == id) { + foundParticle = true; + _particles->removeAt(i); + break; + } } } return foundParticle; From b9e73a6ef73b790476f5c48b60322b72bba0accd Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 22 May 2014 12:23:01 -0700 Subject: [PATCH 10/49] added delete support to edit models --- examples/editModels.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/examples/editModels.js b/examples/editModels.js index a73cf72987..ceaec136c5 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -632,10 +632,23 @@ function mouseMoveEvent(event) { Models.editModel(selectedModelID, selectedModelProperties); } +function setupModelMenus() { + // add our menuitems + Menu.addMenuItem({ menuName: "Edit", menuItemName: "Models", isSeparator: true, beforeItem: "Physics" }); + Menu.addMenuItem({ menuName: "Edit", menuItemName: "Delete Model", shortcutKeyEvent: { text: "backspace" }, afterItem: "Models" }); +} + +function cleanupModelMenus() { + // delete our menuitems + Menu.removeSeparator("Edit", "Models"); + Menu.removeMenuItem("Edit", "Delete Model"); +} + function scriptEnding() { leftController.cleanup(); rightController.cleanup(); toolBar.cleanup(); + cleanupModelMenus(); } Script.scriptEnding.connect(scriptEnding); @@ -644,5 +657,22 @@ Script.update.connect(checkController); Controller.mousePressEvent.connect(mousePressEvent); Controller.mouseMoveEvent.connect(mouseMoveEvent); +setupModelMenus(); +Menu.menuItemEvent.connect(function(menuItem){ + print("menuItemEvent() in JS... menuItem=" + menuItem); + if (menuItem == "Delete Model") { + if (leftController.grabbing) { + print(" Delete Model.... controller.modelID="+ leftController.modelID); + Models.deleteModel(leftController.modelID); + leftController.grabbing = false; + } else if (rightController.grabbing) { + print(" Delete Model.... controller.modelID="+ rightController.modelID); + Models.deleteModel(rightController.modelID); + rightController.grabbing = false; + } else { + print(" Delete Model.... not holding..."); + } + } +}); From 66b9d582a80e9a4ad69dbb835f78b173c945c4dd Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 22 May 2014 12:43:23 -0700 Subject: [PATCH 11/49] fix broken mouse edit --- examples/editModels.js | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/examples/editModels.js b/examples/editModels.js index ceaec136c5..717b7824bb 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -40,6 +40,16 @@ var modelURLs = [ var toolBar; +function isLocked(properties) { + // special case to lock the ground plane model in hq. + if (location.hostname == "hq.highfidelity.io" && + properties.modelURL == "https://s3-us-west-1.amazonaws.com/highfidelity-public/ozan/Terrain_Reduce_forAlpha.fbx") { + return true; + } + return false; +} + + function controller(wichSide) { this.side = wichSide; this.palm = 2 * wichSide; @@ -117,7 +127,7 @@ function controller(wichSide) { this.grab = function (modelID, properties) { - if (this.isLocked(properties)) { + if (isLocked(properties)) { print("Model locked " + modelID.id); } else { print("Grabbing " + modelID.id); @@ -150,15 +160,6 @@ function controller(wichSide) { } } - this.isLocked = function (properties) { - // special case to lock the ground plane model in hq. - if (location.hostname == "hq.highfidelity.io" && - properties.modelURL == "https://s3-us-west-1.amazonaws.com/highfidelity-public/ozan/Terrain_Reduce_forAlpha.fbx") { - return true; - } - return false; - } - this.checkModel = function (properties) { // special case to lock the ground plane model in hq. if (this.isLocked(properties)) { @@ -293,6 +294,7 @@ function controller(wichSide) { if (this.pressing) { Vec3.print("Looking at: ", this.palmPosition); var foundModels = Models.findModels(this.palmPosition, LASER_LENGTH_FACTOR); + for (var i = 0; i < foundModels.length; i++) { if (!foundModels[i].isKnownID) { @@ -305,7 +307,9 @@ function controller(wichSide) { } var properties = Models.getModelProperties(foundModels[i]); - if (this.isLocked(properties)) { + print("foundModels["+i+"].modelURL=" + properties.modelURL); + + if (isLocked(properties)) { print("Model locked " + properties.id); } else { print("Checking properties: " + properties.id + " " + properties.isKnownID); @@ -486,7 +490,7 @@ function mousePressEvent(event) { } var properties = Models.getModelProperties(foundModels[i]); - if (this.isLocked(properties)) { + if (isLocked(properties)) { print("Model locked " + properties.id); } else { print("Checking properties: " + properties.id + " " + properties.isKnownID); From 5013c8c2fab31353f6e49dc44c9a73d0da243d1a Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 22 May 2014 12:45:36 -0700 Subject: [PATCH 12/49] Fixed script editor crash when script calls Script.stop(). Also made the processEraseMessage wait until it can lock to ensure particles are deleted. --- .../src/particles/ParticleTreeRenderer.cpp | 3 ++- interface/src/ui/ScriptEditorWidget.cpp | 10 ++++++++++ interface/src/ui/ScriptEditorWidget.h | 1 + libraries/shared/src/SharedUtil.cpp | 18 +++++++++--------- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/interface/src/particles/ParticleTreeRenderer.cpp b/interface/src/particles/ParticleTreeRenderer.cpp index 781fc2bfc8..c89adab65d 100644 --- a/interface/src/particles/ParticleTreeRenderer.cpp +++ b/interface/src/particles/ParticleTreeRenderer.cpp @@ -127,7 +127,8 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element, RenderArgs* arg } void ParticleTreeRenderer::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) { - if (_tree->tryLockForWrite()) { + if (_tree){ + _tree->lockForWrite(); static_cast(_tree)->processEraseMessage(dataByteArray, sourceNode); } } diff --git a/interface/src/ui/ScriptEditorWidget.cpp b/interface/src/ui/ScriptEditorWidget.cpp index 07c6e72226..be5577e0e8 100644 --- a/interface/src/ui/ScriptEditorWidget.cpp +++ b/interface/src/ui/ScriptEditorWidget.cpp @@ -57,6 +57,11 @@ void ScriptEditorWidget::onScriptModified() { } } +void ScriptEditorWidget::onScriptEnding() { + // signals will automatically be disonnected when the _scriptEngine is deleted later + _scriptEngine = NULL; +} + bool ScriptEditorWidget::isModified() { return _scriptEditorWidgetUI->scriptEdit->document()->isModified(); } @@ -69,11 +74,13 @@ bool ScriptEditorWidget::setRunning(bool run) { if (run && !save()) { return false; } + // Clean-up old connections. if (_scriptEngine != NULL) { disconnect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged); disconnect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError); disconnect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint); + disconnect(_scriptEngine, &ScriptEngine::scriptEnding, this, &ScriptEditorWidget::onScriptEnding); } if (run) { @@ -83,6 +90,7 @@ bool ScriptEditorWidget::setRunning(bool run) { // Make new connections. connect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError); connect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint); + connect(_scriptEngine, &ScriptEngine::scriptEnding, this, &ScriptEditorWidget::onScriptEnding); } else { Application::getInstance()->stopScript(_currentScript); _scriptEngine = NULL; @@ -125,6 +133,7 @@ void ScriptEditorWidget::loadFile(const QString& scriptPath) { disconnect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged); disconnect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError); disconnect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint); + disconnect(_scriptEngine, &ScriptEngine::scriptEnding, this, &ScriptEditorWidget::onScriptEnding); } } else { QNetworkAccessManager* networkManager = new QNetworkAccessManager(this); @@ -144,6 +153,7 @@ void ScriptEditorWidget::loadFile(const QString& scriptPath) { connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged); connect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError); connect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint); + connect(_scriptEngine, &ScriptEngine::scriptEnding, this, &ScriptEditorWidget::onScriptEnding); } } diff --git a/interface/src/ui/ScriptEditorWidget.h b/interface/src/ui/ScriptEditorWidget.h index 1a96661cf7..3e95ea322b 100644 --- a/interface/src/ui/ScriptEditorWidget.h +++ b/interface/src/ui/ScriptEditorWidget.h @@ -46,6 +46,7 @@ private slots: void onScriptError(const QString& message); void onScriptPrint(const QString& message); void onScriptModified(); + void onScriptEnding(); private: Ui::ScriptEditorWidget* _scriptEditorWidgetUI; diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 1136d49dd4..f29e8e3345 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -276,7 +276,7 @@ unsigned char* pointToOctalCode(float x, float y, float z, float s) { unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r, unsigned char g, unsigned char b ) { // special case for size 1, the root node - if (s >= 1.0) { + if (s >= 1.0f) { unsigned char* voxelOut = new unsigned char; *voxelOut = 0; return voxelOut; @@ -289,7 +289,7 @@ unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r, // voxel of size S. unsigned int voxelSizeInOctets = 1; while (sTest > s) { - sTest /= 2.0; + sTest /= 2.0f; voxelSizeInOctets++; } @@ -314,11 +314,11 @@ unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r, if (x >= xTest) { // byte = (byte << 1) | true; - xTest += sTest/2.0; + xTest += sTest/2.0f; } else { // byte = (byte << 1) | false; - xTest -= sTest/2.0; + xTest -= sTest/2.0f; } bitInByteNDX++; // If we've reached the last bit of the byte, then we want to copy this byte @@ -333,11 +333,11 @@ unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r, if (y >= yTest) { // byte = (byte << 1) | true; - yTest += sTest/2.0; + yTest += sTest/2.0f; } else { // byte = (byte << 1) | false; - yTest -= sTest/2.0; + yTest -= sTest/2.0f; } bitInByteNDX++; // If we've reached the last bit of the byte, then we want to copy this byte @@ -352,11 +352,11 @@ unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r, if (z >= zTest) { // byte = (byte << 1) | true; - zTest += sTest/2.0; + zTest += sTest/2.0f; } else { // byte = (byte << 1) | false; - zTest -= sTest/2.0; + zTest -= sTest/2.0f; } bitInByteNDX++; // If we've reached the last bit of the byte, then we want to copy this byte @@ -369,7 +369,7 @@ unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r, } octetsDone++; - sTest /= 2.0; + sTest /= 2.0f; } // If we've got here, and we didn't fill the last byte, we need to zero pad this From b5056dcd3a1ca5586e2270b37a7f4dffc3df7ec8 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 22 May 2014 13:01:02 -0700 Subject: [PATCH 13/49] fix broken mouse edit --- examples/editModels.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/editModels.js b/examples/editModels.js index 717b7824bb..5319d75bb9 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -162,7 +162,7 @@ function controller(wichSide) { this.checkModel = function (properties) { // special case to lock the ground plane model in hq. - if (this.isLocked(properties)) { + if (isLocked(properties)) { return { valid: false }; } From a48c6b82e2a5e70b5f37be97c1bc8efe910d6022 Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 22 May 2014 14:17:26 -0700 Subject: [PATCH 14/49] Fixed my mistake by unlocking the lock. --- interface/src/particles/ParticleTreeRenderer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/particles/ParticleTreeRenderer.cpp b/interface/src/particles/ParticleTreeRenderer.cpp index c89adab65d..d9683405e2 100644 --- a/interface/src/particles/ParticleTreeRenderer.cpp +++ b/interface/src/particles/ParticleTreeRenderer.cpp @@ -130,5 +130,6 @@ void ParticleTreeRenderer::processEraseMessage(const QByteArray& dataByteArray, if (_tree){ _tree->lockForWrite(); static_cast(_tree)->processEraseMessage(dataByteArray, sourceNode); + _tree->unlock(); } } From 01e8d775f23ae5166ebb83d2f1a84c0fb979879e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 22 May 2014 14:24:19 -0700 Subject: [PATCH 15/49] change node auth URL to data.highfidelity.io --- interface/src/ModelUploader.cpp | 1 - interface/src/ui/LoginDialog.cpp | 2 +- interface/ui/loginDialog.ui | 4 ++-- libraries/networking/src/LimitedNodeList.cpp | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/interface/src/ModelUploader.cpp b/interface/src/ModelUploader.cpp index ec7fcee6f2..81bca0fc5a 100644 --- a/interface/src/ModelUploader.cpp +++ b/interface/src/ModelUploader.cpp @@ -50,7 +50,6 @@ static const QString JOINT_FIELD = "joint"; static const QString FREE_JOINT_FIELD = "freeJoint"; static const QString S3_URL = "http://public.highfidelity.io"; -static const QString DATA_SERVER_URL = "https://data-web.highfidelity.io"; static const QString MODEL_URL = "/api/v1/models"; static const QString SETTING_NAME = "LastModelUploadLocation"; diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index 40029b6785..57e02689c1 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -21,7 +21,7 @@ #include "LoginDialog.h" -const QString FORGOT_PASSWORD_URL = "https://data-web.highfidelity.io/password/new"; +const QString FORGOT_PASSWORD_URL = "https://data.highfidelity.io/password/new"; LoginDialog::LoginDialog(QWidget* parent) : FramelessDialog(parent, 0, FramelessDialog::POSITION_TOP), diff --git a/interface/ui/loginDialog.ui b/interface/ui/loginDialog.ui index d54b3c833f..73d466b68a 100644 --- a/interface/ui/loginDialog.ui +++ b/interface/ui/loginDialog.ui @@ -136,7 +136,7 @@ <style type="text/css"> a { text-decoration: none; color: #267077;} </style> -Invalid username or password. <a href="https://data-web.highfidelity.io/password/new">Recover?</a> +Invalid username or password. <a href="https://data.highfidelity.io/password/new">Recover?</a> Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter @@ -458,7 +458,7 @@ border-radius: 4px; padding-top: 1px; <style type="text/css"> a { text-decoration: none; color: #267077;} </style> -<a href="https://data-web.highfidelity.io/password/new">Recover password?</a> +<a href="https://data.highfidelity.io/password/new">Recover password?</a> true diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index b5a23f6b99..c0d7941edf 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -33,7 +33,7 @@ const char SOLO_NODE_TYPES[2] = { NodeType::AudioMixer }; -const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://data-web.highfidelity.io"); +const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://data.highfidelity.io"); LimitedNodeList* LimitedNodeList::_sharedInstance = NULL; From 519f5539d97a9f9be76f89812175e3ff9db23f0f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 22 May 2014 14:37:34 -0700 Subject: [PATCH 16/49] also support deleting mouse selected model --- examples/editModels.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/editModels.js b/examples/editModels.js index 5319d75bb9..55c79cbc1d 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -666,13 +666,17 @@ Menu.menuItemEvent.connect(function(menuItem){ print("menuItemEvent() in JS... menuItem=" + menuItem); if (menuItem == "Delete Model") { if (leftController.grabbing) { - print(" Delete Model.... controller.modelID="+ leftController.modelID); + print(" Delete Model.... leftController.modelID="+ leftController.modelID); Models.deleteModel(leftController.modelID); leftController.grabbing = false; } else if (rightController.grabbing) { - print(" Delete Model.... controller.modelID="+ rightController.modelID); + print(" Delete Model.... rightController.modelID="+ rightController.modelID); Models.deleteModel(rightController.modelID); rightController.grabbing = false; + } else if (modelSelected) { + print(" Delete Model.... selectedModelID="+ selectedModelID); + Models.deleteModel(selectedModelID); + modelSelected = false; } else { print(" Delete Model.... not holding..."); } From d4af39a9f5aded75fc429fe7e89e110529a6c1a3 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 22 May 2014 14:41:46 -0700 Subject: [PATCH 17/49] Working on handling animation priorities to prevent Hydra move/restore from interfering with scripted animations. --- interface/src/avatar/MyAvatar.cpp | 4 +- interface/src/avatar/SkeletonModel.cpp | 29 ++++++----- interface/src/renderer/Model.cpp | 66 ++++++++++++++++---------- interface/src/renderer/Model.h | 16 +++---- interface/src/ui/AnimationsDialog.cpp | 4 ++ interface/src/ui/AnimationsDialog.h | 2 + 6 files changed, 75 insertions(+), 46 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c8d1747505..b2a3ecbedb 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -714,14 +714,14 @@ glm::vec3 MyAvatar::getUprightHeadPosition() const { void MyAvatar::setJointData(int index, const glm::quat& rotation) { Avatar::setJointData(index, rotation); if (QThread::currentThread() == thread()) { - _skeletonModel.setJointState(index, true, rotation); + _skeletonModel.setJointState(index, true, rotation, 2.0f); } } void MyAvatar::clearJointData(int index) { Avatar::clearJointData(index); if (QThread::currentThread() == thread()) { - _skeletonModel.setJointState(index, false); + _skeletonModel.setJointState(index, false, glm::quat(), 2.0f); } } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 09871ad38b..429ab1cf30 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -21,6 +21,8 @@ SkeletonModel::SkeletonModel(Avatar* owningAvatar) : _owningAvatar(owningAvatar) { } +const float PALM_PRIORITY = 3.0f; + void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { setTranslation(_owningAvatar->getPosition()); setRotation(_owningAvatar->getOrientation() * glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f))); @@ -43,7 +45,7 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { } int jointIndex = geometry.humanIKJointIndices.at(humanIKJointIndex); if (jointIndex != -1) { - setJointRotation(jointIndex, _rotation * prioVR->getJointRotations().at(i), true); + setJointRotation(jointIndex, _rotation * prioVR->getJointRotations().at(i), true, PALM_PRIORITY); } } return; @@ -58,16 +60,16 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { if (leftPalmIndex == -1) { // palms are not yet set, use mouse if (_owningAvatar->getHandState() == HAND_STATE_NULL) { - restoreRightHandPosition(HAND_RESTORATION_RATE); + restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); } else { applyHandPosition(geometry.rightHandJointIndex, _owningAvatar->getHandPosition()); } - restoreLeftHandPosition(HAND_RESTORATION_RATE); + restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); } else if (leftPalmIndex == rightPalmIndex) { // right hand only applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[leftPalmIndex]); - restoreLeftHandPosition(HAND_RESTORATION_RATE); + restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); } else { applyPalmData(geometry.leftHandJointIndex, hand->getPalms()[leftPalmIndex]); @@ -132,7 +134,7 @@ void SkeletonModel::applyHandPosition(int jointIndex, const glm::vec3& position) if (jointIndex == -1) { return; } - setJointPosition(jointIndex, position); + setJointPosition(jointIndex, position, glm::quat(), false, -1, false, glm::vec3(0.0f, -1.0f, 0.0f), PALM_PRIORITY); const FBXGeometry& geometry = _geometry->getFBXGeometry(); glm::vec3 handPosition, elbowPosition; @@ -148,7 +150,8 @@ void SkeletonModel::applyHandPosition(int jointIndex, const glm::vec3& position) // align hand with forearm float sign = (jointIndex == geometry.rightHandJointIndex) ? 1.0f : -1.0f; - applyRotationDelta(jointIndex, rotationBetween(handRotation * glm::vec3(-sign, 0.0f, 0.0f), forearmVector)); + applyRotationDelta(jointIndex, rotationBetween(handRotation * glm::vec3(-sign, 0.0f, 0.0f), + forearmVector), true, PALM_PRIORITY); } void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) { @@ -183,12 +186,14 @@ void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) { } else if (Menu::getInstance()->isOptionChecked(MenuOption::AlignForearmsWithWrists)) { glm::vec3 forearmVector = palmRotation * glm::vec3(sign, 0.0f, 0.0f); setJointPosition(parentJointIndex, palm.getPosition() + forearmVector * - geometry.joints.at(jointIndex).distanceToParent * extractUniformScale(_scale)); - setJointRotation(parentJointIndex, palmRotation, true); + geometry.joints.at(jointIndex).distanceToParent * extractUniformScale(_scale), + glm::quat(), false, -1, false, glm::vec3(0.0f, -1.0f, 0.0f), PALM_PRIORITY); + setJointRotation(parentJointIndex, palmRotation, true, PALM_PRIORITY); _jointStates[jointIndex].rotation = glm::quat(); } else { - setJointPosition(jointIndex, palm.getPosition(), palmRotation, true); + setJointPosition(jointIndex, palm.getPosition(), palmRotation, + true, -1, false, glm::vec3(0.0f, -1.0f, 0.0f), PALM_PRIORITY); } } @@ -335,11 +340,11 @@ void SkeletonModel::setHandPosition(int jointIndex, const glm::vec3& position, c glm::vec3 forwardVector(rightHand ? -1.0f : 1.0f, 0.0f, 0.0f); glm::quat shoulderRotation = rotationBetween(forwardVector, elbowPosition - shoulderPosition); - setJointRotation(shoulderJointIndex, shoulderRotation, true); + setJointRotation(shoulderJointIndex, shoulderRotation, true, PALM_PRIORITY); setJointRotation(elbowJointIndex, rotationBetween(shoulderRotation * forwardVector, - wristPosition - elbowPosition) * shoulderRotation, true); + wristPosition - elbowPosition) * shoulderRotation, true, PALM_PRIORITY); - setJointRotation(jointIndex, rotation, true); + setJointRotation(jointIndex, rotation, true, PALM_PRIORITY); } diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 5d0f571b5b..db7e0a7c6d 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -118,7 +118,7 @@ QVector Model::createJointStates(const FBXGeometry& geometry) JointState state; state.translation = joint.translation; state.rotation = joint.rotation; - state.animationDisabled = false; + state.animationPriority = 0.0f; jointStates.append(state); } @@ -473,9 +473,18 @@ bool Model::getJointState(int index, glm::quat& rotation) const { glm::abs(rotation.w - defaultRotation.w) >= EPSILON; } -void Model::setJointState(int index, bool valid, const glm::quat& rotation) { +void Model::setJointState(int index, bool valid, const glm::quat& rotation, float priority) { if (index != -1 && index < _jointStates.size()) { - _jointStates[index].rotation = valid ? rotation : _geometry->getFBXGeometry().joints.at(index).rotation; + JointState& state = _jointStates[index]; + if (priority >= state.animationPriority) { + if (valid) { + state.rotation = rotation; + state.animationPriority = priority; + } else if (priority == state.animationPriority) { + state.rotation = _geometry->getFBXGeometry().joints.at(index).rotation; + state.animationPriority = 0.0f; + } + } } } @@ -535,8 +544,8 @@ bool Model::getRightHandRotation(glm::quat& rotation) const { return getJointRotation(getRightHandJointIndex(), rotation); } -bool Model::restoreLeftHandPosition(float percent) { - return restoreJointPosition(getLeftHandJointIndex(), percent); +bool Model::restoreLeftHandPosition(float percent, float priority) { + return restoreJointPosition(getLeftHandJointIndex(), percent, priority); } bool Model::getLeftShoulderPosition(glm::vec3& position) const { @@ -547,8 +556,8 @@ float Model::getLeftArmLength() const { return getLimbLength(getLeftHandJointIndex()); } -bool Model::restoreRightHandPosition(float percent) { - return restoreJointPosition(getRightHandJointIndex(), percent); +bool Model::restoreRightHandPosition(float percent, float priority) { + return restoreJointPosition(getRightHandJointIndex(), percent, priority); } bool Model::getRightShoulderPosition(glm::vec3& position) const { @@ -1115,7 +1124,7 @@ void Model::maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint } bool Model::setJointPosition(int jointIndex, const glm::vec3& translation, const glm::quat& rotation, bool useRotation, - int lastFreeIndex, bool allIntermediatesFree, const glm::vec3& alignment) { + int lastFreeIndex, bool allIntermediatesFree, const glm::vec3& alignment, float priority) { if (jointIndex == -1 || _jointStates.isEmpty()) { return false; } @@ -1138,7 +1147,7 @@ bool Model::setJointPosition(int jointIndex, const glm::vec3& translation, const glm::quat endRotation; if (useRotation) { getJointRotation(jointIndex, endRotation, true); - applyRotationDelta(jointIndex, rotation * glm::inverse(endRotation)); + applyRotationDelta(jointIndex, rotation * glm::inverse(endRotation), priority); getJointRotation(jointIndex, endRotation, true); } @@ -1182,7 +1191,7 @@ bool Model::setJointPosition(int jointIndex, const glm::vec3& translation, const 1.0f / (combinedWeight + 1.0f)); } } - applyRotationDelta(index, combinedDelta); + applyRotationDelta(index, combinedDelta, priority); glm::quat actualDelta = state.combinedRotation * glm::inverse(oldCombinedRotation); endPosition = actualDelta * jointVector + jointPosition; if (useRotation) { @@ -1200,15 +1209,17 @@ bool Model::setJointPosition(int jointIndex, const glm::vec3& translation, const return true; } -bool Model::setJointRotation(int jointIndex, const glm::quat& rotation, bool fromBind) { +bool Model::setJointRotation(int jointIndex, const glm::quat& rotation, bool fromBind, float priority) { if (jointIndex == -1 || _jointStates.isEmpty()) { return false; } JointState& state = _jointStates[jointIndex]; - state.rotation = state.rotation * glm::inverse(state.combinedRotation) * rotation * - glm::inverse(fromBind ? _geometry->getFBXGeometry().joints.at(jointIndex).inverseBindRotation : - _geometry->getFBXGeometry().joints.at(jointIndex).inverseDefaultRotation); - state.animationDisabled = true; + if (priority >= state.animationPriority) { + state.rotation = state.rotation * glm::inverse(state.combinedRotation) * rotation * + glm::inverse(fromBind ? _geometry->getFBXGeometry().joints.at(jointIndex).inverseBindRotation : + _geometry->getFBXGeometry().joints.at(jointIndex).inverseDefaultRotation); + state.animationPriority = priority; + } return true; } @@ -1229,7 +1240,7 @@ void Model::setJointTranslation(int jointIndex, const glm::vec3& translation) { state.translation = glm::vec3(glm::inverse(parentTransform) * glm::vec4(translation, 1.0f)) - preTranslation; } -bool Model::restoreJointPosition(int jointIndex, float percent) { +bool Model::restoreJointPosition(int jointIndex, float percent, float priority) { if (jointIndex == -1 || _jointStates.isEmpty()) { return false; } @@ -1238,10 +1249,12 @@ bool Model::restoreJointPosition(int jointIndex, float percent) { foreach (int index, freeLineage) { JointState& state = _jointStates[index]; - const FBXJoint& joint = geometry.joints.at(index); - state.rotation = safeMix(state.rotation, joint.rotation, percent); - state.translation = glm::mix(state.translation, joint.translation, percent); - state.animationDisabled = false; + if (priority == state.animationPriority) { + const FBXJoint& joint = geometry.joints.at(index); + state.rotation = safeMix(state.rotation, joint.rotation, percent); + state.translation = glm::mix(state.translation, joint.translation, percent); + state.animationPriority = 0.0f; + } } return true; } @@ -1260,8 +1273,12 @@ float Model::getLimbLength(int jointIndex) const { return length; } -void Model::applyRotationDelta(int jointIndex, const glm::quat& delta, bool constrain) { +void Model::applyRotationDelta(int jointIndex, const glm::quat& delta, bool constrain, float priority) { JointState& state = _jointStates[jointIndex]; + if (priority < state.animationPriority) { + return; + } + state.animationPriority = priority; const FBXJoint& joint = _geometry->getFBXGeometry().joints[jointIndex]; if (!constrain || (joint.rotationMin == glm::vec3(-PI, -PI, -PI) && joint.rotationMax == glm::vec3(PI, PI, PI))) { @@ -1275,7 +1292,6 @@ void Model::applyRotationDelta(int jointIndex, const glm::quat& delta, bool cons glm::quat newRotation = glm::quat(glm::clamp(eulers, joint.rotationMin, joint.rotationMax)); state.combinedRotation = state.combinedRotation * glm::inverse(state.rotation) * newRotation; state.rotation = newRotation; - state.animationDisabled = true; } const int BALL_SUBDIVISIONS = 10; @@ -1749,8 +1765,9 @@ void AnimationHandle::simulate(float deltaTime) { int mapping = _jointMappings.at(i); if (mapping != -1) { Model::JointState& state = _model->_jointStates[mapping]; - if (!state.animationDisabled) { + if (_priority >= state.animationPriority) { state.rotation = frame.rotations.at(i); + state.animationPriority = _priority; } } } @@ -1772,8 +1789,9 @@ void AnimationHandle::simulate(float deltaTime) { int mapping = _jointMappings.at(i); if (mapping != -1) { Model::JointState& state = _model->_jointStates[mapping]; - if (!state.animationDisabled) { + if (_priority >= state.animationPriority) { state.rotation = safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction); + state.animationPriority = _priority; } } } diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 979dc6c601..23bde4846b 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -113,7 +113,7 @@ public: bool getJointState(int index, glm::quat& rotation) const; /// Sets the joint state at the specified index. - void setJointState(int index, bool valid, const glm::quat& rotation = glm::quat()); + void setJointState(int index, bool valid, const glm::quat& rotation = glm::quat(), float priority = 1.0f); /// Returns the index of the left hand joint, or -1 if not found. int getLeftHandJointIndex() const { return isActive() ? _geometry->getFBXGeometry().leftHandJointIndex : -1; } @@ -166,7 +166,7 @@ public: /// Restores some percentage of the default position of the left hand. /// \param percent the percentage of the default position to restore /// \return whether or not the left hand joint was found - bool restoreLeftHandPosition(float percent = 1.0f); + bool restoreLeftHandPosition(float percent = 1.0f, float priority = 1.0f); /// Gets the position of the left shoulder. /// \return whether or not the left shoulder joint was found @@ -178,7 +178,7 @@ public: /// Restores some percentage of the default position of the right hand. /// \param percent the percentage of the default position to restore /// \return whether or not the right hand joint was found - bool restoreRightHandPosition(float percent = 1.0f); + bool restoreRightHandPosition(float percent = 1.0f, float priority = 1.0f); /// Gets the position of the right shoulder. /// \return whether or not the right shoulder joint was found @@ -254,7 +254,7 @@ protected: glm::quat rotation; // rotation relative to parent glm::mat4 transform; // rotation to world frame + translation in model frame glm::quat combinedRotation; // rotation from joint local to world frame - bool animationDisabled; // if true, animations do not affect this joint + float animationPriority; // the priority of the animation affecting this joint }; bool _shapesAreDirty; @@ -290,8 +290,8 @@ protected: bool setJointPosition(int jointIndex, const glm::vec3& translation, const glm::quat& rotation = glm::quat(), bool useRotation = false, int lastFreeIndex = -1, bool allIntermediatesFree = false, - const glm::vec3& alignment = glm::vec3(0.0f, -1.0f, 0.0f)); - bool setJointRotation(int jointIndex, const glm::quat& rotation, bool fromBind = false); + const glm::vec3& alignment = glm::vec3(0.0f, -1.0f, 0.0f), float priority = 1.0f); + bool setJointRotation(int jointIndex, const glm::quat& rotation, bool fromBind = false, float priority = 1.0f); void setJointTranslation(int jointIndex, const glm::vec3& translation); @@ -299,13 +299,13 @@ protected: /// \param percent the percentage of the default position to apply (i.e., 0.25f to slerp one fourth of the way to /// the original position /// \return true if the joint was found - bool restoreJointPosition(int jointIndex, float percent = 1.0f); + bool restoreJointPosition(int jointIndex, float percent = 1.0f, float priority = 0.0f); /// Computes and returns the extended length of the limb terminating at the specified joint and starting at the joint's /// first free ancestor. float getLimbLength(int jointIndex) const; - void applyRotationDelta(int jointIndex, const glm::quat& delta, bool constrain = true); + void applyRotationDelta(int jointIndex, const glm::quat& delta, bool constrain = true, float priority = 1.0f); void computeBoundingShape(const FBXGeometry& geometry); diff --git a/interface/src/ui/AnimationsDialog.cpp b/interface/src/ui/AnimationsDialog.cpp index f30c98cce7..205a215b10 100644 --- a/interface/src/ui/AnimationsDialog.cpp +++ b/interface/src/ui/AnimationsDialog.cpp @@ -10,6 +10,7 @@ // #include +#include #include #include #include @@ -80,6 +81,9 @@ AnimationPanel::AnimationPanel(AnimationsDialog* dialog, const AnimationHandlePo layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); setLayout(layout); + layout->addRow("Role:", _role = new QComboBox()); + _role->setEditable(true); + QHBoxLayout* urlBox = new QHBoxLayout(); layout->addRow("URL:", urlBox); urlBox->addWidget(_url = new QLineEdit(handle->getURL().toString()), 1); diff --git a/interface/src/ui/AnimationsDialog.h b/interface/src/ui/AnimationsDialog.h index 8b0f6cd257..edda665d10 100644 --- a/interface/src/ui/AnimationsDialog.h +++ b/interface/src/ui/AnimationsDialog.h @@ -18,6 +18,7 @@ #include "avatar/MyAvatar.h" class QCheckBox; +class QComboBox; class QDoubleSpinner; class QLineEdit; class QPushButton; @@ -63,6 +64,7 @@ private: AnimationsDialog* _dialog; AnimationHandlePointer _handle; + QComboBox* _role; QLineEdit* _url; QDoubleSpinBox* _fps; QDoubleSpinBox* _priority; From 79f09605d561a342371f857b4fb66d249f017bbb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 22 May 2014 14:55:43 -0700 Subject: [PATCH 18/49] show credit balance in window title --- interface/src/Application.cpp | 26 ++++++++++++++++--- libraries/networking/src/AccountManager.cpp | 20 ++++++++++++++ libraries/networking/src/AccountManager.h | 5 +++- .../networking/src/DataServerAccountInfo.cpp | 20 +++++++++++++- .../networking/src/DataServerAccountInfo.h | 9 +++++++ 5 files changed, 75 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index fd09e530c1..c6704bcd80 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -237,12 +237,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : connect(&nodeList->getDomainHandler(), SIGNAL(connectedToDomain(const QString&)), SLOT(connectedToDomain(const QString&))); // update our location every 5 seconds in the data-server, assuming that we are authenticated with one - const float DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS = 5.0f * 1000.0f; + const qint64 DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS = 5 * 1000; QTimer* locationUpdateTimer = new QTimer(this); connect(locationUpdateTimer, &QTimer::timeout, this, &Application::updateLocationInServer); locationUpdateTimer->start(DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS); - + connect(nodeList, &NodeList::nodeAdded, this, &Application::nodeAdded); connect(nodeList, &NodeList::nodeKilled, this, &Application::nodeKilled); connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer))); @@ -251,9 +251,18 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : connect(nodeList, &NodeList::uuidChanged, this, &Application::updateWindowTitle); connect(nodeList, SIGNAL(uuidChanged(const QUuid&)), _myAvatar, SLOT(setSessionUUID(const QUuid&))); connect(nodeList, &NodeList::limitOfSilentDomainCheckInsReached, nodeList, &NodeList::reset); - + // connect to appropriate slots on AccountManager AccountManager& accountManager = AccountManager::getInstance(); + + const qint64 BALANCE_UPDATE_INTERVAL_MSECS = 5 * 1000; + + QTimer* balanceUpdateTimer = new QTimer(this); + connect(balanceUpdateTimer, &QTimer::timeout, &accountManager, &AccountManager::updateBalance); + balanceUpdateTimer->start(BALANCE_UPDATE_INTERVAL_MSECS); + + connect(&accountManager, &AccountManager::balanceChanged, this, &Application::updateWindowTitle); + connect(&accountManager, &AccountManager::authRequired, Menu::getInstance(), &Menu::loginForCurrentDomain); connect(&accountManager, &AccountManager::usernameChanged, this, &Application::updateWindowTitle); @@ -3095,6 +3104,17 @@ void Application::updateWindowTitle(){ QString title = QString() + (!username.isEmpty() ? username + " @ " : QString()) + nodeList->getDomainHandler().getHostname() + buildVersion; qDebug("Application title set to: %s", title.toStdString().c_str()); + + AccountManager& accountManager = AccountManager::getInstance(); + if (accountManager.getAccountInfo().hasBalance()) { + float creditBalance = accountManager.getAccountInfo().getBalance() * pow(10.0f, -8.0f); + + QString creditBalanceString; + creditBalanceString.sprintf("%.8f", creditBalance); + + title += " - ₵" + creditBalanceString; + } + _window->setWindowTitle(title); } diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index aad2cfb386..7d27332a57 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -61,6 +61,8 @@ AccountManager::AccountManager() : qRegisterMetaType("QNetworkAccessManager::Operation"); qRegisterMetaType("JSONCallbackParameters"); + + connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged); } const QString DOUBLE_SLASH_SUBSTITUTE = "slashslash"; @@ -69,6 +71,9 @@ void AccountManager::logout() { // a logout means we want to delete the DataServerAccountInfo we currently have for this URL, in-memory and in file _accountInfo = DataServerAccountInfo(); + emit balanceChanged(0); + connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged); + QSettings settings; settings.beginGroup(ACCOUNTS_GROUP); @@ -82,6 +87,21 @@ void AccountManager::logout() { emit usernameChanged(QString()); } +void AccountManager::updateBalance() { + if (hasValidAccessToken()) { + // ask our auth endpoint for our balance + JSONCallbackParameters callbackParameters; + callbackParameters.jsonCallbackReceiver = &_accountInfo; + callbackParameters.jsonCallbackMethod = "setBalanceFromJSON"; + + authenticatedRequest("/api/v1/wallets/mine", QNetworkAccessManager::GetOperation, callbackParameters); + } +} + +void AccountManager::accountInfoBalanceChanged(qint64 newBalance) { + emit balanceChanged(newBalance); +} + void AccountManager::setAuthURL(const QUrl& authURL) { if (_authURL != authURL) { _authURL = authURL; diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index 6bdf5d76d8..f32ff75f51 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -34,7 +34,7 @@ public: QString updateSlot; }; -class AccountManager : public QObject { +class AccountManager: public QObject { Q_OBJECT public: static AccountManager& getInstance(); @@ -63,6 +63,8 @@ public slots: void requestFinished(); void requestError(QNetworkReply::NetworkError error); void logout(); + void updateBalance(); + void accountInfoBalanceChanged(qint64 newBalance); signals: void authRequired(); void authEndpointChanged(); @@ -71,6 +73,7 @@ signals: void loginComplete(const QUrl& authURL); void loginFailed(); void logoutComplete(); + void balanceChanged(qint64 newBalance); private slots: void processReply(); private: diff --git a/libraries/networking/src/DataServerAccountInfo.cpp b/libraries/networking/src/DataServerAccountInfo.cpp index 0fdb5ff4b1..ac664bca7c 100644 --- a/libraries/networking/src/DataServerAccountInfo.cpp +++ b/libraries/networking/src/DataServerAccountInfo.cpp @@ -17,7 +17,9 @@ DataServerAccountInfo::DataServerAccountInfo() : _accessToken(), _username(), _xmppPassword(), - _discourseApiKey() + _discourseApiKey(), + _balance(0), + _hasBalance(false) { } @@ -75,6 +77,22 @@ void DataServerAccountInfo::setDiscourseApiKey(const QString& discourseApiKey) { } } +void DataServerAccountInfo::setBalance(quint64 balance) { + if (!_hasBalance || _balance != balance) { + _balance = balance; + _hasBalance = true; + + emit balanceChanged(_balance); + } +} + +void DataServerAccountInfo::setBalanceFromJSON(const QJsonObject& jsonObject) { + if (jsonObject["status"].toString() == "success") { + qint64 balanceInSatoshis = jsonObject["data"].toObject()["wallet"].toObject()["balance"].toInt(); + setBalance(balanceInSatoshis); + } +} + QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info) { out << info._accessToken << info._username << info._xmppPassword << info._discourseApiKey; return out; diff --git a/libraries/networking/src/DataServerAccountInfo.h b/libraries/networking/src/DataServerAccountInfo.h index a7d1fa9cb0..f3fe2401fe 100644 --- a/libraries/networking/src/DataServerAccountInfo.h +++ b/libraries/networking/src/DataServerAccountInfo.h @@ -34,9 +34,16 @@ public: const QString& getDiscourseApiKey() const { return _discourseApiKey; } void setDiscourseApiKey(const QString& discourseApiKey); + + quint64 getBalance() const { return _balance; } + void setBalance(quint64 balance); + bool hasBalance() const { return _hasBalance; } + Q_INVOKABLE void setBalanceFromJSON(const QJsonObject& jsonObject); friend QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info); friend QDataStream& operator>>(QDataStream &in, DataServerAccountInfo& info); +signals: + qint64 balanceChanged(qint64 newBalance); private: void swap(DataServerAccountInfo& otherInfo); @@ -44,6 +51,8 @@ private: QString _username; QString _xmppPassword; QString _discourseApiKey; + quint64 _balance; + bool _hasBalance; }; #endif // hifi_DataServerAccountInfo_h From 083543419d411110027545e9c269c8b7a3ae9b98 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 22 May 2014 15:00:36 -0700 Subject: [PATCH 19/49] More priority bits. --- interface/src/avatar/MyAvatar.cpp | 6 ++++-- interface/src/renderer/Model.cpp | 11 ++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index b2a3ecbedb..06f36afe52 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -711,17 +711,19 @@ glm::vec3 MyAvatar::getUprightHeadPosition() const { return _position + getWorldAlignedOrientation() * glm::vec3(0.0f, getPelvisToHeadLength(), 0.0f); } +const float JOINT_PRIORITY = 2.0f; + void MyAvatar::setJointData(int index, const glm::quat& rotation) { Avatar::setJointData(index, rotation); if (QThread::currentThread() == thread()) { - _skeletonModel.setJointState(index, true, rotation, 2.0f); + _skeletonModel.setJointState(index, true, rotation, JOINT_PRIORITY); } } void MyAvatar::clearJointData(int index) { Avatar::clearJointData(index); if (QThread::currentThread() == thread()) { - _skeletonModel.setJointState(index, false, glm::quat(), 2.0f); + _skeletonModel.setJointState(index, false, glm::quat(), JOINT_PRIORITY); } } diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 835c8fd901..636f66fa16 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1681,7 +1681,7 @@ void AnimationHandle::setURL(const QUrl& url) { static void insertSorted(QList& handles, const AnimationHandlePointer& handle) { for (QList::iterator it = handles.begin(); it != handles.end(); it++) { - if (handle->getPriority() < (*it)->getPriority()) { + if (handle->getPriority() > (*it)->getPriority()) { handles.insert(it, handle); return; } @@ -1713,6 +1713,15 @@ void AnimationHandle::setRunning(bool running) { } else { _model->_runningAnimations.removeOne(_self); + for (int i = 0; i < _jointMappings.size(); i++) { + int mapping = _jointMappings.at(i); + if (mapping != -1) { + Model::JointState& state = _model->_jointStates[mapping]; + if (_priority == state.animationPriority) { + state.animationPriority = 0.0f; + } + } + } } } From 164d3c5fb3aea2ff3c523efc19260ebb569115b9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 22 May 2014 15:06:16 -0700 Subject: [PATCH 20/49] make sure balance is cleared on logout and re-launch --- interface/src/Application.cpp | 2 +- libraries/networking/src/DataServerAccountInfo.cpp | 8 +++++++- libraries/networking/src/DataServerAccountInfo.h | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c6704bcd80..07309fab85 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3103,7 +3103,6 @@ void Application::updateWindowTitle(){ QString username = AccountManager::getInstance().getAccountInfo().getUsername(); QString title = QString() + (!username.isEmpty() ? username + " @ " : QString()) + nodeList->getDomainHandler().getHostname() + buildVersion; - qDebug("Application title set to: %s", title.toStdString().c_str()); AccountManager& accountManager = AccountManager::getInstance(); if (accountManager.getAccountInfo().hasBalance()) { @@ -3115,6 +3114,7 @@ void Application::updateWindowTitle(){ title += " - ₵" + creditBalanceString; } + qDebug("Application title set to: %s", title.toStdString().c_str()); _window->setWindowTitle(title); } diff --git a/libraries/networking/src/DataServerAccountInfo.cpp b/libraries/networking/src/DataServerAccountInfo.cpp index ac664bca7c..b3607200fe 100644 --- a/libraries/networking/src/DataServerAccountInfo.cpp +++ b/libraries/networking/src/DataServerAccountInfo.cpp @@ -27,7 +27,9 @@ DataServerAccountInfo::DataServerAccountInfo() : DataServerAccountInfo::DataServerAccountInfo(const QJsonObject& jsonObject) : _accessToken(jsonObject), _username(), - _xmppPassword() + _xmppPassword(), + _balance(0), + _hasBalance(false) { QJsonObject userJSONObject = jsonObject["user"].toObject(); setUsername(userJSONObject["username"].toString()); @@ -40,6 +42,8 @@ DataServerAccountInfo::DataServerAccountInfo(const DataServerAccountInfo& otherI _username = otherInfo._username; _xmppPassword = otherInfo._xmppPassword; _discourseApiKey = otherInfo._discourseApiKey; + _balance = otherInfo._balance; + _hasBalance = otherInfo._hasBalance; } DataServerAccountInfo& DataServerAccountInfo::operator=(const DataServerAccountInfo& otherInfo) { @@ -55,6 +59,8 @@ void DataServerAccountInfo::swap(DataServerAccountInfo& otherInfo) { swap(_username, otherInfo._username); swap(_xmppPassword, otherInfo._xmppPassword); swap(_discourseApiKey, otherInfo._discourseApiKey); + swap(_balance, otherInfo._balance); + swap(_hasBalance, otherInfo._hasBalance); } void DataServerAccountInfo::setUsername(const QString& username) { diff --git a/libraries/networking/src/DataServerAccountInfo.h b/libraries/networking/src/DataServerAccountInfo.h index f3fe2401fe..fd135f922b 100644 --- a/libraries/networking/src/DataServerAccountInfo.h +++ b/libraries/networking/src/DataServerAccountInfo.h @@ -38,6 +38,7 @@ public: quint64 getBalance() const { return _balance; } void setBalance(quint64 balance); bool hasBalance() const { return _hasBalance; } + void setHasBalance(bool hasBalance) { _hasBalance = hasBalance; } Q_INVOKABLE void setBalanceFromJSON(const QJsonObject& jsonObject); friend QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info); From 40c59a35890eba2c7b3424f81d667dd0fce0aa2f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 22 May 2014 15:10:41 -0700 Subject: [PATCH 21/49] fix rate of payment for assignments --- domain-server/src/DomainServer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 9ad36e6956..20e34744db 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -731,10 +731,11 @@ void DomainServer::setupPendingAssignmentCredits() { qint64 elapsedMsecsSinceLastPayment = nodeData->getPaymentIntervalTimer().elapsed(); nodeData->getPaymentIntervalTimer().restart(); - const float CREDITS_PER_HOUR = 3; + const float CREDITS_PER_HOUR = 0.10; const float CREDITS_PER_MSEC = CREDITS_PER_HOUR / (60 * 60 * 1000); + const int SATOSHIS_PER_MSEC = CREDITS_PER_MSEC * powf(10, 8); - float pendingCredits = elapsedMsecsSinceLastPayment * CREDITS_PER_MSEC; + float pendingCredits = elapsedMsecsSinceLastPayment * SATOSHIS_PER_MSEC; if (existingTransaction) { existingTransaction->incrementAmount(pendingCredits); From fc9d850c40399bcdf20e6fcbcc6a24357dda83c1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 22 May 2014 15:33:06 -0700 Subject: [PATCH 22/49] output when pay-for-assignments is on --- domain-server/src/DomainServer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 20e34744db..cd8e66a2b5 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -218,6 +218,8 @@ bool DomainServer::optionallySetupAssignmentPayment() { } } + qDebug() << "Assignments will be paid for via" << qPrintable(_oauthProviderURL.toString()); + // assume that the fact we are authing against HF data server means we will pay for assignments // setup a timer to send transactions to pay assigned nodes every 30 seconds QTimer* creditSetupTimer = new QTimer(this); From 8458477b9f7d47d4b2dd2ca806e5c265b648cf89 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 22 May 2014 16:15:34 -0700 Subject: [PATCH 23/49] Fixed a compile warning, provide means to start/stop animations. --- interface/src/AudioReflector.cpp | 2 +- interface/src/avatar/MyAvatar.cpp | 6 ++++-- interface/src/renderer/Model.cpp | 19 +++++++++++++++-- interface/src/renderer/Model.h | 18 ++++++++++++++-- interface/src/ui/AnimationsDialog.cpp | 30 ++++++++++++++++++++++----- interface/src/ui/AnimationsDialog.h | 4 ++++ 6 files changed, 67 insertions(+), 12 deletions(-) diff --git a/interface/src/AudioReflector.cpp b/interface/src/AudioReflector.cpp index e66735c403..52d23b4fee 100644 --- a/interface/src/AudioReflector.cpp +++ b/interface/src/AudioReflector.cpp @@ -17,7 +17,7 @@ const float MINIMUM_ATTENUATION_TO_REFLECT = 1.0f / 256.0f; const float DEFAULT_DISTANCE_SCALING_FACTOR = 2.0f; const float MAXIMUM_DELAY_MS = 1000.0 * 20.0f; // stop reflecting after path is this long const int DEFAULT_DIFFUSION_FANOUT = 5; -const int ABSOLUTE_MAXIMUM_BOUNCE_COUNT = 10; +const unsigned int ABSOLUTE_MAXIMUM_BOUNCE_COUNT = 10; const float DEFAULT_LOCAL_ATTENUATION_FACTOR = 0.125; const float DEFAULT_COMB_FILTER_WINDOW = 0.05f; //ms delay differential to avoid diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 06f36afe52..25eb071c8a 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -430,8 +430,6 @@ void MyAvatar::setGravity(const glm::vec3& gravity) { AnimationHandlePointer MyAvatar::addAnimationHandle() { AnimationHandlePointer handle = _skeletonModel.createAnimationHandle(); - handle->setLoop(true); - handle->start(); _animationHandles.append(handle); return handle; } @@ -516,11 +514,13 @@ void MyAvatar::saveData(QSettings* settings) { for (int i = 0; i < _animationHandles.size(); i++) { settings->setArrayIndex(i); const AnimationHandlePointer& pointer = _animationHandles.at(i); + settings->setValue("role", pointer->getRole()); settings->setValue("url", pointer->getURL()); settings->setValue("fps", pointer->getFPS()); settings->setValue("priority", pointer->getPriority()); settings->setValue("loop", pointer->getLoop()); settings->setValue("hold", pointer->getHold()); + settings->setValue("startAutomatically", pointer->getStartAutomatically()); settings->setValue("firstFrame", pointer->getFirstFrame()); settings->setValue("lastFrame", pointer->getLastFrame()); settings->setValue("maskedJoints", pointer->getMaskedJoints()); @@ -587,11 +587,13 @@ void MyAvatar::loadData(QSettings* settings) { for (int i = 0; i < animationCount; i++) { settings->setArrayIndex(i); const AnimationHandlePointer& handle = _animationHandles.at(i); + handle->setRole(settings->value("role", "idle").toString()); handle->setURL(settings->value("url").toUrl()); handle->setFPS(loadSetting(settings, "fps", 30.0f)); handle->setPriority(loadSetting(settings, "priority", 1.0f)); handle->setLoop(settings->value("loop", true).toBool()); handle->setHold(settings->value("hold", false).toBool()); + handle->setStartAutomatically(settings->value("startAutomatically", true).toBool()); handle->setFirstFrame(settings->value("firstFrame", 0).toInt()); handle->setLastFrame(settings->value("lastFrame", INT_MAX).toInt()); handle->setMaskedJoints(settings->value("maskedJoints").toStringList()); diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 636f66fa16..3005921d39 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1699,12 +1699,25 @@ void AnimationHandle::setPriority(float priority) { } } +void AnimationHandle::setStartAutomatically(bool startAutomatically) { + if ((_startAutomatically = startAutomatically) && !_running) { + start(); + } +} + void AnimationHandle::setMaskedJoints(const QStringList& maskedJoints) { _maskedJoints = maskedJoints; _jointMappings.clear(); } void AnimationHandle::setRunning(bool running) { + if (_running == running) { + if (running) { + // move back to the beginning + _frameIndex = _firstFrame; + } + return; + } if ((_running = running)) { if (!_model->_runningAnimations.contains(_self)) { insertSorted(_model->_runningAnimations, _self); @@ -1723,6 +1736,7 @@ void AnimationHandle::setRunning(bool running) { } } } + emit runningChanged(_running); } AnimationHandle::AnimationHandle(Model* model) : @@ -1730,10 +1744,11 @@ AnimationHandle::AnimationHandle(Model* model) : _model(model), _fps(30.0f), _priority(1.0f), - _firstFrame(0), - _lastFrame(INT_MAX), _loop(false), _hold(false), + _startAutomatically(false), + _firstFrame(0), + _lastFrame(INT_MAX), _running(false) { } diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 23bde4846b..a0806ee238 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -381,6 +381,9 @@ class AnimationHandle : public QObject { public: + void setRole(const QString& role) { _role = role; } + const QString& getRole() const { return _role; } + void setURL(const QUrl& url); const QUrl& getURL() const { return _url; } @@ -396,6 +399,9 @@ public: void setHold(bool hold) { _hold = hold; } bool getHold() const { return _hold; } + void setStartAutomatically(bool startAutomatically); + bool getStartAutomatically() const { return _startAutomatically; } + void setFirstFrame(int firstFrame) { _firstFrame = firstFrame; } int getFirstFrame() const { return _firstFrame; } @@ -407,7 +413,13 @@ public: void setRunning(bool running); bool isRunning() const { return _running; } + +signals: + void runningChanged(bool running); + +public slots: + void start() { setRunning(true); } void stop() { setRunning(false); } @@ -422,13 +434,15 @@ private: Model* _model; WeakAnimationHandlePointer _self; AnimationPointer _animation; + QString _role; QUrl _url; float _fps; float _priority; - int _firstFrame; - int _lastFrame; bool _loop; bool _hold; + bool _startAutomatically; + int _firstFrame; + int _lastFrame; QStringList _maskedJoints; bool _running; QVector _jointMappings; diff --git a/interface/src/ui/AnimationsDialog.cpp b/interface/src/ui/AnimationsDialog.cpp index 205a215b10..9f62abc270 100644 --- a/interface/src/ui/AnimationsDialog.cpp +++ b/interface/src/ui/AnimationsDialog.cpp @@ -82,7 +82,11 @@ AnimationPanel::AnimationPanel(AnimationsDialog* dialog, const AnimationHandlePo setLayout(layout); layout->addRow("Role:", _role = new QComboBox()); + _role->addItem("idle"); + _role->addItem("sit"); _role->setEditable(true); + _role->setCurrentText(handle->getRole()); + connect(_role, SIGNAL(currentTextChanged(const QString&)), SLOT(updateHandle())); QHBoxLayout* urlBox = new QHBoxLayout(); layout->addRow("URL:", urlBox); @@ -120,6 +124,10 @@ AnimationPanel::AnimationPanel(AnimationsDialog* dialog, const AnimationHandlePo _hold->setChecked(handle->getHold()); connect(_hold, SIGNAL(toggled(bool)), SLOT(updateHandle())); + layout->addRow("Start Automatically:", _startAutomatically = new QCheckBox()); + _startAutomatically->setChecked(handle->getStartAutomatically()); + connect(_startAutomatically, SIGNAL(toggled(bool)), SLOT(updateHandle())); + layout->addRow("First Frame:", _firstFrame = new QSpinBox()); _firstFrame->setMaximum(INT_MAX); _firstFrame->setValue(handle->getFirstFrame()); @@ -130,9 +138,18 @@ AnimationPanel::AnimationPanel(AnimationsDialog* dialog, const AnimationHandlePo _lastFrame->setValue(handle->getLastFrame()); connect(_lastFrame, SIGNAL(valueChanged(int)), SLOT(updateHandle())); + QHBoxLayout* buttons = new QHBoxLayout(); + layout->addRow(buttons); + buttons->addWidget(_start = new QPushButton("Start")); + _handle->connect(_start, SIGNAL(clicked(bool)), SLOT(start())); + buttons->addWidget(_stop = new QPushButton("Stop")); + _handle->connect(_stop, SIGNAL(clicked(bool)), SLOT(stop())); QPushButton* remove = new QPushButton("Delete"); - layout->addRow(remove); + buttons->addWidget(remove); connect(remove, SIGNAL(clicked(bool)), SLOT(removeHandle())); + + connect(_handle.data(), SIGNAL(runningChanged(bool)), SLOT(updateStartStop())); + updateStartStop(); } void AnimationPanel::chooseURL() { @@ -168,19 +185,22 @@ void AnimationPanel::chooseMaskedJoints() { } } +void AnimationPanel::updateStartStop() { + _start->setEnabled(!_handle->isRunning()); + _stop->setEnabled(_handle->isRunning()); +} + void AnimationPanel::updateHandle() { + _handle->setRole(_role->currentText()); _handle->setURL(_url->text()); _handle->setFPS(_fps->value()); _handle->setPriority(_priority->value()); _handle->setLoop(_loop->isChecked()); _handle->setHold(_hold->isChecked()); + _handle->setStartAutomatically(_startAutomatically->isChecked()); _handle->setFirstFrame(_firstFrame->value()); _handle->setLastFrame(_lastFrame->value()); _handle->setMaskedJoints(_maskedJoints->text().split(QRegExp("\\s*,\\s*"))); - - if ((_loop->isChecked() || _hold->isChecked()) && !_handle->isRunning()) { - _handle->start(); - } } void AnimationPanel::removeHandle() { diff --git a/interface/src/ui/AnimationsDialog.h b/interface/src/ui/AnimationsDialog.h index edda665d10..6f7a2f3784 100644 --- a/interface/src/ui/AnimationsDialog.h +++ b/interface/src/ui/AnimationsDialog.h @@ -57,6 +57,7 @@ private slots: void chooseURL(); void chooseMaskedJoints(); + void updateStartStop(); void updateHandle(); void removeHandle(); @@ -70,10 +71,13 @@ private: QDoubleSpinBox* _priority; QCheckBox* _loop; QCheckBox* _hold; + QCheckBox* _startAutomatically; QSpinBox* _firstFrame; QSpinBox* _lastFrame; QLineEdit* _maskedJoints; QPushButton* _chooseMaskedJoints; + QPushButton* _start; + QPushButton* _stop; bool _applying; }; From 2a50b5451f56c4c6ff2fc5d121d56471453599fe Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 22 May 2014 16:41:51 -0700 Subject: [PATCH 24/49] Script commands to start/stop animations by role. --- interface/src/avatar/MyAvatar.cpp | 42 ++++++++++++++++++++++++++++++- interface/src/avatar/MyAvatar.h | 9 +++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 25eb071c8a..042d2cdc7c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -459,6 +459,47 @@ void MyAvatar::startAnimation(const QString& url, float fps, float priority, handle->start(); } +void MyAvatar::startAnimationByRole(const QString& role, const QString& url, float fps, float priority, + bool loop, bool hold, int firstFrame, int lastFrame, const QStringList& maskedJoints) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "startAnimationByRole", Q_ARG(const QString&, role), Q_ARG(const QString&, url), + Q_ARG(float, fps), Q_ARG(float, priority), Q_ARG(bool, loop), Q_ARG(bool, hold), Q_ARG(int, firstFrame), + Q_ARG(int, lastFrame), Q_ARG(const QStringList&, maskedJoints)); + return; + } + // check for a configured animation for the role + foreach (const AnimationHandlePointer& handle, _animationHandles) { + if (handle->getRole() == role) { + handle->start(); + return; + } + } + // no joy; use the parameters provided + AnimationHandlePointer handle = _skeletonModel.createAnimationHandle(); + handle->setRole(role); + handle->setURL(url); + handle->setFPS(fps); + handle->setPriority(priority); + handle->setLoop(loop); + handle->setHold(hold); + handle->setFirstFrame(firstFrame); + handle->setLastFrame(lastFrame); + handle->setMaskedJoints(maskedJoints); + handle->start(); +} + +void MyAvatar::stopAnimationByRole(const QString& role) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "stopAnimationByRole", Q_ARG(const QString&, role)); + return; + } + foreach (const AnimationHandlePointer& handle, _skeletonModel.getRunningAnimations()) { + if (handle->getRole() == role) { + handle->stop(); + } + } +} + void MyAvatar::stopAnimation(const QString& url) { if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "stopAnimation", Q_ARG(const QString&, url)); @@ -467,7 +508,6 @@ void MyAvatar::stopAnimation(const QString& url) { foreach (const AnimationHandlePointer& handle, _skeletonModel.getRunningAnimations()) { if (handle->getURL() == url) { handle->stop(); - return; } } } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index fcbb2103d1..a8eb3babd0 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -73,6 +73,15 @@ public: /// Stops an animation as identified by a URL. Q_INVOKABLE void stopAnimation(const QString& url); + /// Starts an animation by its role, using the provided URL and parameters if the avatar doesn't have a custom + /// animation for the role. + Q_INVOKABLE void startAnimationByRole(const QString& role, const QString& url = QString(), float fps = 30.0f, + float priority = 1.0f, bool loop = false, bool hold = false, int firstFrame = 0, + int lastFrame = INT_MAX, const QStringList& maskedJoints = QStringList()); + + /// Stops an animation identified by its role. + Q_INVOKABLE void stopAnimationByRole(const QString& role); + // get/set avatar data void saveData(QSettings* settings); void loadData(QSettings* settings); From a32dfdb7bbb51d8196bc7b7a9d1da89ee02c56d3 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 22 May 2014 17:05:28 -0700 Subject: [PATCH 25/49] We should let people "start" even if the animation is already playing (to start again from the beginning). Fixed an issue with competing priorities. --- interface/src/renderer/Model.cpp | 38 +++++++++++++++++---------- interface/src/renderer/Model.h | 3 ++- interface/src/ui/AnimationsDialog.cpp | 9 ++----- interface/src/ui/AnimationsDialog.h | 1 - 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 3005921d39..5d94a9a7d0 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1690,12 +1690,19 @@ static void insertSorted(QList& handles, const Animation } void AnimationHandle::setPriority(float priority) { - if (_priority != priority) { - _priority = priority; - if (_running) { - _model->_runningAnimations.removeOne(_self); - insertSorted(_model->_runningAnimations, _self); + if (_priority == priority) { + return; + } + if (_running) { + _model->_runningAnimations.removeOne(_self); + if (priority < _priority) { + lowerPriority(priority); } + _priority = priority; + insertSorted(_model->_runningAnimations, _self); + + } else { + _priority = priority; } } @@ -1726,15 +1733,7 @@ void AnimationHandle::setRunning(bool running) { } else { _model->_runningAnimations.removeOne(_self); - for (int i = 0; i < _jointMappings.size(); i++) { - int mapping = _jointMappings.at(i); - if (mapping != -1) { - Model::JointState& state = _model->_jointStates[mapping]; - if (_priority == state.animationPriority) { - state.animationPriority = 0.0f; - } - } - } + lowerPriority(0.0f); } emit runningChanged(_running); } @@ -1820,3 +1819,14 @@ void AnimationHandle::simulate(float deltaTime) { } } +void AnimationHandle::lowerPriority(float newPriority) { + for (int i = 0; i < _jointMappings.size(); i++) { + int mapping = _jointMappings.at(i); + if (mapping != -1) { + Model::JointState& state = _model->_jointStates[mapping]; + if (_priority == state.animationPriority) { + state.animationPriority = newPriority; + } + } + } +} diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index a0806ee238..c2aeec7183 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -430,7 +430,8 @@ private: AnimationHandle(Model* model); void simulate(float deltaTime); - + void lowerPriority(float newPriority); + Model* _model; WeakAnimationHandlePointer _self; AnimationPointer _animation; diff --git a/interface/src/ui/AnimationsDialog.cpp b/interface/src/ui/AnimationsDialog.cpp index 9f62abc270..2456b589da 100644 --- a/interface/src/ui/AnimationsDialog.cpp +++ b/interface/src/ui/AnimationsDialog.cpp @@ -148,8 +148,8 @@ AnimationPanel::AnimationPanel(AnimationsDialog* dialog, const AnimationHandlePo buttons->addWidget(remove); connect(remove, SIGNAL(clicked(bool)), SLOT(removeHandle())); - connect(_handle.data(), SIGNAL(runningChanged(bool)), SLOT(updateStartStop())); - updateStartStop(); + _stop->connect(_handle.data(), SIGNAL(runningChanged(bool)), SLOT(setEnabled(bool))); + _stop->setEnabled(_handle->isRunning()); } void AnimationPanel::chooseURL() { @@ -185,11 +185,6 @@ void AnimationPanel::chooseMaskedJoints() { } } -void AnimationPanel::updateStartStop() { - _start->setEnabled(!_handle->isRunning()); - _stop->setEnabled(_handle->isRunning()); -} - void AnimationPanel::updateHandle() { _handle->setRole(_role->currentText()); _handle->setURL(_url->text()); diff --git a/interface/src/ui/AnimationsDialog.h b/interface/src/ui/AnimationsDialog.h index 6f7a2f3784..dd3865741e 100644 --- a/interface/src/ui/AnimationsDialog.h +++ b/interface/src/ui/AnimationsDialog.h @@ -57,7 +57,6 @@ private slots: void chooseURL(); void chooseMaskedJoints(); - void updateStartStop(); void updateHandle(); void removeHandle(); From 6d500d64d12bb4d75cb817208e7f13e086ec6deb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 22 May 2014 17:12:22 -0700 Subject: [PATCH 26/49] fix floats that aren't actually floats --- domain-server/src/DomainServer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index cd8e66a2b5..f979de64c0 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -733,9 +733,9 @@ void DomainServer::setupPendingAssignmentCredits() { qint64 elapsedMsecsSinceLastPayment = nodeData->getPaymentIntervalTimer().elapsed(); nodeData->getPaymentIntervalTimer().restart(); - const float CREDITS_PER_HOUR = 0.10; + const float CREDITS_PER_HOUR = 0.10f; const float CREDITS_PER_MSEC = CREDITS_PER_HOUR / (60 * 60 * 1000); - const int SATOSHIS_PER_MSEC = CREDITS_PER_MSEC * powf(10, 8); + const int SATOSHIS_PER_MSEC = CREDITS_PER_MSEC * powf(10.0f, 8.0f); float pendingCredits = elapsedMsecsSinceLastPayment * SATOSHIS_PER_MSEC; From 4f81bac742a2bf54db72e78f8cc1760c00d6438d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 22 May 2014 17:16:42 -0700 Subject: [PATCH 27/49] add back a missing space in AccountManager --- libraries/networking/src/AccountManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index f32ff75f51..628b084ea8 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -34,7 +34,7 @@ public: QString updateSlot; }; -class AccountManager: public QObject { +class AccountManager : public QObject { Q_OBJECT public: static AccountManager& getInstance(); From 3a45104793bf8c9f8cd0e31546e6b91a08e742f1 Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 22 May 2014 17:55:25 -0700 Subject: [PATCH 28/49] Made overlays thread safe for write operations, which solved a script crash. --- interface/src/ui/overlays/Overlays.cpp | 6 +++--- interface/src/ui/overlays/Overlays.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 9e4a594bbc..6c6f150ae7 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -96,7 +96,6 @@ void Overlays::render3D() { } } -// TODO: make multi-threaded safe unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& properties) { unsigned int thisID = 0; bool created = false; @@ -140,6 +139,7 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope } if (created) { + QWriteLocker lock(&_lock); thisID = _nextOverlayID; _nextOverlayID++; if (is3D) { @@ -152,9 +152,9 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope return thisID; } -// TODO: make multi-threaded safe bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) { Overlay* thisOverlay = NULL; + QWriteLocker lock(&_lock); if (_overlays2D.contains(id)) { thisOverlay = _overlays2D[id]; } else if (_overlays3D.contains(id)) { @@ -167,9 +167,9 @@ bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) { return false; } -// TODO: make multi-threaded safe void Overlays::deleteOverlay(unsigned int id) { Overlay* overlayToDelete; + QWriteLocker lock(&_lock); if (_overlays2D.contains(id)) { overlayToDelete = _overlays2D.take(id); } else if (_overlays3D.contains(id)) { diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index b3477be0c2..20015b8af9 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -45,6 +45,7 @@ private: QList _overlaysToDelete; unsigned int _nextOverlayID; QGLWidget* _parent; + QReadWriteLock _lock; }; From 2681312b54757fd2ef0b938b81d34149ce53cb3f Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 23 May 2014 00:09:15 -0700 Subject: [PATCH 29/49] Velocity damped hand positions --- examples/hydraMove.js | 2 +- interface/src/devices/SixenseManager.cpp | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/hydraMove.js b/examples/hydraMove.js index 60823ffb36..bd462f5e38 100644 --- a/examples/hydraMove.js +++ b/examples/hydraMove.js @@ -50,7 +50,7 @@ var JOYSTICK_PITCH_MAG = PITCH_MAG * 0.5; var LEFT_PALM = 0; -var LEFT_BUTTON_4 = 5; +var LEFT_BUTTON_4 = 4; var LEFT_BUTTON_FWD = 5; var RIGHT_PALM = 2; var RIGHT_BUTTON_4 = 10; diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 547642a1be..d2784961bd 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -120,7 +120,6 @@ void SixenseManager::update(float deltaTime) { // Rotation of Palm glm::quat rotation(data->rot_quat[3], -data->rot_quat[0], data->rot_quat[1], -data->rot_quat[2]); rotation = glm::angleAxis(PI, glm::vec3(0.f, 1.f, 0.f)) * _orbRotation * rotation; - palm->setRawRotation(rotation); // Compute current velocity from position change glm::vec3 rawVelocity; @@ -130,8 +129,13 @@ void SixenseManager::update(float deltaTime) { rawVelocity = glm::vec3(0.0f); } palm->setRawVelocity(rawVelocity); // meters/sec - palm->setRawPosition(position); - + + // Use a velocity sensitive filter to damp small motions and preserve large ones with + // no latency. + float velocityFilter = glm::clamp(1.0f - glm::length(rawVelocity), 0.0f, 1.0f); + palm->setRawPosition(palm->getRawPosition() * velocityFilter + position * (1.0f - velocityFilter)); + palm->setRawRotation(safeMix(palm->getRawRotation(), rotation, 1.0f - velocityFilter)); + // use the velocity to determine whether there's any movement (if the hand isn't new) const float MOVEMENT_DISTANCE_THRESHOLD = 0.003f; _amountMoved += rawVelocity * deltaTime; From f7f4c48b9b9578860460118c281ef2857695911d Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Fri, 23 May 2014 08:40:41 -0600 Subject: [PATCH 30/49] Revert "Initialise lisencing manager after we have enabled Visage." This reverts commit 061f182fab4a8f72e046021cec93a3a41ac22f82. --- interface/src/devices/Visage.cpp | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/interface/src/devices/Visage.cpp b/interface/src/devices/Visage.cpp index 70cdaf2b01..119d89654a 100644 --- a/interface/src/devices/Visage.cpp +++ b/interface/src/devices/Visage.cpp @@ -41,8 +41,14 @@ Visage::Visage() : _headOrigin(DEFAULT_HEAD_ORIGIN) { #ifdef HAVE_VISAGE - _tracker = NULL; - _data = NULL; +#ifdef WIN32 + QByteArray licensePath = Application::resourcesPath().toLatin1() + "visage"; +#else + QByteArray licensePath = Application::resourcesPath().toLatin1() + "visage/license.vlc"; +#endif + initializeLicenseManager(licensePath.data()); + _tracker = new VisageTracker2(Application::resourcesPath().toLatin1() + "visage/tracker.cfg"); + _data = new FaceData(); #endif } @@ -173,19 +179,6 @@ void Visage::setEnabled(bool enabled) { return; } if ((_enabled = enabled)) { - if(_tracker == NULL && _data == NULL){ - - #ifdef WIN32 - QByteArray licensePath = Application::resourcesPath().toLatin1() + "visage"; - #else - QByteArray licensePath = Application::resourcesPath().toLatin1() + "visage/license.vlc"; - #endif - - initializeLicenseManager(licensePath.data()); - _tracker = new VisageTracker2(Application::resourcesPath().toLatin1() + "visage/tracker.cfg"); - _data = new FaceData(); - } - _tracker->trackFromCam(); } else { _tracker->stop(); From 4d6e8a2c9e5746e230d43dba53552312203f3348 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 23 May 2014 09:42:36 -0700 Subject: [PATCH 31/49] Or rather, replaceMatchingPriorities. --- interface/src/renderer/Model.cpp | 6 +++--- interface/src/renderer/Model.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 5d94a9a7d0..d18abce677 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1696,7 +1696,7 @@ void AnimationHandle::setPriority(float priority) { if (_running) { _model->_runningAnimations.removeOne(_self); if (priority < _priority) { - lowerPriority(priority); + replaceMatchingPriorities(priority); } _priority = priority; insertSorted(_model->_runningAnimations, _self); @@ -1733,7 +1733,7 @@ void AnimationHandle::setRunning(bool running) { } else { _model->_runningAnimations.removeOne(_self); - lowerPriority(0.0f); + replaceMatchingPriorities(0.0f); } emit runningChanged(_running); } @@ -1819,7 +1819,7 @@ void AnimationHandle::simulate(float deltaTime) { } } -void AnimationHandle::lowerPriority(float newPriority) { +void AnimationHandle::replaceMatchingPriorities(float newPriority) { for (int i = 0; i < _jointMappings.size(); i++) { int mapping = _jointMappings.at(i); if (mapping != -1) { diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index c2aeec7183..1a6642dfc6 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -430,7 +430,7 @@ private: AnimationHandle(Model* model); void simulate(float deltaTime); - void lowerPriority(float newPriority); + void replaceMatchingPriorities(float newPriority); Model* _model; WeakAnimationHandlePointer _self; From 2dd78b36dbc578b02dda9aac47dca8acfe9efd98 Mon Sep 17 00:00:00 2001 From: wangyix Date: Fri, 23 May 2014 09:47:08 -0700 Subject: [PATCH 32/49] moved _sequenceNumber to OctreeSendThread --- assignment-client/src/octree/OctreeQueryNode.cpp | 13 +++++++++---- assignment-client/src/octree/OctreeQueryNode.h | 9 +++++---- .../src/octree/OctreeSendThread.cpp | 16 +++++++++------- assignment-client/src/octree/OctreeSendThread.h | 2 ++ examples/lookWithMouse.js | 2 +- 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/assignment-client/src/octree/OctreeQueryNode.cpp b/assignment-client/src/octree/OctreeQueryNode.cpp index 10d30ad1ae..d630705f64 100644 --- a/assignment-client/src/octree/OctreeQueryNode.cpp +++ b/assignment-client/src/octree/OctreeQueryNode.cpp @@ -38,7 +38,7 @@ OctreeQueryNode::OctreeQueryNode() : _lastClientOctreeSizeScale(DEFAULT_OCTREE_SIZE_SCALE), _lodChanged(false), _lodInitialized(false), - _sequenceNumber(0), + //_sequenceNumber(0), _lastRootTimestamp(0), _myPacketType(PacketTypeUnknown), _isShuttingDown(false) @@ -161,7 +161,8 @@ void OctreeQueryNode::init() { resetOctreePacket(true); // don't bump sequence } -void OctreeQueryNode::resetOctreePacket(bool lastWasSurpressed) { + +void OctreeQueryNode::resetOctreePacket(OCTREE_PACKET_SEQUENCE sequenceNumber) { // if shutting down, return immediately if (_isShuttingDown) { return; @@ -197,14 +198,18 @@ void OctreeQueryNode::resetOctreePacket(bool lastWasSurpressed) { _octreePacketAt += sizeof(OCTREE_PACKET_FLAGS); _octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_FLAGS); + // pack in sequence number OCTREE_PACKET_SEQUENCE* sequenceAt = (OCTREE_PACKET_SEQUENCE*)_octreePacketAt; - *sequenceAt = _sequenceNumber; + *sequenceAt = sequenceNumber; _octreePacketAt += sizeof(OCTREE_PACKET_SEQUENCE); _octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_SEQUENCE); + /* if (!(lastWasSurpressed || _lastOctreePacketLength == (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE))) { +qDebug() << "_sequenceNumber is now " << _sequenceNumber << " ***********************************************"; _sequenceNumber++; - } + }*/ + // pack in timestamp OCTREE_PACKET_SENT_TIME now = usecTimestampNow(); diff --git a/assignment-client/src/octree/OctreeQueryNode.h b/assignment-client/src/octree/OctreeQueryNode.h index 7b42208f16..ce50617fd4 100644 --- a/assignment-client/src/octree/OctreeQueryNode.h +++ b/assignment-client/src/octree/OctreeQueryNode.h @@ -35,11 +35,11 @@ public: void init(); // called after creation to set up some virtual items virtual PacketType getMyPacketType() const = 0; - void resetOctreePacket(bool lastWasSurpressed = false); // resets octree packet to after "V" header + void resetOctreePacket(OCTREE_PACKET_SEQUENCE sequenceNumber); // resets octree packet to after "V" header void writeToPacket(const unsigned char* buffer, unsigned int bytes); // writes to end of packet - const unsigned char* getPacket() const { return _octreePacket; } + const unsigned char* getPacket() const { return _octreePacket; } unsigned int getPacketLength() const { return (MAX_PACKET_SIZE - _octreePacketAvailableBytes); } bool isPacketWaiting() const { return _octreePacketWaiting; } @@ -135,8 +135,9 @@ private: float _lastClientOctreeSizeScale; bool _lodChanged; bool _lodInitialized; - - OCTREE_PACKET_SEQUENCE _sequenceNumber; + + //OCTREE_PACKET_SEQUENCE _sequenceNumber; + quint64 _lastRootTimestamp; PacketType _myPacketType; diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index d8a9f3d1ea..4a8948197a 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -9,8 +9,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include - #include #include #include @@ -30,7 +28,8 @@ OctreeSendThread::OctreeSendThread(const SharedAssignmentPointer& myAssignment, _nodeUUID(node->getUUID()), _packetData(), _nodeMissingCount(0), - _isShuttingDown(false) + _isShuttingDown(false), + _sequenceNumber(0) { QString safeServerName("Octree"); if (_myServer) { @@ -129,7 +128,7 @@ int OctreeSendThread::handlePacketSend(OctreeQueryNode* nodeData, int& trueBytes return 0; } - bool debug = _myServer->wantsDebugSending(); + bool debug = _myServer->wantsDebugSending(); quint64 now = usecTimestampNow(); bool packetSent = false; // did we send a packet? @@ -139,7 +138,7 @@ int OctreeSendThread::handlePacketSend(OctreeQueryNode* nodeData, int& trueBytes // obscure the packet and not send it. This allows the callers and upper level logic to not need to know about // this rate control savings. if (nodeData->shouldSuppressDuplicatePacket()) { - nodeData->resetOctreePacket(true); // we still need to reset it though! + nodeData->resetOctreePacket(_sequenceNumber); // we still need to reset it though! return packetsSent; // without sending... } @@ -244,7 +243,10 @@ int OctreeSendThread::handlePacketSend(OctreeQueryNode* nodeData, int& trueBytes trueBytesSent += nodeData->getPacketLength(); truePacketsSent++; packetsSent++; - nodeData->resetOctreePacket(); + + _sequenceNumber++; + + nodeData->resetOctreePacket(_sequenceNumber); } return packetsSent; @@ -284,7 +286,7 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus if (nodeData->isPacketWaiting()) { packetsSentThisInterval += handlePacketSend(nodeData, trueBytesSent, truePacketsSent); } else { - nodeData->resetOctreePacket(); + nodeData->resetOctreePacket(_sequenceNumber); } int targetSize = MAX_OCTREE_PACKET_DATA_SIZE; if (wantCompression) { diff --git a/assignment-client/src/octree/OctreeSendThread.h b/assignment-client/src/octree/OctreeSendThread.h index d8eed27802..95e7e2226a 100644 --- a/assignment-client/src/octree/OctreeSendThread.h +++ b/assignment-client/src/octree/OctreeSendThread.h @@ -55,6 +55,8 @@ private: int _nodeMissingCount; bool _isShuttingDown; + + OCTREE_PACKET_SEQUENCE _sequenceNumber; }; #endif // hifi_OctreeSendThread_h diff --git a/examples/lookWithMouse.js b/examples/lookWithMouse.js index 256a3ea67c..2fe12cce24 100644 --- a/examples/lookWithMouse.js +++ b/examples/lookWithMouse.js @@ -11,7 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var alwaysLook = true; // if you want the mouse look to happen only when you click, change this to false +var alwaysLook = false; // if you want the mouse look to happen only when you click, change this to false var isMouseDown = false; var lastX = 0; var lastY = 0; From 6998dfae3cd731f0bfa997c4ec08e3341d2e276d Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 23 May 2014 09:57:47 -0700 Subject: [PATCH 33/49] add visual indicator of thrust direction --- examples/hydraMove.js | 60 ++++++++++++++++++++++++ interface/src/devices/SixenseManager.cpp | 2 +- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/examples/hydraMove.js b/examples/hydraMove.js index bd462f5e38..ed6a5a4f44 100644 --- a/examples/hydraMove.js +++ b/examples/hydraMove.js @@ -26,6 +26,7 @@ var THRUST_INCREASE_RATE = 1.05; var MAX_THRUST_MULTIPLIER = 75.0; var thrustMultiplier = INITIAL_THRUST_MULTPLIER; var grabDelta = { x: 0, y: 0, z: 0}; +var grabStartPosition = { x: 0, y: 0, z: 0}; var grabDeltaVelocity = { x: 0, y: 0, z: 0}; var grabStartRotation = { x: 0, y: 0, z: 0, w: 1}; var grabCurrentRotation = { x: 0, y: 0, z: 0, w: 1}; @@ -63,6 +64,63 @@ function printVector(text, v, decimals) { } var debug = false; +var RED_COLOR = { red: 255, green: 0, blue: 0 }; +var GRAY_COLOR = { red: 25, green: 25, blue: 25 }; +var defaultPosition = { x: 0, y: 0, z: 0}; +var RADIUS = 0.05; +var greenSphere = -1; +var redSphere = -1; + +function createDebugOverlay() { + + if (greenSphere == -1) { + greenSphere = Overlays.addOverlay("sphere", { + position: defaultPosition, + size: RADIUS, + color: GRAY_COLOR, + alpha: 1, + visible: true, + solid: true, + anchor: "MyAvatar" + }); + redSphere = Overlays.addOverlay("sphere", { + position: defaultPosition, + size: RADIUS, + color: RED_COLOR, + alpha: 1, + visible: true, + solid: true, + anchor: "MyAvatar" + }); + } +} + +function destroyDebugOverlay() { + if (greenSphere != -1) { + Overlays.deleteOverlay(greenSphere); + Overlays.deleteOverlay(redSphere); + greenSphere = -1; + redSphere = -1; + } +} + +function displayDebug() { + if (!(grabbingWithRightHand || grabbingWithLeftHand)) { + if (greenSphere != -1) { + destroyDebugOverlay(); + } + } else { + // update debug indicator + if (greenSphere == -1) { + createDebugOverlay(); + } + + var displayOffset = { x:0, y:0.5, z:-0.5 }; + + Overlays.editOverlay(greenSphere, { position: Vec3.sum(grabStartPosition, displayOffset) } ); + Overlays.editOverlay(redSphere, { position: Vec3.sum(Vec3.sum(grabStartPosition, grabDelta), displayOffset), size: RADIUS + (0.25 * Vec3.length(grabDelta)) } ); + } +} function getJoystickPosition(palm) { // returns CONTROLLER_ID position in avatar local frame @@ -220,6 +278,8 @@ function flyWithHydra(deltaTime) { MyAvatar.headPitch = newPitch; } handleGrabBehavior(deltaTime); + displayDebug(); + } Script.update.connect(flyWithHydra); diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index d2784961bd..8cd3cc059e 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -135,7 +135,7 @@ void SixenseManager::update(float deltaTime) { float velocityFilter = glm::clamp(1.0f - glm::length(rawVelocity), 0.0f, 1.0f); palm->setRawPosition(palm->getRawPosition() * velocityFilter + position * (1.0f - velocityFilter)); palm->setRawRotation(safeMix(palm->getRawRotation(), rotation, 1.0f - velocityFilter)); - + // use the velocity to determine whether there's any movement (if the hand isn't new) const float MOVEMENT_DISTANCE_THRESHOLD = 0.003f; _amountMoved += rawVelocity * deltaTime; From 87d927d4478a4dce315588a642a93e39e90f7afa Mon Sep 17 00:00:00 2001 From: wangyix Date: Fri, 23 May 2014 10:09:46 -0700 Subject: [PATCH 34/49] moved _sequenceNumber back to OctreeQueryNode instead added incrementSequenceNumber() to OctreeQueryNode for sendthread to use --- assignment-client/src/octree/OctreeQueryNode.cpp | 12 +++++++----- assignment-client/src/octree/OctreeQueryNode.h | 6 ++++-- assignment-client/src/octree/OctreeSendThread.cpp | 13 +++++-------- assignment-client/src/octree/OctreeSendThread.h | 2 -- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/assignment-client/src/octree/OctreeQueryNode.cpp b/assignment-client/src/octree/OctreeQueryNode.cpp index d630705f64..cb4b6588b0 100644 --- a/assignment-client/src/octree/OctreeQueryNode.cpp +++ b/assignment-client/src/octree/OctreeQueryNode.cpp @@ -38,7 +38,7 @@ OctreeQueryNode::OctreeQueryNode() : _lastClientOctreeSizeScale(DEFAULT_OCTREE_SIZE_SCALE), _lodChanged(false), _lodInitialized(false), - //_sequenceNumber(0), + _sequenceNumber(0), _lastRootTimestamp(0), _myPacketType(PacketTypeUnknown), _isShuttingDown(false) @@ -158,11 +158,11 @@ bool OctreeQueryNode::shouldSuppressDuplicatePacket() { void OctreeQueryNode::init() { _myPacketType = getMyPacketType(); - resetOctreePacket(true); // don't bump sequence + resetOctreePacket(); // don't bump sequence } -void OctreeQueryNode::resetOctreePacket(OCTREE_PACKET_SEQUENCE sequenceNumber) { +void OctreeQueryNode::resetOctreePacket() { // if shutting down, return immediately if (_isShuttingDown) { return; @@ -201,12 +201,11 @@ void OctreeQueryNode::resetOctreePacket(OCTREE_PACKET_SEQUENCE sequenceNumber) { // pack in sequence number OCTREE_PACKET_SEQUENCE* sequenceAt = (OCTREE_PACKET_SEQUENCE*)_octreePacketAt; - *sequenceAt = sequenceNumber; + *sequenceAt = _sequenceNumber; _octreePacketAt += sizeof(OCTREE_PACKET_SEQUENCE); _octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_SEQUENCE); /* if (!(lastWasSurpressed || _lastOctreePacketLength == (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE))) { -qDebug() << "_sequenceNumber is now " << _sequenceNumber << " ***********************************************"; _sequenceNumber++; }*/ @@ -370,3 +369,6 @@ void OctreeQueryNode::dumpOutOfView() { } } +void OctreeQueryNode::incrementSequenceNumber() { + _sequenceNumber++; +} \ No newline at end of file diff --git a/assignment-client/src/octree/OctreeQueryNode.h b/assignment-client/src/octree/OctreeQueryNode.h index ce50617fd4..63380f69e5 100644 --- a/assignment-client/src/octree/OctreeQueryNode.h +++ b/assignment-client/src/octree/OctreeQueryNode.h @@ -35,7 +35,7 @@ public: void init(); // called after creation to set up some virtual items virtual PacketType getMyPacketType() const = 0; - void resetOctreePacket(OCTREE_PACKET_SEQUENCE sequenceNumber); // resets octree packet to after "V" header + void resetOctreePacket(); // resets octree packet to after "V" header void writeToPacket(const unsigned char* buffer, unsigned int bytes); // writes to end of packet @@ -99,6 +99,8 @@ public: void nodeKilled(); void forceNodeShutdown(); bool isShuttingDown() const { return _isShuttingDown; } + + void incrementSequenceNumber(); private slots: void sendThreadFinished(); @@ -136,7 +138,7 @@ private: bool _lodChanged; bool _lodInitialized; - //OCTREE_PACKET_SEQUENCE _sequenceNumber; + OCTREE_PACKET_SEQUENCE _sequenceNumber; quint64 _lastRootTimestamp; diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 4a8948197a..5c8bb9440e 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -28,8 +28,7 @@ OctreeSendThread::OctreeSendThread(const SharedAssignmentPointer& myAssignment, _nodeUUID(node->getUUID()), _packetData(), _nodeMissingCount(0), - _isShuttingDown(false), - _sequenceNumber(0) + _isShuttingDown(false) { QString safeServerName("Octree"); if (_myServer) { @@ -138,7 +137,7 @@ int OctreeSendThread::handlePacketSend(OctreeQueryNode* nodeData, int& trueBytes // obscure the packet and not send it. This allows the callers and upper level logic to not need to know about // this rate control savings. if (nodeData->shouldSuppressDuplicatePacket()) { - nodeData->resetOctreePacket(_sequenceNumber); // we still need to reset it though! + nodeData->resetOctreePacket(); // we still need to reset it though! return packetsSent; // without sending... } @@ -243,10 +242,8 @@ int OctreeSendThread::handlePacketSend(OctreeQueryNode* nodeData, int& trueBytes trueBytesSent += nodeData->getPacketLength(); truePacketsSent++; packetsSent++; - - _sequenceNumber++; - - nodeData->resetOctreePacket(_sequenceNumber); + nodeData->incrementSequenceNumber(); + nodeData->resetOctreePacket(); } return packetsSent; @@ -286,7 +283,7 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus if (nodeData->isPacketWaiting()) { packetsSentThisInterval += handlePacketSend(nodeData, trueBytesSent, truePacketsSent); } else { - nodeData->resetOctreePacket(_sequenceNumber); + nodeData->resetOctreePacket(); } int targetSize = MAX_OCTREE_PACKET_DATA_SIZE; if (wantCompression) { diff --git a/assignment-client/src/octree/OctreeSendThread.h b/assignment-client/src/octree/OctreeSendThread.h index 95e7e2226a..d8eed27802 100644 --- a/assignment-client/src/octree/OctreeSendThread.h +++ b/assignment-client/src/octree/OctreeSendThread.h @@ -55,8 +55,6 @@ private: int _nodeMissingCount; bool _isShuttingDown; - - OCTREE_PACKET_SEQUENCE _sequenceNumber; }; #endif // hifi_OctreeSendThread_h From 9553271fa1da0a52aecabf5cde750d63ebe81d7d Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Fri, 23 May 2014 10:44:40 -0700 Subject: [PATCH 35/49] Added some missing locks to make Overlays thread safe for reading as well. --- interface/src/ui/overlays/Overlays.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 6c6f150ae7..bcac86d7f1 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -39,6 +39,7 @@ void Overlays::init(QGLWidget* parent) { } void Overlays::update(float deltatime) { + QWriteLocker lock(&_lock); foreach (Overlay* thisOverlay, _overlays2D) { thisOverlay->update(deltatime); } @@ -52,12 +53,14 @@ void Overlays::update(float deltatime) { } void Overlays::render2D() { + QReadLocker lock(&_lock); foreach(Overlay* thisOverlay, _overlays2D) { thisOverlay->render(); } } void Overlays::render3D() { + QReadLocker lock(&_lock); if (_overlays3D.size() == 0) { return; } @@ -182,6 +185,7 @@ void Overlays::deleteOverlay(unsigned int id) { } unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { + QReadLocker lock(&_lock); QMapIterator i(_overlays2D); i.toBack(); while (i.hasPrevious()) { From bfd00f1b15b4d0a3371ac9da2d6bbd19ba4186a0 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 23 May 2014 10:57:14 -0700 Subject: [PATCH 36/49] Use local viewer model for specular. --- interface/resources/shaders/model.frag | 5 ++++- interface/resources/shaders/model.vert | 6 ++++++ interface/resources/shaders/model_normal_map.frag | 7 +++++-- interface/resources/shaders/model_normal_map.vert | 6 +++++- .../resources/shaders/model_normal_specular_map.frag | 7 +++++-- interface/resources/shaders/model_specular_map.frag | 5 ++++- interface/resources/shaders/skin_model.vert | 9 ++++++--- .../resources/shaders/skin_model_normal_map.vert | 11 +++++++---- 8 files changed, 42 insertions(+), 14 deletions(-) diff --git a/interface/resources/shaders/model.frag b/interface/resources/shaders/model.frag index a9d93f2f6a..488736abf9 100644 --- a/interface/resources/shaders/model.frag +++ b/interface/resources/shaders/model.frag @@ -14,6 +14,9 @@ // the diffuse texture uniform sampler2D diffuseMap; +// the interpolated position +varying vec4 position; + // the interpolated normal varying vec4 normal; @@ -26,7 +29,7 @@ void main(void) { gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position + vec4(0.0, 0.0, 1.0, 0.0)), + float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), normalizedNormal)); // modulate texture by base color and add specular contribution diff --git a/interface/resources/shaders/model.vert b/interface/resources/shaders/model.vert index 904e3c2a8b..f78ed5045b 100644 --- a/interface/resources/shaders/model.vert +++ b/interface/resources/shaders/model.vert @@ -11,6 +11,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// the interpolated position +varying vec4 position; + // the interpolated normal varying vec4 normal; @@ -19,6 +22,9 @@ void main(void) { // transform and store the normal for interpolation normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0)); + // likewise with the position + position = gl_ModelViewMatrix * gl_Vertex; + // pass along the vertex color gl_FrontColor = gl_Color; diff --git a/interface/resources/shaders/model_normal_map.frag b/interface/resources/shaders/model_normal_map.frag index 392be1f1cf..8444f2d6ea 100644 --- a/interface/resources/shaders/model_normal_map.frag +++ b/interface/resources/shaders/model_normal_map.frag @@ -17,6 +17,9 @@ uniform sampler2D diffuseMap; // the normal map texture uniform sampler2D normalMap; +// the interpolated position +varying vec4 interpolatedPosition; + // the interpolated normal varying vec4 interpolatedNormal; @@ -38,8 +41,8 @@ void main(void) { gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position + vec4(0.0, 0.0, 1.0, 0.0)), - viewNormal)); + float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - + normalize(vec4(vec3(interpolatedPosition), 0.0))), viewNormal)); // modulate texture by base color and add specular contribution gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + diff --git a/interface/resources/shaders/model_normal_map.vert b/interface/resources/shaders/model_normal_map.vert index 3607501acf..b013a0a736 100644 --- a/interface/resources/shaders/model_normal_map.vert +++ b/interface/resources/shaders/model_normal_map.vert @@ -14,6 +14,9 @@ // the tangent vector attribute vec3 tangent; +// the interpolated position +varying vec4 interpolatedPosition; + // the interpolated normal varying vec4 interpolatedNormal; @@ -22,7 +25,8 @@ varying vec4 interpolatedTangent; void main(void) { - // transform and store the normal and tangent for interpolation + // transform and store the position, normal and tangent for interpolation + interpolatedPosition = gl_ModelViewMatrix * gl_Vertex; interpolatedNormal = gl_ModelViewMatrix * vec4(gl_Normal, 0.0); interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0); diff --git a/interface/resources/shaders/model_normal_specular_map.frag b/interface/resources/shaders/model_normal_specular_map.frag index dbbb343c62..357677d82a 100644 --- a/interface/resources/shaders/model_normal_specular_map.frag +++ b/interface/resources/shaders/model_normal_specular_map.frag @@ -20,6 +20,9 @@ uniform sampler2D normalMap; // the specular map texture uniform sampler2D specularMap; +// the interpolated position +varying vec4 interpolatedPosition; + // the interpolated normal varying vec4 interpolatedNormal; @@ -41,8 +44,8 @@ void main(void) { gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position + vec4(0.0, 0.0, 1.0, 0.0)), - viewNormal)); + float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - + normalize(vec4(interpolatedPosition.xyz, 0.0))), viewNormal)); // modulate texture by base color and add specular contribution gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + vec4(pow(specular, gl_FrontMaterial.shininess) * diff --git a/interface/resources/shaders/model_specular_map.frag b/interface/resources/shaders/model_specular_map.frag index b955b5cfa6..a07324cd1b 100644 --- a/interface/resources/shaders/model_specular_map.frag +++ b/interface/resources/shaders/model_specular_map.frag @@ -17,6 +17,9 @@ uniform sampler2D diffuseMap; // the specular texture uniform sampler2D specularMap; +// the interpolated position in view space +varying vec4 position; + // the interpolated normal varying vec4 normal; @@ -29,7 +32,7 @@ void main(void) { gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position + vec4(0.0, 0.0, 1.0, 0.0)), + float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), normalizedNormal)); // modulate texture by base color and add specular contribution diff --git a/interface/resources/shaders/skin_model.vert b/interface/resources/shaders/skin_model.vert index 12320ba9a9..f743609dc3 100644 --- a/interface/resources/shaders/skin_model.vert +++ b/interface/resources/shaders/skin_model.vert @@ -19,11 +19,14 @@ uniform mat4 clusterMatrices[MAX_CLUSTERS]; attribute vec4 clusterIndices; attribute vec4 clusterWeights; +// the interpolated position +varying vec4 position; + // the interpolated normal varying vec4 normal; void main(void) { - vec4 position = vec4(0.0, 0.0, 0.0, 0.0); + position = vec4(0.0, 0.0, 0.0, 0.0); normal = vec4(0.0, 0.0, 0.0, 0.0); for (int i = 0; i < INDICES_PER_VERTEX; i++) { mat4 clusterMatrix = clusterMatrices[int(clusterIndices[i])]; @@ -31,7 +34,7 @@ void main(void) { position += clusterMatrix * gl_Vertex * clusterWeight; normal += clusterMatrix * vec4(gl_Normal, 0.0) * clusterWeight; } - position = gl_ModelViewProjectionMatrix * position; + position = gl_ModelViewMatrix * position; normal = normalize(gl_ModelViewMatrix * normal); // pass along the vertex color @@ -40,5 +43,5 @@ void main(void) { // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; - gl_Position = position; + gl_Position = gl_ProjectionMatrix * position; } diff --git a/interface/resources/shaders/skin_model_normal_map.vert b/interface/resources/shaders/skin_model_normal_map.vert index 872cbe2fc3..5dbc32626a 100644 --- a/interface/resources/shaders/skin_model_normal_map.vert +++ b/interface/resources/shaders/skin_model_normal_map.vert @@ -22,6 +22,9 @@ attribute vec3 tangent; attribute vec4 clusterIndices; attribute vec4 clusterWeights; +// the interpolated position +varying vec4 interpolatedPosition; + // the interpolated normal varying vec4 interpolatedNormal; @@ -29,17 +32,17 @@ varying vec4 interpolatedNormal; varying vec4 interpolatedTangent; void main(void) { - vec4 position = vec4(0.0, 0.0, 0.0, 0.0); + interpolatedPosition = vec4(0.0, 0.0, 0.0, 0.0); interpolatedNormal = vec4(0.0, 0.0, 0.0, 0.0); interpolatedTangent = vec4(0.0, 0.0, 0.0, 0.0); for (int i = 0; i < INDICES_PER_VERTEX; i++) { mat4 clusterMatrix = clusterMatrices[int(clusterIndices[i])]; float clusterWeight = clusterWeights[i]; - position += clusterMatrix * gl_Vertex * clusterWeight; + interpolatedPosition += clusterMatrix * gl_Vertex * clusterWeight; interpolatedNormal += clusterMatrix * vec4(gl_Normal, 0.0) * clusterWeight; interpolatedTangent += clusterMatrix * vec4(tangent, 0.0) * clusterWeight; } - position = gl_ModelViewProjectionMatrix * position; + interpolatedPosition = gl_ModelViewMatrix * interpolatedPosition; interpolatedNormal = gl_ModelViewMatrix * interpolatedNormal; interpolatedTangent = gl_ModelViewMatrix * interpolatedTangent; @@ -49,5 +52,5 @@ void main(void) { // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; - gl_Position = position; + gl_Position = gl_ProjectionMatrix * interpolatedPosition; } From df68082705e0a02266fadee65d9db6cd44fab9a8 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 23 May 2014 11:02:07 -0700 Subject: [PATCH 37/49] Added local glow to models --- interface/src/models/ModelTreeRenderer.cpp | 6 ++++- libraries/models/src/ModelItem.cpp | 28 +++++++++++++++++++--- libraries/models/src/ModelItem.h | 8 +++++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/interface/src/models/ModelTreeRenderer.cpp b/interface/src/models/ModelTreeRenderer.cpp index 0f9da86887..d29303ab79 100644 --- a/interface/src/models/ModelTreeRenderer.cpp +++ b/interface/src/models/ModelTreeRenderer.cpp @@ -203,7 +203,11 @@ void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) // TODO: should we allow modelItems to have alpha on their models? Model::RenderMode modelRenderMode = args->_renderMode == OctreeRenderer::SHADOW_RENDER_MODE ? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE; - model->render(alpha, modelRenderMode); + + { // Sets the glower scope + Glower glower(modelItem.getGlowLevel()); + model->render(alpha, modelRenderMode); + } if (!isShadowMode && displayModelBounds) { glColor3f(0.0f, 1.0f, 0.0f); diff --git a/libraries/models/src/ModelItem.cpp b/libraries/models/src/ModelItem.cpp index 3dd1c99e60..b6f4fe6c1d 100644 --- a/libraries/models/src/ModelItem.cpp +++ b/libraries/models/src/ModelItem.cpp @@ -85,12 +85,13 @@ ModelItem::ModelItem(const ModelItemID& modelItemID, const ModelItemProperties& _shouldDie = false; _modelURL = MODEL_DEFAULT_MODEL_URL; _modelRotation = MODEL_DEFAULT_MODEL_ROTATION; - + // animation related _animationURL = MODEL_DEFAULT_ANIMATION_URL; _animationIsPlaying = false; _animationFrameIndex = 0.0f; _animationFPS = MODEL_DEFAULT_ANIMATION_FPS; + _glowLevel = 0.0f; _jointMappingCompleted = false; _lastAnimated = now; @@ -125,6 +126,7 @@ void ModelItem::init(glm::vec3 position, float radius, rgbColor color, uint32_t _animationIsPlaying = false; _animationFrameIndex = 0.0f; _animationFPS = MODEL_DEFAULT_ANIMATION_FPS; + _glowLevel = 0.0f; _jointMappingCompleted = false; _lastAnimated = now; } @@ -802,6 +804,7 @@ ModelItemProperties::ModelItemProperties() : _animationIsPlaying(false), _animationFrameIndex(0.0), _animationFPS(MODEL_DEFAULT_ANIMATION_FPS), + _glowLevel(0.0f), _id(UNKNOWN_MODEL_ID), _idSet(false), @@ -817,6 +820,7 @@ ModelItemProperties::ModelItemProperties() : _animationIsPlayingChanged(false), _animationFrameIndexChanged(false), _animationFPSChanged(false), + _glowLevelChanged(false), _defaultSettings(true) { } @@ -890,6 +894,7 @@ QScriptValue ModelItemProperties::copyToScriptValue(QScriptEngine* engine) const properties.setProperty("animationIsPlaying", _animationIsPlaying); properties.setProperty("animationFrameIndex", _animationFrameIndex); properties.setProperty("animationFPS", _animationFPS); + properties.setProperty("glowLevel", _glowLevel); if (_idSet) { properties.setProperty("id", _id); @@ -1015,7 +1020,7 @@ void ModelItemProperties::copyFromScriptValue(const QScriptValue &object) { _animationFrameIndexChanged = true; } } - + QScriptValue animationFPS = object.property("animationFPS"); if (animationFPS.isValid()) { float newFPS; @@ -1025,6 +1030,16 @@ void ModelItemProperties::copyFromScriptValue(const QScriptValue &object) { _animationFPSChanged = true; } } + + QScriptValue glowLevel = object.property("glowLevel"); + if (glowLevel.isValid()) { + float newGlowLevel; + newGlowLevel = glowLevel.toVariant().toFloat(); + if (_defaultSettings || newGlowLevel != _glowLevel) { + _glowLevel = newGlowLevel; + _glowLevelChanged = true; + } + } _lastEdited = usecTimestampNow(); } @@ -1075,11 +1090,16 @@ void ModelItemProperties::copyToModelItem(ModelItem& modelItem) const { modelItem.setAnimationFrameIndex(_animationFrameIndex); somethingChanged = true; } - + if (_animationFPSChanged) { modelItem.setAnimationFPS(_animationFPS); somethingChanged = true; } + + if (_glowLevelChanged) { + modelItem.setGlowLevel(_glowLevel); + somethingChanged = true; + } if (somethingChanged) { bool wantDebug = false; @@ -1104,6 +1124,7 @@ void ModelItemProperties::copyFromModelItem(const ModelItem& modelItem) { _animationIsPlaying = modelItem.getAnimationIsPlaying(); _animationFrameIndex = modelItem.getAnimationFrameIndex(); _animationFPS = modelItem.getAnimationFPS(); + _glowLevel = modelItem.getGlowLevel(); _id = modelItem.getID(); _idSet = true; @@ -1119,6 +1140,7 @@ void ModelItemProperties::copyFromModelItem(const ModelItem& modelItem) { _animationIsPlayingChanged = false; _animationFrameIndexChanged = false; _animationFPSChanged = false; + _glowLevelChanged = false; _defaultSettings = false; } diff --git a/libraries/models/src/ModelItem.h b/libraries/models/src/ModelItem.h index 838dbc0fc8..63adae48fa 100644 --- a/libraries/models/src/ModelItem.h +++ b/libraries/models/src/ModelItem.h @@ -83,6 +83,7 @@ public: float getAnimationFrameIndex() const { return _animationFrameIndex; } bool getAnimationIsPlaying() const { return _animationIsPlaying; } float getAnimationFPS() const { return _animationFPS; } + float getGlowLevel() const { return _glowLevel; } quint64 getLastEdited() const { return _lastEdited; } uint16_t getChangedBits() const; @@ -100,6 +101,7 @@ public: void setAnimationFrameIndex(float value) { _animationFrameIndex = value; _animationFrameIndexChanged = true; } void setAnimationIsPlaying(bool value) { _animationIsPlaying = value; _animationIsPlayingChanged = true; } void setAnimationFPS(float value) { _animationFPS = value; _animationFPSChanged = true; } + void setGlowLevel(float value) { _glowLevel = value; _glowLevelChanged = true; } /// used by ModelScriptingInterface to return ModelItemProperties for unknown models void setIsUnknownID() { _id = UNKNOWN_MODEL_ID; _idSet = true; } @@ -119,6 +121,7 @@ private: bool _animationIsPlaying; float _animationFrameIndex; float _animationFPS; + float _glowLevel; uint32_t _id; bool _idSet; @@ -135,6 +138,7 @@ private: bool _animationIsPlayingChanged; bool _animationFrameIndexChanged; bool _animationFPSChanged; + bool _glowLevelChanged; bool _defaultSettings; }; Q_DECLARE_METATYPE(ModelItemProperties); @@ -206,6 +210,7 @@ public: const glm::quat& getModelRotation() const { return _modelRotation; } bool hasAnimation() const { return !_animationURL.isEmpty(); } const QString& getAnimationURL() const { return _animationURL; } + float getGlowLevel() const { return _glowLevel; } ModelItemID getModelItemID() const { return ModelItemID(getID(), getCreatorTokenID(), getID() != UNKNOWN_MODEL_ID); } ModelItemProperties getProperties() const; @@ -248,6 +253,7 @@ public: void setAnimationFrameIndex(float value) { _animationFrameIndex = value; } void setAnimationIsPlaying(bool value) { _animationIsPlaying = value; } void setAnimationFPS(float value) { _animationFPS = value; } + void setGlowLevel(float glowLevel) { _glowLevel = glowLevel; } void setProperties(const ModelItemProperties& properties); @@ -293,6 +299,8 @@ protected: // model related items QString _modelURL; glm::quat _modelRotation; + + float _glowLevel; uint32_t _creatorTokenID; bool _newlyCreated; From 53141ff1c11b4bcf9329fb2e419ed29c3c4acad2 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 23 May 2014 11:10:56 -0700 Subject: [PATCH 38/49] Glow when grabbed with the mouse (for now) --- examples/editModels.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/examples/editModels.js b/examples/editModels.js index 55c79cbc1d..394e9aa783 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -517,7 +517,7 @@ function mousePressEvent(event) { modelSelected = true; selectedModelID = foundModels[i]; selectedModelProperties = properties; - + selectedModelProperties.oldRadius = selectedModelProperties.radius; selectedModelProperties.oldPosition = { x: selectedModelProperties.position.x, @@ -534,7 +534,11 @@ function mousePressEvent(event) { orientation = MyAvatar.orientation; intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation)); - + + + selectedModelProperties.glowLevel = 0.1; + Models.editModel(selectedModelID, { glowLevel: selectedModelProperties.glowLevel}); + print("Clicked on " + selectedModelID.id + " " + modelSelected); return; } @@ -543,6 +547,13 @@ function mousePressEvent(event) { } } +Controller.mouseReleaseEvent.connect(function() { + if (modelSelected) { + Models.editModel(selectedModelID, { glowLevel: 0.0 }); + modelSelected = false; + } + }); + var oldModifier = 0; var modifier = 0; var wasShifted = false; From 6817c9682e5483eb4aff765f054f8ecf956eb972 Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Fri, 23 May 2014 11:17:55 -0700 Subject: [PATCH 39/49] Added a new lock specific to deleting, and improved safety --- interface/src/ui/overlays/Overlays.cpp | 43 ++++++++++++++++---------- interface/src/ui/overlays/Overlays.h | 1 + 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index bcac86d7f1..da7b05ead7 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -39,15 +39,22 @@ void Overlays::init(QGLWidget* parent) { } void Overlays::update(float deltatime) { - QWriteLocker lock(&_lock); - foreach (Overlay* thisOverlay, _overlays2D) { - thisOverlay->update(deltatime); + + { + QWriteLocker lock(&_lock); + foreach(Overlay* thisOverlay, _overlays2D) { + thisOverlay->update(deltatime); + } + foreach(Overlay* thisOverlay, _overlays3D) { + thisOverlay->update(deltatime); + } } - foreach (Overlay* thisOverlay, _overlays3D) { - thisOverlay->update(deltatime); - } - while (!_overlaysToDelete.isEmpty()) { - delete _overlaysToDelete.takeLast(); + + if (!_overlaysToDelete.isEmpty()) { + QWriteLocker lock(&_deleteLock); + do { + delete _overlaysToDelete.takeLast(); + } while (!_overlaysToDelete.isEmpty()); } } @@ -172,15 +179,19 @@ bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) { void Overlays::deleteOverlay(unsigned int id) { Overlay* overlayToDelete; - QWriteLocker lock(&_lock); - if (_overlays2D.contains(id)) { - overlayToDelete = _overlays2D.take(id); - } else if (_overlays3D.contains(id)) { - overlayToDelete = _overlays3D.take(id); - } else { - return; + + { + QWriteLocker lock(&_lock); + if (_overlays2D.contains(id)) { + overlayToDelete = _overlays2D.take(id); + } else if (_overlays3D.contains(id)) { + overlayToDelete = _overlays3D.take(id); + } else { + return; + } } - + + QWriteLocker lock(&_deleteLock); _overlaysToDelete.push_back(overlayToDelete); } diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 20015b8af9..2fbdb993f4 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -46,6 +46,7 @@ private: unsigned int _nextOverlayID; QGLWidget* _parent; QReadWriteLock _lock; + QReadWriteLock _deleteLock; }; From fe5fabdd610da35c4866dcaa248048026006b906 Mon Sep 17 00:00:00 2001 From: wangyix Date: Fri, 23 May 2014 11:17:59 -0700 Subject: [PATCH 40/49] removed old code that was commented out changed tabs to spaces --- assignment-client/src/octree/OctreeQueryNode.cpp | 10 ++-------- assignment-client/src/octree/OctreeQueryNode.h | 4 ++-- assignment-client/src/octree/OctreeSendThread.cpp | 4 ++-- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/assignment-client/src/octree/OctreeQueryNode.cpp b/assignment-client/src/octree/OctreeQueryNode.cpp index cb4b6588b0..ede6dee5e3 100644 --- a/assignment-client/src/octree/OctreeQueryNode.cpp +++ b/assignment-client/src/octree/OctreeQueryNode.cpp @@ -197,18 +197,12 @@ void OctreeQueryNode::resetOctreePacket() { *flagsAt = flags; _octreePacketAt += sizeof(OCTREE_PACKET_FLAGS); _octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_FLAGS); - - + // pack in sequence number OCTREE_PACKET_SEQUENCE* sequenceAt = (OCTREE_PACKET_SEQUENCE*)_octreePacketAt; *sequenceAt = _sequenceNumber; _octreePacketAt += sizeof(OCTREE_PACKET_SEQUENCE); _octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_SEQUENCE); - /* - if (!(lastWasSurpressed || _lastOctreePacketLength == (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE))) { - _sequenceNumber++; - }*/ - // pack in timestamp OCTREE_PACKET_SENT_TIME now = usecTimestampNow(); @@ -370,5 +364,5 @@ void OctreeQueryNode::dumpOutOfView() { } void OctreeQueryNode::incrementSequenceNumber() { - _sequenceNumber++; + _sequenceNumber++; } \ No newline at end of file diff --git a/assignment-client/src/octree/OctreeQueryNode.h b/assignment-client/src/octree/OctreeQueryNode.h index 63380f69e5..1bb3a72a0c 100644 --- a/assignment-client/src/octree/OctreeQueryNode.h +++ b/assignment-client/src/octree/OctreeQueryNode.h @@ -39,7 +39,7 @@ public: void writeToPacket(const unsigned char* buffer, unsigned int bytes); // writes to end of packet - const unsigned char* getPacket() const { return _octreePacket; } + const unsigned char* getPacket() const { return _octreePacket; } unsigned int getPacketLength() const { return (MAX_PACKET_SIZE - _octreePacketAvailableBytes); } bool isPacketWaiting() const { return _octreePacketWaiting; } @@ -100,7 +100,7 @@ public: void forceNodeShutdown(); bool isShuttingDown() const { return _isShuttingDown; } - void incrementSequenceNumber(); + void incrementSequenceNumber(); private slots: void sendThreadFinished(); diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 5c8bb9440e..8d6803adac 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -127,7 +127,7 @@ int OctreeSendThread::handlePacketSend(OctreeQueryNode* nodeData, int& trueBytes return 0; } - bool debug = _myServer->wantsDebugSending(); + bool debug = _myServer->wantsDebugSending(); quint64 now = usecTimestampNow(); bool packetSent = false; // did we send a packet? @@ -242,7 +242,7 @@ int OctreeSendThread::handlePacketSend(OctreeQueryNode* nodeData, int& trueBytes trueBytesSent += nodeData->getPacketLength(); truePacketsSent++; packetsSent++; - nodeData->incrementSequenceNumber(); + nodeData->incrementSequenceNumber(); nodeData->resetOctreePacket(); } From 107c142532e9b6fc231e22e8e491cc06301e88ed Mon Sep 17 00:00:00 2001 From: Kai Ludwig Date: Fri, 23 May 2014 20:21:00 +0200 Subject: [PATCH 41/49] _voxelFades needs locking. --- interface/src/Application.cpp | 10 ++++++++++ interface/src/Application.h | 1 + 2 files changed, 11 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2b552de0ee..95a3c87494 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2525,6 +2525,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { if (_voxelFades.size() > 0) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... voxel fades..."); + _voxelFadesLock.lockForWrite(); for(std::vector::iterator fade = _voxelFades.begin(); fade != _voxelFades.end();) { fade->render(); if(fade->isDone()) { @@ -2533,6 +2534,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { ++fade; } } + _voxelFadesLock.unlock(); } // give external parties a change to hook in @@ -3188,7 +3190,9 @@ void Application::nodeKilled(SharedNodePointer node) { fade.voxelDetails = rootDetails; const float slightly_smaller = 0.99f; fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; + _voxelFadesLock.lockForWrite(); _voxelFades.push_back(fade); + _voxelFadesLock.unlock(); } // If the voxel server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server @@ -3219,7 +3223,9 @@ void Application::nodeKilled(SharedNodePointer node) { fade.voxelDetails = rootDetails; const float slightly_smaller = 0.99f; fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; + _voxelFadesLock.lockForWrite(); _voxelFades.push_back(fade); + _voxelFadesLock.unlock(); } // If the particle server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server @@ -3251,7 +3257,9 @@ void Application::nodeKilled(SharedNodePointer node) { fade.voxelDetails = rootDetails; const float slightly_smaller = 0.99f; fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; + _voxelFadesLock.lockForWrite(); _voxelFades.push_back(fade); + _voxelFadesLock.unlock(); } // If the model server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server @@ -3336,7 +3344,9 @@ int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePoin fade.voxelDetails = rootDetails; const float slightly_smaller = 0.99f; fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; + _voxelFadesLock.lockForWrite(); _voxelFades.push_back(fade); + _voxelFadesLock.unlock(); } } // store jurisdiction details for later use diff --git a/interface/src/Application.h b/interface/src/Application.h index 1968ef4fee..77d948e708 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -533,6 +533,7 @@ private: NodeBounds _nodeBoundsDisplay; std::vector _voxelFades; + QReadWriteLock _voxelFadesLock; ControllerScriptingInterface _controllerScriptingInterface; QPointer _logDialog; QPointer _snapshotShareDialog; From 7fb9e3a7e616b84133e6e1718111d63898872e9b Mon Sep 17 00:00:00 2001 From: Kai Ludwig Date: Fri, 23 May 2014 20:25:20 +0200 Subject: [PATCH 42/49] spaces instead of tabs. --- interface/src/Application.cpp | 20 ++++++++++---------- interface/src/Application.h | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 95a3c87494..ad6c7ebc54 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2525,7 +2525,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { if (_voxelFades.size() > 0) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... voxel fades..."); - _voxelFadesLock.lockForWrite(); + _voxelFadesLock.lockForWrite(); for(std::vector::iterator fade = _voxelFades.begin(); fade != _voxelFades.end();) { fade->render(); if(fade->isDone()) { @@ -2534,7 +2534,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { ++fade; } } - _voxelFadesLock.unlock(); + _voxelFadesLock.unlock(); } // give external parties a change to hook in @@ -3190,9 +3190,9 @@ void Application::nodeKilled(SharedNodePointer node) { fade.voxelDetails = rootDetails; const float slightly_smaller = 0.99f; fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; - _voxelFadesLock.lockForWrite(); + _voxelFadesLock.lockForWrite(); _voxelFades.push_back(fade); - _voxelFadesLock.unlock(); + _voxelFadesLock.unlock(); } // If the voxel server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server @@ -3223,9 +3223,9 @@ void Application::nodeKilled(SharedNodePointer node) { fade.voxelDetails = rootDetails; const float slightly_smaller = 0.99f; fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; - _voxelFadesLock.lockForWrite(); + _voxelFadesLock.lockForWrite(); _voxelFades.push_back(fade); - _voxelFadesLock.unlock(); + _voxelFadesLock.unlock(); } // If the particle server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server @@ -3257,9 +3257,9 @@ void Application::nodeKilled(SharedNodePointer node) { fade.voxelDetails = rootDetails; const float slightly_smaller = 0.99f; fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; - _voxelFadesLock.lockForWrite(); + _voxelFadesLock.lockForWrite(); _voxelFades.push_back(fade); - _voxelFadesLock.unlock(); + _voxelFadesLock.unlock(); } // If the model server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server @@ -3344,9 +3344,9 @@ int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePoin fade.voxelDetails = rootDetails; const float slightly_smaller = 0.99f; fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; - _voxelFadesLock.lockForWrite(); + _voxelFadesLock.lockForWrite(); _voxelFades.push_back(fade); - _voxelFadesLock.unlock(); + _voxelFadesLock.unlock(); } } // store jurisdiction details for later use diff --git a/interface/src/Application.h b/interface/src/Application.h index 77d948e708..9c03dccd0f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -533,7 +533,7 @@ private: NodeBounds _nodeBoundsDisplay; std::vector _voxelFades; - QReadWriteLock _voxelFadesLock; + QReadWriteLock _voxelFadesLock; ControllerScriptingInterface _controllerScriptingInterface; QPointer _logDialog; QPointer _snapshotShareDialog; From 37a939588f543b4fb9769ccad6746fbc962be82d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 23 May 2014 11:28:48 -0700 Subject: [PATCH 43/49] Mode sure the closest model is always selected --- examples/editModels.js | 58 +++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/examples/editModels.js b/examples/editModels.js index 394e9aa783..d53b854003 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -479,6 +479,7 @@ function mousePressEvent(event) { var pickRay = Camera.computePickRay(event.x, event.y); Vec3.print("[Mouse] Looking at: ", pickRay.origin); var foundModels = Models.findModels(pickRay.origin, LASER_LENGTH_FACTOR); + var closest = -1.0; for (var i = 0; i < foundModels.length; i++) { if (!foundModels[i].isKnownID) { var identify = Models.identifyModel(foundModels[i]); @@ -514,36 +515,41 @@ function mousePressEvent(event) { var d = Vec3.length(Vec3.subtract(P, X)); if (d < properties.radius && 0 < x && x < LASER_LENGTH_FACTOR) { - modelSelected = true; - selectedModelID = foundModels[i]; - selectedModelProperties = properties; + if (closest < 0.0) { + closest = x; + } - selectedModelProperties.oldRadius = selectedModelProperties.radius; - selectedModelProperties.oldPosition = { - x: selectedModelProperties.position.x, - y: selectedModelProperties.position.y, - z: selectedModelProperties.position.z, - }; - selectedModelProperties.oldRotation = { - x: selectedModelProperties.modelRotation.x, - y: selectedModelProperties.modelRotation.y, - z: selectedModelProperties.modelRotation.z, - w: selectedModelProperties.modelRotation.w, - }; - - - orientation = MyAvatar.orientation; - intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation)); - - - selectedModelProperties.glowLevel = 0.1; - Models.editModel(selectedModelID, { glowLevel: selectedModelProperties.glowLevel}); - - print("Clicked on " + selectedModelID.id + " " + modelSelected); - return; + if (x <= closest) { + modelSelected = true; + selectedModelID = foundModels[i]; + selectedModelProperties = properties; + + orientation = MyAvatar.orientation; + intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation)); + } } } } + + if (modelSelected) { + selectedModelProperties.oldRadius = selectedModelProperties.radius; + selectedModelProperties.oldPosition = { + x: selectedModelProperties.position.x, + y: selectedModelProperties.position.y, + z: selectedModelProperties.position.z, + }; + selectedModelProperties.oldRotation = { + x: selectedModelProperties.modelRotation.x, + y: selectedModelProperties.modelRotation.y, + z: selectedModelProperties.modelRotation.z, + w: selectedModelProperties.modelRotation.w, + }; + + selectedModelProperties.glowLevel = 0.1; + Models.editModel(selectedModelID, { glowLevel: selectedModelProperties.glowLevel}); + + print("Clicked on " + selectedModelID.id + " " + modelSelected); + } } } From f0f62ced6b07e0ef0a016ad867abac078fe2986d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 23 May 2014 11:41:42 -0700 Subject: [PATCH 44/49] Don't create a glower if no glow --- interface/src/models/ModelTreeRenderer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/models/ModelTreeRenderer.cpp b/interface/src/models/ModelTreeRenderer.cpp index d29303ab79..3f32f7f5ad 100644 --- a/interface/src/models/ModelTreeRenderer.cpp +++ b/interface/src/models/ModelTreeRenderer.cpp @@ -204,9 +204,11 @@ void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) Model::RenderMode modelRenderMode = args->_renderMode == OctreeRenderer::SHADOW_RENDER_MODE ? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE; - { // Sets the glower scope + if (modelItem.getGlowLevel() > 0) { Glower glower(modelItem.getGlowLevel()); model->render(alpha, modelRenderMode); + } else { + model->render(alpha, modelRenderMode); } if (!isShadowMode && displayModelBounds) { From 9acf377573111beb1f76afbe90fc0639203cd1d4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 23 May 2014 11:52:39 -0700 Subject: [PATCH 45/49] balances are 64-bit unsigned ints --- libraries/networking/src/AccountManager.cpp | 2 +- libraries/networking/src/AccountManager.h | 4 ++-- libraries/networking/src/DataServerAccountInfo.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 7d27332a57..96292d7baf 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -98,7 +98,7 @@ void AccountManager::updateBalance() { } } -void AccountManager::accountInfoBalanceChanged(qint64 newBalance) { +void AccountManager::accountInfoBalanceChanged(quint64 newBalance) { emit balanceChanged(newBalance); } diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index 628b084ea8..b761b50610 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -64,7 +64,7 @@ public slots: void requestError(QNetworkReply::NetworkError error); void logout(); void updateBalance(); - void accountInfoBalanceChanged(qint64 newBalance); + void accountInfoBalanceChanged(quint64 newBalance); signals: void authRequired(); void authEndpointChanged(); @@ -73,7 +73,7 @@ signals: void loginComplete(const QUrl& authURL); void loginFailed(); void logoutComplete(); - void balanceChanged(qint64 newBalance); + void balanceChanged(quint64 newBalance); private slots: void processReply(); private: diff --git a/libraries/networking/src/DataServerAccountInfo.h b/libraries/networking/src/DataServerAccountInfo.h index fd135f922b..2777bec4be 100644 --- a/libraries/networking/src/DataServerAccountInfo.h +++ b/libraries/networking/src/DataServerAccountInfo.h @@ -44,7 +44,7 @@ public: friend QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info); friend QDataStream& operator>>(QDataStream &in, DataServerAccountInfo& info); signals: - qint64 balanceChanged(qint64 newBalance); + quint64 balanceChanged(quint64 newBalance); private: void swap(DataServerAccountInfo& otherInfo); From 28536eaef29245b223f1371cc244c0a3c6d51200 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 23 May 2014 11:53:34 -0700 Subject: [PATCH 46/49] CR --- interface/src/models/ModelTreeRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/models/ModelTreeRenderer.cpp b/interface/src/models/ModelTreeRenderer.cpp index 3f32f7f5ad..2ab8a1a7d3 100644 --- a/interface/src/models/ModelTreeRenderer.cpp +++ b/interface/src/models/ModelTreeRenderer.cpp @@ -204,7 +204,7 @@ void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) Model::RenderMode modelRenderMode = args->_renderMode == OctreeRenderer::SHADOW_RENDER_MODE ? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE; - if (modelItem.getGlowLevel() > 0) { + if (modelItem.getGlowLevel() > 0.0f) { Glower glower(modelItem.getGlowLevel()); model->render(alpha, modelRenderMode); } else { From f4292fd29c332ecde41e37ba426f7a2907cf11d9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 23 May 2014 12:33:39 -0700 Subject: [PATCH 47/49] handle serving of scripts at temp unique UUIDs --- assignment-client/src/Agent.cpp | 2 + domain-server/src/DomainServer.cpp | 37 +++++++++++++++++++ .../embedded-webserver/src/HTTPConnection.cpp | 1 + .../embedded-webserver/src/HTTPConnection.h | 1 + 4 files changed, 41 insertions(+) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index e6c14d06da..fcc2288356 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -213,6 +213,8 @@ void Agent::run() { loop.exec(); + + // let the AvatarData and ResourceCache classes use our QNetworkAccessManager AvatarData::setNetworkAccessManager(networkManager); ResourceCache::setNetworkAccessManager(networkManager); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index f979de64c0..28258d59b7 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1004,6 +1004,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url return true; } else { + // check if this is for json stats for a node const QString NODE_JSON_REGEX_STRING = QString("\\%1\\/(%2).json\\/?$").arg(URI_NODES).arg(UUID_REGEX_STRING); QRegExp nodeShowRegex(NODE_JSON_REGEX_STRING); @@ -1028,6 +1029,42 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url // tell the caller we processed the request return true; } + + return false; + } + + // check if this is a request for a scripted assignment (with a temp unique UUID) + const QString ASSIGNMENT_REGEX_STRING = QString("\\%1\\/(%2)\\/?$").arg(URI_ASSIGNMENT).arg(UUID_REGEX_STRING); + QRegExp assignmentRegex(ASSIGNMENT_REGEX_STRING); + + if (assignmentRegex.indexIn(url.path()) != -1) { + QUuid matchingUUID = QUuid(assignmentRegex.cap(1)); + + SharedAssignmentPointer matchingAssignment = _allAssignments.value(matchingUUID); + if (!matchingAssignment) { + // check if we have a pending assignment that matches this temp UUID, and it is a scripted assignment + PendingAssignedNodeData* pendingData = _pendingAssignedNodes.value(matchingUUID); + if (pendingData) { + matchingAssignment = _allAssignments.value(pendingData->getAssignmentUUID()); + + if (matchingAssignment && matchingAssignment->getType() == Assignment::AgentType) { + // we have a matching assignment and it is for the right type, send a temp re-direct to the + // URL for the script so the client can download + + QUrl scriptURL = url; + scriptURL.setPath(URI_ASSIGNMENT + "/" + + uuidStringWithoutCurlyBraces(pendingData->getAssignmentUUID())); + + // have the HTTPManager serve the appropriate script file + return _httpManager.handleHTTPRequest(connection, scriptURL); + } + } else { + return false; + } + } + + // request not handled + return false; } } } else if (connection->requestOperation() == QNetworkAccessManager::PostOperation) { diff --git a/libraries/embedded-webserver/src/HTTPConnection.cpp b/libraries/embedded-webserver/src/HTTPConnection.cpp index a6eb391138..beb107c4cf 100755 --- a/libraries/embedded-webserver/src/HTTPConnection.cpp +++ b/libraries/embedded-webserver/src/HTTPConnection.cpp @@ -19,6 +19,7 @@ const char* HTTPConnection::StatusCode200 = "200 OK"; const char* HTTPConnection::StatusCode301 = "301 Moved Permanently"; +const char* HTTPConnection::StatusCode302 = "302 Found"; const char* HTTPConnection::StatusCode400 = "400 Bad Request"; const char* HTTPConnection::StatusCode404 = "404 Not Found"; const char* HTTPConnection::DefaultContentType = "text/plain; charset=ISO-8859-1"; diff --git a/libraries/embedded-webserver/src/HTTPConnection.h b/libraries/embedded-webserver/src/HTTPConnection.h index d5214ee3a8..e2352ed250 100644 --- a/libraries/embedded-webserver/src/HTTPConnection.h +++ b/libraries/embedded-webserver/src/HTTPConnection.h @@ -44,6 +44,7 @@ class HTTPConnection : public QObject { public: static const char* StatusCode200; static const char* StatusCode301; + static const char* StatusCode302; static const char* StatusCode400; static const char* StatusCode404; static const char* DefaultContentType; From 7e78fc788a1b46714afe29efe416a262ca356332 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 23 May 2014 12:35:16 -0700 Subject: [PATCH 48/49] fix double return false --- domain-server/src/DomainServer.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 28258d59b7..c814f81313 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1058,8 +1058,6 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url // have the HTTPManager serve the appropriate script file return _httpManager.handleHTTPRequest(connection, scriptURL); } - } else { - return false; } } From e7e19e87143f3991de50bcbb33177bb76c63aa97 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 23 May 2014 12:37:27 -0700 Subject: [PATCH 49/49] fix a comment in script handling --- domain-server/src/DomainServer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index c814f81313..a530be5dad 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1048,8 +1048,8 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url matchingAssignment = _allAssignments.value(pendingData->getAssignmentUUID()); if (matchingAssignment && matchingAssignment->getType() == Assignment::AgentType) { - // we have a matching assignment and it is for the right type, send a temp re-direct to the - // URL for the script so the client can download + // we have a matching assignment and it is for the right type, have the HTTP manager handle it + // via correct URL for the script so the client can download QUrl scriptURL = url; scriptURL.setPath(URI_ASSIGNMENT + "/"