diff --git a/.gitignore b/.gitignore index 3b44b99e68..aee74ebddc 100644 --- a/.gitignore +++ b/.gitignore @@ -46,4 +46,5 @@ libraries/audio-client/external/*/* gvr-interface/assets/oculussig* gvr-interface/libs/* -TAGS \ No newline at end of file +TAGS +*.md \ No newline at end of file diff --git a/BUILD_ANDROID.md b/BUILD_ANDROID.md index 6ff3160775..9f86e7e925 100644 --- a/BUILD_ANDROID.md +++ b/BUILD_ANDROID.md @@ -72,38 +72,6 @@ This should generate libcrypto and libssl in the root of the OpenSSL directory. If you have been building other components it is possible that the OpenSSL compile will fail based on the values other cross-compilations (tbb, bullet) have set. Ensure that you are in a new terminal window to avoid compilation errors from previously set environment variables. -####Intel Threading Building Blocks - -Download the [Intel Threading Building Blocks source](https://www.threadingbuildingblocks.org/download) and extract the tarball inside your `ANDROID_LIB_DIR`. Rename the extracted folder to `tbb`. - -NOTE: BEFORE YOU ATTEMPT TO CROSS-COMPILE TBB, DISCONNECT ANY DEVICES ADB WOULD DETECT. The tbb build process asks adb for a couple of strings, and if a device is plugged in extra characters get added that will cause ndk-build to fail with an error. - -From the tbb directory, execute the following commands. First, we build TBB using `ndk-build`. Then, the compiled libs are copied to a lib folder in the root of tbb directory. - -``` -cd jni -ndk-build target=android tbb tbbmalloc arch=arm -cd ../ -mkdir lib -cp `find . -name "*.so"` lib/ -``` - -####Soxr - -Download the [Soxr source](http://sourceforge.net/projects/soxr/) and extract the tarball inside your `ANDROID_LIB_DIR`. Rename the extracted folder to `soxr`. - -From the soxr directory, use cmake, along with the `android.toolchain.cmake` file (included in this repository under cmake/android) to cross-compile soxr for Android. Note that you will need ANDROID_NDK set in your environment before using the toolchain file. - -The full set of commands to build soxr for Android is shown below. It is a long command, make sure you copy the entire command (up to `-DBUILD_TESTS=0`). - -``` -cmake -DCMAKE_TOOLCHAIN_FILE=$FULL_PATH_TO_TOOLCHAIN -DCMAKE_INSTALL_PREFIX=. -DHAVE_WORDS_BIGENDIAN_EXITCODE=1 -DBUILD_TESTS=0 -make -make install -``` - -This will create the `lib` and `include` folders inside `ANDROID_LIB_DIR/soxr` that FindSoxr will look for. - ####Oculus Mobile SDK The Oculus Mobile SDK is optional, for Gear VR support. It is not required to compile gvr-interface. @@ -127,7 +95,6 @@ To put the Gear VR Service into developer mode you need an application with an O Once the application is on your device, go to `Settings->Application Manager->Gear VR Service->Manage Storage`. Tap on `VR Service Version` six times. It will scan your device to verify that you have an osig file in an application on your device, and then it will let you enable Developer mode. - ###CMake We use CMake to generate the makefiles that compile and deploy the Android APKs to your device. In order to create Makefiles for the Android targets, CMake requires that some environment variables are set, and that other variables are passed to it when it is run. diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 08945716ae..933e73e869 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -1,11 +1,5 @@ Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only Linux specific instructions are found in this file. -###Linux Specific Dependencies -* [freeglut](http://freeglut.sourceforge.net/) ~> 2.8.0 -* [zLib](http://www.zlib.net/) ~> 1.2.8 - -In general, as long as external dependencies are placed in OS standard locations, CMake will successfully find them during its run. When possible, you may choose to install depencies from your package manager of choice, or from source. - ###Qt5 Dependencies Should you choose not to install Qt5 via a package manager that handles dependencies for you, you may be missing some Qt5 dependencies. On Ubuntu, for example, the following additional packages are required: diff --git a/BUILD_OSX.md b/BUILD_OSX.md index 2d5460d39d..c199fe4c73 100644 --- a/BUILD_OSX.md +++ b/BUILD_OSX.md @@ -4,7 +4,7 @@ Please read the [general build guide](BUILD.md) for information on dependencies [Homebrew](http://brew.sh/) is an excellent package manager for OS X. It makes install of all hifi dependencies very simple. brew tap highfidelity/homebrew-formulas - brew install cmake openssl tbb libsoxr + brew install cmake openssl brew install highfidelity/formulas/qt5 brew link qt5 --force diff --git a/CMakeLists.txt b/CMakeLists.txt index bc67d622de..75282137dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,10 +86,33 @@ else () endif () endif () +# figure out where the qt dir is +get_filename_component(QT_DIR "${QT_CMAKE_PREFIX_PATH}/../../" ABSOLUTE) + set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT_CMAKE_PREFIX_PATH}) -# set our OS X deployment target to -set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8) +if (APPLE) + # set our OS X deployment target + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8) + + # find the 10.9 SDK path + find_path( + _OSX_DESIRED_SDK_PATH + NAME MacOSX10.9.sdk + HINTS ${OSX_SDK_PATH} + PATHS /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ + /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ + ) + + if (NOT _OSX_DESIRED_SDK_PATH) + message(FATAL_ERROR "Could not find OS X 10.9 SDK. Please pass OSX_SDK_PATH to CMake to point us to your SDKs directory.") + else () + message(STATUS "Found OS X 10.9 SDK at ${_OSX_DESIRED_SDK_PATH}/MacOSX10.9.sdk") + endif () + + # set that as the SDK to use + set(CMAKE_OSX_SYSROOT ${_OSX_DESIRED_SDK_PATH}/MacOSX10.9.sdk) +endif () # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -103,8 +126,15 @@ set(HIFI_LIBRARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries") # setup for find modules set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/") -set(MACRO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macros") -set(EXTERNAL_PROJECT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake/externals") +if (CMAKE_BUILD_TYPE) + string(TOUPPER ${CMAKE_BUILD_TYPE} UPPER_CMAKE_BUILD_TYPE) +else () + set(UPPER_CMAKE_BUILD_TYPE DEBUG) +endif () + +set(HIFI_CMAKE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +set(MACRO_DIR "${HIFI_CMAKE_DIR}/macros") +set(EXTERNAL_PROJECT_DIR "${HIFI_CMAKE_DIR}/externals") file(GLOB HIFI_CUSTOM_MACROS "cmake/macros/*.cmake") foreach(CUSTOM_MACRO ${HIFI_CUSTOM_MACROS}) @@ -118,6 +148,28 @@ if (ANDROID) endforeach() endif () +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_SOXR "Get Soxr library automatically as external project" 1) +option(GET_TBB "Get Threading Building Blocks library automatically as external project" 1) + +if (WIN32) + option(GET_GLEW "Get GLEW library automatically as external project" 1) +endif () + +option(GET_SDL2 "Get SDL2 library automatically as external project" 0) +option(GET_QXMPP "GET Qxmpp library automatically as external project" 0) + +if (WIN32) + add_paths_to_fixup_libs("${QT_DIR}/bin") +endif () + # add subdirectories for all targets if (NOT ANDROID) add_subdirectory(assignment-client) diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index b16314811b..ada534431a 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -2,7 +2,7 @@ set(TARGET_NAME assignment-client) setup_hifi_project(Core Gui Network Script Widgets) -add_dependency_external_project(glm) +add_dependency_external_projects(glm) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PRIVATE ${GLM_INCLUDE_DIRS}) @@ -17,4 +17,4 @@ if (UNIX) target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS}) endif (UNIX) -include_dependency_includes() +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/cmake/android/QtCreateAPK.cmake b/cmake/android/QtCreateAPK.cmake index a8543a5fbc..30ee2f57bd 100644 --- a/cmake/android/QtCreateAPK.cmake +++ b/cmake/android/QtCreateAPK.cmake @@ -26,7 +26,7 @@ macro(qt_create_apk) set(ANDROID_APK_THEME "") endif() - if (CMAKE_BUILD_TYPE MATCHES RELEASE) + if (UPPER_CMAKE_BUILD_TYPE MATCHES RELEASE) set(ANDROID_APK_DEBUGGABLE "false") set(ANDROID_APK_RELEASE_LOCAL ${ANDROID_APK_RELEASE}) else () @@ -39,9 +39,6 @@ macro(qt_create_apk) # create "strings.xml" configure_file("${ANDROID_THIS_DIRECTORY}/strings.xml.in" "${ANDROID_APK_BUILD_DIR}/res/values/strings.xml") - - # figure out where the qt dir is - get_filename_component(QT_DIR "${QT_CMAKE_PREFIX_PATH}/../../" ABSOLUTE) # find androiddeployqt find_program(ANDROID_DEPLOY_QT androiddeployqt HINTS "${QT_DIR}/bin") diff --git a/cmake/externals/bullet/CMakeLists.txt b/cmake/externals/bullet/CMakeLists.txt new file mode 100644 index 0000000000..d08ceb11b9 --- /dev/null +++ b/cmake/externals/bullet/CMakeLists.txt @@ -0,0 +1,93 @@ +set(EXTERNAL_NAME bullet) + +if (WIN32) + set(PLATFORM_CMAKE_ARGS "-DUSE_MSVC_RUNTIME_LIBRARY_DLL=1") +else () + set(PLATFORM_CMAKE_ARGS "-DBUILD_SHARED_LIBS=1") + + if (ANDROID) + list(APPEND PLATFORM_CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DANDROID_NATIVE_API_LEVEL=19") + elseif (APPLE) + list(APPEND PLATFORM_CMAKE_ARGS "-DCMAKE_INSTALL_NAME_DIR=/lib") + endif() +endif () + +include(ExternalProject) + +if (WIN32) + if (UPPER_CMAKE_BUILD_TYPE MATCHES DEBUG) + set(MSBUILD_CONFIGURATION Debug) + else () + set(MSBUILD_CONFIGURATION Release) + endif () + + find_program(MSBUILD_COMMAND msbuild PATHS "C:/Program Files (x86)/MSBUILD/12.0/Bin") + + ExternalProject_Add( + ${EXTERNAL_NAME} + URL https://bullet.googlecode.com/files/bullet-2.82-r2704.zip + URL_MD5 f5e8914fc9064ad32e0d62d19d33d977 + CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_DEMOS=0 -DUSE_GLUT=0 + BUILD_COMMAND ${MSBUILD_COMMAND} ALL_BUILD.vcxproj /p:Configuration=${MSBUILD_CONFIGURATION} + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 + BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build + ) +else () + ExternalProject_Add( + ${EXTERNAL_NAME} + URL http://bullet.googlecode.com/files/bullet-2.82-r2704.tgz + URL_MD5 70b3c8d202dee91a0854b4cbc88173e8 + CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX:PATH= -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_DEMOS=0 -DUSE_GLUT=0 + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 + BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build + ) +endif () + +ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) + +string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) + +set(BULLET_LIB_DIR "${INSTALL_DIR}/lib") + +if (APPLE OR UNIX OR ANDROID) + if (APPLE) + set(BULLET_LIB_EXT "dylib") + else () + set(BULLET_LIB_EXT "so") + endif () + + set(LIB_PREFIX "lib") +elseif (WIN32) + set(BULLET_LIB_EXT "lib") +endif () + +if (DEFINED BULLET_LIB_EXT) + if (NOT WIN32 OR UPPER_CMAKE_BUILD_TYPE MATCHES RELEASE) + set(_PRESENT_LIB_TYPE RELEASE) + set(_MISSING_LIB_TYPE DEBUG) + else () + set(_PRESENT_LIB_TYPE DEBUG) + set(_MISSING_LIB_TYPE RELEASE) + set(_LIB_NAME_SUFFIX _Debug) + endif () + + set(${EXTERNAL_NAME_UPPER}_DYNAMICS_LIBRARY_${_PRESENT_LIB_TYPE} ${BULLET_LIB_DIR}/${LIB_PREFIX}BulletDynamics${_LIB_NAME_SUFFIX}.${BULLET_LIB_EXT} CACHE FILEPATH "Bullet dynamics ${_PRESENT_LIB_TYPE} library location") + set(${EXTERNAL_NAME_UPPER}_DYNAMICS_LIBRARY_${_MISSING_LIB_TYPE} "" CACHE FILEPATH "Bullet dynamics ${_MISSING_LIB_TYPE} library location") + + set(${EXTERNAL_NAME_UPPER}_COLLISION_LIBRARY_${_PRESENT_LIB_TYPE} ${BULLET_LIB_DIR}/${LIB_PREFIX}BulletCollision${_LIB_NAME_SUFFIX}.${BULLET_LIB_EXT} CACHE FILEPATH "Bullet collision ${_PRESENT_LIB_TYPE} library location") + set(${EXTERNAL_NAME_UPPER}_COLLISION_LIBRARY_${_MISSING_LIB_TYPE} "" CACHE FILEPATH "Bullet collision ${_MISSING_LIB_TYPE} library location") + + set(${EXTERNAL_NAME_UPPER}_MATH_LIBRARY_${_PRESENT_LIB_TYPE} ${BULLET_LIB_DIR}/${LIB_PREFIX}LinearMath${_LIB_NAME_SUFFIX}.${BULLET_LIB_EXT} CACHE FILEPATH "Bullet math ${_PRESENT_LIB_TYPE} library location") + set(${EXTERNAL_NAME_UPPER}_MATH_LIBRARY_${_MISSING_LIB_TYPE} "" CACHE FILEPATH "Bullet math ${_MISSING_LIB_TYPE} library location") + + set(${EXTERNAL_NAME_UPPER}_SOFTBODY_LIBRARY_${_PRESENT_LIB_TYPE} ${BULLET_LIB_DIR}/${LIB_PREFIX}BulletSoftBody${_LIB_NAME_SUFFIX}.${BULLET_LIB_EXT} CACHE FILEPATH "Bullet softbody ${_PRESENT_LIB_TYPE} library location") + set(${EXTERNAL_NAME_UPPER}_SOFTBODY_LIBRARY_${_MISSING_LIB_TYPE} "" CACHE FILEPATH "Bullet softbody ${_MISSING_LIB_TYPE} library location") +endif () + +if (DEFINED ${EXTERNAL_NAME_UPPER}_DYNAMICS_LIBRARY_${_PRESENT_LIB_TYPE}) + set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIR ${INSTALL_DIR}/include/bullet CACHE PATH "Path to bullet include directory") +endif () \ No newline at end of file diff --git a/cmake/externals/glew/CMakeLists.txt b/cmake/externals/glew/CMakeLists.txt new file mode 100644 index 0000000000..0d80e7a789 --- /dev/null +++ b/cmake/externals/glew/CMakeLists.txt @@ -0,0 +1,26 @@ +if (WIN32) + set(EXTERNAL_NAME glew) + + include(ExternalProject) + ExternalProject_Add( + ${EXTERNAL_NAME} + URL http://hifi-public.s3.amazonaws.com/dependencies/glew-1.10.0-win32.zip + URL_MD5 37514e4e595a3b3dc587eee8f7e8ec2f + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + LOG_DOWNLOAD 1 + ) + + ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) + + string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) + set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE PATH "List of glew include directories") + + set(_LIB_DIR ${SOURCE_DIR}/lib/Release/Win32) + + set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${_LIB_DIR}/glew32.lib CACHE FILEPATH "Location of GLEW release library") + set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG "" CACHE FILEPATH "Location of GLEW debug library") + + set(${EXTERNAL_NAME_UPPER}_DLL_PATH ${SOURCE_DIR}/bin/Release/Win32 CACHE FILEPATH "Location of GLEW DLL") +endif () \ No newline at end of file diff --git a/cmake/externals/glm/CMakeLists.txt b/cmake/externals/glm/CMakeLists.txt index b1aed7dd7f..6e5b1ef870 100644 --- a/cmake/externals/glm/CMakeLists.txt +++ b/cmake/externals/glm/CMakeLists.txt @@ -3,13 +3,16 @@ set(EXTERNAL_NAME glm) include(ExternalProject) ExternalProject_Add( ${EXTERNAL_NAME} - PREFIX ${EXTERNAL_NAME} URL http://pkgs.fedoraproject.org/repo/pkgs/glm/glm-0.9.5.4.zip/fab76fc982b256b46208e5c750ed456a/glm-0.9.5.4.zip + URL_MD5 fab76fc982b256b46208e5c750ed456a + BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= - LOG_DOWNLOAD ON + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 ) ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) -set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/include CACHE TYPE STRING) \ No newline at end of file +set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/include CACHE PATH "List of glm include directories") \ No newline at end of file diff --git a/cmake/externals/gverb/CMakeLists.txt b/cmake/externals/gverb/CMakeLists.txt index a73b192fee..f5372f6895 100644 --- a/cmake/externals/gverb/CMakeLists.txt +++ b/cmake/externals/gverb/CMakeLists.txt @@ -7,19 +7,22 @@ endif () include(ExternalProject) ExternalProject_Add( ${EXTERNAL_NAME} - PREFIX ${EXTERNAL_NAME} URL http://hifi-public.s3.amazonaws.com/dependencies/gverb-master.zip + URL_MD5 8b16d586390a2102804e46b87820dfc6 CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH= - LOG_DOWNLOAD ON + BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 ) ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) -set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/include CACHE TYPE STRING) +set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/include CACHE FILEPATH "Path to gverb include directory") if (WIN32) - set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${INSTALL_DIR}/lib/gverb.lib CACHE TYPE STRING) + set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${INSTALL_DIR}/lib/gverb.lib CACHE FILEPATH "List of gverb libraries") else () - set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${INSTALL_DIR}/lib/libgverb.a CACHE TYPE STRING) + set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${INSTALL_DIR}/lib/libgverb.a CACHE FILEPATH "List of gverb libraries") endif () \ No newline at end of file diff --git a/cmake/externals/qxmpp/CMakeLists.txt b/cmake/externals/qxmpp/CMakeLists.txt new file mode 100644 index 0000000000..c8bbdba6ba --- /dev/null +++ b/cmake/externals/qxmpp/CMakeLists.txt @@ -0,0 +1,74 @@ +set(EXTERNAL_NAME qxmpp) + +# we need to find qmake inside QT_DIR +find_program(QMAKE_COMMAND NAME qmake PATHS ${QT_DIR}/bin NO_DEFAULT_PATH) + +if (NOT QMAKE_COMMAND) + message(FATAL_ERROR "Could not find qmake. Qxmpp cannot be compiled without qmake.") +endif () + +if (ANDROID) + set(ANDROID_CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DANDROID_NATIVE_API_LEVEL=19") +endif () + +if (WIN32) + find_program(PLATFORM_BUILD_COMMAND nmake PATHS "C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/bin") + + if (NOT PLATFORM_BUILD_COMMAND) + message(FATAL_ERROR "You asked CMake to grap QXmpp and build it, but nmake was not found. Please make sure the folder containing nmake.exe is in your PATH.") + endif () +else () + find_program(PLATFORM_BUILD_COMMAND make) +endif () + +include(ExternalProject) +ExternalProject_Add( + ${EXTERNAL_NAME} + URL http://qxmpp.googlecode.com/files/qxmpp-0.7.6.tar.gz + URL_MD5 ee45a97313306ded2ff0f6618a3ed1e1 + BUILD_IN_SOURCE 1 + PATCH_COMMAND patch -p2 -t -N --verbose < ${CMAKE_CURRENT_SOURCE_DIR}/qxmpp.patch + CONFIGURE_COMMAND ${QMAKE_COMMAND} PREFIX= + BUILD_COMMAND ${PLATFORM_BUILD_COMMAND} + INSTALL_COMMAND ${PLATFORM_BUILD_COMMAND} install + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 +) + +ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) + +if (CMAKE_GENERATOR STREQUAL Xcode) + find_program(DITTO_COMMAND ditto) + + ExternalProject_Add_Step( + ${EXTERNAL_NAME} + copy-from-xcode-install + COMMENT "Copying from /tmp/hifi.dst${INSTALL_DIR} to move install to proper location" + COMMAND ${DITTO_COMMAND} /tmp/hifi.dst${INSTALL_DIR} ${INSTALL_DIR} + DEPENDEES install + LOG 1 + ) +endif () + +string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) +set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/include CACHE FILEPATH "Path to Qxmpp include directory") + +set(_LIB_DIR ${INSTALL_DIR}/lib) + +if (WIN32) + set(_LIB_EXT "0.lib") + + set(${EXTERNAL_NAME_UPPER}_DLL_PATH ${_LIB_DIR} CACHE PATH "Location of QXmpp DLL") +else () + if (APPLE) + set(_LIB_EXT ".dylib") + else () + set(_LIB_EXT ".so") + endif () + + set(_LIB_PREFIX "lib") +endif () + +set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${_LIB_DIR}/${_LIB_PREFIX}qxmpp${_LIB_EXT} CACHE FILEPATH "Path to QXmpp release library") +set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG "" CACHE FILEPATH "Path to QXmpp debug library") diff --git a/cmake/externals/qxmpp/qxmpp.patch b/cmake/externals/qxmpp/qxmpp.patch new file mode 100644 index 0000000000..ca2f455817 --- /dev/null +++ b/cmake/externals/qxmpp/qxmpp.patch @@ -0,0 +1,13 @@ +diff --git a/qxmpp-0.7.6/src/src.pro b/qxmpp-0.7.6-patch/src/src.pro +index 954738c..8404c8c 100644 +--- a/qxmpp-0.7.6/src/src.pro ++++ b/qxmpp-0.7.6-patch/src/src.pro +@@ -4,7 +4,7 @@ QT -= gui + + TEMPLATE = lib + +-CONFIG += $$QXMPP_LIBRARY_TYPE ++CONFIG += $$QXMPP_LIBRARY_TYPE c++11 + DEFINES += QXMPP_BUILD + DEFINES += $$QXMPP_INTERNAL_DEFINES + INCLUDEPATH += $$QXMPP_INCLUDEPATH $$QXMPP_INTERNAL_INCLUDES diff --git a/cmake/externals/sdl2/CMakeLists.txt b/cmake/externals/sdl2/CMakeLists.txt new file mode 100644 index 0000000000..d2a021e833 --- /dev/null +++ b/cmake/externals/sdl2/CMakeLists.txt @@ -0,0 +1,68 @@ +set(EXTERNAL_NAME sdl2) + +include(ExternalProject) + +if (WIN32) + ExternalProject_Add( + ${EXTERNAL_NAME} + URL http://www.libsdl.org/release/SDL2-devel-2.0.3-VC.zip + URL_MD5 30a333bcbe94bc5016e8799c73e86233 + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + LOG_DOWNLOAD 1 + ) +elseif (APPLE) + ExternalProject_Add( + ${EXTERNAL_NAME} + URL http://hifi-public.s3.amazonaws.com/dependencies/SDL2-2.0.3-OSX.tar.gz + URL_MD5 64f888886268bdf1656ef1b4b7d7756d + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + LOG_DOWNLOAD 1 + ) +else () + if (ANDROID) + set(ANDROID_CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DANDROID_NATIVE_API_LEVEL=19") + endif () + + ExternalProject_Add( + ${EXTERNAL_NAME} + URL http://www.libsdl.org/release/SDL2-2.0.3.tar.gz + URL_MD5 fe6c61d2e9df9ef570e7e80c6e822537 + CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH= + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 + ) +endif () + +string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) + +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") +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 diff --git a/cmake/externals/soxr/CMakeLists.txt b/cmake/externals/soxr/CMakeLists.txt new file mode 100644 index 0000000000..d004cf9ccb --- /dev/null +++ b/cmake/externals/soxr/CMakeLists.txt @@ -0,0 +1,31 @@ +set(EXTERNAL_NAME soxr) + +if (ANDROID) + set(PLATFORM_CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DANDROID_NATIVE_API_LEVEL=19" "-DHAVE_WORDS_BIGENDIAN_EXITCODE=1") +endif () + +include(ExternalProject) +ExternalProject_Add( + ${EXTERNAL_NAME} + URL http://hifi-public.s3.amazonaws.com/dependencies/soxr-0.1.1.zip + URL_MD5 349b5b2f323a7380bc12186d98c77d1d + CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DBUILD_SHARED_LIBS=1 -DBUILD_TESTS=0 -DCMAKE_INSTALL_PREFIX:PATH= + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 + BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build +) + +ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) + +string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) +set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/include CACHE PATH "List of soxr include directories") + +if (WIN32) + set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${INSTALL_DIR}/lib/soxr.lib CACHE FILEPATH "List of soxr libraries") + set(${EXTERNAL_NAME_UPPER}_DLL_PATH ${INSTALL_DIR}/bin CACHE PATH "Path to soxr dll") +elseif (APPLE) + set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${INSTALL_DIR}/lib/libsoxr.dylib CACHE FILEPATH "List of soxr libraries") +else () + set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${INSTALL_DIR}/lib/libsoxr.so CACHE FILEPATH "List of soxr libraries") +endif () \ No newline at end of file diff --git a/cmake/externals/tbb/AndroidTBBLibCopy.cmake b/cmake/externals/tbb/AndroidTBBLibCopy.cmake new file mode 100644 index 0000000000..1c7697ab54 --- /dev/null +++ b/cmake/externals/tbb/AndroidTBBLibCopy.cmake @@ -0,0 +1,23 @@ +# +# AndroidTBBLibCopy.cmake +# cmake/externals/tbb +# +# Copyright 2015 High Fidelity, Inc. +# Created by Stephen Birarda on February 18, 2014 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +# first find the so files in the source dir +file(GLOB_RECURSE _TBB_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/build/*.so") + +# raise an error if we found none +if (NOT _TBB_LIBRARIES) + message(FATAL_ERROR "Did not find any compiled TBB libraries") +endif () + +# make the libs directory and copy the resulting files there +file(MAKE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/lib") +message(STATUS "Copying TBB Android libs to ${CMAKE_CURRENT_SOURCE_DIR}/lib") +file(COPY ${_TBB_LIBRARIES} DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/lib") \ No newline at end of file diff --git a/cmake/externals/tbb/CMakeLists.txt b/cmake/externals/tbb/CMakeLists.txt new file mode 100644 index 0000000000..06da60ac04 --- /dev/null +++ b/cmake/externals/tbb/CMakeLists.txt @@ -0,0 +1,105 @@ +set(EXTERNAL_NAME tbb) + +include(ExternalProject) + +if (ANDROID) + + find_program(NDK_BUILD_COMMAND NAMES ndk-build DOC "Path to the ndk-build command") + + ExternalProject_Add( + ${EXTERNAL_NAME} + URL http://hifi-public.s3.amazonaws.com/dependencies/tbb43_20150209oss_src.tgz + URL_MD5 f09c9abe8ec74e6558c1f89cebbe2893 + BUILD_COMMAND ${NDK_BUILD_COMMAND} --directory=jni target=android tbb tbbmalloc arch=arm + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND "" + INSTALL_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/AndroidTBBLibCopy.cmake + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 + ) +else () + if (APPLE) + set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb43_20150209oss_osx.tgz) + set(DOWNLOAD_MD5 3e683c19792582b61382e0d760ea5db2) + elseif (WIN32) + set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb43_20150209oss_win.zip) + set(DOWNLOAD_MD5 e19c184f2bb0e944fc5f397f1e34ca84) + else () + set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb43_20150209oss_lin.tgz) + set(DOWNLOAD_MD5 d9c2a6f7807df364be44a8c3c05e8457) + endif () + + ExternalProject_Add( + ${EXTERNAL_NAME} + URL ${DOWNLOAD_URL} + BUILD_COMMAND "" + CONFIGURE_COMMAND "" + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + ) +endif () + +ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) + +string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) + +if (APPLE) + set(_TBB_LIB_DIR "${SOURCE_DIR}/lib/libc++") + set(_LIB_PREFIX "lib") + set(_LIB_EXT "dylib") + + ExternalProject_Add_Step( + ${EXTERNAL_NAME} + change-install-name + COMMENT "Calling install_name_tool on TBB libraries to fix install name for dylib linking" + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/OSXTBBInstallNameChange.cmake + DEPENDEES install + WORKING_DIRECTORY + LOG 1 + ) + +elseif (WIN32) + set(_TBB_LIB_DIR "${SOURCE_DIR}/lib/ia32/vc12") + set(_LIB_EXT "lib") + set(${EXTERNAL_NAME_UPPER}_DLL_PATH "${SOURCE_DIR}/bin/ia32/vc12" CACHE PATH "Path to TBB DLLs") +elseif (ANDROID) + set(_TBB_LIB_DIR "${SOURCE_DIR}/lib") + set(_LIB_PREFIX "lib") + set(_LIB_EXT "so") +elseif (UNIX) + set(_LIB_PREFIX "lib") + set(_LIB_EXT "so") + + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_TBB_ARCH_DIR "intel64") + else() + set(_TBB_ARCH_DIR "ia32") + endif() + + execute_process( + COMMAND ${CMAKE_C_COMPILER} -dumpversion + OUTPUT_VARIABLE GCC_VERSION + ) + + if (GCC_VERSION VERSION_GREATER 4.4 OR GCC_VERSION VERSION_EQUAL 4.4) + set(_TBB_LIB_DIR "${SOURCE_DIR}/lib/${_TBB_ARCH_DIR}/gcc4.4") + elseif (GCC_VERSION VERSION_GREATER 4.1 OR GCC_VERSION VERSION_EQUAL 4.1) + set(_TBB_LIB_DIR "${SOURCE_DIR}/lib/${_TBB_ARCH_DIR}/gcc4.1") + else () + message(STATUS "Could not find a compatible version of Threading Building Blocks library for your compiler.") + endif () + + +endif () + +if (DEFINED _TBB_LIB_DIR) + set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb_debug.${_LIB_EXT} CACHE FILEPATH "TBB debug library location") + set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb.${_LIB_EXT} CACHE FILEPATH "TBB release library location") + set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc_debug.${_LIB_EXT} CACHE FILEPATH "TBB malloc debug library location") + set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_RELEASE ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc.${_LIB_EXT} CACHE FILEPATH "TBB malloc release library location") +endif () + +if (DEFINED ${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE) + set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE TYPE "List of tbb include directories") +endif () \ No newline at end of file diff --git a/cmake/externals/tbb/OSXTBBInstallNameChange.cmake b/cmake/externals/tbb/OSXTBBInstallNameChange.cmake new file mode 100644 index 0000000000..c263ed7d2e --- /dev/null +++ b/cmake/externals/tbb/OSXTBBInstallNameChange.cmake @@ -0,0 +1,59 @@ +# +# OSXTBBInstallNameChange.cmake +# cmake/externals/tbb +# +# Copyright 2015 High Fidelity, Inc. +# Created by Stephen Birarda on February 20, 2014 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +# first find the so files in the source dir +set(_TBB_LIBRARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/libc++) +file(GLOB_RECURSE _TBB_LIBRARIES "${_TBB_LIBRARY_DIR}/*.dylib") + +# raise an error if we found none +if (NOT _TBB_LIBRARIES) + message(FATAL_ERROR "Did not find any TBB libraries") +endif () + +# find the install_name_tool command +find_program(INSTALL_NAME_TOOL_COMMAND NAMES install_name_tool DOC "Path to the install_name_tool command") + +# find the lipo command +find_program(LIPO_COMMAND NAMES lipo DOC "Path to the lipo command") + +# enumerate the libraries +foreach(_TBB_LIBRARY ${_TBB_LIBRARIES}) + get_filename_component(_TBB_LIBRARY_FILENAME ${_TBB_LIBRARY} NAME) + + set(_LIPO_ARGS -remove i386 ${_TBB_LIBRARY_FILENAME} -output ${_TBB_LIBRARY_FILENAME}) + message(STATUS "${LIPO_COMMAND} ${_LIPO_ARGS}") + + # first we use lipo to remove i386 from each dylib + execute_process( + COMMAND ${LIPO_COMMAND} ${_LIPO_ARGS} + WORKING_DIRECTORY ${_TBB_LIBRARY_DIR} + ERROR_VARIABLE _LIPO_ERROR + ) + + if (_LIPO_ERROR) + message(FATAL_ERROR "There was an error removing i386 for ${_TBB_LIBRARY_FILENAME} - ${_LIPO_ERROR}") + endif () + + set(_INSTALL_NAME_ARGS ${INSTALL_NAME_TOOL_COMMAND} -id ${_TBB_LIBRARY} ${_TBB_LIBRARY_FILENAME}) + + message(STATUS "${INSTALL_NAME_COMMAND} ${_INSTALL_NAME_ARGS}") + + execute_process( + COMMAND ${INSTALL_NAME_COMMAND} ${_INSTALL_NAME_ARGS} + WORKING_DIRECTORY ${_TBB_LIBRARY_DIR} + ERROR_VARIABLE _INSTALL_NAME_ERROR + ) + + if (_INSTALL_NAME_ERROR) + message(FATAL_ERROR "There was an error changing install name for ${_TBB_LIBRARY_FILENAME} - ${_INSTALL_NAME_ERROR}") + endif () +endforeach() + diff --git a/cmake/macros/AddDependencyExternalProject.cmake b/cmake/macros/AddDependencyExternalProject.cmake deleted file mode 100644 index ff0ced411e..0000000000 --- a/cmake/macros/AddDependencyExternalProject.cmake +++ /dev/null @@ -1,25 +0,0 @@ -# -# SetupExternalProject.cmake -# cmake/macros -# -# Copyright 2015 High Fidelity, Inc. -# Created by Stephen Birarda on February 13, 2014 -# -# Distributed under the Apache License, Version 2.0. -# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -# - -macro(ADD_DEPENDENCY_EXTERNAL_PROJECT _PROJ_NAME) - - string(TOUPPER ${_PROJ_NAME} _PROJ_NAME_UPPER) - - if (NOT DEFINED GET_${_PROJ_NAME_UPPER} OR GET_${_PROJ_NAME_UPPER}) - if (NOT TARGET ${_PROJ_NAME}) - add_subdirectory(${EXTERNAL_PROJECT_DIR}/${_PROJ_NAME} ${CMAKE_BINARY_DIR}/externals/${_PROJ_NAME}) - endif () - - add_dependencies(${TARGET_NAME} ${_PROJ_NAME}) - - endif () - -endmacro() \ No newline at end of file diff --git a/cmake/macros/AddDependencyExternalProjects.cmake b/cmake/macros/AddDependencyExternalProjects.cmake new file mode 100644 index 0000000000..e859ef2db5 --- /dev/null +++ b/cmake/macros/AddDependencyExternalProjects.cmake @@ -0,0 +1,46 @@ +# +# AddDependencyExternalProjects.cmake +# cmake/macros +# +# Copyright 2015 High Fidelity, Inc. +# Created by Stephen Birarda on February 13, 2014 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +macro(ADD_DEPENDENCY_EXTERNAL_PROJECTS) + + foreach(_PROJ_NAME ${ARGN}) + + 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}) + # 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? + if (NOT TARGET ${_PROJ_NAME}) + add_subdirectory(${EXTERNAL_PROJECT_DIR}/${_PROJ_NAME} ${EXTERNALS_BINARY_DIR}/${_PROJ_NAME}) + + # did we end up adding an external project target? + if (NOT TARGET ${_PROJ_NAME}) + set(${_PROJ_NAME_UPPER}_EXTERNAL_PROJECT FALSE CACHE BOOL "Presence of ${_PROJ_NAME} as external target") + + message(STATUS "${_PROJ_NAME} was not added as an external project target for your OS." + " Either your system should already have the external library or you will need to install it separately.") + else () + set(${_PROJ_NAME_UPPER}_EXTERNAL_PROJECT TRUE CACHE BOOL "Presence of ${_PROJ_NAME} as external target") + endif () + endif () + + if (TARGET ${_PROJ_NAME}) + add_dependencies(${TARGET_NAME} ${_PROJ_NAME}) + endif () + + endif () + endif () + + endforeach() + +endmacro() \ No newline at end of file diff --git a/cmake/macros/AddPathsToFixupLibs.cmake b/cmake/macros/AddPathsToFixupLibs.cmake new file mode 100644 index 0000000000..913fcb7ee7 --- /dev/null +++ b/cmake/macros/AddPathsToFixupLibs.cmake @@ -0,0 +1,22 @@ +# +# AddPathsToFixupLibs.cmake +# cmake/macros +# +# Copyright 2015 High Fidelity, Inc. +# Created by Stephen Birarda on February 17, 2014 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +macro(add_paths_to_fixup_libs) + foreach(_PATH ${ARGN}) + set(_TEMP_LIB_PATHS ${FIXUP_LIBS}) + + list(APPEND _TEMP_LIB_PATHS ${_PATH}) + + list(REMOVE_DUPLICATES _TEMP_LIB_PATHS) + + set(FIXUP_LIBS ${_TEMP_LIB_PATHS} CACHE STRING "Paths for external libraries passed to fixup_bundle" FORCE) + endforeach() +endmacro() \ No newline at end of file diff --git a/cmake/macros/CopyDllsBesideWindowsExecutable.cmake b/cmake/macros/CopyDllsBesideWindowsExecutable.cmake new file mode 100644 index 0000000000..24996fde03 --- /dev/null +++ b/cmake/macros/CopyDllsBesideWindowsExecutable.cmake @@ -0,0 +1,43 @@ +# +# CopyDllsBesideWindowsExecutable.cmake +# cmake/macros +# +# Copyright 2015 High Fidelity, Inc. +# Created by Stephen Birarda on February 17, 2014 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +macro(COPY_DLLS_BESIDE_WINDOWS_EXECUTABLE) + + if (WIN32) + configure_file( + ${HIFI_CMAKE_DIR}/templates/FixupBundlePostBuild.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/FixupBundlePostBuild.cmake + @ONLY + ) + + # add a post-build command to copy DLLs beside the executable + add_custom_command( + TARGET ${TARGET_NAME} + POST_BUILD + COMMAND ${CMAKE_COMMAND} + -DBUNDLE_EXECUTABLE=$ + -P ${CMAKE_CURRENT_BINARY_DIR}/FixupBundlePostBuild.cmake + ) + + find_program(WINDEPLOYQT_COMMAND windeployqt PATHS ${QT_DIR}/bin NO_DEFAULT_PATH) + + if (NOT WINDEPLOYQT_COMMAND) + message(FATAL_ERROR "Could not find windeployqt at ${QT_DIR}/bin. windeployqt is required.") + endif () + + # add a post-build command to call windeployqt to copy Qt plugins + add_custom_command( + TARGET ${TARGET_NAME} + POST_BUILD + COMMAND CMD /C "SET PATH=%PATH%;${QT_DIR}/bin && ${WINDEPLOYQT_COMMAND} --no-libraries $" + ) + endif () +endmacro() \ No newline at end of file diff --git a/cmake/macros/IncludeBullet.cmake b/cmake/macros/IncludeBullet.cmake deleted file mode 100644 index 186e84d1ab..0000000000 --- a/cmake/macros/IncludeBullet.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# IncludeBullet.cmake -# -# 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 -# - -macro(INCLUDE_BULLET) - find_package(Bullet REQUIRED) - include_directories("${BULLET_INCLUDE_DIRS}") - if (APPLE OR UNIX) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${BULLET_INCLUDE_DIRS}") - endif() -endmacro(INCLUDE_BULLET) diff --git a/cmake/macros/IncludeDependencyIncludes.cmake b/cmake/macros/IncludeDependencyIncludes.cmake deleted file mode 100644 index 4474bdc53a..0000000000 --- a/cmake/macros/IncludeDependencyIncludes.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# -# IncludeDependencyIncludes.cmake -# cmake/macros -# -# Copyright 2014 High Fidelity, Inc. -# Created by Stephen Birarda on August 8, 2014 -# -# Distributed under the Apache License, Version 2.0. -# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -# - -macro(INCLUDE_DEPENDENCY_INCLUDES) - if (${TARGET_NAME}_DEPENDENCY_INCLUDES) - list(REMOVE_DUPLICATES ${TARGET_NAME}_DEPENDENCY_INCLUDES) - - # include those in our own target - include_directories(SYSTEM ${${TARGET_NAME}_DEPENDENCY_INCLUDES}) - - # set the property on this target so it can be retreived by targets linking to us - set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_INCLUDES "${${TARGET_NAME}_DEPENDENCY_INCLUDES}") - endif() -endmacro(INCLUDE_DEPENDENCY_INCLUDES) \ No newline at end of file diff --git a/cmake/macros/SetupExternalsBinaryDir.cmake b/cmake/macros/SetupExternalsBinaryDir.cmake new file mode 100644 index 0000000000..04bd00643c --- /dev/null +++ b/cmake/macros/SetupExternalsBinaryDir.cmake @@ -0,0 +1,32 @@ +# +# SetupExternalsBinaryDir.cmake +# cmake/macros +# +# Copyright 2015 High Fidelity, Inc. +# Created by Stephen Birarda on February 19, 2014 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +macro(SETUP_EXTERNALS_BINARY_DIR) + + # get a short name for the generator to use in the path + STRING(REGEX REPLACE " " "-" CMAKE_GENERATOR_FOLDER_NAME ${CMAKE_GENERATOR}) + + if (MSVC12) + set(CMAKE_GENERATOR_FOLDER_NAME "vc12") + else () + if (CMAKE_GENERATOR_FOLDER_NAME STREQUAL "Unix-Makefiles") + set(CMAKE_GENERATOR_FOLDER_NAME "makefiles") + endif () + endif () + + set(EXTERNALS_BINARY_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/build-ext") + if (ANDROID) + set(EXTERNALS_BINARY_DIR "${EXTERNALS_BINARY_ROOT_DIR}/android/${CMAKE_GENERATOR_FOLDER_NAME}") + else () + set(EXTERNALS_BINARY_DIR "${EXTERNALS_BINARY_ROOT_DIR}/${CMAKE_GENERATOR_FOLDER_NAME}") + endif () + +endmacro() \ No newline at end of file diff --git a/cmake/modules/FindBullet.cmake b/cmake/modules/FindBullet.cmake index c4f63860f2..9ef25f7e1e 100644 --- a/cmake/modules/FindBullet.cmake +++ b/cmake/modules/FindBullet.cmake @@ -85,9 +85,7 @@ set(BULLET_INCLUDE_DIRS ${BULLET_INCLUDE_DIR}) set(BULLET_LIBRARIES ${BULLET_DYNAMICS_LIBRARY} ${BULLET_COLLISION_LIBRARY} ${BULLET_MATH_LIBRARY} ${BULLET_SOFTBODY_LIBRARY}) find_package_handle_standard_args(Bullet "Could NOT find Bullet, try to set the path to Bullet root folder in the system variable BULLET_ROOT_DIR" - BULLET_DYNAMICS_LIBRARY BULLET_COLLISION_LIBRARY BULLET_MATH_LIBRARY BULLET_INCLUDE_DIRS + BULLET_DYNAMICS_LIBRARY BULLET_COLLISION_LIBRARY BULLET_MATH_LIBRARY BULLET_SOFTBODY_LIBRARY BULLET_LIBRARIES -) - - +) \ No newline at end of file diff --git a/cmake/modules/FindGLEW.cmake b/cmake/modules/FindGLEW.cmake index 363f346d09..e86db3fdac 100644 --- a/cmake/modules/FindGLEW.cmake +++ b/cmake/modules/FindGLEW.cmake @@ -24,16 +24,19 @@ if (WIN32) find_path(GLEW_INCLUDE_DIRS GL/glew.h PATH_SUFFIXES include HINTS ${GLEW_SEARCH_DIRS}) - find_library(GLEW_LIBRARY_RELEASE glew32s PATH_SUFFIXES "lib/Release/Win32" "lib" HINTS ${GLEW_SEARCH_DIRS}) - find_library(GLEW_LIBRARY_DEBUG glew32sd PATH_SUFFIXES "lib/Debug/Win32" "lib" HINTS ${GLEW_SEARCH_DIRS}) + find_library(GLEW_LIBRARY_RELEASE glew32 PATH_SUFFIXES "lib/Release/Win32" "lib" HINTS ${GLEW_SEARCH_DIRS}) + find_library(GLEW_LIBRARY_DEBUG glew32d PATH_SUFFIXES "lib/Debug/Win32" "lib" HINTS ${GLEW_SEARCH_DIRS}) + + find_path(GLEW_DLL_PATH glew32.dll PATH_SUFFIXES "bin/Release/Win32" HINTS ${GLEW_SEARCH_DIRS}) include(SelectLibraryConfigurations) select_library_configurations(GLEW) + + set(GLEW_LIBRARIES ${GLEW_LIBRARY}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_INCLUDE_DIRS GLEW_LIBRARIES GLEW_DLL_PATH) + + add_paths_to_fixup_libs(${GLEW_DLL_PATH}) endif () -set(GLEW_LIBRARIES ${GLEW_LIBRARY}) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_INCLUDE_DIRS GLEW_LIBRARIES) - -mark_as_advanced(GLEW_INCLUDE_DIRS GLEW_LIBRARIES GLEW_SEARCH_DIRS) \ No newline at end of file diff --git a/cmake/modules/FindGverb.cmake b/cmake/modules/FindGverb.cmake index e54fba8083..0c149a7ca1 100644 --- a/cmake/modules/FindGverb.cmake +++ b/cmake/modules/FindGverb.cmake @@ -22,4 +22,4 @@ find_path(GVERB_INCLUDE_DIRS gverb.h PATH_SUFFIXES include HINTS ${GVERB_SEARCH_ find_library(GVERB_LIBRARIES gverb PATH_SUFFIXES lib HINTS ${GVERB_SEARCH_DIRS}) include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(GVERB DEFAULT_MSG GVERB_INCLUDE_DIRS GVERB_LIBRARIES) \ No newline at end of file +find_package_handle_standard_args(Gverb DEFAULT_MSG GVERB_INCLUDE_DIRS GVERB_LIBRARIES) \ No newline at end of file diff --git a/cmake/modules/FindLeapMotion.cmake b/cmake/modules/FindLeapMotion.cmake index cb49ceb597..eafb031a07 100644 --- a/cmake/modules/FindLeapMotion.cmake +++ b/cmake/modules/FindLeapMotion.cmake @@ -20,6 +20,8 @@ find_path(LEAPMOTION_INCLUDE_DIRS Leap.h PATH_SUFFIXES include HINTS ${LEAPMOTIO if (WIN32) find_library(LEAPMOTION_LIBRARY_DEBUG Leapd PATH_SUFFIXES lib/x86 HINTS ${LEAPMOTION_SEARCH_DIRS}) find_library(LEAPMOTION_LIBRARY_RELEASE Leap PATH_SUFFIXES lib/x86 HINTS ${LEAPMOTION_SEARCH_DIRS}) + + find_path(LEAPMOTION_DLL_PATH Leap.dll PATH_SUFFIXES lib/x86 HINTS ${LEAPMOTION_SEARCH_DIRS}) elseif (APPLE) find_library(LEAPMOTION_LIBRARY_RELEASE Leap PATH_SUFFIXES lib HINTS ${LEAPMOTION_SEARCH_DIRS}) endif () @@ -27,9 +29,18 @@ endif () include(SelectLibraryConfigurations) select_library_configurations(LEAPMOTION) -set(LEAPMOTION_LIBRARIES "${LEAPMOTION_LIBRARY}") +set(LEAPMOTION_LIBRARIES ${LEAPMOTION_LIBRARY}) + +set(LEAPMOTION_REQUIREMENTS LEAPMOTION_INCLUDE_DIRS LEAPMOTION_LIBRARIES) +if (WIN32) + list(APPEND LEAPMOTION_REQUIREMENTS LEAPMOTION_DLL_PATH) +endif () include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(LeapMotion DEFAULT_MSG LEAPMOTION_INCLUDE_DIRS LEAPMOTION_LIBRARIES) +find_package_handle_standard_args(LeapMotion DEFAULT_MSG ${LEAPMOTION_REQUIREMENTS}) + +if (WIN32) + add_paths_to_fixup_libs(${LEAPMOTION_DLL_PATH}) +endif () mark_as_advanced(LEAPMOTION_INCLUDE_DIRS LEAPMOTION_LIBRARIES LEAPMOTION_SEARCH_DIRS) diff --git a/cmake/modules/FindOpenSSL.cmake b/cmake/modules/FindOpenSSL.cmake index 8298cc75b4..db3b2ba477 100644 --- a/cmake/modules/FindOpenSSL.cmake +++ b/cmake/modules/FindOpenSSL.cmake @@ -98,6 +98,9 @@ if (WIN32 AND NOT CYGWIN) select_library_configurations(SSL_EAY) set(OPENSSL_LIBRARIES ${SSL_EAY_LIBRARY} ${LIB_EAY_LIBRARY}) + + find_path(OPENSSL_DLL_PATH NAMES ssleay32.dll PATH_SUFFIXES "bin" ${_OPENSSL_ROOT_HINTS_AND_PATHS}) + elseif (MINGW) # same player, for MinGW set(LIB_EAY_NAMES libeay32) @@ -218,11 +221,15 @@ endif () include(FindPackageHandleStandardArgs) +set(OPENSSL_REQUIREMENTS OPENSSL_LIBRARIES OPENSSL_INCLUDE_DIR) +if (WIN32) + list(APPEND OPENSSL_REQUIREMENTS OPENSSL_DLL_PATH) +endif () + if (OPENSSL_VERSION) find_package_handle_standard_args(OpenSSL REQUIRED_VARS - OPENSSL_LIBRARIES - OPENSSL_INCLUDE_DIR + ${OPENSSL_REQUIREMENTS} VERSION_VAR OPENSSL_VERSION FAIL_MESSAGE @@ -230,9 +237,12 @@ if (OPENSSL_VERSION) ) else () find_package_handle_standard_args(OpenSSL "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR" - OPENSSL_LIBRARIES - OPENSSL_INCLUDE_DIR + ${OPENSSL_REQUIREMENTS} ) endif () +if (WIN32) + add_paths_to_fixup_libs(${OPENSSL_DLL_PATH}) +endif () + mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES OPENSSL_SEARCH_DIRS) diff --git a/cmake/modules/FindQxmpp.cmake b/cmake/modules/FindQxmpp.cmake index 8fbc63e9dc..5caa929427 100644 --- a/cmake/modules/FindQxmpp.cmake +++ b/cmake/modules/FindQxmpp.cmake @@ -21,11 +21,15 @@ include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") hifi_library_search_hints("qxmpp") -find_path(QXMPP_INCLUDE_DIRS QXmppClient.h PATH_SUFFIXES include/qxmpp HINTS ${QXMPP_SEARCH_DIRS}) +find_path(QXMPP_INCLUDE_DIRS qxmpp/QXmppClient.h PATH_SUFFIXES include HINTS ${QXMPP_SEARCH_DIRS}) find_library(QXMPP_LIBRARY_RELEASE NAMES qxmpp PATH_SUFFIXES lib HINTS ${QXMPP_SEARCH_DIRS}) find_library(QXMPP_LIBRARY_DEBUG NAMES qxmpp_d PATH_SUFFIXES lib HINTS ${QXMPP_SEARCH_DIRS}) +if (WIN32) + find_path(QXMPP_DLL_PATH NAMES qxmpp.dll PATH_SUFFIXES lib HINTS ${QXMPP_SEARCH_DIRS}) +endif () + find_package(Qt5 COMPONENTS Xml REQUIRED) include(SelectLibraryConfigurations) @@ -36,4 +40,6 @@ set(QXMPP_LIBRARIES "${QXMPP_LIBRARY}" Qt5::Xml) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(QXmpp DEFAULT_MSG QXMPP_INCLUDE_DIRS QXMPP_LIBRARIES QXMPP_LIBRARY) -mark_as_advanced(QXMPP_INCLUDE_DIRS QXMPP_LIBRARIES QXMPP_SEARCH_DIRS) \ No newline at end of file +if (QXMPP_DLL_PATH) + add_paths_to_fixup_libs(${QXMPP_DLL_PATH}) +endif () \ No newline at end of file diff --git a/cmake/modules/FindSDL2.cmake b/cmake/modules/FindSDL2.cmake index 6ef9ffa52a..1a089bcb60 100644 --- a/cmake/modules/FindSDL2.cmake +++ b/cmake/modules/FindSDL2.cmake @@ -138,6 +138,10 @@ IF(CMAKE_SIZEOF_VOID_P EQUAL 8) /opt/csw /opt ) + + if (WIN32) + find_path(SDL2_DLL_PATH SDL2.dll PATH_SUFFIXES lib/x64 HINTS ${SDL2_SEARCH_DIRS}) + endif () # On 32bit build find the 32bit libs ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) FIND_LIBRARY(SDL2_LIBRARY_TEMP SDL2 @@ -153,50 +157,12 @@ ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) /opt/csw /opt ) + + if (WIN32) + find_path(SDL2_DLL_PATH SDL2.dll PATH_SUFFIXES lib/x86 HINTS ${SDL2_SEARCH_DIRS}) + endif () ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) -IF(NOT SDL2_BUILDING_LIBRARY) - IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") - # Non-OS X framework versions expect you to also dynamically link to - # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms - # seem to provide SDL2main for compatibility even though they don't - # necessarily need it. - # Lookup the 64 bit libs on x64 - IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - FIND_LIBRARY(SDL2MAIN_LIBRARY - NAMES SDL2main - HINTS - ${SDL2_SEARCH_DIRS} - $ENV{SDL2} - PATH_SUFFIXES lib64 lib - lib/x64 - x86_64-w64-mingw32/lib - PATHS - /sw - /opt/local - /opt/csw - /opt - ) - # On 32bit build find the 32bit libs - ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) - FIND_LIBRARY(SDL2MAIN_LIBRARY - NAMES SDL2main - HINTS - ${SDL2_SEARCH_DIRS} - $ENV{SDL2} - PATH_SUFFIXES lib - lib/x86 - i686-w64-mingw32/lib - PATHS - /sw - /opt/local - /opt/csw - /opt - ) - ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) - ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") -ENDIF(NOT SDL2_BUILDING_LIBRARY) - # SDL2 may require threads on your system. # The Apple build may not need an explicit flag because one of the # frameworks may already provide it. @@ -214,13 +180,6 @@ ENDIF(MINGW) SET(SDL2_FOUND "NO") IF(SDL2_LIBRARY_TEMP) - # For SDL2main - IF(NOT SDL2_BUILDING_LIBRARY) - IF(SDL2MAIN_LIBRARY) - SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) - ENDIF(SDL2MAIN_LIBRARY) - ENDIF(NOT SDL2_BUILDING_LIBRARY) - # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. # CMake doesn't display the -framework Cocoa string in the UI even # though it actually is there if I modify a pre-used variable. @@ -253,4 +212,13 @@ ENDIF(SDL2_LIBRARY_TEMP) INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) +set(SDL2_REQUIREMENTS SDL2_LIBRARY SDL2_INCLUDE_DIR) +if (WIN32) + list(APPEND SDL2_REQUIREMENTS SDL2_DLL_PATH) +endif () + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS ${SDL2_REQUIREMENTS}) + +if (WIN32) + add_paths_to_fixup_libs(${SDL2_DLL_PATH}) +endif () diff --git a/cmake/modules/FindSixense.cmake b/cmake/modules/FindSixense.cmake index f772c42e41..0f4346c53d 100644 --- a/cmake/modules/FindSixense.cmake +++ b/cmake/modules/FindSixense.cmake @@ -32,14 +32,27 @@ elseif (UNIX) elseif (WIN32) find_library(SIXENSE_LIBRARY_RELEASE lib/win32/release_dll/sixense.lib HINTS ${SIXENSE_SEARCH_DIRS}) find_library(SIXENSE_LIBRARY_DEBUG lib/win32/debug_dll/sixensed.lib HINTS ${SIXENSE_SEARCH_DIRS}) + + find_path(SIXENSE_DEBUG_DLL_PATH sixensed.dll PATH_SUFFIXES bin/win32/debug_dll HINTS ${SIXENSE_SEARCH_DIRS}) + find_path(SIXENSE_RELEASE_DLL_PATH sixense.dll PATH_SUFFIXES bin/win32/release_dll HINTS ${SIXENSE_SEARCH_DIRS}) + find_path(SIXENSE_DEVICE_DLL_PATH DeviceDLL.dll PATH_SUFFIXES samples/win32/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_INCLUDE_DIRS SIXENSE_LIBRARIES) +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 () mark_as_advanced(SIXENSE_LIBRARIES SIXENSE_INCLUDE_DIRS SIXENSE_SEARCH_DIRS) diff --git a/cmake/modules/FindSoxr.cmake b/cmake/modules/FindSoxr.cmake index 367022e9ec..df6ad8050e 100644 --- a/cmake/modules/FindSoxr.cmake +++ b/cmake/modules/FindSoxr.cmake @@ -24,7 +24,20 @@ hifi_library_search_hints("soxr") find_path(SOXR_INCLUDE_DIRS soxr.h PATH_SUFFIXES include HINTS ${SOXR_SEARCH_DIRS}) find_library(SOXR_LIBRARIES NAMES soxr PATH_SUFFIXES lib HINTS ${SOXR_SEARCH_DIRS}) +if (WIN32) + find_path(SOXR_DLL_PATH soxr.dll PATH_SUFFIXES bin HINTS ${SOXR_SEARCH_DIRS}) +endif() + +set(SOXR_REQUIREMENTS SOXR_INCLUDE_DIRS SOXR_LIBRARIES) +if (WIN32) + list(APPEND SOXR_REQUIREMENTS SOXR_DLL_PATH) +endif () + include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(SOXR DEFAULT_MSG SOXR_INCLUDE_DIRS SOXR_LIBRARIES) +find_package_handle_standard_args(Soxr DEFAULT_MSG ${SOXR_REQUIREMENTS}) + +if (WIN32) + add_paths_to_fixup_libs(${SOXR_DLL_PATH}) +endif () mark_as_advanced(SOXR_INCLUDE_DIRS SOXR_LIBRARIES SOXR_SEARCH_DIRS) \ No newline at end of file diff --git a/cmake/modules/FindTBB.cmake b/cmake/modules/FindTBB.cmake index 03ac99b73c..4d4b3ca504 100644 --- a/cmake/modules/FindTBB.cmake +++ b/cmake/modules/FindTBB.cmake @@ -56,6 +56,9 @@ elseif (WIN32) endif() set(_TBB_LIB_DIR "lib/${_TBB_ARCH_DIR}/vc12") + + find_path(TBB_DLL_PATH tbb_debug.dll PATH_SUFFIXES "bin/${_TBB_ARCH_DIR}/vc12" HINTS ${TBB_SEARCH_DIRS}) + elseif (ANDROID) set(_TBB_DEFAULT_INSTALL_DIR "/tbb") set(_TBB_LIB_NAME "tbb") @@ -77,6 +80,15 @@ include(FindPackageHandleStandardArgs) select_library_configurations(TBB) select_library_configurations(TBB_MALLOC) -find_package_handle_standard_args(TBB DEFAULT_MSG TBB_LIBRARY TBB_MALLOC_LIBRARY TBB_INCLUDE_DIRS) +set(TBB_REQUIREMENTS TBB_LIBRARY TBB_MALLOC_LIBRARY TBB_INCLUDE_DIRS) +if (WIN32) + list(APPEND TBB_REQUIREMENTS TBB_DLL_PATH) +endif () + +find_package_handle_standard_args(TBB DEFAULT_MSG ${TBB_REQUIREMENTS}) + +if (WIN32) + add_paths_to_fixup_libs(${TBB_DLL_PATH}) +endif () set(TBB_LIBRARIES ${TBB_LIBRARY} ${TBB_MALLOC_LIBRARY}) diff --git a/cmake/templates/FixupBundlePostBuild.cmake.in b/cmake/templates/FixupBundlePostBuild.cmake.in new file mode 100644 index 0000000000..7d98e9796c --- /dev/null +++ b/cmake/templates/FixupBundlePostBuild.cmake.in @@ -0,0 +1,14 @@ +# +# FixupBundlePostBuild.cmake.in +# cmake/templates +# +# Copyright 2015 High Fidelity, Inc. +# Created by Stephen Birarda on February 13, 2014 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +include(BundleUtilities) +message(STATUS "FIXUP_LIBS for fixup_bundle called for bundle ${BUNDLE_EXECUTABLE} are @FIXUP_LIBS@") +fixup_bundle("${BUNDLE_EXECUTABLE}" "" "@FIXUP_LIBS@") \ No newline at end of file diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index 421a1da2d4..4ff3c1cce1 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -52,4 +52,4 @@ include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") # append OpenSSL to our list of libraries to link target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES}) -include_dependency_includes() \ No newline at end of file +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/examples/editEntities.js b/examples/editEntities.js index 61100b4556..9b13b167e7 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -396,6 +396,10 @@ var toolBar = (function () { return handled; } + Window.domainChanged.connect(function() { + that.setActive(false); + }); + that.cleanup = function () { toolBar.cleanup(); }; diff --git a/examples/notifications.js b/examples/notifications.js index f9d2ba83ed..27192ed789 100644 --- a/examples/notifications.js +++ b/examples/notifications.js @@ -38,11 +38,13 @@ // function onIncomingMessage(user, message) { // //do stuff here; // var text = "This is a notification"; -// wordWrap(text); +// var wrappedText = wordWrap(text); +// createNotification(wrappedText, NotificationType.SNAPSHOT); // } // // This new function must call wordWrap(text) if the length of message is longer than 42 chars or unknown. -// wordWrap() will format the text to fit the notifications overlay and send it to createNotification(text). +// wordWrap() will format the text to fit the notifications overlay and return it +// after that we will send it to createNotification(text). // If the message is 42 chars or less you should bypass wordWrap() and call createNotification() directly. @@ -50,12 +52,12 @@ // // 1. Add a key to the keyPressEvent(key). // 2. Declare a text string. -// 3. Call createNotifications(text) parsing the text. +// 3. Call createNotifications(text, NotificationType) parsing the text. // example: // var welcome; // if (key.text == "q") { //queries number of users online // var welcome = "There are " + GlobalServices.onlineUsers.length + " users online now."; -// createNotification(welcome); +// createNotification(welcome, NotificationType.USERS_ONLINE); // } Script.include("./libraries/globals.js"); Script.include("./libraries/soundArray.js"); @@ -83,6 +85,46 @@ var last_users = GlobalServices.onlineUsers; var users = []; var ctrlIsPressed = false; var ready = true; +var MENU_NAME = 'Tools > Notifications'; +var PLAY_NOTIFICATION_SOUNDS_MENU_ITEM = "Play Notification Sounds"; +var NOTIFICATION_MENU_ITEM_POST = " Notifications"; +var PLAY_NOTIFICATION_SOUNDS_SETTING = "play_notification_sounds"; +var PLAY_NOTIFICATION_SOUNDS_TYPE_SETTING_PRE = "play_notification_sounds_type_"; + +var NotificationType = { + UNKNOWN: 0, + USER_JOINS: 1, + USER_LEAVES: 2, + MUTE_TOGGLE: 3, + CHAT_MENTION: 4, + USERS_ONLINE: 5, + SNAPSHOT: 6, + WINDOW_RESIZE: 7, + properties: [ + { text: "User Join" }, + { text: "User Leave" }, + { text: "Mute Toggle" }, + { text: "Chat Mention" }, + { text: "Users Online" }, + { text: "Snapshot" }, + { text: "Window Resize" } + ], + getTypeFromMenuItem: function(menuItemName) { + if (menuItemName.substr(menuItemName.length - NOTIFICATION_MENU_ITEM_POST.length) !== NOTIFICATION_MENU_ITEM_POST) { + return NotificationType.UNKNOWN; + } + var preMenuItemName = menuItemName.substr(0, menuItemName.length - NOTIFICATION_MENU_ITEM_POST.length); + for (type in this.properties) { + if (this.properties[type].text === preMenuItemName) { + return parseInt(type) + 1; + } + } + return NotificationType.UNKNOWN; + }, + getMenuString: function(type) { + return this.properties[type - 1].text + NOTIFICATION_MENU_ITEM_POST; + } +}; var randomSounds = new SoundArray({ localOnly: true }, true); var numberOfSounds = 2; @@ -90,15 +132,6 @@ for (var i = 1; i <= numberOfSounds; i++) { randomSounds.addSound(HIFI_PUBLIC_BUCKET + "sounds/UI/notification-general" + i + ".raw"); } -// When our script shuts down, we should clean up all of our overlays -function scriptEnding() { - for (i = 0; i < notifications.length; i++) { - Overlays.deleteOverlay(notifications[i]); - Overlays.deleteOverlay(buttons[i]); - } -} -Script.scriptEnding.connect(scriptEnding); - var notifications = []; var buttons = []; var times = []; @@ -211,8 +244,6 @@ function notify(notice, button, height) { positions, last; - randomSounds.playRandom(); - if (isOnHMD) { // Calculate 3D values from 2D overlay properties. @@ -257,7 +288,7 @@ function notify(notice, button, height) { } // This function creates and sizes the overlays -function createNotification(text) { +function createNotification(text, notificationType) { var count = (text.match(/\n/g) || []).length, breakPoint = 43.0, // length when new line is added extraLine = 0, @@ -307,6 +338,12 @@ function createNotification(text) { alpha: backgroundAlpha }; + if (Menu.isOptionChecked(PLAY_NOTIFICATION_SOUNDS_MENU_ITEM) && + Menu.isOptionChecked(NotificationType.getMenuString(notificationType))) + { + randomSounds.playRandom(); + } + notify(noticeProperties, buttonProperties, height); } @@ -345,8 +382,7 @@ function stringDivider(str, slotWidth, spaceReplacer) { // formats string to add newline every 43 chars function wordWrap(str) { - var result = stringDivider(str, 43.0, "\n"); - createNotification(result); + return stringDivider(str, 43.0, "\n"); } // This fires a notification on window resize @@ -358,7 +394,7 @@ function checkSize() { windowDimensions = Controller.getViewportDimensions(); overlayLocationX = (windowDimensions.x - (width + 60.0)); buttonLocationX = overlayLocationX + (width - 35.0); - createNotification(windowResize); + createNotification(windowResize, NotificationType.WINDOW_RESIZE); } } @@ -442,10 +478,7 @@ var STARTUP_TIMEOUT = 500, // ms // This reports the number of users online at startup function reportUsers() { - var welcome; - - welcome = "Welcome! There are " + GlobalServices.onlineUsers.length + " users online now."; - createNotification(welcome); + createNotification("Welcome! There are " + GlobalServices.onlineUsers.length + " users online now.", NotificationType.USERS_ONLINE); } function finishStartup() { @@ -472,13 +505,13 @@ function onOnlineUsersChanged(users) { if (!isStartingUp()) { // Skip user notifications at startup. for (i = 0; i < users.length; i += 1) { if (last_users.indexOf(users[i]) === -1.0) { - createNotification(users[i] + " has joined"); + createNotification(users[i] + " has joined", NotificationType.USER_JOINS); } } for (i = 0; i < last_users.length; i += 1) { if (users.indexOf(last_users[i]) === -1.0) { - createNotification(last_users[i] + " has left"); + createNotification(last_users[i] + " has left", NotificationType.USER_LEAVES); } } } @@ -497,7 +530,7 @@ function onIncomingMessage(user, message) { thisAlert = user + ": " + myMessage; if (myMessage.indexOf(alertMe) > -1.0) { - wordWrap(thisAlert); + CreateNotification(wordWrap(thisAlert), NotificationType.CHAT_MENTION); } } @@ -506,9 +539,9 @@ function onMuteStateChanged() { var muteState, muteString; - muteState = AudioDevice.getMuted() ? "muted" : "unmuted"; + muteState = AudioDevice.getMuted() ? "muted" : "unmuted"; muteString = "Microphone is now " + muteState; - createNotification(muteString); + createNotification(muteString, NotificationType.MUTE_TOGGLE); } // handles mouse clicks on buttons @@ -551,25 +584,58 @@ function keyPressEvent(key) { if (key.text === "q") { //queries number of users online numUsers = GlobalServices.onlineUsers.length; welcome = "There are " + numUsers + " users online now."; - createNotification(welcome); + createNotification(welcome, NotificationType.USERS_ONLINE); } if (key.text === "s") { if (ctrlIsPressed === true) { noteString = "Snapshot taken."; - createNotification(noteString); + createNotification(noteString, NotificationType.SNAPSHOT); } } } +function setup() { + Menu.addMenu(MENU_NAME); + var checked = Settings.getValue(PLAY_NOTIFICATION_SOUNDS_SETTING); + checked = checked === '' ? true : checked; + Menu.addMenuItem({ + menuName: MENU_NAME, + menuItemName: PLAY_NOTIFICATION_SOUNDS_MENU_ITEM, + isCheckable: true, + isChecked: Settings.getValue(PLAY_NOTIFICATION_SOUNDS_SETTING) + }); + Menu.addSeparator(MENU_NAME, "Play sounds for:"); + for (type in NotificationType.properties) { + checked = Settings.getValue(PLAY_NOTIFICATION_SOUNDS_TYPE_SETTING_PRE + (parseInt(type) + 1)); + checked = checked === '' ? true : checked; + Menu.addMenuItem({ + menuName: MENU_NAME, + menuItemName: NotificationType.properties[type].text + NOTIFICATION_MENU_ITEM_POST, + isCheckable: true, + isChecked: checked + }); + } +} + // When our script shuts down, we should clean up all of our overlays function scriptEnding() { - var i; - - for (i = 0; i < notifications.length; i += 1) { + for (var i = 0; i < notifications.length; i++) { Overlays.deleteOverlay(notifications[i]); Overlays.deleteOverlay(buttons[i]); } + Menu.removeMenu(MENU_NAME); +} + +function menuItemEvent(menuItem) { + if (menuItem === PLAY_NOTIFICATION_SOUNDS_MENU_ITEM) { + Settings.setValue(PLAY_NOTIFICATION_SOUNDS_SETTING, Menu.isOptionChecked(PLAY_NOTIFICATION_SOUNDS_MENU_ITEM)); + return; + } + var notificationType = NotificationType.getTypeFromMenuItem(menuItem); + if (notificationType !== notificationType.UNKNOWN) { + Settings.setValue(PLAY_NOTIFICATION_SOUNDS_TYPE_SETTING_PRE + notificationType, Menu.isOptionChecked(menuItem)); + } } AudioDevice.muteToggled.connect(onMuteStateChanged); @@ -580,3 +646,6 @@ GlobalServices.incomingMessage.connect(onIncomingMessage); Controller.keyReleaseEvent.connect(keyReleaseEvent); Script.update.connect(update); Script.scriptEnding.connect(scriptEnding); +Menu.menuItemEvent.connect(menuItemEvent); + +setup(); diff --git a/gvr-interface/CMakeLists.txt b/gvr-interface/CMakeLists.txt index de0b66165b..a986fcae0d 100644 --- a/gvr-interface/CMakeLists.txt +++ b/gvr-interface/CMakeLists.txt @@ -24,12 +24,11 @@ endif () include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) -add_dependency_external_project(glm) +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) -include_dependency_includes() if (ANDROID) find_package(LibOVR) @@ -87,4 +86,6 @@ if (ANDROID) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/templates/hockeyapp.xml.in" "${ANDROID_APK_BUILD_DIR}/res/values/hockeyapp.xml") qt_create_apk() -endif (ANDROID) \ No newline at end of file +endif (ANDROID) + +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/ice-server/CMakeLists.txt b/ice-server/CMakeLists.txt index 6a8ca5bd9f..13d89fc4a2 100644 --- a/ice-server/CMakeLists.txt +++ b/ice-server/CMakeLists.txt @@ -6,4 +6,4 @@ setup_hifi_project(Network) # link the shared hifi libraries link_hifi_libraries(embedded-webserver networking shared) -include_dependency_includes() \ No newline at end of file +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 7d581284e5..ee41648758 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -32,8 +32,6 @@ elseif (WIN32) set(GL_HEADERS "#include \n#include \n#include ") endif () -include_bullet() - # create the InterfaceConfig.h file based on GL_HEADERS above configure_file(InterfaceConfig.h.in "${PROJECT_BINARY_DIR}/includes/InterfaceConfig.h") configure_file(InterfaceVersion.h.in "${PROJECT_BINARY_DIR}/includes/InterfaceVersion.h") @@ -78,7 +76,7 @@ if (APPLE) set(MACOSX_BUNDLE_BUNDLE_NAME Interface) set(MACOSX_BUNDLE_GUI_IDENTIFIER io.highfidelity.Interface) - if (${CMAKE_BUILD_TYPE} MATCHES "RELEASE") + if (UPPER_CMAKE_BUILD_TYPE MATCHES RELEASE OR UPPER_CMAKE_BUILD_TYPE MATCHES RELWITHDEBINFO) set(ICON_FILENAME "interface.icns") else () set(ICON_FILENAME "interface-beta.icns") @@ -108,17 +106,20 @@ endif() add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS} ${QM}) # set up the external glm library -add_dependency_external_project(glm) +add_dependency_external_projects(glm bullet) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PRIVATE ${GLM_INCLUDE_DIRS}) +find_package(Bullet REQUIRED) +target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BULLET_INCLUDE_DIRS}) +target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) + # link required hifi libraries link_hifi_libraries(shared octree environment gpu model fbx metavoxels networking entities avatars audio audio-client animation script-engine physics render-utils entities-renderer) -# find any optional and required libraries -find_package(ZLIB REQUIRED) +add_dependency_external_projects(sdl2 qxmpp) # perform standard include and linking for found externals foreach(EXTERNAL ${OPTIONAL_EXTERNALS}) @@ -175,15 +176,20 @@ if (RTMIDI_FOUND AND NOT DISABLE_RTMIDI AND APPLE) endif () if (QXMPP_FOUND AND NOT DISABLE_QXMPP AND WIN32) - # assume we're linking a static Qt on windows - add_definitions(-DQXMPP_STATIC) + if (NOT QXMPP_DLL_PATH) + # if we have no QXmpp DLL path, assume we're linking a static QXmpp on windows + add_definitions(-DQXMPP_STATIC) + else () + # otherwise assume we are linking a dynamic QXmpp + add_definitions(-DQXMPP_SHARED) + endif () endif () # include headers for interface and InterfaceConfig. include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes") target_link_libraries( - ${TARGET_NAME} ${ZLIB_LIBRARIES} + ${TARGET_NAME} Qt5::Gui Qt5::Network Qt5::Multimedia Qt5::OpenGL Qt5::Script Qt5::Svg Qt5::WebKitWidgets ) @@ -220,13 +226,11 @@ else (APPLE) # link target to external libraries if (WIN32) + add_dependency_external_projects(glew) find_package(GLEW REQUIRED) - include_directories(${GLEW_INCLUDE_DIRS}) + target_include_directories(${TARGET_NAME} PRIVATE ${GLEW_INCLUDE_DIRS}) - # we're using static GLEW, so define GLEW_STATIC - add_definitions(-DGLEW_STATIC) - - target_link_libraries(${TARGET_NAME} ${GLEW_LIBRARIES} "${NSIGHT_LIBRARIES}" wsock32.lib opengl32.lib Winmm.lib) + target_link_libraries(${TARGET_NAME} ${GLEW_LIBRARIES} ${NSIGHT_LIBRARIES} wsock32.lib opengl32.lib Winmm.lib) # try to find the Nsight package and add it to the build if we find it find_package(NSIGHT) @@ -239,5 +243,4 @@ else (APPLE) endif() endif (APPLE) -# link any dependencies bubbled up from our linked dependencies -include_dependency_includes() +copy_dlls_beside_windows_executable() diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a7e73da1bd..0bdd8f8f53 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -215,7 +215,6 @@ bool setupEssentials(int& argc, char** argv) { DependencyManager::registerInheritance(); // Set dependencies - auto glCanvas = DependencyManager::set(); auto addressManager = DependencyManager::set(); auto nodeList = DependencyManager::set(NodeType::Agent, listenPort); auto geometryCache = DependencyManager::set(); @@ -307,7 +306,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : Model::setAbstractViewStateInterface(this); // The model class will sometimes need to know view state details from us - auto glCanvas = DependencyManager::get(); auto nodeList = DependencyManager::get(); _myAvatar = DependencyManager::get()->getMyAvatar(); @@ -447,16 +445,16 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : ResourceCache::setRequestLimit(3); - _window->setCentralWidget(glCanvas.data()); + _window->setCentralWidget(_glWidget); _window->restoreGeometry(); _window->setVisible(true); - glCanvas->setFocusPolicy(Qt::StrongFocus); - glCanvas->setFocus(); + _glWidget->setFocusPolicy(Qt::StrongFocus); + _glWidget->setFocus(); // enable mouse tracking; otherwise, we only get drag events - glCanvas->setMouseTracking(true); + _glWidget->setMouseTracking(true); _toolWindow = new ToolWindow(); _toolWindow->setWindowFlags(_toolWindow->windowFlags() | Qt::WindowStaysOnTopHint); @@ -474,7 +472,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : checkVersion(); - _overlays.init(glCanvas.data()); // do this before scripts load + _overlays.init(); // do this before scripts load _runningScriptsWidget->setRunningScripts(getRunningScripts()); connect(_runningScriptsWidget, &RunningScriptsWidget::stopScriptName, this, &Application::stopScript); @@ -533,6 +531,10 @@ void Application::aboutToQuit() { } void Application::cleanupBeforeQuit() { + _datagramProcessor.shutdown(); // tell the datagram processor we're shutting down, so it can short circuit + _entities.shutdown(); // tell the entities system we're shutting down, so it will stop running scripts + ScriptEngine::stopAllScripts(this); // stop all currently running global scripts + // first stop all timers directly or by invokeMethod // depending on what thread they run in locationUpdateTimer->stop(); @@ -580,8 +582,6 @@ Application::~Application() { _entities.getTree()->setSimulation(NULL); tree->unlock(); - qInstallMessageHandler(NULL); - // ask the datagram processing thread to quit and wait until it is done _nodeThread->quit(); _nodeThread->wait(); @@ -595,15 +595,13 @@ Application::~Application() { ModelEntityItem::cleanupLoadedAnimations() ; - DependencyManager::destroy(); - - qDebug() << "start destroying ResourceCaches Application::~Application() line:" << __LINE__; DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); - qDebug() << "done destroying ResourceCaches Application::~Application() line:" << __LINE__; + + qInstallMessageHandler(NULL); // NOTE: Do this as late as possible so we continue to get our log messages } void Application::initializeGL() { @@ -688,7 +686,7 @@ void Application::paintGL() { if (OculusManager::isConnected()) { DependencyManager::get()->setFrameBufferSize(OculusManager::getRenderTargetSize()); } else { - QSize fbSize = DependencyManager::get()->getDeviceSize() * getRenderResolutionScale(); + QSize fbSize = _glWidget->getDeviceSize() * getRenderResolutionScale(); DependencyManager::get()->setFrameBufferSize(fbSize); } @@ -1055,8 +1053,7 @@ void Application::keyPressEvent(QKeyEvent* event) { if (isShifted) { _viewFrustum.setFocalLength(_viewFrustum.getFocalLength() - 0.1f); if (TV3DManager::isConnected()) { - auto glCanvas = DependencyManager::get(); - TV3DManager::configureCamera(_myCamera, glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight()); + TV3DManager::configureCamera(_myCamera, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); } } else { _myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(-0.001, 0, 0)); @@ -1068,8 +1065,7 @@ void Application::keyPressEvent(QKeyEvent* event) { if (isShifted) { _viewFrustum.setFocalLength(_viewFrustum.getFocalLength() + 0.1f); if (TV3DManager::isConnected()) { - auto glCanvas = DependencyManager::get(); - TV3DManager::configureCamera(_myCamera, glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight()); + TV3DManager::configureCamera(_myCamera, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); } } else { @@ -1469,6 +1465,10 @@ void Application::checkFPS() { void Application::idle() { PerformanceTimer perfTimer("idle"); + + if (_aboutToQuit) { + return; // bail early, nothing to do here. + } // Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing // details if we're in ExtraDebugging mode. However, the ::update() and it's subcomponents will show their timing @@ -1494,7 +1494,7 @@ void Application::idle() { { PerformanceTimer perfTimer("updateGL"); PerformanceWarning warn(showWarnings, "Application::idle()... updateGL()"); - DependencyManager::get()->updateGL(); + _glWidget->updateGL(); } { PerformanceTimer perfTimer("rest"); @@ -1535,8 +1535,7 @@ void Application::setFullscreen(bool fullscreen) { } void Application::setEnable3DTVMode(bool enable3DTVMode) { - auto glCanvas = DependencyManager::get(); - resizeGL(glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight()); + resizeGL(_glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); } void Application::setEnableVRMode(bool enableVRMode) { @@ -1561,8 +1560,7 @@ void Application::setEnableVRMode(bool enableVRMode) { _myCamera.setHmdRotation(glm::quat()); } - auto glCanvas = DependencyManager::get(); - resizeGL(glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight()); + resizeGL(_glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); updateCursorVisibility(); } @@ -1573,9 +1571,8 @@ void Application::setLowVelocityFilter(bool lowVelocityFilter) { bool Application::mouseOnScreen() const { if (OculusManager::isConnected()) { - auto glCanvas = DependencyManager::get(); - return getMouseX() >= 0 && getMouseX() <= glCanvas->getDeviceWidth() && - getMouseY() >= 0 && getMouseY() <= glCanvas->getDeviceHeight(); + return getMouseX() >= 0 && getMouseX() <= _glWidget->getDeviceWidth() && + getMouseY() >= 0 && getMouseY() <= _glWidget->getDeviceHeight(); } return true; } @@ -1785,8 +1782,7 @@ void Application::init() { _metavoxels.init(); - auto glCanvas = DependencyManager::get(); - _rearMirrorTools = new RearMirrorTools(glCanvas.data(), _mirrorViewRect); + _rearMirrorTools = new RearMirrorTools(_glWidget, _mirrorViewRect); connect(_rearMirrorTools, SIGNAL(closeView()), SLOT(closeMirrorView())); connect(_rearMirrorTools, SIGNAL(restoreView()), SLOT(restoreMirrorView())); @@ -1794,10 +1790,10 @@ void Application::init() { connect(_rearMirrorTools, SIGNAL(resetView()), SLOT(resetSensors())); // make sure our texture cache knows about window size changes - DependencyManager::get()->associateWithWidget(glCanvas.data()); + DependencyManager::get()->associateWithWidget(_glWidget); // initialize the GlowEffect with our widget - DependencyManager::get()->init(glCanvas.data(), + DependencyManager::get()->init(_glWidget, Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)); } @@ -2051,9 +2047,9 @@ void Application::updateCursor(float deltaTime) { void Application::updateCursorVisibility() { if (!_cursorVisible || Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode)) { - DependencyManager::get()->setCursor(Qt::BlankCursor); + _glWidget->setCursor(Qt::BlankCursor); } else { - DependencyManager::get()->unsetCursor(); + _glWidget->unsetCursor(); } } @@ -2643,8 +2639,7 @@ void Application::updateShadowMap() { fbo->release(); - auto glCanvas = DependencyManager::get(); - glViewport(0, 0, glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight()); + glViewport(0, 0, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); } const GLfloat WORLD_AMBIENT_COLOR[] = { 0.525f, 0.525f, 0.6f }; @@ -2694,7 +2689,7 @@ QImage Application::renderAvatarBillboard() { Glower glower; const int BILLBOARD_SIZE = 64; - renderRearViewMirror(QRect(0, DependencyManager::get()->getDeviceHeight() - BILLBOARD_SIZE, + renderRearViewMirror(QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE, BILLBOARD_SIZE, BILLBOARD_SIZE), true); @@ -2986,9 +2981,8 @@ bool Application::getCascadeShadowsEnabled() { } glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) { - auto glCanvas = DependencyManager::get(); - float horizontalScale = glCanvas->getDeviceWidth() / 2.0f; - float verticalScale = glCanvas->getDeviceHeight() / 2.0f; + float horizontalScale = _glWidget->getDeviceWidth() / 2.0f; + float verticalScale = _glWidget->getDeviceHeight() / 2.0f; // -1,-1 is 0,windowHeight // 1,1 is windowWidth,0 @@ -3007,7 +3001,7 @@ glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) { // -1,-1 1,-1 glm::vec2 screenPoint((projectedPoint.x + 1.0) * horizontalScale, - ((projectedPoint.y + 1.0) * -verticalScale) + glCanvas->getDeviceHeight()); + ((projectedPoint.y + 1.0) * -verticalScale) + _glWidget->getDeviceHeight()); return screenPoint; } @@ -3143,7 +3137,7 @@ void Application::resetSensors() { QScreen* currentScreen = _window->windowHandle()->screen(); QWindow* mainWindow = _window->windowHandle(); QPoint windowCenter = mainWindow->geometry().center(); - DependencyManager::get()->cursor().setPos(currentScreen, windowCenter); + _glWidget->cursor().setPos(currentScreen, windowCenter); _myAvatar->reset(); @@ -3535,19 +3529,20 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("MIDI", &MIDIManager::getInstance()); #endif + // TODO: Consider moving some of this functionality into the ScriptEngine class instead. It seems wrong that this + // work is being done in the Application class when really these dependencies are more related to the ScriptEngine's + // implementation QThread* workerThread = new QThread(this); - workerThread->setObjectName("Script Engine Thread"); + QString scriptEngineName = QString("Script Thread:") + scriptEngine->getFilename(); + workerThread->setObjectName(scriptEngineName); // when the worker thread is started, call our engine's run.. connect(workerThread, &QThread::started, scriptEngine, &ScriptEngine::run); // when the thread is terminated, add both scriptEngine and thread to the deleteLater queue - connect(scriptEngine, SIGNAL(finished(const QString&)), scriptEngine, SLOT(deleteLater())); + connect(scriptEngine, SIGNAL(doneRunning()), scriptEngine, SLOT(deleteLater())); connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater())); - // when the application is about to quit, stop our script engine so it unwinds properly - connect(this, SIGNAL(aboutToQuit()), scriptEngine, SLOT(stop())); - auto nodeList = DependencyManager::get(); connect(nodeList.data(), &NodeList::nodeKilled, scriptEngine, &ScriptEngine::nodeKilled); @@ -3558,7 +3553,12 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri } ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUserLoaded, - bool loadScriptFromEditor, bool activateMainWindow) { + bool loadScriptFromEditor, bool activateMainWindow) { + + if (isAboutToQuit()) { + return NULL; + } + QUrl scriptUrl(scriptFilename); const QString& scriptURLString = scriptUrl.toString(); if (_scriptEnginesHash.contains(scriptURLString) && loadScriptFromEditor @@ -3749,8 +3749,8 @@ void Application::domainSettingsReceived(const QJsonObject& domainSettingsObject voxelWalletUUID = QUuid(voxelObject[VOXEL_WALLET_UUID].toString()); } - qDebug() << "Voxel costs are" << satoshisPerVoxel << "per voxel and" << satoshisPerMeterCubed << "per meter cubed"; - qDebug() << "Destination wallet UUID for voxel payments is" << voxelWalletUUID; + qDebug() << "Octree edits costs are" << satoshisPerVoxel << "per octree cell and" << satoshisPerMeterCubed << "per meter cubed"; + qDebug() << "Destination wallet UUID for edit payments is" << voxelWalletUUID; } QString Application::getPreviousScriptLocation() { @@ -3773,7 +3773,7 @@ void Application::setPreviousScriptLocation(const QString& previousScriptLocatio void Application::loadDialog() { - QString fileNameString = QFileDialog::getOpenFileName(DependencyManager::get().data(), + QString fileNameString = QFileDialog::getOpenFileName(_glWidget, tr("Open Script"), getPreviousScriptLocation(), tr("JavaScript Files (*.js)")); @@ -3814,7 +3814,7 @@ void Application::setScriptsLocation(const QString& scriptsLocation) { void Application::toggleLogDialog() { if (! _logDialog) { - _logDialog = new LogDialog(DependencyManager::get().data(), getLogger()); + _logDialog = new LogDialog(_glWidget, getLogger()); } if (_logDialog->isVisible()) { @@ -3871,7 +3871,7 @@ void Application::parseVersionXml() { } if (!shouldSkipVersion(latestVersion) && applicationVersion() != latestVersion) { - new UpdateDialog(DependencyManager::get().data(), releaseNotes, latestVersion, downloadUrl); + new UpdateDialog(_glWidget, releaseNotes, latestVersion, downloadUrl); } sender->deleteLater(); } @@ -3904,7 +3904,7 @@ void Application::takeSnapshot() { } if (!_snapshotShareDialog) { - _snapshotShareDialog = new SnapshotShareDialog(fileName, DependencyManager::get().data()); + _snapshotShareDialog = new SnapshotShareDialog(fileName, _glWidget); } _snapshotShareDialog->show(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 669187138c..9cd19c8259 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -171,7 +171,8 @@ public: bool event(QEvent* event); bool eventFilter(QObject* object, QEvent* event); - bool isThrottleRendering() const { return DependencyManager::get()->isThrottleRendering(); } + GLCanvas* getGLWidget() { return _glWidget; } + bool isThrottleRendering() const { return _glWidget->isThrottleRendering(); } Camera* getCamera() { return &_myCamera; } ViewFrustum* getViewFrustum() { return &_viewFrustum; } @@ -195,8 +196,8 @@ public: bool mouseOnScreen() const; int getMouseX() const; int getMouseY() const; - int getTrueMouseX() const { return DependencyManager::get()->mapFromGlobal(QCursor::pos()).x(); } - int getTrueMouseY() const { return DependencyManager::get()->mapFromGlobal(QCursor::pos()).y(); } + int getTrueMouseX() const { return _glWidget->mapFromGlobal(QCursor::pos()).x(); } + int getTrueMouseY() const { return _glWidget->mapFromGlobal(QCursor::pos()).y(); } int getMouseDragStartedX() const; int getMouseDragStartedY() const; int getTrueMouseDragStartedX() const { return _mouseDragStartedX; } @@ -270,8 +271,8 @@ public: FileLogger* getLogger() { return _logger; } - glm::vec2 getViewportDimensions() const { return glm::vec2(DependencyManager::get()->getDeviceWidth(), - DependencyManager::get()->getDeviceHeight()); } + glm::vec2 getViewportDimensions() const { return glm::vec2(_glWidget->getDeviceWidth(), + _glWidget->getDeviceHeight()); } NodeToJurisdictionMap& getEntityServerJurisdictions() { return _entityServerJurisdictions; } void skipVersion(QString latestVersion); @@ -593,6 +594,8 @@ private: QThread _settingsThread; QTimer _settingsTimer; + + GLCanvas* _glWidget = new GLCanvas(); // our GLCanvas has a couple extra features }; #endif // hifi_Application_h diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 5019599641..e334fd7c65 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -122,7 +122,7 @@ void Camera::setFarClip(float f) { } PickRay Camera::computePickRay(float x, float y) { - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); return computeViewPickRay(x / glCanvas->width(), y / glCanvas->height()); } diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index 02d3c62765..a491f9444d 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -30,6 +30,10 @@ DatagramProcessor::DatagramProcessor(QObject* parent) : void DatagramProcessor::processDatagrams() { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "DatagramProcessor::processDatagrams()"); + + if (_isShuttingDown) { + return; // bail early... we're shutting down. + } HifiSockAddr senderSockAddr; diff --git a/interface/src/DatagramProcessor.h b/interface/src/DatagramProcessor.h index 4ce090e52e..7fc192ee2d 100644 --- a/interface/src/DatagramProcessor.h +++ b/interface/src/DatagramProcessor.h @@ -25,14 +25,17 @@ public: int getOutByteCount() const { return _outByteCount; } void resetCounters() { _inPacketCount = 0; _outPacketCount = 0; _inByteCount = 0; _outByteCount = 0; } + + void shutdown() { _isShuttingDown = true; } public slots: void processDatagrams(); private: - int _inPacketCount; - int _outPacketCount; - int _inByteCount; - int _outByteCount; + int _inPacketCount = 0; + int _outPacketCount = 0; + int _inByteCount = 0; + int _outByteCount = 0; + bool _isShuttingDown = false; }; #endif // hifi_DatagramProcessor_h diff --git a/interface/src/GLCanvas.h b/interface/src/GLCanvas.h index ee101743cf..e2bbf3b841 100644 --- a/interface/src/GLCanvas.h +++ b/interface/src/GLCanvas.h @@ -16,14 +16,13 @@ #include #include -#include - /// customized canvas that simply forwards requests/events to the singleton application -class GLCanvas : public QGLWidget, public Dependency { +class GLCanvas : public QGLWidget { Q_OBJECT - SINGLETON_DEPENDENCY public: + GLCanvas(); + bool isThrottleRendering() const; int getDeviceWidth() const; @@ -60,12 +59,8 @@ private slots: void activeChanged(Qt::ApplicationState state); void throttleRender(); bool eventFilter(QObject*, QEvent* event); - -private: - GLCanvas(); - ~GLCanvas() { - qDebug() << "Deleting GLCanvas"; - } + }; + #endif // hifi_GLCanvas_h diff --git a/interface/src/UIUtil.cpp b/interface/src/UIUtil.cpp index 19d3a51917..8951ada5a6 100644 --- a/interface/src/UIUtil.cpp +++ b/interface/src/UIUtil.cpp @@ -12,7 +12,6 @@ #include #include -#include "DependencyManager.h" #include "GLCanvas.h" #include "UIUtil.h" @@ -44,8 +43,6 @@ int UIUtil::getWindowTitleBarHeight(const QWidget* window) { // this function at all. If you mix both you will end up with inconsistent results // across platforms. void UIUtil::scaleWidgetFontSizes(QWidget* widget) { - auto glCanvas = DependencyManager::get(); - // This is the base dpi that we are targetting. This is based on Mac OSXs default DPI, // and is the basis for all font sizes. const float BASE_DPI = 72.0f; diff --git a/interface/src/XmppClient.h b/interface/src/XmppClient.h index 91c10c4055..2b7a831ff3 100644 --- a/interface/src/XmppClient.h +++ b/interface/src/XmppClient.h @@ -15,8 +15,8 @@ #include #ifdef HAVE_QXMPP -#include -#include +#include +#include #endif /// Generalized threaded processor for handling received inbound packets. diff --git a/interface/src/audio/AudioToolBox.cpp b/interface/src/audio/AudioToolBox.cpp index 924c8105ea..330e7bc194 100644 --- a/interface/src/audio/AudioToolBox.cpp +++ b/interface/src/audio/AudioToolBox.cpp @@ -16,6 +16,7 @@ #include #include +#include "Application.h" #include "AudioToolBox.h" // Mute icon configration @@ -37,7 +38,7 @@ bool AudioToolBox::mousePressEvent(int x, int y) { void AudioToolBox::render(int x, int y, bool boxed) { glEnable(GL_TEXTURE_2D); - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); if (_micTextureId == 0) { _micTextureId = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/mic.svg")); } @@ -105,8 +106,12 @@ void AudioToolBox::render(int x, int y, bool boxed) { glm::vec2 bottomRight(_iconBounds.right(), _iconBounds.bottom()); glm::vec2 texCoordTopLeft(1,1); glm::vec2 texCoordBottomRight(0,0); + + if (_boxQuadID == GeometryCache::UNKNOWN_ID) { + _boxQuadID = DependencyManager::get()->allocateID(); + } - DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor); + DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, quadColor, _boxQuadID); glDisable(GL_TEXTURE_2D); } \ No newline at end of file diff --git a/interface/src/audio/AudioToolBox.h b/interface/src/audio/AudioToolBox.h index 2c073c1825..526de89b9c 100644 --- a/interface/src/audio/AudioToolBox.h +++ b/interface/src/audio/AudioToolBox.h @@ -13,6 +13,7 @@ #define hifi_AudioToolBox_h #include +#include class AudioToolBox : public Dependency { SINGLETON_DEPENDENCY @@ -26,6 +27,7 @@ private: GLuint _micTextureId = 0; GLuint _muteTextureId = 0; GLuint _boxTextureId = 0; + int _boxQuadID = GeometryCache::UNKNOWN_ID; QRect _iconBounds; qint64 _iconPulseTimeReference = 0; }; diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 14d1939198..4d864d8cec 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -566,7 +566,7 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p } // restore our normal viewport - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); glViewport(0, 0, glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight()); glMatrixMode(GL_PROJECTION); @@ -585,7 +585,7 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p void OculusManager::renderDistortionMesh(ovrPosef eyeRenderPose[ovrEye_Count]) { glLoadIdentity(); - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); glOrtho(0, glCanvas->getDeviceWidth(), 0, glCanvas->getDeviceHeight(), -1.0, 1.0); glDisable(GL_DEPTH_TEST); diff --git a/interface/src/devices/PrioVR.cpp b/interface/src/devices/PrioVR.cpp index b3342ac2bd..428c223eb7 100644 --- a/interface/src/devices/PrioVR.cpp +++ b/interface/src/devices/PrioVR.cpp @@ -216,7 +216,7 @@ void PrioVR::renderCalibrationCountdown() { static TextRenderer* textRenderer = TextRenderer::getInstance(MONO_FONT_FAMILY, 18, QFont::Bold, false, TextRenderer::OUTLINE_EFFECT, 2); QByteArray text = "Assume T-Pose in " + QByteArray::number(secondsRemaining) + "..."; - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); textRenderer->draw((glCanvas->width() - textRenderer->computeExtent(text.constData()).x) / 2, glCanvas->height() / 2, text, glm::vec4(1,1,1,1)); diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 609ac7b349..ce6ca57c69 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -472,7 +472,7 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers) //Injecting mouse movements and clicks void SixenseManager::emulateMouse(PalmData* palm, int index) { MyAvatar* avatar = DependencyManager::get()->getMyAvatar(); - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); QPoint pos; Qt::MouseButton bumperButton; diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index 9af13c461e..205ebfd29d 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -35,7 +35,7 @@ bool TV3DManager::isConnected() { } void TV3DManager::connect() { - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); int width = glCanvas->getDeviceWidth(); int height = glCanvas->getDeviceHeight(); Camera& camera = *Application::getInstance()->getCamera(); @@ -93,7 +93,7 @@ void TV3DManager::display(Camera& whichCamera) { // left eye portal int portalX = 0; int portalY = 0; - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); QSize deviceSize = glCanvas->getDeviceSize() * Application::getInstance()->getRenderResolutionScale(); int portalW = deviceSize.width() / 2; diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index 2188f45374..35c24346d2 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -15,6 +15,7 @@ #include #include +#include "Application.h" #include "devices/MotionTracker.h" #include "devices/SixenseManager.h" #include "ControllerScriptingInterface.h" @@ -285,7 +286,7 @@ void ControllerScriptingInterface::releaseJoystick(int joystickIndex) { } glm::vec2 ControllerScriptingInterface::getViewportDimensions() const { - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); return glm::vec2(glCanvas->width(), glCanvas->height()); } diff --git a/interface/src/scripting/GlobalServicesScriptingInterface.h b/interface/src/scripting/GlobalServicesScriptingInterface.h index 657cb945c5..d8b436a6e6 100644 --- a/interface/src/scripting/GlobalServicesScriptingInterface.h +++ b/interface/src/scripting/GlobalServicesScriptingInterface.h @@ -21,8 +21,8 @@ #ifdef HAVE_QXMPP -#include -#include +#include +#include #endif // HAVE_QXMPP diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index c4b288347d..8ec9fbbb82 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -18,6 +18,7 @@ #include #include "Application.h" +#include "DomainHandler.h" #include "MainWindow.h" #include "Menu.h" #include "ui/ModelsBrowser.h" @@ -34,6 +35,8 @@ WindowScriptingInterface::WindowScriptingInterface() : _nonBlockingFormActive(false), _formResult(QDialog::Rejected) { + const DomainHandler& domainHandler = DependencyManager::get()->getDomainHandler(); + connect(&domainHandler, &DomainHandler::hostnameChanged, this, &WindowScriptingInterface::domainChanged); } WebWindowClass* WindowScriptingInterface::doCreateWebWindow(const QString& title, const QString& url, int width, int height) { @@ -41,7 +44,7 @@ WebWindowClass* WindowScriptingInterface::doCreateWebWindow(const QString& title } QScriptValue WindowScriptingInterface::hasFocus() { - return DependencyManager::get()->hasFocus(); + return Application::getInstance()->getGLWidget()->hasFocus(); } void WindowScriptingInterface::setFocus() { diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 66d0ab9306..5c0aa4f0a8 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -57,6 +57,7 @@ public slots: QScriptValue peekNonBlockingFormResult(QScriptValue array); signals: + void domainChanged(const QString& domainHostname); void inlineButtonClicked(const QString& name); void nonBlockingFormClosed(); diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 632e76c840..0c5941366f 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -170,7 +170,7 @@ ApplicationOverlay::~ApplicationOverlay() { void ApplicationOverlay::renderOverlay(bool renderToTexture) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()"); Overlays& overlays = qApp->getOverlays(); - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); _textureFov = glm::radians(_oculusUIAngularSize); _textureAspectRatio = (float)glCanvas->getDeviceWidth() / (float)glCanvas->getDeviceHeight(); @@ -239,7 +239,7 @@ void ApplicationOverlay::displayOverlayTexture() { if (_alpha == 0.0f) { return; } - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); glEnable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); @@ -401,7 +401,7 @@ void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float as glm::vec2(1.0f, 0.0f), glm::vec2(0.0f, 0.0f), overlayColor); - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); if (_crosshairTexture == 0) { _crosshairTexture = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/sixense-reticle.png")); } @@ -451,7 +451,7 @@ void ApplicationOverlay::computeOculusPickRay(float x, float y, glm::vec3& origi //Caculate the click location using one of the sixense controllers. Scale is not applied QPoint ApplicationOverlay::getPalmClickLocation(const PalmData *palm) const { - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); glm::vec3 tip = myAvatar->getLaserPointerTipPosition(palm); @@ -528,7 +528,7 @@ bool ApplicationOverlay::calculateRayUICollisionPoint(const glm::vec3& position, //Renders optional pointers void ApplicationOverlay::renderPointers() { - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); //lazily load crosshair texture if (_crosshairTexture == 0) { @@ -575,7 +575,7 @@ void ApplicationOverlay::renderPointers() { } void ApplicationOverlay::renderControllerPointers() { - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); //Static variables used for storing controller state @@ -722,7 +722,7 @@ void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool if (!_magnifier) { return; } - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); const int widgetWidth = glCanvas->width(); const int widgetHeight = glCanvas->height(); @@ -787,7 +787,7 @@ void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool } void ApplicationOverlay::renderAudioMeter() { - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); auto audio = DependencyManager::get(); // Audio VU Meter and Mute Icon @@ -905,7 +905,7 @@ void ApplicationOverlay::renderStatsAndLogs() { Application* application = Application::getInstance(); QSharedPointer bandwidthRecorder = DependencyManager::get(); - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); const OctreePacketProcessor& octreePacketProcessor = application->getOctreePacketProcessor(); NodeBounds& nodeBoundsDisplay = application->getNodeBoundsDisplay(); @@ -943,7 +943,7 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder() { auto nodeList = DependencyManager::get(); if (nodeList && !nodeList->getDomainHandler().isConnected()) { - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); auto geometryCache = DependencyManager::get(); int width = glCanvas->width(); int height = glCanvas->height(); @@ -1087,7 +1087,7 @@ void ApplicationOverlay::TexturedHemisphere::cleanupVBO() { } void ApplicationOverlay::TexturedHemisphere::buildFramebufferObject() { - QSize size = DependencyManager::get()->getDeviceSize(); + QSize size = Application::getInstance()->getGLWidget()->getDeviceSize(); if (_framebufferObject != NULL && size == _framebufferObject->size()) { // Already build return; @@ -1138,7 +1138,7 @@ void ApplicationOverlay::TexturedHemisphere::render() { glm::vec2 ApplicationOverlay::screenToSpherical(glm::vec2 screenPos) const { - QSize screenSize = DependencyManager::get()->getDeviceSize(); + QSize screenSize = Application::getInstance()->getGLWidget()->getDeviceSize(); float yaw = -(screenPos.x / screenSize.width() - 0.5f) * MOUSE_YAW_RANGE; float pitch = (screenPos.y / screenSize.height() - 0.5f) * MOUSE_PITCH_RANGE; @@ -1146,7 +1146,7 @@ glm::vec2 ApplicationOverlay::screenToSpherical(glm::vec2 screenPos) const { } glm::vec2 ApplicationOverlay::sphericalToScreen(glm::vec2 sphericalPos) const { - QSize screenSize = DependencyManager::get()->getDeviceSize(); + QSize screenSize = Application::getInstance()->getGLWidget()->getDeviceSize(); float x = (-sphericalPos.x / MOUSE_YAW_RANGE + 0.5f) * screenSize.width(); float y = (sphericalPos.y / MOUSE_PITCH_RANGE + 0.5f) * screenSize.height(); @@ -1154,7 +1154,7 @@ glm::vec2 ApplicationOverlay::sphericalToScreen(glm::vec2 sphericalPos) const { } glm::vec2 ApplicationOverlay::sphericalToOverlay(glm::vec2 sphericalPos) const { - QSize screenSize = DependencyManager::get()->getDeviceSize(); + QSize screenSize = Application::getInstance()->getGLWidget()->getDeviceSize(); float x = (-sphericalPos.x / (_textureFov * _textureAspectRatio) + 0.5f) * screenSize.width(); float y = (sphericalPos.y / _textureFov + 0.5f) * screenSize.height(); @@ -1162,7 +1162,7 @@ glm::vec2 ApplicationOverlay::sphericalToOverlay(glm::vec2 sphericalPos) const { } glm::vec2 ApplicationOverlay::overlayToSpherical(glm::vec2 overlayPos) const { - QSize screenSize = DependencyManager::get()->getDeviceSize(); + QSize screenSize = Application::getInstance()->getGLWidget()->getDeviceSize(); float yaw = -(overlayPos.x / screenSize.width() - 0.5f) * _textureFov * _textureAspectRatio; float pitch = (overlayPos.y / screenSize.height() - 0.5f) * _textureFov; diff --git a/interface/src/ui/ChatWindow.h b/interface/src/ui/ChatWindow.h index 2338ab280d..b2ee113637 100644 --- a/interface/src/ui/ChatWindow.h +++ b/interface/src/ui/ChatWindow.h @@ -25,8 +25,8 @@ #ifdef HAVE_QXMPP -#include -#include +#include +#include #endif diff --git a/interface/src/ui/MetavoxelEditor.cpp b/interface/src/ui/MetavoxelEditor.cpp index bead5c743f..34c6ec9a30 100644 --- a/interface/src/ui/MetavoxelEditor.cpp +++ b/interface/src/ui/MetavoxelEditor.cpp @@ -140,7 +140,7 @@ MetavoxelEditor::MetavoxelEditor(QWidget* parent) : connect(Application::getInstance()->getMetavoxels(), &MetavoxelSystem::rendering, this, &MetavoxelEditor::renderPreview); - DependencyManager::get()->installEventFilter(this); + Application::getInstance()->getGLWidget()->installEventFilter(this); show(); diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 1a3ad541c9..fa63079290 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -235,7 +235,7 @@ void PreferencesDialog::savePreferences() { myAvatar->setLeanScale(ui.leanScaleSpin->value()); myAvatar->setClampedTargetScale(ui.avatarScaleSpin->value()); - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); Application::getInstance()->resizeGL(glCanvas->width(), glCanvas->height()); DependencyManager::get()->getMyAvatar()->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value()); diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index 9f8603e2ca..5a3109ff64 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -23,6 +23,7 @@ #include #include +#include "Application.h" #include "Snapshot.h" // filename format: hifi-snap-by-%username%-on-%date%_%time%_@-%location%.jpg @@ -93,7 +94,7 @@ QTemporaryFile* Snapshot::saveTempSnapshot() { } QFile* Snapshot::savedFileForSnapshot(bool isTemporary) { - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); QImage shot = glCanvas->grabFrameBuffer(); Avatar* avatar = DependencyManager::get()->getMyAvatar(); diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 7617adf01c..a4bb60bf7c 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -62,7 +62,7 @@ Stats::Stats(): _metavoxelReceiveProgress(0), _metavoxelReceiveTotal(0) { - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); resetWidth(glCanvas->width(), 0); } @@ -73,7 +73,7 @@ void Stats::toggleExpanded() { // called on mouse click release // check for clicks over stats in order to expand or contract them void Stats::checkClick(int mouseX, int mouseY, int mouseDragStartedX, int mouseDragStartedY, int horizontalOffset) { - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); if (0 != glm::compMax(glm::abs(glm::ivec2(mouseX - mouseDragStartedX, mouseY - mouseDragStartedY)))) { // not worried about dragging on stats @@ -128,7 +128,7 @@ void Stats::checkClick(int mouseX, int mouseY, int mouseDragStartedX, int mouseD } void Stats::resetWidth(int width, int horizontalOffset) { - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); int extraSpace = glCanvas->width() - horizontalOffset -2 - STATS_GENERAL_MIN_WIDTH - (Menu::getInstance()->isOptionChecked(MenuOption::TestPing) ? STATS_PING_MIN_WIDTH -1 : 0) @@ -202,7 +202,7 @@ void Stats::display( int outKbitsPerSecond, int voxelPacketsToProcess) { - auto glCanvas = DependencyManager::get(); + auto glCanvas = Application::getInstance()->getGLWidget(); unsigned int backgroundColor = 0x33333399; int verticalOffset = 0, lines = 0; diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 57c7aa791b..f0c49979c8 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -11,7 +11,6 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include #include #include "Application.h" diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index 27bd0c9102..88c097575b 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -10,6 +10,8 @@ // #include "Application.h" +#include "GeometryUtil.h" +#include "PlaneShape.h" #include "BillboardOverlay.h" @@ -191,19 +193,25 @@ bool BillboardOverlay::findRayIntersection(const glm::vec3& origin, const glm::v float& distance, BoxFace& face) { if (_texture) { + glm::quat rotation; + if (_isFacingAvatar) { + // rotate about vertical to face the camera + rotation = Application::getInstance()->getCamera()->getRotation(); + rotation *= glm::angleAxis(glm::pi(), glm::vec3(0.0f, 1.0f, 0.0f)); + } else { + rotation = _rotation; + } + + // Produce the dimensions of the billboard based on the image's aspect ratio and the overlay's scale. bool isNull = _fromImage.isNull(); float width = isNull ? _texture->getWidth() : _fromImage.width(); float height = isNull ? _texture->getHeight() : _fromImage.height(); - float maxSize = glm::max(width, height); - float x = width / (2.0f * maxSize); - float y = -height / (2.0f * maxSize); - float maxDimension = glm::max(x,y); - float scaledDimension = maxDimension * _scale; - glm::vec3 corner = getCenter() - glm::vec3(scaledDimension, scaledDimension, scaledDimension) ; - AACube myCube(corner, scaledDimension * 2.0f); - return myCube.findRayIntersection(origin, direction, distance, face); + glm::vec2 dimensions = _scale * glm::vec2(width / maxSize, height / maxSize); + + return findRayRectangleIntersection(origin, direction, rotation, _position, dimensions, distance); } + return false; } diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index e68f1bfb37..132f58b6f0 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -11,7 +11,6 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include #include #include #include diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 53d7d4e70b..a9bfbae8dd 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -11,8 +11,6 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include - #include #include #include diff --git a/interface/src/ui/overlays/Grid3DOverlay.h b/interface/src/ui/overlays/Grid3DOverlay.h index d6c85a10ee..451ce0a498 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.h +++ b/interface/src/ui/overlays/Grid3DOverlay.h @@ -17,8 +17,6 @@ #include -#include - #include #include diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index 3cc1b54b62..72e47b5e3d 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -11,7 +11,6 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include #include #include diff --git a/interface/src/ui/overlays/ImageOverlay.h b/interface/src/ui/overlays/ImageOverlay.h index e167c4e755..31c6031102 100644 --- a/interface/src/ui/overlays/ImageOverlay.h +++ b/interface/src/ui/overlays/ImageOverlay.h @@ -14,7 +14,6 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include #include #include #include diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index fd7aaca717..2cb8b3c91d 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -11,16 +11,12 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include -#include -#include #include #include "Overlay.h" Overlay::Overlay() : - _parent(NULL), _isLoaded(true), _alpha(DEFAULT_ALPHA), _glowLevel(0.0f), @@ -40,7 +36,6 @@ Overlay::Overlay() : } Overlay::Overlay(const Overlay* overlay) : - _parent(NULL), _isLoaded(overlay->_isLoaded), _alpha(overlay->_alpha), _glowLevel(overlay->_glowLevel), @@ -60,8 +55,7 @@ Overlay::Overlay(const Overlay* overlay) : { } -void Overlay::init(QGLWidget* parent, QScriptEngine* scriptEngine) { - _parent = parent; +void Overlay::init(QScriptEngine* scriptEngine) { _scriptEngine = scriptEngine; } diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index 99ab588197..9077605fc4 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -14,7 +14,6 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include #include #include #include @@ -38,7 +37,7 @@ public: Overlay(); Overlay(const Overlay* overlay); ~Overlay(); - void init(QGLWidget* parent, QScriptEngine* scriptEngine); + void init(QScriptEngine* scriptEngine); virtual void update(float deltatime) {} virtual void render(RenderArgs* args) = 0; @@ -85,7 +84,6 @@ public: protected: float updatePulse(); - QGLWidget* _parent; bool _isLoaded; float _alpha; float _glowLevel; diff --git a/interface/src/ui/overlays/Overlay2D.cpp b/interface/src/ui/overlays/Overlay2D.cpp index df7df391eb..f60d44a472 100644 --- a/interface/src/ui/overlays/Overlay2D.cpp +++ b/interface/src/ui/overlays/Overlay2D.cpp @@ -11,9 +11,6 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include -#include -#include #include #include "Overlay2D.h" diff --git a/interface/src/ui/overlays/Overlay2D.h b/interface/src/ui/overlays/Overlay2D.h index 7493add905..20641206c2 100644 --- a/interface/src/ui/overlays/Overlay2D.h +++ b/interface/src/ui/overlays/Overlay2D.h @@ -14,7 +14,6 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include #include #include #include diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 8ba7ddea00..c7b350f100 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -58,8 +58,7 @@ Overlays::~Overlays() { } -void Overlays::init(QGLWidget* parent) { - _parent = parent; +void Overlays::init() { _scriptEngine = new QScriptEngine(); } @@ -202,7 +201,7 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope } unsigned int Overlays::addOverlay(Overlay* overlay) { - overlay->init(_parent, _scriptEngine); + overlay->init(_scriptEngine); QWriteLocker lock(&_lock); unsigned int thisID = _nextOverlayID; diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 94ac6f98bb..42227d04f6 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -51,7 +51,7 @@ class Overlays : public QObject { public: Overlays(); ~Overlays(); - void init(QGLWidget* parent); + void init(); void update(float deltatime); void renderWorld(bool drawFront, RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); @@ -95,7 +95,6 @@ private: QMap _overlaysWorld; QList _overlaysToDelete; unsigned int _nextOverlayID; - QGLWidget* _parent; QReadWriteLock _lock; QReadWriteLock _deleteLock; QScriptEngine* _scriptEngine; diff --git a/interface/src/ui/overlays/Planar3DOverlay.cpp b/interface/src/ui/overlays/Planar3DOverlay.cpp index 508b5c4227..7ed7332f19 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.cpp +++ b/interface/src/ui/overlays/Planar3DOverlay.cpp @@ -11,12 +11,13 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include #include #include #include #include +#include "GeometryUtil.h" + #include "Planar3DOverlay.h" const float DEFAULT_SIZE = 1.0f; @@ -93,29 +94,5 @@ QScriptValue Planar3DOverlay::getProperty(const QString& property) { bool Planar3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) { - RayIntersectionInfo rayInfo; - rayInfo._rayStart = origin; - rayInfo._rayDirection = direction; - rayInfo._rayLength = std::numeric_limits::max(); - - PlaneShape plane; - - const glm::vec3 UNROTATED_NORMAL(0.0f, 0.0f, -1.0f); - glm::vec3 normal = _rotation * UNROTATED_NORMAL; - plane.setNormal(normal); - plane.setPoint(_position); // the position is definitely a point on our plane - - bool intersects = plane.findRayIntersection(rayInfo); - - if (intersects) { - distance = rayInfo._hitDistance; - - glm::vec3 hitPosition = origin + (distance * direction); - glm::vec3 localHitPosition = glm::inverse(_rotation) * (hitPosition - _position); - glm::vec2 halfDimensions = _dimensions / 2.0f; - - intersects = -halfDimensions.x <= localHitPosition.x && localHitPosition.x <= halfDimensions.x - && -halfDimensions.y <= localHitPosition.y && localHitPosition.y <= halfDimensions.y; - } - return intersects; + return findRayRectangleIntersection(origin, direction, _rotation, _position, _dimensions, distance); } diff --git a/interface/src/ui/overlays/Planar3DOverlay.h b/interface/src/ui/overlays/Planar3DOverlay.h index 9355265f80..8a02b35bd2 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.h +++ b/interface/src/ui/overlays/Planar3DOverlay.h @@ -16,7 +16,6 @@ #include -#include #include #include "Base3DOverlay.h" diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.cpp b/interface/src/ui/overlays/Rectangle3DOverlay.cpp index 7a88b327d1..8662030e23 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.cpp +++ b/interface/src/ui/overlays/Rectangle3DOverlay.cpp @@ -11,8 +11,6 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include - #include #include #include diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index 11bd7b97e8..a0e8d06b41 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -11,8 +11,6 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include - #include #include diff --git a/interface/src/ui/overlays/TextOverlay.cpp b/interface/src/ui/overlays/TextOverlay.cpp index f3b05b7300..85e5af708c 100644 --- a/interface/src/ui/overlays/TextOverlay.cpp +++ b/interface/src/ui/overlays/TextOverlay.cpp @@ -11,8 +11,6 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include - #include #include #include diff --git a/interface/src/ui/overlays/TextOverlay.h b/interface/src/ui/overlays/TextOverlay.h index 793d705d3c..6387b42bc3 100644 --- a/interface/src/ui/overlays/TextOverlay.h +++ b/interface/src/ui/overlays/TextOverlay.h @@ -14,13 +14,9 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include -#include -#include #include #include #include -#include #include diff --git a/interface/src/ui/overlays/Volume3DOverlay.cpp b/interface/src/ui/overlays/Volume3DOverlay.cpp index 40fea5c8c9..b0310f8155 100644 --- a/interface/src/ui/overlays/Volume3DOverlay.cpp +++ b/interface/src/ui/overlays/Volume3DOverlay.cpp @@ -14,7 +14,6 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" -#include #include #include #include diff --git a/interface/src/ui/overlays/Volume3DOverlay.h b/interface/src/ui/overlays/Volume3DOverlay.h index 7938641a8f..b7c59b2ace 100644 --- a/interface/src/ui/overlays/Volume3DOverlay.h +++ b/interface/src/ui/overlays/Volume3DOverlay.h @@ -16,7 +16,6 @@ #include -#include #include #include "Base3DOverlay.h" diff --git a/libraries/animation/CMakeLists.txt b/libraries/animation/CMakeLists.txt index 4024205f81..8c75d5620c 100644 --- a/libraries/animation/CMakeLists.txt +++ b/libraries/animation/CMakeLists.txt @@ -3,7 +3,4 @@ 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) - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() \ No newline at end of file +link_hifi_libraries(shared gpu model fbx) \ No newline at end of file diff --git a/libraries/audio-client/CMakeLists.txt b/libraries/audio-client/CMakeLists.txt index 1cd76cf2f5..43a2016acf 100644 --- a/libraries/audio-client/CMakeLists.txt +++ b/libraries/audio-client/CMakeLists.txt @@ -6,10 +6,10 @@ setup_hifi_library(Network Multimedia) link_hifi_libraries(audio) # append audio includes to our list of includes to bubble -list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${HIFI_LIBRARY_DIR}/audio/src") +target_include_directories(${TARGET_NAME} PUBLIC "${HIFI_LIBRARY_DIR}/audio/src") -# have CMake grab Gverb from git and then set up linking and directory include -add_dependency_external_project(gverb) +# have CMake grab externals for us +add_dependency_external_projects(gverb soxr) find_package(Gverb REQUIRED) @@ -19,13 +19,10 @@ target_include_directories(${TARGET_NAME} PRIVATE ${GVERB_INCLUDE_DIRS}) # we use libsoxr for resampling find_package(Soxr REQUIRED) target_link_libraries(${TARGET_NAME} ${SOXR_LIBRARIES}) -include_directories(SYSTEM ${SOXR_INCLUDE_DIRS}) +target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${SOXR_INCLUDE_DIRS}) if (APPLE) find_library(CoreAudio CoreAudio) find_library(CoreFoundation CoreFoundation) target_link_libraries(${TARGET_NAME} ${CoreAudio} ${CoreFoundation}) -endif () - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() \ No newline at end of file +endif () \ No newline at end of file diff --git a/libraries/audio/CMakeLists.txt b/libraries/audio/CMakeLists.txt index 6ec35e00fc..c2d5c8aca9 100644 --- a/libraries/audio/CMakeLists.txt +++ b/libraries/audio/CMakeLists.txt @@ -3,11 +3,8 @@ 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_project(glm) +add_dependency_external_projects(glm) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) -link_hifi_libraries(networking shared) - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() \ No newline at end of file +link_hifi_libraries(networking shared) \ No newline at end of file diff --git a/libraries/avatars/CMakeLists.txt b/libraries/avatars/CMakeLists.txt index bb4b8fdde0..acc939b25c 100644 --- a/libraries/avatars/CMakeLists.txt +++ b/libraries/avatars/CMakeLists.txt @@ -3,11 +3,8 @@ 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_project(glm) +add_dependency_external_projects(glm) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) link_hifi_libraries(audio shared networking) - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() diff --git a/libraries/embedded-webserver/CMakeLists.txt b/libraries/embedded-webserver/CMakeLists.txt index ef2cf1054c..955487e540 100644 --- a/libraries/embedded-webserver/CMakeLists.txt +++ b/libraries/embedded-webserver/CMakeLists.txt @@ -1,7 +1,4 @@ set(TARGET_NAME embedded-webserver) # use setup_hifi_library macro to setup our project and link appropriate Qt modules -setup_hifi_library(Network) - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() \ No newline at end of file +setup_hifi_library(Network) \ No newline at end of file diff --git a/libraries/entities-renderer/CMakeLists.txt b/libraries/entities-renderer/CMakeLists.txt index e706b07538..c0880ed15d 100644 --- a/libraries/entities-renderer/CMakeLists.txt +++ b/libraries/entities-renderer/CMakeLists.txt @@ -3,11 +3,8 @@ set(TARGET_NAME entities-renderer) # use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(Widgets OpenGL Network Script) -add_dependency_external_project(glm) +add_dependency_external_projects(glm) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) -link_hifi_libraries(shared gpu script-engine render-utils) - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() +link_hifi_libraries(shared gpu script-engine render-utils) \ No newline at end of file diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 975d0f515d..46f9ff6f55 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -59,10 +59,17 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf } EntityTreeRenderer::~EntityTreeRenderer() { - // NOTE: we don't need to delete _entitiesScriptEngine because it's owned by the application and gets cleaned up - // automatically but we do need to delete our sandbox script engine. - delete _sandboxScriptEngine; - _sandboxScriptEngine = NULL; + // NOTE: we don't need to delete _entitiesScriptEngine because it is registered with the application and has a + // signal tied to call it's deleteLater on doneRunning + if (_sandboxScriptEngine) { + // TODO: consider reworking how _sandboxScriptEngine is managed. It's treated differently than _entitiesScriptEngine + // because we don't call registerScriptEngineWithApplicationServices() for it. This implementation is confusing and + // potentially error prone because it's not a full fledged ScriptEngine that has been fully connected to the + // application. We did this so that scripts that were ill-formed could be evaluated but not execute against the + // application services. But this means it's shutdown behavior is different from other ScriptEngines + delete _sandboxScriptEngine; + _sandboxScriptEngine = NULL; + } } void EntityTreeRenderer::clear() { @@ -97,6 +104,11 @@ void EntityTreeRenderer::init() { connect(entityTree, &EntityTree::changingEntityID, this, &EntityTreeRenderer::changingEntityID); } +void EntityTreeRenderer::shutdown() { + _shuttingDown = true; +} + + QScriptValue EntityTreeRenderer::loadEntityScript(const EntityItemID& entityItemID) { EntityItem* entity = static_cast(_tree)->findEntityByEntityItemID(entityItemID); return loadEntityScript(entity); @@ -156,6 +168,10 @@ QString EntityTreeRenderer::loadScriptContents(const QString& scriptMaybeURLorTe QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity) { + if (_shuttingDown) { + return QScriptValue(); // since we're shutting down, we don't load any more scripts + } + if (!entity) { return QScriptValue(); // no entity... } @@ -235,7 +251,7 @@ void EntityTreeRenderer::setTree(Octree* newTree) { } void EntityTreeRenderer::update() { - if (_tree) { + if (_tree && !_shuttingDown) { EntityTree* tree = static_cast(_tree); tree->update(); @@ -258,7 +274,7 @@ void EntityTreeRenderer::update() { } void EntityTreeRenderer::checkEnterLeaveEntities() { - if (_tree) { + if (_tree && !_shuttingDown) { _tree->lockForWrite(); // so that our scripts can do edits if they want glm::vec3 avatarPosition = _viewState->getAvatarPosition() / (float) TREE_SCALE; @@ -309,7 +325,7 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { } void EntityTreeRenderer::leaveAllEntities() { - if (_tree) { + if (_tree && !_shuttingDown) { _tree->lockForWrite(); // so that our scripts can do edits if they want // for all of our previous containing entities, if they are no longer containing then send them a leave event @@ -330,7 +346,7 @@ void EntityTreeRenderer::leaveAllEntities() { } } void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { - if (_tree) { + if (_tree && !_shuttingDown) { Model::startScene(renderSide); RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -700,9 +716,14 @@ QScriptValueList EntityTreeRenderer::createEntityArgs(const EntityItemID& entity } void EntityTreeRenderer::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { + // If we don't have a tree, or we're in the process of shutting down, then don't + // process these events. + if (!_tree || _shuttingDown) { + return; + } PerformanceTimer perfTimer("EntityTreeRenderer::mousePressEvent"); PickRay ray = _viewState->computePickRay(event->x(), event->y()); - + bool precisionPicking = !_dontDoPrecisionPicking; RayToEntityIntersectionResult rayPickResult = findRayIntersectionWorker(ray, Octree::Lock, precisionPicking); if (rayPickResult.intersects) { @@ -714,7 +735,7 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event, unsigned int device if (entityScript.property("mousePressOnEntity").isValid()) { entityScript.property("mousePressOnEntity").call(entityScript, entityScriptArgs); } - + _currentClickingOnEntityID = rayPickResult.entityID; emit clickDownOnEntity(_currentClickingOnEntityID, MouseEvent(*event, deviceID)); if (entityScript.property("clickDownOnEntity").isValid()) { @@ -726,6 +747,11 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event, unsigned int device } void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) { + // If we don't have a tree, or we're in the process of shutting down, then don't + // process these events. + if (!_tree || _shuttingDown) { + return; + } PerformanceTimer perfTimer("EntityTreeRenderer::mouseReleaseEvent"); PickRay ray = _viewState->computePickRay(event->x(), event->y()); bool precisionPicking = !_dontDoPrecisionPicking; @@ -740,7 +766,7 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event, unsigned int devi entityScript.property("mouseReleaseOnEntity").call(entityScript, entityScriptArgs); } } - + // Even if we're no longer intersecting with an entity, if we started clicking on it, and now // we're releasing the button, then this is considered a clickOn event if (!_currentClickingOnEntityID.isInvalidID()) { @@ -752,7 +778,7 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event, unsigned int devi currentClickingEntity.property("clickReleaseOnEntity").call(currentClickingEntity, currentClickingEntityArgs); } } - + // makes it the unknown ID, we just released so we can't be clicking on anything _currentClickingOnEntityID = EntityItemID::createInvalidEntityID(); _lastMouseEvent = MouseEvent(*event, deviceID); @@ -760,10 +786,15 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event, unsigned int devi } void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) { + // If we don't have a tree, or we're in the process of shutting down, then don't + // process these events. + if (!_tree || _shuttingDown) { + return; + } PerformanceTimer perfTimer("EntityTreeRenderer::mouseMoveEvent"); PickRay ray = _viewState->computePickRay(event->x(), event->y()); - + bool precisionPicking = false; // for mouse moves we do not do precision picking RayToEntityIntersectionResult rayPickResult = findRayIntersectionWorker(ray, Octree::TryLock, precisionPicking); if (rayPickResult.intersects) { @@ -774,15 +805,15 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event, unsigned int deviceI if (entityScript.property("mouseMoveEvent").isValid()) { entityScript.property("mouseMoveEvent").call(entityScript, entityScriptArgs); } - + //qDebug() << "mouseMoveEvent over entity:" << rayPickResult.entityID; emit mouseMoveOnEntity(rayPickResult.entityID, MouseEvent(*event, deviceID)); if (entityScript.property("mouseMoveOnEntity").isValid()) { entityScript.property("mouseMoveOnEntity").call(entityScript, entityScriptArgs); } - + // handle the hover logic... - + // if we were previously hovering over an entity, and this new entity is not the same as our previous entity // then we need to send the hover leave. if (!_currentHoverOverEntityID.isInvalidID() && rayPickResult.entityID != _currentHoverOverEntityID) { @@ -832,7 +863,7 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event, unsigned int deviceI _currentHoverOverEntityID = EntityItemID::createInvalidEntityID(); // makes it the unknown ID } } - + // Even if we're no longer intersecting with an entity, if we started clicking on an entity and we have // not yet released the hold then this is still considered a holdingClickOnEntity event if (!_currentClickingOnEntityID.isInvalidID()) { @@ -850,29 +881,37 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event, unsigned int deviceI } void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) { - checkAndCallUnload(entityID); + if (_tree && !_shuttingDown) { + checkAndCallUnload(entityID); + } _entityScripts.remove(entityID); } void EntityTreeRenderer::entitySciptChanging(const EntityItemID& entityID) { - checkAndCallUnload(entityID); - checkAndCallPreload(entityID); + if (_tree && !_shuttingDown) { + checkAndCallUnload(entityID); + checkAndCallPreload(entityID); + } } void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID) { - // load the entity script if needed... - QScriptValue entityScript = loadEntityScript(entityID); - if (entityScript.property("preload").isValid()) { - QScriptValueList entityArgs = createEntityArgs(entityID); - entityScript.property("preload").call(entityScript, entityArgs); + if (_tree && !_shuttingDown) { + // load the entity script if needed... + QScriptValue entityScript = loadEntityScript(entityID); + if (entityScript.property("preload").isValid()) { + QScriptValueList entityArgs = createEntityArgs(entityID); + entityScript.property("preload").call(entityScript, entityArgs); + } } } void EntityTreeRenderer::checkAndCallUnload(const EntityItemID& entityID) { - QScriptValue entityScript = getPreviouslyLoadedEntityScript(entityID); - if (entityScript.property("unload").isValid()) { - QScriptValueList entityArgs = createEntityArgs(entityID); - entityScript.property("unload").call(entityScript, entityArgs); + if (_tree && !_shuttingDown) { + QScriptValue entityScript = getPreviouslyLoadedEntityScript(entityID); + if (entityScript.property("unload").isValid()) { + QScriptValueList entityArgs = createEntityArgs(entityID); + entityScript.property("unload").call(entityScript, entityArgs); + } } } @@ -887,6 +926,11 @@ void EntityTreeRenderer::changingEntityID(const EntityItemID& oldEntityID, const void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) { + // If we don't have a tree, or we're in the process of shutting down, then don't + // process these events. + if (!_tree || _shuttingDown) { + return; + } QScriptValue entityScriptA = loadEntityScript(idA); if (entityScriptA.property("collisionWithEntity").isValid()) { QScriptValueList args; diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 3826a80238..0da85f360b 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -46,6 +46,7 @@ public: virtual int getBoundaryLevelAdjust() const; virtual void setTree(Octree* newTree); + void shutdown(); void update(); EntityTree* getTree() { return static_cast(_tree); } @@ -154,6 +155,8 @@ private: bool _displayModelElementProxy; bool _dontDoPrecisionPicking; + bool _shuttingDown = false; + }; #endif // hifi_EntityTreeRenderer_h diff --git a/libraries/entities/CMakeLists.txt b/libraries/entities/CMakeLists.txt index d0c39cac84..e57bcf67fa 100644 --- a/libraries/entities/CMakeLists.txt +++ b/libraries/entities/CMakeLists.txt @@ -3,13 +3,14 @@ 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_project(glm) +add_dependency_external_projects(glm) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) -include_bullet() +add_dependency_external_projects(bullet) + +find_package(Bullet REQUIRED) +target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BULLET_INCLUDE_DIRS}) +target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) link_hifi_libraries(avatars shared octree gpu model fbx networking animation) - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 15d46603b5..d6a3aab970 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1002,7 +1002,7 @@ void EntityItem::computeShapeInfo(ShapeInfo& info) const { } const float MIN_POSITION_DELTA = 0.0001f; -const float MIN_ALIGNMENT_DOT = 0.9999f; +const float MIN_ALIGNMENT_DOT = 0.999999f; const float MIN_VELOCITY_DELTA = 0.01f; const float MIN_DAMPING_DELTA = 0.001f; const float MIN_GRAVITY_DELTA = 0.001f; diff --git a/libraries/environment/CMakeLists.txt b/libraries/environment/CMakeLists.txt index e5e7b80701..a2ee9e3f55 100644 --- a/libraries/environment/CMakeLists.txt +++ b/libraries/environment/CMakeLists.txt @@ -3,18 +3,8 @@ set(TARGET_NAME environment) # use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library() -add_dependency_external_project(glm) +add_dependency_external_projects(glm) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) -link_hifi_libraries(shared networking) - -# find ZLIB -find_package(ZLIB REQUIRED) -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") - -# add it to our list of libraries to link -target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES}) - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() \ No newline at end of file +link_hifi_libraries(shared networking) \ No newline at end of file diff --git a/libraries/fbx/CMakeLists.txt b/libraries/fbx/CMakeLists.txt index da6d471c72..1ce1c74922 100644 --- a/libraries/fbx/CMakeLists.txt +++ b/libraries/fbx/CMakeLists.txt @@ -3,15 +3,8 @@ set(TARGET_NAME fbx) # use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library() -add_dependency_external_project(glm) +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) - -find_package(ZLIB REQUIRED) -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") -target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES}) - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() +link_hifi_libraries(shared gpu model networking octree) \ No newline at end of file diff --git a/libraries/gpu/CMakeLists.txt b/libraries/gpu/CMakeLists.txt index 789ffdbfeb..7b1d6e743a 100644 --- a/libraries/gpu/CMakeLists.txt +++ b/libraries/gpu/CMakeLists.txt @@ -11,16 +11,11 @@ if (APPLE) target_link_libraries(${TARGET_NAME} ${OpenGL}) elseif (WIN32) + add_dependency_external_projects(glew) find_package(GLEW REQUIRED) - include_directories(${GLEW_INCLUDE_DIRS}) - - # we're using static GLEW, so define GLEW_STATIC - add_definitions(-DGLEW_STATIC) + target_include_directories(${TARGET_NAME} PUBLIC ${GLEW_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${GLEW_LIBRARIES} opengl32.lib) - - # need to bubble up the GLEW_INCLUDE_DIRS - list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${GLEW_INCLUDE_DIRS}") # try to find the Nsight package and add it to the build if we find it find_package(NSIGHT) @@ -40,9 +35,5 @@ else () target_link_libraries(${TARGET_NAME} "${OPENGL_LIBRARY}") - # need to bubble up the OPENGL_INCLUDE_DIR - list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${OPENGL_INCLUDE_DIR}") + target_include_directories(${TARGET_NAME} PUBLIC ${OPENGL_INCLUDE_DIR}) endif (APPLE) - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index b8cba3ded1..8140c91bf6 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -21,7 +21,7 @@ namespace gpu { class GPUObject { public: GPUObject() {} - ~GPUObject() {} + virtual ~GPUObject() {} }; class Batch; diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index e3450ae71a..49d4bd4c19 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -32,7 +32,7 @@ public: static void checkGLError(); - class GLBuffer { + class GLBuffer : public GPUObject { public: Stamp _stamp; GLuint _buffer; diff --git a/libraries/metavoxels/CMakeLists.txt b/libraries/metavoxels/CMakeLists.txt index 593ee800a7..240a2d8853 100644 --- a/libraries/metavoxels/CMakeLists.txt +++ b/libraries/metavoxels/CMakeLists.txt @@ -8,9 +8,6 @@ setup_hifi_library(Network Script Widgets) # link in the networking library link_hifi_libraries(shared networking) -add_dependency_external_project(glm) +add_dependency_external_projects(glm) find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() \ No newline at end of file +target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) \ No newline at end of file diff --git a/libraries/metavoxels/src/Spanner.cpp b/libraries/metavoxels/src/Spanner.cpp index fbd0d311f5..fd5a59fdfb 100644 --- a/libraries/metavoxels/src/Spanner.cpp +++ b/libraries/metavoxels/src/Spanner.cpp @@ -1959,7 +1959,7 @@ HeightfieldNode* HeightfieldNode::fillHeight(const glm::vec3& translation, const } else { colorWidth = innerHeightWidth + HeightfieldData::SHARED_EDGE; colorHeight = innerHeightHeight + HeightfieldData::SHARED_EDGE; - newColorContents = QByteArray(colorWidth * colorHeight * DataBlock::COLOR_BYTES, 0xFF); + newColorContents = QByteArray(colorWidth * colorHeight * DataBlock::COLOR_BYTES, 0xFFu); } int innerColorWidth = colorWidth - HeightfieldData::SHARED_EDGE; int innerColorHeight = colorHeight - HeightfieldData::SHARED_EDGE; @@ -2185,7 +2185,7 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons } else { colorWidth = innerHeightWidth + HeightfieldData::SHARED_EDGE; colorHeight = innerHeightHeight + HeightfieldData::SHARED_EDGE; - newColorContents = QByteArray(colorWidth * colorHeight * DataBlock::COLOR_BYTES, 0xFF); + newColorContents = QByteArray(colorWidth * colorHeight * DataBlock::COLOR_BYTES, 0xFFu); } int innerColorWidth = colorWidth - HeightfieldData::SHARED_EDGE; int innerColorHeight = colorHeight - HeightfieldData::SHARED_EDGE; @@ -2428,7 +2428,7 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons } } } - bool nextAlphaY = stackDest->getEntryAlpha(y + 1, voxelHeight); + int nextAlphaY = stackDest->getEntryAlpha(y + 1, voxelHeight); if (nextAlphaY == currentAlpha) { entryDest->hermiteY = 0; @@ -2447,7 +2447,7 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons } int nextStackZ = (int)stackZ + 1; if (nextStackZ <= innerStackHeight) { - bool nextAlphaZ = newStackContents.at(nextStackZ * stackWidth + (int)stackX).getEntryAlpha( + int nextAlphaZ = newStackContents.at(nextStackZ * stackWidth + (int)stackX).getEntryAlpha( y, nextVoxelHeightZ); if (nextAlphaZ == currentAlpha) { entryDest->hermiteZ = 0; @@ -2828,7 +2828,7 @@ void HeightfieldNode::mergeChildren(bool height, bool colorMaterial) { _height.reset(); } if (colorWidth > 0 && colorMaterial) { - QByteArray colorContents(colorWidth * colorHeight * DataBlock::COLOR_BYTES, 0xFF); + QByteArray colorContents(colorWidth * colorHeight * DataBlock::COLOR_BYTES, 0xFFu); for (int i = 0; i < CHILD_COUNT; i++) { HeightfieldColorPointer childColor = _children[i]->getColor(); if (!childColor) { @@ -3266,7 +3266,7 @@ HeightfieldNode* HeightfieldNode::subdivide(const QVector& heightConten } for (int i = 0; i < CHILD_COUNT; i++) { QVector childHeightContents(heightWidth * heightHeight); - QByteArray childColorContents(colorWidth * colorHeight * DataBlock::COLOR_BYTES, 0xFF); + QByteArray childColorContents(colorWidth * colorHeight * DataBlock::COLOR_BYTES, 0xFFu); QByteArray childMaterialContents(materialWidth * materialHeight, 0); QVector childStackContents(stackWidth * stackHeight); diff --git a/libraries/model/CMakeLists.txt b/libraries/model/CMakeLists.txt index 0f71a25047..c62b29599f 100755 --- a/libraries/model/CMakeLists.txt +++ b/libraries/model/CMakeLists.txt @@ -3,11 +3,8 @@ set(TARGET_NAME model) # use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library() -add_dependency_external_project(glm) +add_dependency_external_projects(glm) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) -link_hifi_libraries(shared gpu) - -# call macro to link our dependencies and bubble them up via a property on our target -include_dependency_includes() +link_hifi_libraries(shared gpu) \ No newline at end of file diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index bc251a42d4..6b386ace92 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -10,6 +10,8 @@ if (WIN32) target_link_libraries(${TARGET_NAME} ws2_32.lib) endif () +add_dependency_external_projects(tbb) + # find required dependencies find_package(OpenSSL REQUIRED) find_package(TBB REQUIRED) @@ -25,8 +27,5 @@ include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") # append OpenSSL to our list of libraries to link target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES} ${TBB_LIBRARIES}) -# append libcuckoo includes to our list of includes to bubble -list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${TBB_INCLUDE_DIRS}") - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() \ No newline at end of file +# append tbb includes to our list of includes to bubble +target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${TBB_INCLUDE_DIRS}) \ No newline at end of file diff --git a/libraries/octree/CMakeLists.txt b/libraries/octree/CMakeLists.txt index 3c7e8e7749..cc36aead15 100644 --- a/libraries/octree/CMakeLists.txt +++ b/libraries/octree/CMakeLists.txt @@ -3,19 +3,8 @@ set(TARGET_NAME octree) # use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library() -add_dependency_external_project(glm) +add_dependency_external_projects(glm) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) link_hifi_libraries(shared networking) - -# find ZLIB -find_package(ZLIB REQUIRED) - -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") - -# append ZLIB and OpenSSL to our list of libraries to link -target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES}) - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() diff --git a/libraries/physics/CMakeLists.txt b/libraries/physics/CMakeLists.txt index 7fc3f82496..5e94513da4 100644 --- a/libraries/physics/CMakeLists.txt +++ b/libraries/physics/CMakeLists.txt @@ -3,17 +3,15 @@ set(TARGET_NAME physics) # use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library() -add_dependency_external_project(glm) +add_dependency_external_projects(glm) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) -include_bullet() -if (BULLET_FOUND) - target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) -endif (BULLET_FOUND) +add_dependency_external_projects(bullet) + +find_package(Bullet REQUIRED) +target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BULLET_INCLUDE_DIRS}) +target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) link_hifi_libraries(shared fbx entities) include_hifi_library_headers(fbx) - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() diff --git a/libraries/render-utils/CMakeLists.txt b/libraries/render-utils/CMakeLists.txt index 054b30d7fb..5737d8e4c1 100644 --- a/libraries/render-utils/CMakeLists.txt +++ b/libraries/render-utils/CMakeLists.txt @@ -8,16 +8,8 @@ qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts # use setup_hifi_library macro to setup our project and link appropriate Qt modules setup_hifi_library(Widgets OpenGL Network Script) -add_dependency_external_project(glm) -find_package(GLM REQUIRED) +add_dependency_external_projects(glm) +find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) -link_hifi_libraries(animation fbx shared gpu) - -if (WIN32) - # we're using static GLEW, so define GLEW_STATIC - add_definitions(-DGLEW_STATIC) -endif () - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() +link_hifi_libraries(animation fbx shared gpu) \ No newline at end of file diff --git a/libraries/script-engine/CMakeLists.txt b/libraries/script-engine/CMakeLists.txt index 4e13ddf513..013f43530c 100644 --- a/libraries/script-engine/CMakeLists.txt +++ b/libraries/script-engine/CMakeLists.txt @@ -3,12 +3,8 @@ 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 Widgets) -add_dependency_external_project(glm) +add_dependency_external_projects(glm) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) link_hifi_libraries(shared octree gpu model fbx entities animation audio physics metavoxels) - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() - diff --git a/libraries/script-engine/src/KeyEvent.cpp b/libraries/script-engine/src/KeyEvent.cpp index b7564db1b6..febc8fc21f 100644 --- a/libraries/script-engine/src/KeyEvent.cpp +++ b/libraries/script-engine/src/KeyEvent.cpp @@ -121,8 +121,7 @@ bool KeyEvent::operator==(const KeyEvent& other) const { && other.isControl == isControl && other.isMeta == isMeta && other.isAlt == isAlt - && other.isKeypad == isKeypad - && other.isAutoRepeat == isAutoRepeat; + && other.isKeypad == isKeypad; } diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 0956374238..d201c1568c 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -41,6 +41,7 @@ #include "MIDIEvent.h" + EntityScriptingInterface ScriptEngine::_entityScriptingInterface; static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine){ @@ -94,8 +95,109 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam _isUserLoaded(false), _arrayBufferClass(new ArrayBufferClass(this)) { + _allScriptsMutex.lock(); + _allKnownScriptEngines.insert(this); + _allScriptsMutex.unlock(); } +ScriptEngine::~ScriptEngine() { + // If we're not already in the middle of stopping all scripts, then we should remove ourselves + // from the list of running scripts. We don't do this if we're in the process of stopping all scripts + // because that method removes scripts from its list as it iterates them + if (!_stoppingAllScripts) { + _allScriptsMutex.lock(); + _allKnownScriptEngines.remove(this); + _allScriptsMutex.unlock(); + } +} + +QSet ScriptEngine::_allKnownScriptEngines; +QMutex ScriptEngine::_allScriptsMutex; +bool ScriptEngine::_stoppingAllScripts = false; +bool ScriptEngine::_doneRunningThisScript = false; + +void ScriptEngine::stopAllScripts(QObject* application) { + _allScriptsMutex.lock(); + _stoppingAllScripts = true; + + QMutableSetIterator i(_allKnownScriptEngines); + while (i.hasNext()) { + ScriptEngine* scriptEngine = i.next(); + + QString scriptName = scriptEngine->getFilename(); + + // NOTE: typically all script engines are running. But there's at least one known exception to this, the + // "entities sandbox" which is only used to evaluate entities scripts to test their validity before using + // them. We don't need to stop scripts that aren't running. + if (scriptEngine->isRunning()) { + + // If the script is running, but still evaluating then we need to wait for its evaluation step to + // complete. After that we can handle the stop process appropriately + if (scriptEngine->evaluatePending()) { + while (scriptEngine->evaluatePending()) { + + // This event loop allows any started, but not yet finished evaluate() calls to complete + // we need to let these complete so that we can be guaranteed that the script engine isn't + // in a partially setup state, which can confuse our shutdown unwinding. + QEventLoop loop; + QObject::connect(scriptEngine, &ScriptEngine::evaluationFinished, &loop, &QEventLoop::quit); + loop.exec(); + } + } + + // We disconnect any script engine signals from the application because we don't want to do any + // extra stopScript/loadScript processing that the Application normally does when scripts start + // and stop. We can safely short circuit this because we know we're in the "quitting" process + scriptEngine->disconnect(application); + + // Calling stop on the script engine will set it's internal _isFinished state to true, and result + // in the ScriptEngine gracefully ending it's run() method. + scriptEngine->stop(); + + // We need to wait for the engine to be done running before we proceed, because we don't + // want any of the scripts final "scriptEnding()" or pending "update()" methods from accessing + // any application state after we leave this stopAllScripts() method + scriptEngine->waitTillDoneRunning(); + + // If the script is stopped, we can remove it from our set + i.remove(); + } + } + _stoppingAllScripts = false; + _allScriptsMutex.unlock(); +} + + +void ScriptEngine::waitTillDoneRunning() { + QString scriptName = getFilename(); + + // If the script never started running or finished running before we got here, we don't need to wait for it + if (_isRunning) { + + _doneRunningThisScript = false; // NOTE: this is static, we serialize our waiting for scripts to finish + + // NOTE: waitTillDoneRunning() will be called on the main Application thread, inside of stopAllScripts() + // we want the application thread to continue to process events, because the scripts will likely need to + // marshall messages across to the main thread. For example if they access Settings or Meny in any of their + // shutdown code. + while (!_doneRunningThisScript) { + + // process events for the main application thread, allowing invokeMethod calls to pass between threads + QCoreApplication::processEvents(); + } + } +} + +QString ScriptEngine::getFilename() const { + QStringList fileNameParts = _fileNameString.split("/"); + QString lastPart; + if (!fileNameParts.isEmpty()) { + lastPart = fileNameParts.last(); + } + return lastPart; +} + + void ScriptEngine::setIsAvatar(bool isAvatar) { _isAvatar = isAvatar; @@ -295,12 +397,18 @@ void ScriptEngine::registerGetterSetter(const QString& name, QScriptEngine::Func } void ScriptEngine::evaluate() { + if (_stoppingAllScripts) { + return; // bail early + } + if (!_isInitialized) { init(); } QScriptValue result = evaluate(_scriptContents); + // TODO: why do we check this twice? It seems like the call to clearExcpetions() in the lower level evaluate call + // will cause this code to never actually run... if (hasUncaughtException()) { int line = uncaughtExceptionLineNumber(); qDebug() << "Uncaught exception at (" << _fileNameString << ") line" << line << ":" << result.toString(); @@ -310,11 +418,17 @@ void ScriptEngine::evaluate() { } QScriptValue ScriptEngine::evaluate(const QString& program, const QString& fileName, int lineNumber) { + if (_stoppingAllScripts) { + return QScriptValue(); // bail early + } + + _evaluatesPending++; QScriptValue result = QScriptEngine::evaluate(program, fileName, lineNumber); if (hasUncaughtException()) { int line = uncaughtExceptionLineNumber(); qDebug() << "Uncaught exception at (" << _fileNameString << " : " << fileName << ") line" << line << ": " << result.toString(); } + _evaluatesPending--; emit evaluationFinished(result, hasUncaughtException()); clearExceptions(); return result; @@ -333,6 +447,9 @@ void ScriptEngine::sendAvatarBillboardPacket() { } void ScriptEngine::run() { + // TODO: can we add a short circuit for _stoppingAllScripts here? What does it mean to not start running if + // we're in the process of stopping? + if (!_isInitialized) { init(); } @@ -341,12 +458,6 @@ void ScriptEngine::run() { emit runningStateChanged(); QScriptValue result = evaluate(_scriptContents); - if (hasUncaughtException()) { - int line = uncaughtExceptionLineNumber(); - qDebug() << "Uncaught exception at (" << _fileNameString << ") line" << line << ":" << result.toString(); - emit errorMessage("Uncaught exception at (" + _fileNameString + ") line" + QString::number(line) + ":" + result.toString()); - clearExceptions(); - } QElapsedTimer startTime; startTime.start(); @@ -373,7 +484,7 @@ void ScriptEngine::run() { break; } - if (_entityScriptingInterface.getEntityPacketSender()->serversExist()) { + if (!_isFinished && _entityScriptingInterface.getEntityPacketSender()->serversExist()) { // release the queue of edit entity messages. _entityScriptingInterface.getEntityPacketSender()->releaseQueuedMessages(); @@ -383,7 +494,7 @@ void ScriptEngine::run() { } } - if (_isAvatar && _avatarData) { + if (!_isFinished && _isAvatar && _avatarData) { const int SCRIPT_AUDIO_BUFFER_SAMPLES = floor(((SCRIPT_DATA_CALLBACK_USECS * AudioConstants::SAMPLE_RATE) / (1000 * 1000)) + 0.5); @@ -493,9 +604,14 @@ void ScriptEngine::run() { clearExceptions(); } - emit update(deltaTime); + if (!_isFinished) { + emit update(deltaTime); + } lastUpdate = now; + } + + stopAllTimers(); // make sure all our timers are stopped if the script is ending emit scriptEnding(); // kill the avatar identity timer @@ -520,6 +636,21 @@ void ScriptEngine::run() { _isRunning = false; emit runningStateChanged(); + + emit doneRunning(); + + _doneRunningThisScript = true; +} + +// NOTE: This is private because it must be called on the same thread that created the timers, which is why +// we want to only call it in our own run "shutdown" processing. +void ScriptEngine::stopAllTimers() { + QMutableHashIterator i(_timerFunctionMap); + while (i.hasNext()) { + i.next(); + QTimer* timer = i.key(); + stopTimer(timer); + } } void ScriptEngine::stop() { @@ -560,10 +691,20 @@ QObject* ScriptEngine::setupTimerWithInterval(const QScriptValue& function, int } QObject* ScriptEngine::setInterval(const QScriptValue& function, int intervalMS) { + if (_stoppingAllScripts) { + qDebug() << "Script.setInterval() while shutting down is ignored... parent script:" << getFilename(); + return NULL; // bail early + } + return setupTimerWithInterval(function, intervalMS, false); } QObject* ScriptEngine::setTimeout(const QScriptValue& function, int timeoutMS) { + if (_stoppingAllScripts) { + qDebug() << "Script.setTimeout() while shutting down is ignored... parent script:" << getFilename(); + return NULL; // bail early + } + return setupTimerWithInterval(function, timeoutMS, true); } @@ -604,13 +745,16 @@ void ScriptEngine::print(const QString& message) { emit printedMessage(message); } -/** - * If a callback is specified, the included files will be loaded asynchronously and the callback will be called - * when all of the files have finished loading. - * If no callback is specified, the included files will be loaded synchronously and will block execution until - * all of the files have finished loading. - */ +// If a callback is specified, the included files will be loaded asynchronously and the callback will be called +// when all of the files have finished loading. +// If no callback is specified, the included files will be loaded synchronously and will block execution until +// all of the files have finished loading. void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callback) { + if (_stoppingAllScripts) { + qDebug() << "Script.include() while shutting down is ignored..." + << "includeFiles:" << includeFiles << "parent script:" << getFilename(); + return; // bail early + } QList urls; for (QString file : includeFiles) { urls.append(resolvePath(file)); @@ -650,12 +794,27 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac } void ScriptEngine::include(const QString& includeFile, QScriptValue callback) { + if (_stoppingAllScripts) { + qDebug() << "Script.include() while shutting down is ignored... " + << "includeFile:" << includeFile << "parent script:" << getFilename(); + return; // bail early + } + QStringList urls; urls.append(includeFile); include(urls, callback); } +// NOTE: The load() command is similar to the include() command except that it loads the script +// as a stand-alone script. To accomplish this, the ScriptEngine class just emits a signal which +// the Application or other context will connect to in order to know to actually load the script void ScriptEngine::load(const QString& loadFile) { + if (_stoppingAllScripts) { + qDebug() << "Script.load() while shutting down is ignored... " + << "loadFile:" << loadFile << "parent script:" << getFilename(); + return; // bail early + } + QUrl url = resolvePath(loadFile); emit loadScript(url.toString(), false); } diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index f2911842e6..154fdb88e3 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -43,6 +44,8 @@ public: const QString& fileNameString = QString(""), AbstractControllerScriptingInterface* controllerScriptingInterface = NULL); + ~ScriptEngine(); + /// Access the EntityScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener static EntityScriptingInterface* getEntityScriptingInterface() { return &_entityScriptingInterface; } @@ -83,11 +86,18 @@ public: bool isFinished() const { return _isFinished; } bool isRunning() const { return _isRunning; } + bool evaluatePending() const { return _evaluatesPending > 0; } void setUserLoaded(bool isUserLoaded) { _isUserLoaded = isUserLoaded; } bool isUserLoaded() const { return _isUserLoaded; } void setParentURL(const QString& parentURL) { _parentURL = parentURL; } + + QString getFilename() const; + + static void stopAllScripts(QObject* application); + + void waitTillDoneRunning(); public slots: void loadURL(const QUrl& scriptURL); @@ -118,12 +128,14 @@ signals: void runningStateChanged(); void evaluationFinished(QScriptValue result, bool isException); void loadScript(const QString& scriptName, bool isUserLoaded); + void doneRunning(); protected: QString _scriptContents; QString _parentURL; bool _isFinished; bool _isRunning; + int _evaluatesPending = 0; bool _isInitialized; bool _isAvatar; QTimer* _avatarIdentityTimer; @@ -134,6 +146,7 @@ protected: int _numAvatarSoundSentBytes; private: + void stopAllTimers(); void sendAvatarIdentityPacket(); void sendAvatarBillboardPacket(); @@ -156,6 +169,12 @@ private: QHash _outgoingScriptAudioSequenceNumbers; private slots: void handleScriptDownload(); + +private: + static QSet _allKnownScriptEngines; + static QMutex _allScriptsMutex; + static bool _stoppingAllScripts; + static bool _doneRunningThisScript; }; #endif // hifi_ScriptEngine_h diff --git a/libraries/shared/CMakeLists.txt b/libraries/shared/CMakeLists.txt index 54cd91deaf..9785994a29 100644 --- a/libraries/shared/CMakeLists.txt +++ b/libraries/shared/CMakeLists.txt @@ -4,9 +4,6 @@ set(TARGET_NAME shared) # 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) -add_dependency_external_project(glm) +add_dependency_external_projects(glm) find_package(GLM REQUIRED) -target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() \ No newline at end of file +target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) \ No newline at end of file diff --git a/libraries/shared/src/GeometryUtil.cpp b/libraries/shared/src/GeometryUtil.cpp index aaec8b3e4a..13d78ec8b3 100644 --- a/libraries/shared/src/GeometryUtil.cpp +++ b/libraries/shared/src/GeometryUtil.cpp @@ -12,8 +12,10 @@ #include #include -#include "SharedUtil.h" #include "GeometryUtil.h" +#include "PlaneShape.h" +#include "RayIntersectionInfo.h" +#include "SharedUtil.h" glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end) { // compute the projection of the point vector onto the segment vector @@ -491,3 +493,34 @@ void PolygonClip::copyCleanArray(int& lengthA, glm::vec2* vertexArrayA, int& len } } } + +bool findRayRectangleIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::quat& rotation, + const glm::vec3& position, const glm::vec2& dimensions, float& distance) { + RayIntersectionInfo rayInfo; + rayInfo._rayStart = origin; + rayInfo._rayDirection = direction; + rayInfo._rayLength = std::numeric_limits::max(); + + PlaneShape plane; + + const glm::vec3 UNROTATED_NORMAL(0.0f, 0.0f, -1.0f); + glm::vec3 normal = rotation * UNROTATED_NORMAL; + plane.setNormal(normal); + plane.setPoint(position); // the position is definitely a point on our plane + + bool intersects = plane.findRayIntersection(rayInfo); + + if (intersects) { + distance = rayInfo._hitDistance; + + glm::vec3 hitPosition = origin + (distance * direction); + glm::vec3 localHitPosition = glm::inverse(rotation) * (hitPosition - position); + + glm::vec2 halfDimensions = 0.5f * dimensions; + + intersects = -halfDimensions.x <= localHitPosition.x && localHitPosition.x <= halfDimensions.x + && -halfDimensions.y <= localHitPosition.y && localHitPosition.y <= halfDimensions.y; + } + + return intersects; +} diff --git a/libraries/shared/src/GeometryUtil.h b/libraries/shared/src/GeometryUtil.h index a6889ef73e..657a06a604 100644 --- a/libraries/shared/src/GeometryUtil.h +++ b/libraries/shared/src/GeometryUtil.h @@ -76,6 +76,9 @@ bool findRaySphereIntersection(const glm::vec3& origin, const glm::vec3& directi bool findRayCapsuleIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& start, const glm::vec3& end, float radius, float& distance); +bool findRayRectangleIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::quat& rotation, + const glm::vec3& position, const glm::vec2& dimensions, float& distance); + bool findRayTriangleIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, float& distance); diff --git a/tests/audio/CMakeLists.txt b/tests/audio/CMakeLists.txt index 62d0ce5be9..a106fc9ea9 100644 --- a/tests/audio/CMakeLists.txt +++ b/tests/audio/CMakeLists.txt @@ -5,4 +5,4 @@ setup_hifi_project() # link in the shared libraries link_hifi_libraries(shared audio networking) -include_dependency_includes() \ No newline at end of file +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/tests/jitter/CMakeLists.txt b/tests/jitter/CMakeLists.txt index 93f7caefdd..377dcc1081 100644 --- a/tests/jitter/CMakeLists.txt +++ b/tests/jitter/CMakeLists.txt @@ -5,4 +5,4 @@ setup_hifi_project() # link in the shared libraries link_hifi_libraries(shared networking) -include_dependency_includes() \ No newline at end of file +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/tests/jitter/src/main.cpp b/tests/jitter/src/main.cpp index baaa2d08d6..788ae89c6f 100644 --- a/tests/jitter/src/main.cpp +++ b/tests/jitter/src/main.cpp @@ -8,7 +8,7 @@ #include #ifdef _WINDOWS -#include +#include #else #include #include @@ -76,7 +76,7 @@ void runSend(const char* addressOption, int port, int gap, int size, int report) memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = inet_addr(addressOption); + inet_pton(AF_INET, addressOption, &servaddr.sin_addr); servaddr.sin_port = htons(port); const int SAMPLES_FOR_SECOND = 1000000 / gap; diff --git a/tests/metavoxels/CMakeLists.txt b/tests/metavoxels/CMakeLists.txt index 76f8870b34..e6a62dc55c 100644 --- a/tests/metavoxels/CMakeLists.txt +++ b/tests/metavoxels/CMakeLists.txt @@ -7,4 +7,4 @@ setup_hifi_project(Network Script Widgets) # link in the shared libraries link_hifi_libraries(metavoxels networking shared) -include_dependency_includes() \ No newline at end of file +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/tests/networking/CMakeLists.txt b/tests/networking/CMakeLists.txt index 113a75ab50..6b9d3738d4 100644 --- a/tests/networking/CMakeLists.txt +++ b/tests/networking/CMakeLists.txt @@ -5,4 +5,4 @@ setup_hifi_project() # link in the shared libraries link_hifi_libraries(shared networking) -include_dependency_includes() \ No newline at end of file +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/tests/octree/CMakeLists.txt b/tests/octree/CMakeLists.txt index 99e3516431..70457e220a 100644 --- a/tests/octree/CMakeLists.txt +++ b/tests/octree/CMakeLists.txt @@ -5,4 +5,4 @@ setup_hifi_project(Script Network) # link in the shared libraries link_hifi_libraries(shared octree gpu model fbx metavoxels networking entities avatars audio animation script-engine physics) -include_dependency_includes() +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/tests/physics/CMakeLists.txt b/tests/physics/CMakeLists.txt index e20f323392..888b158035 100644 --- a/tests/physics/CMakeLists.txt +++ b/tests/physics/CMakeLists.txt @@ -2,12 +2,16 @@ set(TARGET_NAME physics-tests) setup_hifi_project() -add_dependency_external_project(glm) +add_dependency_external_projects(glm) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) -include_bullet() +add_dependency_external_projects(bullet) + +find_package(Bullet REQUIRED) +target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BULLET_INCLUDE_DIRS}) +target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) link_hifi_libraries(shared physics) -include_dependency_includes() +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/tests/render-utils/CMakeLists.txt b/tests/render-utils/CMakeLists.txt index 12a9fe5701..0452fd629c 100644 --- a/tests/render-utils/CMakeLists.txt +++ b/tests/render-utils/CMakeLists.txt @@ -7,11 +7,4 @@ setup_hifi_project(Quick Gui OpenGL) # link in the shared libraries link_hifi_libraries(render-utils gpu shared) -if (WIN32) - # we're using static GLEW, so define GLEW_STATIC - add_definitions(-DGLEW_STATIC) -endif () - -#link_libraries(animation fbx shared gpu) -include_dependency_includes() - +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/tests/shared/CMakeLists.txt b/tests/shared/CMakeLists.txt index 0402d3c74b..9ae00756e8 100644 --- a/tests/shared/CMakeLists.txt +++ b/tests/shared/CMakeLists.txt @@ -5,4 +5,4 @@ setup_hifi_project() # link in the shared libraries link_hifi_libraries(shared) -include_dependency_includes() \ No newline at end of file +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/tools/bitstream2json/CMakeLists.txt b/tools/bitstream2json/CMakeLists.txt index 64ffbae5bf..32a5a639ab 100644 --- a/tools/bitstream2json/CMakeLists.txt +++ b/tools/bitstream2json/CMakeLists.txt @@ -3,4 +3,4 @@ setup_hifi_project(Widgets Script) link_hifi_libraries(metavoxels) -include_dependency_includes() \ No newline at end of file +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/tools/json2bitstream/CMakeLists.txt b/tools/json2bitstream/CMakeLists.txt index d69a8dbe17..abda40667c 100644 --- a/tools/json2bitstream/CMakeLists.txt +++ b/tools/json2bitstream/CMakeLists.txt @@ -3,4 +3,4 @@ setup_hifi_project(Widgets Script) link_hifi_libraries(metavoxels) -include_dependency_includes() \ No newline at end of file +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/tools/mtc/CMakeLists.txt b/tools/mtc/CMakeLists.txt index 06b9f86d06..5c598eaf0b 100644 --- a/tools/mtc/CMakeLists.txt +++ b/tools/mtc/CMakeLists.txt @@ -1,4 +1,4 @@ set(TARGET_NAME mtc) setup_hifi_project() -include_dependency_includes() \ No newline at end of file +copy_dlls_beside_windows_executable() \ No newline at end of file diff --git a/tools/scribe/CMakeLists.txt b/tools/scribe/CMakeLists.txt index e67354cffa..b71a287e46 100755 --- a/tools/scribe/CMakeLists.txt +++ b/tools/scribe/CMakeLists.txt @@ -1,5 +1,2 @@ set(TARGET_NAME scribe) -setup_hifi_project() - -# call macro to include our dependency includes and bubble them up via a property on our target -include_dependency_includes() \ No newline at end of file +setup_hifi_project() \ No newline at end of file