From a308eb2e2fa660d178fd00cb5cd8300f81c44230 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 30 Mar 2015 16:44:10 -0700 Subject: [PATCH 01/20] don't use DX11 for bullet even if found --- cmake/externals/bullet/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/externals/bullet/CMakeLists.txt b/cmake/externals/bullet/CMakeLists.txt index e3610997d1..2d98b2e147 100644 --- a/cmake/externals/bullet/CMakeLists.txt +++ b/cmake/externals/bullet/CMakeLists.txt @@ -19,7 +19,7 @@ if (WIN32) ${EXTERNAL_NAME} URL https://bullet.googlecode.com/files/bullet-2.82-r2704.zip URL_MD5 f5e8914fc9064ad32e0d62d19d33d977 - CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH= -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_DEMOS=0 -DUSE_GLUT=0 + CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH= -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_DEMOS=0 -DUSE_GLUT=0 -DUSE_DX11=0 LOG_DOWNLOAD 1 LOG_CONFIGURE 1 LOG_BUILD 1 From 94c1cf12f5b44f714630410e93c0ab5c0c197008 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 30 Mar 2015 17:12:19 -0700 Subject: [PATCH 02/20] deleting _dynamicsWorld doesn't crash on shutdown --- libraries/physics/src/PhysicsEngine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 139a954b22..467b51560f 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -36,8 +36,8 @@ PhysicsEngine::~PhysicsEngine() { delete _collisionDispatcher; delete _broadphaseFilter; delete _constraintSolver; - // delete _dynamicsWorld; - // delete _ghostPairCallback; + delete _dynamicsWorld; + delete _ghostPairCallback; } // begin EntitySimulation overrides From f0c4aef93291471aaf1bb00c717bee9abce2ab6d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 30 Mar 2015 17:26:33 -0700 Subject: [PATCH 03/20] download and make tbb for OS X --- cmake/externals/tbb/CMakeLists.txt | 34 +++++++++++-------- .../tbb/OSXTBBInstallNameChange.cmake | 18 ++-------- ...droidTBBLibCopy.cmake => TBBLibCopy.cmake} | 4 +-- 3 files changed, 25 insertions(+), 31 deletions(-) rename cmake/externals/tbb/{AndroidTBBLibCopy.cmake => TBBLibCopy.cmake} (94%) diff --git a/cmake/externals/tbb/CMakeLists.txt b/cmake/externals/tbb/CMakeLists.txt index ad46196b95..b9b2b65010 100644 --- a/cmake/externals/tbb/CMakeLists.txt +++ b/cmake/externals/tbb/CMakeLists.txt @@ -13,16 +13,28 @@ if (ANDROID) 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 + INSTALL_COMMAND ${CMAKE_COMMAND} -DTBB_LIBS_SUFFIX=so -P ${CMAKE_CURRENT_SOURCE_DIR}/TBBLibCopy.cmake + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1 + LOG_BUILD 1 + ) +elseif (APPLE) + find_program(MAKE_COMMAND NAMES make DOC "Path to the make command") + + ExternalProject_Add( + ${EXTERNAL_NAME} + URL http://hifi-public.s3.amazonaws.com/dependencies/tbb43_20150316oss_src.tgz + URL_MD5 bf090eaa86cf89ea014b7b462786a440 + BUILD_COMMAND ${MAKE_COMMAND} tbb_os=macos + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND "" + INSTALL_COMMAND ${CMAKE_COMMAND} -DTBB_LIBS_SUFFIX=dylib -P ${CMAKE_CURRENT_SOURCE_DIR}/TBBLibCopy.cmake LOG_DOWNLOAD 1 LOG_CONFIGURE 1 LOG_BUILD 1 ) else () - if (APPLE) - set(DOWNLOAD_URL http://hifi-public.s3.amazonaws.com/dependencies/tbb43_20150316oss_osx.tgz) - set(DOWNLOAD_MD5 25a36ebff070ff801760ec658079f6aa) - elseif (WIN32) + if (WIN32) set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb43_20150316oss_win.zip) set(DOWNLOAD_MD5 d250d40bb93b255f75bcbb19e976a440) else () @@ -46,7 +58,7 @@ 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(_TBB_LIB_DIR "${SOURCE_DIR}/lib") set(_LIB_PREFIX "lib") set(_LIB_EXT "dylib") @@ -95,14 +107,8 @@ elseif (UNIX) endif () if (DEFINED _TBB_LIB_DIR) - if (NOT APPLE) - 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}_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc_debug.${_LIB_EXT} CACHE FILEPATH "TBB malloc debug library location") - else () - set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG "" CACHE FILEPATH "TBB debug library location") - set(${EXTERNAL_NAME_UPPER}_MALLOC_LIBRARY_DEBUG "" CACHE FILEPATH "TBB malloc debug library location") - endif () - + 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}_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc_debug.${_LIB_EXT} CACHE FILEPATH "TBB malloc 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_RELEASE ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbbmalloc.${_LIB_EXT} CACHE FILEPATH "TBB malloc release library location") endif () diff --git a/cmake/externals/tbb/OSXTBBInstallNameChange.cmake b/cmake/externals/tbb/OSXTBBInstallNameChange.cmake index c263ed7d2e..cc4df46812 100644 --- a/cmake/externals/tbb/OSXTBBInstallNameChange.cmake +++ b/cmake/externals/tbb/OSXTBBInstallNameChange.cmake @@ -10,9 +10,11 @@ # # first find the so files in the source dir -set(_TBB_LIBRARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/libc++) +set(_TBB_LIBRARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib) file(GLOB_RECURSE _TBB_LIBRARIES "${_TBB_LIBRARY_DIR}/*.dylib") +message(${_TBB_LIBRARIES}) + # raise an error if we found none if (NOT _TBB_LIBRARIES) message(FATAL_ERROR "Did not find any TBB libraries") @@ -28,20 +30,6 @@ find_program(LIPO_COMMAND NAMES lipo DOC "Path to the lipo command") 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}") diff --git a/cmake/externals/tbb/AndroidTBBLibCopy.cmake b/cmake/externals/tbb/TBBLibCopy.cmake similarity index 94% rename from cmake/externals/tbb/AndroidTBBLibCopy.cmake rename to cmake/externals/tbb/TBBLibCopy.cmake index 1c7697ab54..8f5423750b 100644 --- a/cmake/externals/tbb/AndroidTBBLibCopy.cmake +++ b/cmake/externals/tbb/TBBLibCopy.cmake @@ -1,5 +1,5 @@ # -# AndroidTBBLibCopy.cmake +# TBBLibCopy.cmake # cmake/externals/tbb # # Copyright 2015 High Fidelity, Inc. @@ -10,7 +10,7 @@ # # first find the so files in the source dir -file(GLOB_RECURSE _TBB_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/build/*.so") +file(GLOB_RECURSE _TBB_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/build/*.${TBB_LIBS_SUFFIX}") # raise an error if we found none if (NOT _TBB_LIBRARIES) From 63a59aa00a304d458c03156147c21bf1a293c141 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Mar 2015 15:56:01 -0700 Subject: [PATCH 04/20] fix a couple of crashes --- libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 2 +- libraries/physics/src/PhysicsEngine.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index eb6706e27f..826df45294 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -282,7 +282,7 @@ bool RenderableModelEntityItem::hasCollisionModel() const { } const QString& RenderableModelEntityItem::getCollisionModelURL() const { - assert (!_model || _collisionModelURL == _model->getCollisionURL().toString()); + // assert (!_model || _collisionModelURL == _model->getCollisionURL().toString()); return _collisionModelURL; } diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index f7dc90e72f..aabf3dc331 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -33,7 +33,7 @@ PhysicsEngine::~PhysicsEngine() { delete _collisionDispatcher; delete _broadphaseFilter; delete _constraintSolver; - delete _dynamicsWorld; + // delete _dynamicsWorld; // delete _ghostPairCallback; } From bdfe75b1f544952987dfd98176f2e78539fee4d4 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 30 Mar 2015 15:51:58 -0700 Subject: [PATCH 05/20] remove character from PhysicsEngine on shutdown --- interface/src/Application.cpp | 1 + libraries/physics/src/CharacterController.cpp | 6 ++++++ libraries/physics/src/PhysicsEngine.cpp | 15 +++++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5753449075..549f05a905 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -608,6 +608,7 @@ Application::~Application() { Menu::getInstance()->deleteLater(); + _physicsEngine.setCharacterController(NULL); _myAvatar = NULL; ModelEntityItem::cleanupLoadedAnimations(); diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 148746a76e..626a1ea3a9 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -241,6 +241,12 @@ CharacterController::CharacterController(AvatarData* avatarData) { } CharacterController::~CharacterController() { + delete _ghostObject; + _ghostObject = NULL; + delete _convexShape; + _convexShape = NULL; + // make sure you remove this Character from its DynamicsWorld before reaching this spot + assert(_dynamicsWorld == NULL); } btPairCachingGhostObject* CharacterController::getGhostObject() { diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index aabf3dc331..00361693b3 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -28,6 +28,9 @@ PhysicsEngine::PhysicsEngine(const glm::vec3& offset) } PhysicsEngine::~PhysicsEngine() { + if (_characterController) { + _characterController->setDynamicsWorld(NULL); + } // TODO: delete engine components... if we ever plan to create more than one instance delete _collisionConfig; delete _collisionDispatcher; @@ -614,10 +617,18 @@ bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio } void PhysicsEngine::setCharacterController(CharacterController* character) { - if (!_characterController) { + if (_characterController != character) { lock(); - _characterController = character; + if (_characterController) { + // remove the character from the DynamicsWorld immediately + _characterController->setDynamicsWorld(NULL); + _characterController = NULL; + } unlock(); + if (character) { + // the character will be added to the DynamicsWorld later + _characterController = character; + } } } From b8ff253f86034684e3d0b98198eab6ada3105135 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 30 Mar 2015 16:07:56 -0700 Subject: [PATCH 06/20] unlock after character is properly updated --- libraries/physics/src/PhysicsEngine.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 00361693b3..139a954b22 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -624,11 +624,9 @@ void PhysicsEngine::setCharacterController(CharacterController* character) { _characterController->setDynamicsWorld(NULL); _characterController = NULL; } + // the character will be added to the DynamicsWorld later + _characterController = character; unlock(); - if (character) { - // the character will be added to the DynamicsWorld later - _characterController = character; - } } } From b7174b517078bc22880a0588a1c3a385c6e7aad3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 30 Mar 2015 18:00:15 -0700 Subject: [PATCH 07/20] fix for cleanup of SettingsManager thread --- libraries/shared/src/SettingInterface.cpp | 15 +++++++++++---- libraries/shared/src/SettingManager.cpp | 1 + 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/libraries/shared/src/SettingInterface.cpp b/libraries/shared/src/SettingInterface.cpp index 0ef22e3fcb..217a8f00b2 100644 --- a/libraries/shared/src/SettingInterface.cpp +++ b/libraries/shared/src/SettingInterface.cpp @@ -1,6 +1,6 @@ // // SettingInterface.cpp -// +// libraries/shared/src // // Created by Clement on 2/2/15. // Copyright 2015 High Fidelity, Inc. @@ -9,7 +9,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - #include #include #include @@ -23,8 +22,16 @@ namespace Setting { // cleans up the settings private instance. Should only be run once at closing down. void cleanupPrivateInstance() { - delete privateInstance; - privateInstance = nullptr; + // grab the thread before we nuke the instance + QThread* settingsManagerThread = privateInstance->thread(); + + // tell the private instance to clean itself up on its thread + privateInstance->deleteLater(); + privateInstance = NULL; + + // quit the settings manager thread and wait on it to make sure it's gone + settingsManagerThread->quit(); + settingsManagerThread->wait(); } // Sets up the settings private instance. Should only be run once at startup diff --git a/libraries/shared/src/SettingManager.cpp b/libraries/shared/src/SettingManager.cpp index 8bb6c89c82..e53185deb7 100644 --- a/libraries/shared/src/SettingManager.cpp +++ b/libraries/shared/src/SettingManager.cpp @@ -16,6 +16,7 @@ namespace Setting { Manager::~Manager() { + // Cleanup timer stopTimer(); disconnect(_saveTimer, 0, 0, 0); From 7d5b8c430a281ec4ade9e4345aff49aa5fea8218 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 30 Mar 2015 18:06:51 -0700 Subject: [PATCH 08/20] remove extra added space --- libraries/shared/src/SettingManager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/shared/src/SettingManager.cpp b/libraries/shared/src/SettingManager.cpp index e53185deb7..8bb6c89c82 100644 --- a/libraries/shared/src/SettingManager.cpp +++ b/libraries/shared/src/SettingManager.cpp @@ -16,7 +16,6 @@ namespace Setting { Manager::~Manager() { - // Cleanup timer stopTimer(); disconnect(_saveTimer, 0, 0, 0); From 622f10bd25bab208002fbcb544506a7e7a82c41b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 30 Mar 2015 17:54:57 -0700 Subject: [PATCH 09/20] Add minimize button --- examples/users.js | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/examples/users.js b/examples/users.js index ebd59886aa..51b198720a 100644 --- a/examples/users.js +++ b/examples/users.js @@ -11,7 +11,9 @@ var usersWindow = (function () { - var WINDOW_WIDTH_2D = 160, + var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/", + + WINDOW_WIDTH_2D = 160, WINDOW_MARGIN_2D = 12, WINDOW_FONT_2D = { size: 12 }, WINDOW_FOREGROUND_COLOR_2D = { red: 240, green: 240, blue: 240 }, @@ -22,6 +24,14 @@ var usersWindow = (function () { WINDOW_BACKGROUND_ALPHA_2D = 0.7, windowPane2D, windowHeading2D, + MINIMIZE_BUTTON_SVG = HIFI_PUBLIC_BUCKET + "images/tools/min-max-toggle.svg", + MINIMIZE_BUTTON_SVG_WIDTH = 17.1, + MINIMIZE_BUTTON_SVG_HEIGHT = 32.5, + MINIMIZE_BUTTON_WIDTH_2D = 14, + MINIMIZE_BUTTON_HEIGHT_2D = MINIMIZE_BUTTON_WIDTH_2D, + MINIMIZE_BUTTON_COLOR_2D = { red: 255, green: 255, blue: 255 }, + MINIMIZE_BUTTON_ALPHA_2D = 0.9, + minimizeButton2D, SCROLLBAR_BACKGROUND_WIDTH_2D = 12, SCROLLBAR_BACKGROUND_COLOR_2D = { red: 80, green: 80, blue: 80 }, SCROLLBAR_BACKGROUND_ALPHA_2D = 0.8, @@ -77,7 +87,6 @@ var usersWindow = (function () { scrollbarBarClickedAt, // 0.0 .. 1.0 scrollbarValue = 0.0, // 0.0 .. 1.0 - HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/", RADIO_BUTTON_SVG = HIFI_PUBLIC_BUCKET + "images/radio-button.svg", RADIO_BUTTON_SVG_DIAMETER = 14, RADIO_BUTTON_DISPLAY_SCALE = 0.7, // 1.0 = windowTextHeight @@ -123,6 +132,10 @@ var usersWindow = (function () { y: viewportHeight - windowHeight + WINDOW_MARGIN_2D }); + Overlays.editOverlay(minimizeButton2D, { + y: viewportHeight - windowHeight + WINDOW_MARGIN_2D / 2 + }); + scrollbarBackgroundPosition.y = viewportHeight - windowHeight + WINDOW_MARGIN_2D + windowTextHeight; Overlays.editOverlay(scrollbarBackground2D, { y: scrollbarBackgroundPosition.y @@ -305,6 +318,7 @@ var usersWindow = (function () { Overlays.editOverlay(windowPane2D, { visible: isVisible }); Overlays.editOverlay(windowHeading2D, { visible: isVisible }); + Overlays.editOverlay(minimizeButton2D, { visible: isVisible }); Overlays.editOverlay(scrollbarBackground2D, { visible: isVisible && isUsingScrollbars }); Overlays.editOverlay(scrollbarBar2D, { visible: isVisible && isUsingScrollbars }); Overlays.editOverlay(visibilityHeading2D, { visible: isVisible }); @@ -495,6 +509,17 @@ var usersWindow = (function () { visible: isVisible }); + minimizeButton2D = Overlays.addOverlay("image", { + x: WINDOW_WIDTH_2D - WINDOW_MARGIN_2D / 2 - MINIMIZE_BUTTON_WIDTH_2D, + y: viewportHeight, + width: MINIMIZE_BUTTON_WIDTH_2D, + height: MINIMIZE_BUTTON_HEIGHT_2D, + imageURL: MINIMIZE_BUTTON_SVG, + subImage: { x: 0, y: 0, width: MINIMIZE_BUTTON_SVG_WIDTH, height: MINIMIZE_BUTTON_SVG_HEIGHT / 2 }, + color: MINIMIZE_BUTTON_COLOR_2D, + alpha: MINIMIZE_BUTTON_ALPHA_2D + }); + scrollbarBackgroundPosition = { x: WINDOW_WIDTH_2D - 0.5 * WINDOW_MARGIN_2D - SCROLLBAR_BACKGROUND_WIDTH_2D, y: viewportHeight @@ -634,6 +659,7 @@ var usersWindow = (function () { Script.clearTimeout(usersTimer); Overlays.deleteOverlay(windowPane2D); Overlays.deleteOverlay(windowHeading2D); + Overlays.deleteOverlay(minimizeButton2D); Overlays.deleteOverlay(scrollbarBackground2D); Overlays.deleteOverlay(scrollbarBar2D); Overlays.deleteOverlay(visibilityHeading2D); From 495b62b3565e7030224534528e2f866cdbc8146a Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 30 Mar 2015 20:36:01 -0700 Subject: [PATCH 10/20] Add minimized state --- examples/users.js | 142 +++++++++++++++++++++++++++++----------------- 1 file changed, 89 insertions(+), 53 deletions(-) diff --git a/examples/users.js b/examples/users.js index 51b198720a..2bc69d1638 100644 --- a/examples/users.js +++ b/examples/users.js @@ -15,6 +15,7 @@ var usersWindow = (function () { WINDOW_WIDTH_2D = 160, WINDOW_MARGIN_2D = 12, + WINDOW_BASE_MARGIN_2D = 6, // A little less is needed in order look correct WINDOW_FONT_2D = { size: 12 }, WINDOW_FOREGROUND_COLOR_2D = { red: 240, green: 240, blue: 240 }, WINDOW_FOREGROUND_ALPHA_2D = 0.9, @@ -75,6 +76,7 @@ var usersWindow = (function () { MENU_ITEM_AFTER = "Chat...", isVisible = true, + isMinimized = false, viewportHeight, isMirrorDisplay = false, @@ -98,9 +100,15 @@ var usersWindow = (function () { nonUsersHeight, maxWindowHeight; + if (isMinimized) { + windowHeight = windowTextHeight + WINDOW_MARGIN_2D + WINDOW_BASE_MARGIN_2D; + return; + } + // Reserve 5 lines for window heading plus visibility heading and controls // Subtract windowLineSpacing for both end of user list and end of controls - nonUsersHeight = 5 * windowLineHeight - 2 * windowLineSpacing + VISIBILITY_SPACER_2D + 2 * WINDOW_MARGIN_2D; + nonUsersHeight = 5 * windowLineHeight - 2 * windowLineSpacing + VISIBILITY_SPACER_2D + WINDOW_MARGIN_2D + + WINDOW_BASE_MARGIN_2D; // Limit window to height of viewport minus VU meter and mirror if displayed windowHeight = linesOfUsers.length * windowLineHeight + nonUsersHeight; @@ -111,7 +119,7 @@ var usersWindow = (function () { windowHeight = Math.max(Math.min(windowHeight, maxWindowHeight), nonUsersHeight); // Corresponding number of users to actually display - numUsersToDisplay = Math.max(Math.round((windowHeight - nonUsersHeight) / windowLineHeight), 0); + numUsersToDisplay = Math.max(Math.floor((windowHeight - nonUsersHeight) / windowLineHeight), 0); isUsingScrollbars = 0 < numUsersToDisplay && numUsersToDisplay < linesOfUsers.length; if (isUsingScrollbars) { firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay)); @@ -146,10 +154,10 @@ var usersWindow = (function () { y: scrollbarBarPosition.y }); Overlays.editOverlay(visibilityHeading2D, { - y: viewportHeight - 4 * windowLineHeight + windowLineSpacing - WINDOW_MARGIN_2D + y: viewportHeight - 4 * windowLineHeight + windowLineSpacing - WINDOW_BASE_MARGIN_2D }); for (i = 0; i < visibilityControls2D.length; i += 1) { - y = viewportHeight - (3 - i) * windowLineHeight + windowLineSpacing - WINDOW_MARGIN_2D; + y = viewportHeight - (3 - i) * windowLineHeight + windowLineSpacing - WINDOW_BASE_MARGIN_2D; Overlays.editOverlay(visibilityControls2D[i].radioOverlay, { y: y }); Overlays.editOverlay(visibilityControls2D[i].textOverlay, { y: y }); } @@ -179,29 +187,43 @@ var usersWindow = (function () { reducedTextWidth, i; - maxTextWidth = WINDOW_WIDTH_2D - (isUsingScrollbars ? SCROLLBAR_BACKGROUND_WIDTH_2D : 0) - 2 * WINDOW_MARGIN_2D; - ellipsisWidth = Overlays.textSize(windowPane2D, "...").width; - reducedTextWidth = maxTextWidth - ellipsisWidth; + if (!isMinimized) { + maxTextWidth = WINDOW_WIDTH_2D - (isUsingScrollbars ? SCROLLBAR_BACKGROUND_WIDTH_2D : 0) - 2 * WINDOW_MARGIN_2D; + ellipsisWidth = Overlays.textSize(windowPane2D, "...").width; + reducedTextWidth = maxTextWidth - ellipsisWidth; - for (i = 0; i < numUsersToDisplay; i += 1) { - user = usersOnline[linesOfUsers[firstUserToDisplay + i]]; - userText = user.text; - textWidth = user.textWidth; + for (i = 0; i < numUsersToDisplay; i += 1) { + user = usersOnline[linesOfUsers[firstUserToDisplay + i]]; + userText = user.text; + textWidth = user.textWidth; - if (textWidth > maxTextWidth) { - // Trim and append "..." to fit window width - maxTextWidth = maxTextWidth - Overlays.textSize(windowPane2D, "...").width; - while (textWidth > reducedTextWidth) { - userText = userText.slice(0, -1); - textWidth = Overlays.textSize(windowPane2D, userText).width; + if (textWidth > maxTextWidth) { + // Trim and append "..." to fit window width + maxTextWidth = maxTextWidth - Overlays.textSize(windowPane2D, "...").width; + while (textWidth > reducedTextWidth) { + userText = userText.slice(0, -1); + textWidth = Overlays.textSize(windowPane2D, userText).width; + } + userText += "..."; } - userText += "..."; + + displayText += "\n" + userText; } - displayText += "\n" + userText; - } + displayText = displayText.slice(1); // Remove leading "\n". - displayText = displayText.slice(1); // Remove leading "\n". + scrollbarBackgroundHeight = numUsersToDisplay * windowLineHeight - windowLineSpacing / 2; + Overlays.editOverlay(scrollbarBackground2D, { + height: scrollbarBackgroundHeight, + visible: isUsingScrollbars + }); + scrollbarBarHeight = Math.max(numUsersToDisplay / linesOfUsers.length * scrollbarBackgroundHeight, + SCROLLBAR_BAR_MIN_HEIGHT); + Overlays.editOverlay(scrollbarBar2D, { + height: scrollbarBarHeight, + visible: isUsingScrollbars + }); + } Overlays.editOverlay(windowPane2D, { height: windowHeight, @@ -211,20 +233,6 @@ var usersWindow = (function () { Overlays.editOverlay(windowHeading2D, { text: linesOfUsers.length > 0 ? "Users online" : "No users online" }); - - scrollbarBackgroundHeight = numUsersToDisplay * windowLineHeight - windowLineSpacing / 2; - Overlays.editOverlay(scrollbarBackground2D, { - height: scrollbarBackgroundHeight, - visible: isUsingScrollbars - }); - scrollbarBarHeight = Math.max(numUsersToDisplay / linesOfUsers.length * scrollbarBackgroundHeight, - SCROLLBAR_BAR_MIN_HEIGHT); - Overlays.editOverlay(scrollbarBar2D, { - height: scrollbarBarHeight, - visible: isUsingScrollbars - }); - - updateOverlayPositions(); } function pollUsers() { @@ -277,6 +285,7 @@ var usersWindow = (function () { calculateWindowHeight(); updateUsersDisplay(); + updateOverlayPositions(); } else { print("Error: Request for users status returned " + usersRequest.status + " " + usersRequest.statusText); @@ -302,9 +311,22 @@ var usersWindow = (function () { } } - function setVisible(visible) { + function updateOverlayVisibility() { var i; + Overlays.editOverlay(windowPane2D, { visible: isVisible }); + Overlays.editOverlay(windowHeading2D, { visible: isVisible }); + Overlays.editOverlay(minimizeButton2D, { visible: isVisible }); + Overlays.editOverlay(scrollbarBackground2D, { visible: isVisible && isUsingScrollbars && !isMinimized }); + Overlays.editOverlay(scrollbarBar2D, { visible: isVisible && isUsingScrollbars && !isMinimized }); + Overlays.editOverlay(visibilityHeading2D, { visible: isVisible && !isMinimized }); + for (i = 0; i < visibilityControls2D.length; i += 1) { + Overlays.editOverlay(visibilityControls2D[i].radioOverlay, { visible: isVisible && !isMinimized }); + Overlays.editOverlay(visibilityControls2D[i].textOverlay, { visible: isVisible && !isMinimized }); + } + } + + function setVisible(visible) { isVisible = visible; if (isVisible) { @@ -316,16 +338,15 @@ var usersWindow = (function () { usersTimer = null; } - Overlays.editOverlay(windowPane2D, { visible: isVisible }); - Overlays.editOverlay(windowHeading2D, { visible: isVisible }); - Overlays.editOverlay(minimizeButton2D, { visible: isVisible }); - Overlays.editOverlay(scrollbarBackground2D, { visible: isVisible && isUsingScrollbars }); - Overlays.editOverlay(scrollbarBar2D, { visible: isVisible && isUsingScrollbars }); - Overlays.editOverlay(visibilityHeading2D, { visible: isVisible }); - for (i = 0; i < visibilityControls2D.length; i += 1) { - Overlays.editOverlay(visibilityControls2D[i].radioOverlay, { visible: isVisible }); - Overlays.editOverlay(visibilityControls2D[i].textOverlay, { visible: isVisible }); - } + updateOverlayVisibility(); + } + + function setMinimized(minimized) { + isMinimized = minimized; + Overlays.editOverlay(minimizeButton2D, { + subImage: { y: isMinimized ? MINIMIZE_BUTTON_SVG_HEIGHT / 2 : 0 } + }); + updateOverlayVisibility(); } function onMenuItemEvent(event) { @@ -374,6 +395,8 @@ var usersWindow = (function () { //print("Go to " + usersOnline[linesOfUsers[userClicked]].username); location.goToUser(usersOnline[linesOfUsers[userClicked]].username); } + + return; } visibilityChanged = false; @@ -390,6 +413,15 @@ var usersWindow = (function () { visibilityControls2D[i].selected = clickedOverlay === visibilityControls2D[i].textOverlay; } updateVisibilityControls(); + return; + } + + if (clickedOverlay === minimizeButton2D) { + setMinimized(!isMinimized); + calculateWindowHeight(); + updateOverlayPositions(); + updateUsersDisplay(); + return; } if (clickedOverlay === scrollbarBar2D) { @@ -398,6 +430,7 @@ var usersWindow = (function () { backgroundAlpha: SCROLLBAR_BAR_SELECTED_ALPHA_2D }); isMovingScrollbar = true; + return; } if (clickedOverlay === scrollbarBackground2D) { @@ -412,6 +445,7 @@ var usersWindow = (function () { firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay)); updateOverlayPositions(); updateUsersDisplay(); + return; } } @@ -506,7 +540,7 @@ var usersWindow = (function () { backgroundAlpha: 0.0, text: "No users online", font: WINDOW_FONT_2D, - visible: isVisible + visible: isVisible && !isMinimized }); minimizeButton2D = Overlays.addOverlay("image", { @@ -517,7 +551,8 @@ var usersWindow = (function () { imageURL: MINIMIZE_BUTTON_SVG, subImage: { x: 0, y: 0, width: MINIMIZE_BUTTON_SVG_WIDTH, height: MINIMIZE_BUTTON_SVG_HEIGHT / 2 }, color: MINIMIZE_BUTTON_COLOR_2D, - alpha: MINIMIZE_BUTTON_ALPHA_2D + alpha: MINIMIZE_BUTTON_ALPHA_2D, + visible: isVisible && !isMinimized }); scrollbarBackgroundPosition = { @@ -532,7 +567,7 @@ var usersWindow = (function () { backgroundColor: SCROLLBAR_BACKGROUND_COLOR_2D, backgroundAlpha: SCROLLBAR_BACKGROUND_ALPHA_2D, text: "", - visible: isVisible && isUsingScrollbars + visible: isVisible && isUsingScrollbars && !isMinimized }); scrollbarBarPosition = { @@ -547,7 +582,7 @@ var usersWindow = (function () { backgroundColor: SCROLLBAR_BAR_COLOR_2D, backgroundAlpha: SCROLLBAR_BAR_ALPHA_2D, text: "", - visible: isVisible && isUsingScrollbars + visible: isVisible && isUsingScrollbars && !isMinimized }); visibilityHeading2D = Overlays.addOverlay("text", { @@ -562,7 +597,7 @@ var usersWindow = (function () { backgroundAlpha: 0.0, text: "I am visible to:", font: WINDOW_FONT_2D, - visible: isVisible + visible: isVisible && !isMinimized }); myVisibility = GlobalServices.findableBy; @@ -586,7 +621,8 @@ var usersWindow = (function () { height: RADIO_BUTTON_SVG_DIAMETER }, color: WINDOW_HEADING_COLOR_2D, - alpha: WINDOW_FOREGROUND_ALPHA_2D + alpha: WINDOW_FOREGROUND_ALPHA_2D, + visible: isVisible && !isMinimized }), textOverlay: Overlays.addOverlay("text", { x: WINDOW_MARGIN_2D, @@ -600,7 +636,7 @@ var usersWindow = (function () { backgroundAlpha: 0.0, text: optionText, font: WINDOW_FONT_2D, - visible: isVisible + visible: isVisible && !isMinimized }), selected: myVisibility === VISIBILITY_VALUES[0] }]; From fdfb8bd1b45b123ea80af0f50dd2b9edb649c5d3 Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 31 Mar 2015 09:26:33 -0700 Subject: [PATCH 11/20] fix intermittent crash on windows during login --- libraries/physics/src/CharacterController.cpp | 48 +++++++++---------- libraries/physics/src/CharacterController.h | 28 +++++------ 2 files changed, 36 insertions(+), 40 deletions(-) mode change 100644 => 100755 libraries/physics/src/CharacterController.cpp diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp old mode 100644 new mode 100755 index 626a1ea3a9..65feaa7ea3 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -274,7 +274,6 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl collisionWorld->getDispatcher()->dispatchAllCollisionPairs(_ghostObject->getOverlappingPairCache(), collisionWorld->getDispatchInfo(), collisionWorld->getDispatcher()); _currentPosition = _ghostObject->getWorldTransform().getOrigin(); - btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); btVector3 currentPosition = _currentPosition; @@ -308,7 +307,7 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl btVector3 normal = pt.m_normalWorldOnB; normal *= directionSign; // always points from object to character - btScalar normalDotUp = normal.dot(up); + btScalar normalDotUp = normal.dot(_currentUp); if (normalDotUp < _maxSlopeCosine) { // this contact has a non-vertical normal... might need to ignored btVector3 collisionPoint; @@ -319,9 +318,9 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl } // we do math in frame where character base is origin - btVector3 characterBase = currentPosition - (_radius + _halfHeight) * up; + btVector3 characterBase = currentPosition - (_radius + _halfHeight) * _currentUp; collisionPoint -= characterBase; - btScalar collisionHeight = collisionPoint.dot(up); + btScalar collisionHeight = collisionPoint.dot(_currentUp); if (collisionHeight < _lastStepUp) { // This contact is below the lastStepUp, so we ignore it for penetration resolution, @@ -357,11 +356,10 @@ void CharacterController::scanDown(btCollisionWorld* world) { callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; - btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); btVector3 start = _currentPosition; const btScalar MAX_SCAN_HEIGHT = 20.0f + _halfHeight + _radius; // closest possible floor for disabling hover const btScalar MIN_HOVER_HEIGHT = 3.0f + _halfHeight + _radius; // distance to floor for enabling hover - btVector3 end = start - MAX_SCAN_HEIGHT * up; + btVector3 end = start - MAX_SCAN_HEIGHT * _currentUp; world->rayTest(start, end, callback); if (!callback.hasHit()) { @@ -377,15 +375,14 @@ void CharacterController::stepUp(btCollisionWorld* world) { // compute start and end btTransform start, end; start.setIdentity(); - btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); - start.setOrigin(_currentPosition + up * (_convexShape->getMargin() + _addedMargin)); + start.setOrigin(_currentPosition + _currentUp * (_convexShape->getMargin() + _addedMargin)); - _targetPosition = _currentPosition + up * _stepUpHeight; + _targetPosition = _currentPosition + _currentUp * _stepUpHeight; end.setIdentity(); end.setOrigin(_targetPosition); // sweep up - btVector3 sweepDirNegative = - up; + btVector3 sweepDirNegative = - _currentUp; btKinematicClosestNotMeConvexResultCallback callback(_ghostObject, sweepDirNegative, btScalar(0.7071)); callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; @@ -397,7 +394,7 @@ void CharacterController::stepUp(btCollisionWorld* world) { _verticalOffset = 0.0f; // Only modify the position if the hit was a slope and not a wall or ceiling. - if (callback.m_hitNormalWorld.dot(up) > 0.0f) { + if (callback.m_hitNormalWorld.dot(_currentUp) > 0.0f) { _lastStepUp = _stepUpHeight * callback.m_closestHitFraction; _currentPosition.setInterpolate3(_currentPosition, _targetPosition, callback.m_closestHitFraction); } else { @@ -469,8 +466,8 @@ void CharacterController::stepForward(btCollisionWorld* collisionWorld, const bt // sweep forward btVector3 sweepDirNegative(_currentPosition - _targetPosition); btKinematicClosestNotMeConvexResultCallback callback(_ghostObject, sweepDirNegative, btScalar(0.0)); - callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; - callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; + callback.m_collisionFilterGroup = _ghostObject->getBroadphaseHandle()->m_collisionFilterGroup; + callback.m_collisionFilterMask = _ghostObject->getBroadphaseHandle()->m_collisionFilterMask; _ghostObject->convexSweepTest(_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); if (callback.hasHit()) { @@ -502,17 +499,16 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt // reach of the character's feet. // first sweep for ledge - btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); - btVector3 step = (_verticalVelocity * dt - _lastStepUp) * up; + btVector3 step = (_verticalVelocity * dt - _lastStepUp) * _currentUp; StepDownConvexResultCallback callback(_ghostObject, - up, + _currentUp, _currentPosition, step, _walkDirection, _maxSlopeCosine, _radius, _halfHeight); - callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; - callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; + callback.m_collisionFilterGroup = _ghostObject->getBroadphaseHandle()->m_collisionFilterGroup; + callback.m_collisionFilterMask = _ghostObject->getBroadphaseHandle()->m_collisionFilterMask; btTransform start, end; start.setIdentity(); @@ -532,16 +528,16 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt _isOnGround = true; } else if (!_isJumping) { // sweep again for floor within downStep threshold - step = -_stepDownHeight * up; + step = -_stepDownHeight * _currentUp; StepDownConvexResultCallback callback2 (_ghostObject, - up, + _currentUp, _currentPosition, step, _walkDirection, _maxSlopeCosine, _radius, _halfHeight); - callback2.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; - callback2.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; + callback2.m_collisionFilterGroup = _ghostObject->getBroadphaseHandle()->m_collisionFilterGroup; + callback2.m_collisionFilterMask = _ghostObject->getBroadphaseHandle()->m_collisionFilterMask; _currentPosition = _targetPosition; _targetPosition = _currentPosition + step; @@ -617,10 +613,10 @@ void CharacterController::preStep(btCollisionWorld* collisionWorld) { } } + // the CharacterController algorithm can only change the position, + // so we don't bother to pull the rotation out of the transform const btTransform& transform = _ghostObject->getWorldTransform(); - _currentRotation = transform.getRotation(); _currentPosition = transform.getOrigin(); - _targetPosition = _currentPosition; } void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar dt) { @@ -868,6 +864,7 @@ void CharacterController::updateShapeIfNecessary() { void CharacterController::preSimulation(btScalar timeStep) { if (_enabled && _dynamicsWorld) { glm::quat rotation = _avatarData->getOrientation(); + btVector3 _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS); glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset; btVector3 walkVelocity = glmToBullet(_avatarData->getVelocity()); @@ -895,8 +892,7 @@ void CharacterController::postSimulation() { // cap the velocity of the step so that the character doesn't POP! so hard on steps glm::vec3 finalStep = position - _lastPosition; btVector3 finalVelocity = _walkDirection; - btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); - finalVelocity += _verticalVelocity * up; + finalVelocity += _verticalVelocity * _currentUp; const btScalar MAX_RESOLUTION_SPEED = 5.0f; // m/sec btScalar maxStepLength = glm::max(MAX_RESOLUTION_SPEED, 2.0f * finalVelocity.length()) * _stepDt; btScalar stepLength = glm::length(finalStep); diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index eeaa5836dd..e4e73b6d3f 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -42,9 +42,22 @@ class btPairCachingGhostObject; ATTRIBUTE_ALIGNED16(class) CharacterController : public btCharacterControllerInterface { protected: + ///this is the desired walk direction, set by the user + btVector3 _walkDirection; + btVector3 _normalizedDirection; + + //some internal variables + btVector3 _currentPosition; + btVector3 _currentUp; + btVector3 _targetPosition; + glm::vec3 _lastPosition; + btVector3 _floorNormal; // points from object to character + + glm::vec3 _shapeLocalOffset; + glm::vec3 _boxScale; // used to compute capsule shape AvatarData* _avatarData = NULL; - btPairCachingGhostObject* _ghostObject; + btPairCachingGhostObject* _ghostObject = NULL; btConvexShape* _convexShape;//is also in _ghostObject, but it needs to be convex, so we store it here to avoid upcast btScalar _radius; @@ -64,22 +77,12 @@ protected: btScalar _addedMargin;//@todo: remove this and fix the code - ///this is the desired walk direction, set by the user - btVector3 _walkDirection; - btVector3 _normalizedDirection; - - //some internal variables - btVector3 _currentPosition; - btQuaternion _currentRotation; - btVector3 _targetPosition; - glm::vec3 _lastPosition; btScalar _lastStepUp; ///keep track of the contact manifolds btManifoldArray _manifoldArray; bool _touchingContact; - btVector3 _floorNormal; // points from object to character bool _enabled; bool _isOnGround; @@ -90,9 +93,6 @@ protected: btScalar _stepDt; uint32_t _pendingFlags; - glm::vec3 _shapeLocalOffset; - glm::vec3 _boxScale; // used to compute capsule shape - btDynamicsWorld* _dynamicsWorld = NULL; btVector3 computeReflectionDirection(const btVector3& direction, const btVector3& normal); From edf0ca2b06e4621afc82db46945d8d5c3fcee474 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 31 Mar 2015 10:29:03 -0700 Subject: [PATCH 12/20] Forbifd the global ambient lighting to go the simple global value and instead fallback to the first Spherical harmonics preset --- libraries/render-utils/src/DeferredLightingEffect.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index ffa84adbdf..6ed73c6750 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -535,10 +535,14 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit } void DeferredLightingEffect::setAmbientLightMode(int preset) { - if ((preset >= -1) && (preset < model::SphericalHarmonics::NUM_PRESET)) { + //if ((preset >= -1) && (preset < model::SphericalHarmonics::NUM_PRESET)) { + if ((preset >= 0) && (preset < model::SphericalHarmonics::NUM_PRESET)) { _ambientLightMode = preset; auto light = _allocatedLights.front(); light->setAmbientSpherePreset(model::SphericalHarmonics::Preset(preset % model::SphericalHarmonics::NUM_PRESET)); + } else { + // force to preset 0 + setAmbientLightMode(0); } } From 79305141d168a1b95f277f5a9078ac2df929e951 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 31 Mar 2015 10:51:07 -0700 Subject: [PATCH 13/20] Fix edit.js not selecting all when tabbing between properties --- examples/html/entityProperties.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 596bf5c9d5..1c5fd58084 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -210,6 +210,9 @@ disableChildren(document.getElementById("properties-list"), 'input'); } else { + var activeElement = document.activeElement; + var selected = activeElement.selectionStart == 0 && activeElement.selectionEnd == activeElement.value.length; + var properties = data.selections[0].properties; elID.innerHTML = properties.id; @@ -335,6 +338,11 @@ elLightExponent.value = properties.exponent; elLightCutoff.value = properties.cutoff; } + + if (selected) { + activeElement.focus(); + activeElement.select(); + } } } }); From df99c314aa9ffeede5a4040e69c3d762ec23facc Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 31 Mar 2015 12:44:44 -0700 Subject: [PATCH 14/20] fix issue with preload not being called on import --- .../entities-renderer/src/EntityTreeRenderer.cpp | 9 ++++++--- libraries/entities-renderer/src/EntityTreeRenderer.h | 1 + libraries/entities/src/EntityTree.cpp | 12 +++++++++++- libraries/entities/src/EntityTree.h | 1 + 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 058e02b507..95ca30a90f 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -101,7 +101,7 @@ void EntityTreeRenderer::init() { _lastAvatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE); connect(entityTree, &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity); - connect(entityTree, &EntityTree::addingEntity, this, &EntityTreeRenderer::checkAndCallPreload); + connect(entityTree, &EntityTree::addingEntity, this, &EntityTreeRenderer::addingEntity); connect(entityTree, &EntityTree::entityScriptChanging, this, &EntityTreeRenderer::entitySciptChanging); connect(entityTree, &EntityTree::changingEntityID, this, &EntityTreeRenderer::changingEntityID); } @@ -193,7 +193,7 @@ QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity, bool isPre // can accomplish all we need to here with just the script "text" and the ID. EntityItemID entityID = entity->getEntityItemID(); QString entityScript = entity->getScript(); - + if (_entityScripts.contains(entityID)) { EntityScriptDetails details = _entityScripts[entityID]; @@ -217,7 +217,6 @@ QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity, bool isPre if (isPending && isPreload && isURL) { _waitingOnPreload.insert(url, entityID); - } auto scriptCache = DependencyManager::get(); @@ -941,6 +940,10 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) { _entityScripts.remove(entityID); } +void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) { + checkAndCallPreload(entityID); +} + void EntityTreeRenderer::entitySciptChanging(const EntityItemID& entityID) { if (_tree && !_shuttingDown) { checkAndCallUnload(entityID); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 12d5f6e166..e8d70c9df9 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -105,6 +105,7 @@ signals: void leaveEntity(const EntityItemID& entityItemID); public slots: + void addingEntity(const EntityItemID& entityID); void deletingEntity(const EntityItemID& entityID); void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID); void entitySciptChanging(const EntityItemID& entityID); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 266aa2bdce..cb5d43693d 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -404,7 +404,8 @@ void EntityTree::handleAddEntityResponse(const QByteArray& packet) { EntityItem* foundEntity = NULL; EntityItemID creatorTokenVersion = searchEntityID.convertToCreatorTokenVersion(); EntityItemID knownIDVersion = searchEntityID.convertToKnownIDVersion(); - + + _changedEntityIDs[creatorTokenVersion] = knownIDVersion; // First look for and find the "viewed version" of this entity... it's possible we got // the known ID version sent to us between us creating our local version, and getting this @@ -592,6 +593,9 @@ EntityItem* EntityTree::findEntityByEntityItemID(const EntityItemID& entityID) / EntityTreeElement* containingElement = getContainingElement(entityID); if (containingElement) { foundEntity = containingElement->getEntityWithEntityItemID(entityID); + if (!foundEntity && _changedEntityIDs.contains(entityID)) { + foundEntity = containingElement->getEntityWithEntityItemID(_changedEntityIDs[entityID]); + } } return foundEntity; } @@ -958,6 +962,12 @@ EntityTreeElement* EntityTree::getContainingElement(const EntityItemID& entityIt creatorTokenOnly.isKnownID = false; element = _entityToElementMap.value(creatorTokenOnly); } + + // If we still didn't find the entity, but the ID was in our changed entityIDs, search for the new ID version + if (!element && _changedEntityIDs.contains(entityItemID)) { + element = getContainingElement(_changedEntityIDs[entityItemID]); + } + return element; } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 29fecc88b4..c49cfb2600 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -195,6 +195,7 @@ private: EntityItemFBXService* _fbxService; QHash _entityToElementMap; + QHash _changedEntityIDs; EntitySimulation* _simulation; From 9739d6837064e0648cc496f9ad7bd5230734e41d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 31 Mar 2015 13:20:06 -0700 Subject: [PATCH 15/20] fix typo that broke avatar motion --- libraries/physics/src/CharacterController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 65feaa7ea3..d714194b2e 100755 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -864,7 +864,7 @@ void CharacterController::updateShapeIfNecessary() { void CharacterController::preSimulation(btScalar timeStep) { if (_enabled && _dynamicsWorld) { glm::quat rotation = _avatarData->getOrientation(); - btVector3 _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS); + _currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS); glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset; btVector3 walkVelocity = glmToBullet(_avatarData->getVelocity()); From f4695643e3eb2f1ab8600d10621b973470eb7373 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 31 Mar 2015 14:13:19 -0700 Subject: [PATCH 16/20] Blocks fall when made, better edge colors --- examples/blocks.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/examples/blocks.js b/examples/blocks.js index 30c2126096..7bc52824db 100644 --- a/examples/blocks.js +++ b/examples/blocks.js @@ -43,8 +43,8 @@ var floor = Entities.addEntity( var edge1 = Entities.addEntity( { type: "Box", position: Vec3.sum(center, { x: FLOOR_SIZE / 2.0, y: FLOOR_THICKNESS / 2.0, z: 0 }), - dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE }, - color: { red: 128, green: 128, blue: 128 }, + dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE + EDGE_THICKESS }, + color: { red: 100, green: 100, blue: 100 }, gravity: { x: 0, y: 0, z: 0 }, ignoreCollisions: false, visible: true, @@ -54,8 +54,8 @@ var edge1 = Entities.addEntity( var edge2 = Entities.addEntity( { type: "Box", position: Vec3.sum(center, { x: -FLOOR_SIZE / 2.0, y: FLOOR_THICKNESS / 2.0, z: 0 }), - dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE }, - color: { red: 128, green: 128, blue: 128 }, + dimensions: { x: EDGE_THICKESS, y: EDGE_THICKESS, z: FLOOR_SIZE + EDGE_THICKESS }, + color: { red: 100, green: 100, blue: 100 }, gravity: { x: 0, y: 0, z: 0 }, ignoreCollisions: false, visible: true, @@ -65,8 +65,8 @@ var edge2 = Entities.addEntity( var edge3 = Entities.addEntity( { type: "Box", position: Vec3.sum(center, { x: 0, y: FLOOR_THICKNESS / 2.0, z: -FLOOR_SIZE / 2.0 }), - dimensions: { x: FLOOR_SIZE, y: EDGE_THICKESS, z: EDGE_THICKESS }, - color: { red: 128, green: 128, blue: 128 }, + dimensions: { x: FLOOR_SIZE + EDGE_THICKESS, y: EDGE_THICKESS, z: EDGE_THICKESS }, + color: { red: 100, green: 100, blue: 100 }, gravity: { x: 0, y: 0, z: 0 }, ignoreCollisions: false, visible: true, @@ -76,8 +76,8 @@ var edge3 = Entities.addEntity( var edge4 = Entities.addEntity( { type: "Box", position: Vec3.sum(center, { x: 0, y: FLOOR_THICKNESS / 2.0, z: FLOOR_SIZE / 2.0 }), - dimensions: { x: FLOOR_SIZE, y: EDGE_THICKESS, z: EDGE_THICKESS }, - color: { red: 128, green: 128, blue: 128 }, + dimensions: { x: FLOOR_SIZE + EDGE_THICKESS, y: EDGE_THICKESS, z: EDGE_THICKESS }, + color: { red: 100, green: 100, blue: 100 }, gravity: { x: 0, y: 0, z: 0 }, ignoreCollisions: false, visible: true, @@ -97,6 +97,7 @@ for (var i = 0; i < NUM_BLOCKS; i++) { dimensions: { x: type.x * SCALE, y: type.y * SCALE, z: type.z * SCALE }, color: { red: type.red, green: type.green, blue: type.blue }, gravity: { x: 0, y: GRAVITY, z: 0 }, + velocity: { x: 0, y: 0.05, z: 0 }, ignoreCollisions: false, damping: DAMPING, lifetime: LIFETIME, @@ -104,6 +105,11 @@ for (var i = 0; i < NUM_BLOCKS; i++) { } function scriptEnding() { + Entities.editEntity(edge1, { locked: false }); + Entities.editEntity(edge2, { locked: false }); + Entities.editEntity(edge3, { locked: false }); + Entities.editEntity(edge4, { locked: false }); + Entities.editEntity(floor, { locked: false }); Entities.deleteEntity(edge1); Entities.deleteEntity(edge2); Entities.deleteEntity(edge3); From 154dacf7912d46340419914a0f7bc405074ec676 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 31 Mar 2015 14:21:56 -0700 Subject: [PATCH 17/20] Fix typo --- assignment-client/src/Agent.cpp | 2 +- interface/src/Application.cpp | 2 +- libraries/networking/src/ResourceCache.cpp | 4 ++-- libraries/networking/src/ResourceCache.h | 10 +++++----- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index ed1f293c06..098460ecac 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -45,7 +45,7 @@ Agent::Agent(const QByteArray& packet) : DependencyManager::get()->setPacketSender(&_entityEditSender); - DependencyManager::set(); + DependencyManager::set(); DependencyManager::set(); } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index eb427737e1..fc34eb3971 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -241,7 +241,7 @@ bool setupEssentials(int& argc, char** argv) { auto jsConsole = DependencyManager::set(); auto dialogsManager = DependencyManager::set(); auto bandwidthRecorder = DependencyManager::set(); - auto resouceCacheSharedItems = DependencyManager::set(); + auto resourceCacheSharedItems = DependencyManager::set(); auto entityScriptingInterface = DependencyManager::set(); auto windowScriptingInterface = DependencyManager::set(); #if defined(Q_OS_MAC) || defined(Q_OS_WIN) diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index 739e587f5f..83f473d8c5 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -134,7 +134,7 @@ void ResourceCache::reserveUnusedResource(qint64 resourceSize) { } void ResourceCache::attemptRequest(Resource* resource) { - auto sharedItems = DependencyManager::get(); + auto sharedItems = DependencyManager::get(); if (_requestLimit <= 0) { // wait until a slot becomes available sharedItems->_pendingRequests.append(resource); @@ -147,7 +147,7 @@ void ResourceCache::attemptRequest(Resource* resource) { void ResourceCache::requestCompleted(Resource* resource) { - auto sharedItems = DependencyManager::get(); + auto sharedItems = DependencyManager::get(); sharedItems->_loadingRequests.removeOne(resource); _requestLimit++; diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index c7aceb2e1a..ebe2c6e684 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -48,14 +48,14 @@ static const qint64 MAX_UNUSED_MAX_SIZE = 10 * BYTES_PER_GIGABYTES; // ResourceCache derived classes. Since we can't count on the ordering of // static members destruction, we need to use this Dependency manager implemented // object instead -class ResouceCacheSharedItems : public Dependency { +class ResourceCacheSharedItems : public Dependency { SINGLETON_DEPENDENCY public: QList > _pendingRequests; QList _loadingRequests; private: - ResouceCacheSharedItems() { } - virtual ~ResouceCacheSharedItems() { } + ResourceCacheSharedItems() { } + virtual ~ResourceCacheSharedItems() { } }; @@ -71,10 +71,10 @@ public: qint64 getUnusedResourceCacheSize() const { return _unusedResourcesMaxSize; } static const QList& getLoadingRequests() - { return DependencyManager::get()->_loadingRequests; } + { return DependencyManager::get()->_loadingRequests; } static int getPendingRequestCount() - { return DependencyManager::get()->_pendingRequests.size(); } + { return DependencyManager::get()->_pendingRequests.size(); } ResourceCache(QObject* parent = NULL); virtual ~ResourceCache(); From a8891919164b72cf09e2f18715b641480eaaaabe Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 31 Mar 2015 14:27:34 -0700 Subject: [PATCH 18/20] never cull mesh parts for avatars --- libraries/render-utils/src/Model.cpp | 19 ++++++------------- libraries/render-utils/src/Model.h | 4 ++-- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 81c9f9448c..e9cfdaf345 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -2372,7 +2372,7 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args, - bool forceRenderSomeMeshes) { + bool forceRenderMeshes) { PROFILE_RANGE(__FUNCTION__); int meshPartsRendered = 0; @@ -2395,7 +2395,7 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, args, locations, skinLocations); meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, - args, locations, skinLocations, forceRenderSomeMeshes); + args, locations, skinLocations, forceRenderMeshes); GLBATCH(glUseProgram)(0); return meshPartsRendered; @@ -2403,7 +2403,7 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args, - Locations* locations, SkinLocations* skinLocations, bool forceRenderSomeMeshes) { + Locations* locations, SkinLocations* skinLocations, bool forceRenderMeshes) { PROFILE_RANGE(__FUNCTION__); auto textureCache = DependencyManager::get(); @@ -2439,21 +2439,14 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod // if we got here, then check to see if this mesh is in view if (args) { bool shouldRender = true; - bool forceRender = false; args->_meshesConsidered++; if (args->_viewFrustum) { - // NOTE: This is a hack to address the fact that for avatar meshes, the _calculatedMeshBoxes can be wrong - // for some meshes. Those meshes where the mesh's modelTransform is the identity matrix, and will have - // incorrectly calculated mesh boxes. In this case, we will ignore the box and assume it's visible. - if (forceRenderSomeMeshes && (geometry.meshes.at(i).modelTransform == glm::mat4())) { - forceRender = true; - } - - shouldRender = forceRender || args->_viewFrustum->boxInFrustum(_calculatedMeshBoxes.at(i)) != ViewFrustum::OUTSIDE; + shouldRender = forceRenderMeshes || + args->_viewFrustum->boxInFrustum(_calculatedMeshBoxes.at(i)) != ViewFrustum::OUTSIDE; - if (shouldRender && !forceRender) { + if (shouldRender && !forceRenderMeshes) { float distance = args->_viewFrustum->distanceToCamera(_calculatedMeshBoxes.at(i).calcCenter()); shouldRender = !_viewState ? false : _viewState->shouldRenderMesh(_calculatedMeshBoxes.at(i).getLargestDimension(), distance); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 3b4cbdd450..299853ec9d 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -460,14 +460,14 @@ private: bool renderCore(float alpha, RenderMode mode, RenderArgs* args); int renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL, - bool forceRenderSomeMeshes = false); + bool forceRenderMeshes = false); void setupBatchTransform(gpu::Batch& batch); QVector* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned); int renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args, Locations* locations, SkinLocations* skinLocations, - bool forceRenderSomeMeshes = false); + bool forceRenderMeshes = false); static void pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args, From 74f04c0c8450fe8cff8cd406f3ab4a25ea0e12a3 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 31 Mar 2015 14:57:51 -0700 Subject: [PATCH 19/20] remove useless comment --- libraries/render-utils/src/DeferredLightingEffect.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 6ed73c6750..f46bd689d4 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -535,7 +535,6 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit } void DeferredLightingEffect::setAmbientLightMode(int preset) { - //if ((preset >= -1) && (preset < model::SphericalHarmonics::NUM_PRESET)) { if ((preset >= 0) && (preset < model::SphericalHarmonics::NUM_PRESET)) { _ambientLightMode = preset; auto light = _allocatedLights.front(); From b4d11e2eb5680a8f31d8207ac1c7ec23ff271e06 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 31 Mar 2015 15:18:59 -0700 Subject: [PATCH 20/20] Add the needed global variable exported to enable the nvidia gpu on optimus platform (laptops with intel integrated) also log the opengl version and gpu and driver used --- interface/src/Application.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index eb427737e1..83e26719db 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -136,6 +136,13 @@ #include "ui/StandAloneJSConsole.h" #include "ui/Stats.h" +// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU +#if defined(Q_OS_WIN) +extern "C" { + _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; +} +#endif + using namespace std; // Starfield information @@ -646,6 +653,11 @@ void Application::initializeGL() { } #endif + qDebug() << "GL Version: " << QString((const char*) glGetString(GL_VERSION)); + qDebug() << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); + qDebug() << "GL Vendor: " << QString((const char*) glGetString(GL_VENDOR)); + qDebug() << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER)); + #ifdef WIN32 GLenum err = glewInit(); if (GLEW_OK != err) {