diff --git a/CMakeLists.txt b/CMakeLists.txt index 79d8a0c0e0..efe99b550b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -185,22 +185,8 @@ set(EXTERNAL_PROJECT_PREFIX "project") set_property(DIRECTORY PROPERTY EP_PREFIX ${EXTERNAL_PROJECT_PREFIX}) setup_externals_binary_dir() -# setup options to grab external project dependencies -option(GET_BULLET "Get Bullet library automatically as external project" 1) -option(GET_GLM "Get GLM library automatically as external project" 1) -option(GET_GVERB "Get Gverb library automatically as external project" 1) -option(GET_TBB "Get Threading Building Blocks library automatically as external project" 1) -option(GET_LIBOVR "Get LibOVR library automatically as external project" 1) -option(GET_VHACD "Get V-HACD library automatically as external project" 1) -option(GET_POLYVOX "Get polyvox library automatically as external project" 1) -option(GET_OPENVR "Get OpenVR library automatically as external project" 1) -option(GET_BOOSTCONFIG "Get Boost-config library automatically as external project" 1) -option(GET_OGLPLUS "Get OGLplus library automatically as external project" 1) -option(GET_GLEW "Get GLEW library automatically as external project" 1) - option(USE_NSIGHT "Attempt to find the nSight libraries" 1) -option(GET_SDL2 "Get SDL2 library automatically as external project" 0) if (WIN32) add_paths_to_fixup_libs("${QT_DIR}/bin") diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 833b53b729..0a455891f9 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -254,10 +254,10 @@ void AvatarMixer::broadcastAvatarData() { // potentially update the max full rate distance for this frame maxAvatarDistanceThisFrame = std::max(maxAvatarDistanceThisFrame, distanceToAvatar); - if (distanceToAvatar != 0.0f + if (distanceToAvatar != 0.0f && distribution(generator) > (nodeData->getFullRateDistance() / distanceToAvatar)) { - return; - } + return; + } AvatarDataSequenceNumber lastSeqToReceiver = nodeData->getLastBroadcastSequenceNumber(otherNode->getUUID()); AvatarDataSequenceNumber lastSeqFromSender = otherNodeData->getLastReceivedSequenceNumber(); diff --git a/cmake/externals/faceshift/CMakeLists.txt b/cmake/externals/faceshift/CMakeLists.txt new file mode 100644 index 0000000000..b18b861912 --- /dev/null +++ b/cmake/externals/faceshift/CMakeLists.txt @@ -0,0 +1,30 @@ +set(EXTERNAL_NAME faceshift) + +include(ExternalProject) +ExternalProject_Add( + ${EXTERNAL_NAME} + URL https://hifi-public.s3.amazonaws.com/dependencies/faceshift.zip + CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH= + BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 +) + +# URL_MD5 1bdcb8a0b8d5b1ede434cc41efade41d + +# Hide this external target (for ide users) +set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") + +ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) + +string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) +set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/include CACHE FILEPATH "Path to Faceshift include directory") + +if (WIN32) + set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/Debug/faceshift.lib CACHE FILEPATH "Faceshift libraries") + set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/Release/faceshift.lib CACHE FILEPATH "Faceshift libraries") +elseif (APPLE) + set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/Debug/libfaceshift.a CACHE FILEPATH "Faceshift libraries") + set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/Release/libfaceshift.a CACHE FILEPATH "Faceshift libraries") +endif() diff --git a/cmake/externals/sdl2/CMakeLists.txt b/cmake/externals/sdl2/CMakeLists.txt index e6c80cf6ef..0f44f28610 100644 --- a/cmake/externals/sdl2/CMakeLists.txt +++ b/cmake/externals/sdl2/CMakeLists.txt @@ -47,25 +47,13 @@ if (APPLE) ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIR ${SOURCE_DIR}/SDL2.framework/Headers CACHE PATH "Location of SDL2 include directory") set(${EXTERNAL_NAME_UPPER}_LIBRARY_TEMP ${SOURCE_DIR}/SDL2.framework/SDL2 CACHE STRING "Path to SDL2 library") +elseif (WIN32) + ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) + set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIR ${SOURCE_DIR}/include CACHE PATH "Location of SDL2 include directory") + set(${EXTERNAL_NAME_UPPER}_LIBRARY_TEMP ${SOURCE_DIR}/lib/x86/SDL2.lib CACHE FILEPATH "Path to SDL2 library") + set(${EXTERNAL_NAME_UPPER}_DLL_PATH ${SOURCE_DIR}/lib/x86 CACHE PATH "Location of SDL2 DLL") else () - if (WIN32) - ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) - set(_ROOT_DIR ${SOURCE_DIR}) - set(_INCLUDE_DIR ${_ROOT_DIR}/include) - set(_LIB_DIR "${SOURCE_DIR}/lib/x86") - set(_LIB_EXT "lib") - - set(${EXTERNAL_NAME_UPPER}_DLL_PATH ${_LIB_DIR} CACHE PATH "Location of SDL2 DLL") - else () - ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) - set(_ROOT_DIR ${INSTALL_DIR}) - set(_INCLUDE_DIR ${_ROOT_DIR}/include/SDL2) - - set(_LIB_DIR ${INSTALL_DIR}/lib) - set(_LIB_EXT "so") - set(_LIB_PREFIX "lib") - endif () - - set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIR ${_INCLUDE_DIR} CACHE PATH "Location of SDL2 include directory") - set(${EXTERNAL_NAME_UPPER}_LIBRARY_TEMP ${_LIB_DIR}/${_LIB_PREFIX}SDL2.${_LIB_EXT} CACHE FILEPATH "Path to SDL2 library") -endif () \ No newline at end of file + ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) + set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIR ${INSTALL_DIR}/include/SDL2 CACHE PATH "Location of SDL2 include directory") + set(${EXTERNAL_NAME_UPPER}_LIBRARY_TEMP ${INSTALL_DIR}/lib/libSDL2.so CACHE FILEPATH "Path to SDL2 library") +endif () diff --git a/cmake/externals/sixense/CMakeLists.txt b/cmake/externals/sixense/CMakeLists.txt index f6646e2272..72de4a7e15 100644 --- a/cmake/externals/sixense/CMakeLists.txt +++ b/cmake/externals/sixense/CMakeLists.txt @@ -1,30 +1,20 @@ include(ExternalProject) -include(SelectLibraryConfigurations) -set(EXTERNAL_NAME Sixense) +set(EXTERNAL_NAME sixense) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) ExternalProject_Add( ${EXTERNAL_NAME} - URL ./SixenseSDK_062612.zip - URL_MD5 10cc8dc470d2ac1244a88cf04bc549cc + URL http://hifi-public.s3.amazonaws.com/dependencies/SixenseSDK_071615.zip + URL_MD5 752a3901f334124e9cffc2ba4136ef7d CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" LOG_DOWNLOAD 1 ) -if (APPLE) - find_library(SIXENSE_LIBRARY_RELEASE lib/osx_x64/release_dll/libsixense_x64.dylib HINTS ${SIXENSE_SEARCH_DIRS}) - find_library(SIXENSE_LIBRARY_DEBUG lib/osx_x64/debug_dll/libsixensed_x64.dylib HINTS ${SIXENSE_SEARCH_DIRS}) -elseif (UNIX) - find_library(SIXENSE_LIBRARY_RELEASE lib/linux_x64/release/libsixense_x64.so HINTS ${SIXENSE_SEARCH_DIRS}) - # find_library(SIXENSE_LIBRARY_DEBUG lib/linux_x64/debug/libsixensed_x64.so HINTS ${SIXENSE_SEARCH_DIRS}) -elseif (WIN32) -endif () - - +set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) @@ -39,22 +29,18 @@ if (WIN32) set(ARCH_DIR "Win32") set(ARCH_SUFFIX "") endif() - - # FIXME need to account for different architectures - set(${EXTERNAL_NAME_UPPER}_LIBRARIES "${SOURCE_DIR}/lib/${ARCH_DIR}/release_dll/sixense${ARCH_SUFFIX}.lib" CACHE TYPE INTERNAL) - add_paths_to_fixup_libs(${SOURCE_DIR}/bin/win32) + + set(${EXTERNAL_NAME_UPPER}_LIBRARIES "${SOURCE_DIR}/lib/${ARCH_DIR}/VS2013/release_dll/sixense${ARCH_SUFFIX}.lib" CACHE TYPE INTERNAL) + add_paths_to_fixup_libs("${SOURCE_DIR}/bin/${ARCH_DIR}/VS2013/release_dll") elseif(APPLE) - # FIXME need to account for different architectures - set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/osx_x64/release_dll/libsixense_x64.dylib CACHE TYPE INTERNAL) - add_paths_to_fixup_libs(${SOURCE_DIR}/bin/osx32) + set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/osx_x64/release_dll/libsixense_x64.dylib CACHE TYPE INTERNAL) elseif(NOT ANDROID) - # FIXME need to account for different architectures - set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/linux_x64/release/libsixense_x64.so CACHE TYPE INTERNAL) - add_paths_to_fixup_libs(${SOURCE_DIR}/bin/linux32) - + # FIXME need to account for different architectures + set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/linux_x64/release/libsixense_x64.so CACHE TYPE INTERNAL) + endif() diff --git a/cmake/macros/AddDependencyExternalProjects.cmake b/cmake/macros/AddDependencyExternalProjects.cmake index e859ef2db5..e35ca98959 100644 --- a/cmake/macros/AddDependencyExternalProjects.cmake +++ b/cmake/macros/AddDependencyExternalProjects.cmake @@ -16,7 +16,7 @@ macro(ADD_DEPENDENCY_EXTERNAL_PROJECTS) string(TOUPPER ${_PROJ_NAME} _PROJ_NAME_UPPER) # has the user told us they specific don't want this as an external project? - if (GET_${_PROJ_NAME_UPPER}) + if (NOT USE_LOCAL_${_PROJ_NAME_UPPER}) # have we already detected we can't have this as external project on this OS? if (NOT DEFINED ${_PROJ_NAME_UPPER}_EXTERNAL_PROJECT OR ${_PROJ_NAME_UPPER}_EXTERNAL_PROJECT) # have we already setup the target? diff --git a/cmake/macros/TargetFaceshift.cmake b/cmake/macros/TargetFaceshift.cmake new file mode 100644 index 0000000000..99f65d942a --- /dev/null +++ b/cmake/macros/TargetFaceshift.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_FACESHIFT) + add_dependency_external_projects(faceshift) + find_package(Faceshift REQUIRED) + target_include_directories(${TARGET_NAME} PRIVATE ${FACESHIFT_INCLUDE_DIRS}) + target_link_libraries(${TARGET_NAME} ${FACESHIFT_LIBRARIES}) + add_definitions(-DHAVE_FACESHIFT) +endmacro() \ No newline at end of file diff --git a/cmake/macros/TargetSDL2.cmake b/cmake/macros/TargetSDL2.cmake new file mode 100644 index 0000000000..ee2328dfff --- /dev/null +++ b/cmake/macros/TargetSDL2.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_SDL2) + add_dependency_external_projects(sdl2) + find_package(SDL2 REQUIRED) + target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${SDL2_INCLUDE_DIR}) + target_link_libraries(${TARGET_NAME} ${SDL2_LIBRARY}) + add_definitions(-DHAVE_SDL2) +endmacro() \ No newline at end of file diff --git a/cmake/macros/TargetSixense.cmake b/cmake/macros/TargetSixense.cmake new file mode 100644 index 0000000000..b52af9cdd2 --- /dev/null +++ b/cmake/macros/TargetSixense.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_SIXENSE) + add_dependency_external_projects(sixense) + find_package(Sixense REQUIRED) + target_include_directories(${TARGET_NAME} PRIVATE ${SIXENSE_INCLUDE_DIRS}) + target_link_libraries(${TARGET_NAME} ${SIXENSE_LIBRARIES}) + add_definitions(-DHAVE_SIXENSE) +endmacro() \ No newline at end of file diff --git a/cmake/modules/FindFaceshift.cmake b/cmake/modules/FindFaceshift.cmake index 1f8b7b19fe..bd77951273 100644 --- a/cmake/modules/FindFaceshift.cmake +++ b/cmake/modules/FindFaceshift.cmake @@ -18,32 +18,9 @@ # See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html # -include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") -hifi_library_search_hints("faceshift") - -find_path(FACESHIFT_INCLUDE_DIRS fsbinarystream.h PATH_SUFFIXES include HINTS ${FACESHIFT_SEARCH_DIRS}) - -if (APPLE) - set(ARCH_DIR "MacOS") -elseif (UNIX) - set(ARCH_DIR "UNIX") -elseif (WIN32) - if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - set(ARCH_DIR "x64") - else() - set(ARCH_DIR "Win32") - endif() -endif () - -find_library(FACESHIFT_LIBRARY_RELEASE NAME faceshift PATH_SUFFIXES lib/${ARCH_DIR} HINTS ${FACESHIFT_SEARCH_DIRS}) -find_library(FACESHIFT_LIBRARY_DEBUG NAME faceshiftd PATH_SUFFIXES lib/${ARCH_DIR} HINTS ${FACESHIFT_SEARCH_DIRS}) - include(SelectLibraryConfigurations) select_library_configurations(FACESHIFT) -set(FACESHIFT_LIBRARIES ${FACESHIFT_LIBRARY}) - include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Faceshift DEFAULT_MSG FACESHIFT_INCLUDE_DIRS FACESHIFT_LIBRARIES) - mark_as_advanced(FACESHIFT_INCLUDE_DIRS FACESHIFT_LIBRARIES FACESHIFT_SEARCH_DIRS) \ No newline at end of file diff --git a/cmake/modules/FindSixense.cmake b/cmake/modules/FindSixense.cmake index 98b37d5410..9abacac136 100644 --- a/cmake/modules/FindSixense.cmake +++ b/cmake/modules/FindSixense.cmake @@ -18,49 +18,6 @@ # See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html # -include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") -hifi_library_search_hints("sixense") - -find_path(SIXENSE_INCLUDE_DIRS sixense.h PATH_SUFFIXES include HINTS ${SIXENSE_SEARCH_DIRS}) - -if (APPLE) - find_library(SIXENSE_LIBRARY_RELEASE lib/osx_x64/release_dll/libsixense_x64.dylib HINTS ${SIXENSE_SEARCH_DIRS}) - find_library(SIXENSE_LIBRARY_DEBUG lib/osx_x64/debug_dll/libsixensed_x64.dylib HINTS ${SIXENSE_SEARCH_DIRS}) -elseif (UNIX) - find_library(SIXENSE_LIBRARY_RELEASE lib/linux_x64/release/libsixense_x64.so HINTS ${SIXENSE_SEARCH_DIRS}) - # find_library(SIXENSE_LIBRARY_DEBUG lib/linux_x64/debug/libsixensed_x64.so HINTS ${SIXENSE_SEARCH_DIRS}) -elseif (WIN32) - if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - set(ARCH_DIR "x64") - set(ARCH_SUFFIX "_x64") - else() - set(ARCH_DIR "Win32") - set(ARCH_SUFFIX "") - endif() - - find_library(SIXENSE_LIBRARY_RELEASE "lib/${ARCH_DIR}/release_dll/sixense${ARCH_SUFFIX}.lib" HINTS ${SIXENSE_SEARCH_DIRS}) - find_library(SIXENSE_LIBRARY_DEBUG "lib/${ARCH_DIR}/debug_dll/sixensed.lib" HINTS ${SIXENSE_SEARCH_DIRS}) - - find_path(SIXENSE_DEBUG_DLL_PATH "sixensed${ARCH_SUFFIX}.dll" PATH_SUFFIXES bin/${ARCH_DIR}/debug_dll HINTS ${SIXENSE_SEARCH_DIRS}) - find_path(SIXENSE_RELEASE_DLL_PATH "sixense${ARCH_SUFFIX}.dll" PATH_SUFFIXES bin/${ARCH_DIR}/release_dll HINTS ${SIXENSE_SEARCH_DIRS}) - find_path(SIXENSE_DEVICE_DLL_PATH DeviceDLL.dll PATH_SUFFIXES samples/${ARCH_DIR}/sixense_simple3d HINTS ${SIXENSE_SEARCH_DIRS}) -endif () - -include(SelectLibraryConfigurations) -select_library_configurations(SIXENSE) - -set(SIXENSE_REQUIREMENTS SIXENSE_INCLUDE_DIRS SIXENSE_LIBRARIES) -if (WIN32) - list(APPEND SIXENSE_REQUIREMENTS SIXENSE_DEBUG_DLL_PATH SIXENSE_RELEASE_DLL_PATH SIXENSE_DEVICE_DLL_PATH) -endif () - -set(SIXENSE_LIBRARIES "${SIXENSE_LIBRARY}") - include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Sixense DEFAULT_MSG ${SIXENSE_REQUIREMENTS}) - -if (WIN32) - add_paths_to_fixup_libs(${SIXENSE_DEBUG_DLL_PATH} ${SIXENSE_RELEASE_DLL_PATH} ${SIXENSE_DEVICE_DLL_PATH}) -endif () - +find_package_handle_standard_args(Sixense DEFAULT_MSG SIXENSE_INCLUDE_DIRS SIXENSE_LIBRARIES) mark_as_advanced(SIXENSE_LIBRARIES SIXENSE_INCLUDE_DIRS SIXENSE_SEARCH_DIRS) diff --git a/examples/baseball/audio/assets.txt b/examples/baseball/audio/assets.txt new file mode 100644 index 0000000000..225714cbe1 --- /dev/null +++ b/examples/baseball/audio/assets.txt @@ -0,0 +1,23 @@ +crowd-boos.wav +atp:c632c92b166ade60aa16b23ff1dfdf712856caeb83bd9311980b2d5edac821af.wav + +crowd-cheers-organ.wav +atp:b8044401a846ed29f881a0b9b80cf1ba41f26327180c28fc9c70d144f9b70045.wav + +crowd-medium.wav +atp:0821bf2ac60dd2f356dfdd948e8bb89c23984dc3584612f6c815765154f02cae.wav + +baseball-hitting-bat-1.wav +atp:6f0b691a0c9c9ece6557d97fe242b1faec4020fe26efc9c17327993b513c5fe5.wav + +baseball-hitting-bat-set-1.wav +atp:5be5806205158ebdc5c3623ceb7ae73315028b51ffeae24292aff7042e3fa6a9.wav + +baseball-hitting-bat-set-2.wav +atp:e68661374e2145c480809c26134782aad11e0de456c7802170c7abccc4028873.wav + +baseball-hitting-bat-set-3.wav +atp:787e3c9af17dd3929527787176ede83d6806260e63ddd5a4cef48cd22e32c6f7.wav + +baseball-hitting-bat-set-4.wav +atp:fc65383431a6238c7a4749f0f6f061f75a604ed5e17d775ab1b2955609e67ebb.wav \ No newline at end of file diff --git a/examples/baseball/audio/attribution.txt b/examples/baseball/audio/attribution.txt new file mode 100644 index 0000000000..760951447c --- /dev/null +++ b/examples/baseball/audio/attribution.txt @@ -0,0 +1,8 @@ +Baseball bat hitting sounds +https://www.freesound.org/people/SocializedArtist45/sounds/266595/ +https://www.freesound.org/people/CGEffex/sounds/93136/ + +Crowd Sounds +http://freesound.org/people/AshFox/sounds/191925/ +http://freesound.org/people/AshFox/sounds/191928/ +http://freesound.org/people/AshFox/sounds/191929/ \ No newline at end of file diff --git a/examples/baseball/line.js b/examples/baseball/line.js new file mode 100644 index 0000000000..c4fac784c4 --- /dev/null +++ b/examples/baseball/line.js @@ -0,0 +1,165 @@ +function info(message) { + print("[INFO] " + message); +} + +function error(message) { + print("[ERROR] " + message); +} + + +/****************************************************************************** + * PolyLine + *****************************************************************************/ +var LINE_DIMENSIONS = { x: 2000, y: 2000, z: 2000 }; +var MAX_LINE_LENGTH = 40; // This must be 2 or greater; +var PolyLine = function(position, color, defaultStrokeWidth) { + //info("Creating polyline"); + //Vec3.print("New line at", position); + this.position = position; + this.color = color; + this.defaultStrokeWidth = 0.10; + this.points = [ + { x: 0, y: 0, z: 0 }, + ]; + this.strokeWidths = [ + this.defaultStrokeWidth, + ] + this.normals = [ + { x: 1, y: 0, z: 0 }, + ] + this.entityID = Entities.addEntity({ + type: "PolyLine", + position: position, + linePoints: this.points, + normals: this.normals, + strokeWidths: this.strokeWidths, + dimensions: LINE_DIMENSIONS, + color: color, + lifetime: 20, + }); +}; + +PolyLine.prototype.enqueuePoint = function(position) { + if (this.isFull()) { + error("Hit max PolyLine size"); + return; + } + + //Vec3.print("pos", position); + //info("Number of points: " + this.points.length); + + position = Vec3.subtract(position, this.position); + this.points.push(position); + this.normals.push({ x: 1, y: 0, z: 0 }); + this.strokeWidths.push(this.defaultStrokeWidth); + Entities.editEntity(this.entityID, { + linePoints: this.points, + normals: this.normals, + strokeWidths: this.strokeWidths, + }); +}; + +PolyLine.prototype.dequeuePoint = function() { + if (this.points.length == 0) { + error("Hit min PolyLine size"); + return; + } + + this.points = this.points.slice(1); + this.normals = this.normals.slice(1); + this.strokeWidths = this.strokeWidths.slice(1); + + Entities.editEntity(this.entityID, { + linePoints: this.points, + normals: this.normals, + strokeWidths: this.strokeWidths, + }); +}; + +PolyLine.prototype.getFirstPoint = function() { + return Vec3.sum(this.position, this.points[0]); +}; + +PolyLine.prototype.getLastPoint = function() { + return Vec3.sum(this.position, this.points[this.points.length - 1]); +}; + +PolyLine.prototype.getSize = function() { + return this.points.length; +} + +PolyLine.prototype.isFull = function() { + return this.points.length >= MAX_LINE_LENGTH; +}; + +PolyLine.prototype.destroy = function() { + Entities.deleteEntity(this.entityID); + this.points = []; +}; + + +/****************************************************************************** + * InfiniteLine + *****************************************************************************/ +InfiniteLine = function(position, color) { + this.position = position; + this.color = color; + this.lines = [new PolyLine(position, color)]; + this.size = 0; +}; + +InfiniteLine.prototype.enqueuePoint = function(position) { + var currentLine; + + if (this.lines.length == 0) { + currentLine = new PolyLine(position, this.color); + this.lines.push(currentLine); + } else { + currentLine = this.lines[this.lines.length - 1]; + } + + if (currentLine.isFull()) { + //info("Current line is full, creating new line"); + //Vec3.print("Last line is", currentLine.getLastPoint()); + //Vec3.print("New line is", position); + var newLine = new PolyLine(currentLine.getLastPoint(), this.color); + this.lines.push(newLine); + currentLine = newLine; + } + + currentLine.enqueuePoint(position); + + ++this.size; +}; + +InfiniteLine.prototype.dequeuePoint = function() { + if (this.lines.length == 0) { + error("Trying to dequeue from InfiniteLine when no points are left"); + return; + } + + var lastLine = this.lines[0]; + lastLine.dequeuePoint(); + + if (lastLine.getSize() <= 1) { + this.lines = this.lines.slice(1); + } + + --this.size; +}; + +InfiniteLine.prototype.getFirstPoint = function() { + return this.lines.length > 0 ? this.lines[0].getFirstPoint() : null; +}; + +InfiniteLine.prototype.getLastPoint = function() { + return this.lines.length > 0 ? this.lines[lines.length - 1].getLastPoint() : null; +}; + +InfiniteLine.prototype.destroy = function() { + for (var i = 0; i < this.lines.length; ++i) { + this.lines[i].destroy(); + } + + this.size = 0; +}; diff --git a/examples/baseball/pitching.js b/examples/baseball/pitching.js new file mode 100644 index 0000000000..5cb29ac5d7 --- /dev/null +++ b/examples/baseball/pitching.js @@ -0,0 +1,313 @@ +Script.include("line.js"); + +var AUDIO = { + crowdBoos: [ + SoundCache.getSound("atp:c632c92b166ade60aa16b23ff1dfdf712856caeb83bd9311980b2d5edac821af.wav", false) + ], + crowdCheers: [ + SoundCache.getSound("atp:0821bf2ac60dd2f356dfdd948e8bb89c23984dc3584612f6c815765154f02cae.wav", false), + SoundCache.getSound("atp:b8044401a846ed29f881a0b9b80cf1ba41f26327180c28fc9c70d144f9b70045.wav", false), + ], + batHit: [ + SoundCache.getSound("atp:6f0b691a0c9c9ece6557d97fe242b1faec4020fe26efc9c17327993b513c5fe5.wav", false), + SoundCache.getSound("atp:5be5806205158ebdc5c3623ceb7ae73315028b51ffeae24292aff7042e3fa6a9.wav", false), + SoundCache.getSound("atp:e68661374e2145c480809c26134782aad11e0de456c7802170c7abccc4028873.wav", false), + SoundCache.getSound("atp:787e3c9af17dd3929527787176ede83d6806260e63ddd5a4cef48cd22e32c6f7.wav", false), + SoundCache.getSound("atp:fc65383431a6238c7a4749f0f6f061f75a604ed5e17d775ab1b2955609e67ebb.wav", false), + ] +} + +var PITCH_THUNK_SOUND_URL = "http://hifi-public.s3.amazonaws.com/sounds/ping_pong_gun/pong_sound.wav"; +var pitchSound = SoundCache.getSound(PITCH_THUNK_SOUND_URL, false); + +var PITCHING_MACHINE_URL = "atp:87d4879530b698741ecc45f6f31789aac11f7865a2c3bec5fe9b061a182c80d4.fbx"; +var PITCHING_MACHINE_OUTPUT_OFFSET_PCT = { + x: 0.0, + y: 0.25, + z: -1.05, +}; +var PITCHING_MACHINE_PROPERTIES = { + name: "Pitching Machine", + type: "Model", + position: { + x: 0, + y: 0.8, + z: -18.3, + }, + velocity: { + x: 0, + y: -0.01, + z: 0 + }, + gravity: { + x: 0.0, + y: -9.8, + z: 0.0 + }, + registrationPoint: { + x: 0.5, + y: 0.5, + z: 0.5, + }, + rotation: Quat.fromPitchYawRollDegrees(0, 180, 0), + modelURL: PITCHING_MACHINE_URL, + dimensions: { + x: 0.4, + y: 0.61, + z: 0.39 + }, + collisionsWillMove: false, + shapeType: "Box", +}; +PITCHING_MACHINE_PROPERTIES.dimensions = Vec3.multiply(2.5, PITCHING_MACHINE_PROPERTIES.dimensions); +var DISTANCE_FROM_PLATE = PITCHING_MACHINE_PROPERTIES.position.z; + +var PITCH_RATE = 5000; + +var BASEBALL_MODEL_URL = "atp:7185099f1f650600ca187222573a88200aeb835454bd2f578f12c7fb4fd190fa.fbx"; +var BASEBALL_MIN_SPEED = 2.7; +var BASEBALL_MAX_SPEED = 5.7; +var BASEBALL_RADIUS = 0.07468; +var BASEBALL_PROPERTIES = { + name: "Baseball", + type: "Model", + modelURL: BASEBALL_MODEL_URL, + shapeType: "Sphere", + position: { + x: 0, + y: 0, + z: 0 + }, + dimensions: { + x: BASEBALL_RADIUS, + y: BASEBALL_RADIUS, + z: BASEBALL_RADIUS + }, + collisionsWillMove: true, + angularVelocity: { + x: 17.0, + y: 0, + z: -8.0, + + x: 0.0, + y: 0, + z: 0.0, + }, + angularDamping: 0.0, + damping: 0.0, + restitution: 0.5, + friction: 0.0, + lifetime: 20, + //collisionSoundURL: PITCH_THUNK_SOUND_URL, + gravity: { + x: 0, + y: 0,//-9.8, + z: 0 + } +}; + + +var pitchingMachineID = Entities.addEntity(PITCHING_MACHINE_PROPERTIES); + +var pitchFromPosition = { x: 0, y: 1.0, z: 0 }; +var pitchDirection = { x: 0, y: 0, z: 1 }; + +function shallowCopy(obj) { + var copy = {} + for (var key in obj) { + copy[key] = obj[key]; + } + return copy; +} + +function randomInt(low, high) { + return Math.floor(randomFloat(low, high)); +} + +function randomFloat(low, high) { + if (high === undefined) { + high = low; + low = 0; + } + return low + Math.random() * (high - low); +} + +var ACCELERATION_SPREAD = 10.15; + +function Baseball(position, velocity, ballScale) { + var self = this; + + // Setup entity properties + var properties = shallowCopy(BASEBALL_PROPERTIES); + properties.position = position; + properties.velocity = velocity; + /* + properties.gravity = { + x: randomInt(-ACCELERATION_SPREAD, ACCELERATION_SPREAD), + y: randomInt(-ACCELERATION_SPREAD, ACCELERATION_SPREAD), + z: 0.0, + }; + */ + properties.dimensions = Vec3.multiply(ballScale, properties.dimensions); + + // Create entity + this.entityID = Entities.addEntity(properties); + this.trail = null; + this.onHit = function() { return true; }; + this.hasBeenHit = false; + + this.boundCollisionCallback = function(a, b, c) { self.collisionCallback.call(self, a, b, c); }; + Script.addEventHandler(this.entityID, "collisionWithEntity", this.boundCollisionCallback); + /* + if (false && Math.random() < 0.5) { + for (var i = 0; i < 50; i++) { + Script.setTimeout(function() { + Entities.editEntity(entityID, { + gravity: { + x: randomInt(-ACCELERATION_SPREAD, ACCELERATION_SPREAD), + y: randomInt(-ACCELERATION_SPREAD, ACCELERATION_SPREAD), + z: 0.0, + } + }) + }, i * 100); + } + } + */ +} + +Baseball.prototype = { + collisionCallback: function(entityA, entityB, collision) { + var self = this; + + this.hasBeenHit = true; + var properties = Entities.getEntityProperties(this.entityID, ['position', 'velocity']); + this.trail = new InfiniteLine(properties.position, { red: 255, green: 128, blue: 89 }); + var lastPosition = properties.position; + //Vec3.print("Velocity", properties.velocity); + //Vec3.print("VelocityChange", collision.velocityChange); + var speed = Vec3.length(properties.velocity); + playRandomSound(AUDIO.batHit, { + position: properties.position, + volume: 2.0 + }); + var sounds = null; + if (speed < 5.0) { + sounds = AUDIO.crowdBoos; + } else { + sounds = AUDIO.crowdCheers; + } + var self = this; + this.trailInterval = Script.setInterval(function() { + var properties = Entities.getEntityProperties(self.entityID, ['position']); + if (Vec3.distance(properties.position, lastPosition)) { + self.trail.enqueuePoint(properties.position); + lastPosition = properties.position; + } + }, 50); + Entities.editEntity(self.entityID, { + velocity: Vec3.multiply(2, properties.velocity), + gravity: { + x: 0, + y: -9.8, + z: 0 + } + }); + + var removeHandler = this.onHit(entityB, collision); + if (removeHandler) { + Script.removeEventHandler(self.entityID, "collisionWithEntity", self.boundCollisionCallback); + } + }, + cleanupTrail: function() { + if (this.trail) { + Script.clearInterval(this.trailInterval); + this.trailInterval = null; + + this.trail.destroy(); + this.trail = null; + } + } +} + +function playRandomSound(sounds, options) { + if (options === undefined) { + options = { + volume: 1.0, + position: MyAvatar.position, + } + } + Audio.playSound(sounds[randomInt(sounds.length)], options); +} + +var lastTrail = null; + + +function vec3Mult(a, b) { + return { + x: a.x * b.x, + y: a.y * b.y, + z: a.z * b.z, + }; +} + +var lastBall = null; +var injector = null; + +function pitchBall() { + if (lastBall) { + lastBall.cleanupTrail(); + } + + var machineProperties = Entities.getEntityProperties(pitchingMachineID, ["dimensions", "position", "rotation"]); + var pitchFromPositionBase = machineProperties.position; + var pitchFromOffset = vec3Mult(machineProperties.dimensions, PITCHING_MACHINE_OUTPUT_OFFSET_PCT); + pitchFromOffset = Vec3.multiplyQbyV(machineProperties.rotation, pitchFromOffset); + var pitchFromPosition = Vec3.sum(pitchFromPositionBase, pitchFromOffset); + var pitchDirection = Quat.getFront(machineProperties.rotation); + var ballScale = machineProperties.dimensions.x / PITCHING_MACHINE_PROPERTIES.dimensions.x; + print("Creating baseball"); + + var speed = randomFloat(BASEBALL_MIN_SPEED, BASEBALL_MAX_SPEED) + var timeToPassPlate = (DISTANCE_FROM_PLATE + 1.0) / speed; + + var baseball = new Baseball(pitchFromPosition, Vec3.multiply(speed, pitchDirection), ballScale); + lastBall = baseball; + + baseball.onHit = function(entityB, collision) { + var properties = Entities.getEntityProperties(entityB, ["name"]); + var name = properties.name; + print("Hit: " + name); + if (name == "backstop") { + print("STRIKE"); + } else if (name == "bat") { + print("HIT"); + Script.setTimeout(function() { + playRandomSound(sounds, { + position: { x: 0 ,y: 0, z: 0 }, + volume: 1.0, + }); + }, 500); + } + //Script.clearTimeout(strikeTimeout); + return true; + } + + if (!injector) { + injector = Audio.playSound(pitchSound, { + position: pitchFromPosition, + volume: 1.0 + }); + } else { + injector.restart(); + } +} + +Script.scriptEnding.connect(function() { + Entities.deleteEntity(pitchingMachineID); +}) + +Script.setInterval(pitchBall, PITCH_RATE); + + + + diff --git a/examples/baseballEntityScript.js b/examples/baseballEntityScript.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index cb445a0960..9ee9ed1e04 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -55,6 +55,7 @@ var NEAR_GRABBING_VELOCITY_SMOOTH_RATIO = 1.0; // adjust time-averaging of held var NEAR_PICK_MAX_DISTANCE = 0.3; // max length of pick-ray for close grabbing to be selected var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things var PICK_BACKOFF_DISTANCE = 0.2; // helps when hand is intersecting the grabble object +var NEAR_GRABBING_KINEMATIC = true; // force objects to be kinematic when near-grabbed ///////////////////////////////////////////////////////////////// // @@ -404,8 +405,9 @@ function MyController(hand, triggerAction) { var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); - var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation", - "gravity", "ignoreForCollisions"]); + var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation", "gravity", + "ignoreForCollisions", + "collisionsWillMove"]); var now = Date.now(); // add the action and initialize some variables @@ -549,8 +551,14 @@ function MyController(hand, triggerAction) { this.lineOff(); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, - ["position", "rotation", "gravity", "ignoreForCollisions"]); + ["position", "rotation", "gravity", + "ignoreForCollisions", "collisionsWillMove"]); this.activateEntity(this.grabbedEntity, grabbedProperties); + if (grabbedProperties.collisionsWillMove && NEAR_GRABBING_KINEMATIC) { + Entities.editEntity(this.grabbedEntity, { + collisionsWillMove: false + }); + } var handRotation = this.getHandRotation(); var handPosition = this.getHandPosition(); @@ -579,7 +587,8 @@ function MyController(hand, triggerAction) { timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, relativeRotation: this.offsetRotation, - ttl: ACTION_TTL + ttl: ACTION_TTL, + kinematic: NEAR_GRABBING_KINEMATIC }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; @@ -631,7 +640,8 @@ function MyController(hand, triggerAction) { timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, relativeRotation: this.offsetRotation, - ttl: ACTION_TTL + ttl: ACTION_TTL, + kinematic: NEAR_GRABBING_KINEMATIC }); this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); } @@ -828,6 +838,7 @@ function MyController(hand, triggerAction) { if (data["refCount"] == 1) { data["gravity"] = grabbedProperties.gravity; data["ignoreForCollisions"] = grabbedProperties.ignoreForCollisions; + data["collisionsWillMove"] = grabbedProperties.collisionsWillMove; var whileHeldProperties = {gravity: {x:0, y:0, z:0}}; if (invertSolidWhileHeld) { whileHeldProperties["ignoreForCollisions"] = ! grabbedProperties.ignoreForCollisions; @@ -845,7 +856,8 @@ function MyController(hand, triggerAction) { if (data["refCount"] < 1) { Entities.editEntity(entityID, { gravity: data["gravity"], - ignoreForCollisions: data["ignoreForCollisions"] + ignoreForCollisions: data["ignoreForCollisions"], + collisionsWillMove: data["collisionsWillMove"] }); data = null; } diff --git a/examples/map.js~ b/examples/map.js~ new file mode 100644 index 0000000000..5a4e0f0f8c --- /dev/null +++ b/examples/map.js~ @@ -0,0 +1,323 @@ +Script.include("entityManager.js"); +Script.include("overlayManager.js"); + + +// Poll for nearby map data + +var entityManager = new EntityManager(); + +// From http://evanw.github.io/lightgl.js/docs/raytracer.html +function raySphereIntersection(origin, ray, center, radius) { + var offset = Vec3.subtract(origin, center); + var a = Vec3.dot(ray, ray); + // var a = ray.dot(ray); + var b = 2 * Vec3.dot(ray, offset); + // var b = 2 * ray.dot(offset); + var c = Vec3.dot(offset, offset) - radius * radius; + // var c = offset.dot(offset) - radius * radius; + var discriminant = b * b - 4 * a * c; + + if (discriminant > 0) { + return true; + } + + return null; +}; + + +Map = function(data) { + var visible = false; + + var ROOT_OFFSET = Vec3.multiply(0.3, Quat.getFront(MyAvatar.orientation)); + var ROOT_POSITION = Vec3.sum(MyAvatar.position, ROOT_OFFSET); + + var ROOT_SCALE = 0.0005; + + // Create object in objectManager + var rootObject = entityManager.addBare(); + var position = ROOT_POSITION; + rootObject.position = ROOT_POSITION; + rootObject.scale = ROOT_SCALE + Vec3.print("Position:", position); + + // Search for all nearby objects that have the userData "mapped" + // TODO Update to use the zone's bounds + var entities = Entities.findEntities(MyAvatar.position, 32000); + var mappedEntities = []; + var minCorner = { + x: 4294967295, + y: 4294967295, + z: 4294967295, + }; + var maxCorner = { + x: -4294967295, + y: -4294967295, + z: -4294967295, + }; + + for (var i = 0; i < entities.length; ++i) { + var entityID = entities[i]; + var properties = Entities.getEntityProperties(entityID); + if (properties.userData == "mapped" || properties.userData == "tracked") { + + print("Found: ", properties.name); + + minCorner.x = Math.min(minCorner.x, properties.position.x - (properties.dimensions.x / 2)); + minCorner.y = Math.min(minCorner.y, properties.position.y - (properties.dimensions.y / 2)); + minCorner.z = Math.min(minCorner.z, properties.position.z - (properties.dimensions.z / 2)); + + maxCorner.x = Math.max(maxCorner.x, properties.position.x - (properties.dimensions.x / 2)); + maxCorner.y = Math.max(maxCorner.y, properties.position.y - (properties.dimensions.y / 2)); + maxCorner.z = Math.max(maxCorner.z, properties.position.z - (properties.dimensions.z / 2)); + + } + // if (properties.userData == "mapped") { + // properties.visible = false; + // var entity = entityManager.add(properties.type, properties); + // mappedEntities.push(entity); + // } else if (properties.userData == "tracked") { + // // TODO implement tracking of objects + // } + } + + var dimensions = { + x: maxCorner.x - minCorner.x, + y: maxCorner.y - minCorner.y, + z: maxCorner.z - minCorner.z, + }; + Vec3.print("dims", dimensions); + + var center = { + x: minCorner.x + (dimensions.x / 2), + y: minCorner.y + (dimensions.y / 2), + z: minCorner.z + (dimensions.z / 2), + }; + Vec3.print("center", center); + + var trackedEntities = []; + var waypointEntities = []; + for (var i = 0; i < entities.length; ++i) { + var entityID = entities[i]; + var properties = Entities.getEntityProperties(entityID); + var mapData = null; + try { + var data = JSON.parse(properties.userData.replace(/(\r\n|\n|\r)/gm,"")); + mapData = data.mapData; + } catch (e) { + print("Caught: ", properties.name); + } + + if (mapData) { + print("Creating copy of", properties.name); + properties.name += " (COPY)"; + properties.userData = ""; + properties.visible = true; + var position = properties.position; + properties.position = Vec3.subtract(properties.position, center); + properties.position = Vec3.multiply(properties.position, ROOT_SCALE); + var extra = { }; + + if (mapData.track) { + extra.trackingEntityID= entityID; + trackedEntities.push(entity); + rootObject.addChild(entity); + } + if (mapData.waypoint) { + print("Waypoint: ", mapData.waypoint.name); + // properties.type = "Model"; + // properties.modelURL = "atp:ca49a13938376b3eb68d7b2b9189afb3f580c07b6950ea9e65b5260787204145.fbx"; + extra.waypoint = mapData.waypoint; + extra.waypoint.position = position; + } + + var entity = entityManager.add(properties.type, properties); + entity.__extra__ = extra; + if (mapData.waypoint) { + waypointEntities.push(entity); + } + mappedEntities.push(entity); + + rootObject.addChild(entity); + + } else { + // print("Not creating copy of", properties.name); + } + } + + var avatarArrowEntity = entityManager.add("Model", { + name: "You Are Here", + modelURL: "atp:ce4f0c4e491e40b73d28f2646da4f676fe9ea364cf5f1bf5615522ef6acfd80e.fbx", + position: Vec3.multiply(Vec3.subtract(MyAvatar.position, center), ROOT_SCALE), + dimensions: { x: 30, y: 100, z: 100 }, + }); + rootObject.addChild(avatarArrowEntity); + + this.isVisible = function() { + return visible; + } + + Controller.mousePressEvent.connect(mousePressEvent); + function mousePressEvent(event) { + // Entities.setZonesArePickable(false); + + var pickRay = Camera.computePickRay(event.x, event.y); + for (var i = 0; i < waypointEntities.length; ++i) { + var entity = waypointEntities[i]; + print("Checkit for hit", entity.__extra__.waypoint.name); + var result = raySphereIntersection(pickRay.origin, pickRay.direction, entity.worldPosition, 0.1);//entity.worldScale); + if (result) { + print("Pressed entity: ", entity.id); + print("Pressed waypoint: ", entity.__extra__.waypoint.name); + print("Teleporting..."); + MyAvatar.position = entity.__extra__.waypoint.position; + break; + } + } + // var result = Entities.findRayIntersection(pickRay, false); + // if (result.intersects) { + // var entity = entityManager.get(result.entityID); + // if (entity) { + // print("Pressed entity: ", entity.id); + // } + // if (entity && entity.__extra__.waypoint) { + // print("Pressed waypoint: ", entity.__extra__.waypoint.name); + // print("Teleporting..."); + // MyAvatar.position = entity.__extra__.waypoint.position; + // } + // } + + // Entities.setZonesArePickable(true); + }; + + var time = 0; + Script.update.connect(function(dt) { + time += dt; + // Update tracked entities + for (var i = 0; i < trackedEntities.length; ++i) { + entity = trackedEntities[i]; + var entityID = entity.__extra__.trackingEntityID; + var properties = Entities.getEntityProperties(entityID); + properties.position = Vec3.subtract(properties.position, center); + properties.position = Vec3.multiply(properties.position, ROOT_SCALE); + entity.position = properties.position; + } + + + var position = Vec3.subtract(MyAvatar.position, center) + position.y += 60 + (Math.sin(time) * 10); + position = Vec3.multiply(position, ROOT_SCALE); + avatarArrowEntity.position = position; + // Vec3.print("Position:", avatarArrowEntity.position); + + // rootObject.position = Vec3.sum(position, { x: 0, y: Math.sin(time) / 30, z: 0 }); + //var ROOT_OFFSET = Vec3.multiply(0.3, Quat.getFront(MyAvatar.orientation)); + //var ROOT_POSITION = Vec3.sum(MyAvatar.position, ROOT_OFFSET); + // position = ROOT_POSITION; + rootObject.position = ROOT_POSITION; + entityManager.update(); + + // Update waypoint highlights + var pickRay = Camera.computePickRay(event.x, event.y); + for (var i = 0; i < waypointEntities.length; ++i) { + var entity = waypointEntities[i]; + print("Checkit for hit", entity.__extra__.waypoint.name); + var result = raySphereIntersection(pickRay.origin, pickRay.direction, entity.worldPosition, 0.1);//entity.worldScale); + if (result) { + print("Pressed entity: ", entity.id); + print("Pressed waypoint: ", entity.__extra__.waypoint.name); + print("Teleporting..."); + MyAvatar.position = entity.__extra__.waypoint.position; + break; + } + } + }); + + function setVisible(newValue) { + if (visible != newValue) { + visible = newValue; + + if (visible) { + } else { + } + } + } + + this.show = function() { + setVisible(true); + } + + this.hide = function() { + setVisible(false); + } +}; + +var map = null; +map = Map(mapData); + +// On press key +Controller.keyPressEvent.connect(function(event) { + if (event.text == "m") { + if (!map) { + map = Map(mapData); + } + + map.show(); + print("MAP!"); + } +}); + + + + + +var mapData = { + config: { + // World dimensions that the minimap maps to + worldDimensions: { + x: 10.0, + y: 10.0, + z: 10.0, + }, + // The center of the map should map to this location in the center of the area + worldCenter: { + x: 5.0, + y: 5.0, + z: 5.0, + }, + // Map dimensions + mapDimensions: { + x: 10.0, + y: 10.0, + z: 10.0, + }, + + // Can this be automated? Tag entities that should be included? Store in UserData? + objects: [ + { + type: "Model", + modelURL: "https://hifi-public.s3.amazonaws.com/ozan/sets/huffman_set/huffman_set.fbx", + }, + ], + }, + waypoints: [ + { + name: "Forest's Edge", + position: { + }, + }, + ], +}; + + +// entityManager = new OverlayManager(); +// entityManager = new EntityManager(); +// +// var rootEntity = entityManager.addBare(); +// +// var time = 0; +// +// +// rootEntity.scale = 0.1; +// Script.include("sfData.js"); +// rootEntity.addChild(entity); +entityManager.update(); diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index f38073f389..c10a8c23fe 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -47,6 +47,7 @@ if (this.painting) { return; } + this.whichHand = this.hand; if (this.hand === RIGHT_HAND) { this.getHandPosition = MyAvatar.getRightPalmPosition; this.getHandRotation = MyAvatar.getRightPalmRotation; @@ -183,6 +184,9 @@ }, releaseGrab: function() { + if(this.hand !== this.whichHand) { + return; + } this.stopPainting(); }, @@ -241,10 +245,8 @@ Overlays.deleteOverlay(this.laserPointer); // this.eraseBoard(); } - }; - // entity scripts always need to return a newly constructed object of our type return new Whiteboard(); }); \ No newline at end of file diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index cbc26da670..701112e1a8 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -16,186 +16,199 @@ Script.include("../../libraries/utils.js"); var scriptURL = Script.resolvePath("whiteboardEntityScript.js"); +var modelURL = "https://s3.amazonaws.com/hifi-public/eric/models/whiteboard.fbx"; + +var colorIndicatorBorderModelURL = "https://s3.amazonaws.com/hifi-public/eric/models/colorIndicatorBorder.fbx"; +var eraserModelURL = "https://s3.amazonaws.com/hifi-public/eric/models/eraser.fbx"; +var surfaceModelURL = "https://s3.amazonaws.com/hifi-public/eric/models/boardSurface.fbx"; var rotation = Quat.safeEulerAngles(Camera.getOrientation()); rotation = Quat.fromPitchYawRollDegrees(0, rotation.y, 0); var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(rotation))); -center.y += 0.4; + +var whiteboardDimensions, colorIndicatorBoxDimensions, colorIndicatorBox, eraser, blocker; +var colorBoxes = []; var colors = [ - hexToRgb("#2F8E84"), hexToRgb("#66CCB3"), hexToRgb("#A43C37"), hexToRgb("#491849"), hexToRgb("#6AB03B"), hexToRgb("#993369"), - hexToRgb("#9B47C2") + hexToRgb("#000000") ]; -//WHITEBOARD -var whiteboardDimensions = { - x: 2, - y: 1.5, - z: 0.08 -}; var whiteboard = Entities.addEntity({ type: "Model", - modelURL: "https://hifi-public.s3.amazonaws.com/ozan/support/for_eric/whiteboard/whiteboard.fbx", - name: "whiteboard", + shapeType: "box", + modelURL: modelURL, + name: "whiteboard base", position: center, rotation: rotation, - script: scriptURL, - dimensions: whiteboardDimensions, - color: { - red: 255, - green: 255, - blue: 255 - } }); - -// COLOR INDICATOR BOX -var colorIndicatorDimensions = { - x: whiteboardDimensions.x, - y: 0.05, - z: 0.02 +var colorIndicatorPosition = { + x: center.x, + y: center.y, + z: center.z }; -scriptURL = Script.resolvePath("colorIndicatorEntityScript.js"); -var colorIndicatorPosition = Vec3.sum(center, { - x: 0, - y: whiteboardDimensions.y / 2 + colorIndicatorDimensions.y / 2, - z: 0 -}); -var colorIndicatorBox = Entities.addEntity({ - type: "Box", - name: "Color Indicator", - color: colors[0], - rotation: rotation, +colorIndicatorPosition.y += 1.55; +colorIndicatorPosition = Vec3.sum(colorIndicatorPosition, Vec3.multiply(-0.1, Quat.getFront(rotation))); +var colorIndicatorBorder = Entities.addEntity({ + type: "Model", position: colorIndicatorPosition, - dimensions: colorIndicatorDimensions, - script: scriptURL, - userData: JSON.stringify({ - whiteboard: whiteboard - }) + modelURL: colorIndicatorBorderModelURL, + rotation: rotation, + shapeType: "box" }); -Entities.editEntity(whiteboard, { +var surfaceCenter = Vec3.sum(center, Vec3.multiply(-0.1, Quat.getFront(rotation))); +surfaceCenter.y += 0.6; +var drawingSurface = Entities.addEntity({ + type: "Model", + modelURL: surfaceModelURL, + shapeType: "box", + name: "whiteboard surface", + position: surfaceCenter, + script: scriptURL, + rotation: rotation, userData: JSON.stringify({ color: { currentColor: colors[0] - }, - colorIndicator: colorIndicatorBox - }) -}); - -//COLOR BOXES -var direction = Quat.getRight(rotation); -var colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboardDimensions.x / 2)); -var colorBoxes = []; -var colorSquareDimensions = { - x: (whiteboardDimensions.x / 2) / (colors.length - 1), - y: 0.1, - z: 0.05 -}; -colorBoxPosition.y += whiteboardDimensions.y / 2 + colorIndicatorDimensions.y + colorSquareDimensions.y / 2; -var spaceBetweenColorBoxes = Vec3.multiply(direction, colorSquareDimensions.x * 2); -var scriptURL = Script.resolvePath("colorSelectorEntityScript.js"); -for (var i = 0; i < colors.length; i++) { - var colorBox = Entities.addEntity({ - type: "Box", - name: "Color Selector", - position: colorBoxPosition, - dimensions: colorSquareDimensions, - rotation: rotation, - color: colors[i], - script: scriptURL, - userData: JSON.stringify({ - whiteboard: whiteboard, - colorIndicator: colorIndicatorBox - }) - }); - colorBoxes.push(colorBox); - colorBoxPosition = Vec3.sum(colorBoxPosition, spaceBetweenColorBoxes); -} - - -// BLACK BOX -var blackBoxDimensions = { - x: 0.3, - y: 0.3, - z: 0.01 -}; - -colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboardDimensions.x / 2 + blackBoxDimensions.x / 2 - 0.01)); -colorBoxPosition.y += 0.3; -var fragShaderURL = Script.resolvePath('blackInk.fs?v1' + Math.random()); -var blackBox = Entities.addEntity({ - type: 'Box', - name: "Black Color", - position: colorBoxPosition, - dimensions: blackBoxDimensions, - rotation: rotation, - color: { - red: 0, - green: 0, - blue: 0 - }, - script: scriptURL, - userData: JSON.stringify({ - whiteboard: whiteboard, - version: 2, - ProceduralEntity: { - shaderUrl: fragShaderURL } }) + }); +var lightPosition = Vec3.sum(center, Vec3.multiply(-3, Quat.getFront(rotation))); +var light = Entities.addEntity({ + type: 'Light', + name: 'whiteboard light', + position: lightPosition, + dimensions: {x: 10, y: 10, z: 10}, + intensity: 2, + color: {red: 255, green: 255, blue: 255} +}); -var eraseBoxDimensions = { - x: 0.5, - y: 0.1, - z: 0.01 -}; - - -var eraseBoxPosition = Vec3.sum(center, Vec3.multiply(direction, whiteboardDimensions.x / 2 + eraseBoxDimensions.x / 2 + 0.01)); -eraseBoxPosition.y += 0.3; +var eraserPosition = Vec3.sum(center, {x: 0, y: 2.05, z: 0 }); +eraserPosition = Vec3.sum(eraserPosition, Vec3.multiply(-0.1, rotation)); scriptURL = Script.resolvePath("eraseBoardEntityScript.js"); -var eraseAllText = Entities.addEntity({ - type: "Text", - position: eraseBoxPosition, +var eraser = Entities.addEntity({ + type: "Model", + modelURL: eraserModelURL, + position: eraserPosition, name: "Eraser", script: scriptURL, rotation: rotation, - dimensions: eraseBoxDimensions, - backgroundColor: { - red: 0, - green: 60, - blue: 0 - }, - textColor: { - red: 255, - green: 10, - blue: 10 - }, - text: "ERASE BOARD", - lineHeight: 0.07, userData: JSON.stringify({ - whiteboard: whiteboard + whiteboard: drawingSurface }) }); +Script.setTimeout(function() { + whiteboardDimensions = Entities.getEntityProperties(whiteboard, "naturalDimensions").naturalDimensions; + colorIndicatorBorderDimensions = Entities.getEntityProperties(colorIndicatorBorder, "naturalDimensions").naturalDimensions; + setUp(); +}, 2000) +function setUp() { + var blockerPosition = Vec3.sum(center, {x: 0, y: -1, z: 0 }); + blockerPosition = Vec3.sum(blockerPosition, Vec3.multiply(-1, Quat.getFront(rotation))); + blocker = Entities.addEntity({ + type: "Box", + rotation: rotation, + position: blockerPosition, + dimensions: {x: whiteboardDimensions.x, y: 1, z: 0.1}, + shapeType: "box", + visible: false + }); + + var eraseModelDimensions = Entities.getEntityProperties(eraser, "naturalDimensions").naturalDimensions; + Entities.editEntity(eraser, {dimensions: eraseModelDimensions}); + Entities.editEntity(colorIndicatorBorder, {dimensions: colorIndicatorBorderDimensions}); + + scriptURL = Script.resolvePath("colorIndicatorEntityScript.js"); + var colorIndicatorPosition = Vec3.sum(center, { + x: 0, + y: whiteboardDimensions.y / 2 + colorIndicatorBorderDimensions.y / 2, + z: 0 + }); + colorIndicatorPosition = Vec3.sum(colorIndicatorPosition, Vec3.multiply(-.1, Quat.getFront(rotation))); + var colorIndicatorBoxDimensions = Vec3.multiply(colorIndicatorBorderDimensions, 0.9); + colorIndicatorBox = Entities.addEntity({ + type: "Box", + name: "Color Indicator", + color: colors[0], + rotation: rotation, + position: colorIndicatorPosition, + dimensions: colorIndicatorBoxDimensions, + script: scriptURL, + userData: JSON.stringify({ + whiteboard: drawingSurface + }) + }); + + Entities.editEntity(drawingSurface, { + userData: JSON.stringify({ + color: { + currentColor: colors[0] + }, + colorIndicator: colorIndicatorBox + }) + }); + + //COLOR BOXES + var direction = Quat.getRight(rotation); + var colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboardDimensions.x / 2)); + var colorSquareDimensions = { + x: 0.13, + y: 0.13, + z: 0.002 + }; + + var palleteDepthOffset = -0.07; + var palleteHeightOffset = -0.28; + + colorBoxPosition = Vec3.sum(colorBoxPosition, Vec3.multiply(palleteDepthOffset, Quat.getFront(rotation))); + colorBoxPosition.y += palleteHeightOffset; + var spaceBetweenColorBoxes = Vec3.multiply(direction, colorSquareDimensions.x * 1.76); + var palleteXOffset = Vec3.multiply(direction, 0.43); + colorBoxPosition = Vec3.sum(colorBoxPosition, palleteXOffset); + var scriptURL = Script.resolvePath("colorSelectorEntityScript.js"); + for (var i = 0; i < colors.length; i++) { + var colorBox = Entities.addEntity({ + type: "Box", + name: "Color Selector", + position: colorBoxPosition, + dimensions: colorSquareDimensions, + rotation: rotation, + color: colors[i], + script: scriptURL, + userData: JSON.stringify({ + whiteboard: drawingSurface, + colorIndicator: colorIndicatorBox + }) + }); + colorBoxes.push(colorBox); + colorBoxPosition = Vec3.sum(colorBoxPosition, spaceBetweenColorBoxes); + } + +} + function cleanup() { Entities.deleteEntity(whiteboard); - Entities.deleteEntity(eraseAllText); - Entities.deleteEntity(blackBox); + Entities.deleteEntity(drawingSurface); + Entities.deleteEntity(colorIndicatorBorder); + Entities.deleteEntity(eraser); Entities.deleteEntity(colorIndicatorBox); + Entities.deleteEntity(blocker); + Entities.deleteEntity(light); colorBoxes.forEach(function(colorBox) { Entities.deleteEntity(colorBox); }); } + // Uncomment this line to delete whiteboard and all associated entity on script close -Script.scriptEnding.connect(cleanup); \ No newline at end of file +// Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/examples/toybox/flashlight/flashlight.js b/examples/toybox/flashlight/flashlight.js index 722a5c1bfc..912d542d6c 100644 --- a/examples/toybox/flashlight/flashlight.js +++ b/examples/toybox/flashlight/flashlight.js @@ -266,4 +266,4 @@ // entity scripts always need to return a newly constructed object of our type return new Flashlight(); -}); +}); \ No newline at end of file diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index f9c92c59e7..f04fa88910 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -2,7 +2,12 @@ set(TARGET_NAME interface) project(${TARGET_NAME}) # 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") +set(OPTIONAL_EXTERNALS "LeapMotion" "RtMidi" "RSSDK" "iViewHMD") + +if(WIN32) + list(APPEND OPTIONAL_EXTERNALS "3DConnexionClient") +endif() + foreach(EXTERNAL ${OPTIONAL_EXTERNALS}) string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE) if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR) @@ -102,12 +107,14 @@ link_hifi_libraries(shared octree environment gpu gl procedural model render render-utils entities-renderer ui auto-updater plugins display-plugins input-plugins) +#fixme find a way to express faceshift as a plugin target_bullet() target_glew() target_opengl() - -add_dependency_external_projects(sdl2) +if (WIN32 OR APPLE) + target_faceshift() +endif() # perform standard include and linking for found externals foreach(EXTERNAL ${OPTIONAL_EXTERNALS}) diff --git a/interface/external/faceshift/readme.txt b/interface/external/faceshift/readme.txt deleted file mode 100644 index 4208711632..0000000000 --- a/interface/external/faceshift/readme.txt +++ /dev/null @@ -1,26 +0,0 @@ - -Instructions for adding the Faceshift library to Interface -Stephen Birarda, July 18th, 2014 - -OS X users: You can also use homebrew to get the Faceshift library by tapping our repo - highfidelity/homebrew-formulas -and then calling 'brew install highfidelity/formulas/faceshift'. - -You can download the Faceshift SDK from http://download.faceshift.com/faceshift-network.zip. - -Create a ‘faceshift’ folder under interface/externals. - -You may optionally choose to place this folder in a location outside the repository (so you can re-use with different checkouts and different projects). - -If so our CMake find module expects you to set the ENV variable 'HIFI_LIB_DIR' to a directory containing a subfolder ‘faceshift’ that contains the lib and include folders. - -1. Build a Faceshift static library from the fsbinarystream.cpp file. - Windows: Win32 console application; no precompiled header or SDL checks; no ATL or MFC headers; Project Properties, Configuration Type = Static Library (.lib). - -2. Copy the library files to the ‘lib’ folder in your Faceshift folder. - OSX: If you build a release version call it libfaceshift.a. The debug version should be called libfaceshiftd.a. - Windows: The release and debug versions should be called faceshift.lib and faceshiftd.lib, respectively. Copy them into a ‘Win32’ folder in your ‘lib’ folder. - -3. Copy the fsbinarystream.h header file from the Faceshift SDK into the ‘include’ folder in your Faceshift folder. - -4. Clear your build directory, run cmake and build, and you should be all set. - diff --git a/interface/external/sdl2/readme.txt b/interface/external/sdl2/readme.txt deleted file mode 100644 index 9f3bd40e15..0000000000 --- a/interface/external/sdl2/readme.txt +++ /dev/null @@ -1,13 +0,0 @@ - -Instructions for adding the SDL library (SDL2) to Interface -David Rowe, 11 Jan 2015 - -You can download the SDL development library from https://www.libsdl.org/. Interface has been tested with version 2.0.3. - -1. Copy the include and lib folders into the interface/externals/sdl2 folder. - This readme.txt should be there as well. - - You may optionally choose to copy the SDK folders to a location outside the repository (so you can re-use with different checkouts and different projects). - If so our CMake find module expects you to set the ENV variable 'HIFI_LIB_DIR' to a directory containing a subfolder 'sdl2' that contains the two folders mentioned above. - -2. Clear your build directory, run cmake and build, and you should be all set. diff --git a/interface/external/sixense/readme.txt b/interface/external/sixense/readme.txt deleted file mode 100644 index a4790caa5e..0000000000 --- a/interface/external/sixense/readme.txt +++ /dev/null @@ -1,10 +0,0 @@ - -Instructions for adding the Sixense driver to Interface -Andrzej Kapolka, November 18, 2013 - -1. Copy the Sixense sdk folders (bin, include, lib, and samples) into the interface/external/Sixense folder. This readme.txt should be there as well. - - You may optionally choose to copy the SDK folders to a location outside the repository (so you can re-use with different checkouts and different projects). - If so our CMake find module expects you to set the ENV variable 'HIFI_LIB_DIR' to a directory containing a subfolder 'sixense' that contains the folders mentioned above. - -3. Delete your build directory, run cmake and build, and you should be all set. diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index 682e0be1bf..515f6e96fe 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -197,7 +197,7 @@ "id": "rightHandOpen", "type": "clip", "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/hand_anims/point_right_hand.fbx", + "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/grab/grab_right.fbx", "startFrame": 0.0, "endFrame": 0.0, "timeScale": 1.0, @@ -209,9 +209,9 @@ "id": "rightHandClose", "type": "clip", "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/squeeze_hands/right_hand_anim.fbx", - "startFrame": 15.0, - "endFrame": 15.0, + "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/grab/grab_right.fbx", + "startFrame": 10.0, + "endFrame": 10.0, "timeScale": 1.0, "loopFlag": true }, @@ -346,7 +346,7 @@ "id": "leftHandOpen", "type": "clip", "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/hand_anims/point_left_hand.fbx", + "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/grab/grab_left.fbx", "startFrame": 0.0, "endFrame": 0.0, "timeScale": 1.0, @@ -358,9 +358,9 @@ "id": "leftHandClose", "type": "clip", "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/squeeze_hands/left_hand_anim.fbx", - "startFrame": 15.0, - "endFrame": 15.0, + "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/grab/grab_left.fbx", + "startFrame": 10.0, + "endFrame": 10.0, "timeScale": 1.0, "loopFlag": true }, diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index eebd26c3c3..8f9fc9b16e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -950,8 +950,8 @@ void Application::initializeGL() { checkFPStimer.start(1000); // call our idle function whenever we can - connect(&idleTimer, &QTimer::timeout, this, &Application::idle); - idleTimer.start(TARGET_SIM_FRAME_PERIOD_MS); + // connect(&idleTimer, &QTimer::timeout, this, &Application::idle); + // idleTimer.start(TARGET_SIM_FRAME_PERIOD_MS); _idleLoopStdev.reset(); // update before the first render @@ -1023,6 +1023,10 @@ void Application::paintGL() { if (_inPaint) { return; } + + // this is a good idea + idle(); + _inPaint = true; Finally clearFlagLambda([this] { _inPaint = false; }); @@ -2070,7 +2074,7 @@ void Application::idle() { float secondsSinceLastUpdate = timeSinceLastUpdateUs / USECS_PER_SECOND; if (isThrottled && (timeSinceLastUpdateUs / USECS_PER_MSEC) < THROTTLED_SIM_FRAME_PERIOD_MS) { - return; // bail early, we're throttled and not enough time has elapsed + //return; // bail early, we're throttled and not enough time has elapsed } _lastTimeUpdated.start(); diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 238e48d2fd..941e876075 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -35,7 +35,8 @@ AvatarActionHold::~AvatarActionHold() { qDebug() << "AvatarActionHold::~AvatarActionHold"; #endif } - +#include +#include void AvatarActionHold::updateActionWorker(float deltaTimeStep) { bool gotLock = false; glm::quat rotation; @@ -51,7 +52,24 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { glm::vec3 offset; glm::vec3 palmPosition; glm::quat palmRotation; - if (_hand == "right") { + + const auto& plugins = PluginManager::getInstance()->getInputPlugins(); + auto it = std::find_if(std::begin(plugins), std::end(plugins), [](const InputPluginPointer& plugin) { + return plugin->getName() == ViveControllerManager::NAME; + }); + + if (it != std::end(plugins)) { + const auto& vive = it->dynamicCast(); + auto index = (_hand == "right") ? 0 : 1; auto userInputMapper = DependencyManager::get(); + auto translation = extractTranslation(userInputMapper->getSensorToWorldMat()); + auto rotation = glm::quat_cast(userInputMapper->getSensorToWorldMat()); + + + const glm::quat quarterX = glm::angleAxis(PI / 2.0f, glm::vec3(1.0f, 0.0f, 0.0f)); + const glm::quat yFlip = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); + palmPosition = translation + rotation * vive->getPosition(index); + palmRotation = rotation * vive->getRotation(index) * yFlip * quarterX; + } else if (_hand == "right") { palmPosition = holdingAvatar->getRightPalmPosition(); palmRotation = holdingAvatar->getRightPalmRotation(); } else { @@ -119,6 +137,9 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) { worldTrans.setRotation(glmToBullet(_rotationalTarget)); rigidBody->setWorldTransform(worldTrans); + ownerEntity->setPosition(_positionalTarget); + ownerEntity->setRotation(_rotationalTarget); + _previousPositionalTarget = _positionalTarget; _previousRotationalTarget = _rotationalTarget; _previousSet = true; @@ -224,6 +245,8 @@ QVariantMap AvatarActionHold::getArguments() { arguments["relativeRotation"] = glmToQMap(_relativeRotation); arguments["timeScale"] = _linearTimeScale; arguments["hand"] = _hand; + arguments["kinematic"] = _kinematic; + arguments["kinematicSetVelocity"] = _kinematicSetVelocity; }); return arguments; } diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 3f1e668cd0..342f995de7 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -50,7 +50,7 @@ AvatarSharedPointer AvatarHashMap::addAvatar(const QUuid& sessionUUID, const QWe avatar->setOwningAvatarMixer(mixerWeakPointer); QWriteLocker locker(&_hashLock); _avatarHash.insert(sessionUUID, avatar); - + emit avatarAddedEvent(sessionUUID); return avatar; } @@ -137,13 +137,16 @@ void AvatarHashMap::processKillAvatar(QSharedPointer packet, SharedNod // read the node id QUuid sessionUUID = QUuid::fromRfc4122(packet->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); removeAvatar(sessionUUID); + } void AvatarHashMap::removeAvatar(const QUuid& sessionUUID) { QWriteLocker locker(&_hashLock); _avatarHash.remove(sessionUUID); + emit avatarRemovedEvent(sessionUUID); } void AvatarHashMap::sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID) { _lastOwnerSessionUUID = oldUUID; + emit avatarSessionChangedEvent(sessionUUID, oldUUID); } diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 93364eb1ef..a125784cd8 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -34,6 +34,11 @@ public: void withAvatarHash(std::function); int size() { return _avatarHash.size(); } +signals: + void avatarAddedEvent(const QUuid& sessionUUID); + void avatarRemovedEvent(const QUuid& sessionUUID); + void avatarSessionChangedEvent(const QUuid& sessionUUID,const QUuid& oldUUID); + public slots: bool isAvatarInRange(const glm::vec3 & position, const float range); diff --git a/libraries/gl/src/gl/GlWindow.cpp b/libraries/gl/src/gl/GlWindow.cpp index 7e43b29e73..40a5bedf7e 100644 --- a/libraries/gl/src/gl/GlWindow.cpp +++ b/libraries/gl/src/gl/GlWindow.cpp @@ -44,8 +44,7 @@ bool GlWindow::makeCurrent() { qDebug() << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER)); }); - QOpenGLContext * currentContext = QOpenGLContext::currentContext(); - Q_ASSERT(_context == currentContext); + Q_ASSERT(_context == QOpenGLContext::currentContext()); return makeCurrentResult; } diff --git a/libraries/input-plugins/CMakeLists.txt b/libraries/input-plugins/CMakeLists.txt index 094a697012..c26e14e756 100644 --- a/libraries/input-plugins/CMakeLists.txt +++ b/libraries/input-plugins/CMakeLists.txt @@ -11,55 +11,5 @@ if (WIN32) target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES}) endif() -#add_dependency_external_projects(Sixense) -#find_package(Sixense REQUIRED) -#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}) - - if (${${EXTERNAL}_UPPERCASE}_REQUIRED) - find_package(${EXTERNAL} REQUIRED) - else () - find_package(${EXTERNAL}) - endif () - - if (${${EXTERNAL}_UPPERCASE}_FOUND AND NOT DISABLE_${${EXTERNAL}_UPPERCASE}) - add_definitions(-DHAVE_${${EXTERNAL}_UPPERCASE}) - - # include the library directories (ignoring warnings) - if (NOT ${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS) - set(${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS ${${${EXTERNAL}_UPPERCASE}_INCLUDE_DIR}) - endif () - - include_directories(SYSTEM ${${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS}) - - # perform the system include hack for OS X to ignore warnings - if (APPLE) - foreach(EXTERNAL_INCLUDE_DIR ${${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS}) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${EXTERNAL_INCLUDE_DIR}") - endforeach() - endif () - - if (NOT ${${EXTERNAL}_UPPERCASE}_LIBRARIES) - set(${${EXTERNAL}_UPPERCASE}_LIBRARIES ${${${EXTERNAL}_UPPERCASE}_LIBRARY}) - endif () - - if (NOT APPLE OR NOT ${${EXTERNAL}_UPPERCASE} MATCHES "SIXENSE") - target_link_libraries(${TARGET_NAME} ${${${EXTERNAL}_UPPERCASE}_LIBRARIES}) - elseif (APPLE AND NOT INSTALLER_BUILD) - add_definitions(-DSIXENSE_LIB_FILENAME=\"${${${EXTERNAL}_UPPERCASE}_LIBRARY_RELEASE}\") - endif () - endif () -endforeach() +target_sdl2() +target_sixense() diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp index bb8267b616..28e001208c 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp +++ b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp @@ -217,6 +217,15 @@ void ViveControllerManager::renderHand(UserInputMapper::PoseValue pose, gpu::Bat batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0); } +glm::vec3 ViveControllerManager::getPosition(int hand) const { + const mat4& mat = _trackedDevicePoseMat4[hand ? 3 : 4]; + return extractTranslation(mat); +} +glm::quat ViveControllerManager::getRotation(int hand) const { + const mat4& mat = _trackedDevicePoseMat4[hand ? 3 : 4]; + return glm::quat_cast(mat); +} + void ViveControllerManager::update(float deltaTime, bool jointsCaptured) { #ifdef Q_OS_WIN _poseStateMap.clear(); @@ -250,7 +259,7 @@ void ViveControllerManager::update(float deltaTime, bool jointsCaptured) { numTrackedControllers++; const mat4& mat = _trackedDevicePoseMat4[device]; - + if (!jointsCaptured) { handlePoseEvent(mat, numTrackedControllers - 1); } @@ -372,16 +381,23 @@ void ViveControllerManager::handlePoseEvent(const mat4& mat, int index) { // Q = (deltaQ * QOffset) * (yFlip * quarterTurnAboutX) // // Q = (deltaQ * inverse(deltaQForAlignedHand)) * (yFlip * quarterTurnAboutX) - + + float sign = (index == LEFT_HAND) ? -1.0f : 1.0f; + const glm::quat quarterX = glm::angleAxis(PI / 2.0f, glm::vec3(1.0f, 0.0f, 0.0f)); const glm::quat yFlip = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); - float sign = (index == LEFT_HAND) ? -1.0f : 1.0f; const glm::quat signedQuaterZ = glm::angleAxis(sign * PI / 2.0f, glm::vec3(0.0f, 0.0f, 1.0f)); const glm::quat eighthX = glm::angleAxis(PI / 4.0f, glm::vec3(1.0f, 0.0f, 0.0f)); - const glm::quat offset = glm::inverse(signedQuaterZ * eighthX); - rotation = rotation * offset * yFlip * quarterX; + + + const glm::quat rotationOffset = glm::inverse(signedQuaterZ * eighthX) * yFlip * quarterX; + const glm::vec3 translationOffset = glm::vec3(sign * CONTROLLER_LENGTH_OFFSET / 2.0f, + CONTROLLER_LENGTH_OFFSET / 2.0f, + 2.0f * CONTROLLER_LENGTH_OFFSET); - position += rotation * glm::vec3(0, 0, -CONTROLLER_LENGTH_OFFSET); + position += rotation * translationOffset; + rotation = rotation * rotationOffset; + //{quat, x = 0.653281, y = -0.270598, z = 0.653281, w = 0.270598}{vec3, x = 0.0381, y = -0.0381, z = -0.1524} _poseStateMap[makeInput(JointChannel(index)).getChannel()] = UserInputMapper::PoseValue(position, rotation); } diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.h b/libraries/input-plugins/src/input-plugins/ViveControllerManager.h index 5cae8daaf4..f6220ca97a 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.h +++ b/libraries/input-plugins/src/input-plugins/ViveControllerManager.h @@ -27,6 +27,8 @@ class ViveControllerManager : public InputPlugin, public InputDevice { Q_OBJECT public: + static const QString NAME; + enum JoystickAxisChannel { AXIS_Y_POS = 1U << 1, AXIS_Y_NEG = 1U << 2, @@ -74,6 +76,10 @@ public: UserInputMapper::Input makeInput(unsigned int button, int index); UserInputMapper::Input makeInput(JoystickAxisChannel axis, int index); UserInputMapper::Input makeInput(JointChannel joint); + + int getNumDevices() const; + glm::vec3 getPosition(int device) const; + glm::quat getRotation(int device) const; private: void renderHand(UserInputMapper::PoseValue pose, gpu::Batch& batch, int index); @@ -92,8 +98,6 @@ private: int _rightHandRenderID; bool _renderControllers; - - static const QString NAME; }; #endif // hifi__ViveControllerManager diff --git a/libraries/networking/src/AssetClient.cpp b/libraries/networking/src/AssetClient.cpp index b7f1205847..6a1b46340c 100644 --- a/libraries/networking/src/AssetClient.cpp +++ b/libraries/networking/src/AssetClient.cpp @@ -89,7 +89,6 @@ AssetRequest* AssetClient::createRequest(const QString& hash, const QString& ext // Move to the AssetClient thread in case we are not currently on that thread (which will usually be the case) request->moveToThread(thread()); - request->setParent(this); return request; } else { @@ -105,7 +104,6 @@ AssetUpload* AssetClient::createUpload(const QString& filename) { auto upload = new AssetUpload(filename); upload->moveToThread(thread()); - upload->setParent(this); return upload; } else { @@ -118,7 +116,6 @@ AssetUpload* AssetClient::createUpload(const QByteArray& data, const QString& ex auto upload = new AssetUpload(data, extension); upload->moveToThread(thread()); - upload->setParent(this); return upload; } else { diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index aadf9b16ea..8da9541387 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -14,11 +14,11 @@ #include "PhysicsCollisionGroups.h" bool CharacterController::needsRemoval() const { - return (bool)(_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION); + return ((_pendingFlags & PENDING_FLAG_REMOVE_FROM_SIMULATION) == PENDING_FLAG_REMOVE_FROM_SIMULATION); } bool CharacterController::needsAddition() const { - return (bool)(_pendingFlags & PENDING_FLAG_ADD_TO_SIMULATION); + return ((_pendingFlags & PENDING_FLAG_ADD_TO_SIMULATION) == PENDING_FLAG_ADD_TO_SIMULATION); } void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index ff8382a143..d44ebc30b1 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -35,7 +35,9 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta if (ownerEntityExpired) { qDebug() << "warning -- action with no entity removing self from btCollisionWorld."; btDynamicsWorld* dynamicsWorld = static_cast(collisionWorld); - dynamicsWorld->removeAction(this); + if (dynamicsWorld) { + dynamicsWorld->removeAction(this); + } return; } @@ -120,6 +122,17 @@ QVariantMap ObjectAction::getArguments() { arguments["ttl"] = (float)(_expires - now) / (float)USECS_PER_SECOND; } arguments["tag"] = _tag; + + EntityItemPointer entity = _ownerEntity.lock(); + if (entity) { + ObjectMotionState* motionState = static_cast(entity->getPhysicsInfo()); + if (motionState) { + arguments["::active"] = motionState->isActive(); + arguments["::motion-type"] = motionTypeToString(motionState->getMotionType()); + } else { + arguments["::no-motion-state"] = true; + } + } }); return arguments; } diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 4f3d0396c6..b47c870216 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -115,6 +115,21 @@ void ObjectMotionState::setMotionType(MotionType motionType) { _motionType = motionType; } +void ObjectMotionState::updateCCDConfiguration() { + if (_body) { + if (_shape) { + btVector3 center; + btScalar radius; + _shape->getBoundingSphere(center, radius); + _body->setCcdMotionThreshold(radius * 2.0f); + _body->setCcdSweptSphereRadius(radius); + } else { + // Disable CCD + _body->setCcdMotionThreshold(0); + } + } +} + void ObjectMotionState::setRigidBody(btRigidBody* body) { // give the body a (void*) back-pointer to this ObjectMotionState if (_body != body) { @@ -125,6 +140,7 @@ void ObjectMotionState::setRigidBody(btRigidBody* body) { if (_body) { _body->setUserPointer(this); } + updateCCDConfiguration(); } } @@ -187,6 +203,8 @@ bool ObjectMotionState::handleHardAndEasyChanges(uint32_t flags, PhysicsEngine* if (_shape != newShape) { _shape = newShape; _body->setCollisionShape(_shape); + + updateCCDConfiguration(); } else { // huh... the shape didn't actually change, so we clear the DIRTY_SHAPE flag flags &= ~Simulation::DIRTY_SHAPE; diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 450ac34a90..967069657c 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -29,6 +29,15 @@ enum MotionType { MOTION_TYPE_KINEMATIC // keyframed motion }; +inline QString motionTypeToString(MotionType motionType) { + switch(motionType) { + case MOTION_TYPE_STATIC: return QString("static"); + case MOTION_TYPE_DYNAMIC: return QString("dynamic"); + case MOTION_TYPE_KINEMATIC: return QString("kinematic"); + } + return QString("unknown"); +} + enum MotionStateType { MOTIONSTATE_TYPE_INVALID, MOTIONSTATE_TYPE_ENTITY, @@ -137,6 +146,7 @@ protected: virtual bool isReadyToComputeShape() = 0; virtual btCollisionShape* computeNewShape() = 0; void setMotionType(MotionType motionType); + void updateCCDConfiguration(); // clearObjectBackPointer() overrrides should call the base method, then actually clear the object back pointer. virtual void clearObjectBackPointer() { _type = MOTIONSTATE_TYPE_INVALID; } diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 6773cecb14..1e652b75c4 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -241,7 +241,7 @@ void PhysicsEngine::stepSimulation() { float timeStep = btMin(dt, MAX_TIMESTEP); if (_myAvatarController) { - // ADEBUG TODO: move this stuff outside and in front of stepSimulation, because + // ADEBUG TODO: move this stuff outside and in front of stepSimulation, because // the updateShapeIfNecessary() call needs info from MyAvatar and should // be done on the main thread during the pre-simulation stuff if (_myAvatarController->needsRemoval()) { @@ -263,7 +263,8 @@ void PhysicsEngine::stepSimulation() { updateContactMap(); }; - int numSubsteps = _dynamicsWorld->stepSimulation(timeStep, PHYSICS_ENGINE_MAX_NUM_SUBSTEPS, PHYSICS_ENGINE_FIXED_SUBSTEP, onSubStep); + int numSubsteps = _dynamicsWorld->stepSimulationWithSubstepCallback(timeStep, PHYSICS_ENGINE_MAX_NUM_SUBSTEPS, + PHYSICS_ENGINE_FIXED_SUBSTEP, onSubStep); if (numSubsteps > 0) { BT_PROFILE("postSimulation"); _numSubsteps += (uint32_t)numSubsteps; diff --git a/libraries/physics/src/ThreadSafeDynamicsWorld.cpp b/libraries/physics/src/ThreadSafeDynamicsWorld.cpp index 8bf7cdab20..94d6315705 100644 --- a/libraries/physics/src/ThreadSafeDynamicsWorld.cpp +++ b/libraries/physics/src/ThreadSafeDynamicsWorld.cpp @@ -27,8 +27,9 @@ ThreadSafeDynamicsWorld::ThreadSafeDynamicsWorld( : btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration) { } -int ThreadSafeDynamicsWorld::stepSimulation( btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep, SubStepCallback onSubStep) { - BT_PROFILE("stepSimulation"); +int ThreadSafeDynamicsWorld::stepSimulationWithSubstepCallback(btScalar timeStep, int maxSubSteps, + btScalar fixedTimeStep, SubStepCallback onSubStep) { + BT_PROFILE("stepSimulationWithSubstepCallback"); int subSteps = 0; if (maxSubSteps) { //fixed timestep with interpolation diff --git a/libraries/physics/src/ThreadSafeDynamicsWorld.h b/libraries/physics/src/ThreadSafeDynamicsWorld.h index 1f6ce09d0c..26954832cf 100644 --- a/libraries/physics/src/ThreadSafeDynamicsWorld.h +++ b/libraries/physics/src/ThreadSafeDynamicsWorld.h @@ -37,8 +37,9 @@ public: btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration); - // virtual overrides from btDiscreteDynamicsWorld - int stepSimulation( btScalar timeStep, int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.), SubStepCallback onSubStep = []() { }); + int stepSimulationWithSubstepCallback(btScalar timeStep, int maxSubSteps = 1, + btScalar fixedTimeStep = btScalar(1.)/btScalar(60.), + SubStepCallback onSubStep = []() { }); void synchronizeMotionStates(); // btDiscreteDynamicsWorld::m_localTime is the portion of real-time that has not yet been simulated diff --git a/libraries/script-engine/src/Vec3.h b/libraries/script-engine/src/Vec3.h index b05e729a49..17a5afd09a 100644 --- a/libraries/script-engine/src/Vec3.h +++ b/libraries/script-engine/src/Vec3.h @@ -23,6 +23,25 @@ /// Scriptable interface a Vec3ernion helper class object. Used exclusively in the JavaScript API class Vec3 : public QObject { Q_OBJECT + Q_PROPERTY(glm::vec3 UNIT_X READ UNIT_X CONSTANT) + Q_PROPERTY(glm::vec3 UNIT_Y READ UNIT_Y CONSTANT) + Q_PROPERTY(glm::vec3 UNIT_Z READ UNIT_Z CONSTANT) + Q_PROPERTY(glm::vec3 UNIT_NEG_X READ UNIT_NEG_X CONSTANT) + Q_PROPERTY(glm::vec3 UNIT_NEG_Y READ UNIT_NEG_Y CONSTANT) + Q_PROPERTY(glm::vec3 UNIT_NEG_Z READ UNIT_NEG_Z CONSTANT) + Q_PROPERTY(glm::vec3 UNIT_XY READ UNIT_XY CONSTANT) + Q_PROPERTY(glm::vec3 UNIT_XZ READ UNIT_XZ CONSTANT) + Q_PROPERTY(glm::vec3 UNIT_YZ READ UNIT_YZ CONSTANT) + Q_PROPERTY(glm::vec3 UNIT_XYZ READ UNIT_XYZ CONSTANT) + Q_PROPERTY(glm::vec3 FLOAT_MAX READ FLOAT_MAX CONSTANT) + Q_PROPERTY(glm::vec3 FLOAT_MIN READ FLOAT_MIN CONSTANT) + Q_PROPERTY(glm::vec3 ZERO READ ZERO CONSTANT) + Q_PROPERTY(glm::vec3 ONE READ ONE CONSTANT) + Q_PROPERTY(glm::vec3 TWO READ TWO CONSTANT) + Q_PROPERTY(glm::vec3 HALF READ HALF CONSTANT) + Q_PROPERTY(glm::vec3 RIGHT READ RIGHT CONSTANT) + Q_PROPERTY(glm::vec3 UP READ UP CONSTANT) + Q_PROPERTY(glm::vec3 FRONT READ FRONT CONSTANT) public slots: glm::vec3 reflect(const glm::vec3& v1, const glm::vec3& v2) { return glm::reflect(v1, v2); } @@ -30,6 +49,7 @@ public slots: float dot(const glm::vec3& v1, const glm::vec3& v2) { return glm::dot(v1, v2); } glm::vec3 multiply(const glm::vec3& v1, float f) { return v1 * f; } glm::vec3 multiply(float f, const glm::vec3& v1) { return v1 * f; } + glm::vec3 multiplyVbyV(const glm::vec3& v1, const glm::vec3& v2) { return v1 * v2; } glm::vec3 multiplyQbyV(const glm::quat& q, const glm::vec3& v) { return q * v; } glm::vec3 sum(const glm::vec3& v1, const glm::vec3& v2) { return v1 + v2; } glm::vec3 subtract(const glm::vec3& v1, const glm::vec3& v2) { return v1 - v2; } @@ -45,6 +65,8 @@ public slots: glm::vec3 toPolar(const glm::vec3& v); glm::vec3 fromPolar(const glm::vec3& polar); glm::vec3 fromPolar(float elevation, float azimuth); + +private: const glm::vec3& UNIT_X() { return Vectors::UNIT_X; } const glm::vec3& UNIT_Y() { return Vectors::UNIT_Y; } const glm::vec3& UNIT_Z() { return Vectors::UNIT_Z; } diff --git a/libraries/shared/src/PhysicsHelpers.h b/libraries/shared/src/PhysicsHelpers.h index 7ceafea915..3b6fccdc99 100644 --- a/libraries/shared/src/PhysicsHelpers.h +++ b/libraries/shared/src/PhysicsHelpers.h @@ -16,7 +16,7 @@ #include const int PHYSICS_ENGINE_MAX_NUM_SUBSTEPS = 6; // Bullet will start to "lose time" at 10 FPS. -const float PHYSICS_ENGINE_FIXED_SUBSTEP = 1.0f / 60.0f; +const float PHYSICS_ENGINE_FIXED_SUBSTEP = 1.0f / 90.0f; // return incremental rotation (Bullet-style) caused by angularVelocity over timeStep glm::quat computeBulletRotationStep(const glm::vec3& angularVelocity, float timeStep); diff --git a/libraries/ui/src/VrMenu.cpp b/libraries/ui/src/VrMenu.cpp index 57df4d5306..211e0e0f72 100644 --- a/libraries/ui/src/VrMenu.cpp +++ b/libraries/ui/src/VrMenu.cpp @@ -113,6 +113,7 @@ void VrMenu::addMenu(QMenu* menu) { Q_ARG(QVariant, QVariant::fromValue(qmlParent)), Q_ARG(QVariant, QVariant::fromValue(menu->title()))); Q_ASSERT(invokeResult); + Q_UNUSED(invokeResult); // FIXME - apparently we haven't upgraded the Qt on our unix Jenkins environments to 5.5.x QObject* result = returnedValue.value(); Q_ASSERT(result); @@ -153,6 +154,7 @@ void VrMenu::addAction(QMenu* menu, QAction* action) { Q_ARG(QVariant, QVariant::fromValue(menuQml)), Q_ARG(QVariant, QVariant::fromValue(action->text()))); Q_ASSERT(invokeResult); + Q_UNUSED(invokeResult); // FIXME - apparently we haven't upgraded the Qt on our unix Jenkins environments to 5.5.x QObject* result = returnedValue.value(); Q_ASSERT(result); // Bind the QML and Widget together @@ -174,6 +176,7 @@ void VrMenu::insertAction(QAction* before, QAction* action) { Q_ARG(QVariant, QVariant::fromValue(beforeQml)), Q_ARG(QVariant, QVariant::fromValue(action->text()))); Q_ASSERT(invokeResult); + Q_UNUSED(invokeResult); // FIXME - apparently we haven't upgraded the Qt on our unix Jenkins environments to 5.5.x QObject* result = returnedValue.value(); Q_ASSERT(result); bindActionToQmlAction(result, action); @@ -192,4 +195,5 @@ void VrMenu::removeAction(QAction* action) { Q_ARG(QVariant, QVariant::fromValue(menu)), Q_ARG(QVariant, QVariant::fromValue(item))); Q_ASSERT(invokeResult); + Q_UNUSED(invokeResult); // FIXME - apparently we haven't upgraded the Qt on our unix Jenkins environments to 5.5.x }