diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index fd48a792dc..9ce11ca032 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -28,6 +28,78 @@ !include "WinVer.nsh" +;-------------------------------- +;Include Installer Logging +; taken from http://nsis.sourceforge.net/Logging:_Simple_Text_File_Logging_Functions_and_Macros +; TextLog.nsh v1.1 - 2005-12-26 +; Written by Mike Schinkel [http://www.mikeschinkel.com/blog/] + + Var /GLOBAL __TextLog_FileHandle + Var /GLOBAL __TextLog_FileName + Var /GLOBAL __TextLog_State + + !define LogMsg '!insertmacro LogMsgCall' + !macro LogMsgCall _text + Call LogSetOn + Push "${_text}" + Call LogText + Call LogSetOff + !macroend + + + !define LogText '!insertmacro LogTextCall' + !macro LogTextCall _text + Push "${_text}" + Call LogText + !macroend + + Function LogText + Exch $0 ; pABC -> 0ABC + FileWrite $__TextLog_FileHandle "$0$\r$\n" + Pop $0 ; 0ABC -> ABC + FunctionEnd + + !define LogSetFileName '!insertmacro LogSetFileNameCall' + !macro LogSetFileNameCall _filename + Push "${_filename}" + Call LogSetFileName + !macroend + + Function LogSetFileName + Exch $0 ; pABC -> 0ABC + StrCpy $__TextLog_FileName "$0" + StrCmp $__TextLog_State "open" +1 +3 + Call LogSetOff + Call LogSetOn + Pop $0 ; 0ABC -> ABC + FunctionEnd + + !define LogSetOn '!insertmacro LogSetOnCall' + !macro LogSetOnCall + Call LogSetOn + !macroend + + Function LogSetOn + StrCmp $__TextLog_FileName "" +1 AlreadySet + StrCpy $__TextLog_FileName "$INSTDIR\install.log" + AlreadySet: + StrCmp $__TextLog_State "open" +2 + FileOpen $__TextLog_FileHandle "$__TextLog_FileName" a + FileSeek $__TextLog_FileHandle 0 END + StrCpy $__TextLog_State "open" + FunctionEnd + + !define LogSetOff '!insertmacro LogSetOffCall' + !macro LogSetOffCall + Call LogSetOff + !macroend + + Function LogSetOff + StrCmp $__TextLog_State "open" +1 +2 + FileClose $__TextLog_FileHandle + StrCpy $__TextLog_State "" + FunctionEnd + ;-------------------------------- ; Utilities and Functions ;-------------------------------- @@ -375,6 +447,10 @@ Var GAClientID !insertmacro CreateGUID $GAClientID !macroend +!macro LogStep Category Action Label Value + ${LogText} "Step: ${Category} ${Action} ${Label} ${Value}" +!macroend + !macro GoogleAnalytics Category Action Label Value ${If} "@GA_TRACKING_ID@" != "" Push $0 @@ -557,11 +633,13 @@ Var Express !macro MaybeSkipPage ; Check if Express is set, if so, abort the post install options page ${If} $Express == "1" + ${LogText} "Express Install: Skipping Post Install Options Page" Abort ${EndIf} !macroend !macro DownloadSlideshowImages + ${LogText} "Download Slideshow Images" InitPluginsDir Push $0 @@ -583,32 +661,40 @@ Var Express !macroend Function OnUserAbort + !insertmacro LogStep "Installer" "Abort" "User Abort" "" !insertmacro GoogleAnalytics "Installer" "Abort" "User Abort" "" FunctionEnd Function PageWelcomePre + !insertmacro LogStep "Installer" "Welcome" "" "" !insertmacro GoogleAnalytics "Installer" "Welcome" "" "" !insertmacro DownloadSlideshowImages FunctionEnd Function PageLicensePre + !insertmacro LogStep "Installer" "License" "" "" !insertmacro GoogleAnalytics "Installer" "License" "" "" FunctionEnd Function PageDirectoryPre !insertmacro MaybeSkipPage + !insertmacro LogStep "Installer" "Directory" "" "" !insertmacro GoogleAnalytics "Installer" "Directory" "" "" FunctionEnd Function PageStartMenuPre !insertmacro MaybeSkipPage + !insertmacro LogStep "Installer" "StartMenu" "" "" !insertmacro GoogleAnalytics "Installer" "StartMenu" "" "" FunctionEnd Function PageComponentsPre !insertmacro MaybeSkipPage + !insertmacro LogStep "Installer" "Components" "" "" !insertmacro GoogleAnalytics "Installer" "Components" "" "" FunctionEnd Function PageInstallFilesPre + !insertmacro LogStep "Installer" "Install" "" "" !insertmacro GoogleAnalytics "Installer" "Install" "" "" FunctionEnd !macro SetInstallOption Checkbox OptionName Default + ${LogText} "SetInstallOption ${OptionName} ${Default}" ; reads the value for the given install option to the registry ReadRegStr $0 HKLM "@REGISTRY_HKLM_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\@POST_INSTALL_OPTIONS_REG_GROUP@" "${OptionName}" @@ -625,6 +711,7 @@ FunctionEnd !macroend Function InstallTypesPage + !insertmacro LogStep "Installer" "Install Types" "" "" !insertmacro GoogleAnalytics "Installer" "Install Types" "" "" !insertmacro MUI_HEADER_TEXT "Choose Installation Type" "Express or Custom Install" @@ -688,6 +775,7 @@ FunctionEnd Function StartInstallSlideshow ; create a slideshow file based on what files we have available + ${LogText} "Start Installs Slideshow" ; stash $0 and $1 Push $0 @@ -730,7 +818,11 @@ Function StartInstallSlideshow FunctionEnd Function PostInstallOptionsPage + + ${LogText} "Install Directory: $INSTDIR" + !insertmacro MaybeSkipPage + !insertmacro LogStep "Installer" "Post Install Options" "" "" !insertmacro GoogleAnalytics "Installer" "Post Install Options" "" "" !insertmacro MUI_HEADER_TEXT "Setup Options" "" @@ -876,30 +968,43 @@ Function ReadPostInstallOptions ; check if the user asked for a desktop shortcut to console ${NSD_GetState} $DesktopConsoleCheckbox $DesktopConsoleState - + ${LogText} "Option: Start Desktop Console: $DesktopConsoleState" + ; check if the user asked to have console launched every startup ${NSD_GetState} $ConsoleStartupCheckbox $ConsoleStartupState + ${LogText} "Option: Start Desktop Console On Startup: $ConsoleStartupState" + ${If} @SERVER_COMPONENT_CONDITIONAL@ + ${LogText} "Option: Install Server" + ${EndIf} + ${If} @CLIENT_COMPONENT_CONDITIONAL@ + ${LogText} "Option: Install Client" ; check if the user asked for a desktop shortcut to High Fidelity ${NSD_GetState} $DesktopClientCheckbox $DesktopClientState + ${LogText} "Option: Create Client Desktop Shortcut: $DesktopClientState" ${EndIf} ${If} @PR_BUILD@ == 1 + ${LogText} "Option: PR Build" ; check if we need to copy settings/content from production for this PR build ${NSD_GetState} $CopyFromProductionCheckbox $CopyFromProductionState + ${LogText} "Option: Copy Settings From Production: $CopyFromProductionState" ${EndIf} ; check if we need to launch the console post-install ${NSD_GetState} $LaunchConsoleNowCheckbox $LaunchConsoleNowState + ${LogText} "Option: Launch Console Now: $LaunchConsoleNowState" ${If} @CLIENT_COMPONENT_CONDITIONAL@ ; check if we need to launch the client post-install ${NSD_GetState} $LaunchClientNowCheckbox $LaunchClientNowState + ${LogText} "Option: Launch Client Now: $LaunchClientNowState" ${EndIf} ; check if the user asked for a clean install ${NSD_GetState} $CleanInstallCheckbox $CleanInstallState + ${LogText} "Option: Clean Install: $CleanInstallState" FunctionEnd Function HandlePostInstallOptions @@ -1225,6 +1330,7 @@ Section "-Core installation" ; Handle whichever post install options were set Call HandlePostInstallOptions + !insertmacro LogStep "Installer" "Done" "" "" !insertmacro GoogleAnalytics "Installer" "Done" "" "" SectionEnd @@ -1232,7 +1338,6 @@ SectionEnd !macro PromptForRunningApplication applicationName displayName action prompter !define UniqueID ${__LINE__} - Prompt_${UniqueID}: ${nsProcess::FindProcess} ${applicationName} $R0 @@ -1478,6 +1583,11 @@ InstallDirRegKey HKLM "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_RE Function .onInit + Delete "$TEMP\hifi_install.log" + ${LogSetFileName} "$TEMP\hifi_install.log" + ${LogSetOn} + ${LogText} "In .onInit" + !ifdef INNER ; If INNER is defined, then we aren't supposed to do anything except write out ; the installer. This is better than processing a command line option as it means @@ -1495,6 +1605,7 @@ Function .onInit !insertmacro GoogleAnalytics "Installer" "Start" "$CampaignName" "" ; make sure none of the installed applications are still running + ${LogText} "Checking For Running Applications" !insertmacro CheckForRunningApplications "installed" "Installer" ${nsProcess::Unload} diff --git a/interface/resources/qml/hifi/avatarapp/AdjustWearables.qml b/interface/resources/qml/hifi/avatarapp/AdjustWearables.qml index 0740914440..b707d41025 100644 --- a/interface/resources/qml/hifi/avatarapp/AdjustWearables.qml +++ b/interface/resources/qml/hifi/avatarapp/AdjustWearables.qml @@ -48,16 +48,32 @@ Rectangle { refresh(avatar); } + function extractTitleFromUrl(url) { + for (var j = (url.length - 1); j >= 0; --j) { + if (url[j] === '/') { + return url.substring(j + 1); + } + } + return url; + } + function refresh(avatar) { wearablesCombobox.model.clear(); wearablesCombobox.currentIndex = -1; for (var i = 0; i < avatar.wearables.count; ++i) { var wearable = avatar.wearables.get(i).properties; - for (var j = (wearable.modelURL.length - 1); j >= 0; --j) { - if (wearable.modelURL[j] === '/') { - wearable.text = wearable.modelURL.substring(j + 1); - break; + if (wearable.modelURL) { + wearable.text = extractTitleFromUrl(wearable.modelURL); + } else if (wearable.materialURL) { + var materialUrlOrJson = ''; + if (!wearable.materialURL.startsWith('materialData')) { + materialUrlOrJson = extractTitleFromUrl(wearable.materialURL); + } else if (wearable.materialData) { + materialUrlOrJson = JSON.stringify(JSON.parse(wearable.materialData)) + } + if(materialUrlOrJson) { + wearable.text = 'Material: ' + materialUrlOrJson; } } wearablesCombobox.model.append(wearable); diff --git a/interface/resources/qml/hifi/dialogs/security/Security.qml b/interface/resources/qml/hifi/dialogs/security/Security.qml index 08605033a5..b754cb06ab 100644 --- a/interface/resources/qml/hifi/dialogs/security/Security.qml +++ b/interface/resources/qml/hifi/dialogs/security/Security.qml @@ -15,7 +15,7 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 import QtGraphicalEffects 1.0 import stylesUit 1.0 as HifiStylesUit -import controlsUit 1.0 as as HifiControlsUit +import controlsUit 1.0 as HifiControlsUit import "qrc:////qml//controls" as HifiControls import "qrc:////qml//hifi//commerce//common" as HifiCommerceCommon diff --git a/interface/resources/qml/hifi/dialogs/security/SecurityImageChange.qml b/interface/resources/qml/hifi/dialogs/security/SecurityImageChange.qml index 82d094144d..e563bd13ca 100644 --- a/interface/resources/qml/hifi/dialogs/security/SecurityImageChange.qml +++ b/interface/resources/qml/hifi/dialogs/security/SecurityImageChange.qml @@ -13,7 +13,7 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 -import stylesUit 1.0 +import stylesUit 1.0 as HifiStylesUit import controlsUit 1.0 as HifiControlsUit import "qrc:////qml//controls" as HifiControls diff --git a/interface/resources/qml/hifi/dialogs/security/SecurityImageSelection.qml b/interface/resources/qml/hifi/dialogs/security/SecurityImageSelection.qml index 366372622c..3451cbcf50 100644 --- a/interface/resources/qml/hifi/dialogs/security/SecurityImageSelection.qml +++ b/interface/resources/qml/hifi/dialogs/security/SecurityImageSelection.qml @@ -13,7 +13,7 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 -import stylesUit 1.0 +import stylesUit 1.0 as HifiStylesUit import controlsUit 1.0 as HifiControlsUit import "qrc:////qml//controls" as HifiControls diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 8d47591d40..876e64c592 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1893,8 +1893,6 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { bool isWearableEntity(const EntityItemPointer& entity) { return entity->isVisible() - && (entity->getParentJointIndex() != INVALID_JOINT_INDEX - || (entity->getType() == EntityTypes::Model && (std::static_pointer_cast(entity))->getRelayParentJoints())) && (entity->getParentID() == DependencyManager::get()->getSessionUUID() || entity->getParentID() == AVATAR_SELF_ID); } diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index c3baa80f33..476372160e 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -108,10 +108,6 @@ bool WebEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointe return true; } - if (_lastLocked != entity->getLocked()) { - return true; - } - return false; } @@ -203,7 +199,6 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene } _lastDPI = entity->getDPI(); - _lastLocked = entity->getLocked(); glm::vec2 windowSize = getWindowSize(entity); _webSurface->resize(QSize(windowSize.x, windowSize.y)); @@ -362,7 +357,7 @@ glm::vec2 WebEntityRenderer::getWindowSize(const TypedEntityPointer& entity) con } void WebEntityRenderer::hoverEnterEntity(const PointerEvent& event) { - if (!_lastLocked && _webSurface) { + if (_webSurface) { PointerEvent webEvent = event; webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _lastDPI)); _webSurface->hoverBeginEvent(webEvent, _touchDevice); @@ -370,7 +365,7 @@ void WebEntityRenderer::hoverEnterEntity(const PointerEvent& event) { } void WebEntityRenderer::hoverLeaveEntity(const PointerEvent& event) { - if (!_lastLocked && _webSurface) { + if (_webSurface) { PointerEvent webEvent = event; webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _lastDPI)); _webSurface->hoverEndEvent(webEvent, _touchDevice); @@ -378,8 +373,7 @@ void WebEntityRenderer::hoverLeaveEntity(const PointerEvent& event) { } void WebEntityRenderer::handlePointerEvent(const PointerEvent& event) { - // Ignore mouse interaction if we're locked - if (!_lastLocked && _webSurface) { + if (_webSurface) { PointerEvent webEvent = event; webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _lastDPI)); _webSurface->handlePointerEvent(webEvent, _touchDevice); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.h b/libraries/entities-renderer/src/RenderableWebEntityItem.h index 1ba8ed0ec7..12640f697d 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.h +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.h @@ -65,7 +65,6 @@ private: gpu::TexturePointer _texture; QString _lastSourceUrl; uint16_t _lastDPI; - bool _lastLocked; QTimer _timer; uint64_t _lastRenderTime { 0 }; }; diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 1a62227c31..905bf3ccfd 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -9,6 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include #include "GLMHelpers.h" #include #include "NumericalConstants.h" @@ -43,8 +44,8 @@ const mat4 Matrices::X_180 { createMatFromQuatAndPos(Quaternions::X_180, Vectors const mat4 Matrices::Y_180 { createMatFromQuatAndPos(Quaternions::Y_180, Vectors::ZERO) }; const mat4 Matrices::Z_180 { createMatFromQuatAndPos(Quaternions::Z_180, Vectors::ZERO) }; -// Safe version of glm::mix; based on the code in Nick Bobick's article, -// http://www.gamasutra.com/features/19980703/quaternions_01.htm (via Clyde, +// Safe version of glm::mix; based on the code in Nick Bobic's article, +// https://www.gamasutra.com/view/feature/131686/rotating_objects_using_quaternions.php?page=1 (via Clyde, // https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Quaternion.java) glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float proportion) { float cosa = q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w; @@ -76,9 +77,11 @@ glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float proportion) { // Allows sending of fixed-point numbers: radix 1 makes 15.1 number, radix 8 makes 8.8 number, etc int packFloatScalarToSignedTwoByteFixed(unsigned char* buffer, float scalar, int radix) { - int16_t twoByteFixed = (int16_t)(scalar * (float)(1 << radix)); - memcpy(buffer, &twoByteFixed, sizeof(int16_t)); - return sizeof(int16_t); + using FixedType = int16_t; + FixedType twoByteFixed = (FixedType) glm::clamp(scalar * (1 << radix), (float)std::numeric_limits::min(), + (float)std::numeric_limits::max()); + memcpy(buffer, &twoByteFixed, sizeof(FixedType)); + return sizeof(FixedType); } int unpackFloatScalarFromSignedTwoByteFixed(const int16_t* byteFixedPointer, float* destinationPointer, int radix) { diff --git a/scripts/system/avatarapp.js b/scripts/system/avatarapp.js index 44f10396ca..a55ed74a86 100644 --- a/scripts/system/avatarapp.js +++ b/scripts/system/avatarapp.js @@ -28,9 +28,8 @@ function executeLater(callback) { Script.setTimeout(callback, 300); } -var INVALID_JOINT_INDEX = -1 function isWearable(avatarEntity) { - return avatarEntity.properties.visible === true && (avatarEntity.properties.parentJointIndex !== INVALID_JOINT_INDEX || avatarEntity.properties.relayParentJoints === true) && + return avatarEntity.properties.visible === true && (avatarEntity.properties.parentID === MyAvatar.sessionUUID || avatarEntity.properties.parentID === MyAvatar.SELF_ID); } diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index 2f343ff84b..12a69d7b27 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -485,7 +485,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa } var handJointIndex; - if (grabData.grabFollowsController) { + if (HMD.mounted && HMD.isHandControllerAvailable() && grabData.grabFollowsController) { handJointIndex = this.controllerJointIndex; } else { handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"); diff --git a/scripts/system/controllers/controllerModules/farParentGrabEntity.js b/scripts/system/controllers/controllerModules/farParentGrabEntity.js index ac6c41d4d6..f85869aa7f 100644 --- a/scripts/system/controllers/controllerModules/farParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farParentGrabEntity.js @@ -262,7 +262,9 @@ Script.include("/~/system/libraries/controllers.js"); if (this.thisFarGrabJointIsParent(endProps)) { Entities.editEntity(this.targetEntityID, { parentID: this.previousParentID[this.targetEntityID], - parentJointIndex: this.previousParentJointIndex[this.targetEntityID] + parentJointIndex: this.previousParentJointIndex[this.targetEntityID], + localVelocity: {x: 0, y: 0, z: 0}, + localAngularVelocity: {x: 0, y: 0, z: 0} }); } diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index bbdcbaaa64..f354067a77 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -149,20 +149,12 @@ Script.include("/~/system/libraries/controllers.js"); this.hapticTargetID = null; var props = controllerData.nearbyEntityPropertiesByID[this.targetEntityID]; if (this.thisHandIsParent(props) && !this.robbed) { - if (this.previousParentID[this.targetEntityID] === Uuid.NULL || this.previousParentID === undefined) { - Entities.editEntity(this.targetEntityID, { - parentID: this.previousParentID[this.targetEntityID], - parentJointIndex: this.previousParentJointIndex[this.targetEntityID] - }); - } else { - // we're putting this back as a child of some other parent, so zero its velocity - Entities.editEntity(this.targetEntityID, { - parentID: this.previousParentID[this.targetEntityID], - parentJointIndex: this.previousParentJointIndex[this.targetEntityID], - localVelocity: {x: 0, y: 0, z: 0}, - localAngularVelocity: {x: 0, y: 0, z: 0} - }); - } + Entities.editEntity(this.targetEntityID, { + parentID: this.previousParentID[this.targetEntityID], + parentJointIndex: this.previousParentJointIndex[this.targetEntityID], + localVelocity: {x: 0, y: 0, z: 0}, + localAngularVelocity: {x: 0, y: 0, z: 0} + }); } var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];