From e5fc2e552550dc03fa933d8a291c5fd06490326d Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 8 Oct 2015 14:03:59 -0700 Subject: [PATCH 01/49] Low level support for URL overrides when loading content --- .../src/EntityTreeRenderer.cpp | 4 +- libraries/networking/src/ResourceManager.cpp | 38 +++++++++++++++++-- libraries/networking/src/ResourceManager.h | 2 + .../procedural/src/procedural/Procedural.cpp | 1 + 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 7dea243145..fb9ab6563b 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -704,7 +704,9 @@ void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, const if (_tree && !_shuttingDown) { EntityItemPointer entity = getTree()->findEntityByEntityItemID(entityID); if (entity && !entity->getScript().isEmpty()) { - _entitiesScriptEngine->loadEntityScript(entityID, entity->getScript(), reload); + QString scriptUrl = entity->getScript(); + scriptUrl = ResourceManager::normalizeURL(scriptUrl); + _entitiesScriptEngine->loadEntityScript(entityID, scriptUrl, reload); } } } diff --git a/libraries/networking/src/ResourceManager.cpp b/libraries/networking/src/ResourceManager.cpp index 774664f2c8..6b97018ed9 100644 --- a/libraries/networking/src/ResourceManager.cpp +++ b/libraries/networking/src/ResourceManager.cpp @@ -17,7 +17,37 @@ #include -QUrl ResourceManager::normalizeURL(const QUrl& url) { + +using PrefixMap = std::map; +static PrefixMap PREFIX_MAP; +static QMutex PREFIX_MAP_LOCK; + +void ResourceManager::setUrlPrefixOverride(const QString& prefix, const QString& replacement) { + QMutexLocker locker(&PREFIX_MAP_LOCK); + PREFIX_MAP[prefix] = replacement; +} + +QString ResourceManager::normalizeURL(const QString& urlString) { + QString result = urlString; + QMutexLocker locker(&PREFIX_MAP_LOCK); + bool modified{ false }; + foreach(const auto& entry, PREFIX_MAP) { + const auto& prefix = entry.first; + const auto& replacement = entry.second; + if (result.startsWith(prefix)) { + qDebug() << prefix; + result.replace(0, prefix.size(), replacement); + modified = true; + } + } + if (modified) { + qDebug() << result; + } + return result; +} + +QUrl ResourceManager::normalizeURL(const QUrl& originalUrl) { + QUrl url = QUrl(normalizeURL(originalUrl.toString())); auto scheme = url.scheme(); if (!(scheme == URL_SCHEME_FILE || scheme == URL_SCHEME_HTTP || scheme == URL_SCHEME_HTTPS || scheme == URL_SCHEME_FTP || @@ -37,11 +67,11 @@ ResourceRequest* ResourceManager::createResourceRequest(QObject* parent, const Q auto normalizedURL = normalizeURL(url); auto scheme = normalizedURL.scheme(); if (scheme == URL_SCHEME_FILE) { - return new FileResourceRequest(parent, url); + return new FileResourceRequest(parent, normalizedURL); } else if (scheme == URL_SCHEME_HTTP || scheme == URL_SCHEME_HTTPS || scheme == URL_SCHEME_FTP) { - return new HTTPResourceRequest(parent, url); + return new HTTPResourceRequest(parent, normalizedURL); } else if (scheme == URL_SCHEME_ATP) { - return new AssetResourceRequest(parent, url); + return new AssetResourceRequest(parent, normalizedURL); } qDebug() << "Unknown scheme (" << scheme << ") for URL: " << url.url(); diff --git a/libraries/networking/src/ResourceManager.h b/libraries/networking/src/ResourceManager.h index 40b67b1cd1..58f4679c97 100644 --- a/libraries/networking/src/ResourceManager.h +++ b/libraries/networking/src/ResourceManager.h @@ -24,6 +24,8 @@ const QString URL_SCHEME_ATP = "atp"; class ResourceManager { public: + static void setUrlPrefixOverride(const QString& prefix, const QString& replacement); + static QString normalizeURL(const QString& urlString); static QUrl normalizeURL(const QUrl& url); static ResourceRequest* createResourceRequest(QObject* parent, const QUrl& url); }; diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index f5448bda5c..a0020d21f3 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -88,6 +88,7 @@ void Procedural::parse(const QJsonObject& proceduralData) { // Get the path to the shader { QString shaderUrl = proceduralData[URL_KEY].toString(); + shaderUrl = ResourceManager::normalizeURL(shaderUrl); _shaderUrl = QUrl(shaderUrl); if (!_shaderUrl.isValid()) { qWarning() << "Invalid shader URL: " << shaderUrl; From 6f5f6450dfcca1877d00ffc49ab6a49d5a724112 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sun, 11 Oct 2015 00:01:03 -0700 Subject: [PATCH 02/49] Cleanup CMake files --- assignment-client/CMakeLists.txt | 4 -- cmake/macros/LinkHifiLibraries.cmake | 1 - cmake/macros/SetupHifiLibrary.cmake | 4 ++ cmake/macros/SetupHifiProject.cmake | 3 ++ cmake/macros/SetupHifiTestCase.cmake | 6 ++- cmake/macros/TargetBullet.cmake | 18 ++++++++ cmake/macros/TargetGlew.cmake | 14 ++++++ cmake/macros/TargetGlm.cmake | 12 +++++ cmake/macros/TargetNsight.cmake | 20 +++++++++ cmake/macros/TargetOglplus.cmake | 21 +++++++++ ...tupHifiOpenGL.cmake => TargetOpenGL.cmake} | 32 ++++--------- gvr-interface/CMakeLists.txt | 4 -- interface/CMakeLists.txt | 24 +++------- libraries/animation/CMakeLists.txt | 3 -- libraries/audio-client/CMakeLists.txt | 5 --- libraries/audio/CMakeLists.txt | 7 --- libraries/auto-updater/CMakeLists.txt | 1 - libraries/avatars/CMakeLists.txt | 7 --- libraries/display-plugins/CMakeLists.txt | 21 ++------- libraries/embedded-webserver/CMakeLists.txt | 2 - libraries/entities-renderer/CMakeLists.txt | 21 +-------- libraries/entities/CMakeLists.txt | 23 ++-------- libraries/environment/CMakeLists.txt | 7 --- libraries/fbx/CMakeLists.txt | 7 --- libraries/gpu/CMakeLists.txt | 45 +------------------ libraries/input-plugins/CMakeLists.txt | 27 +++++------ libraries/model-networking/CMakeLists.txt | 7 --- libraries/model/CMakeLists.txt | 9 +--- libraries/networking/CMakeLists.txt | 3 -- libraries/octree/CMakeLists.txt | 7 --- libraries/physics/CMakeLists.txt | 23 +--------- libraries/plugins/CMakeLists.txt | 8 ---- libraries/procedural/CMakeLists.txt | 9 +--- libraries/render-utils/CMakeLists.txt | 42 ++--------------- libraries/render/CMakeLists.txt | 21 +-------- libraries/script-engine/CMakeLists.txt | 7 --- libraries/shared/CMakeLists.txt | 6 +-- libraries/ui/CMakeLists.txt | 8 ---- tests/gpu-test/CMakeLists.txt | 8 ---- tests/physics/CMakeLists.txt | 17 +------ 40 files changed, 141 insertions(+), 373 deletions(-) create mode 100644 cmake/macros/TargetBullet.cmake create mode 100644 cmake/macros/TargetGlew.cmake create mode 100644 cmake/macros/TargetGlm.cmake create mode 100644 cmake/macros/TargetNsight.cmake create mode 100644 cmake/macros/TargetOglplus.cmake rename cmake/macros/{SetupHifiOpenGL.cmake => TargetOpenGL.cmake} (58%) diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index 84a36c6c51..e543b3aa21 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -2,10 +2,6 @@ set(TARGET_NAME assignment-client) setup_hifi_project(Core Gui Network Script Widgets WebSockets) -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PRIVATE ${GLM_INCLUDE_DIRS}) - # link in the shared libraries link_hifi_libraries( audio avatars octree environment gpu model fbx entities diff --git a/cmake/macros/LinkHifiLibraries.cmake b/cmake/macros/LinkHifiLibraries.cmake index d0a12f3bea..70399bedb4 100644 --- a/cmake/macros/LinkHifiLibraries.cmake +++ b/cmake/macros/LinkHifiLibraries.cmake @@ -16,7 +16,6 @@ macro(LINK_HIFI_LIBRARIES) foreach(HIFI_LIBRARY ${LIBRARIES_TO_LINK}) if (NOT TARGET ${HIFI_LIBRARY}) add_subdirectory("${RELATIVE_LIBRARY_DIR_PATH}/${HIFI_LIBRARY}" "${RELATIVE_LIBRARY_DIR_PATH}/${HIFI_LIBRARY}") - set_target_properties(${HIFI_LIBRARY} PROPERTIES FOLDER "Libraries") endif () include_directories("${HIFI_LIBRARY_DIR}/${HIFI_LIBRARY}/src") diff --git a/cmake/macros/SetupHifiLibrary.cmake b/cmake/macros/SetupHifiLibrary.cmake index ccb5ca2484..9c6cbf6831 100644 --- a/cmake/macros/SetupHifiLibrary.cmake +++ b/cmake/macros/SetupHifiLibrary.cmake @@ -36,5 +36,9 @@ macro(SETUP_HIFI_LIBRARY) # Don't make scribed shaders cumulative set(AUTOSCRIBE_SHADER_LIB_SRC "") + + target_glm() + + set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Libraries") endmacro(SETUP_HIFI_LIBRARY) \ No newline at end of file diff --git a/cmake/macros/SetupHifiProject.cmake b/cmake/macros/SetupHifiProject.cmake index bd6cbef9dc..166a3fd4b9 100644 --- a/cmake/macros/SetupHifiProject.cmake +++ b/cmake/macros/SetupHifiProject.cmake @@ -34,4 +34,7 @@ macro(SETUP_HIFI_PROJECT) foreach(QT_MODULE ${${TARGET_NAME}_DEPENDENCY_QT_MODULES}) target_link_libraries(${TARGET_NAME} Qt5::${QT_MODULE}) endforeach() + + target_glm() + endmacro() diff --git a/cmake/macros/SetupHifiTestCase.cmake b/cmake/macros/SetupHifiTestCase.cmake index 2507a30f5e..38239d6e97 100644 --- a/cmake/macros/SetupHifiTestCase.cmake +++ b/cmake/macros/SetupHifiTestCase.cmake @@ -94,6 +94,7 @@ macro(SETUP_HIFI_TESTCASE) EXCLUDE_FROM_DEFAULT_BUILD TRUE EXCLUDE_FROM_ALL TRUE) + list (APPEND ${TEST_PROJ_NAME}_TARGETS ${TARGET_NAME}) #list (APPEND ALL_TEST_TARGETS ${TARGET_NAME}) @@ -111,8 +112,9 @@ macro(SETUP_HIFI_TESTCASE) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "hidden/test-executables") # handle testcase-specific dependencies (this a macro that should be defined in the cmakelists.txt file in each tests subdir) - - SETUP_TESTCASE_DEPENDENCIES () + SETUP_TESTCASE_DEPENDENCIES() + target_glm() + endforeach () set(TEST_TARGET ${TEST_PROJ_NAME}-tests) diff --git a/cmake/macros/TargetBullet.cmake b/cmake/macros/TargetBullet.cmake new file mode 100644 index 0000000000..600ae9e63b --- /dev/null +++ b/cmake/macros/TargetBullet.cmake @@ -0,0 +1,18 @@ +# +# Copyright 2015 High Fidelity, Inc. +# Created by Bradley Austin Davis on 2015/10/10 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# +macro(TARGET_BULLET) + add_dependency_external_projects(bullet) + find_package(Bullet REQUIRED) + # perform the system include hack for OS X to ignore warnings + if (APPLE) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${BULLET_INCLUDE_DIRS}") + else() + target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BULLET_INCLUDE_DIRS}) + endif() + target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) +endmacro() \ No newline at end of file diff --git a/cmake/macros/TargetGlew.cmake b/cmake/macros/TargetGlew.cmake new file mode 100644 index 0000000000..5f71f021ec --- /dev/null +++ b/cmake/macros/TargetGlew.cmake @@ -0,0 +1,14 @@ +# +# Copyright 2015 High Fidelity, Inc. +# Created by Bradley Austin Davis on 2015/10/10 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# +macro(TARGET_GLEW) + add_dependency_external_projects(glew) + find_package(GLEW REQUIRED) + add_definitions(-DGLEW_STATIC) + target_include_directories(${TARGET_NAME} PUBLIC ${GLEW_INCLUDE_DIRS}) + target_link_libraries(${TARGET_NAME} ${GLEW_LIBRARY}) +endmacro() \ No newline at end of file diff --git a/cmake/macros/TargetGlm.cmake b/cmake/macros/TargetGlm.cmake new file mode 100644 index 0000000000..324cb1c17a --- /dev/null +++ b/cmake/macros/TargetGlm.cmake @@ -0,0 +1,12 @@ +# +# Copyright 2015 High Fidelity, Inc. +# Created by Bradley Austin Davis on 2015/10/10 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# +macro(TARGET_GLM) + add_dependency_external_projects(glm) + find_package(GLM REQUIRED) + target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) +endmacro() \ No newline at end of file diff --git a/cmake/macros/TargetNsight.cmake b/cmake/macros/TargetNsight.cmake new file mode 100644 index 0000000000..4b7e87e9d3 --- /dev/null +++ b/cmake/macros/TargetNsight.cmake @@ -0,0 +1,20 @@ +# +# Copyright 2015 High Fidelity, Inc. +# Created by Bradley Austin Davis on 2015/10/10 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# +macro(TARGET_NSIGHT) + if (WIN32) + if (USE_NSIGHT) + # try to find the Nsight package and add it to the build if we find it + find_package(NSIGHT) + if (NSIGHT_FOUND) + include_directories(${NSIGHT_INCLUDE_DIRS}) + add_definitions(-DNSIGHT_FOUND) + target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}") + endif () + endif() + endif (WIN32) +endmacro() \ No newline at end of file diff --git a/cmake/macros/TargetOglplus.cmake b/cmake/macros/TargetOglplus.cmake new file mode 100644 index 0000000000..16a50f3dd7 --- /dev/null +++ b/cmake/macros/TargetOglplus.cmake @@ -0,0 +1,21 @@ +# +# Copyright 2015 High Fidelity, Inc. +# Created by Bradley Austin Davis on 2015/10/10 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# +macro(TARGET_OGLPLUS) + # our OGL plus setup requires glew + target_glew() + + # our OGL plus setup requires boostconfig + add_dependency_external_projects(boostconfig) + find_package(BoostConfig REQUIRED) + target_include_directories(${TARGET_NAME} PUBLIC ${BOOSTCONFIG_INCLUDE_DIRS}) + + + add_dependency_external_projects(oglplus) + find_package(OGLPLUS REQUIRED) + target_include_directories(${TARGET_NAME} PUBLIC ${OGLPLUS_INCLUDE_DIRS}) +endmacro() \ No newline at end of file diff --git a/cmake/macros/SetupHifiOpenGL.cmake b/cmake/macros/TargetOpenGL.cmake similarity index 58% rename from cmake/macros/SetupHifiOpenGL.cmake rename to cmake/macros/TargetOpenGL.cmake index 2b1858fd4b..7b3178d579 100644 --- a/cmake/macros/SetupHifiOpenGL.cmake +++ b/cmake/macros/TargetOpenGL.cmake @@ -1,38 +1,24 @@ - - -macro(SETUP_HIFI_OPENGL) - +# +# Copyright 2015 High Fidelity, Inc. +# Created by Bradley Austin Davis on 2015/10/10 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# +macro(TARGET_OPENGL) if (APPLE) - # link in required OS X frameworks and include the right GL headers find_library(OpenGL OpenGL) target_link_libraries(${TARGET_NAME} ${OpenGL}) - - elseif (WIN32) - - if (USE_NSIGHT) - # try to find the Nsight package and add it to the build if we find it - find_package(NSIGHT) - if (NSIGHT_FOUND) - include_directories(${NSIGHT_INCLUDE_DIRS}) - add_definitions(-DNSIGHT_FOUND) - target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}") - endif() - endif() - elseif(ANDROID) - target_link_libraries(${TARGET_NAME} "-lGLESv3" "-lEGL") - else() - + target_nsight() find_package(OpenGL REQUIRED) if (${OPENGL_INCLUDE_DIR}) include_directories(SYSTEM "${OPENGL_INCLUDE_DIR}") endif() target_link_libraries(${TARGET_NAME} "${OPENGL_LIBRARY}") target_include_directories(${TARGET_NAME} PUBLIC ${OPENGL_INCLUDE_DIR}) - endif() - endmacro() diff --git a/gvr-interface/CMakeLists.txt b/gvr-interface/CMakeLists.txt index 2c1e87c8b4..175706a3ff 100644 --- a/gvr-interface/CMakeLists.txt +++ b/gvr-interface/CMakeLists.txt @@ -24,10 +24,6 @@ endif () include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PRIVATE ${GLM_INCLUDE_DIRS}) - link_hifi_libraries(shared networking audio-client avatars) if (ANDROID) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 63d1445496..00f6d2ecea 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -1,8 +1,6 @@ set(TARGET_NAME interface) project(${TARGET_NAME}) -add_definitions(-DGLEW_STATIC) - # set a default root dir for each of our optional externals if it was not passed set(OPTIONAL_EXTERNALS "Faceshift" "LeapMotion" "RtMidi" "RSSDK" "3DConnexionClient" "iViewHMD") foreach(EXTERNAL ${OPTIONAL_EXTERNALS}) @@ -97,29 +95,17 @@ else() add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM}) endif() -add_dependency_external_projects(glm bullet) - -# set up the external glm library -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PRIVATE ${GLM_INCLUDE_DIRS}) - -find_package(Bullet REQUIRED) - -# perform the system include hack for OS X to ignore warnings -if (APPLE) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${BULLET_INCLUDE_DIRS}") -else() - target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BULLET_INCLUDE_DIRS}) -endif() - -target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) - # link required hifi libraries link_hifi_libraries(shared octree environment gpu procedural model render fbx networking model-networking entities avatars audio audio-client animation script-engine physics render-utils entities-renderer ui auto-updater plugins display-plugins input-plugins) +target_bullet() +target_glew() +target_opengl() + + add_dependency_external_projects(sdl2) # perform standard include and linking for found externals diff --git a/libraries/animation/CMakeLists.txt b/libraries/animation/CMakeLists.txt index 115a2e360c..3cf7bfa295 100644 --- a/libraries/animation/CMakeLists.txt +++ b/libraries/animation/CMakeLists.txt @@ -1,6 +1,3 @@ set(TARGET_NAME animation) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(Network Script) - link_hifi_libraries(shared gpu model fbx) diff --git a/libraries/audio-client/CMakeLists.txt b/libraries/audio-client/CMakeLists.txt index f631ec6387..90937edc5d 100644 --- a/libraries/audio-client/CMakeLists.txt +++ b/libraries/audio-client/CMakeLists.txt @@ -1,8 +1,5 @@ set(TARGET_NAME audio-client) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(Network Multimedia) - link_hifi_libraries(audio) # append audio includes to our list of includes to bubble @@ -10,9 +7,7 @@ target_include_directories(${TARGET_NAME} PUBLIC "${HIFI_LIBRARY_DIR}/audio/src" # have CMake grab externals for us add_dependency_external_projects(gverb) - find_package(Gverb REQUIRED) - target_link_libraries(${TARGET_NAME} ${GVERB_LIBRARIES}) target_include_directories(${TARGET_NAME} PRIVATE ${GVERB_INCLUDE_DIRS}) diff --git a/libraries/audio/CMakeLists.txt b/libraries/audio/CMakeLists.txt index 5134ccda36..c49c9547a5 100644 --- a/libraries/audio/CMakeLists.txt +++ b/libraries/audio/CMakeLists.txt @@ -1,10 +1,3 @@ set(TARGET_NAME audio) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(Network) - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - link_hifi_libraries(networking shared) diff --git a/libraries/auto-updater/CMakeLists.txt b/libraries/auto-updater/CMakeLists.txt index c3d6e74a6f..b3665af2cb 100644 --- a/libraries/auto-updater/CMakeLists.txt +++ b/libraries/auto-updater/CMakeLists.txt @@ -1,4 +1,3 @@ set(TARGET_NAME auto-updater) - setup_hifi_library(Network) link_hifi_libraries(shared networking) diff --git a/libraries/avatars/CMakeLists.txt b/libraries/avatars/CMakeLists.txt index acc939b25c..849828bbf6 100644 --- a/libraries/avatars/CMakeLists.txt +++ b/libraries/avatars/CMakeLists.txt @@ -1,10 +1,3 @@ set(TARGET_NAME avatars) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(Network Script) - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - link_hifi_libraries(audio shared networking) diff --git a/libraries/display-plugins/CMakeLists.txt b/libraries/display-plugins/CMakeLists.txt index b602327f4c..504370796a 100644 --- a/libraries/display-plugins/CMakeLists.txt +++ b/libraries/display-plugins/CMakeLists.txt @@ -1,27 +1,12 @@ set(TARGET_NAME display-plugins) - -add_definitions(-DGLEW_STATIC) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(OpenGL) - -setup_hifi_opengl() - link_hifi_libraries(shared plugins gpu render-utils) +target_opengl() + GroupSources("src/display-plugins") -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - -add_dependency_external_projects(boostconfig) -find_package(BoostConfig REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${BOOSTCONFIG_INCLUDE_DIRS}) - -add_dependency_external_projects(oglplus) -find_package(OGLPLUS REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${OGLPLUS_INCLUDE_DIRS}) +target_oglplus() add_dependency_external_projects(LibOVR) find_package(LibOVR REQUIRED) diff --git a/libraries/embedded-webserver/CMakeLists.txt b/libraries/embedded-webserver/CMakeLists.txt index 45d9827d42..b23be3a7a2 100644 --- a/libraries/embedded-webserver/CMakeLists.txt +++ b/libraries/embedded-webserver/CMakeLists.txt @@ -1,4 +1,2 @@ set(TARGET_NAME embedded-webserver) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(Network) diff --git a/libraries/entities-renderer/CMakeLists.txt b/libraries/entities-renderer/CMakeLists.txt index d092f188e1..bb90c04c95 100644 --- a/libraries/entities-renderer/CMakeLists.txt +++ b/libraries/entities-renderer/CMakeLists.txt @@ -1,29 +1,12 @@ set(TARGET_NAME entities-renderer) - AUTOSCRIBE_SHADER_LIB(gpu model render render-utils) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(Widgets Network Script) +link_hifi_libraries(shared gpu procedural model model-networking script-engine render render-utils) -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - -add_dependency_external_projects(bullet) -find_package(Bullet REQUIRED) - -# perform the system include hack for OS X to ignore warnings -if (APPLE) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${BULLET_INCLUDE_DIRS}") -else() - target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BULLET_INCLUDE_DIRS}) -endif() - -target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) +target_bullet() add_dependency_external_projects(polyvox) find_package(PolyVox REQUIRED) target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${POLYVOX_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${POLYVOX_LIBRARIES}) -link_hifi_libraries(shared gpu procedural model model-networking script-engine render render-utils) diff --git a/libraries/entities/CMakeLists.txt b/libraries/entities/CMakeLists.txt index f7936ff125..f6b2e0e280 100644 --- a/libraries/entities/CMakeLists.txt +++ b/libraries/entities/CMakeLists.txt @@ -1,24 +1,7 @@ set(TARGET_NAME entities) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(Network Script) - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - -add_dependency_external_projects(bullet) - -find_package(Bullet REQUIRED) - -# perform the system include hack for OS X to ignore warnings -if (APPLE) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${BULLET_INCLUDE_DIRS}") -else() - target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BULLET_INCLUDE_DIRS}) -endif() - -target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) - link_hifi_libraries(avatars shared octree gpu model fbx networking animation environment) + +target_bullet() + include_hifi_library_headers(render) diff --git a/libraries/environment/CMakeLists.txt b/libraries/environment/CMakeLists.txt index e3fc143c14..11538a8f2b 100644 --- a/libraries/environment/CMakeLists.txt +++ b/libraries/environment/CMakeLists.txt @@ -1,10 +1,3 @@ set(TARGET_NAME environment) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library() - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - link_hifi_libraries(shared networking) diff --git a/libraries/fbx/CMakeLists.txt b/libraries/fbx/CMakeLists.txt index 9d9f57ad20..e10b6bcfd5 100644 --- a/libraries/fbx/CMakeLists.txt +++ b/libraries/fbx/CMakeLists.txt @@ -1,10 +1,3 @@ set(TARGET_NAME fbx) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library() - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - link_hifi_libraries(shared gpu model networking octree) diff --git a/libraries/gpu/CMakeLists.txt b/libraries/gpu/CMakeLists.txt index 38fe5cb22f..63da1d8f8a 100644 --- a/libraries/gpu/CMakeLists.txt +++ b/libraries/gpu/CMakeLists.txt @@ -1,48 +1,7 @@ set(TARGET_NAME gpu) - AUTOSCRIBE_SHADER_LIB(gpu) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library() - link_hifi_libraries(shared) -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - -add_dependency_external_projects(glew) -find_package(GLEW REQUIRED) -add_definitions(-DGLEW_STATIC) -target_include_directories(${TARGET_NAME} PUBLIC ${GLEW_INCLUDE_DIRS}) -target_link_libraries(${TARGET_NAME} ${GLEW_LIBRARY}) - -if (APPLE) - # link in required OS X frameworks and include the right GL headers - find_library(OpenGL OpenGL) - target_link_libraries(${TARGET_NAME} ${OpenGL}) -elseif (WIN32) - target_link_libraries(${TARGET_NAME} ${GLEW_LIBRARY} opengl32.lib) - - if (USE_NSIGHT) - # try to find the Nsight package and add it to the build if we find it - # note that this will also enable NSIGHT profilers in all the projects linking gpu - find_package(NSIGHT) - if (NSIGHT_FOUND) - target_include_directories(${TARGET_NAME} PUBLIC ${NSIGHT_INCLUDE_DIRS}) - target_compile_definitions(${TARGET_NAME} PUBLIC NSIGHT_FOUND) - target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}") - endif () - endif() -elseif (ANDROID) - target_link_libraries(${TARGET_NAME} "-lGLESv3" "-lEGL") -else () - - find_package(OpenGL REQUIRED) - - if (${OPENGL_INCLUDE_DIR}) - include_directories(SYSTEM "${OPENGL_INCLUDE_DIR}") - endif () - - target_link_libraries(${TARGET_NAME} "${OPENGL_LIBRARY}") -endif (APPLE) +target_glew() +target_opengl() \ No newline at end of file diff --git a/libraries/input-plugins/CMakeLists.txt b/libraries/input-plugins/CMakeLists.txt index 1ac8047edc..094a697012 100644 --- a/libraries/input-plugins/CMakeLists.txt +++ b/libraries/input-plugins/CMakeLists.txt @@ -1,26 +1,9 @@ set(TARGET_NAME input-plugins) - -# set a default root dir for each of our optional externals if it was not passed -set(OPTIONAL_EXTERNALS "SDL2" "Sixense") -foreach(EXTERNAL ${OPTIONAL_EXTERNALS}) - string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE) - if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR) - string(TOLOWER ${EXTERNAL} ${EXTERNAL}_LOWERCASE) - set(${${EXTERNAL}_UPPERCASE}_ROOT_DIR "${CMAKE_SOURCE_DIR}/interface/external/${${EXTERNAL}_LOWERCASE}") - endif () -endforeach() - setup_hifi_library() - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules link_hifi_libraries(shared plugins gpu render-utils) GroupSources("src/input-plugins") -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - if (WIN32) add_dependency_external_projects(OpenVR) find_package(OpenVR REQUIRED) @@ -33,6 +16,16 @@ endif() #target_include_directories(${TARGET_NAME} PRIVATE ${SIXENSE_INCLUDE_DIRS}) #target_link_libraries(${TARGET_NAME} ${SIXENSE_LIBRARIES}) +# set a default root dir for each of our optional externals if it was not passed +set(OPTIONAL_EXTERNALS "SDL2" "Sixense") +foreach(EXTERNAL ${OPTIONAL_EXTERNALS}) + string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE) + if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR) + string(TOLOWER ${EXTERNAL} ${EXTERNAL}_LOWERCASE) + set(${${EXTERNAL}_UPPERCASE}_ROOT_DIR "${CMAKE_SOURCE_DIR}/interface/external/${${EXTERNAL}_LOWERCASE}") + endif () +endforeach() + # perform standard include and linking for found externals foreach(EXTERNAL ${OPTIONAL_EXTERNALS}) diff --git a/libraries/model-networking/CMakeLists.txt b/libraries/model-networking/CMakeLists.txt index f014885794..29ab17f2ec 100644 --- a/libraries/model-networking/CMakeLists.txt +++ b/libraries/model-networking/CMakeLists.txt @@ -1,11 +1,4 @@ set(TARGET_NAME model-networking) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library() - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - link_hifi_libraries(shared networking gpu model fbx) diff --git a/libraries/model/CMakeLists.txt b/libraries/model/CMakeLists.txt index c30ffb7238..63f632e484 100755 --- a/libraries/model/CMakeLists.txt +++ b/libraries/model/CMakeLists.txt @@ -1,12 +1,5 @@ set(TARGET_NAME model) - AUTOSCRIBE_SHADER_LIB(gpu model) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library() - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - link_hifi_libraries(shared gpu) + diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index 274dae7420..470c9145df 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -1,8 +1,5 @@ set(TARGET_NAME networking) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(Network) - link_hifi_libraries(shared) if (WIN32) diff --git a/libraries/octree/CMakeLists.txt b/libraries/octree/CMakeLists.txt index cc36aead15..bea036add3 100644 --- a/libraries/octree/CMakeLists.txt +++ b/libraries/octree/CMakeLists.txt @@ -1,10 +1,3 @@ set(TARGET_NAME octree) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library() - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - link_hifi_libraries(shared networking) diff --git a/libraries/physics/CMakeLists.txt b/libraries/physics/CMakeLists.txt index b1f9fbb79c..b734c9ac2e 100644 --- a/libraries/physics/CMakeLists.txt +++ b/libraries/physics/CMakeLists.txt @@ -1,24 +1,5 @@ set(TARGET_NAME physics) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library() - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - -add_dependency_external_projects(bullet) - -find_package(Bullet REQUIRED) - -# perform the system include hack for OS X to ignore warnings -if (APPLE) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${BULLET_INCLUDE_DIRS}") -else() - target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BULLET_INCLUDE_DIRS}) -endif() - -target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) - link_hifi_libraries(shared fbx entities) -include_hifi_library_headers(fbx) + +target_bullet() diff --git a/libraries/plugins/CMakeLists.txt b/libraries/plugins/CMakeLists.txt index 42b8cb1625..f32650df94 100644 --- a/libraries/plugins/CMakeLists.txt +++ b/libraries/plugins/CMakeLists.txt @@ -1,11 +1,3 @@ set(TARGET_NAME plugins) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(OpenGL) - link_hifi_libraries(shared) - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) - -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) diff --git a/libraries/procedural/CMakeLists.txt b/libraries/procedural/CMakeLists.txt index 9595ef5f7a..0483b8d3a8 100644 --- a/libraries/procedural/CMakeLists.txt +++ b/libraries/procedural/CMakeLists.txt @@ -1,12 +1,5 @@ set(TARGET_NAME procedural) - AUTOSCRIBE_SHADER_LIB(gpu model) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library() - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - link_hifi_libraries(shared gpu model model-networking) + diff --git a/libraries/render-utils/CMakeLists.txt b/libraries/render-utils/CMakeLists.txt index fa6cc6fe77..c74089a238 100644 --- a/libraries/render-utils/CMakeLists.txt +++ b/libraries/render-utils/CMakeLists.txt @@ -1,45 +1,9 @@ set(TARGET_NAME render-utils) - AUTOSCRIBE_SHADER_LIB(gpu model render) - # pull in the resources.qrc file qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc") - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(Widgets OpenGL Network Qml Quick Script) - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - -add_dependency_external_projects(boostconfig) -find_package(BoostConfig REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${BOOSTCONFIG_INCLUDE_DIRS}) - -add_dependency_external_projects(oglplus) -find_package(OGLPLUS REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${OGLPLUS_INCLUDE_DIRS}) - -add_definitions(-DGLEW_STATIC) - -if (WIN32) - if (USE_NSIGHT) - # try to find the Nsight package and add it to the build if we find it - find_package(NSIGHT) - if (NSIGHT_FOUND) - include_directories(${NSIGHT_INCLUDE_DIRS}) - add_definitions(-DNSIGHT_FOUND) - target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}") - endif () - endif() -endif (WIN32) - -add_dependency_external_projects(boostconfig) -find_package(BoostConfig REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${BOOSTCONFIG_INCLUDE_DIRS}) - -add_dependency_external_projects(oglplus) -find_package(OGLPLUS REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${OGLPLUS_INCLUDE_DIRS}) - link_hifi_libraries(shared gpu procedural model model-networking render environment animation fbx) + +target_nsight() +target_oglplus() diff --git a/libraries/render/CMakeLists.txt b/libraries/render/CMakeLists.txt index f2bcb7c47c..76fc8303ce 100644 --- a/libraries/render/CMakeLists.txt +++ b/libraries/render/CMakeLists.txt @@ -1,24 +1,7 @@ set(TARGET_NAME render) - AUTOSCRIBE_SHADER_LIB(gpu model) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library() - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - link_hifi_libraries(shared gpu model) -if (WIN32) - if (USE_NSIGHT) - # try to find the Nsight package and add it to the build if we find it - find_package(NSIGHT) - if (NSIGHT_FOUND) - include_directories(${NSIGHT_INCLUDE_DIRS}) - add_definitions(-DNSIGHT_FOUND) - target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}") - endif () - endif() -endif (WIN32) + +target_nsight() diff --git a/libraries/script-engine/CMakeLists.txt b/libraries/script-engine/CMakeLists.txt index a458d4de51..cfe0afd220 100644 --- a/libraries/script-engine/CMakeLists.txt +++ b/libraries/script-engine/CMakeLists.txt @@ -1,10 +1,3 @@ set(TARGET_NAME script-engine) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(Gui Network Script WebSockets Widgets) - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - link_hifi_libraries(shared networking octree gpu procedural model model-networking fbx entities animation audio physics) diff --git a/libraries/shared/CMakeLists.txt b/libraries/shared/CMakeLists.txt index 00a80619bc..d9df5eba7f 100644 --- a/libraries/shared/CMakeLists.txt +++ b/libraries/shared/CMakeLists.txt @@ -1,15 +1,11 @@ set(TARGET_NAME shared) -# use setup_hifi_library macro to setup our project and link appropriate Qt modules # TODO: there isn't really a good reason to have Script linked here - let's get what is requiring it out (RegisteredMetaTypes.cpp) setup_hifi_library(Gui Network Script Widgets) find_package(ZLIB REQUIRED) target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES}) - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS}) +target_include_directories(${TARGET_NAME} PUBLIC ${ZLIB_INCLUDE_DIRS}) if (WIN32) # Birarda will fix this when he finds it. diff --git a/libraries/ui/CMakeLists.txt b/libraries/ui/CMakeLists.txt index b07651f7d4..d4cd1fc2bb 100644 --- a/libraries/ui/CMakeLists.txt +++ b/libraries/ui/CMakeLists.txt @@ -1,11 +1,3 @@ set(TARGET_NAME ui) - -# use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(OpenGL Network Qml Quick Script XmlPatterns) - link_hifi_libraries(render-utils shared) - -add_dependency_external_projects(glm) -find_package(GLM REQUIRED) - -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) diff --git a/tests/gpu-test/CMakeLists.txt b/tests/gpu-test/CMakeLists.txt index 1cb9e9f78e..0c183fc2f0 100644 --- a/tests/gpu-test/CMakeLists.txt +++ b/tests/gpu-test/CMakeLists.txt @@ -1,15 +1,7 @@ - set(TARGET_NAME gpu-test) - AUTOSCRIBE_SHADER_LIB(gpu model render-utils) - # This is not a testcase -- just set it up as a regular hifi project setup_hifi_project(Quick Gui OpenGL Script Widgets) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") - -#include_oglplus() - -# link in the shared libraries link_hifi_libraries(networking gpu procedural shared fbx model model-networking animation script-engine render-utils ) - copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/tests/physics/CMakeLists.txt b/tests/physics/CMakeLists.txt index 36cf21c681..f789a7b2ba 100644 --- a/tests/physics/CMakeLists.txt +++ b/tests/physics/CMakeLists.txt @@ -1,22 +1,7 @@ # Declare dependencies macro (SETUP_TESTCASE_DEPENDENCIES) - add_dependency_external_projects(glm) - find_package(GLM REQUIRED) - target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - - add_dependency_external_projects(bullet) - - find_package(Bullet REQUIRED) - target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) - - # perform the system include hack for OS X to ignore warnings - if (APPLE) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${BULLET_INCLUDE_DIRS}") - else() - target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BULLET_INCLUDE_DIRS}) - endif() - + target_bullet() link_hifi_libraries(shared physics) copy_dlls_beside_windows_executable() endmacro () From cd1b7585348a6468ae4f138502b9f6fbad378fdb Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sun, 11 Oct 2015 00:07:34 -0700 Subject: [PATCH 03/49] PR comments --- libraries/networking/src/ResourceManager.cpp | 19 ++++++------------- libraries/networking/src/ResourceManager.h | 7 +++++++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/libraries/networking/src/ResourceManager.cpp b/libraries/networking/src/ResourceManager.cpp index 6b97018ed9..fd465a0aed 100644 --- a/libraries/networking/src/ResourceManager.cpp +++ b/libraries/networking/src/ResourceManager.cpp @@ -17,32 +17,25 @@ #include +ResourceManager::PrefixMap ResourceManager::_prefixMap; +QMutex ResourceManager::_prefixMapLock; -using PrefixMap = std::map; -static PrefixMap PREFIX_MAP; -static QMutex PREFIX_MAP_LOCK; void ResourceManager::setUrlPrefixOverride(const QString& prefix, const QString& replacement) { - QMutexLocker locker(&PREFIX_MAP_LOCK); - PREFIX_MAP[prefix] = replacement; + QMutexLocker locker(&_prefixMapLock); + _prefixMap[prefix] = replacement; } QString ResourceManager::normalizeURL(const QString& urlString) { QString result = urlString; - QMutexLocker locker(&PREFIX_MAP_LOCK); - bool modified{ false }; - foreach(const auto& entry, PREFIX_MAP) { + QMutexLocker locker(&_prefixMapLock); + foreach(const auto& entry, _prefixMap) { const auto& prefix = entry.first; const auto& replacement = entry.second; if (result.startsWith(prefix)) { - qDebug() << prefix; result.replace(0, prefix.size(), replacement); - modified = true; } } - if (modified) { - qDebug() << result; - } return result; } diff --git a/libraries/networking/src/ResourceManager.h b/libraries/networking/src/ResourceManager.h index 58f4679c97..c010c67f9b 100644 --- a/libraries/networking/src/ResourceManager.h +++ b/libraries/networking/src/ResourceManager.h @@ -14,6 +14,8 @@ #include +#include + #include "ResourceRequest.h" const QString URL_SCHEME_FILE = "file"; @@ -28,6 +30,11 @@ public: static QString normalizeURL(const QString& urlString); static QUrl normalizeURL(const QUrl& url); static ResourceRequest* createResourceRequest(QObject* parent, const QUrl& url); +private: + using PrefixMap = std::map; + + static PrefixMap _prefixMap; + static QMutex _prefixMapLock; }; #endif From b5b4c2153a0bb8053c117192cee4cd4abc5257a3 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 11 Oct 2015 14:00:35 -0700 Subject: [PATCH 04/49] temp fix to get editing working again --- examples/libraries/entitySelectionTool.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index c49408fef6..7b79b654f7 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -2324,9 +2324,11 @@ SelectionDisplay = (function () { } }); - that.checkMove = function() { + that.checkMove = function () { if (SelectionManager.hasSelection()) { - SelectionManager._update(); + + // FIXME - this cause problems with editing in the entity properties window + //SelectionManager._update(); if (!Vec3.equal(Camera.getPosition(), lastCameraPosition) || !Quat.equal(Camera.getOrientation(), lastCameraOrientation)) { From e09fe30f05718fe742b5961488a9d86cfd1d9286 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 11 Oct 2015 14:02:33 -0700 Subject: [PATCH 05/49] damn you visual studio --- examples/libraries/entitySelectionTool.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 7b79b654f7..61aa5b0394 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -2324,7 +2324,7 @@ SelectionDisplay = (function () { } }); - that.checkMove = function () { + that.checkMove = function() { if (SelectionManager.hasSelection()) { // FIXME - this cause problems with editing in the entity properties window From 0986f86c349417fc61a2598043bc9fbaf803e8d7 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 11 Oct 2015 14:55:07 -0700 Subject: [PATCH 06/49] implement StandardController and expose it to JS as Controller.Standard.* --- .../scripts/controllerScriptingExamples.js | 9 +++++++-- .../scripting/ControllerScriptingInterface.cpp | 13 +++++++++++++ .../src/input-plugins/UserInputMapper.cpp | 15 +++++++++++++++ .../src/input-plugins/UserInputMapper.h | 14 +++++++++++++- 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/examples/example/scripts/controllerScriptingExamples.js b/examples/example/scripts/controllerScriptingExamples.js index 88c4ae2daa..6db7b38705 100644 --- a/examples/example/scripts/controllerScriptingExamples.js +++ b/examples/example/scripts/controllerScriptingExamples.js @@ -11,14 +11,19 @@ // Assumes you only have the default keyboard connected + +Object.keys(Controller.Standard).forEach(function (input) { + print("Controller.Standard." + input + ":" + Controller.Standard[input]); +}); + Object.keys(Controller.Hardware).forEach(function (deviceName) { Object.keys(Controller.Hardware[deviceName]).forEach(function (input) { - print(deviceName + "." + input + ":" + Controller.Hardware[deviceName][input]); + print("Controller.Hardware." + deviceName + "." + input + ":" + Controller.Hardware[deviceName][input]); }); }); Object.keys(Controller.Actions).forEach(function (actionName) { - print(actionName + ":" + Controller.Actions[actionName]); + print("Controller.Actions." + actionName + ":" + Controller.Actions[actionName]); }); // Resets every device to its default key bindings: diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index 4db482b6d4..9bdf8d1a4a 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -391,6 +391,19 @@ QString ControllerScriptingInterface::sanatizeName(const QString& name) { void ControllerScriptingInterface::wireUpControllers(ScriptEngine* engine) { + // Controller.Standard.* + auto standardDevice = DependencyManager::get()->getStandardDevice(); + if (standardDevice) { + auto deviceName = sanatizeName(standardDevice->getName()); + auto deviceInputs = standardDevice->getAvailabeInputs(); + for (const auto& inputMapping : deviceInputs) { + auto input = inputMapping.first; + auto inputName = sanatizeName(inputMapping.second); + QString deviceInputName{ "Controller." + deviceName + "." + inputName }; + engine->registerValue(deviceInputName, input.getID()); + } + } + // Controller.Hardware.* auto devices = DependencyManager::get()->getDevices(); for(const auto& deviceMapping : devices) { diff --git a/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp b/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp index 5c51db9410..82f90fc5dc 100755 --- a/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp +++ b/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp @@ -10,13 +10,20 @@ // #include "UserInputMapper.h" +#include "StandardController.h" // Default contruct allocate the poutput size with the current hardcoded action channels UserInputMapper::UserInputMapper() { + registerStandardDevice(); assignDefaulActionScales(); createActionNames(); } +UserInputMapper::~UserInputMapper() { + delete _standardController; +} + + bool UserInputMapper::registerDevice(uint16 deviceID, const DeviceProxy::Pointer& proxy){ proxy->_name += " (" + QString::number(deviceID) + ")"; _registeredDevices[deviceID] = proxy; @@ -322,3 +329,11 @@ void UserInputMapper::createActionNames() { _actionNames[CONTEXT_MENU] = "CONTEXT_MENU"; _actionNames[TOGGLE_MUTE] = "TOGGLE_MUTE"; } + +void UserInputMapper::registerStandardDevice() { + _standardController = new StandardController; + _standardController->registerToUserInputMapper(*this); + + //mapper.registerDevice(_deviceID, proxy); + //_standardDevice = proxy; +} \ No newline at end of file diff --git a/libraries/input-plugins/src/input-plugins/UserInputMapper.h b/libraries/input-plugins/src/input-plugins/UserInputMapper.h index 1ad4294e0c..8995d3544b 100755 --- a/libraries/input-plugins/src/input-plugins/UserInputMapper.h +++ b/libraries/input-plugins/src/input-plugins/UserInputMapper.h @@ -19,13 +19,16 @@ #include #include #include - + +class StandardController; class UserInputMapper : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY Q_ENUMS(Action) public: + ~UserInputMapper(); + typedef unsigned short uint16; typedef unsigned int uint32; @@ -123,6 +126,7 @@ public: // GetFreeDeviceID should be called before registering a device to use an ID not used by a different device. uint16 getFreeDeviceID() { return _nextFreeDeviceID++; } bool registerDevice(uint16 deviceID, const DeviceProxy::Pointer& device); + bool registerStandardDevice(const DeviceProxy::Pointer& device) { _standardDevice = device; return true; } DeviceProxy::Pointer getDeviceProxy(const Input& input); QString getDeviceName(uint16 deviceID); QVector getAvailableInputs(uint16 deviceID) { return _registeredDevices[deviceID]->getAvailabeInputs(); } @@ -238,11 +242,19 @@ public: typedef std::map DevicesMap; DevicesMap getDevices() { return _registeredDevices; } + uint16 getStandardDeviceID() const { return _standardDeviceID; } + DeviceProxy::Pointer getStandardDevice() { return _standardDevice; } + signals: void actionEvent(int action, float state); protected: + void registerStandardDevice(); + uint16 _standardDeviceID = 0; + DeviceProxy::Pointer _standardDevice; + StandardController* _standardController = nullptr; + DevicesMap _registeredDevices; uint16 _nextFreeDeviceID = 1; From 9667a103aa6295a36aaafd2bb62889c7732bbc2d Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 11 Oct 2015 15:02:11 -0700 Subject: [PATCH 07/49] actually add new files --- .../src/input-plugins/StandardController.cpp | 156 ++++++++++++++++++ .../src/input-plugins/StandardController.h | 69 ++++++++ 2 files changed, 225 insertions(+) create mode 100644 libraries/input-plugins/src/input-plugins/StandardController.cpp create mode 100644 libraries/input-plugins/src/input-plugins/StandardController.h diff --git a/libraries/input-plugins/src/input-plugins/StandardController.cpp b/libraries/input-plugins/src/input-plugins/StandardController.cpp new file mode 100644 index 0000000000..ba5b5baa19 --- /dev/null +++ b/libraries/input-plugins/src/input-plugins/StandardController.cpp @@ -0,0 +1,156 @@ +// +// StandardController.cpp +// input-plugins/src/input-plugins +// +// Created by Stephen Birarda on 2014-09-23. +// 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 + +#include "StandardController.h" + +const float CONTROLLER_THRESHOLD = 0.3f; + +const float MAX_AXIS = 32768.0f; + +StandardController::~StandardController() { +} + +void StandardController::update(float deltaTime, bool jointsCaptured) { + for (auto axisState : _axisStateMap) { + if (fabsf(axisState.second) < CONTROLLER_THRESHOLD) { + _axisStateMap[axisState.first] = 0.0f; + } + } +} + +void StandardController::focusOutEvent() { + _axisStateMap.clear(); + _buttonPressedMap.clear(); +}; + +void StandardController::registerToUserInputMapper(UserInputMapper& mapper) { + // Grab the current free device ID + _deviceID = mapper.getStandardDeviceID(); + + auto proxy = std::make_shared(_name); + proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input.getChannel()); }; + proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input.getChannel()); }; + proxy->getAvailabeInputs = [this] () -> QVector { + QVector availableInputs; + availableInputs.append(UserInputMapper::InputPair(makeInput(STANDARD_CONTROLLER_BUTTON_A), "Bottom Button")); + availableInputs.append(UserInputMapper::InputPair(makeInput(STANDARD_CONTROLLER_BUTTON_B), "Right Button")); + availableInputs.append(UserInputMapper::InputPair(makeInput(STANDARD_CONTROLLER_BUTTON_X), "Left Button")); + availableInputs.append(UserInputMapper::InputPair(makeInput(STANDARD_CONTROLLER_BUTTON_Y), "Top Button")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(STANDARD_CONTROLLER_BUTTON_DPAD_UP), "DPad Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(STANDARD_CONTROLLER_BUTTON_DPAD_DOWN), "DPad Down")); + availableInputs.append(UserInputMapper::InputPair(makeInput(STANDARD_CONTROLLER_BUTTON_DPAD_LEFT), "DPad Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(STANDARD_CONTROLLER_BUTTON_DPAD_RIGHT), "DPad Right")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(STANDARD_CONTROLLER_BUTTON_LEFTSHOULDER), "L1")); + availableInputs.append(UserInputMapper::InputPair(makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), "R1")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_SHOULDER), "L2")); + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_SHOULDER), "R2")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_Y_NEG), "Left Stick Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_Y_POS), "Left Stick Down")); + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_X_POS), "Left Stick Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_X_NEG), "Left Stick Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_AXIS_Y_NEG), "Right Stick Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_AXIS_Y_POS), "Right Stick Down")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_AXIS_X_POS), "Right Stick Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_AXIS_X_NEG), "Right Stick Left")); + + return availableInputs; + }; + proxy->resetDeviceBindings = [this, &mapper] () -> bool { + mapper.removeAllInputChannelsForDevice(_deviceID); + this->assignDefaultInputMapping(mapper); + return true; + }; + mapper.registerStandardDevice(proxy); +} + +void StandardController::assignDefaultInputMapping(UserInputMapper& mapper) { + const float JOYSTICK_MOVE_SPEED = 1.0f; + const float DPAD_MOVE_SPEED = 0.5f; + const float JOYSTICK_YAW_SPEED = 0.5f; + const float JOYSTICK_PITCH_SPEED = 0.25f; + const float BOOM_SPEED = 0.1f; + + // Y axes are flipped (up is negative) + // Left StandardController: Movement, strafing + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(LEFT_AXIS_Y_NEG), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(LEFT_AXIS_Y_POS), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(LEFT_AXIS_X_POS), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(LEFT_AXIS_X_NEG), JOYSTICK_MOVE_SPEED); + + // Right StandardController: Camera orientation + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(RIGHT_AXIS_X_POS), JOYSTICK_YAW_SPEED); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(RIGHT_AXIS_X_NEG), JOYSTICK_YAW_SPEED); + mapper.addInputChannel(UserInputMapper::PITCH_UP, makeInput(RIGHT_AXIS_Y_NEG), JOYSTICK_PITCH_SPEED); + mapper.addInputChannel(UserInputMapper::PITCH_DOWN, makeInput(RIGHT_AXIS_Y_POS), JOYSTICK_PITCH_SPEED); + + // Dpad movement + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(STANDARD_CONTROLLER_BUTTON_DPAD_UP), DPAD_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(STANDARD_CONTROLLER_BUTTON_DPAD_DOWN), DPAD_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(STANDARD_CONTROLLER_BUTTON_DPAD_RIGHT), DPAD_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(STANDARD_CONTROLLER_BUTTON_DPAD_LEFT), DPAD_MOVE_SPEED); + + // Button controls + mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(STANDARD_CONTROLLER_BUTTON_Y), DPAD_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(STANDARD_CONTROLLER_BUTTON_X), DPAD_MOVE_SPEED); + + // Zoom + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(RIGHT_SHOULDER), BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(LEFT_SHOULDER), BOOM_SPEED); + + + // Hold front right shoulder button for precision controls + // Left StandardController: Movement, strafing + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(LEFT_AXIS_Y_NEG), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(LEFT_AXIS_Y_POS), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(LEFT_AXIS_X_POS), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(LEFT_AXIS_X_NEG), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.0f); + + // Right StandardController: Camera orientation + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(RIGHT_AXIS_X_POS), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(RIGHT_AXIS_X_NEG), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::PITCH_UP, makeInput(RIGHT_AXIS_Y_NEG), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_PITCH_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::PITCH_DOWN, makeInput(RIGHT_AXIS_Y_POS), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_PITCH_SPEED/2.0f); + + // Dpad movement + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(STANDARD_CONTROLLER_BUTTON_DPAD_UP), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(STANDARD_CONTROLLER_BUTTON_DPAD_DOWN), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(STANDARD_CONTROLLER_BUTTON_DPAD_RIGHT), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(STANDARD_CONTROLLER_BUTTON_DPAD_LEFT), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + + // Button controls + mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(STANDARD_CONTROLLER_BUTTON_Y), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(STANDARD_CONTROLLER_BUTTON_X), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + + // Zoom + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(RIGHT_SHOULDER), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), BOOM_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(LEFT_SHOULDER), makeInput(STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER), BOOM_SPEED/2.0f); + + mapper.addInputChannel(UserInputMapper::SHIFT, makeInput(STANDARD_CONTROLLER_BUTTON_LEFTSHOULDER)); + + mapper.addInputChannel(UserInputMapper::ACTION1, makeInput(STANDARD_CONTROLLER_BUTTON_B)); + mapper.addInputChannel(UserInputMapper::ACTION2, makeInput(STANDARD_CONTROLLER_BUTTON_A)); +} + +UserInputMapper::Input StandardController::makeInput(StandardController::StandardControllerButtonChannel button) { + return UserInputMapper::Input(_deviceID, button, UserInputMapper::ChannelType::BUTTON); +} + +UserInputMapper::Input StandardController::makeInput(StandardController::StandardControllerAxisChannel axis) { + return UserInputMapper::Input(_deviceID, axis, UserInputMapper::ChannelType::AXIS); +} + diff --git a/libraries/input-plugins/src/input-plugins/StandardController.h b/libraries/input-plugins/src/input-plugins/StandardController.h new file mode 100644 index 0000000000..ac89bca581 --- /dev/null +++ b/libraries/input-plugins/src/input-plugins/StandardController.h @@ -0,0 +1,69 @@ +// +// StandardController.h +// input-plugins/src/input-plugins +// +// Created by Stephen Birarda on 2014-09-23. +// 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_StandardController_h +#define hifi_StandardController_h + +#include +#include + +#include "InputDevice.h" + +class StandardController : public QObject, public InputDevice { + Q_OBJECT + Q_PROPERTY(QString name READ getName) + +public: + enum StandardControllerAxisChannel { + LEFT_AXIS_X_POS = 0, + LEFT_AXIS_X_NEG, + LEFT_AXIS_Y_POS, + LEFT_AXIS_Y_NEG, + RIGHT_AXIS_X_POS, + RIGHT_AXIS_X_NEG, + RIGHT_AXIS_Y_POS, + RIGHT_AXIS_Y_NEG, + RIGHT_SHOULDER, + LEFT_SHOULDER, + }; + enum StandardControllerButtonChannel { + STANDARD_CONTROLLER_BUTTON_A = 0, + STANDARD_CONTROLLER_BUTTON_B, + STANDARD_CONTROLLER_BUTTON_X, + STANDARD_CONTROLLER_BUTTON_Y, + + STANDARD_CONTROLLER_BUTTON_DPAD_UP, + STANDARD_CONTROLLER_BUTTON_DPAD_DOWN, + STANDARD_CONTROLLER_BUTTON_DPAD_LEFT, + STANDARD_CONTROLLER_BUTTON_DPAD_RIGHT, + + STANDARD_CONTROLLER_BUTTON_LEFTSHOULDER, + STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER, + }; + + const QString& getName() const { return _name; } + + // Device functions + virtual void registerToUserInputMapper(UserInputMapper& mapper) override; + virtual void assignDefaultInputMapping(UserInputMapper& mapper) override; + virtual void update(float deltaTime, bool jointsCaptured) override; + virtual void focusOutEvent() override; + + StandardController() : InputDevice("Standard") {} + ~StandardController(); + + UserInputMapper::Input makeInput(StandardController::StandardControllerButtonChannel button); + UserInputMapper::Input makeInput(StandardController::StandardControllerAxisChannel axis); + +private: +}; + +#endif // hifi_StandardController_h From 312bbf6167871c4020e52e5a27cab630df6fc8f0 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 11 Oct 2015 15:15:20 -0700 Subject: [PATCH 08/49] CR feedback --- .../src/input-plugins/StandardController.cpp | 10 ++++++++-- .../src/input-plugins/StandardController.h | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/StandardController.cpp b/libraries/input-plugins/src/input-plugins/StandardController.cpp index ba5b5baa19..4fb4a23654 100644 --- a/libraries/input-plugins/src/input-plugins/StandardController.cpp +++ b/libraries/input-plugins/src/input-plugins/StandardController.cpp @@ -2,8 +2,8 @@ // StandardController.cpp // input-plugins/src/input-plugins // -// Created by Stephen Birarda on 2014-09-23. -// Copyright 2014 High Fidelity, Inc. +// Created by Brad Hefta-Gaub on 2015-10-11. +// Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -68,6 +68,9 @@ void StandardController::registerToUserInputMapper(UserInputMapper& mapper) { availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_AXIS_X_POS), "Right Stick Right")); availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_AXIS_X_NEG), "Right Stick Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_HAND), "Left Hand")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_HAND), "Right Hand")); + return availableInputs; }; proxy->resetDeviceBindings = [this, &mapper] () -> bool { @@ -154,3 +157,6 @@ UserInputMapper::Input StandardController::makeInput(StandardController::Standar return UserInputMapper::Input(_deviceID, axis, UserInputMapper::ChannelType::AXIS); } +UserInputMapper::Input StandardController::makeInput(StandardController::StandardControllerPoseChannel pose) { + return UserInputMapper::Input(_deviceID, pose, UserInputMapper::ChannelType::POSE); +} diff --git a/libraries/input-plugins/src/input-plugins/StandardController.h b/libraries/input-plugins/src/input-plugins/StandardController.h index ac89bca581..7f13b61783 100644 --- a/libraries/input-plugins/src/input-plugins/StandardController.h +++ b/libraries/input-plugins/src/input-plugins/StandardController.h @@ -2,8 +2,8 @@ // StandardController.h // input-plugins/src/input-plugins // -// Created by Stephen Birarda on 2014-09-23. -// Copyright 2014 High Fidelity, Inc. +// Created by Brad Hefta-Gaub on 2015-10-11. +// Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -49,6 +49,11 @@ public: STANDARD_CONTROLLER_BUTTON_RIGHTSHOULDER, }; + enum StandardControllerPoseChannel { + LEFT_HAND = 0, + RIGHT_HAND, + }; + const QString& getName() const { return _name; } // Device functions @@ -62,6 +67,7 @@ public: UserInputMapper::Input makeInput(StandardController::StandardControllerButtonChannel button); UserInputMapper::Input makeInput(StandardController::StandardControllerAxisChannel axis); + UserInputMapper::Input makeInput(StandardController::StandardControllerPoseChannel pose); private: }; From 21a473035e2b60d7f854f1abe432cf6e2cd7c586 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 11 Oct 2015 15:37:17 -0700 Subject: [PATCH 09/49] more CR feedback --- .../input-plugins/src/input-plugins/StandardController.h | 2 ++ .../input-plugins/src/input-plugins/UserInputMapper.cpp | 6 +----- libraries/input-plugins/src/input-plugins/UserInputMapper.h | 3 ++- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/StandardController.h b/libraries/input-plugins/src/input-plugins/StandardController.h index 7f13b61783..f7a4215242 100644 --- a/libraries/input-plugins/src/input-plugins/StandardController.h +++ b/libraries/input-plugins/src/input-plugins/StandardController.h @@ -17,6 +17,8 @@ #include "InputDevice.h" +typedef std::shared_ptr StandardControllerPointer; + class StandardController : public QObject, public InputDevice { Q_OBJECT Q_PROPERTY(QString name READ getName) diff --git a/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp b/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp index 82f90fc5dc..fad962345c 100755 --- a/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp +++ b/libraries/input-plugins/src/input-plugins/UserInputMapper.cpp @@ -20,7 +20,6 @@ UserInputMapper::UserInputMapper() { } UserInputMapper::~UserInputMapper() { - delete _standardController; } @@ -331,9 +330,6 @@ void UserInputMapper::createActionNames() { } void UserInputMapper::registerStandardDevice() { - _standardController = new StandardController; + _standardController = std::make_shared(); _standardController->registerToUserInputMapper(*this); - - //mapper.registerDevice(_deviceID, proxy); - //_standardDevice = proxy; } \ No newline at end of file diff --git a/libraries/input-plugins/src/input-plugins/UserInputMapper.h b/libraries/input-plugins/src/input-plugins/UserInputMapper.h index 8995d3544b..1d64638ee1 100755 --- a/libraries/input-plugins/src/input-plugins/UserInputMapper.h +++ b/libraries/input-plugins/src/input-plugins/UserInputMapper.h @@ -21,6 +21,7 @@ #include class StandardController; +typedef std::shared_ptr StandardControllerPointer; class UserInputMapper : public QObject, public Dependency { Q_OBJECT @@ -253,7 +254,7 @@ protected: void registerStandardDevice(); uint16 _standardDeviceID = 0; DeviceProxy::Pointer _standardDevice; - StandardController* _standardController = nullptr; + StandardControllerPointer _standardController; DevicesMap _registeredDevices; uint16 _nextFreeDeviceID = 1; From ab32470699bf005e044de8d672cd8540b816481b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 12 Oct 2015 09:12:33 -0700 Subject: [PATCH 10/49] Fixed syntax error in hiddenEntityResetScript --- unpublishedScripts/hiddenEntityReset.js | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index d480c0ac74..10966f3a7b 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -407,11 +407,6 @@ type: 'Box', position: startPosition, dimensions: TARGET_DIMENSIONS, - color: { - red: 0, - green: 255, - blue: 0 - }, rotation: rotation, visible: false, collisionsWillMove: false, @@ -734,7 +729,6 @@ - var sconceLight3 = Entities.addEntity({ type: "Light", position: { @@ -888,7 +882,7 @@ y: 1.13, z: 0.2 }, - rotation: rotation2, + rotation: rotation, collisionsWillMove: true, gravity: { x: 0, @@ -1256,7 +1250,7 @@ y: 0.05, z: 0.25 } - },]; + }, ]; var modelURL, entity; for (i = 0; i < blockTypes.length; i++) { @@ -1305,7 +1299,6 @@ Script.scriptEnding.connect(cleanup); } }; - // entity scripts always need to return a newly constructed object of our type return new ResetSwitch(); -}); +}); \ No newline at end of file From 08a94189b73fa64a06746e526fc8de6104eba817 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 12 Oct 2015 09:31:12 -0700 Subject: [PATCH 11/49] explicitly setting isSpotlight to false --- unpublishedScripts/hiddenEntityReset.js | 6 +++++- unpublishedScripts/masterReset.js | 10 +++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index 10966f3a7b..0a678d668e 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -52,7 +52,6 @@ }; - MasterReset = function() { var resetKey = "resetMe"; var GRABBABLE_DATA_KEY = "grabbableKey"; @@ -653,6 +652,7 @@ green: 146, blue: 24 }, + isSpotlight: false, userData: JSON.stringify({ resetMe: { resetMe: true, @@ -680,6 +680,7 @@ green: 146, blue: 24 }, + isSpotlight: false, userData: JSON.stringify({ resetMe: { resetMe: true, @@ -749,6 +750,7 @@ green: 146, blue: 24 }, + isSpotlight: false, userData: JSON.stringify({ resetMe: { resetMe: true, @@ -777,6 +779,7 @@ green: 146, blue: 24 }, + isSpotlight: false, userData: JSON.stringify({ resetMe: { resetMe: true, @@ -804,6 +807,7 @@ green: 146, blue: 24 }, + isSpotlight: false, userData: JSON.stringify({ resetMe: { resetMe: true, diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 693e2eb28b..d9199a124d 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -625,6 +625,7 @@ MasterReset = function() { green: 146, blue: 24 }, + isSpotlight: false, userData: JSON.stringify({ resetMe: { resetMe: true, @@ -652,6 +653,7 @@ MasterReset = function() { green: 146, blue: 24 }, + isSpotlight: false, userData: JSON.stringify({ resetMe: { resetMe: true, @@ -701,7 +703,6 @@ MasterReset = function() { - var sconceLight3 = Entities.addEntity({ type: "Light", position: { @@ -722,6 +723,7 @@ MasterReset = function() { green: 146, blue: 24 }, + isSpotlight: false, userData: JSON.stringify({ resetMe: { resetMe: true, @@ -750,6 +752,7 @@ MasterReset = function() { green: 146, blue: 24 }, + isSpotlight: false, userData: JSON.stringify({ resetMe: { resetMe: true, @@ -777,6 +780,7 @@ MasterReset = function() { green: 146, blue: 24 }, + isSpotlight: false, userData: JSON.stringify({ resetMe: { resetMe: true, @@ -1223,7 +1227,7 @@ MasterReset = function() { y: 0.05, z: 0.25 } - },]; + }, ]; var modelURL, entity; for (i = 0; i < blockTypes.length; i++) { @@ -1271,4 +1275,4 @@ MasterReset = function() { Script.scriptEnding.connect(cleanup); } -}; +}; \ No newline at end of file From 03eaa9525836518c854f49b1d77eb763bfa609fe Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 8 Oct 2015 16:39:25 -0700 Subject: [PATCH 12/49] initial hip translation from IK works for 2D 3rd person but probably not well for HMD --- .../defaultAvatar_full/avatar-animation.json | 12 ++++ .../animation/src/AnimInverseKinematics.cpp | 62 +++++++++++++++++-- .../animation/src/AnimInverseKinematics.h | 11 +++- 3 files changed, 77 insertions(+), 8 deletions(-) diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index dceecddfe0..e930f583f6 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -23,6 +23,18 @@ "positionVar": "leftHandPosition", "rotationVar": "leftHandRotation" }, + { + "jointName": "RightFoot", + "positionVar": "rightToePosition", + "rotationVar": "rightToeRotation", + "typeVar": "rightToeType" + }, + { + "jointName": "LeftFoot", + "positionVar": "leftToePosition", + "rotationVar": "leftToeRotation", + "typeVar": "leftToeType" + }, { "jointName": "Neck", "positionVar": "neckPosition", diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 8a9971f362..54ec2d839b 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -343,7 +343,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars // build a list of targets from _targetVarVec std::vector targets; computeTargets(animVars, targets, underPoses); - + if (targets.empty()) { // no IK targets but still need to enforce constraints std::map::iterator constraintItr = _constraints.begin(); @@ -355,7 +355,45 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars ++constraintItr; } } else { + // shift the hips according to the offset from the previous frame + float offsetLength = glm::length(_actualHipsOffset); + const float MIN_OFFSET_LENGTH = 0.03f; + if (offsetLength > MIN_OFFSET_LENGTH) { + // but only if actual offset is long enough + float scaleFactor = ((offsetLength - MIN_OFFSET_LENGTH) / offsetLength); + _relativePoses[0].trans = underPoses[0].trans + scaleFactor * _actualHipsOffset; + } + solveWithCyclicCoordinateDescent(targets); + + // compute the new target hips offset (for next frame) + // by looking for discrepancies between where a targeted endEffector is + // and where it wants to be (after IK solutions are done) + _targetHipsOffset = Vectors::ZERO; + for (auto& target: targets) { + if (target.index == _headIndex && _headIndex != -1) { + // special handling for headTarget + AnimPose headUnderPose = _skeleton->getAbsolutePose(_headIndex, underPoses); + AnimPose headOverPose = headUnderPose; + if (target.type == IKTarget::Type::RotationOnly) { + headOverPose = _skeleton->getAbsolutePose(_headIndex, _relativePoses); + } else if (target.type == IKTarget::Type::RotationAndPosition) { + headOverPose = target.pose; + } + glm::vec3 headOffset = headOverPose.trans - headUnderPose.trans; + const float HEAD_OFFSET_SLAVE_FACTOR = 0.65f; + _targetHipsOffset += HEAD_OFFSET_SLAVE_FACTOR * headOffset; + } else if (target.type == IKTarget::Type::RotationAndPosition) { + glm::vec3 actualPosition = _skeleton->getAbsolutePose(target.index, _relativePoses).trans; + glm::vec3 targetPosition = target.pose.trans; + _targetHipsOffset += targetPosition - actualPosition; + } + } + + // smooth transitions by relaxing targetHipsOffset onto actualHipsOffset over some timescale + const float HIPS_OFFSET_SLAVE_TIMESCALE = 0.15f; + glm::vec3 deltaOffset = (_targetHipsOffset - _actualHipsOffset) * (dt / HIPS_OFFSET_SLAVE_TIMESCALE); + _actualHipsOffset += deltaOffset; } } return _relativePoses; @@ -477,7 +515,7 @@ void AnimInverseKinematics::initConstraints() { stConstraint->setSwingLimits(minDots); constraint = static_cast(stConstraint); - } else if (0 == baseName.compare("UpLegXXX", Qt::CaseInsensitive)) { + } else if (0 == baseName.compare("UpLeg", Qt::CaseInsensitive)) { SwingTwistConstraint* stConstraint = new SwingTwistConstraint(); stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot); stConstraint->setTwistLimits(-PI / 4.0f, PI / 4.0f); @@ -581,7 +619,7 @@ void AnimInverseKinematics::initConstraints() { } else if (0 == baseName.compare("Neck", Qt::CaseInsensitive)) { SwingTwistConstraint* stConstraint = new SwingTwistConstraint(); stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot); - const float MAX_NECK_TWIST = PI / 2.0f; + const float MAX_NECK_TWIST = PI / 4.0f; stConstraint->setTwistLimits(-MAX_NECK_TWIST, MAX_NECK_TWIST); std::vector minDots; @@ -589,6 +627,18 @@ void AnimInverseKinematics::initConstraints() { minDots.push_back(cosf(MAX_NECK_SWING)); stConstraint->setSwingLimits(minDots); + constraint = static_cast(stConstraint); + } else if (0 == baseName.compare("Head", Qt::CaseInsensitive)) { + SwingTwistConstraint* stConstraint = new SwingTwistConstraint(); + stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot); + const float MAX_HEAD_TWIST = PI / 4.0f; + stConstraint->setTwistLimits(-MAX_HEAD_TWIST, MAX_HEAD_TWIST); + + std::vector minDots; + const float MAX_HEAD_SWING = PI / 4.0f; + minDots.push_back(cosf(MAX_HEAD_SWING)); + stConstraint->setSwingLimits(minDots); + constraint = static_cast(stConstraint); } else if (0 == baseName.compare("ForeArm", Qt::CaseInsensitive)) { // The elbow joint rotates about the parent-frame's zAxis (-zAxis) for the Right (Left) arm. @@ -621,7 +671,7 @@ void AnimInverseKinematics::initConstraints() { eConstraint->setAngleLimits(minAngle, maxAngle); constraint = static_cast(eConstraint); - } else if (0 == baseName.compare("LegXXX", Qt::CaseInsensitive)) { + } else if (0 == baseName.compare("Leg", Qt::CaseInsensitive)) { // The knee joint rotates about the parent-frame's -xAxis. ElbowConstraint* eConstraint = new ElbowConstraint(); glm::quat referenceRotation = _defaultRelativePoses[i].rot; @@ -652,7 +702,7 @@ void AnimInverseKinematics::initConstraints() { eConstraint->setAngleLimits(minAngle, maxAngle); constraint = static_cast(eConstraint); - } else if (0 == baseName.compare("FootXXX", Qt::CaseInsensitive)) { + } else if (0 == baseName.compare("Foot", Qt::CaseInsensitive)) { SwingTwistConstraint* stConstraint = new SwingTwistConstraint(); stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot); stConstraint->setTwistLimits(-PI / 4.0f, PI / 4.0f); @@ -697,7 +747,9 @@ void AnimInverseKinematics::setSkeletonInternal(AnimSkeleton::ConstPointer skele if (skeleton) { initConstraints(); + _headIndex = _skeleton->nameToJointIndex("Head"); } else { clearConstraints(); + _headIndex = -1; } } diff --git a/libraries/animation/src/AnimInverseKinematics.h b/libraries/animation/src/AnimInverseKinematics.h index 0ef81f8b3c..634c71cea9 100644 --- a/libraries/animation/src/AnimInverseKinematics.h +++ b/libraries/animation/src/AnimInverseKinematics.h @@ -60,6 +60,10 @@ protected: void clearConstraints(); void initConstraints(); + // no copies + AnimInverseKinematics(const AnimInverseKinematics&) = delete; + AnimInverseKinematics& operator=(const AnimInverseKinematics&) = delete; + struct IKTargetVar { IKTargetVar(const QString& jointNameIn, const QString& positionVarIn, @@ -85,9 +89,10 @@ protected: AnimPoseVec _defaultRelativePoses; // poses of the relaxed state AnimPoseVec _relativePoses; // current relative poses - // no copies - AnimInverseKinematics(const AnimInverseKinematics&) = delete; - AnimInverseKinematics& operator=(const AnimInverseKinematics&) = delete; + // experimental data for moving hips during IK + int _headIndex = -1; + glm::vec3 _targetHipsOffset = Vectors::ZERO; // offset we want + glm::vec3 _actualHipsOffset = Vectors::ZERO; // offset we have // _maxTargetIndex is tracked to help optimize the recalculation of absolute poses // during the the cyclic coordinate descent algorithm From 56f038d5a7409e16dd4c97a7ed39a830c824b0b8 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Sat, 10 Oct 2015 10:13:33 -0700 Subject: [PATCH 13/49] simpler logic for tracking hips offset --- .../animation/src/AnimInverseKinematics.cpp | 16 ++++++++-------- libraries/animation/src/AnimInverseKinematics.h | 3 +-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 54ec2d839b..247a7c8409 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -356,12 +356,12 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars } } else { // shift the hips according to the offset from the previous frame - float offsetLength = glm::length(_actualHipsOffset); + float offsetLength = glm::length(_hipsOffset); const float MIN_OFFSET_LENGTH = 0.03f; if (offsetLength > MIN_OFFSET_LENGTH) { // but only if actual offset is long enough float scaleFactor = ((offsetLength - MIN_OFFSET_LENGTH) / offsetLength); - _relativePoses[0].trans = underPoses[0].trans + scaleFactor * _actualHipsOffset; + _relativePoses[0].trans = underPoses[0].trans + scaleFactor * _hipsOffset; } solveWithCyclicCoordinateDescent(targets); @@ -369,7 +369,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars // compute the new target hips offset (for next frame) // by looking for discrepancies between where a targeted endEffector is // and where it wants to be (after IK solutions are done) - _targetHipsOffset = Vectors::ZERO; + glm::vec3 newOffset = Vectors::ZERO; for (auto& target: targets) { if (target.index == _headIndex && _headIndex != -1) { // special handling for headTarget @@ -382,18 +382,18 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars } glm::vec3 headOffset = headOverPose.trans - headUnderPose.trans; const float HEAD_OFFSET_SLAVE_FACTOR = 0.65f; - _targetHipsOffset += HEAD_OFFSET_SLAVE_FACTOR * headOffset; + newOffset += HEAD_OFFSET_SLAVE_FACTOR * headOffset; } else if (target.type == IKTarget::Type::RotationAndPosition) { glm::vec3 actualPosition = _skeleton->getAbsolutePose(target.index, _relativePoses).trans; glm::vec3 targetPosition = target.pose.trans; - _targetHipsOffset += targetPosition - actualPosition; + newOffset += targetPosition - actualPosition; } } - // smooth transitions by relaxing targetHipsOffset onto actualHipsOffset over some timescale + // smooth transitions by relaxing _hipsOffset toward the new value const float HIPS_OFFSET_SLAVE_TIMESCALE = 0.15f; - glm::vec3 deltaOffset = (_targetHipsOffset - _actualHipsOffset) * (dt / HIPS_OFFSET_SLAVE_TIMESCALE); - _actualHipsOffset += deltaOffset; + glm::vec3 deltaOffset = (newOffset - _hipsOffset) * (dt / HIPS_OFFSET_SLAVE_TIMESCALE); + _hipsOffset += deltaOffset; } } return _relativePoses; diff --git a/libraries/animation/src/AnimInverseKinematics.h b/libraries/animation/src/AnimInverseKinematics.h index 634c71cea9..8fc03b7a0a 100644 --- a/libraries/animation/src/AnimInverseKinematics.h +++ b/libraries/animation/src/AnimInverseKinematics.h @@ -91,8 +91,7 @@ protected: // experimental data for moving hips during IK int _headIndex = -1; - glm::vec3 _targetHipsOffset = Vectors::ZERO; // offset we want - glm::vec3 _actualHipsOffset = Vectors::ZERO; // offset we have + glm::vec3 _hipsOffset = Vectors::ZERO; // _maxTargetIndex is tracked to help optimize the recalculation of absolute poses // during the the cyclic coordinate descent algorithm From bc48f70877190f4542a53006d4671745ee3fbb99 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Sat, 10 Oct 2015 11:15:51 -0700 Subject: [PATCH 14/49] move IKTarget into its own files --- .../animation/src/AnimInverseKinematics.cpp | 66 +++++++++---------- .../animation/src/AnimInverseKinematics.h | 13 +--- libraries/animation/src/IKTarget.cpp | 31 +++++++++ libraries/animation/src/IKTarget.h | 42 ++++++++++++ libraries/animation/src/Rig.cpp | 11 ++-- 5 files changed, 112 insertions(+), 51 deletions(-) create mode 100644 libraries/animation/src/IKTarget.cpp create mode 100644 libraries/animation/src/IKTarget.h diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 247a7c8409..00a752c69b 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -96,13 +96,13 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: } else { IKTarget target; AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, underPoses); - target.pose.trans = animVars.lookup(targetVar.positionVar, defaultPose.trans); - target.pose.rot = animVars.lookup(targetVar.rotationVar, defaultPose.rot); - target.setType(animVars.lookup(targetVar.typeVar, QString(""))); - target.index = targetVar.jointIndex; + target.setPose(animVars.lookup(targetVar.rotationVar, defaultPose.rot), + animVars.lookup(targetVar.positionVar, defaultPose.trans)); + target.setType(animVars.lookup(targetVar.typeVar, (int)IKTarget::Type::Unknown)); + target.setIndex(targetVar.jointIndex); targets.push_back(target); - if (target.index > _maxTargetIndex) { - _maxTargetIndex = target.index; + if (targetVar.jointIndex > _maxTargetIndex) { + _maxTargetIndex = targetVar.jointIndex; } } } @@ -141,14 +141,13 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector& targets, const AnimPoseVec& underPoses); void solveWithCyclicCoordinateDescent(const std::vector& targets); virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) override; diff --git a/libraries/animation/src/IKTarget.cpp b/libraries/animation/src/IKTarget.cpp new file mode 100644 index 0000000000..a7e3296d35 --- /dev/null +++ b/libraries/animation/src/IKTarget.cpp @@ -0,0 +1,31 @@ +// +// IKTarget.cpp +// +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "IKTarget.h" + +void IKTarget::setPose(const glm::quat& rotation, const glm::vec3& translation) { + _pose.rot = rotation; + _pose.trans = translation; +} + +void IKTarget::setType(int type) { + switch (type) { + case (int)Type::RotationAndPosition: + _type = Type::RotationAndPosition; + break; + case (int)Type::RotationOnly: + _type = Type::RotationOnly; + break; + case (int)Type::HmdHead: + _type = Type::HmdHead; + break; + default: + _type = Type::Unknown; + } +} diff --git a/libraries/animation/src/IKTarget.h b/libraries/animation/src/IKTarget.h new file mode 100644 index 0000000000..fa920d1511 --- /dev/null +++ b/libraries/animation/src/IKTarget.h @@ -0,0 +1,42 @@ +// +// IKTarget.h +// +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_IKTarget_h +#define hifi_IKTarget_h + +#include "AnimSkeleton.h" + +class IKTarget { +public: + enum class Type { + RotationAndPosition, + RotationOnly, + HmdHead, + Unknown, + }; + + IKTarget() {} + + const glm::vec3& getTranslation() const { return _pose.trans; } + const glm::quat& getRotation() const { return _pose.rot; } + int getIndex() const { return _index; } + Type getType() const { return _type; } + + void setPose(const glm::quat& rotation, const glm::vec3& translation); + void setIndex(int index) { _index = index; } + void setType(int); + +private: + AnimPose _pose; + int _index = -1; + Type _type = Type::RotationAndPosition; + +}; + +#endif // hifi_IKTarget_h diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 7f300fc84a..3a1dafa10c 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -14,13 +14,14 @@ #include #include -#include "NumericalConstants.h" +#include +#include + #include "AnimationHandle.h" #include "AnimationLogging.h" #include "AnimSkeleton.h" -#include "DebugDraw.h" +#include "IKTarget.h" -#include "Rig.h" void Rig::HeadParameters::dump() const { qCDebug(animation, "HeadParameters ="); @@ -1057,7 +1058,7 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { _animVars.set("headPosition", headPos); _animVars.set("headRotation", headRot); - _animVars.set("headAndNeckType", QString("RotationAndPosition")); + _animVars.set("headAndNeckType", (int)IKTarget::Type::RotationAndPosition); _animVars.set("neckPosition", neckPos); _animVars.set("neckRotation", neckRot); @@ -1070,7 +1071,7 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { _animVars.unset("headPosition"); _animVars.set("headRotation", realLocalHeadOrientation); - _animVars.set("headAndNeckType", QString("RotationOnly")); + _animVars.set("headAndNeckType", (int)IKTarget::Type::RotationOnly); _animVars.unset("neckPosition"); _animVars.unset("neckRotation"); } From 6a96d5f0c5d9b52a7e4c84a2555c0788637e4f9b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Sat, 10 Oct 2015 14:37:19 -0700 Subject: [PATCH 15/49] don't bother to create targets with bad types --- .../animation/src/AnimInverseKinematics.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 00a752c69b..c9f0960a4f 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -95,14 +95,16 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: } } else { IKTarget target; - AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, underPoses); - target.setPose(animVars.lookup(targetVar.rotationVar, defaultPose.rot), - animVars.lookup(targetVar.positionVar, defaultPose.trans)); - target.setType(animVars.lookup(targetVar.typeVar, (int)IKTarget::Type::Unknown)); - target.setIndex(targetVar.jointIndex); - targets.push_back(target); - if (targetVar.jointIndex > _maxTargetIndex) { - _maxTargetIndex = targetVar.jointIndex; + target.setType(animVars.lookup(targetVar.typeVar, (int)IKTarget::Type::RotationAndPosition)); + if (target.getType() != IKTarget::Type::Unknown) { + AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, underPoses); + target.setPose(animVars.lookup(targetVar.rotationVar, defaultPose.rot), + animVars.lookup(targetVar.positionVar, defaultPose.trans)); + target.setIndex(targetVar.jointIndex); + targets.push_back(target); + if (targetVar.jointIndex > _maxTargetIndex) { + _maxTargetIndex = targetVar.jointIndex; + } } } } From 5f1068c404facaf50389606946413b2b75265b2b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Sat, 10 Oct 2015 15:53:03 -0700 Subject: [PATCH 16/49] cleanup and optimization of IK loop --- .../animation/src/AnimInverseKinematics.cpp | 183 +++++++++--------- 1 file changed, 90 insertions(+), 93 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index c9f0960a4f..0d1868d955 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -143,106 +143,114 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vectorgetParentIndex(tipIndex); + if (pivotIndex == -1) { + continue; + } + int pivotsParentIndex = _skeleton->getParentIndex(pivotIndex); + if (pivotsParentIndex == -1) { + // TODO?: handle case where tip's parent is root? + continue; + } + glm::vec3 tipPosition = absolutePoses[tipIndex].trans; - glm::quat tipRotation = absolutePoses[tipIndex].rot; + //glm::quat tipRotation = absolutePoses[tipIndex].rot; // cache tip's parent's absolute rotation so we can recompute the tip's parent-relative // as we proceed walking down the joint chain - int pivotIndex = _skeleton->getParentIndex(tipIndex); - glm::quat tipParentRotation; - if (pivotIndex != -1) { - tipParentRotation = absolutePoses[pivotIndex].rot; - } + glm::quat tipParentRotation = absolutePoses[pivotIndex].rot; // descend toward root, pivoting each joint to get tip closer to target - int ancestorCount = 1; - while (pivotIndex != -1) { + while (pivotsParentIndex != -1) { // compute the two lines that should be aligned glm::vec3 jointPosition = absolutePoses[pivotIndex].trans; glm::vec3 leverArm = tipPosition - jointPosition; - glm::vec3 targetLine = target.getTranslation() - jointPosition; - // compute the swing that would get get tip closer - glm::vec3 axis = glm::cross(leverArm, targetLine); - float axisLength = glm::length(axis); glm::quat deltaRotation; - const float MIN_AXIS_LENGTH = 1.0e-4f; - if (axisLength > MIN_AXIS_LENGTH) { - // compute deltaRotation for alignment (swings tip closer to target) - axis /= axisLength; - float angle = acosf(glm::dot(leverArm, targetLine) / (glm::length(leverArm) * glm::length(targetLine))); - - // NOTE: even when axisLength is not zero (e.g. lever-arm and pivot-arm are not quite aligned) it is - // still possible for the angle to be zero so we also check that to avoid unnecessary calculations. - const float MIN_ADJUSTMENT_ANGLE = 1.0e-4f; - if (angle > MIN_ADJUSTMENT_ANGLE) { - // reduce angle by a fraction (reduces IK swing contribution of this joint) - angle /= (float)ancestorCount; - deltaRotation = glm::angleAxis(angle, axis); - } - - // The swing will re-orient the tip but there will tend to be be a non-zero delta between the tip's - // new rotation and its target. We compute that delta here and rotate the tipJoint accordingly. - glm::quat tipRelativeRotation = glm::inverse(deltaRotation * tipParentRotation) * target.getRotation(); - - // enforce tip's constraint - RotationConstraint* constraint = getConstraint(tipIndex); - if (constraint) { - bool constrained = constraint->apply(tipRelativeRotation); - if (constrained) { - // The tip's final parent-relative rotation violates its constraint - // so we try to twist this pivot to compensate. - glm::quat constrainedTipRotation = deltaRotation * tipParentRotation * tipRelativeRotation; - glm::quat missingRotation = target.getRotation() * glm::inverse(constrainedTipRotation); - glm::quat swingPart; - glm::quat twistPart; - glm::vec3 axis = glm::normalize(deltaRotation * leverArm); - swingTwistDecomposition(missingRotation, axis, swingPart, twistPart); - deltaRotation = twistPart * deltaRotation; - } - // we update the tip rotation here to rotate it as close to its target orientation as possible - // before moving on to next pivot - tipRotation = tipParentRotation * tipRelativeRotation; - } - } - ++ancestorCount; - - int parentIndex = _skeleton->getParentIndex(pivotIndex); - if (parentIndex == -1) { - // TODO? apply constraints to root? - // TODO? harvest the root's transform as movement of entire skeleton? - } else { - // compute joint's new parent-relative rotation after swing - // Q' = dQ * Q and Q = Qp * q --> q' = Qp^ * dQ * Q - glm::quat newRot = glm::normalize(glm::inverse( - absolutePoses[parentIndex].rot) * - deltaRotation * - absolutePoses[pivotIndex].rot); - - // enforce pivot's constraint - RotationConstraint* constraint = getConstraint(pivotIndex); - if (constraint) { - bool constrained = constraint->apply(newRot); - if (constrained) { - // the constraint will modify the movement of the tip so we have to compute the modified - // model-frame deltaRotation - // Q' = Qp^ * dQ * Q --> dQ = Qp * Q' * Q^ - deltaRotation = absolutePoses[parentIndex].rot * - newRot * - glm::inverse(absolutePoses[pivotIndex].rot); + if (targetType == IKTarget::Type::RotationAndPosition) { + // compute the swing that would get get tip closer + glm::vec3 targetLine = target.getTranslation() - jointPosition; + glm::vec3 axis = glm::cross(leverArm, targetLine); + float axisLength = glm::length(axis); + const float MIN_AXIS_LENGTH = 1.0e-4f; + if (axisLength > MIN_AXIS_LENGTH) { + // compute deltaRotation for alignment (swings tip closer to target) + axis /= axisLength; + float angle = acosf(glm::dot(leverArm, targetLine) / (glm::length(leverArm) * glm::length(targetLine))); + + // NOTE: even when axisLength is not zero (e.g. lever-arm and pivot-arm are not quite aligned) it is + // still possible for the angle to be zero so we also check that to avoid unnecessary calculations. + const float MIN_ADJUSTMENT_ANGLE = 1.0e-4f; + if (angle > MIN_ADJUSTMENT_ANGLE) { + // reduce angle by a fraction (for stability) + const float fraction = 0.5f; + angle *= fraction; + deltaRotation = glm::angleAxis(angle, axis); + + // The swing will re-orient the tip but there will tend to be be a non-zero delta between the tip's + // new rotation and its target. This is the final parent-relative rotation that the tip joint have + // make to achieve its target rotation. + glm::quat tipRelativeRotation = glm::inverse(deltaRotation * tipParentRotation) * target.getRotation(); + + // enforce tip's constraint + RotationConstraint* constraint = getConstraint(tipIndex); + if (constraint) { + bool constrained = constraint->apply(tipRelativeRotation); + if (constrained) { + // The tip's final parent-relative rotation would violate its constraint + // so we try to pre-twist this pivot to compensate. + glm::quat constrainedTipRotation = deltaRotation * tipParentRotation * tipRelativeRotation; + glm::quat missingRotation = target.getRotation() * glm::inverse(constrainedTipRotation); + glm::quat swingPart; + glm::quat twistPart; + glm::vec3 axis = glm::normalize(deltaRotation * leverArm); + swingTwistDecomposition(missingRotation, axis, swingPart, twistPart); + float dotSign = copysignf(1.0f, twistPart.w); + deltaRotation = glm::normalize(glm::lerp(glm::quat(), dotSign * twistPart, fraction)) * deltaRotation; + } + } } } - - // store the rotation change in the accumulator - _accumulators[pivotIndex].add(newRot); + } else if (targetType == IKTarget::Type::HmdHead) { + /* TODO: implement this + // An HmdHead target slaves the orientation of the end-effector by distributing rotation + // deltas up the hierarchy. Its target position is enforced later by shifting the hips. + deltaRotation = target.getRotation() * glm::inverse(tipRotation); + */ } + + // compute joint's new parent-relative rotation after swing + // Q' = dQ * Q and Q = Qp * q --> q' = Qp^ * dQ * Q + glm::quat newRot = glm::normalize(glm::inverse( + absolutePoses[pivotsParentIndex].rot) * + deltaRotation * + absolutePoses[pivotIndex].rot); + + // enforce pivot's constraint + RotationConstraint* constraint = getConstraint(pivotIndex); + if (constraint) { + bool constrained = constraint->apply(newRot); + if (constrained) { + // the constraint will modify the movement of the tip so we have to compute the modified + // model-frame deltaRotation + // Q' = Qp^ * dQ * Q --> dQ = Qp * Q' * Q^ + deltaRotation = absolutePoses[pivotsParentIndex].rot * + newRot * + glm::inverse(absolutePoses[pivotIndex].rot); + } + } + + // store the rotation change in the accumulator + _accumulators[pivotIndex].add(newRot); + // this joint has been changed so we check to see if it has the lowest index if (pivotIndex < lowestMovedIndex) { lowestMovedIndex = pivotIndex; @@ -250,10 +258,10 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vectorgetParentIndex(pivotIndex); + pivotIndex = pivotsParentIndex; + pivotsParentIndex = _skeleton->getParentIndex(pivotIndex); } } ++numLoops; @@ -276,17 +284,6 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector Date: Sat, 10 Oct 2015 19:23:21 -0700 Subject: [PATCH 18/49] experimental HMD hips tracking --- .../defaultAvatar_full/avatar-animation.json | 12 +++--- interface/src/avatar/MyAvatar.cpp | 4 +- .../animation/src/AnimInverseKinematics.cpp | 40 ++++++++++++++----- libraries/animation/src/IKTarget.cpp | 3 ++ libraries/animation/src/IKTarget.h | 1 + libraries/animation/src/Rig.cpp | 10 ++++- 6 files changed, 53 insertions(+), 17 deletions(-) diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index e930f583f6..737a27be02 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -16,12 +16,14 @@ { "jointName": "RightHand", "positionVar": "rightHandPosition", - "rotationVar": "rightHandRotation" + "rotationVar": "rightHandRotation", + "typeVar": "rightHandType" }, { "jointName": "LeftHand", "positionVar": "leftHandPosition", - "rotationVar": "leftHandRotation" + "rotationVar": "leftHandRotation", + "typeVar": "leftHandType" }, { "jointName": "RightFoot", @@ -39,13 +41,13 @@ "jointName": "Neck", "positionVar": "neckPosition", "rotationVar": "neckRotation", - "typeVar": "headAndNeckType" + "typeVar": "neckType" }, { "jointName": "Head", "positionVar": "headPosition", "rotationVar": "headRotation", - "typeVar": "headAndNeckType" + "typeVar": "headType" } ] }, @@ -63,7 +65,7 @@ "id": "spineLean", "type": "manipulator", "data": { - "alpha": 1.0, + "alpha": 0.0, "joints": [ { "var": "lean", "jointName": "Spine" } ] diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 22816e9001..41e067c047 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -337,16 +337,18 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { const float STRAIGHTENING_LEAN_DURATION = 0.5f; // seconds // define a vertical capsule + static float adebug = 1.0f; // adebug const float STRAIGHTENING_LEAN_CAPSULE_RADIUS = 0.2f; // meters const float STRAIGHTENING_LEAN_CAPSULE_LENGTH = 0.05f; // length of the cylinder part of the capsule in meters. auto newBodySensorMatrix = deriveBodyFromHMDSensor(); glm::vec3 diff = extractTranslation(newBodySensorMatrix) - extractTranslation(_bodySensorMatrix); - if (!_straighteningLean && (capsuleCheck(diff, STRAIGHTENING_LEAN_CAPSULE_LENGTH, STRAIGHTENING_LEAN_CAPSULE_RADIUS) || hmdIsAtRest)) { + if (!_straighteningLean && (capsuleCheck(diff, adebug * STRAIGHTENING_LEAN_CAPSULE_LENGTH, adebug * STRAIGHTENING_LEAN_CAPSULE_RADIUS) || hmdIsAtRest)) { // begin homing toward derived body position. _straighteningLean = true; _straighteningLeanAlpha = 0.0f; + adebug = 1000.0f; // adebug } else if (_straighteningLean) { diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 80c8152e3a..7e677abcba 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -98,8 +98,14 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: target.setType(animVars.lookup(targetVar.typeVar, (int)IKTarget::Type::RotationAndPosition)); if (target.getType() != IKTarget::Type::Unknown) { AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, underPoses); - target.setPose(animVars.lookup(targetVar.rotationVar, defaultPose.rot), - animVars.lookup(targetVar.positionVar, defaultPose.trans)); + glm::quat rotation = animVars.lookup(targetVar.rotationVar, defaultPose.rot); + glm::vec3 translation = animVars.lookup(targetVar.positionVar, defaultPose.trans); + if (target.getType() == IKTarget::Type::HipsRelativeRotationAndPosition) { + translation += _hipsOffset; + // HACK to test whether lifting idle hands will release the shoulders + translation.y += 0.10f; + } + target.setPose(rotation, translation); target.setIndex(targetVar.jointIndex); targets.push_back(target); if (targetVar.jointIndex > _maxTargetIndex) { @@ -125,6 +131,10 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: } } } + static int adebug = 0; ++adebug; bool verbose = (0 == (adebug % 100)); + if (verbose) { + std::cout << "adebug num targets = " << targets.size() << std::endl; // adebug + } } void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector& targets) { @@ -175,7 +185,8 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vectorgetAbsolutePose(_headIndex, underPoses).trans; - glm::vec3 over = under; if (target.getType() == IKTarget::Type::RotationOnly) { - over = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans; - } else if (target.getType() == IKTarget::Type::RotationAndPosition) { - over = target.getTranslation(); + // we want to shift the hips to bring the underpose closer + // to where the head happens to be (overpose) + glm::vec3 under = _skeleton->getAbsolutePose(_headIndex, underPoses).trans; + glm::vec3 actual = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans; + const float HEAD_OFFSET_SLAVE_FACTOR = 0.65f; + newHipsOffset += HEAD_OFFSET_SLAVE_FACTOR * (actual - under); + } else if (target.getType() == IKTarget::Type::HmdHead) { + // we want to shift the hips to bring the head to its designated position + glm::vec3 actual = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans; + hmdHipsOffset = _hipsOffset + target.getTranslation() - actual; } - const float HEAD_OFFSET_SLAVE_FACTOR = 0.65f; - newHipsOffset += HEAD_OFFSET_SLAVE_FACTOR * (over - under); } else if (target.getType() == IKTarget::Type::RotationAndPosition) { glm::vec3 actualPosition = _skeleton->getAbsolutePose(targetIndex, _relativePoses).trans; glm::vec3 targetPosition = target.getTranslation(); @@ -392,6 +408,10 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars // smooth transitions by relaxing _hipsOffset toward the new value const float HIPS_OFFSET_SLAVE_TIMESCALE = 0.15f; _hipsOffset += (newHipsOffset - _hipsOffset) * (dt / HIPS_OFFSET_SLAVE_TIMESCALE); + //_hipsOffset *= 0.0f; // adebug + if (glm::length2(hmdHipsOffset) < 100.0f) { + _hipsOffset = hmdHipsOffset; + } } } return _relativePoses; diff --git a/libraries/animation/src/IKTarget.cpp b/libraries/animation/src/IKTarget.cpp index a7e3296d35..b17f186b47 100644 --- a/libraries/animation/src/IKTarget.cpp +++ b/libraries/animation/src/IKTarget.cpp @@ -25,6 +25,9 @@ void IKTarget::setType(int type) { case (int)Type::HmdHead: _type = Type::HmdHead; break; + case (int)Type::HipsRelativeRotationAndPosition: + _type = Type::HipsRelativeRotationAndPosition; + break; default: _type = Type::Unknown; } diff --git a/libraries/animation/src/IKTarget.h b/libraries/animation/src/IKTarget.h index fa920d1511..983eafd9cb 100644 --- a/libraries/animation/src/IKTarget.h +++ b/libraries/animation/src/IKTarget.h @@ -18,6 +18,7 @@ public: RotationAndPosition, RotationOnly, HmdHead, + HipsRelativeRotationAndPosition, Unknown, }; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 3a1dafa10c..340c09060a 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1058,9 +1058,11 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { _animVars.set("headPosition", headPos); _animVars.set("headRotation", headRot); - _animVars.set("headAndNeckType", (int)IKTarget::Type::RotationAndPosition); + _animVars.set("headType", (int)IKTarget::Type::HmdHead); _animVars.set("neckPosition", neckPos); _animVars.set("neckRotation", neckRot); + //_animVars.set("neckType", (int)IKTarget::Type::RotationOnly); + _animVars.set("neckType", (int)IKTarget::Type::Unknown); // 'Unknown' disables the target } else { @@ -1072,8 +1074,10 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { _animVars.unset("headPosition"); _animVars.set("headRotation", realLocalHeadOrientation); _animVars.set("headAndNeckType", (int)IKTarget::Type::RotationOnly); + _animVars.set("headType", (int)IKTarget::Type::RotationOnly); _animVars.unset("neckPosition"); _animVars.unset("neckRotation"); + _animVars.set("neckType", (int)IKTarget::Type::RotationOnly); } } else if (!_enableAnimGraph) { @@ -1131,16 +1135,20 @@ void Rig::updateFromHandParameters(const HandParameters& params, float dt) { if (params.isLeftEnabled) { _animVars.set("leftHandPosition", rootBindPose.trans + rootBindPose.rot * yFlipHACK * params.leftPosition); _animVars.set("leftHandRotation", rootBindPose.rot * yFlipHACK * params.leftOrientation); + _animVars.set("leftHandType", (int)IKTarget::Type::RotationAndPosition); } else { _animVars.unset("leftHandPosition"); _animVars.unset("leftHandRotation"); + _animVars.set("leftHandType", (int)IKTarget::Type::HipsRelativeRotationAndPosition); } if (params.isRightEnabled) { _animVars.set("rightHandPosition", rootBindPose.trans + rootBindPose.rot * yFlipHACK * params.rightPosition); _animVars.set("rightHandRotation", rootBindPose.rot * yFlipHACK * params.rightOrientation); + _animVars.set("rightHandType", (int)IKTarget::Type::RotationAndPosition); } else { _animVars.unset("rightHandPosition"); _animVars.unset("rightHandRotation"); + _animVars.set("rightHandType", (int)IKTarget::Type::HipsRelativeRotationAndPosition); } // set leftHand grab vars From 44243aaa523b424d257d282f03be6936819d88af Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 12 Oct 2015 11:34:07 -0700 Subject: [PATCH 19/49] remove some debug code --- libraries/animation/src/AnimInverseKinematics.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 7e677abcba..fd25705660 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -131,10 +131,6 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: } } } - static int adebug = 0; ++adebug; bool verbose = (0 == (adebug % 100)); - if (verbose) { - std::cout << "adebug num targets = " << targets.size() << std::endl; // adebug - } } void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector& targets) { @@ -408,7 +404,6 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars // smooth transitions by relaxing _hipsOffset toward the new value const float HIPS_OFFSET_SLAVE_TIMESCALE = 0.15f; _hipsOffset += (newHipsOffset - _hipsOffset) * (dt / HIPS_OFFSET_SLAVE_TIMESCALE); - //_hipsOffset *= 0.0f; // adebug if (glm::length2(hmdHipsOffset) < 100.0f) { _hipsOffset = hmdHipsOffset; } From e1a5afcff317bf58190c8a52b34af624aebaa449 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 12 Oct 2015 11:42:03 -0700 Subject: [PATCH 20/49] re-enable avatar position update when moving HMD --- interface/src/avatar/MyAvatar.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 41e067c047..22816e9001 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -337,18 +337,16 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { const float STRAIGHTENING_LEAN_DURATION = 0.5f; // seconds // define a vertical capsule - static float adebug = 1.0f; // adebug const float STRAIGHTENING_LEAN_CAPSULE_RADIUS = 0.2f; // meters const float STRAIGHTENING_LEAN_CAPSULE_LENGTH = 0.05f; // length of the cylinder part of the capsule in meters. auto newBodySensorMatrix = deriveBodyFromHMDSensor(); glm::vec3 diff = extractTranslation(newBodySensorMatrix) - extractTranslation(_bodySensorMatrix); - if (!_straighteningLean && (capsuleCheck(diff, adebug * STRAIGHTENING_LEAN_CAPSULE_LENGTH, adebug * STRAIGHTENING_LEAN_CAPSULE_RADIUS) || hmdIsAtRest)) { + if (!_straighteningLean && (capsuleCheck(diff, STRAIGHTENING_LEAN_CAPSULE_LENGTH, STRAIGHTENING_LEAN_CAPSULE_RADIUS) || hmdIsAtRest)) { // begin homing toward derived body position. _straighteningLean = true; _straighteningLeanAlpha = 0.0f; - adebug = 1000.0f; // adebug } else if (_straighteningLean) { From 7b41efcf8622b4ac2a269b7e592e757615ec5c76 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 12 Oct 2015 13:35:21 -0700 Subject: [PATCH 21/49] All file types eligible for upload to asset server --- interface/src/Application.cpp | 128 ++++++++++---------- interface/src/Application.h | 2 +- interface/src/ui/AssetUploadDialogFactory.h | 1 - 3 files changed, 64 insertions(+), 67 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cfeb77f638..0d51ccbbc7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -126,6 +126,7 @@ #include "Stars.h" #include "ui/AddressBarDialog.h" #include "ui/AvatarInputs.h" +#include "ui/AssetUploadDialogFactory.h" #include "ui/DataWebDialog.h" #include "ui/DialogsManager.h" #include "ui/LoginDialog.h" @@ -159,6 +160,7 @@ static const QString SVO_JSON_EXTENSION = ".svo.json"; static const QString JS_EXTENSION = ".js"; static const QString FST_EXTENSION = ".fst"; static const QString FBX_EXTENSION = ".fbx"; +static const QString OBJ_EXTENSION = ".obj"; static const int MIRROR_VIEW_TOP_PADDING = 5; static const int MIRROR_VIEW_LEFT_PADDING = 10; @@ -179,9 +181,6 @@ static const unsigned int THROTTLED_SIM_FRAMERATE = 15; static const int TARGET_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / TARGET_SIM_FRAMERATE; static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SIM_FRAMERATE; -const QString CHECK_VERSION_URL = "https://highfidelity.com/latestVersion.xml"; -const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/hifi.skipversion"; - #ifndef __APPLE__ static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); #else @@ -197,8 +196,7 @@ const QHash Application::_acceptedExtensi { SVO_EXTENSION, &Application::importSVOFromURL }, { SVO_JSON_EXTENSION, &Application::importSVOFromURL }, { JS_EXTENSION, &Application::askToLoadScript }, - { FST_EXTENSION, &Application::askToSetAvatarUrl }, - { FBX_EXTENSION, &Application::askToUploadAsset } + { FST_EXTENSION, &Application::askToSetAvatarUrl } }; #ifdef Q_OS_WIN @@ -2023,21 +2021,14 @@ void Application::dropEvent(QDropEvent *event) { const QMimeData* mimeData = event->mimeData(); for (auto& url : mimeData->urls()) { QString urlString = url.toString(); - if (canAcceptURL(urlString) && acceptURL(urlString)) { + if (acceptURL(urlString, true)) { event->acceptProposedAction(); } } } void Application::dragEnterEvent(QDragEnterEvent* event) { - const QMimeData* mimeData = event->mimeData(); - for (auto& url : mimeData->urls()) { - auto urlString = url.toString(); - if (canAcceptURL(urlString)) { - event->acceptProposedAction(); - break; - } - } + event->acceptProposedAction(); } bool Application::acceptSnapshot(const QString& urlString) { @@ -3973,26 +3964,26 @@ bool Application::canAcceptURL(const QString& urlString) { return false; } -bool Application::acceptURL(const QString& urlString) { +bool Application::acceptURL(const QString& urlString, bool defaultUpload) { if (urlString.startsWith(HIFI_URL_SCHEME)) { // this is a hifi URL - have the AddressManager handle it QMetaObject::invokeMethod(DependencyManager::get().data(), "handleLookupString", Qt::AutoConnection, Q_ARG(const QString&, urlString)); return true; - } else { - QUrl url(urlString); - QHashIterator i(_acceptedExtensions); - QString lowerPath = url.path().toLower(); - while (i.hasNext()) { - i.next(); - if (lowerPath.endsWith(i.key())) { - AcceptURLMethod method = i.value(); - (this->*method)(urlString); - return true; - } + } + + QUrl url(urlString); + QHashIterator i(_acceptedExtensions); + QString lowerPath = url.path().toLower(); + while (i.hasNext()) { + i.next(); + if (lowerPath.endsWith(i.key())) { + AcceptURLMethod method = i.value(); + return (this->*method)(urlString); } } - return false; + + return defaultUpload && askToUploadAsset(urlString); } void Application::setSessionUUID(const QUuid& sessionUUID) { @@ -4076,8 +4067,36 @@ bool Application::askToUploadAsset(const QString& filename) { QUrl url { filename }; if (auto upload = DependencyManager::get()->createUpload(url.toLocalFile())) { + + QMessageBox messageBox; + messageBox.setWindowTitle("Asset upload"); + messageBox.setText("You are about to upload the following file to the asset server:\n" + + url.toDisplayString()); + messageBox.setInformativeText("Do you want to continue?"); + messageBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + messageBox.setDefaultButton(QMessageBox::Ok); + + // Option to drop model in world for models + if (filename.endsWith(FBX_EXTENSION) || filename.endsWith(OBJ_EXTENSION)) { + auto checkBox = new QCheckBox(&messageBox); + checkBox->setText("Drop model in world."); + messageBox.setCheckBox(checkBox); + } + + if (messageBox.exec() != QMessageBox::Ok) { + upload->deleteLater(); + return false; + } + // connect to the finished signal so we know when the AssetUpload is done - QObject::connect(upload, &AssetUpload::finished, this, &Application::assetUploadFinished); + if (messageBox.checkBox() && (messageBox.checkBox()->checkState() == Qt::Checked)) { + // Custom behavior for models + QObject::connect(upload, &AssetUpload::finished, this, &Application::assetUploadFinished); + } else { + QObject::connect(upload, &AssetUpload::finished, + &AssetUploadDialogFactory::getInstance(), + &AssetUploadDialogFactory::handleUploadFinished); + } // start the upload now upload->start(); @@ -4090,46 +4109,25 @@ bool Application::askToUploadAsset(const QString& filename) { } void Application::assetUploadFinished(AssetUpload* upload, const QString& hash) { - if (upload->getError() != AssetUpload::NoError) { - // figure out the right error message for the message box - QString additionalError; + auto filename = QFileInfo(upload->getFilename()).fileName(); + + if ((upload->getError() == AssetUpload::NoError) && + (filename.endsWith(FBX_EXTENSION) || filename.endsWith(OBJ_EXTENSION))) { - switch (upload->getError()) { - case AssetUpload::PermissionDenied: - additionalError = "You do not have permission to upload content to this asset-server."; - break; - case AssetUpload::TooLarge: - additionalError = "The uploaded content was too large and could not be stored in the asset-server."; - break; - case AssetUpload::FileOpenError: - additionalError = "The file could not be opened. Please check your permissions and try again."; - break; - case AssetUpload::NetworkError: - additionalError = "The file could not be opened. Please check your network connectivity."; - break; - default: - // not handled, do not show a message box - return; - } + auto entities = DependencyManager::get(); - // display a message box with the error - auto filename = QFileInfo(upload->getFilename()).fileName(); - QString errorMessage = QString("Failed to upload %1.\n\n%2").arg(filename, additionalError); - QMessageBox::warning(_window, "Failed Upload", errorMessage); + EntityItemProperties properties; + properties.setType(EntityTypes::Model); + properties.setModelURL(QString("%1:%2.%3").arg(ATP_SCHEME).arg(hash).arg(upload->getExtension())); + properties.setPosition(_myCamera.getPosition() + _myCamera.getOrientation() * Vectors::FRONT * 2.0f); + properties.setName(QUrl(upload->getFilename()).fileName()); + + entities->addEntity(properties); + + upload->deleteLater(); + } else { + AssetUploadDialogFactory::getInstance().handleUploadFinished(upload, hash); } - - auto entities = DependencyManager::get(); - auto myAvatar = getMyAvatar(); - - EntityItemProperties properties; - properties.setType(EntityTypes::Model); - properties.setModelURL(QString("%1:%2.%3").arg(ATP_SCHEME).arg(hash).arg(upload->getExtension())); - properties.setPosition(myAvatar->getPosition() + myAvatar->getOrientation() * Vectors::FRONT * 2.0f); - properties.setName(QUrl(upload->getFilename()).fileName()); - - entities->addEntity(properties); - - upload->deleteLater(); } ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUserLoaded, diff --git a/interface/src/Application.h b/interface/src/Application.h index 8444eab2b6..3e443ea843 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -211,7 +211,7 @@ public: void setScriptsLocation(const QString& scriptsLocation); bool canAcceptURL(const QString& url); - bool acceptURL(const QString& url); + bool acceptURL(const QString& url, bool defaultUpload = false); void setMaxOctreePacketsPerSecond(int maxOctreePPS); int getMaxOctreePacketsPerSecond(); diff --git a/interface/src/ui/AssetUploadDialogFactory.h b/interface/src/ui/AssetUploadDialogFactory.h index 36c5d10595..a8e8765f20 100644 --- a/interface/src/ui/AssetUploadDialogFactory.h +++ b/interface/src/ui/AssetUploadDialogFactory.h @@ -30,7 +30,6 @@ public: public slots: void showDialog(); -private slots: void handleUploadFinished(AssetUpload* upload, const QString& hash); private: From 22786dea7d3d3438888fe46cbadc15215b5b5fce Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 12 Oct 2015 13:35:26 -0700 Subject: [PATCH 22/49] cleanup --- .../defaultAvatar_full/avatar-animation.json | 12 +++++------ .../animation/src/AnimInverseKinematics.cpp | 20 ++++++++----------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index 737a27be02..682e0be1bf 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -27,15 +27,15 @@ }, { "jointName": "RightFoot", - "positionVar": "rightToePosition", - "rotationVar": "rightToeRotation", - "typeVar": "rightToeType" + "positionVar": "rightFootPosition", + "rotationVar": "rightFootRotation", + "typeVar": "rightFootType" }, { "jointName": "LeftFoot", - "positionVar": "leftToePosition", - "rotationVar": "leftToeRotation", - "typeVar": "leftToeType" + "positionVar": "leftFootPosition", + "rotationVar": "leftFootRotation", + "typeVar": "leftFootType" }, { "jointName": "Neck", diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index fd25705660..a1c6848b0c 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -102,8 +102,6 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: glm::vec3 translation = animVars.lookup(targetVar.positionVar, defaultPose.trans); if (target.getType() == IKTarget::Type::HipsRelativeRotationAndPosition) { translation += _hipsOffset; - // HACK to test whether lifting idle hands will release the shoulders - translation.y += 0.10f; } target.setPose(rotation, translation); target.setIndex(targetVar.jointIndex); @@ -363,20 +361,18 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars } else { // shift the hips according to the offset from the previous frame float offsetLength = glm::length(_hipsOffset); - const float MIN_OFFSET_LENGTH = 0.03f; - if (offsetLength > MIN_OFFSET_LENGTH) { - // but only if actual offset is long enough - float scaleFactor = ((offsetLength - MIN_OFFSET_LENGTH) / offsetLength); + const float MIN_HIPS_OFFSET_LENGTH = 0.03f; + if (offsetLength > MIN_HIPS_OFFSET_LENGTH) { + // but only if offset is long enough + float scaleFactor = ((offsetLength - MIN_HIPS_OFFSET_LENGTH) / offsetLength); _relativePoses[0].trans = underPoses[0].trans + scaleFactor * _hipsOffset; } solveWithCyclicCoordinateDescent(targets); - // compute the new target hips offset (for next frame) // by looking for discrepancies between where a targeted endEffector is // and where it wants to be (after IK solutions are done) - glm::vec3 hmdHipsOffset(100.0f); glm::vec3 newHipsOffset = Vectors::ZERO; for (auto& target: targets) { int targetIndex = target.getIndex(); @@ -392,7 +388,10 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars } else if (target.getType() == IKTarget::Type::HmdHead) { // we want to shift the hips to bring the head to its designated position glm::vec3 actual = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans; - hmdHipsOffset = _hipsOffset + target.getTranslation() - actual; + _hipsOffset += target.getTranslation() - actual; + // and ignore all other targets + newHipsOffset = _hipsOffset; + break; } } else if (target.getType() == IKTarget::Type::RotationAndPosition) { glm::vec3 actualPosition = _skeleton->getAbsolutePose(targetIndex, _relativePoses).trans; @@ -404,9 +403,6 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars // smooth transitions by relaxing _hipsOffset toward the new value const float HIPS_OFFSET_SLAVE_TIMESCALE = 0.15f; _hipsOffset += (newHipsOffset - _hipsOffset) * (dt / HIPS_OFFSET_SLAVE_TIMESCALE); - if (glm::length2(hmdHipsOffset) < 100.0f) { - _hipsOffset = hmdHipsOffset; - } } } return _relativePoses; From c666c9fb9b5df854990826a27d2b665aeb86a51e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 12 Oct 2015 13:40:33 -0700 Subject: [PATCH 23/49] Fix warning --- .../input-plugins/src/input-plugins/StandardController.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/StandardController.cpp b/libraries/input-plugins/src/input-plugins/StandardController.cpp index 4fb4a23654..9b89c081b3 100644 --- a/libraries/input-plugins/src/input-plugins/StandardController.cpp +++ b/libraries/input-plugins/src/input-plugins/StandardController.cpp @@ -17,8 +17,6 @@ const float CONTROLLER_THRESHOLD = 0.3f; -const float MAX_AXIS = 32768.0f; - StandardController::~StandardController() { } From 8ebdd25b7123e9620545471ac9783ca9a66e4c79 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 12 Oct 2015 14:07:23 -0700 Subject: [PATCH 24/49] more cleanup --- .../animation/src/AnimInverseKinematics.cpp | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index a1c6848b0c..17a1af1969 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -56,9 +56,9 @@ void AnimInverseKinematics::computeAbsolutePoses(AnimPoseVec& absolutePoses) con } void AnimInverseKinematics::setTargetVars( - const QString& jointName, - const QString& positionVar, - const QString& rotationVar, + const QString& jointName, + const QString& positionVar, + const QString& rotationVar, const QString& typeVar) { // if there are dups, last one wins. bool found = false; @@ -98,7 +98,7 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: target.setType(animVars.lookup(targetVar.typeVar, (int)IKTarget::Type::RotationAndPosition)); if (target.getType() != IKTarget::Type::Unknown) { AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, underPoses); - glm::quat rotation = animVars.lookup(targetVar.rotationVar, defaultPose.rot); + glm::quat rotation = animVars.lookup(targetVar.rotationVar, defaultPose.rot); glm::vec3 translation = animVars.lookup(targetVar.positionVar, defaultPose.trans); if (target.getType() == IKTarget::Type::HipsRelativeRotationAndPosition) { translation += _hipsOffset; @@ -168,7 +168,7 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vectorapply(tipRelativeRotation); if (constrained) { - // The tip's final parent-relative rotation would violate its constraint + // The tip's final parent-relative rotation would violate its constraint // so we try to pre-twist this pivot to compensate. glm::quat constrainedTipRotation = deltaRotation * tipParentRotation * tipRelativeRotation; glm::quat missingRotation = target.getRotation() * glm::inverse(constrainedTipRotation); @@ -225,11 +225,12 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vectorgetAbsolutePose(_headIndex, underPoses).trans; glm::vec3 actual = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans; From eea89ba010bedfe3052bf14e68450a6ba404e129 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 12 Oct 2015 14:26:28 -0700 Subject: [PATCH 25/49] CR - Rename method --- interface/src/Application.cpp | 4 ++-- interface/src/Application.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0d51ccbbc7..9e9830d977 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4091,7 +4091,7 @@ bool Application::askToUploadAsset(const QString& filename) { // connect to the finished signal so we know when the AssetUpload is done if (messageBox.checkBox() && (messageBox.checkBox()->checkState() == Qt::Checked)) { // Custom behavior for models - QObject::connect(upload, &AssetUpload::finished, this, &Application::assetUploadFinished); + QObject::connect(upload, &AssetUpload::finished, this, &Application::modelUploadFinished); } else { QObject::connect(upload, &AssetUpload::finished, &AssetUploadDialogFactory::getInstance(), @@ -4108,7 +4108,7 @@ bool Application::askToUploadAsset(const QString& filename) { return false; } -void Application::assetUploadFinished(AssetUpload* upload, const QString& hash) { +void Application::modelUploadFinished(AssetUpload* upload, const QString& hash) { auto filename = QFileInfo(upload->getFilename()).fileName(); if ((upload->getError() == AssetUpload::NoError) && diff --git a/interface/src/Application.h b/interface/src/Application.h index 3e443ea843..a2125e7e09 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -329,7 +329,7 @@ private slots: bool askToSetAvatarUrl(const QString& url); bool askToLoadScript(const QString& scriptFilenameOrURL); bool askToUploadAsset(const QString& asset); - void assetUploadFinished(AssetUpload* upload, const QString& hash); + void modelUploadFinished(AssetUpload* upload, const QString& hash); void setSessionUUID(const QUuid& sessionUUID); void domainChanged(const QString& domainHostname); From 84f0c404adf6d3b5f628cf2645fd90eb40dca687 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 12 Oct 2015 14:55:52 -0700 Subject: [PATCH 26/49] fix bug related to camera lock for entity orbit and pan --- examples/edit.js | 593 +++++++++++++++++++------ examples/libraries/entityCameraTool.js | 208 +++++++-- 2 files changed, 622 insertions(+), 179 deletions(-) diff --git a/examples/edit.js b/examples/edit.js index 0afc3ec1b6..09d30c712b 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -39,7 +39,9 @@ var lightOverlayManager = new LightOverlayManager(); var cameraManager = new CameraManager(); var grid = Grid(); -gridTool = GridTool({ horizontalGrid: grid }); +gridTool = GridTool({ + horizontalGrid: grid +}); gridTool.setVisible(false); var entityListTool = EntityListTool(); @@ -92,8 +94,8 @@ var INSUFFICIENT_PERMISSIONS_ERROR_MSG = "You do not have the necessary permissi var INSUFFICIENT_PERMISSIONS_IMPORT_ERROR_MSG = "You do not have the necessary permissions to place items on this domain." var modelURLs = [ - "Insert the URL to your FBX" - ]; + "Insert the URL to your FBX" +]; var mode = 0; var isActive = false; @@ -109,20 +111,30 @@ var importingSVOImageOverlay = Overlays.addOverlay("image", { width: 20, height: 20, alpha: 1.0, - color: { red: 255, green: 255, blue: 255 }, + color: { + red: 255, + green: 255, + blue: 255 + }, x: Window.innerWidth - IMPORTING_SVO_OVERLAY_WIDTH, y: Window.innerHeight - IMPORTING_SVO_OVERLAY_HEIGHT, visible: false, }); var importingSVOTextOverlay = Overlays.addOverlay("text", { - font: { size: 14 }, + font: { + size: 14 + }, text: "Importing SVO...", leftMargin: IMPORTING_SVO_OVERLAY_LEFT_MARGIN, x: Window.innerWidth - IMPORTING_SVO_OVERLAY_WIDTH - IMPORTING_SVO_OVERLAY_MARGIN, y: Window.innerHeight - IMPORTING_SVO_OVERLAY_HEIGHT - IMPORTING_SVO_OVERLAY_MARGIN, width: IMPORTING_SVO_OVERLAY_WIDTH, height: IMPORTING_SVO_OVERLAY_HEIGHT, - backgroundColor: { red: 80, green: 80, blue: 80 }, + backgroundColor: { + red: 80, + green: 80, + blue: 80 + }, backgroundAlpha: 0.7, visible: false, }); @@ -131,7 +143,7 @@ var MARKETPLACE_URL = "https://metaverse.highfidelity.com/marketplace"; var marketplaceWindow = new WebWindow('Marketplace', MARKETPLACE_URL, 900, 700, false); marketplaceWindow.setVisible(false); -var toolBar = (function () { +var toolBar = (function() { var that = {}, toolBar, activeButton, @@ -146,7 +158,7 @@ var toolBar = (function () { browseMarketplaceButton; function initialize() { - toolBar = new ToolBar(0, 0, ToolBar.VERTICAL, "highfidelity.edit.toolbar", function (windowDimensions, toolbar) { + toolBar = new ToolBar(0, 0, ToolBar.VERTICAL, "highfidelity.edit.toolbar", function(windowDimensions, toolbar) { return { x: windowDimensions.x - 8 - toolbar.width, y: (windowDimensions.y - toolbar.height) / 2 @@ -163,7 +175,12 @@ var toolBar = (function () { activeButton = toolBar.addTool({ imageURL: toolIconUrl + "edit-status.svg", - subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + subImage: { + x: 0, + y: Tool.IMAGE_WIDTH, + width: Tool.IMAGE_WIDTH, + height: Tool.IMAGE_HEIGHT + }, width: toolWidth, height: toolHeight, alpha: 0.9, @@ -172,7 +189,12 @@ var toolBar = (function () { newModelButton = toolBar.addTool({ imageURL: toolIconUrl + "upload.svg", - subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + subImage: { + x: 0, + y: Tool.IMAGE_WIDTH, + width: Tool.IMAGE_WIDTH, + height: Tool.IMAGE_HEIGHT + }, width: toolWidth, height: toolHeight, alpha: 0.9, @@ -181,7 +203,12 @@ var toolBar = (function () { newCubeButton = toolBar.addTool({ imageURL: toolIconUrl + "add-cube.svg", - subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + subImage: { + x: 0, + y: Tool.IMAGE_WIDTH, + width: Tool.IMAGE_WIDTH, + height: Tool.IMAGE_HEIGHT + }, width: toolWidth, height: toolHeight, alpha: 0.9, @@ -190,7 +217,12 @@ var toolBar = (function () { newSphereButton = toolBar.addTool({ imageURL: toolIconUrl + "add-sphere.svg", - subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + subImage: { + x: 0, + y: Tool.IMAGE_WIDTH, + width: Tool.IMAGE_WIDTH, + height: Tool.IMAGE_HEIGHT + }, width: toolWidth, height: toolHeight, alpha: 0.9, @@ -199,7 +231,12 @@ var toolBar = (function () { newLightButton = toolBar.addTool({ imageURL: toolIconUrl + "light.svg", - subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + subImage: { + x: 0, + y: Tool.IMAGE_WIDTH, + width: Tool.IMAGE_WIDTH, + height: Tool.IMAGE_HEIGHT + }, width: toolWidth, height: toolHeight, alpha: 0.9, @@ -208,7 +245,12 @@ var toolBar = (function () { newTextButton = toolBar.addTool({ imageURL: toolIconUrl + "add-text.svg", - subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + subImage: { + x: 0, + y: Tool.IMAGE_WIDTH, + width: Tool.IMAGE_WIDTH, + height: Tool.IMAGE_HEIGHT + }, width: toolWidth, height: toolHeight, alpha: 0.9, @@ -217,7 +259,12 @@ var toolBar = (function () { newWebButton = toolBar.addTool({ imageURL: "https://hifi-public.s3.amazonaws.com/images/www.svg", - subImage: { x: 0, y: 0, width: 128, height: 128 }, + subImage: { + x: 0, + y: 0, + width: 128, + height: 128 + }, width: toolWidth, height: toolHeight, alpha: 0.9, @@ -226,7 +273,12 @@ var toolBar = (function () { newZoneButton = toolBar.addTool({ imageURL: toolIconUrl + "zonecube_text.svg", - subImage: { x: 0, y: 128, width: 128, height: 128 }, + subImage: { + x: 0, + y: 128, + width: 128, + height: 128 + }, width: toolWidth, height: toolHeight, alpha: 0.9, @@ -235,7 +287,12 @@ var toolBar = (function () { newPolyVoxButton = toolBar.addTool({ imageURL: toolIconUrl + "polyvox.svg", - subImage: { x: 0, y: 0, width: 256, height: 256 }, + subImage: { + x: 0, + y: 0, + width: 256, + height: 256 + }, width: toolWidth, height: toolHeight, alpha: 0.9, @@ -293,6 +350,7 @@ var toolBar = (function () { var RESIZE_INTERVAL = 50; var RESIZE_TIMEOUT = 120000; // 2 minutes var RESIZE_MAX_CHECKS = RESIZE_TIMEOUT / RESIZE_INTERVAL; + function addModel(url) { var entityID = createNewEntity({ type: "Model", @@ -314,7 +372,7 @@ var toolBar = (function () { var entityID = null; if (position != null) { position = grid.snapToSurface(grid.snapToGrid(position, false, dimensions), dimensions), - properties.position = position; + properties.position = position; entityID = Entities.addEntity(properties); if (dragOnCreate) { @@ -329,12 +387,15 @@ var toolBar = (function () { var newModelButtonDown = false; var browseMarketplaceButtonDown = false; - that.mousePressEvent = function (event) { + that.mousePressEvent = function(event) { var clickedOverlay, url, file; - clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); + clickedOverlay = Overlays.getOverlayAtPoint({ + x: event.x, + y: event.y + }); if (activeButton === toolBar.clicked(clickedOverlay)) { that.setActive(!isActive); @@ -360,7 +421,11 @@ var toolBar = (function () { createNewEntity({ type: "Box", dimensions: DEFAULT_DIMENSIONS, - color: { red: 255, green: 0, blue: 0 } + color: { + red: 255, + green: 0, + blue: 0 + } }); return true; @@ -370,7 +435,11 @@ var toolBar = (function () { createNewEntity({ type: "Sphere", dimensions: DEFAULT_DIMENSIONS, - color: { red: 255, green: 0, blue: 0 } + color: { + red: 255, + green: 0, + blue: 0 + } }); return true; @@ -381,7 +450,11 @@ var toolBar = (function () { type: "Light", dimensions: DEFAULT_LIGHT_DIMENSIONS, isSpotlight: false, - color: { red: 150, green: 150, blue: 150 }, + color: { + red: 150, + green: 150, + blue: 150 + }, constantAttenuation: 1, linearAttenuation: 0, @@ -396,9 +469,21 @@ var toolBar = (function () { if (newTextButton === toolBar.clicked(clickedOverlay)) { createNewEntity({ type: "Text", - dimensions: { x: 0.65, y: 0.3, z: 0.01 }, - backgroundColor: { red: 64, green: 64, blue: 64 }, - textColor: { red: 255, green: 255, blue: 255 }, + dimensions: { + x: 0.65, + y: 0.3, + z: 0.01 + }, + backgroundColor: { + red: 64, + green: 64, + blue: 64 + }, + textColor: { + red: 255, + green: 255, + blue: 255 + }, text: "some text", lineHeight: 0.06 }); @@ -409,7 +494,11 @@ var toolBar = (function () { if (newWebButton === toolBar.clicked(clickedOverlay)) { createNewEntity({ type: "Web", - dimensions: { x: 1.6, y: 0.9, z: 0.01 }, + dimensions: { + x: 1.6, + y: 0.9, + z: 0.01 + }, sourceUrl: "https://highfidelity.com/", }); @@ -419,7 +508,11 @@ var toolBar = (function () { if (newZoneButton === toolBar.clicked(clickedOverlay)) { createNewEntity({ type: "Zone", - dimensions: { x: 10, y: 10, z: 10 }, + dimensions: { + x: 10, + y: 10, + z: 10 + }, }); return true; @@ -428,27 +521,83 @@ var toolBar = (function () { if (newPolyVoxButton === toolBar.clicked(clickedOverlay)) { var polyVoxId = createNewEntity({ type: "PolyVox", - dimensions: { x: 10, y: 10, z: 10 }, - voxelVolumeSize: {x:16, y:16, z:16}, + dimensions: { + x: 10, + y: 10, + z: 10 + }, + voxelVolumeSize: { + x: 16, + y: 16, + z: 16 + }, voxelSurfaceStyle: 2 }); for (var x = 1; x <= 14; x++) { - Entities.setVoxel(polyVoxId, {x: x, y: 1, z: 1}, 255); - Entities.setVoxel(polyVoxId, {x: x, y: 14, z: 1}, 255); - Entities.setVoxel(polyVoxId, {x: x, y: 1, z: 14}, 255); - Entities.setVoxel(polyVoxId, {x: x, y: 14, z: 14}, 255); + Entities.setVoxel(polyVoxId, { + x: x, + y: 1, + z: 1 + }, 255); + Entities.setVoxel(polyVoxId, { + x: x, + y: 14, + z: 1 + }, 255); + Entities.setVoxel(polyVoxId, { + x: x, + y: 1, + z: 14 + }, 255); + Entities.setVoxel(polyVoxId, { + x: x, + y: 14, + z: 14 + }, 255); } for (var y = 2; y <= 13; y++) { - Entities.setVoxel(polyVoxId, {x: 1, y: y, z: 1}, 255); - Entities.setVoxel(polyVoxId, {x: 14, y: y, z: 1}, 255); - Entities.setVoxel(polyVoxId, {x: 1, y: y, z: 14}, 255); - Entities.setVoxel(polyVoxId, {x: 14, y: y, z: 14}, 255); + Entities.setVoxel(polyVoxId, { + x: 1, + y: y, + z: 1 + }, 255); + Entities.setVoxel(polyVoxId, { + x: 14, + y: y, + z: 1 + }, 255); + Entities.setVoxel(polyVoxId, { + x: 1, + y: y, + z: 14 + }, 255); + Entities.setVoxel(polyVoxId, { + x: 14, + y: y, + z: 14 + }, 255); } for (var z = 2; z <= 13; z++) { - Entities.setVoxel(polyVoxId, {x: 1, y: 1, z: z}, 255); - Entities.setVoxel(polyVoxId, {x: 14, y: 1, z: z}, 255); - Entities.setVoxel(polyVoxId, {x: 1, y: 14, z: z}, 255); - Entities.setVoxel(polyVoxId, {x: 14, y: 14, z: z}, 255); + Entities.setVoxel(polyVoxId, { + x: 1, + y: 1, + z: z + }, 255); + Entities.setVoxel(polyVoxId, { + x: 14, + y: 1, + z: z + }, 255); + Entities.setVoxel(polyVoxId, { + x: 1, + y: 14, + z: z + }, 255); + Entities.setVoxel(polyVoxId, { + x: 14, + y: 14, + z: z + }, 255); } @@ -461,7 +610,10 @@ var toolBar = (function () { that.mouseReleaseEvent = function(event) { var handled = false; if (newModelButtonDown) { - var clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); + var clickedOverlay = Overlays.getOverlayAtPoint({ + x: event.x, + y: event.y + }); if (newModelButton === toolBar.clicked(clickedOverlay)) { url = Window.prompt("Model URL", modelURLs[Math.floor(Math.random() * modelURLs.length)]); if (url !== null && url !== "") { @@ -470,7 +622,10 @@ var toolBar = (function () { handled = true; } } else if (browseMarketplaceButtonDown) { - var clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); + var clickedOverlay = Overlays.getOverlayAtPoint({ + x: event.x, + y: event.y + }); if (browseMarketplaceButton === toolBar.clicked(clickedOverlay)) { url = Window.s3Browse(".*(fbx|FBX|obj|OBJ)"); if (url !== null && url !== "") { @@ -497,7 +652,7 @@ var toolBar = (function () { } }); - that.cleanup = function () { + that.cleanup = function() { toolBar.cleanup(); }; @@ -568,17 +723,26 @@ function findClickedEntity(event) { } var foundEntity = result.entityID; - return { pickRay: pickRay, entityID: foundEntity }; + return { + pickRay: pickRay, + entityID: foundEntity + }; } var mouseHasMovedSincePress = false; var mousePressStartTime = 0; -var mousePressStartPosition = { x: 0, y: 0 }; +var mousePressStartPosition = { + x: 0, + y: 0 +}; var mouseDown = false; function mousePressEvent(event) { mouseDown = true; - mousePressStartPosition = { x: event.x, y: event.y }; + mousePressStartPosition = { + x: event.x, + y: event.y + }; mousePressStartTime = Date.now(); mouseHasMovedSincePress = false; mouseCapturedByTool = false; @@ -605,9 +769,11 @@ var IDLE_MOUSE_TIMEOUT = 200; var DEFAULT_ENTITY_DRAG_DROP_DISTANCE = 2.0; var lastMouseMoveEvent = null; + function mouseMoveEventBuffered(event) { lastMouseMoveEvent = event; } + function mouseMove(event) { if (mouseDown && !mouseHasMovedSincePress) { var timeSincePressMicro = Date.now() - mousePressStartTime; @@ -647,7 +813,10 @@ function mouseMove(event) { return; } - lastMousePosition = { x: event.x, y: event.y }; + lastMousePosition = { + x: event.x, + y: event.y + }; idleMouseTimerId = Script.setTimeout(handleIdleMouse, IDLE_MOUSE_TIMEOUT); } @@ -660,22 +829,25 @@ function highlightEntityUnderCursor(position, accurateRay) { var pickRay = Camera.computePickRay(position.x, position.y); var entityIntersection = Entities.findRayIntersection(pickRay, accurateRay); if (entityIntersection.accurate) { - if(highlightedEntityID && highlightedEntityID != entityIntersection.entityID) { + if (highlightedEntityID && highlightedEntityID != entityIntersection.entityID) { selectionDisplay.unhighlightSelectable(highlightedEntityID); - highlightedEntityID = { id: -1 }; + highlightedEntityID = { + id: -1 + }; } var halfDiagonal = Vec3.length(entityIntersection.properties.dimensions) / 2.0; var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(), - entityIntersection.properties.position)) * 180 / 3.14; + entityIntersection.properties.position)) * 180 / 3.14; - var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE) - && (allowSmallModels || angularSize > MIN_ANGULAR_SIZE); + var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE) && (allowSmallModels || angularSize > MIN_ANGULAR_SIZE); if (entityIntersection.entityID && sizeOK) { if (wantEntityGlow) { - Entities.editEntity(entityIntersection.entityID, { glowLevel: 0.25 }); + Entities.editEntity(entityIntersection.entityID, { + glowLevel: 0.25 + }); } highlightedEntityID = entityIntersection.entityID; selectionDisplay.highlightSelectable(entityIntersection.entityID); @@ -693,18 +865,23 @@ function mouseReleaseEvent(event) { lastMouseMoveEvent = null; } if (propertyMenu.mouseReleaseEvent(event) || toolBar.mouseReleaseEvent(event)) { + return true; } if (placingEntityID) { + if (isActive) { + selectionManager.setSelections([placingEntityID]); } placingEntityID = null; } if (isActive && selectionManager.hasSelection()) { + tooltip.show(false); } if (mouseCapturedByTool) { + return; } @@ -757,8 +934,7 @@ function mouseClickEvent(event) { var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(), properties.position)) * 180 / 3.14; - var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE) - && (allowSmallModels || angularSize > MIN_ANGULAR_SIZE); + var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE) && (allowSmallModels || angularSize > MIN_ANGULAR_SIZE); if (0 < x && sizeOK) { entitySelected = true; @@ -779,8 +955,8 @@ function mouseClickEvent(event) { if (Menu.isOptionChecked(MENU_AUTO_FOCUS_ON_SELECT)) { cameraManager.enable(); cameraManager.focus(selectionManager.worldPosition, - selectionManager.worldDimensions, - Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + selectionManager.worldDimensions, + Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); } } } @@ -813,44 +989,125 @@ Controller.mouseReleaseEvent.connect(mouseReleaseEvent); // added it. var modelMenuAddedDelete = false; var originalLightsArePickable = Entities.getLightsArePickable(); + function setupModelMenus() { print("setupModelMenus()"); // adj our menuitems - Menu.addMenuItem({ menuName: "Edit", menuItemName: "Models", isSeparator: true, beforeItem: "Physics" }); + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: "Models", + isSeparator: true, + beforeItem: "Physics" + }); if (!Menu.menuItemExists("Edit", "Delete")) { print("no delete... adding ours"); - Menu.addMenuItem({ menuName: "Edit", menuItemName: "Delete", - shortcutKeyEvent: { text: "backspace" }, afterItem: "Models" }); + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: "Delete", + shortcutKeyEvent: { + text: "backspace" + }, + afterItem: "Models" + }); modelMenuAddedDelete = true; } else { print("delete exists... don't add ours"); } - Menu.addMenuItem({ menuName: "Edit", menuItemName: "Entity List...", shortcutKey: "CTRL+META+L", afterItem: "Models" }); - Menu.addMenuItem({ menuName: "Edit", menuItemName: "Allow Selecting of Large Models", shortcutKey: "CTRL+META+L", - afterItem: "Entity List...", isCheckable: true, isChecked: true }); - Menu.addMenuItem({ menuName: "Edit", menuItemName: "Allow Selecting of Small Models", shortcutKey: "CTRL+META+S", - afterItem: "Allow Selecting of Large Models", isCheckable: true, isChecked: true }); - Menu.addMenuItem({ menuName: "Edit", menuItemName: "Allow Selecting of Lights", shortcutKey: "CTRL+SHIFT+META+L", - afterItem: "Allow Selecting of Small Models", isCheckable: true }); - Menu.addMenuItem({ menuName: "Edit", menuItemName: "Select All Entities In Box", shortcutKey: "CTRL+SHIFT+META+A", - afterItem: "Allow Selecting of Lights" }); - Menu.addMenuItem({ menuName: "Edit", menuItemName: "Select All Entities Touching Box", shortcutKey: "CTRL+SHIFT+META+T", - afterItem: "Select All Entities In Box" }); + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: "Entity List...", + shortcutKey: "CTRL+META+L", + afterItem: "Models" + }); + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: "Allow Selecting of Large Models", + shortcutKey: "CTRL+META+L", + afterItem: "Entity List...", + isCheckable: true, + isChecked: true + }); + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: "Allow Selecting of Small Models", + shortcutKey: "CTRL+META+S", + afterItem: "Allow Selecting of Large Models", + isCheckable: true, + isChecked: true + }); + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: "Allow Selecting of Lights", + shortcutKey: "CTRL+SHIFT+META+L", + afterItem: "Allow Selecting of Small Models", + isCheckable: true + }); + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: "Select All Entities In Box", + shortcutKey: "CTRL+SHIFT+META+A", + afterItem: "Allow Selecting of Lights" + }); + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: "Select All Entities Touching Box", + shortcutKey: "CTRL+SHIFT+META+T", + afterItem: "Select All Entities In Box" + }); - Menu.addMenuItem({ menuName: "File", menuItemName: "Models", isSeparator: true, beforeItem: "Settings" }); - Menu.addMenuItem({ menuName: "File", menuItemName: "Export Entities", shortcutKey: "CTRL+META+E", afterItem: "Models" }); - Menu.addMenuItem({ menuName: "File", menuItemName: "Import Entities", shortcutKey: "CTRL+META+I", afterItem: "Export Entities" }); - Menu.addMenuItem({ menuName: "File", menuItemName: "Import Entities from URL", shortcutKey: "CTRL+META+U", afterItem: "Import Entities" }); + Menu.addMenuItem({ + menuName: "File", + menuItemName: "Models", + isSeparator: true, + beforeItem: "Settings" + }); + Menu.addMenuItem({ + menuName: "File", + menuItemName: "Export Entities", + shortcutKey: "CTRL+META+E", + afterItem: "Models" + }); + Menu.addMenuItem({ + menuName: "File", + menuItemName: "Import Entities", + shortcutKey: "CTRL+META+I", + afterItem: "Export Entities" + }); + Menu.addMenuItem({ + menuName: "File", + menuItemName: "Import Entities from URL", + shortcutKey: "CTRL+META+U", + afterItem: "Import Entities" + }); - Menu.addMenuItem({ menuName: "View", menuItemName: MENU_AUTO_FOCUS_ON_SELECT, - isCheckable: true, isChecked: Settings.getValue(SETTING_AUTO_FOCUS_ON_SELECT) == "true" }); - Menu.addMenuItem({ menuName: "View", menuItemName: MENU_EASE_ON_FOCUS, afterItem: MENU_AUTO_FOCUS_ON_SELECT, - isCheckable: true, isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) == "true" }); - Menu.addMenuItem({ menuName: "View", menuItemName: MENU_SHOW_LIGHTS_IN_EDIT_MODE, afterItem: MENU_EASE_ON_FOCUS, - isCheckable: true, isChecked: Settings.getValue(SETTING_SHOW_LIGHTS_IN_EDIT_MODE) == "true" }); - Menu.addMenuItem({ menuName: "View", menuItemName: MENU_SHOW_ZONES_IN_EDIT_MODE, afterItem: MENU_SHOW_LIGHTS_IN_EDIT_MODE, - isCheckable: true, isChecked: Settings.getValue(SETTING_SHOW_ZONES_IN_EDIT_MODE) == "true" }); + Menu.addMenuItem({ + menuName: "View", + menuItemName: MENU_AUTO_FOCUS_ON_SELECT, + isCheckable: true, + isChecked: Settings.getValue(SETTING_AUTO_FOCUS_ON_SELECT) == "true" + }); + Menu.addMenuItem({ + menuName: "View", + menuItemName: MENU_EASE_ON_FOCUS, + afterItem: MENU_AUTO_FOCUS_ON_SELECT, + isCheckable: true, + isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) == "true" + }); + Menu.addMenuItem({ + menuName: "View", + menuItemName: MENU_SHOW_LIGHTS_IN_EDIT_MODE, + afterItem: MENU_EASE_ON_FOCUS, + isCheckable: true, + isChecked: Settings.getValue(SETTING_SHOW_LIGHTS_IN_EDIT_MODE) == "true" + }); + Menu.addMenuItem({ + menuName: "View", + menuItemName: MENU_SHOW_ZONES_IN_EDIT_MODE, + afterItem: MENU_SHOW_LIGHTS_IN_EDIT_MODE, + isCheckable: true, + isChecked: Settings.getValue(SETTING_SHOW_ZONES_IN_EDIT_MODE) == "true" + }); Entities.setLightsArePickable(false); } @@ -903,7 +1160,7 @@ var lastOrientation = null; var lastPosition = null; // Do some stuff regularly, like check for placement of various overlays -Script.update.connect(function (deltaTime) { +Script.update.connect(function(deltaTime) { progressDialog.move(); selectionDisplay.checkMove(); var dOrientation = Math.abs(Quat.dot(Camera.orientation, lastOrientation) - 1); @@ -920,16 +1177,14 @@ Script.update.connect(function (deltaTime) { }); function insideBox(center, dimensions, point) { - return (Math.abs(point.x - center.x) <= (dimensions.x / 2.0)) - && (Math.abs(point.y - center.y) <= (dimensions.y / 2.0)) - && (Math.abs(point.z - center.z) <= (dimensions.z / 2.0)); + return (Math.abs(point.x - center.x) <= (dimensions.x / 2.0)) && (Math.abs(point.y - center.y) <= (dimensions.y / 2.0)) && (Math.abs(point.z - center.z) <= (dimensions.z / 2.0)); } function selectAllEtitiesInCurrentSelectionBox(keepIfTouching) { if (selectionManager.hasSelection()) { // Get all entities touching the bounding box of the current selection var boundingBoxCorner = Vec3.subtract(selectionManager.worldPosition, - Vec3.multiply(selectionManager.worldDimensions, 0.5)); + Vec3.multiply(selectionManager.worldDimensions, 0.5)); var entities = Entities.findEntitiesInBox(boundingBoxCorner, selectionManager.worldDimensions); if (!keepIfTouching) { @@ -941,9 +1196,13 @@ function selectAllEtitiesInCurrentSelectionBox(keepIfTouching) { } else { isValid = function(position) { var localPosition = Vec3.multiplyQbyV(Quat.inverse(selectionManager.localRotation), - Vec3.subtract(position, - selectionManager.localPosition)); - return insideBox({ x: 0, y: 0, z: 0 }, selectionManager.localDimensions, localPosition); + Vec3.subtract(position, + selectionManager.localPosition)); + return insideBox({ + x: 0, + y: 0, + z: 0 + }, selectionManager.localDimensions, localPosition); } } for (var i = 0; i < entities.length; ++i) { @@ -1038,15 +1297,11 @@ function getPositionToCreateEntity() { var placementPosition = Vec3.sum(Camera.position, offset); var cameraPosition = Camera.position; - + var HALF_TREE_SCALE = 16384; - var cameraOutOfBounds = Math.abs(cameraPosition.x) > HALF_TREE_SCALE - || Math.abs(cameraPosition.y) > HALF_TREE_SCALE - || Math.abs(cameraPosition.z) > HALF_TREE_SCALE; - var placementOutOfBounds = Math.abs(placementPosition.x) > HALF_TREE_SCALE - || Math.abs(placementPosition.y) > HALF_TREE_SCALE - || Math.abs(placementPosition.z) > HALF_TREE_SCALE; + var cameraOutOfBounds = Math.abs(cameraPosition.x) > HALF_TREE_SCALE || Math.abs(cameraPosition.y) > HALF_TREE_SCALE || Math.abs(cameraPosition.z) > HALF_TREE_SCALE; + var placementOutOfBounds = Math.abs(placementPosition.x) > HALF_TREE_SCALE || Math.abs(placementPosition.y) > HALF_TREE_SCALE || Math.abs(placementPosition.z) > HALF_TREE_SCALE; if (cameraOutOfBounds && placementOutOfBounds) { return null; @@ -1065,14 +1320,22 @@ function importSVO(importURL) { return; } - Overlays.editOverlay(importingSVOTextOverlay, { visible: true }); - Overlays.editOverlay(importingSVOImageOverlay, { visible: true }); + Overlays.editOverlay(importingSVOTextOverlay, { + visible: true + }); + Overlays.editOverlay(importingSVOImageOverlay, { + visible: true + }); var success = Clipboard.importEntities(importURL); if (success) { var VERY_LARGE = 10000; - var position = { x: 0, y: 0, z: 0 }; + var position = { + x: 0, + y: 0, + z: 0 + }; if (Clipboard.getClipboardContentsLargestDimension() < VERY_LARGE) { position = getPositionToCreateEntity(); } @@ -1091,8 +1354,12 @@ function importSVO(importURL) { Window.alert("There was an error importing the entity file."); } - Overlays.editOverlay(importingSVOTextOverlay, { visible: false }); - Overlays.editOverlay(importingSVOImageOverlay, { visible: false }); + Overlays.editOverlay(importingSVOTextOverlay, { + visible: false + }); + Overlays.editOverlay(importingSVOImageOverlay, { + visible: false + }); } Window.svoImportRequested.connect(importSVO); @@ -1104,7 +1371,7 @@ Controller.keyPressEvent.connect(function(event) { } }); -Controller.keyReleaseEvent.connect(function (event) { +Controller.keyReleaseEvent.connect(function(event) { if (isActive) { cameraManager.keyReleaseEvent(event); } @@ -1120,8 +1387,8 @@ Controller.keyReleaseEvent.connect(function (event) { if (selectionManager.hasSelection()) { cameraManager.enable(); cameraManager.focus(selectionManager.worldPosition, - selectionManager.worldDimensions, - Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + selectionManager.worldDimensions, + Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); } } } else if (event.text == '[') { @@ -1131,7 +1398,11 @@ Controller.keyReleaseEvent.connect(function (event) { } else if (event.text == 'g') { if (isActive && selectionManager.hasSelection()) { var newPosition = selectionManager.worldPosition; - newPosition = Vec3.subtract(newPosition, { x: 0, y: selectionManager.worldDimensions.y * 0.5, z: 0 }); + newPosition = Vec3.subtract(newPosition, { + x: 0, + y: selectionManager.worldDimensions.y * 0.5, + z: 0 + }); grid.setPosition(newPosition); } } @@ -1140,8 +1411,7 @@ Controller.keyReleaseEvent.connect(function (event) { // When an entity has been deleted we need a way to "undo" this deletion. Because it's not currently // possible to create an entity with a specific id, earlier undo commands to the deleted entity // will fail if there isn't a way to find the new entity id. -DELETED_ENTITY_MAP = { -} +DELETED_ENTITY_MAP = {} function applyEntityProperties(data) { var properties = data.setProperties; @@ -1293,7 +1563,11 @@ PropertiesTool = function(opts) { if (selectionManager.hasSelection()) { selectionManager.saveProperties(); var dY = grid.getOrigin().y - (selectionManager.worldPosition.y - selectionManager.worldDimensions.y / 2); - var diff = { x: 0, y: dY, z: 0 }; + var diff = { + x: 0, + y: dY, + z: 0 + }; for (var i = 0; i < selectionManager.selections.length; i++) { var properties = selectionManager.savedProperties[selectionManager.selections[i]]; var newPosition = Vec3.sum(properties.position, diff); @@ -1311,7 +1585,11 @@ PropertiesTool = function(opts) { var properties = selectionManager.savedProperties[selectionManager.selections[i]]; var bottomY = properties.boundingBox.center.y - properties.boundingBox.dimensions.y / 2; var dY = grid.getOrigin().y - bottomY; - var diff = { x: 0, y: dY, z: 0 }; + var diff = { + x: 0, + y: dY, + z: 0 + }; var newPosition = Vec3.sum(properties.position, diff); Entities.editEntity(selectionManager.selections[i], { position: newPosition, @@ -1328,10 +1606,8 @@ PropertiesTool = function(opts) { var naturalDimensions = properties.naturalDimensions; // If any of the natural dimensions are not 0, resize - if (properties.type == "Model" && naturalDimensions.x == 0 - && naturalDimensions.y == 0 && naturalDimensions.z == 0) { - Window.alert("Cannot reset entity to its natural dimensions: Model URL" - + " is invalid or the model has not yet been loaded."); + if (properties.type == "Model" && naturalDimensions.x == 0 && naturalDimensions.y == 0 && naturalDimensions.z == 0) { + Window.alert("Cannot reset entity to its natural dimensions: Model URL" + " is invalid or the model has not yet been loaded."); } else { Entities.editEntity(selectionManager.selections[i], { dimensions: properties.naturalDimensions, @@ -1370,12 +1646,16 @@ PropertiesTool = function(opts) { var properties = selectionManager.savedProperties[selectionManager.selections[i]]; if (properties.type == "Zone") { var centerOfZone = properties.boundingBox.center; - var atmosphereCenter = { x: centerOfZone.x, - y: centerOfZone.y - properties.atmosphere.innerRadius, - z: centerOfZone.z }; + var atmosphereCenter = { + x: centerOfZone.x, + y: centerOfZone.y - properties.atmosphere.innerRadius, + z: centerOfZone.z + }; Entities.editEntity(selectionManager.selections[i], { - atmosphere: { center: atmosphereCenter }, + atmosphere: { + center: atmosphereCenter + }, }); } } @@ -1399,11 +1679,23 @@ PopupMenu = function() { var overlays = []; var overlayInfo = {}; - var upColor = { red: 0, green: 0, blue: 0 }; - var downColor = { red: 192, green: 192, blue: 192 }; - var overColor = { red: 128, green: 128, blue: 128 }; + var upColor = { + red: 0, + green: 0, + blue: 0 + }; + var downColor = { + red: 192, + green: 192, + blue: 192 + }; + var overColor = { + red: 128, + green: 128, + blue: 128 + }; - self.onSelectMenuItem = function() { }; + self.onSelectMenuItem = function() {}; self.addMenuItem = function(name) { var id = Overlays.addOverlay("text", { @@ -1414,16 +1706,22 @@ PopupMenu = function() { leftMargin: TEXT_MARGIN, width: 210, height: MENU_ITEM_HEIGHT, - font: { size: 12 }, + font: { + size: 12 + }, visible: false, }); overlays.push(id); - overlayInfo[id] = { name: name }; + overlayInfo[id] = { + name: name + }; return id; }; self.updateMenuItemText = function(id, newText) { - Overlays.editOverlay(id, { text: newText }); + Overlays.editOverlay(id, { + text: newText + }); }; self.setPosition = function(x, y) { @@ -1436,17 +1734,22 @@ PopupMenu = function() { } }; - self.onSelected = function() { }; + self.onSelected = function() {}; var pressingOverlay = null; var hoveringOverlay = null; self.mousePressEvent = function(event) { if (event.isLeftButton) { - var overlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); + var overlay = Overlays.getOverlayAtPoint({ + x: event.x, + y: event.y + }); if (overlay in overlayInfo) { pressingOverlay = overlay; - Overlays.editOverlay(pressingOverlay, { backgroundColor: downColor }); + Overlays.editOverlay(pressingOverlay, { + backgroundColor: downColor + }); } else { self.hide(); } @@ -1455,14 +1758,21 @@ PopupMenu = function() { }; self.mouseMoveEvent = function(event) { if (visible) { - var overlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); + var overlay = Overlays.getOverlayAtPoint({ + x: event.x, + y: event.y + }); if (!pressingOverlay) { if (hoveringOverlay != null && overlay != hoveringOverlay) { - Overlays.editOverlay(hoveringOverlay, { backgroundColor: upColor}); + Overlays.editOverlay(hoveringOverlay, { + backgroundColor: upColor + }); hoveringOverlay = null; } if (overlay != hoveringOverlay && overlay in overlayInfo) { - Overlays.editOverlay(overlay, { backgroundColor: overColor }); + Overlays.editOverlay(overlay, { + backgroundColor: overColor + }); hoveringOverlay = overlay; } } @@ -1470,12 +1780,17 @@ PopupMenu = function() { return false; }; self.mouseReleaseEvent = function(event) { - var overlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); + var overlay = Overlays.getOverlayAtPoint({ + x: event.x, + y: event.y + }); if (pressingOverlay != null) { if (overlay == pressingOverlay) { self.onSelectMenuItem(overlayInfo[overlay].name); } - Overlays.editOverlay(pressingOverlay, { backgroundColor: upColor }); + Overlays.editOverlay(pressingOverlay, { + backgroundColor: upColor + }); pressingOverlay = null; self.hide(); } @@ -1487,7 +1802,9 @@ PopupMenu = function() { if (newVisible != visible) { visible = newVisible; for (var key in overlayInfo) { - Overlays.editOverlay(key, { visible: newVisible }); + Overlays.editOverlay(key, { + visible: newVisible + }); } } } @@ -1527,4 +1844,4 @@ propertyMenu.onSelectMenuItem = function(name) { var showMenuItem = propertyMenu.addMenuItem("Show in Marketplace"); -propertiesTool = PropertiesTool(); +propertiesTool = PropertiesTool(); \ No newline at end of file diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index a3b817e300..d304a6382e 100644 --- a/examples/libraries/entityCameraTool.js +++ b/examples/libraries/entityCameraTool.js @@ -118,8 +118,16 @@ CameraManager = function() { that.targetYaw = 0; that.targetPitch = 0; - that.focalPoint = { x: 0, y: 0, z: 0 }; - that.targetFocalPoint = { x: 0, y: 0, z: 0 }; + that.focalPoint = { + x: 0, + y: 0, + z: 0 + }; + that.targetFocalPoint = { + x: 0, + y: 0, + z: 0 + }; easing = false; easingTime = 0; @@ -127,13 +135,18 @@ CameraManager = function() { that.previousCameraMode = null; - that.lastMousePosition = { x: 0, y: 0 }; + that.lastMousePosition = { + x: 0, + y: 0 + }; that.enable = function() { if (Camera.mode == "independent" || that.enabled) return; for (var i = 0; i < CAPTURED_KEYS.length; i++) { - Controller.captureKeyEvents({ text: CAPTURED_KEYS[i] }); + Controller.captureKeyEvents({ + text: CAPTURED_KEYS[i] + }); } that.enabled = true; @@ -143,7 +156,7 @@ CameraManager = function() { that.zoomDistance = INITIAL_ZOOM_DISTANCE; that.targetZoomDistance = that.zoomDistance + 3.0; var focalPoint = Vec3.sum(Camera.getPosition(), - Vec3.multiply(that.zoomDistance, Quat.getFront(Camera.getOrientation()))); + Vec3.multiply(that.zoomDistance, Quat.getFront(Camera.getOrientation()))); // Determine the correct yaw and pitch to keep the camera in the same location var dPos = Vec3.subtract(focalPoint, Camera.getPosition()); @@ -169,7 +182,9 @@ CameraManager = function() { if (!that.enabled) return; for (var i = 0; i < CAPTURED_KEYS.length; i++) { - Controller.releaseKeyEvents({ text: CAPTURED_KEYS[i] }); + Controller.releaseKeyEvents({ + text: CAPTURED_KEYS[i] + }); } that.enabled = false; @@ -335,19 +350,27 @@ CameraManager = function() { var hasDragged = false; that.mousePressEvent = function(event) { + if (cameraTool.mousePressEvent(event)) { + return true; } + if (!that.enabled) return; if (event.isRightButton || (event.isLeftButton && event.isControl && !event.isShifted)) { + that.mode = MODE_ORBIT; } else if (event.isMiddleButton || (event.isLeftButton && event.isControl && event.isShifted)) { + + that.mode = MODE_PAN; } - if (that.mode != MODE_INACTIVE) { + if (that.mode !== MODE_INACTIVE) { + + hasDragged = false; return true; @@ -357,10 +380,12 @@ CameraManager = function() { } that.mouseReleaseEvent = function(event) { + if (!that.enabled) return; - Window.setCursorVisible(true); that.mode = MODE_INACTIVE; + Window.setCursorVisible(true); + } that.keyPressEvent = function(event) { @@ -396,15 +421,31 @@ CameraManager = function() { return; } - var yRot = Quat.angleAxis(that.yaw, { x: 0, y: 1, z: 0 }); - var xRot = Quat.angleAxis(that.pitch, { x: 1, y: 0, z: 0 }); + var yRot = Quat.angleAxis(that.yaw, { + x: 0, + y: 1, + z: 0 + }); + var xRot = Quat.angleAxis(that.pitch, { + x: 1, + y: 0, + z: 0 + }); var q = Quat.multiply(yRot, xRot); var pos = Vec3.multiply(Quat.getFront(q), that.zoomDistance); Camera.setPosition(Vec3.sum(that.focalPoint, pos)); - yRot = Quat.angleAxis(that.yaw - 180, { x: 0, y: 1, z: 0 }); - xRot = Quat.angleAxis(-that.pitch, { x: 1, y: 0, z: 0 }); + yRot = Quat.angleAxis(that.yaw - 180, { + x: 0, + y: 1, + z: 0 + }); + xRot = Quat.angleAxis(-that.pitch, { + x: 1, + y: 0, + z: 0 + }); q = Quat.multiply(yRot, xRot); if (easing) { @@ -483,7 +524,7 @@ CameraManager = function() { } }); - Controller.keyReleaseEvent.connect(function (event) { + Controller.keyReleaseEvent.connect(function(event) { if (event.text == "ESC" && that.enabled) { Camera.mode = lastAvatarCameraMode; cameraManager.disable(true); @@ -503,9 +544,21 @@ CameraManager = function() { CameraTool = function(cameraManager) { var that = {}; - var RED = { red: 191, green: 78, blue: 38 }; - var GREEN = { red: 26, green: 193, blue: 105 }; - var BLUE = { red: 0, green: 131, blue: 204 }; + var RED = { + red: 191, + green: 78, + blue: 38 + }; + var GREEN = { + red: 26, + green: 193, + blue: 105 + }; + var BLUE = { + red: 0, + green: 131, + blue: 204 + }; var BORDER_WIDTH = 1; @@ -513,10 +566,10 @@ CameraTool = function(cameraManager) { var ORIENTATION_OVERLAY_HALF_SIZE = ORIENTATION_OVERLAY_SIZE / 2; var ORIENTATION_OVERLAY_CUBE_SIZE = 10.5, - var ORIENTATION_OVERLAY_OFFSET = { - x: 30, - y: 30, - } + var ORIENTATION_OVERLAY_OFFSET = { + x: 30, + y: 30, + } var UI_WIDTH = 70; var UI_HEIGHT = 70; @@ -536,7 +589,11 @@ CameraTool = function(cameraManager) { height: UI_HEIGHT + BORDER_WIDTH * 2, alpha: 0, text: "", - backgroundColor: { red: 101, green: 101, blue: 101 }, + backgroundColor: { + red: 101, + green: 101, + blue: 101 + }, backgroundAlpha: 1.0, visible: false, }); @@ -548,7 +605,11 @@ CameraTool = function(cameraManager) { height: UI_HEIGHT, alpha: 0, text: "", - backgroundColor: { red: 51, green: 51, blue: 51 }, + backgroundColor: { + red: 51, + green: 51, + blue: 51 + }, backgroundAlpha: 1.0, visible: false, }); @@ -556,7 +617,11 @@ CameraTool = function(cameraManager) { var defaultCubeProps = { size: ORIENTATION_OVERLAY_CUBE_SIZE, alpha: 1, - color: { red: 255, green: 0, blue: 0 }, + color: { + red: 255, + green: 0, + blue: 0 + }, solid: true, visible: true, drawOnHUD: true, @@ -564,10 +629,26 @@ CameraTool = function(cameraManager) { var defaultLineProps = { lineWidth: 1.5, alpha: 1, - position: { x: 0, y: 0, z: 0 }, - start: { x: 0, y: 0, z: 0 }, - end: { x: 0, y: 0, z: 0 }, - color: { red: 255, green: 0, blue: 0 }, + position: { + x: 0, + y: 0, + z: 0 + }, + start: { + x: 0, + y: 0, + z: 0 + }, + end: { + x: 0, + y: 0, + z: 0 + }, + color: { + red: 255, + green: 0, + blue: 0 + }, visible: false, drawOnHUD: true, }; @@ -582,30 +663,66 @@ CameraTool = function(cameraManager) { var OOHS = ORIENTATION_OVERLAY_HALF_SIZE; var cubeX = orientationOverlay.createOverlay("cube", mergeObjects(defaultCubeProps, { - position: { x: -OOHS, y: OOHS, z: OOHS }, + position: { + x: -OOHS, + y: OOHS, + z: OOHS + }, color: RED, })); var cubeY = orientationOverlay.createOverlay("cube", mergeObjects(defaultCubeProps, { - position: { x: OOHS, y: -OOHS, z: OOHS }, + position: { + x: OOHS, + y: -OOHS, + z: OOHS + }, color: GREEN, })); var cubeZ = orientationOverlay.createOverlay("cube", mergeObjects(defaultCubeProps, { - position: { x: OOHS, y: OOHS, z: -OOHS }, + position: { + x: OOHS, + y: OOHS, + z: -OOHS + }, color: BLUE, })); orientationOverlay.createOverlay("line3d", mergeObjects(defaultLineProps, { - start: { x: -OOHS, y: OOHS, z: OOHS }, - end: { x: OOHS, y: OOHS, z: OOHS }, + start: { + x: -OOHS, + y: OOHS, + z: OOHS + }, + end: { + x: OOHS, + y: OOHS, + z: OOHS + }, color: RED, })); orientationOverlay.createOverlay("line3d", mergeObjects(defaultLineProps, { - start: { x: OOHS, y: -OOHS, z: OOHS }, - end: { x: OOHS, y: OOHS, z: OOHS }, + start: { + x: OOHS, + y: -OOHS, + z: OOHS + }, + end: { + x: OOHS, + y: OOHS, + z: OOHS + }, color: GREEN, })); orientationOverlay.createOverlay("line3d", mergeObjects(defaultLineProps, { - start: { x: OOHS, y: OOHS, z: -OOHS }, - end: { x: OOHS, y: OOHS, z: OOHS }, + start: { + x: OOHS, + y: OOHS, + z: -OOHS + }, + end: { + x: OOHS, + y: OOHS, + z: OOHS + }, color: BLUE, })); @@ -645,7 +762,10 @@ CameraTool = function(cameraManager) { } that.mousePressEvent = function(event) { - var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); + var clickedOverlay = Overlays.getOverlayAtPoint({ + x: event.x, + y: event.y + }); if (clickedOverlay == cubeX) { targetPitch = 0; @@ -666,12 +786,18 @@ CameraTool = function(cameraManager) { }; that.setVisible = function(visible) { - orientationOverlay.setProperties({ visible: visible }); - Overlays.editOverlay(background, { visible: visible }); - Overlays.editOverlay(backgroundBorder, { visible: visible }); + orientationOverlay.setProperties({ + visible: visible + }); + Overlays.editOverlay(background, { + visible: visible + }); + Overlays.editOverlay(backgroundBorder, { + visible: visible + }); }; that.setVisible(false); return that; -}; +}; \ No newline at end of file From 51acf07c153d27c5fce95f6d6198897e1dd0c49b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 12 Oct 2015 14:50:42 -0700 Subject: [PATCH 27/49] Factor couple methods in AssetUtils --- interface/src/Application.cpp | 2 +- interface/src/ui/AssetUploadDialogFactory.cpp | 13 ++-- libraries/networking/src/AssetRequest.cpp | 52 ++------------ libraries/networking/src/AssetRequest.h | 3 - libraries/networking/src/AssetUtils.cpp | 67 +++++++++++++++++++ libraries/networking/src/AssetUtils.h | 12 ++-- 6 files changed, 87 insertions(+), 62 deletions(-) create mode 100644 libraries/networking/src/AssetUtils.cpp diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9e9830d977..a553eb4e9e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4118,7 +4118,7 @@ void Application::modelUploadFinished(AssetUpload* upload, const QString& hash) EntityItemProperties properties; properties.setType(EntityTypes::Model); - properties.setModelURL(QString("%1:%2.%3").arg(ATP_SCHEME).arg(hash).arg(upload->getExtension())); + properties.setModelURL(QString("%1:%2.%3").arg(URL_SCHEME_ATP).arg(hash).arg(upload->getExtension())); properties.setPosition(_myCamera.getPosition() + _myCamera.getOrientation() * Vectors::FRONT * 2.0f); properties.setName(QUrl(upload->getFilename()).fileName()); diff --git a/interface/src/ui/AssetUploadDialogFactory.cpp b/interface/src/ui/AssetUploadDialogFactory.cpp index 4910e6d604..e169d88c8c 100644 --- a/interface/src/ui/AssetUploadDialogFactory.cpp +++ b/interface/src/ui/AssetUploadDialogFactory.cpp @@ -11,11 +11,6 @@ #include "AssetUploadDialogFactory.h" -#include -#include -#include -#include - #include #include #include @@ -24,6 +19,12 @@ #include #include +#include +#include +#include +#include +#include + AssetUploadDialogFactory& AssetUploadDialogFactory::getInstance() { static AssetUploadDialogFactory staticInstance; return staticInstance; @@ -85,7 +86,7 @@ void AssetUploadDialogFactory::handleUploadFinished(AssetUpload* upload, const Q // setup the line edit to hold the copiable text QLineEdit* lineEdit = new QLineEdit; - QString atpURL = QString("%1:%2.%3").arg(ATP_SCHEME).arg(hash).arg(upload->getExtension()); + QString atpURL = QString("%1:%2.%3").arg(URL_SCHEME_ATP).arg(hash).arg(upload->getExtension()); // set the ATP URL as the text value so it's copiable lineEdit->insert(atpURL); diff --git a/libraries/networking/src/AssetRequest.cpp b/libraries/networking/src/AssetRequest.cpp index b4e3882a5e..a0a3ca5339 100644 --- a/libraries/networking/src/AssetRequest.cpp +++ b/libraries/networking/src/AssetRequest.cpp @@ -14,10 +14,8 @@ #include #include -#include #include "AssetClient.h" -#include "NetworkAccessManager.h" #include "NetworkLogging.h" #include "NodeList.h" #include "ResourceCache.h" @@ -41,7 +39,8 @@ void AssetRequest::start() { } // Try to load from cache - if (loadFromCache()) { + _data = loadFromCache(getUrl()); + if (!_data.isNull()) { _info.hash = _hash; _info.size = _data.size(); _error = NoError; @@ -112,7 +111,7 @@ void AssetRequest::start() { _totalReceived += data.size(); emit progress(_totalReceived, _info.size); - if (saveToCache(data)) { + if (saveToCache(getUrl(), data)) { qCDebug(asset_client) << getUrl().toDisplayString() << "saved to disk cache"; } } else { @@ -133,49 +132,6 @@ void AssetRequest::start() { } QUrl AssetRequest::getUrl() const { - if (!_extension.isEmpty()) { - return QUrl(QString("%1:%2.%3").arg(URL_SCHEME_ATP, _hash, _extension)); - } else { - return QUrl(QString("%1:%2").arg(URL_SCHEME_ATP, _hash)); - } -} - -bool AssetRequest::loadFromCache() { - if (auto cache = NetworkAccessManager::getInstance().cache()) { - auto url = getUrl(); - if (auto ioDevice = cache->data(url)) { - _data = ioDevice->readAll(); - return true; - } else { - qCDebug(asset_client) << url.toDisplayString() << "not in disk cache"; - } - } else { - qCWarning(asset_client) << "No disk cache to load assets from."; - } - return false; -} - -bool AssetRequest::saveToCache(const QByteArray& file) const { - if (auto cache = NetworkAccessManager::getInstance().cache()) { - auto url = getUrl(); - - if (!cache->metaData(url).isValid()) { - QNetworkCacheMetaData metaData; - metaData.setUrl(url); - metaData.setSaveToDisk(true); - metaData.setLastModified(QDateTime::currentDateTime()); - metaData.setExpirationDate(QDateTime()); // Never expires - - if (auto ioDevice = cache->prepare(metaData)) { - ioDevice->write(file); - cache->insert(ioDevice); - return true; - } - qCWarning(asset_client) << "Could not save" << url.toDisplayString() << "to disk cache."; - } - } else { - qCWarning(asset_client) << "No disk cache to save assets to."; - } - return false; + return ::getUrl(_hash, _extension); } diff --git a/libraries/networking/src/AssetRequest.h b/libraries/networking/src/AssetRequest.h index 75e2353425..a5275e718a 100644 --- a/libraries/networking/src/AssetRequest.h +++ b/libraries/networking/src/AssetRequest.h @@ -53,9 +53,6 @@ signals: void progress(qint64 totalReceived, qint64 total); private: - bool loadFromCache(); - bool saveToCache(const QByteArray& file) const; - State _state = NotStarted; Error _error = NoError; AssetInfo _info; diff --git a/libraries/networking/src/AssetUtils.cpp b/libraries/networking/src/AssetUtils.cpp new file mode 100644 index 0000000000..0cf45c3a4f --- /dev/null +++ b/libraries/networking/src/AssetUtils.cpp @@ -0,0 +1,67 @@ +// +// AssetUtils.h +// libraries/networking/src +// +// Created by Clément Brisset on 10/12/2015 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "AssetUtils.h" + +#include +#include + +#include "NetworkAccessManager.h" +#include "NetworkLogging.h" + +#include "ResourceManager.h" + +QUrl getUrl(const QString& hash, const QString& extension) { + if (!extension.isEmpty()) { + return QUrl(QString("%1:%2.%3").arg(URL_SCHEME_ATP, hash, extension)); + } else { + return QUrl(QString("%1:%2").arg(URL_SCHEME_ATP, hash)); + } +} + +QByteArray hashData(const QByteArray& data) { + return QCryptographicHash::hash(data, QCryptographicHash::Sha256); +} + +QByteArray loadFromCache(const QUrl& url) { + if (auto cache = NetworkAccessManager::getInstance().cache()) { + if (auto ioDevice = cache->data(url)) { + return ioDevice->readAll(); + } else { + qCDebug(asset_client) << url.toDisplayString() << "not in disk cache"; + } + } else { + qCWarning(asset_client) << "No disk cache to load assets from."; + } + return QByteArray(); +} + +bool saveToCache(const QUrl& url, const QByteArray& file) { + if (auto cache = NetworkAccessManager::getInstance().cache()) { + if (!cache->metaData(url).isValid()) { + QNetworkCacheMetaData metaData; + metaData.setUrl(url); + metaData.setSaveToDisk(true); + metaData.setLastModified(QDateTime::currentDateTime()); + metaData.setExpirationDate(QDateTime()); // Never expires + + if (auto ioDevice = cache->prepare(metaData)) { + ioDevice->write(file); + cache->insert(ioDevice); + return true; + } + qCWarning(asset_client) << "Could not save" << url.toDisplayString() << "to disk cache."; + } + } else { + qCWarning(asset_client) << "No disk cache to save assets to."; + } + return false; +} \ No newline at end of file diff --git a/libraries/networking/src/AssetUtils.h b/libraries/networking/src/AssetUtils.h index b18ff329fc..5fd5c9144d 100644 --- a/libraries/networking/src/AssetUtils.h +++ b/libraries/networking/src/AssetUtils.h @@ -12,10 +12,11 @@ #ifndef hifi_AssetUtils_h #define hifi_AssetUtils_h -#include - #include +#include +#include + using MessageID = uint32_t; using DataOffset = int64_t; @@ -31,8 +32,11 @@ enum AssetServerError : uint8_t { PermissionDenied }; -const QString ATP_SCHEME = "atp"; +QUrl getUrl(const QString& hash, const QString& extension = QString()); -inline QByteArray hashData(const QByteArray& data) { return QCryptographicHash::hash(data, QCryptographicHash::Sha256); } +QByteArray hashData(const QByteArray& data); + +QByteArray loadFromCache(const QUrl& url); +bool saveToCache(const QUrl& url, const QByteArray& file); #endif From 4abac35c721198556c9d3c293774b58b808f45ef Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 12 Oct 2015 14:51:28 -0700 Subject: [PATCH 28/49] Cache on upload --- libraries/networking/src/AssetUpload.cpp | 16 ++++++++++++---- libraries/networking/src/AssetUpload.h | 3 ++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/libraries/networking/src/AssetUpload.cpp b/libraries/networking/src/AssetUpload.cpp index 92632a43e5..67c079d248 100644 --- a/libraries/networking/src/AssetUpload.cpp +++ b/libraries/networking/src/AssetUpload.cpp @@ -23,9 +23,9 @@ AssetUpload::AssetUpload(QObject* object, const QString& filename) : } -void AssetUpload::start() { +void AssetUpload::start(bool cacheOnSuccess) { if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "start", Qt::AutoConnection); + QMetaObject::invokeMethod(this, "start", Q_ARG(bool, cacheOnSuccess)); return; } @@ -37,14 +37,16 @@ void AssetUpload::start() { // file opened, read the data and grab the extension _extension = QFileInfo(_filename).suffix(); - auto data = file.readAll(); + _data = file.readAll(); // ask the AssetClient to upload the asset and emit the proper signals from the passed callback auto assetClient = DependencyManager::get(); qCDebug(asset_client) << "Attempting to upload" << _filename << "to asset-server."; - assetClient->uploadAsset(data, _extension, [this](bool responseReceived, AssetServerError error, const QString& hash){ + assetClient->uploadAsset(_data, _extension, + [this, cacheOnSuccess](bool responseReceived, AssetServerError error, + const QString& hash){ if (!responseReceived) { _error = NetworkError; } else { @@ -63,6 +65,12 @@ void AssetUpload::start() { break; } } + + if (cacheOnSuccess && _error == NoError && + hash == hashData(_data).toHex()) { + saveToCache(getUrl(hash, _extension), _data); + } + emit finished(this, hash); }); } else { diff --git a/libraries/networking/src/AssetUpload.h b/libraries/networking/src/AssetUpload.h index 80faa8a9c1..fbba545209 100644 --- a/libraries/networking/src/AssetUpload.h +++ b/libraries/networking/src/AssetUpload.h @@ -37,7 +37,7 @@ public: AssetUpload(QObject* parent, const QString& filename); - Q_INVOKABLE void start(); + Q_INVOKABLE void start(bool cacheOnSuccess = true); const QString& getFilename() const { return _filename; } const QString& getExtension() const { return _extension; } @@ -50,6 +50,7 @@ signals: private: QString _filename; QString _extension; + QByteArray _data; Error _error; }; From 0cdad785811cf0c41927408d8f66279ca54b9b0e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 12 Oct 2015 14:58:44 -0700 Subject: [PATCH 29/49] Move debug to helper functions --- libraries/networking/src/AssetRequest.cpp | 5 +---- libraries/networking/src/AssetUtils.cpp | 2 ++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/libraries/networking/src/AssetRequest.cpp b/libraries/networking/src/AssetRequest.cpp index a0a3ca5339..121b4cd4fd 100644 --- a/libraries/networking/src/AssetRequest.cpp +++ b/libraries/networking/src/AssetRequest.cpp @@ -47,7 +47,6 @@ void AssetRequest::start() { _state = Finished; emit finished(this); - qCDebug(asset_client) << getUrl().toDisplayString() << "loaded from disk cache."; return; } @@ -111,9 +110,7 @@ void AssetRequest::start() { _totalReceived += data.size(); emit progress(_totalReceived, _info.size); - if (saveToCache(getUrl(), data)) { - qCDebug(asset_client) << getUrl().toDisplayString() << "saved to disk cache"; - } + saveToCache(getUrl(), data); } else { // hash doesn't match - we have an error _error = HashVerificationFailed; diff --git a/libraries/networking/src/AssetUtils.cpp b/libraries/networking/src/AssetUtils.cpp index 0cf45c3a4f..7311d73525 100644 --- a/libraries/networking/src/AssetUtils.cpp +++ b/libraries/networking/src/AssetUtils.cpp @@ -34,6 +34,7 @@ QByteArray hashData(const QByteArray& data) { QByteArray loadFromCache(const QUrl& url) { if (auto cache = NetworkAccessManager::getInstance().cache()) { if (auto ioDevice = cache->data(url)) { + qCDebug(asset_client) << url.toDisplayString() << "loaded from disk cache."; return ioDevice->readAll(); } else { qCDebug(asset_client) << url.toDisplayString() << "not in disk cache"; @@ -56,6 +57,7 @@ bool saveToCache(const QUrl& url, const QByteArray& file) { if (auto ioDevice = cache->prepare(metaData)) { ioDevice->write(file); cache->insert(ioDevice); + qCDebug(asset_client) << url.toDisplayString() << "saved to disk cache"; return true; } qCWarning(asset_client) << "Could not save" << url.toDisplayString() << "to disk cache."; From cfba5752cecf9ecf8607ade2514d20bc51b8825c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 12 Oct 2015 15:02:53 -0700 Subject: [PATCH 30/49] Change checkbox text --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a553eb4e9e..9a6e2fff4d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4079,7 +4079,7 @@ bool Application::askToUploadAsset(const QString& filename) { // Option to drop model in world for models if (filename.endsWith(FBX_EXTENSION) || filename.endsWith(OBJ_EXTENSION)) { auto checkBox = new QCheckBox(&messageBox); - checkBox->setText("Drop model in world."); + checkBox->setText("Add to scene"); messageBox.setCheckBox(checkBox); } From 0e0a8301eb09d12a59ef60fcd71dbc074dd3e3fb Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 12 Oct 2015 15:06:51 -0700 Subject: [PATCH 31/49] Collapse line --- libraries/networking/src/AssetUpload.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/networking/src/AssetUpload.cpp b/libraries/networking/src/AssetUpload.cpp index 67c079d248..fd9ae7ab43 100644 --- a/libraries/networking/src/AssetUpload.cpp +++ b/libraries/networking/src/AssetUpload.cpp @@ -66,8 +66,7 @@ void AssetUpload::start(bool cacheOnSuccess) { } } - if (cacheOnSuccess && _error == NoError && - hash == hashData(_data).toHex()) { + if (cacheOnSuccess && _error == NoError && hash == hashData(_data).toHex()) { saveToCache(getUrl(hash, _extension), _data); } From 7eadb11404a33919023d3bcb7587cf4210b32b64 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 12 Oct 2015 15:09:17 -0700 Subject: [PATCH 32/49] Remove optional upload caching --- libraries/networking/src/AssetUpload.cpp | 11 +++++------ libraries/networking/src/AssetUpload.h | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/libraries/networking/src/AssetUpload.cpp b/libraries/networking/src/AssetUpload.cpp index fd9ae7ab43..6f4fcbf1f2 100644 --- a/libraries/networking/src/AssetUpload.cpp +++ b/libraries/networking/src/AssetUpload.cpp @@ -23,9 +23,9 @@ AssetUpload::AssetUpload(QObject* object, const QString& filename) : } -void AssetUpload::start(bool cacheOnSuccess) { +void AssetUpload::start() { if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "start", Q_ARG(bool, cacheOnSuccess)); + QMetaObject::invokeMethod(this, "start"); return; } @@ -44,9 +44,8 @@ void AssetUpload::start(bool cacheOnSuccess) { qCDebug(asset_client) << "Attempting to upload" << _filename << "to asset-server."; - assetClient->uploadAsset(_data, _extension, - [this, cacheOnSuccess](bool responseReceived, AssetServerError error, - const QString& hash){ + assetClient->uploadAsset(_data, _extension, [this](bool responseReceived, AssetServerError error, + const QString& hash){ if (!responseReceived) { _error = NetworkError; } else { @@ -66,7 +65,7 @@ void AssetUpload::start(bool cacheOnSuccess) { } } - if (cacheOnSuccess && _error == NoError && hash == hashData(_data).toHex()) { + if (_error == NoError && hash == hashData(_data).toHex()) { saveToCache(getUrl(hash, _extension), _data); } diff --git a/libraries/networking/src/AssetUpload.h b/libraries/networking/src/AssetUpload.h index fbba545209..4047a44923 100644 --- a/libraries/networking/src/AssetUpload.h +++ b/libraries/networking/src/AssetUpload.h @@ -37,7 +37,7 @@ public: AssetUpload(QObject* parent, const QString& filename); - Q_INVOKABLE void start(bool cacheOnSuccess = true); + Q_INVOKABLE void start(); const QString& getFilename() const { return _filename; } const QString& getExtension() const { return _extension; } From b7ba99380ab087168b305abbed084a8fa323180e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 12 Oct 2015 15:32:44 -0700 Subject: [PATCH 33/49] Pretty up loading debug --- libraries/networking/src/ResourceCache.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index e2f57f97a3..84af87f217 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -319,10 +319,10 @@ void Resource::attemptRequest() { void Resource::finishedLoading(bool success) { if (success) { - qDebug() << "Finished loading:" << _url; + qDebug().noquote() << "Finished loading:" << _url.toDisplayString(); _loaded = true; } else { - qDebug() << "Failed to load:" << _url; + qDebug().noquote() << "Failed to load:" << _url.toDisplayString(); _failedToLoad = true; } _loadPriorities.clear(); @@ -339,13 +339,13 @@ void Resource::makeRequest() { _request = ResourceManager::createResourceRequest(this, _activeUrl); if (!_request) { - qDebug() << "Failed to get request for " << _url; + qDebug().noquote() << "Failed to get request for" << _url.toDisplayString(); ResourceCache::requestCompleted(this); finishedLoading(false); return; } - qDebug() << "Starting request for: " << _url; + qDebug().noquote() << "Starting request for:" << _url.toDisplayString(); connect(_request, &ResourceRequest::progress, this, &Resource::handleDownloadProgress); connect(_request, &ResourceRequest::finished, this, &Resource::handleReplyFinished); @@ -368,7 +368,8 @@ void Resource::handleReplyFinished() { auto result = _request->getResult(); if (result == ResourceRequest::Success) { _data = _request->getData(); - qDebug() << "Request finished for " << _url << ", " << _activeUrl; + auto extraInfo = _url == _activeUrl ? "" : QString(", %1").arg(_activeUrl.toDisplayString()); + qDebug().noquote() << QString("Request finished for %1%2").arg(_url.toDisplayString(), extraInfo); finishedLoading(true); emit loaded(_data); From 6cbeb6e7c3a120b73601268c39da56bf6c691853 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 12 Oct 2015 15:40:16 -0700 Subject: [PATCH 34/49] Fix my bug, introduced in PR#6012, in which startup position goto got cancelled out. --- interface/src/avatar/MyAvatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 22816e9001..605a81e9d9 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -152,7 +152,7 @@ void MyAvatar::reset() { setEnableRigAnimations(true); // Reset dynamic state. - _wasPushing = _isPushing = _isBraking = _billboardValid = _goToPending = _straighteningLean = false; + _wasPushing = _isPushing = _isBraking = _billboardValid = _straighteningLean = false; _skeletonModel.reset(); getHead()->reset(); _targetVelocity = glm::vec3(0.0f); From ed9907ce66a2832cddac36f66f106778811b0f39 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 12 Oct 2015 16:23:12 -0700 Subject: [PATCH 35/49] do avatar simulation before physics simulation so that physics actions can update based on avatar --- interface/src/Application.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9e9830d977..739fefbc7f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2761,6 +2761,8 @@ void Application::update(float deltaTime) { updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process... updateDialogs(deltaTime); // update various stats dialogs if present + _avatarUpdate->synchronousProcess(); + { PerformanceTimer perfTimer("physics"); myAvatar->relayDriveKeysToCharacterController(); @@ -2822,8 +2824,6 @@ void Application::update(float deltaTime) { _overlays.update(deltaTime); } - _avatarUpdate->synchronousProcess(); - // Update _viewFrustum with latest camera and view frustum data... // NOTE: we get this from the view frustum, to make it simpler, since the // loadViewFrumstum() method will get the correct details from the camera From 47471e837ff72a9c30812aa972d848bc85afea15 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 12 Oct 2015 16:31:36 -0700 Subject: [PATCH 36/49] reset targets once they have stopped moving --- examples/toys/ping_pong_gun/createTargets.js | 15 ++++++++++++--- unpublishedScripts/hiddenEntityReset.js | 19 ++++++++++--------- unpublishedScripts/masterReset.js | 18 +++++++++--------- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/examples/toys/ping_pong_gun/createTargets.js b/examples/toys/ping_pong_gun/createTargets.js index 22329f90f0..013150b241 100644 --- a/examples/toys/ping_pong_gun/createTargets.js +++ b/examples/toys/ping_pong_gun/createTargets.js @@ -16,8 +16,9 @@ var scriptURL = Script.resolvePath('wallTarget.js'); var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx'; var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target_collision_hull.obj'; +var MINIMUM_MOVE_LENGTH = 0.05; +var RESET_DISTANCE = 0.5; -var RESET_DISTANCE = 1; var TARGET_USER_DATA_KEY = 'hifi-ping_pong_target'; var NUMBER_OF_TARGETS = 6; var TARGETS_PER_ROW = 3; @@ -60,6 +61,8 @@ var targets = []; var originalPositions = []; +var lastPositions = []; + function addTargets() { var i; var row = -1; @@ -77,6 +80,7 @@ function addTargets() { position.y = startPosition.y - (row * VERTICAL_SPACING); originalPositions.push(position); + lastPositions.push(position); var targetProperties = { name: 'Target', @@ -103,7 +107,11 @@ function testTargetDistanceFromStart() { var distance = Vec3.subtract(originalPosition, currentPosition); var length = Vec3.length(distance); - if (length > RESET_DISTANCE) { + var moving = Vec3.length(Vec3.subtract(currentPosition, lastPositions[index])); + + lastPositions[index] = currentPosition; + + if (length > RESET_DISTANCE && moving RESET_DISTANCE) { + var moving = Vec3.length(Vec3.subtract(currentPosition, lastPositions[index])); + + lastPositions[index] = currentPosition; + + if (length > RESET_DISTANCE && moving < MINIMUM_MOVE_LENGTH) { Entities.deleteEntity(target); @@ -482,15 +488,10 @@ compoundShapeURL: COLLISION_HULL_URL, position: originalPositions[index], rotation: rotation, - script: targetsScriptURL, - userData: JSON.stringify({ - resetMe: { - resetMe: true - } - }) + script: scriptURL }; - var target = Entities.addEntity(targetProperties); - targets[index] = target; + + targets[index] = Entities.addEntity(targetProperties); } }); diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index d9199a124d..e4db5fbf55 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -393,6 +393,7 @@ MasterReset = function() { var targets = []; var originalPositions = []; + var lastPositions = []; function addTargets() { var i; @@ -441,7 +442,11 @@ MasterReset = function() { var distance = Vec3.subtract(originalPosition, currentPosition); var length = Vec3.length(distance); - if (length > RESET_DISTANCE) { + var moving = Vec3.length(Vec3.subtract(currentPosition, lastPositions[index])); + + lastPositions[index] = currentPosition; + + if (length > RESET_DISTANCE && moving < MINIMUM_MOVE_LENGTH) { Entities.deleteEntity(target); @@ -455,15 +460,10 @@ MasterReset = function() { compoundShapeURL: COLLISION_HULL_URL, position: originalPositions[index], rotation: rotation, - script: targetsScriptURL, - userData: JSON.stringify({ - resetMe: { - resetMe: true - } - }) + script: scriptURL }; - var target = Entities.addEntity(targetProperties); - targets[index] = target; + + targets[index] = Entities.addEntity(targetProperties); } }); From bc4200d8d7b42eac3a5ebb422f394d66077093ea Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 12 Oct 2015 16:35:06 -0700 Subject: [PATCH 37/49] push last positions to array --- unpublishedScripts/hiddenEntityReset.js | 5 +++-- unpublishedScripts/masterReset.js | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index 5eff989701..bc9ecbcf22 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -438,8 +438,9 @@ var position = Vec3.sum(startPosition, multiplier); position.y = startPosition.y - (row * VERTICAL_SPACING); - originalPositions.push(position); - + originalPositions.push(position); + lastPositions.push(position); + var targetProperties = { name: 'Target', type: 'Model', diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index e4db5fbf55..1644688e5d 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -411,7 +411,8 @@ MasterReset = function() { position.y = startPosition.y - (row * VERTICAL_SPACING); originalPositions.push(position); - + lastPositions.push(position); + var targetProperties = { name: 'Target', type: 'Model', @@ -429,8 +430,10 @@ MasterReset = function() { } }) }; + var target = Entities.addEntity(targetProperties); targets.push(target); + } } From 60f5a0630822e5bd4c0fc0be2d536a6f90f03a23 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 12 Oct 2015 16:44:51 -0700 Subject: [PATCH 38/49] turn on the asset-server by default --- domain-server/resources/describe-settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index e3ab2c51b8..eb1c478489 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -176,7 +176,7 @@ "type": "checkbox", "label": "Enabled", "help": "Assigns an asset-server in your domain to serve files to clients via the ATP protocol (over UDP)", - "default": false, + "default": true, "advanced": true } ] From f0ce698d78042e0b5313264fc1d152d64d274f52 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 12 Oct 2015 16:57:20 -0700 Subject: [PATCH 39/49] switch back to springy grab --- examples/controllers/handControllerGrab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 05dfc8e5d5..f4bc7496da 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -480,7 +480,7 @@ function MyController(hand, triggerAction) { var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset); this.actionID = NULL_ACTION_ID; - this.actionID = Entities.addAction("kinematic-hold", this.grabbedEntity, { + this.actionID = Entities.addAction("hold", this.grabbedEntity, { hand: this.hand === RIGHT_HAND ? "right" : "left", timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: offsetPosition, From 02620c4b0dced96e067ffcedc39ebe51b0fe7f3f Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 12 Oct 2015 16:59:42 -0700 Subject: [PATCH 40/49] make targets ungrabbable --- examples/toys/ping_pong_gun/createTargets.js | 9 +- unpublishedScripts/hiddenEntityReset.js | 11 +- unpublishedScripts/masterReset.js | 2435 +++++++++--------- 3 files changed, 1233 insertions(+), 1222 deletions(-) diff --git a/examples/toys/ping_pong_gun/createTargets.js b/examples/toys/ping_pong_gun/createTargets.js index 013150b241..fb286b1928 100644 --- a/examples/toys/ping_pong_gun/createTargets.js +++ b/examples/toys/ping_pong_gun/createTargets.js @@ -111,7 +111,7 @@ function testTargetDistanceFromStart() { lastPositions[index] = currentPosition; - if (length > RESET_DISTANCE && moving RESET_DISTANCE && moving < MINIMUM_MOVE_LENGTH) { Entities.deleteEntity(target); @@ -125,7 +125,12 @@ function testTargetDistanceFromStart() { compoundShapeURL: COLLISION_HULL_URL, position: originalPositions[index], rotation: rotation, - script: scriptURL + script: scriptURL, + userData: JSON.stringify({ + grabbableKey: { + grabbable: false + } + }) }; targets[index] = Entities.addEntity(targetProperties); diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index bc9ecbcf22..f959923ad3 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -413,6 +413,9 @@ userData: JSON.stringify({ resetMe: { resetMe: true + }, + grabbableKey: { + grabbable: false } }) }); @@ -438,9 +441,9 @@ var position = Vec3.sum(startPosition, multiplier); position.y = startPosition.y - (row * VERTICAL_SPACING); - originalPositions.push(position); - lastPositions.push(position); - + originalPositions.push(position); + lastPositions.push(position); + var targetProperties = { name: 'Target', type: 'Model', @@ -455,7 +458,7 @@ userData: JSON.stringify({ resetMe: { resetMe: true - } + }, }) }; var target = Entities.addEntity(targetProperties); diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 1644688e5d..fdedac3ec3 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -26,1256 +26,1259 @@ var targetsScriptURL = Script.resolvePath('../examples/toys/ping_pong_gun/wallTa MasterReset = function() { - var resetKey = "resetMe"; - var GRABBABLE_DATA_KEY = "grabbableKey"; + var resetKey = "resetMe"; + var GRABBABLE_DATA_KEY = "grabbableKey"; - var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; + var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; - var shouldDeleteOnEndScript = false; + var shouldDeleteOnEndScript = false; - //Before creating anything, first search a radius and delete all the things that should be deleted - deleteAllToys(); - createAllToys(); + //Before creating anything, first search a radius and delete all the things that should be deleted + deleteAllToys(); + createAllToys(); - function createAllToys() { - createBlocks({ - x: 548.3, - y: 495.55, - z: 504.4 - }); - - createBasketBall({ - x: 547.73, - y: 495.5, - z: 505.47 - }); - - createDoll({ - x: 546.67, - y: 495.41, - z: 505.09 - }); - - createWand({ - x: 546.71, - y: 495.55, - z: 506.15 - }); - - createDice(); - - createFlashlight({ - x: 545.72, - y: 495.41, - z: 505.78 - }); - - - - createCombinedArmChair({ - x: 549.29, - y: 494.9, - z: 508.22 - }); - - createPottedPlant({ - x: 554.26, - y: 495.2, - z: 504.53 - }); - - createPingPongBallGun(); - - createBasketballHoop(); - createBasketballRack(); - - createGates(); - - createFire(); - // Handles toggling of all sconce lights - createLights(); - - - - createCat({ - x: 551.09, - y: 494.98, - z: 503.49 - }); - - - createSprayCan({ - x: 549.7, - y: 495.6, - z: 503.91 - }); - - createTargets(); - - } - - function deleteAllToys() { - var entities = Entities.findEntities(MyAvatar.position, 100); - - entities.forEach(function(entity) { - //params: customKey, id, defaultValue - var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; - if (shouldReset === true) { - Entities.deleteEntity(entity); - } - }); - } - - function createFire() { - - - var myOrientation = Quat.fromPitchYawRollDegrees(-90, 0, 0.0); - - var animationSettings = JSON.stringify({ - fps: 30, - running: true, - loop: true, - firstFrame: 1, - lastFrame: 10000 - }); - - - var fire = Entities.addEntity({ - type: "ParticleEffect", - name: "fire", - animationSettings: animationSettings, - textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", - position: { - x: 551.45, - y: 494.82, - z: 502.05 - }, - emitRate: 100, - colorStart: { - red: 70, - green: 70, - blue: 137 - }, - color: { - red: 200, - green: 99, - blue: 42 - }, - colorFinish: { - red: 255, - green: 99, - blue: 32 - }, - radiusSpread: 0.01, - radiusStart: 0.02, - radiusEnd: 0.001, - particleRadius: 0.05, - radiusFinish: 0.0, - emitOrientation: myOrientation, - emitSpeed: 0.3, - speedSpread: 0.1, - alphaStart: 0.05, - alpha: 0.1, - alphaFinish: 0.05, - emitDimensions: { - x: 1, - y: 1, - z: 0.1 - }, - polarFinish: 0.1, - emitAcceleration: { - x: 0.0, - y: 0.0, - z: 0.0 - }, - accelerationSpread: { - x: 0.1, - y: 0.01, - z: 0.1 - }, - lifespan: 1, - userData: JSON.stringify({ - resetMe: { - resetMe: true - } - }) - }); - } - - function createBasketballRack() { - var NUMBER_OF_BALLS = 4; - var DIAMETER = 0.30; - var RESET_DISTANCE = 1; - var MINIMUM_MOVE_LENGTH = 0.05; - var basketballURL = HIFI_PUBLIC_BUCKET + "models/content/basketball2.fbx"; - var basketballCollisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav"; - var rackURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_rack.fbx"; - var rackCollisionHullURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/rack_collision_hull.obj"; - - var rackRotation = Quat.fromPitchYawRollDegrees(0, -90, 0); - - var rackStartPosition = { - x: 542.86, - y: 494.84, - z: 475.06 - }; - var rack = Entities.addEntity({ - name: 'Basketball Rack', - type: "Model", - modelURL: rackURL, - position: rackStartPosition, - rotation: rackRotation, - shapeType: 'compound', - gravity: { - x: 0, - y: -9.8, - z: 0 - }, - linearDamping: 1, - dimensions: { - x: 0.4, - y: 1.37, - z: 1.73 - }, - collisionsWillMove: true, - ignoreForCollisions: false, - compoundShapeURL: rackCollisionHullURL, - userData: JSON.stringify({ - resetMe: { - resetMe: true - }, - grabbableKey: { - grabbable: false - } - - }) - }); - - var collidingBalls = []; - var originalBallPositions = []; - - function createCollidingBalls() { - var position = rackStartPosition; - - var i; - for (i = 0; i < NUMBER_OF_BALLS; i++) { - var ballPosition = { - x: position.x, - y: position.y + DIAMETER * 2, - z: position.z + (DIAMETER) - (DIAMETER * i) - }; - - var collidingBall = Entities.addEntity({ - type: "Model", - name: 'Colliding Basketball', - shapeType: 'Sphere', - position: { - x: position.x + (DIAMETER * 2) - (DIAMETER * i), - y: position.y + DIAMETER * 2, - z: position.z - }, - dimensions: { - x: DIAMETER, - y: DIAMETER, - z: DIAMETER - }, - restitution: 1.0, - linearDamping: 0.00001, - gravity: { - x: 0, - y: -9.8, - z: 0 - }, - collisionsWillMove: true, - ignoreForCollisions: false, - modelURL: basketballURL, - userData: JSON.stringify({ - resetMe: { - resetMe: true - } - }) + function createAllToys() { + createBlocks({ + x: 548.3, + y: 495.55, + z: 504.4 }); - collidingBalls.push(collidingBall); - originalBallPositions.push(position); - } + createBasketBall({ + x: 547.73, + y: 495.5, + z: 505.47 + }); + + createDoll({ + x: 546.67, + y: 495.41, + z: 505.09 + }); + + createWand({ + x: 546.71, + y: 495.55, + z: 506.15 + }); + + createDice(); + + createFlashlight({ + x: 545.72, + y: 495.41, + z: 505.78 + }); + + + + createCombinedArmChair({ + x: 549.29, + y: 494.9, + z: 508.22 + }); + + createPottedPlant({ + x: 554.26, + y: 495.2, + z: 504.53 + }); + + createPingPongBallGun(); + + createBasketballHoop(); + createBasketballRack(); + + createGates(); + + createFire(); + // Handles toggling of all sconce lights + createLights(); + + + + createCat({ + x: 551.09, + y: 494.98, + z: 503.49 + }); + + + createSprayCan({ + x: 549.7, + y: 495.6, + z: 503.91 + }); + + createTargets(); + } - function testBallDistanceFromStart() { - var resetCount = 0; + function deleteAllToys() { + var entities = Entities.findEntities(MyAvatar.position, 100); - collidingBalls.forEach(function(ball, index) { - var currentPosition = Entities.getEntityProperties(ball, "position").position; - var originalPosition = originalBallPositions[index]; - var distance = Vec3.subtract(originalPosition, currentPosition); - var length = Vec3.length(distance); + entities.forEach(function(entity) { + //params: customKey, id, defaultValue + var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; + if (shouldReset === true) { + Entities.deleteEntity(entity); + } + }); + } - if (length > RESET_DISTANCE) { - Script.setTimeout(function() { - var newPosition = Entities.getEntityProperties(ball, "position").position; - var moving = Vec3.length(Vec3.subtract(currentPosition, newPosition)); - if (moving < MINIMUM_MOVE_LENGTH) { - resetCount++; - if (resetCount === NUMBER_OF_BALLS) { + function createFire() { + + + var myOrientation = Quat.fromPitchYawRollDegrees(-90, 0, 0.0); + + var animationSettings = JSON.stringify({ + fps: 30, + running: true, + loop: true, + firstFrame: 1, + lastFrame: 10000 + }); + + + var fire = Entities.addEntity({ + type: "ParticleEffect", + name: "fire", + animationSettings: animationSettings, + textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", + position: { + x: 551.45, + y: 494.82, + z: 502.05 + }, + emitRate: 100, + colorStart: { + red: 70, + green: 70, + blue: 137 + }, + color: { + red: 200, + green: 99, + blue: 42 + }, + colorFinish: { + red: 255, + green: 99, + blue: 32 + }, + radiusSpread: 0.01, + radiusStart: 0.02, + radiusEnd: 0.001, + particleRadius: 0.05, + radiusFinish: 0.0, + emitOrientation: myOrientation, + emitSpeed: 0.3, + speedSpread: 0.1, + alphaStart: 0.05, + alpha: 0.1, + alphaFinish: 0.05, + emitDimensions: { + x: 1, + y: 1, + z: 0.1 + }, + polarFinish: 0.1, + emitAcceleration: { + x: 0.0, + y: 0.0, + z: 0.0 + }, + accelerationSpread: { + x: 0.1, + y: 0.01, + z: 0.1 + }, + lifespan: 1, + userData: JSON.stringify({ + resetMe: { + resetMe: true + } + }) + }); + } + + function createBasketballRack() { + var NUMBER_OF_BALLS = 4; + var DIAMETER = 0.30; + var RESET_DISTANCE = 1; + var MINIMUM_MOVE_LENGTH = 0.05; + var basketballURL = HIFI_PUBLIC_BUCKET + "models/content/basketball2.fbx"; + var basketballCollisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav"; + var rackURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_rack.fbx"; + var rackCollisionHullURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/rack_collision_hull.obj"; + + var rackRotation = Quat.fromPitchYawRollDegrees(0, -90, 0); + + var rackStartPosition = { + x: 542.86, + y: 494.84, + z: 475.06 + }; + var rack = Entities.addEntity({ + name: 'Basketball Rack', + type: "Model", + modelURL: rackURL, + position: rackStartPosition, + rotation: rackRotation, + shapeType: 'compound', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + linearDamping: 1, + dimensions: { + x: 0.4, + y: 1.37, + z: 1.73 + }, + collisionsWillMove: true, + ignoreForCollisions: false, + compoundShapeURL: rackCollisionHullURL, + userData: JSON.stringify({ + resetMe: { + resetMe: true + }, + grabbableKey: { + grabbable: false + } + + }) + }); + + var collidingBalls = []; + var originalBallPositions = []; + + function createCollidingBalls() { + var position = rackStartPosition; + + var i; + for (i = 0; i < NUMBER_OF_BALLS; i++) { + var ballPosition = { + x: position.x, + y: position.y + DIAMETER * 2, + z: position.z + (DIAMETER) - (DIAMETER * i) + }; + + var collidingBall = Entities.addEntity({ + type: "Model", + name: 'Colliding Basketball', + shapeType: 'Sphere', + position: { + x: position.x + (DIAMETER * 2) - (DIAMETER * i), + y: position.y + DIAMETER * 2, + z: position.z + }, + dimensions: { + x: DIAMETER, + y: DIAMETER, + z: DIAMETER + }, + restitution: 1.0, + linearDamping: 0.00001, + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + collisionsWillMove: true, + ignoreForCollisions: false, + modelURL: basketballURL, + userData: JSON.stringify({ + resetMe: { + resetMe: true + } + }) + }); + + collidingBalls.push(collidingBall); + originalBallPositions.push(position); + } + } + + function testBallDistanceFromStart() { + var resetCount = 0; + + collidingBalls.forEach(function(ball, index) { + var currentPosition = Entities.getEntityProperties(ball, "position").position; + var originalPosition = originalBallPositions[index]; + var distance = Vec3.subtract(originalPosition, currentPosition); + var length = Vec3.length(distance); + + if (length > RESET_DISTANCE) { + Script.setTimeout(function() { + var newPosition = Entities.getEntityProperties(ball, "position").position; + var moving = Vec3.length(Vec3.subtract(currentPosition, newPosition)); + if (moving < MINIMUM_MOVE_LENGTH) { + resetCount++; + if (resetCount === NUMBER_OF_BALLS) { + deleteCollidingBalls(); + createCollidingBalls(); + } + } + }, 200); + } + }); + } + + function deleteEntity(entityID) { + if (entityID === rack) { deleteCollidingBalls(); - createCollidingBalls(); - } + Script.clearInterval(distanceCheckInterval); + Entities.deletingEntity.disconnect(deleteEntity); } - }, 200); - } - }); - } - - function deleteEntity(entityID) { - if (entityID === rack) { - deleteCollidingBalls(); - Script.clearInterval(distanceCheckInterval); - Entities.deletingEntity.disconnect(deleteEntity); - } - } - - function deleteCollidingBalls() { - while (collidingBalls.length > 0) { - Entities.deleteEntity(collidingBalls.pop()); - } - } - - createCollidingBalls(); - Entities.deletingEntity.connect(deleteEntity); - - var distanceCheckInterval = Script.setInterval(testBallDistanceFromStart, 1000); - } - - function createTargets() { - - var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx'; - var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target_collision_hull.obj'; - - var RESET_DISTANCE = 1; - var TARGET_USER_DATA_KEY = 'hifi-ping_pong_target'; - var NUMBER_OF_TARGETS = 6; - var TARGETS_PER_ROW = 3; - - var TARGET_DIMENSIONS = { - x: 0.06, - y: 0.42, - z: 0.42 - }; - - var VERTICAL_SPACING = TARGET_DIMENSIONS.y + 0.5; - var HORIZONTAL_SPACING = TARGET_DIMENSIONS.z + 0.5; - - - var startPosition = { - x: 548.68, - y: 497.30, - z: 509.74 - }; - - var rotation = Quat.fromPitchYawRollDegrees(0, -55.25, 0); - - var targetIntervalClearer = Entities.addEntity({ - name: 'Target Interval Clearer - delete me to clear', - type: 'Box', - position: startPosition, - dimensions: TARGET_DIMENSIONS, - rotation: rotation, - visible: false, - collisionsWillMove: false, - ignoreForCollisions: true, - userData: JSON.stringify({ - resetMe: { - resetMe: true - } - }) - }); - - var targets = []; - - var originalPositions = []; - var lastPositions = []; - - function addTargets() { - var i; - var row = -1; - for (i = 0; i < NUMBER_OF_TARGETS; i++) { - - if (i % TARGETS_PER_ROW === 0) { - row++; } - var vHat = Quat.getFront(rotation); - var spacer = HORIZONTAL_SPACING * (i % TARGETS_PER_ROW) + (row * HORIZONTAL_SPACING / 2); - var multiplier = Vec3.multiply(spacer, vHat); - var position = Vec3.sum(startPosition, multiplier); - position.y = startPosition.y - (row * VERTICAL_SPACING); - - originalPositions.push(position); - lastPositions.push(position); - - var targetProperties = { - name: 'Target', - type: 'Model', - modelURL: MODEL_URL, - shapeType: 'compound', - collisionsWillMove: true, - dimensions: TARGET_DIMENSIONS, - compoundShapeURL: COLLISION_HULL_URL, - position: position, - rotation: rotation, - script: targetsScriptURL, - userData: JSON.stringify({ - resetMe: { - resetMe: true + function deleteCollidingBalls() { + while (collidingBalls.length > 0) { + Entities.deleteEntity(collidingBalls.pop()); } - }) + } + + createCollidingBalls(); + Entities.deletingEntity.connect(deleteEntity); + + var distanceCheckInterval = Script.setInterval(testBallDistanceFromStart, 1000); + } + + function createTargets() { + + var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx'; + var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target_collision_hull.obj'; + + var RESET_DISTANCE = 1; + var TARGET_USER_DATA_KEY = 'hifi-ping_pong_target'; + var NUMBER_OF_TARGETS = 6; + var TARGETS_PER_ROW = 3; + + var TARGET_DIMENSIONS = { + x: 0.06, + y: 0.42, + z: 0.42 }; - var target = Entities.addEntity(targetProperties); - targets.push(target); + var VERTICAL_SPACING = TARGET_DIMENSIONS.y + 0.5; + var HORIZONTAL_SPACING = TARGET_DIMENSIONS.z + 0.5; + + + var startPosition = { + x: 548.68, + y: 497.30, + z: 509.74 + }; + + var rotation = Quat.fromPitchYawRollDegrees(0, -55.25, 0); + + var targetIntervalClearer = Entities.addEntity({ + name: 'Target Interval Clearer - delete me to clear', + type: 'Box', + position: startPosition, + dimensions: TARGET_DIMENSIONS, + rotation: rotation, + visible: false, + collisionsWillMove: false, + ignoreForCollisions: true, + userData: JSON.stringify({ + resetMe: { + resetMe: true + } + }) + }); + + var targets = []; + + var originalPositions = []; + var lastPositions = []; + + function addTargets() { + var i; + var row = -1; + for (i = 0; i < NUMBER_OF_TARGETS; i++) { + + if (i % TARGETS_PER_ROW === 0) { + row++; + } + + var vHat = Quat.getFront(rotation); + var spacer = HORIZONTAL_SPACING * (i % TARGETS_PER_ROW) + (row * HORIZONTAL_SPACING / 2); + var multiplier = Vec3.multiply(spacer, vHat); + var position = Vec3.sum(startPosition, multiplier); + position.y = startPosition.y - (row * VERTICAL_SPACING); + + originalPositions.push(position); + lastPositions.push(position); + + var targetProperties = { + name: 'Target', + type: 'Model', + modelURL: MODEL_URL, + shapeType: 'compound', + collisionsWillMove: true, + dimensions: TARGET_DIMENSIONS, + compoundShapeURL: COLLISION_HULL_URL, + position: position, + rotation: rotation, + script: targetsScriptURL, + userData: JSON.stringify({ + resetMe: { + resetMe: true + }, + grabbableKey: { + grabbable: false + } + }) + }; + + var target = Entities.addEntity(targetProperties); + targets.push(target); + + } + } + + function testTargetDistanceFromStart() { + targets.forEach(function(target, index) { + + var currentPosition = Entities.getEntityProperties(target, "position").position; + var originalPosition = originalPositions[index]; + var distance = Vec3.subtract(originalPosition, currentPosition); + var length = Vec3.length(distance); + + var moving = Vec3.length(Vec3.subtract(currentPosition, lastPositions[index])); + + lastPositions[index] = currentPosition; + + if (length > RESET_DISTANCE && moving < MINIMUM_MOVE_LENGTH) { + + Entities.deleteEntity(target); + + var targetProperties = { + name: 'Target', + type: 'Model', + modelURL: MODEL_URL, + shapeType: 'compound', + collisionsWillMove: true, + dimensions: TARGET_DIMENSIONS, + compoundShapeURL: COLLISION_HULL_URL, + position: originalPositions[index], + rotation: rotation, + script: scriptURL + }; + + targets[index] = Entities.addEntity(targetProperties); + + } + }); + } + + + function deleteEntity(entityID) { + if (entityID === targetIntervalClearer) { + deleteTargets(); + Script.clearInterval(distanceCheckInterval); + Entities.deletingEntity.disconnect(deleteEntity); + } + } + + function deleteTargets() { + while (targets.length > 0) { + Entities.deleteEntity(targets.pop()); + } + Entities.deleteEntity(targetIntervalClearer); + } + + Entities.deletingEntity.connect(deleteEntity); + var distanceCheckInterval = Script.setInterval(testTargetDistanceFromStart, 1000); + + addTargets(); - } } - function testTargetDistanceFromStart() { - targets.forEach(function(target, index) { + function createCat(position) { - var currentPosition = Entities.getEntityProperties(target, "position").position; - var originalPosition = originalPositions[index]; - var distance = Vec3.subtract(originalPosition, currentPosition); - var length = Vec3.length(distance); + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; + var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; + var animationSettings = JSON.stringify({ + running: true, + }); + var cat = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "cat", + script: catScriptURL, + animationURL: animationURL, + animationSettings: animationSettings, + position: position, + rotation: { + w: 0.35020983219146729, + x: -4.57763671875e-05, + y: 0.93664455413818359, + z: -1.52587890625e-05 + }, + dimensions: { + x: 0.15723302960395813, + y: 0.50762706995010376, + z: 0.90716040134429932 + }, + userData: JSON.stringify({ + resetMe: { + resetMe: true + } + }) + }); - var moving = Vec3.length(Vec3.subtract(currentPosition, lastPositions[index])); + } - lastPositions[index] = currentPosition; + function createFlashlight(position) { + var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx"; - if (length > RESET_DISTANCE && moving < MINIMUM_MOVE_LENGTH) { + var flashlight = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "flashlight", + script: flashlightScriptURL, + position: position, + dimensions: { + x: 0.08, + y: 0.30, + z: 0.08 + }, + collisionsWillMove: true, + gravity: { + x: 0, + y: -3.5, + z: 0 + }, + velocity: { + x: 0, + y: -0.01, + z: 0 + }, + shapeType: 'box', + userData: JSON.stringify({ + resetMe: { + resetMe: true + } + }) + }); - Entities.deleteEntity(target); - var targetProperties = { - name: 'Target', + } + + function createLights() { + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/lightswitch.fbx"; + + + var rotation = { + w: 0.63280689716339111, + x: 0.63280689716339111, + y: -0.31551080942153931, + z: 0.31548023223876953 + }; + var axis = { + x: 0, + y: 1, + z: 0 + }; + var dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); + + var lightSwitchHall = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "Light Switch Hall", + script: lightsScriptURL, + position: { + x: 543.27764892578125, + y: 495.67999267578125, + z: 511.00564575195312 + }, + rotation: rotation, + dimensions: { + x: 0.10546875, + y: 0.032372996211051941, + z: 0.16242524981498718 + }, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + on: true, + type: "Hall Light" + } + }) + }); + + var sconceLight1 = Entities.addEntity({ + type: "Light", + position: { + x: 543.75, + y: 496.24, + z: 511.13 + }, + name: "Sconce 1 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + }, + isSpotlight: false, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + type: "Hall Light" + } + }) + }); + + var sconceLight2 = Entities.addEntity({ + type: "Light", + position: { + x: 540.1, + y: 496.24, + z: 505.57 + }, + name: "Sconce 2 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + }, + isSpotlight: false, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + type: "Hall Light" + } + }) + }); + + rotation = { + w: 0.20082402229309082, + x: 0.20082402229309082, + y: -0.67800414562225342, + z: 0.67797362804412842 + }; + axis = { + x: 0, + y: 1, + z: 0 + }; + dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); + + var lightSwitchGarage = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "Light Switch Garage", + script: lightsScriptURL, + position: { + x: 545.62, + y: 495.68, + z: 500.21 + }, + rotation: rotation, + dimensions: { + x: 0.10546875, + y: 0.032372996211051941, + z: 0.16242524981498718 + }, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + on: true, + type: "Garage Light" + } + }) + }); + + + + var sconceLight3 = Entities.addEntity({ + type: "Light", + position: { + x: 545.49468994140625, + y: 496.24026489257812, + z: 500.63516235351562 + }, + + name: "Sconce 3 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + }, + isSpotlight: false, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + type: "Garage Light" + } + }) + }); + + + var sconceLight4 = Entities.addEntity({ + type: "Light", + position: { + x: 550.90399169921875, + y: 496.24026489257812, + z: 507.90237426757812 + }, + name: "Sconce 4 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + }, + isSpotlight: false, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + type: "Garage Light" + } + }) + }); + + var sconceLight5 = Entities.addEntity({ + type: "Light", + position: { + x: 548.407958984375, + y: 496.24026489257812, + z: 509.5504150390625 + }, + name: "Sconce 5 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + }, + isSpotlight: false, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + type: "Garage Light" + } + }) + }); + + } + + + + function createDice() { + var diceProps = { + type: "Model", + modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx", + collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", + name: "dice", + position: { + x: 541, + y: 494.96, + z: 509.1 + }, + dimensions: { + x: 0.09, + y: 0.09, + z: 0.09 + }, + gravity: { + x: 0, + y: -3.5, + z: 0 + }, + velocity: { + x: 0, + y: -0.01, + z: 0 + }, + shapeType: "box", + collisionsWillMove: true, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + } + }) + }; + var dice1 = Entities.addEntity(diceProps); + + diceProps.position = { + x: 541.05, + y: 494.96, + z: 509.0 + }; + + var dice2 = Entities.addEntity(diceProps); + + } + + + function createGates() { + var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/ryan/fence.fbx'; + + var rotation = Quat.fromPitchYawRollDegrees(0, -16, 0); + var gate = Entities.addEntity({ + name: 'Front Door Fence', type: 'Model', modelURL: MODEL_URL, + shapeType: 'box', + position: { + x: 531.15, + y: 495.11, + z: 520.20 + }, + dimensions: { + x: 1.42, + y: 1.13, + z: 0.2 + }, + rotation: rotation, + collisionsWillMove: true, + gravity: { + x: 0, + y: -100, + z: 0 + }, + linearDamping: 1, + angularDamping: 10, + mass: 10, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + }, + grabbableKey: { + grabbable: false + } + }) + }); + } + + function createPingPongBallGun() { + var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx'; + var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun_collision_hull.obj'; + + var position = { + x: 548.6, + y: 495.4, + z: 503.39 + }; + + var rotation = Quat.fromPitchYawRollDegrees(0, 36, 0); + + var pingPongGun = Entities.addEntity({ + type: "Model", + modelURL: MODEL_URL, + shapeType: 'box', + script: pingPongScriptURL, + position: position, + rotation: rotation, + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + dimensions: { + x: 0.08, + y: 0.21, + z: 0.47 + }, + collisionsWillMove: true, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + } + }) + }); + } + + function createBasketballHoop() { + var position = { + x: 539.23, + y: 496.13, + z: 475.89 + }; + var rotation = Quat.fromPitchYawRollDegrees(0, 58.49, 0); + + var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop.fbx"; + var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop_collision_hull.obj"; + + var hoop = Entities.addEntity({ + type: "Model", + modelURL: hoopURL, + position: position, + rotation: rotation, + shapeType: 'compound', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + dimensions: { + x: 1.89, + y: 3.99, + z: 3.79 + }, + compoundShapeURL: hoopCollisionHullURL, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + }, + grabbableKey: { + grabbable: false + } + }) + }); + } + + function createWand(position) { + var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; + var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/actual_no_top_collision_hull.obj'; + + var entity = Entities.addEntity({ + name: 'Bubble Wand', + type: "Model", + modelURL: WAND_MODEL, + position: position, + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + dimensions: { + x: 0.05, + y: 0.25, + z: 0.05 + }, + //must be enabled to be grabbable in the physics engine shapeType: 'compound', collisionsWillMove: true, - dimensions: TARGET_DIMENSIONS, - compoundShapeURL: COLLISION_HULL_URL, - position: originalPositions[index], - rotation: rotation, - script: scriptURL - }; - - targets[index] = Entities.addEntity(targetProperties); - - } - }); - } - - - function deleteEntity(entityID) { - if (entityID === targetIntervalClearer) { - deleteTargets(); - Script.clearInterval(distanceCheckInterval); - Entities.deletingEntity.disconnect(deleteEntity); - } - } - - function deleteTargets() { - while (targets.length > 0) { - Entities.deleteEntity(targets.pop()); - } - Entities.deleteEntity(targetIntervalClearer); - } - - Entities.deletingEntity.connect(deleteEntity); - var distanceCheckInterval = Script.setInterval(testTargetDistanceFromStart, 1000); - - addTargets(); - - } - - function createCat(position) { - - var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; - var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; - var animationSettings = JSON.stringify({ - running: true, - }); - var cat = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - name: "cat", - script: catScriptURL, - animationURL: animationURL, - animationSettings: animationSettings, - position: position, - rotation: { - w: 0.35020983219146729, - x: -4.57763671875e-05, - y: 0.93664455413818359, - z: -1.52587890625e-05 - }, - dimensions: { - x: 0.15723302960395813, - y: 0.50762706995010376, - z: 0.90716040134429932 - }, - userData: JSON.stringify({ - resetMe: { - resetMe: true - } - }) - }); - - } - - function createFlashlight(position) { - var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx"; - - var flashlight = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - name: "flashlight", - script: flashlightScriptURL, - position: position, - dimensions: { - x: 0.08, - y: 0.30, - z: 0.08 - }, - collisionsWillMove: true, - gravity: { - x: 0, - y: -3.5, - z: 0 - }, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, - shapeType: 'box', - userData: JSON.stringify({ - resetMe: { - resetMe: true - } - }) - }); - - - } - - function createLights() { - var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/lightswitch.fbx"; - - - var rotation = { - w: 0.63280689716339111, - x: 0.63280689716339111, - y: -0.31551080942153931, - z: 0.31548023223876953 - }; - var axis = { - x: 0, - y: 1, - z: 0 - }; - var dQ = Quat.angleAxis(180, axis); - rotation = Quat.multiply(rotation, dQ); - - var lightSwitchHall = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - name: "Light Switch Hall", - script: lightsScriptURL, - position: { - x: 543.27764892578125, - y: 495.67999267578125, - z: 511.00564575195312 - }, - rotation: rotation, - dimensions: { - x: 0.10546875, - y: 0.032372996211051941, - z: 0.16242524981498718 - }, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - on: true, - type: "Hall Light" - } - }) - }); - - var sconceLight1 = Entities.addEntity({ - type: "Light", - position: { - x: 543.75, - y: 496.24, - z: 511.13 - }, - name: "Sconce 1 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - }, - isSpotlight: false, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - type: "Hall Light" - } - }) - }); - - var sconceLight2 = Entities.addEntity({ - type: "Light", - position: { - x: 540.1, - y: 496.24, - z: 505.57 - }, - name: "Sconce 2 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - }, - isSpotlight: false, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - type: "Hall Light" - } - }) - }); - - rotation = { - w: 0.20082402229309082, - x: 0.20082402229309082, - y: -0.67800414562225342, - z: 0.67797362804412842 - }; - axis = { - x: 0, - y: 1, - z: 0 - }; - dQ = Quat.angleAxis(180, axis); - rotation = Quat.multiply(rotation, dQ); - - var lightSwitchGarage = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - name: "Light Switch Garage", - script: lightsScriptURL, - position: { - x: 545.62, - y: 495.68, - z: 500.21 - }, - rotation: rotation, - dimensions: { - x: 0.10546875, - y: 0.032372996211051941, - z: 0.16242524981498718 - }, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - on: true, - type: "Garage Light" - } - }) - }); - - - - var sconceLight3 = Entities.addEntity({ - type: "Light", - position: { - x: 545.49468994140625, - y: 496.24026489257812, - z: 500.63516235351562 - }, - - name: "Sconce 3 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - }, - isSpotlight: false, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - type: "Garage Light" - } - }) - }); - - - var sconceLight4 = Entities.addEntity({ - type: "Light", - position: { - x: 550.90399169921875, - y: 496.24026489257812, - z: 507.90237426757812 - }, - name: "Sconce 4 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - }, - isSpotlight: false, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - type: "Garage Light" - } - }) - }); - - var sconceLight5 = Entities.addEntity({ - type: "Light", - position: { - x: 548.407958984375, - y: 496.24026489257812, - z: 509.5504150390625 - }, - name: "Sconce 5 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - }, - isSpotlight: false, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - type: "Garage Light" - } - }) - }); - - } - - - - function createDice() { - var diceProps = { - type: "Model", - modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx", - collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", - name: "dice", - position: { - x: 541, - y: 494.96, - z: 509.1 - }, - dimensions: { - x: 0.09, - y: 0.09, - z: 0.09 - }, - gravity: { - x: 0, - y: -3.5, - z: 0 - }, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, - shapeType: "box", - collisionsWillMove: true, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - } - }) - }; - var dice1 = Entities.addEntity(diceProps); - - diceProps.position = { - x: 541.05, - y: 494.96, - z: 509.0 - }; - - var dice2 = Entities.addEntity(diceProps); - - } - - - function createGates() { - var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/ryan/fence.fbx'; - - var rotation = Quat.fromPitchYawRollDegrees(0, -16, 0); - var gate = Entities.addEntity({ - name: 'Front Door Fence', - type: 'Model', - modelURL: MODEL_URL, - shapeType: 'box', - position: { - x: 531.15, - y: 495.11, - z: 520.20 - }, - dimensions: { - x: 1.42, - y: 1.13, - z: 0.2 - }, - rotation: rotation, - collisionsWillMove: true, - gravity: { - x: 0, - y: -100, - z: 0 - }, - linearDamping: 1, - angularDamping: 10, - mass: 10, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - }, - grabbableKey: { - grabbable: false - } - }) - }); - } - - function createPingPongBallGun() { - var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx'; - var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun_collision_hull.obj'; - - var position = { - x: 548.6, - y: 495.4, - z: 503.39 - }; - - var rotation = Quat.fromPitchYawRollDegrees(0, 36, 0); - - var pingPongGun = Entities.addEntity({ - type: "Model", - modelURL: MODEL_URL, - shapeType: 'box', - script: pingPongScriptURL, - position: position, - rotation: rotation, - gravity: { - x: 0, - y: -9.8, - z: 0 - }, - dimensions: { - x: 0.08, - y: 0.21, - z: 0.47 - }, - collisionsWillMove: true, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - } - }) - }); - } - - function createBasketballHoop() { - var position = { - x: 539.23, - y: 496.13, - z: 475.89 - }; - var rotation = Quat.fromPitchYawRollDegrees(0, 58.49, 0); - - var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop.fbx"; - var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop_collision_hull.obj"; - - var hoop = Entities.addEntity({ - type: "Model", - modelURL: hoopURL, - position: position, - rotation: rotation, - shapeType: 'compound', - gravity: { - x: 0, - y: -9.8, - z: 0 - }, - dimensions: { - x: 1.89, - y: 3.99, - z: 3.79 - }, - compoundShapeURL: hoopCollisionHullURL, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - }, - grabbableKey: { - grabbable: false - } - }) - }); - } - - function createWand(position) { - var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; - var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/actual_no_top_collision_hull.obj'; - - var entity = Entities.addEntity({ - name: 'Bubble Wand', - type: "Model", - modelURL: WAND_MODEL, - position: position, - gravity: { - x: 0, - y: -9.8, - z: 0 - }, - dimensions: { - x: 0.05, - y: 0.25, - z: 0.05 - }, - //must be enabled to be grabbable in the physics engine - shapeType: 'compound', - collisionsWillMove: true, - compoundShapeURL: WAND_COLLISION_SHAPE, - //Look into why bubble wand is going through table when gravity is enabled - // gravity: {x: 0, y: -3.5, z: 0}, - // velocity: {x: 0, y: -0.01, z:0}, - script: wandScriptURL, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - } - }) - }); - - - } - - function createBasketBall(position) { - - var modelURL = "http://s3.amazonaws.com/hifi-public/models/content/basketball2.fbx"; - - var entity = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - position: position, - collisionsWillMove: true, - shapeType: "sphere", - name: "basketball", - dimensions: { - x: 0.25, - y: 0.26, - z: 0.25 - }, - gravity: { - x: 0, - y: -7, - z: 0 - }, - restitution: 10, - linearDamping: 0.0, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, - collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav", - userData: JSON.stringify({ - resetMe: { - resetMe: true, - } - }) - }); - - } - - function createDoll(position) { - var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; - - var naturalDimensions = { - x: 1.63, - y: 1.67, - z: 0.26 - }; - var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); - var entity = Entities.addEntity({ - type: "Model", - name: "doll", - modelURL: modelURL, - script: dollScriptURL, - position: position, - shapeType: 'box', - dimensions: desiredDimensions, - gravity: { - x: 0, - y: -5, - z: 0 - }, - velocity: { - x: 0, - y: -0.1, - z: 0 - }, - collisionsWillMove: true, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - } - }) - }); - - } - - function createSprayCan(position) { - - var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; - - var entity = Entities.addEntity({ - type: "Model", - name: "spraycan", - script: sprayPaintScriptURL, - modelURL: modelURL, - position: position, - dimensions: { - x: 0.07, - y: 0.17, - z: 0.07 - }, - collisionsWillMove: true, - shapeType: 'box', - gravity: { - x: 0, - y: -0.5, - z: 0 - }, - velocity: { - x: 0, - y: -1, - z: 0 - }, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - } - }) - }); - - } - - function createPottedPlant(position) { - var modelURL = "http://hifi-public.s3.amazonaws.com/models/potted_plant/potted_plant.fbx"; - - var entity = Entities.addEntity({ - type: "Model", - name: "Potted Plant", - modelURL: modelURL, - position: position, - dimensions: { - x: 1.10, - y: 2.18, - z: 1.07 - }, - collisionsWillMove: true, - shapeType: 'box', - gravity: { - x: 0, - y: -9.8, - z: 0 - }, - velocity: { - x: 0, - y: 0, - z: 0 - }, - linearDamping: 0.4, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - }, - grabbableKey: { - grabbable: false - } - }) - }); - } - - - function createCombinedArmChair(position) { - var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/combined_chair.fbx"; - var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj"; - - var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); - - var entity = Entities.addEntity({ - type: "Model", - name: "Red Arm Chair", - modelURL: modelURL, - shapeType: 'compound', - compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL, - position: position, - rotation: rotation, - dimensions: { - x: 1.26, - y: 1.56, - z: 1.35 - }, - collisionsWillMove: true, - gravity: { - x: 0, - y: -0.8, - z: 0 - }, - velocity: { - x: 0, - y: 0, - z: 0 - }, - linearDamping: 0.2, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - }, - grabbableKey: { - grabbable: false - } - }) - }); - - } - - function createBlocks(position) { - var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/"; - var collisionSoundURL = "https://hifi-public.s3.amazonaws.com/sounds/Collisions-otherorganic/ToyWoodBlock.L.wav"; - var NUM_BLOCKS_PER_COLOR = 4; - var i, j; - - var blockTypes = [{ - url: "planky_blue.fbx", - dimensions: { - x: 0.05, - y: 0.05, - z: 0.25 - } - }, { - url: "planky_green.fbx", - dimensions: { - x: 0.1, - y: 0.1, - z: 0.25 - } - }, { - url: "planky_natural.fbx", - dimensions: { - x: 0.05, - y: 0.05, - z: 0.05 - } - }, { - url: "planky_yellow.fbx", - dimensions: { - x: 0.03, - y: 0.05, - z: 0.25 - } - }, { - url: "planky_red.fbx", - dimensions: { - x: 0.1, - y: 0.05, - z: 0.25 - } - }, ]; - - var modelURL, entity; - for (i = 0; i < blockTypes.length; i++) { - for (j = 0; j < NUM_BLOCKS_PER_COLOR; j++) { - modelURL = baseURL + blockTypes[i].url; - entity = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - position: Vec3.sum(position, { - x: j / 10, - y: i / 10, - z: 0 - }), - shapeType: 'box', - name: "block", - dimensions: blockTypes[i].dimensions, - collisionsWillMove: true, - collisionSoundURL: collisionSoundURL, - gravity: { - x: 0, - y: -2.5, - z: 0 - }, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - } - }) + compoundShapeURL: WAND_COLLISION_SHAPE, + //Look into why bubble wand is going through table when gravity is enabled + // gravity: {x: 0, y: -3.5, z: 0}, + // velocity: {x: 0, y: -0.01, z:0}, + script: wandScriptURL, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + } + }) }); - } + } - } - function cleanup() { - deleteAllToys(); - } + function createBasketBall(position) { - if (shouldDeleteOnEndScript) { + var modelURL = "http://s3.amazonaws.com/hifi-public/models/content/basketball2.fbx"; - Script.scriptEnding.connect(cleanup); - } + var entity = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + position: position, + collisionsWillMove: true, + shapeType: "sphere", + name: "basketball", + dimensions: { + x: 0.25, + y: 0.26, + z: 0.25 + }, + gravity: { + x: 0, + y: -7, + z: 0 + }, + restitution: 10, + linearDamping: 0.0, + velocity: { + x: 0, + y: -0.01, + z: 0 + }, + collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav", + userData: JSON.stringify({ + resetMe: { + resetMe: true, + } + }) + }); + + } + + function createDoll(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; + + var naturalDimensions = { + x: 1.63, + y: 1.67, + z: 0.26 + }; + var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); + var entity = Entities.addEntity({ + type: "Model", + name: "doll", + modelURL: modelURL, + script: dollScriptURL, + position: position, + shapeType: 'box', + dimensions: desiredDimensions, + gravity: { + x: 0, + y: -5, + z: 0 + }, + velocity: { + x: 0, + y: -0.1, + z: 0 + }, + collisionsWillMove: true, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + } + }) + }); + + } + + function createSprayCan(position) { + + var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; + + var entity = Entities.addEntity({ + type: "Model", + name: "spraycan", + script: sprayPaintScriptURL, + modelURL: modelURL, + position: position, + dimensions: { + x: 0.07, + y: 0.17, + z: 0.07 + }, + collisionsWillMove: true, + shapeType: 'box', + gravity: { + x: 0, + y: -0.5, + z: 0 + }, + velocity: { + x: 0, + y: -1, + z: 0 + }, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + } + }) + }); + + } + + function createPottedPlant(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/potted_plant/potted_plant.fbx"; + + var entity = Entities.addEntity({ + type: "Model", + name: "Potted Plant", + modelURL: modelURL, + position: position, + dimensions: { + x: 1.10, + y: 2.18, + z: 1.07 + }, + collisionsWillMove: true, + shapeType: 'box', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + velocity: { + x: 0, + y: 0, + z: 0 + }, + linearDamping: 0.4, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + }, + grabbableKey: { + grabbable: false + } + }) + }); + } + + + function createCombinedArmChair(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/combined_chair.fbx"; + var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj"; + + var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); + + var entity = Entities.addEntity({ + type: "Model", + name: "Red Arm Chair", + modelURL: modelURL, + shapeType: 'compound', + compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL, + position: position, + rotation: rotation, + dimensions: { + x: 1.26, + y: 1.56, + z: 1.35 + }, + collisionsWillMove: true, + gravity: { + x: 0, + y: -0.8, + z: 0 + }, + velocity: { + x: 0, + y: 0, + z: 0 + }, + linearDamping: 0.2, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + }, + grabbableKey: { + grabbable: false + } + }) + }); + + } + + function createBlocks(position) { + var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/"; + var collisionSoundURL = "https://hifi-public.s3.amazonaws.com/sounds/Collisions-otherorganic/ToyWoodBlock.L.wav"; + var NUM_BLOCKS_PER_COLOR = 4; + var i, j; + + var blockTypes = [{ + url: "planky_blue.fbx", + dimensions: { + x: 0.05, + y: 0.05, + z: 0.25 + } + }, { + url: "planky_green.fbx", + dimensions: { + x: 0.1, + y: 0.1, + z: 0.25 + } + }, { + url: "planky_natural.fbx", + dimensions: { + x: 0.05, + y: 0.05, + z: 0.05 + } + }, { + url: "planky_yellow.fbx", + dimensions: { + x: 0.03, + y: 0.05, + z: 0.25 + } + }, { + url: "planky_red.fbx", + dimensions: { + x: 0.1, + y: 0.05, + z: 0.25 + } + }, ]; + + var modelURL, entity; + for (i = 0; i < blockTypes.length; i++) { + for (j = 0; j < NUM_BLOCKS_PER_COLOR; j++) { + modelURL = baseURL + blockTypes[i].url; + entity = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + position: Vec3.sum(position, { + x: j / 10, + y: i / 10, + z: 0 + }), + shapeType: 'box', + name: "block", + dimensions: blockTypes[i].dimensions, + collisionsWillMove: true, + collisionSoundURL: collisionSoundURL, + gravity: { + x: 0, + y: -2.5, + z: 0 + }, + velocity: { + x: 0, + y: -0.01, + z: 0 + }, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + } + }) + }); + + } + } + } + + function cleanup() { + deleteAllToys(); + } + + if (shouldDeleteOnEndScript) { + + Script.scriptEnding.connect(cleanup); + } }; \ No newline at end of file From fc8a4f4f2dba746f0883e606dae60ef8dcd114e3 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 12 Oct 2015 17:00:49 -0700 Subject: [PATCH 41/49] cleanup --- unpublishedScripts/masterReset.js | 1 - 1 file changed, 1 deletion(-) diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index fdedac3ec3..03dacef0a4 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -247,7 +247,6 @@ MasterReset = function() { grabbableKey: { grabbable: false } - }) }); From 0f998e81afd9f123083639e2d986220c689ba5fc Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 12 Oct 2015 17:03:32 -0700 Subject: [PATCH 42/49] add min reset distance --- unpublishedScripts/hiddenEntityReset.js | 4 ++-- unpublishedScripts/masterReset.js | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index f959923ad3..702aaec378 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -378,7 +378,8 @@ var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx'; var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target_collision_hull.obj'; - var RESET_DISTANCE = 1; + var MINIMUM_MOVE_LENGTH = 0.05; + var RESET_DISTANCE = 0.5; var TARGET_USER_DATA_KEY = 'hifi-ping_pong_target'; var NUMBER_OF_TARGETS = 6; var TARGETS_PER_ROW = 3; @@ -392,7 +393,6 @@ var VERTICAL_SPACING = TARGET_DIMENSIONS.y + 0.5; var HORIZONTAL_SPACING = TARGET_DIMENSIONS.z + 0.5; - var startPosition = { x: 548.68, y: 497.30, diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 03dacef0a4..a6c3bfdd16 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -350,7 +350,8 @@ MasterReset = function() { var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx'; var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target_collision_hull.obj'; - var RESET_DISTANCE = 1; + var MINIMUM_MOVE_LENGTH = 0.05; + var RESET_DISTANCE = 0.5; var TARGET_USER_DATA_KEY = 'hifi-ping_pong_target'; var NUMBER_OF_TARGETS = 6; var TARGETS_PER_ROW = 3; From 6a8ff676ed3c979d3c441ad72405a35f7bba8cac Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 12 Oct 2015 17:32:18 -0700 Subject: [PATCH 43/49] Remove overlay hiding from middle mouse button. Because it conflicts with edit.js camera panning. You can still toggle the overlay via the O key. --- interface/src/Application.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9a6e2fff4d..8705c7b61d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1890,16 +1890,6 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { computePickRay(mappedEvent.x(), mappedEvent.y())); sendEvent(this, &actionEvent); - } else if (event->button() == Qt::RightButton) { - // "right click" on controllers to toggle the overlay - if (deviceID > 0) { - _overlayConductor.setEnabled(!_overlayConductor.getEnabled()); - } - } else if (event->button() == Qt::MiddleButton) { - // mouse middle click to toggle the overlay - if (deviceID == 0) { - _overlayConductor.setEnabled(!_overlayConductor.getEnabled()); - } } } } From 309cde7f28735d2a23ac7f3943e7f35ea6513ed1 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 13 Oct 2015 10:31:36 -0700 Subject: [PATCH 44/49] invert solidity of most toybox objects while held --- unpublishedScripts/hiddenEntityReset.js | 41 +- unpublishedScripts/masterReset.js | 1248 ++++++++++++----------- 2 files changed, 686 insertions(+), 603 deletions(-) diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index 702aaec378..1b3dd07e5e 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -319,6 +319,9 @@ userData: JSON.stringify({ resetMe: { resetMe: true + }, + grabbableKey: { + invertSolidWhileHeld: true } }) }); @@ -459,6 +462,9 @@ resetMe: { resetMe: true }, + grabbableKey: { + grabbable: false + } }) }; var target = Entities.addEntity(targetProperties); @@ -492,7 +498,15 @@ compoundShapeURL: COLLISION_HULL_URL, position: originalPositions[index], rotation: rotation, - script: scriptURL + script: scriptURL, + userData: JSON.stringify({ + resetMe: { + resetMe: true + }, + grabbableKey: { + grabbable: false + } + }) }; targets[index] = Entities.addEntity(targetProperties); @@ -553,6 +567,9 @@ userData: JSON.stringify({ resetMe: { resetMe: true + }, + grabbableKey: { + grabbable: false } }) }); @@ -588,7 +605,11 @@ userData: JSON.stringify({ resetMe: { resetMe: true + }, + grabbableKey: { + invertSolidWhileHeld: true } + }) }); @@ -856,6 +877,9 @@ userData: JSON.stringify({ resetMe: { resetMe: true, + }, + grabbableKey: { + invertSolidWhileHeld: true } }) }; @@ -945,6 +969,9 @@ userData: JSON.stringify({ resetMe: { resetMe: true, + }, + grabbableKey: { + invertSolidWhileHeld: true } }) }); @@ -1019,6 +1046,9 @@ userData: JSON.stringify({ resetMe: { resetMe: true, + }, + grabbableKey: { + invertSolidWhileHeld: true } }) }); @@ -1058,6 +1088,9 @@ userData: JSON.stringify({ resetMe: { resetMe: true, + }, + grabbableKey: { + invertSolidWhileHeld: true } }) }); @@ -1095,6 +1128,9 @@ userData: JSON.stringify({ resetMe: { resetMe: true, + }, + grabbableKey: { + invertSolidWhileHeld: true } }) }); @@ -1131,6 +1167,9 @@ userData: JSON.stringify({ resetMe: { resetMe: true, + }, + grabbableKey: { + invertSolidWhileHeld: true } }) }); diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index a6c3bfdd16..5eaa35372f 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -291,6 +291,9 @@ MasterReset = function() { userData: JSON.stringify({ resetMe: { resetMe: true + }, + grabbable: { + invertSolidWhileHeld: true } }) }); @@ -443,69 +446,78 @@ MasterReset = function() { function testTargetDistanceFromStart() { targets.forEach(function(target, index) { - var currentPosition = Entities.getEntityProperties(target, "position").position; - var originalPosition = originalPositions[index]; - var distance = Vec3.subtract(originalPosition, currentPosition); - var length = Vec3.length(distance); + var currentPosition = Entities.getEntityProperties(target, "position").position; + var originalPosition = originalPositions[index]; + var distance = Vec3.subtract(originalPosition, currentPosition); + var length = Vec3.length(distance); - var moving = Vec3.length(Vec3.subtract(currentPosition, lastPositions[index])); + var moving = Vec3.length(Vec3.subtract(currentPosition, lastPositions[index])); - lastPositions[index] = currentPosition; + lastPositions[index] = currentPosition; - if (length > RESET_DISTANCE && moving < MINIMUM_MOVE_LENGTH) { + if (length > RESET_DISTANCE && moving < MINIMUM_MOVE_LENGTH) { - Entities.deleteEntity(target); + Entities.deleteEntity(target); - var targetProperties = { - name: 'Target', - type: 'Model', - modelURL: MODEL_URL, - shapeType: 'compound', - collisionsWillMove: true, - dimensions: TARGET_DIMENSIONS, - compoundShapeURL: COLLISION_HULL_URL, - position: originalPositions[index], - rotation: rotation, - script: scriptURL + var targetProperties = { + name: 'Target', + type: 'Model', + modelURL: MODEL_URL, + shapeType: 'compound', + collisionsWillMove: true, + dimensions: TARGET_DIMENSIONS, + compoundShapeURL: COLLISION_HULL_URL, + position: originalPositions[index], + rotation: rotation, + script: scriptURL, + userData: JSON.stringify({ + resetMe: { + resetMe: true + }, + grabbableKey: { + grabbable: false + } + } + }) }; targets[index] = Entities.addEntity(targetProperties); } }); - } - - - function deleteEntity(entityID) { - if (entityID === targetIntervalClearer) { - deleteTargets(); - Script.clearInterval(distanceCheckInterval); - Entities.deletingEntity.disconnect(deleteEntity); - } - } - - function deleteTargets() { - while (targets.length > 0) { - Entities.deleteEntity(targets.pop()); - } - Entities.deleteEntity(targetIntervalClearer); - } - - Entities.deletingEntity.connect(deleteEntity); - var distanceCheckInterval = Script.setInterval(testTargetDistanceFromStart, 1000); - - addTargets(); - } - function createCat(position) { - var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; - var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; - var animationSettings = JSON.stringify({ - running: true, - }); - var cat = Entities.addEntity({ + function deleteEntity(entityID) { + if (entityID === targetIntervalClearer) { + deleteTargets(); + Script.clearInterval(distanceCheckInterval); + Entities.deletingEntity.disconnect(deleteEntity); + } + } + + function deleteTargets() { + while (targets.length > 0) { + Entities.deleteEntity(targets.pop()); + } + Entities.deleteEntity(targetIntervalClearer); + } + + Entities.deletingEntity.connect(deleteEntity); + var distanceCheckInterval = Script.setInterval(testTargetDistanceFromStart, 1000); + + addTargets(); + +} + +function createCat(position) { + + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; + var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; + var animationSettings = JSON.stringify({ + running: true, + }); + var cat = Entities.addEntity({ type: "Model", modelURL: modelURL, name: "cat", @@ -525,18 +537,22 @@ MasterReset = function() { z: 0.90716040134429932 }, userData: JSON.stringify({ - resetMe: { - resetMe: true + resetMe: { + resetMe: true + }, + grabbableKey: { + grabbable: false + } } }) - }); + }); - } +} - function createFlashlight(position) { - var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx"; +function createFlashlight(position) { + var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx"; - var flashlight = Entities.addEntity({ + var flashlight = Entities.addEntity({ type: "Model", modelURL: modelURL, name: "flashlight", @@ -560,345 +576,353 @@ MasterReset = function() { }, shapeType: 'box', userData: JSON.stringify({ - resetMe: { - resetMe: true + resetMe: { + resetMe: true + }, + grabbableKey: { + invertSolidWhileHeld: true + } } }) - }); + }); - } +} - function createLights() { - var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/lightswitch.fbx"; +function createLights() { + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/lightswitch.fbx"; - var rotation = { - w: 0.63280689716339111, - x: 0.63280689716339111, - y: -0.31551080942153931, - z: 0.31548023223876953 - }; - var axis = { - x: 0, - y: 1, - z: 0 - }; - var dQ = Quat.angleAxis(180, axis); - rotation = Quat.multiply(rotation, dQ); + var rotation = { + w: 0.63280689716339111, + x: 0.63280689716339111, + y: -0.31551080942153931, + z: 0.31548023223876953 + }; + var axis = { + x: 0, + y: 1, + z: 0 + }; + var dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); - var lightSwitchHall = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - name: "Light Switch Hall", - script: lightsScriptURL, - position: { - x: 543.27764892578125, - y: 495.67999267578125, - z: 511.00564575195312 - }, - rotation: rotation, - dimensions: { - x: 0.10546875, - y: 0.032372996211051941, - z: 0.16242524981498718 - }, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - on: true, - type: "Hall Light" - } - }) - }); + var lightSwitchHall = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "Light Switch Hall", + script: lightsScriptURL, + position: { + x: 543.27764892578125, + y: 495.67999267578125, + z: 511.00564575195312 + }, + rotation: rotation, + dimensions: { + x: 0.10546875, + y: 0.032372996211051941, + z: 0.16242524981498718 + }, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + on: true, + type: "Hall Light" + } + }) + }); - var sconceLight1 = Entities.addEntity({ - type: "Light", - position: { - x: 543.75, - y: 496.24, - z: 511.13 - }, - name: "Sconce 1 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - }, - isSpotlight: false, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - type: "Hall Light" - } - }) - }); + var sconceLight1 = Entities.addEntity({ + type: "Light", + position: { + x: 543.75, + y: 496.24, + z: 511.13 + }, + name: "Sconce 1 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + }, + isSpotlight: false, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + type: "Hall Light" + } + }) + }); - var sconceLight2 = Entities.addEntity({ - type: "Light", - position: { - x: 540.1, - y: 496.24, - z: 505.57 - }, - name: "Sconce 2 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - }, - isSpotlight: false, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - type: "Hall Light" - } - }) - }); + var sconceLight2 = Entities.addEntity({ + type: "Light", + position: { + x: 540.1, + y: 496.24, + z: 505.57 + }, + name: "Sconce 2 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + }, + isSpotlight: false, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + type: "Hall Light" + } + }) + }); - rotation = { - w: 0.20082402229309082, - x: 0.20082402229309082, - y: -0.67800414562225342, - z: 0.67797362804412842 - }; - axis = { - x: 0, - y: 1, - z: 0 - }; - dQ = Quat.angleAxis(180, axis); - rotation = Quat.multiply(rotation, dQ); + rotation = { + w: 0.20082402229309082, + x: 0.20082402229309082, + y: -0.67800414562225342, + z: 0.67797362804412842 + }; + axis = { + x: 0, + y: 1, + z: 0 + }; + dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); - var lightSwitchGarage = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - name: "Light Switch Garage", - script: lightsScriptURL, - position: { - x: 545.62, - y: 495.68, - z: 500.21 - }, - rotation: rotation, - dimensions: { - x: 0.10546875, - y: 0.032372996211051941, - z: 0.16242524981498718 - }, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - on: true, - type: "Garage Light" - } - }) - }); + var lightSwitchGarage = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "Light Switch Garage", + script: lightsScriptURL, + position: { + x: 545.62, + y: 495.68, + z: 500.21 + }, + rotation: rotation, + dimensions: { + x: 0.10546875, + y: 0.032372996211051941, + z: 0.16242524981498718 + }, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + on: true, + type: "Garage Light" + } + }) + }); - var sconceLight3 = Entities.addEntity({ - type: "Light", - position: { - x: 545.49468994140625, - y: 496.24026489257812, - z: 500.63516235351562 - }, + var sconceLight3 = Entities.addEntity({ + type: "Light", + position: { + x: 545.49468994140625, + y: 496.24026489257812, + z: 500.63516235351562 + }, - name: "Sconce 3 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - }, - isSpotlight: false, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - type: "Garage Light" - } - }) - }); + name: "Sconce 3 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + }, + isSpotlight: false, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + type: "Garage Light" + } + }) + }); - var sconceLight4 = Entities.addEntity({ - type: "Light", - position: { - x: 550.90399169921875, - y: 496.24026489257812, - z: 507.90237426757812 - }, - name: "Sconce 4 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - }, - isSpotlight: false, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - type: "Garage Light" - } - }) - }); + var sconceLight4 = Entities.addEntity({ + type: "Light", + position: { + x: 550.90399169921875, + y: 496.24026489257812, + z: 507.90237426757812 + }, + name: "Sconce 4 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + }, + isSpotlight: false, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + type: "Garage Light" + } + }) + }); - var sconceLight5 = Entities.addEntity({ - type: "Light", - position: { - x: 548.407958984375, - y: 496.24026489257812, - z: 509.5504150390625 - }, - name: "Sconce 5 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - }, - isSpotlight: false, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - type: "Garage Light" - } - }) - }); + var sconceLight5 = Entities.addEntity({ + type: "Light", + position: { + x: 548.407958984375, + y: 496.24026489257812, + z: 509.5504150390625 + }, + name: "Sconce 5 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + }, + isSpotlight: false, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + type: "Garage Light" + } + }) + }); - } +} - function createDice() { - var diceProps = { - type: "Model", - modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx", - collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", - name: "dice", - position: { - x: 541, - y: 494.96, - z: 509.1 - }, - dimensions: { - x: 0.09, - y: 0.09, - z: 0.09 - }, - gravity: { - x: 0, - y: -3.5, - z: 0 - }, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, - shapeType: "box", - collisionsWillMove: true, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - } - }) - }; - var dice1 = Entities.addEntity(diceProps); - - diceProps.position = { - x: 541.05, +function createDice() { + var diceProps = { + type: "Model", + modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx", + collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", + name: "dice", + position: { + x: 541, y: 494.96, - z: 509.0 - }; - - var dice2 = Entities.addEntity(diceProps); - - } - - - function createGates() { - var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/ryan/fence.fbx'; - - var rotation = Quat.fromPitchYawRollDegrees(0, -16, 0); - var gate = Entities.addEntity({ - name: 'Front Door Fence', - type: 'Model', - modelURL: MODEL_URL, - shapeType: 'box', - position: { - x: 531.15, - y: 495.11, - z: 520.20 - }, - dimensions: { - x: 1.42, - y: 1.13, - z: 0.2 - }, - rotation: rotation, - collisionsWillMove: true, - gravity: { - x: 0, - y: -100, - z: 0 - }, - linearDamping: 1, - angularDamping: 10, - mass: 10, - userData: JSON.stringify({ + z: 509.1 + }, + dimensions: { + x: 0.09, + y: 0.09, + z: 0.09 + }, + gravity: { + x: 0, + y: -3.5, + z: 0 + }, + velocity: { + x: 0, + y: -0.01, + z: 0 + }, + shapeType: "box", + collisionsWillMove: true, + userData: JSON.stringify({ resetMe: { resetMe: true, }, grabbableKey: { - grabbable: false + invertSolidWhileHeld: true } - }) - }); - } + } + }) +}; +var dice1 = Entities.addEntity(diceProps); - function createPingPongBallGun() { - var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx'; - var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun_collision_hull.obj'; +diceProps.position = { + x: 541.05, + y: 494.96, + z: 509.0 +}; - var position = { - x: 548.6, - y: 495.4, - z: 503.39 - }; +var dice2 = Entities.addEntity(diceProps); - var rotation = Quat.fromPitchYawRollDegrees(0, 36, 0); +} - var pingPongGun = Entities.addEntity({ + +function createGates() { + var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/ryan/fence.fbx'; + + var rotation = Quat.fromPitchYawRollDegrees(0, -16, 0); + var gate = Entities.addEntity({ + name: 'Front Door Fence', + type: 'Model', + modelURL: MODEL_URL, + shapeType: 'box', + position: { + x: 531.15, + y: 495.11, + z: 520.20 + }, + dimensions: { + x: 1.42, + y: 1.13, + z: 0.2 + }, + rotation: rotation, + collisionsWillMove: true, + gravity: { + x: 0, + y: -100, + z: 0 + }, + linearDamping: 1, + angularDamping: 10, + mass: 10, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + }, + grabbableKey: { + grabbable: false + } + }) + }); +} + +function createPingPongBallGun() { + var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx'; + var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun_collision_hull.obj'; + + var position = { + x: 548.6, + y: 495.4, + z: 503.39 + }; + + var rotation = Quat.fromPitchYawRollDegrees(0, 36, 0); + + var pingPongGun = Entities.addEntity({ type: "Model", modelURL: MODEL_URL, shapeType: 'box', @@ -917,57 +941,61 @@ MasterReset = function() { }, collisionsWillMove: true, userData: JSON.stringify({ - resetMe: { - resetMe: true, + resetMe: { + resetMe: true, + }, + grabbableKey: { + invertSolidWhileHeld: true + } } }) - }); - } + }); +} - function createBasketballHoop() { - var position = { - x: 539.23, - y: 496.13, - z: 475.89 - }; - var rotation = Quat.fromPitchYawRollDegrees(0, 58.49, 0); +function createBasketballHoop() { + var position = { + x: 539.23, + y: 496.13, + z: 475.89 + }; + var rotation = Quat.fromPitchYawRollDegrees(0, 58.49, 0); - var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop.fbx"; - var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop_collision_hull.obj"; + var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop.fbx"; + var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop_collision_hull.obj"; - var hoop = Entities.addEntity({ - type: "Model", - modelURL: hoopURL, - position: position, - rotation: rotation, - shapeType: 'compound', - gravity: { - x: 0, - y: -9.8, - z: 0 + var hoop = Entities.addEntity({ + type: "Model", + modelURL: hoopURL, + position: position, + rotation: rotation, + shapeType: 'compound', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + dimensions: { + x: 1.89, + y: 3.99, + z: 3.79 + }, + compoundShapeURL: hoopCollisionHullURL, + userData: JSON.stringify({ + resetMe: { + resetMe: true, }, - dimensions: { - x: 1.89, - y: 3.99, - z: 3.79 - }, - compoundShapeURL: hoopCollisionHullURL, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - }, - grabbableKey: { - grabbable: false - } - }) - }); - } + grabbableKey: { + grabbable: false + } + }) + }); +} - function createWand(position) { - var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; - var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/actual_no_top_collision_hull.obj'; +function createWand(position) { + var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; + var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/actual_no_top_collision_hull.obj'; - var entity = Entities.addEntity({ + var entity = Entities.addEntity({ name: 'Bubble Wand', type: "Model", modelURL: WAND_MODEL, @@ -991,20 +1019,24 @@ MasterReset = function() { // velocity: {x: 0, y: -0.01, z:0}, script: wandScriptURL, userData: JSON.stringify({ - resetMe: { - resetMe: true, + resetMe: { + resetMe: true, + }, + grabbableKey: { + invertSolidWhileHeld: true + } } }) - }); + }); - } +} - function createBasketBall(position) { +function createBasketBall(position) { - var modelURL = "http://s3.amazonaws.com/hifi-public/models/content/basketball2.fbx"; + var modelURL = "http://s3.amazonaws.com/hifi-public/models/content/basketball2.fbx"; - var entity = Entities.addEntity({ + var entity = Entities.addEntity({ type: "Model", modelURL: modelURL, position: position, @@ -1030,24 +1062,28 @@ MasterReset = function() { }, collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav", userData: JSON.stringify({ - resetMe: { - resetMe: true, + resetMe: { + resetMe: true, + }, + grabbableKey: { + invertSolidWhileHeld: true + } } }) - }); + }); - } +} - function createDoll(position) { - var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; +function createDoll(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; - var naturalDimensions = { - x: 1.63, - y: 1.67, - z: 0.26 - }; - var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); - var entity = Entities.addEntity({ + var naturalDimensions = { + x: 1.63, + y: 1.67, + z: 0.26 + }; + var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); + var entity = Entities.addEntity({ type: "Model", name: "doll", modelURL: modelURL, @@ -1067,19 +1103,23 @@ MasterReset = function() { }, collisionsWillMove: true, userData: JSON.stringify({ - resetMe: { - resetMe: true, + resetMe: { + resetMe: true, + }, + grabbableKey: { + invertSolidWhileHeld: true + } } }) - }); + }); - } +} - function createSprayCan(position) { +function createSprayCan(position) { - var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; + var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; - var entity = Entities.addEntity({ + var entity = Entities.addEntity({ type: "Model", name: "spraycan", script: sprayPaintScriptURL, @@ -1103,182 +1143,186 @@ MasterReset = function() { z: 0 }, userData: JSON.stringify({ - resetMe: { - resetMe: true, - } - }) - }); - - } - - function createPottedPlant(position) { - var modelURL = "http://hifi-public.s3.amazonaws.com/models/potted_plant/potted_plant.fbx"; - - var entity = Entities.addEntity({ - type: "Model", - name: "Potted Plant", - modelURL: modelURL, - position: position, - dimensions: { - x: 1.10, - y: 2.18, - z: 1.07 - }, - collisionsWillMove: true, - shapeType: 'box', - gravity: { - x: 0, - y: -9.8, - z: 0 - }, - velocity: { - x: 0, - y: 0, - z: 0 - }, - linearDamping: 0.4, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - }, - grabbableKey: { - grabbable: false - } - }) - }); - } - - - function createCombinedArmChair(position) { - var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/combined_chair.fbx"; - var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj"; - - var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); - - var entity = Entities.addEntity({ - type: "Model", - name: "Red Arm Chair", - modelURL: modelURL, - shapeType: 'compound', - compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL, - position: position, - rotation: rotation, - dimensions: { - x: 1.26, - y: 1.56, - z: 1.35 - }, - collisionsWillMove: true, - gravity: { - x: 0, - y: -0.8, - z: 0 - }, - velocity: { - x: 0, - y: 0, - z: 0 - }, - linearDamping: 0.2, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - }, - grabbableKey: { - grabbable: false - } - }) - }); - - } - - function createBlocks(position) { - var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/"; - var collisionSoundURL = "https://hifi-public.s3.amazonaws.com/sounds/Collisions-otherorganic/ToyWoodBlock.L.wav"; - var NUM_BLOCKS_PER_COLOR = 4; - var i, j; - - var blockTypes = [{ - url: "planky_blue.fbx", - dimensions: { - x: 0.05, - y: 0.05, - z: 0.25 - } - }, { - url: "planky_green.fbx", - dimensions: { - x: 0.1, - y: 0.1, - z: 0.25 - } - }, { - url: "planky_natural.fbx", - dimensions: { - x: 0.05, - y: 0.05, - z: 0.05 - } - }, { - url: "planky_yellow.fbx", - dimensions: { - x: 0.03, - y: 0.05, - z: 0.25 - } - }, { - url: "planky_red.fbx", - dimensions: { - x: 0.1, - y: 0.05, - z: 0.25 - } - }, ]; - - var modelURL, entity; - for (i = 0; i < blockTypes.length; i++) { - for (j = 0; j < NUM_BLOCKS_PER_COLOR; j++) { - modelURL = baseURL + blockTypes[i].url; - entity = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - position: Vec3.sum(position, { - x: j / 10, - y: i / 10, - z: 0 - }), - shapeType: 'box', - name: "block", - dimensions: blockTypes[i].dimensions, - collisionsWillMove: true, - collisionSoundURL: collisionSoundURL, - gravity: { - x: 0, - y: -2.5, - z: 0 + resetMe: { + resetMe: true, }, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, - userData: JSON.stringify({ - resetMe: { - resetMe: true, - } - }) - }); + grabbableKey: { + invertSolidWhileHeld: true + } + } + }) + }); +} + +function createPottedPlant(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/potted_plant/potted_plant.fbx"; + + var entity = Entities.addEntity({ + type: "Model", + name: "Potted Plant", + modelURL: modelURL, + position: position, + dimensions: { + x: 1.10, + y: 2.18, + z: 1.07 + }, + collisionsWillMove: true, + shapeType: 'box', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + velocity: { + x: 0, + y: 0, + z: 0 + }, + linearDamping: 0.4, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + }, + grabbableKey: { + grabbable: false } + }) + }); +} + + +function createCombinedArmChair(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/combined_chair.fbx"; + var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj"; + + var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); + + var entity = Entities.addEntity({ + type: "Model", + name: "Red Arm Chair", + modelURL: modelURL, + shapeType: 'compound', + compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL, + position: position, + rotation: rotation, + dimensions: { + x: 1.26, + y: 1.56, + z: 1.35 + }, + collisionsWillMove: true, + gravity: { + x: 0, + y: -0.8, + z: 0 + }, + velocity: { + x: 0, + y: 0, + z: 0 + }, + linearDamping: 0.2, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + }, + grabbableKey: { + grabbable: false + } + }) + }); + +} + +function createBlocks(position) { + var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/"; + var collisionSoundURL = "https://hifi-public.s3.amazonaws.com/sounds/Collisions-otherorganic/ToyWoodBlock.L.wav"; + var NUM_BLOCKS_PER_COLOR = 4; + var i, j; + + var blockTypes = [{ + url: "planky_blue.fbx", + dimensions: { + x: 0.05, + y: 0.05, + z: 0.25 + } + }, { + url: "planky_green.fbx", + dimensions: { + x: 0.1, + y: 0.1, + z: 0.25 + } + }, { + url: "planky_natural.fbx", + dimensions: { + x: 0.05, + y: 0.05, + z: 0.05 + } + }, { + url: "planky_yellow.fbx", + dimensions: { + x: 0.03, + y: 0.05, + z: 0.25 + } + }, { + url: "planky_red.fbx", + dimensions: { + x: 0.1, + y: 0.05, + z: 0.25 + } + }, ]; + + var modelURL, entity; + for (i = 0; i < blockTypes.length; i++) { + for (j = 0; j < NUM_BLOCKS_PER_COLOR; j++) { + modelURL = baseURL + blockTypes[i].url; + entity = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + position: Vec3.sum(position, { + x: j / 10, + y: i / 10, + z: 0 + }), + shapeType: 'box', + name: "block", + dimensions: blockTypes[i].dimensions, + collisionsWillMove: true, + collisionSoundURL: collisionSoundURL, + gravity: { + x: 0, + y: -2.5, + z: 0 + }, + velocity: { + x: 0, + y: -0.01, + z: 0 + }, + userData: JSON.stringify({ + resetMe: { + resetMe: true, + } + }) + }); + } } +} - function cleanup() { - deleteAllToys(); - } +function cleanup() { + deleteAllToys(); +} - if (shouldDeleteOnEndScript) { +if (shouldDeleteOnEndScript) { - Script.scriptEnding.connect(cleanup); - } + Script.scriptEnding.connect(cleanup); +} }; \ No newline at end of file From c84d2fc36a29ab8ad3fe5163fb9453329445b6f5 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 13 Oct 2015 10:44:43 -0700 Subject: [PATCH 45/49] fix target script url --- unpublishedScripts/hiddenEntityReset.js | 2 +- unpublishedScripts/masterReset.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index 1b3dd07e5e..13e5f89914 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -498,7 +498,7 @@ compoundShapeURL: COLLISION_HULL_URL, position: originalPositions[index], rotation: rotation, - script: scriptURL, + script: targetsScriptURL, userData: JSON.stringify({ resetMe: { resetMe: true diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 5eaa35372f..f855caa9a1 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -469,7 +469,7 @@ MasterReset = function() { compoundShapeURL: COLLISION_HULL_URL, position: originalPositions[index], rotation: rotation, - script: scriptURL, + script: targetsScriptURL, userData: JSON.stringify({ resetMe: { resetMe: true From 93e908a592093671fbd6c1e19c97c2a58a5e54f6 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 13 Oct 2015 12:15:13 -0700 Subject: [PATCH 46/49] Don't reload/recenter some avatar data on startup, when we don't necessarilly have all the required data initialized. --- interface/src/Application.cpp | 6 +-- interface/src/Application.h | 2 +- interface/src/PluginContainerProxy.cpp | 2 +- interface/src/avatar/MyAvatar.cpp | 62 ++++++++++++++------------ interface/src/avatar/MyAvatar.h | 2 +- 5 files changed, 40 insertions(+), 34 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 30014f8906..aad480edde 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1559,7 +1559,7 @@ void Application::keyPressEvent(QKeyEvent* event) { cursor->setIcon(Cursor::Icon::DEFAULT); } } else { - resetSensors(); + resetSensors(true); } break; } @@ -3591,7 +3591,7 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi renderArgs->_viewport = originalViewport; } -void Application::resetSensors() { +void Application::resetSensors(bool andReload) { DependencyManager::get()->reset(); DependencyManager::get()->reset(); DependencyManager::get()->reset(); @@ -3603,7 +3603,7 @@ void Application::resetSensors() { QPoint windowCenter = mainWindow->geometry().center(); _glWidget->cursor().setPos(currentScreen, windowCenter); - getMyAvatar()->reset(); + getMyAvatar()->reset(andReload); QMetaObject::invokeMethod(DependencyManager::get().data(), "reset", Qt::QueuedConnection); } diff --git a/interface/src/Application.h b/interface/src/Application.h index a2125e7e09..dc714ad82a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -274,7 +274,7 @@ public slots: void setRawAvatarUpdateThreading(); void setRawAvatarUpdateThreading(bool isThreaded); - void resetSensors(); + void resetSensors(bool andReload = false); void setActiveFaceTracker(); #ifdef HAVE_IVIEWHMD diff --git a/interface/src/PluginContainerProxy.cpp b/interface/src/PluginContainerProxy.cpp index 19bb6ab8de..079d6d0bea 100644 --- a/interface/src/PluginContainerProxy.cpp +++ b/interface/src/PluginContainerProxy.cpp @@ -144,7 +144,7 @@ void PluginContainerProxy::unsetFullscreen(const QScreen* avoid) { void PluginContainerProxy::requestReset() { // We could signal qApp to sequence this, but it turns out that requestReset is only used from within the main thread anyway. - qApp->resetSensors(); + qApp->resetSensors(true); } void PluginContainerProxy::showDisplayPluginsTools() { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 605a81e9d9..f5c3acd386 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -140,16 +140,18 @@ QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) { return AvatarData::toByteArray(cullSmallChanges, sendAll); } -void MyAvatar::reset() { +void MyAvatar::reset(bool andReload) { // Gather animation mode... // This should be simpler when we have only graph animations always on. bool isRig = _rig->getEnableRig(); // seting rig animation to true, below, will clear the graph animation menu item, so grab it now. bool isGraph = _rig->getEnableAnimGraph() || Menu::getInstance()->isOptionChecked(MenuOption::EnableAnimGraph); // ... and get to sane configuration where other activity won't bother us. - qApp->setRawAvatarUpdateThreading(false); - _rig->disableHands = true; - setEnableRigAnimations(true); + if (andReload) { + qApp->setRawAvatarUpdateThreading(false); + _rig->disableHands = true; + setEnableRigAnimations(true); + } // Reset dynamic state. _wasPushing = _isPushing = _isBraking = _billboardValid = _straighteningLean = false; @@ -158,32 +160,34 @@ void MyAvatar::reset() { _targetVelocity = glm::vec3(0.0f); setThrust(glm::vec3(0.0f)); - // Get fresh data, in case we're really slow and out of wack. - _hmdSensorMatrix = qApp->getHMDSensorPose(); - _hmdSensorPosition = extractTranslation(_hmdSensorMatrix); - _hmdSensorOrientation = glm::quat_cast(_hmdSensorMatrix); + if (andReload) { + // Get fresh data, in case we're really slow and out of wack. + _hmdSensorMatrix = qApp->getHMDSensorPose(); + _hmdSensorPosition = extractTranslation(_hmdSensorMatrix); + _hmdSensorOrientation = glm::quat_cast(_hmdSensorMatrix); - // Reset body position/orientation under the head. - auto newBodySensorMatrix = deriveBodyFromHMDSensor(); // Based on current cached HMD position/rotation.. - auto worldBodyMatrix = _sensorToWorldMatrix * newBodySensorMatrix; - glm::vec3 worldBodyPos = extractTranslation(worldBodyMatrix); - glm::quat worldBodyRot = glm::normalize(glm::quat_cast(worldBodyMatrix)); + // Reset body position/orientation under the head. + auto newBodySensorMatrix = deriveBodyFromHMDSensor(); // Based on current cached HMD position/rotation.. + auto worldBodyMatrix = _sensorToWorldMatrix * newBodySensorMatrix; + glm::vec3 worldBodyPos = extractTranslation(worldBodyMatrix); + glm::quat worldBodyRot = glm::normalize(glm::quat_cast(worldBodyMatrix)); - // FIXME: Hack to retain the previous behavior wrt height. - // I'd like to make the body match head height, but that will have to wait for separate PR. - worldBodyPos.y = getPosition().y; + // FIXME: Hack to retain the previous behavior wrt height. + // I'd like to make the body match head height, but that will have to wait for separate PR. + worldBodyPos.y = getPosition().y; - setPosition(worldBodyPos); - setOrientation(worldBodyRot); - // If there is any discrepency between positioning and the head (as there is in initial deriveBodyFromHMDSensor), - // we can make that right by setting _bodySensorMatrix = newBodySensorMatrix. - // However, doing so will make the head want to point to the previous body orientation, as cached above. - //_bodySensorMatrix = newBodySensorMatrix; - //updateSensorToWorldMatrix(); // Uses updated position/orientation and _bodySensorMatrix changes + setPosition(worldBodyPos); + setOrientation(worldBodyRot); + // If there is any discrepency between positioning and the head (as there is in initial deriveBodyFromHMDSensor), + // we can make that right by setting _bodySensorMatrix = newBodySensorMatrix. + // However, doing so will make the head want to point to the previous body orientation, as cached above. + //_bodySensorMatrix = newBodySensorMatrix; + //updateSensorToWorldMatrix(); // Uses updated position/orientation and _bodySensorMatrix changes - _skeletonModel.simulate(0.1f); // non-zero - setEnableRigAnimations(false); - _skeletonModel.simulate(0.1f); + _skeletonModel.simulate(0.1f); // non-zero + setEnableRigAnimations(false); + _skeletonModel.simulate(0.1f); + } if (isRig) { setEnableRigAnimations(true); Menu::getInstance()->setIsOptionChecked(MenuOption::EnableRigAnimations, true); @@ -191,8 +195,10 @@ void MyAvatar::reset() { setEnableAnimGraph(true); Menu::getInstance()->setIsOptionChecked(MenuOption::EnableAnimGraph, true); } - _rig->disableHands = false; - qApp->setRawAvatarUpdateThreading(); + if (andReload) { + _rig->disableHands = false; + qApp->setRawAvatarUpdateThreading(); + } } void MyAvatar::update(float deltaTime) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index cca0c4152f..02c9f53082 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -58,7 +58,7 @@ public: AudioListenerMode getAudioListenerModeCamera() const { return FROM_CAMERA; } AudioListenerMode getAudioListenerModeCustom() const { return CUSTOM; } - void reset(); + void reset(bool andReload = false); void update(float deltaTime); void preRender(RenderArgs* renderArgs); From ad96d7692191bd959f7760cb6b740d8f19d26493 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 13 Oct 2015 15:06:11 -0700 Subject: [PATCH 47/49] implement comfort mode hack --- interface/src/Menu.cpp | 1 + interface/src/Menu.h | 1 + interface/src/avatar/MyAvatar.cpp | 79 ++++++++++++++++++++++--------- 3 files changed, 59 insertions(+), 22 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index ae41ca2493..3d671b0447 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -461,6 +461,7 @@ Menu::Menu() { 0, false, &ConnexionClient::getInstance(), SLOT(toggleConnexion(bool))); + addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ComfortMode, 0, true); MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands"); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 4c9c3ef7b5..216a410603 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -159,6 +159,7 @@ namespace MenuOption { const QString CenterPlayerInView = "Center Player In View"; const QString Chat = "Chat..."; const QString Collisions = "Collisions"; + const QString ComfortMode = "Comfort Mode"; const QString Connexion = "Activate 3D Connexion Devices"; const QString Console = "Console..."; const QString ControlWithSpeech = "Control With Speech"; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 605a81e9d9..55690c98f1 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1514,33 +1514,68 @@ bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const { void MyAvatar::updateOrientation(float deltaTime) { // Smoothly rotate body with arrow keys - float targetSpeed = (_driveKeys[ROT_LEFT] - _driveKeys[ROT_RIGHT]) * YAW_SPEED; - if (targetSpeed != 0.0f) { - const float ROTATION_RAMP_TIMESCALE = 0.1f; - float blend = deltaTime / ROTATION_RAMP_TIMESCALE; - if (blend > 1.0f) { - blend = 1.0f; - } - _bodyYawDelta = (1.0f - blend) * _bodyYawDelta + blend * targetSpeed; - } else if (_bodyYawDelta != 0.0f) { - // attenuate body rotation speed - const float ROTATION_DECAY_TIMESCALE = 0.05f; - float attenuation = 1.0f - deltaTime / ROTATION_DECAY_TIMESCALE; - if (attenuation < 0.0f) { - attenuation = 0.0f; - } - _bodyYawDelta *= attenuation; + float targetSpeed = 0.0f; + + // FIXME - this comfort mode code is a total hack, remove it when we have new input mapping + bool isComfortMode = Menu::getInstance()->isOptionChecked(MenuOption::ComfortMode); + bool isHMDMode = qApp->getAvatarUpdater()->isHMDMode(); + + if (!isHMDMode || !isComfortMode) { + targetSpeed = (_driveKeys[ROT_LEFT] - _driveKeys[ROT_RIGHT]) * YAW_SPEED; + + if (targetSpeed != 0.0f) { + const float ROTATION_RAMP_TIMESCALE = 0.1f; + float blend = deltaTime / ROTATION_RAMP_TIMESCALE; + if (blend > 1.0f) { + blend = 1.0f; + } + _bodyYawDelta = (1.0f - blend) * _bodyYawDelta + blend * targetSpeed; + } + else if (_bodyYawDelta != 0.0f) { + // attenuate body rotation speed + const float ROTATION_DECAY_TIMESCALE = 0.05f; + float attenuation = 1.0f - deltaTime / ROTATION_DECAY_TIMESCALE; + if (attenuation < 0.0f) { + attenuation = 0.0f; + } + _bodyYawDelta *= attenuation; + + float MINIMUM_ROTATION_RATE = 2.0f; + if (fabsf(_bodyYawDelta) < MINIMUM_ROTATION_RATE) { + _bodyYawDelta = 0.0f; + } + } + + // update body orientation by movement inputs + setOrientation(getOrientation() * + glm::quat(glm::radians(glm::vec3(0.0f, _bodyYawDelta * deltaTime, 0.0f)))); + + } else { + // comfort mode.... + _bodyYawDelta = 0.0f; + + static quint64 lastPulse = 0; + quint64 now = usecTimestampNow(); + quint64 COMFORT_MODE_PULSE_TIMING = USECS_PER_SECOND / 2; // turn once per second + + float driveLeft = _driveKeys[ROT_LEFT]; + float driveRight= _driveKeys[ROT_RIGHT]; + + if ((driveLeft != 0.0f || driveRight != 0.0f) && (now - lastPulse > COMFORT_MODE_PULSE_TIMING)) { + lastPulse = now; + + const float SNAP_TURN_DELTA = 15.0f; // degrees + float direction = (driveLeft - driveRight) < 0.0f ? -1.0f : 1.0f; + float turnAmount = direction * SNAP_TURN_DELTA; + + // update body orientation by movement inputs + setOrientation(getOrientation() * + glm::quat(glm::radians(glm::vec3(0.0f, turnAmount, 0.0f)))); - float MINIMUM_ROTATION_RATE = 2.0f; - if (fabsf(_bodyYawDelta) < MINIMUM_ROTATION_RATE) { - _bodyYawDelta = 0.0f; } } getHead()->setBasePitch(getHead()->getBasePitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime); - // update body orientation by movement inputs - setOrientation(getOrientation() * - glm::quat(glm::radians(glm::vec3(0.0f, _bodyYawDelta * deltaTime, 0.0f)))); if (qApp->getAvatarUpdater()->isHMDMode()) { glm::quat orientation = glm::quat_cast(getSensorToWorldMatrix()) * getHMDSensorOrientation(); From c468cabe7e75cc7322f2fff42c83686e3d18d5cb Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 13 Oct 2015 15:12:01 -0700 Subject: [PATCH 48/49] Fix crash when atp url is empty --- libraries/networking/src/AssetResourceRequest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index ecbe80cddb..eba9e45e5c 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -24,7 +24,7 @@ void AssetResourceRequest::doSend() { // Make request to atp auto assetClient = DependencyManager::get(); auto parts = _url.path().split(".", QString::SkipEmptyParts); - auto hash = parts[0]; + auto hash = parts.length() > 0 ? parts[0] : ""; auto extension = parts.length() > 1 ? parts[1] : ""; if (hash.length() != SHA256_HASH_HEX_LENGTH) { From 8a2e23cae4909057bb1bf2c7c9505b704dcaebe6 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 13 Oct 2015 16:20:52 -0700 Subject: [PATCH 49/49] CR feedback --- interface/src/avatar/MyAvatar.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 55690c98f1..aa579b670f 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1530,8 +1530,7 @@ void MyAvatar::updateOrientation(float deltaTime) { blend = 1.0f; } _bodyYawDelta = (1.0f - blend) * _bodyYawDelta + blend * targetSpeed; - } - else if (_bodyYawDelta != 0.0f) { + } else if (_bodyYawDelta != 0.0f) { // attenuate body rotation speed const float ROTATION_DECAY_TIMESCALE = 0.05f; float attenuation = 1.0f - deltaTime / ROTATION_DECAY_TIMESCALE; @@ -1551,12 +1550,14 @@ void MyAvatar::updateOrientation(float deltaTime) { glm::quat(glm::radians(glm::vec3(0.0f, _bodyYawDelta * deltaTime, 0.0f)))); } else { - // comfort mode.... + // Comfort Mode: If you press any of the left/right rotation drive keys or input, you'll + // get an instantaneous 15 degree turn. If you keep holding the key down you'll get another + // snap turn every half second. _bodyYawDelta = 0.0f; static quint64 lastPulse = 0; quint64 now = usecTimestampNow(); - quint64 COMFORT_MODE_PULSE_TIMING = USECS_PER_SECOND / 2; // turn once per second + quint64 COMFORT_MODE_PULSE_TIMING = USECS_PER_SECOND / 2; // turn once per half second float driveLeft = _driveKeys[ROT_LEFT]; float driveRight= _driveKeys[ROT_RIGHT];