diff --git a/BUILD_WIN.md b/BUILD_WIN.md index 2faa9809bb..bc6e5c8386 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -5,7 +5,7 @@ If you are upgrading from previous versions, do a clean uninstall of those versi Note: The prerequisites will require about 10 GB of space on your drive. You will also need a system with at least 8GB of main memory. -### Step 1. Visual Studio & Python +### Step 1. Visual Studio & Python 3.x If you don’t have Community or Professional edition of Visual Studio, download [Visual Studio Community 2019](https://visualstudio.microsoft.com/vs/). If you have Visual Studio 2017, you are not required to download Visual Studio 2019. @@ -21,7 +21,7 @@ When selecting components, check "Desktop development with C++". On the right on * MSVC v141 - VS 2017 C++ x64/x86 build tools * MSVC v140 - VS 2015 C++ build tools (v14.00) -If you do not already have a Python development environment installed, also check "Python Development" in this screen. +If you do not already have a Python 3.x development environment installed, also check "Python Development" in this screen. If you already have Visual Studio installed and need to add Python, open the "Add or remove programs" control panel and find the "Microsoft Visual Studio Installer". Select it and click "Modify". In the installer, select "Modify" again, then check "Python Development" and allow the installer to apply the changes. @@ -31,9 +31,10 @@ If you do not wish to use the Python installation bundled with Visual Studio, yo ### Step 2. Installing CMake -Download and install the latest version of CMake 3.14. +Download and install the latest version of CMake 3.15. + * Note that earlier versions of CMake will work, but there is a specific bug related to the interaction of Visual Studio 2019 and CMake versions prior to 3.15 that will cause Visual Studio to rebuild far more than it needs to on every build -Download the file named win64-x64 Installer from the [CMake Website](https://cmake.org/download/). You can access the installer on this [3.14 Version page](https://cmake.org/files/v3.14/). During installation, make sure to check "Add CMake to system PATH for all users" when prompted. +Download the file named win64-x64 Installer from the [CMake Website](https://cmake.org/download/). You can access the installer on this [3.15 Version page](https://cmake.org/files/v3.15/). During installation, make sure to check "Add CMake to system PATH for all users" when prompted. ### Step 3. Create VCPKG environment variable In the next step, you will use CMake to build High Fidelity. By default, the CMake process builds dependency files in Windows' `%TEMP%` directory, which is periodically cleared by the operating system. To prevent you from having to re-build the dependencies in the event that Windows clears that directory, we recommend that you create a `HIFI_VCPKG_BASE` environment variable linked to a directory somewhere on your machine. That directory will contain all dependency files until you manually remove them. @@ -42,9 +43,18 @@ To create this variable: * Naviagte to 'Edit the System Environment Variables' Through the start menu. * Click on 'Environment Variables' * Select 'New' -* Set "Variable name" to HIFI_VCPKG_BASE +* Set "Variable name" to `HIFI_VCPKG_BASE` * Set "Variable value" to any directory that you have control over. +Additionally, if you have Visual Studio 2019 installed and _only_ Visual Studio 2019 (i.e. you do not have Visual Studio 2017 installed) you must add an additional environment variable `HIFI_VCPKG_BOOTSTRAP` that will fix a bug in our `vcpkg` pre-build step. + +To create this variable: +* Naviagte to 'Edit the System Environment Variables' Through the start menu. +* Click on 'Environment Variables' +* Select 'New' +* Set "Variable name" to `HIFI_VCPKG_BOOTSTRAP` +* Set "Variable value" to `1` + ### Step 4. Running CMake to Generate Build Files Run Command Prompt from Start and run the following commands: diff --git a/hifi_vcpkg.py b/hifi_vcpkg.py index 764a6270bd..821d9ae0b7 100644 --- a/hifi_vcpkg.py +++ b/hifi_vcpkg.py @@ -71,16 +71,19 @@ endif() if 'Windows' == system: self.exe = os.path.join(self.path, 'vcpkg.exe') + self.bootstrapCmd = 'bootstrap-vcpkg.bat' self.vcpkgUrl = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/vcpkg-win32.tar.gz?versionId=YZYkDejDRk7L_hrK_WVFthWvisAhbDzZ' self.vcpkgHash = '3e0ff829a74956491d57666109b3e6b5ce4ed0735c24093884317102387b2cb1b2cd1ff38af9ed9173501f6e32ffa05cc6fe6d470b77a71ca1ffc3e0aa46ab9e' self.hostTriplet = 'x64-windows' elif 'Darwin' == system: self.exe = os.path.join(self.path, 'vcpkg') + self.bootstrapCmd = 'bootstrap-vcpkg.sh' self.vcpkgUrl = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/vcpkg-osx.tar.gz?versionId=_fhqSxjfrtDJBvEsQ8L_ODcdUjlpX9cc' self.vcpkgHash = '519d666d02ef22b87c793f016ca412e70f92e1d55953c8f9bd4ee40f6d9f78c1df01a6ee293907718f3bbf24075cc35492fb216326dfc50712a95858e9cbcb4d' self.hostTriplet = 'x64-osx' else: self.exe = os.path.join(self.path, 'vcpkg') + self.bootstrapCmd = 'bootstrap-vcpkg.sh' self.vcpkgUrl = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/vcpkg-linux.tar.gz?versionId=97Nazh24etEVKWz33XwgLY0bvxEfZgMU' self.vcpkgHash = '6a1ce47ef6621e699a4627e8821ad32528c82fce62a6939d35b205da2d299aaa405b5f392df4a9e5343dd6a296516e341105fbb2dd8b48864781d129d7fba10d' self.hostTriplet = 'x64-linux' @@ -141,8 +144,14 @@ endif() downloadVcpkg = True if downloadVcpkg: - print("Fetching vcpkg from {} to {}".format(self.vcpkgUrl, self.path)) - hifi_utils.downloadAndExtract(self.vcpkgUrl, self.path, self.vcpkgHash) + if "HIFI_VCPKG_BOOTSTRAP" in os.environ: + print("Cloning vcpkg from github to {}".format(self.path)) + hifi_utils.executeSubprocess(['git', 'clone', 'git@github.com:microsoft/vcpkg.git', self.path]) + print("Bootstrapping vcpkg") + hifi_utils.executeSubprocess([self.bootstrapCmd], folder=self.path) + else: + print("Fetching vcpkg from {} to {}".format(self.vcpkgUrl, self.path)) + hifi_utils.downloadAndExtract(self.vcpkgUrl, self.path, self.vcpkgHash) print("Replacing port files") portsPath = os.path.join(self.path, 'ports') diff --git a/interface/resources/avatar/animations/emote_clap02_all.fbx b/interface/resources/avatar/animations/emote_clap02_all.fbx index 5584a38ac0..caf673f28a 100644 Binary files a/interface/resources/avatar/animations/emote_clap02_all.fbx and b/interface/resources/avatar/animations/emote_clap02_all.fbx differ diff --git a/interface/resources/avatar/animations/sitting_emote_agree_headnod.fbx b/interface/resources/avatar/animations/sitting_emote_agree_headnod.fbx new file mode 100644 index 0000000000..655608fe55 Binary files /dev/null and b/interface/resources/avatar/animations/sitting_emote_agree_headnod.fbx differ diff --git a/interface/resources/avatar/animations/sitting_emote_agree_headnodyes.fbx b/interface/resources/avatar/animations/sitting_emote_agree_headnodyes.fbx new file mode 100644 index 0000000000..cfe90c45f0 Binary files /dev/null and b/interface/resources/avatar/animations/sitting_emote_agree_headnodyes.fbx differ diff --git a/interface/resources/avatar/animations/sitting_emote_agree_longheadnod.fbx b/interface/resources/avatar/animations/sitting_emote_agree_longheadnod.fbx new file mode 100644 index 0000000000..ead3a29fe6 Binary files /dev/null and b/interface/resources/avatar/animations/sitting_emote_agree_longheadnod.fbx differ diff --git a/interface/resources/avatar/animations/sitting_emote_clap_all.fbx b/interface/resources/avatar/animations/sitting_emote_clap_all.fbx new file mode 100644 index 0000000000..947ef4541a Binary files /dev/null and b/interface/resources/avatar/animations/sitting_emote_clap_all.fbx differ diff --git a/interface/resources/avatar/animations/sitting_emote_disagree_drophead.fbx b/interface/resources/avatar/animations/sitting_emote_disagree_drophead.fbx new file mode 100644 index 0000000000..239b242aab Binary files /dev/null and b/interface/resources/avatar/animations/sitting_emote_disagree_drophead.fbx differ diff --git a/interface/resources/avatar/animations/sitting_emote_disagree_headshake.fbx b/interface/resources/avatar/animations/sitting_emote_disagree_headshake.fbx new file mode 100644 index 0000000000..7c6f90ee89 Binary files /dev/null and b/interface/resources/avatar/animations/sitting_emote_disagree_headshake.fbx differ diff --git a/interface/resources/avatar/animations/sitting_emote_point_all.fbx b/interface/resources/avatar/animations/sitting_emote_point_all.fbx new file mode 100644 index 0000000000..f850c8e9b3 Binary files /dev/null and b/interface/resources/avatar/animations/sitting_emote_point_all.fbx differ diff --git a/interface/resources/avatar/animations/sitting_emote_raisehand_all.fbx b/interface/resources/avatar/animations/sitting_emote_raisehand_all.fbx new file mode 100644 index 0000000000..7f1b2efea2 Binary files /dev/null and b/interface/resources/avatar/animations/sitting_emote_raisehand_all.fbx differ diff --git a/interface/resources/avatar/animations/sitting_talk04.fbx b/interface/resources/avatar/animations/sitting_talk04.fbx new file mode 100644 index 0000000000..ee920672fa Binary files /dev/null and b/interface/resources/avatar/animations/sitting_talk04.fbx differ diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index 0c8d331164..b23e1c74d9 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -615,6 +615,19 @@ }, "id": "seatedTalk03", "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 442, + "loopFlag": true, + "startFrame": 0, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_talk04.fbx" + }, + "id": "seatedTalk04", + "type": "clip" } ], "data": { @@ -639,6 +652,15 @@ "resume": true, "transitions": [ ] + }, + { + "id": "seatedTalk04", + "interpDuration": 6, + "interpTarget": 6, + "priority": 1, + "resume": true, + "transitions": [ + ] } ] }, @@ -713,68 +735,433 @@ }, { "children": [ + { + "children": [ + ], + "data": { + "endFrame": 44, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_agree_headnod.fbx" + }, + "id": "seatedReactionPositiveHeadNod", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 78, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_agree_headnodyes.fbx" + }, + "id": "seatedReactionPositiveHeadNodYes", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 65, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_agree_longheadnod.fbx" + }, + "id": "seatedReactionPositiveLongHeadNod", + "type": "clip" + } ], "data": { + "currentState": "seatedReactionPositiveHeadNod", "endFrame": 30, "loopFlag": false, + "randomSwitchTimeMax": 10, + "randomSwitchTimeMin": 1, "startFrame": 0, + "states": [ + { + "id": "seatedReactionPositiveHeadNod", + "interpDuration": 6, + "interpTarget": 6, + "priority": 1, + "resume": false, + "transitions": [ + ] + }, + { + "id": "seatedReactionPositiveHeadNodYes", + "interpDuration": 6, + "interpTarget": 6, + "priority": 1, + "resume": false, + "transitions": [ + ] + }, + { + "id": "seatedReactionPositiveLongHeadNod", + "interpDuration": 6, + "interpTarget": 6, + "priority": 1, + "resume": false, + "transitions": [ + ] + } + ], "timeScale": 1, + "triggerRandomSwitch": "", "url": "qrc:///avatar/animations/sitting_idle.fbx" }, "id": "seatedReactionPositive", - "type": "clip" + "type": "randomSwitchStateMachine" }, { "children": [ + { + "children": [ + ], + "data": { + "endFrame": 64, + "loopFlag": false, + "startFrame": 0, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_disagree_headshake.fbx" + }, + "id": "seatedReactionNegativeDisagreeHeadshake", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 158, + "loopFlag": false, + "startFrame": 0, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_disagree_drophead.fbx" + }, + "id": "seatedReactionNegativeDisagreeDropHead", + "type": "clip" + } ], "data": { + "currentState": "seatedReactionNegativeDisagreeHeadshake", "endFrame": 30, "loopFlag": false, + "randomSwitchTimeMax": 10, + "randomSwitchTimeMin": 1, "startFrame": 0, + "states": [ + { + "id": "seatedReactionNegativeDisagreeHeadshake", + "interpDuration": 6, + "interpTarget": 6, + "priority": 1, + "resume": false, + "transitions": [ + ] + }, + { + "id": "seatedReactionNegativeDisagreeDropHead", + "interpDuration": 6, + "interpTarget": 6, + "priority": 1, + "resume": false, + "transitions": [ + ] + } + ], "timeScale": 1, + "triggerRandomSwitch": "", "url": "qrc:///avatar/animations/sitting_idle.fbx" }, "id": "seatedReactionNegative", - "type": "clip" + "type": "randomSwitchStateMachine" }, { "children": [ + { + "children": [ + ], + "data": { + "endFrame": 32, + "loopFlag": false, + "startFrame": 0, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_raisehand_all.fbx" + }, + "id": "seatedReactionRaiseHandIntro", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 345, + "loopFlag": true, + "startFrame": 32, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_raisehand_all.fbx" + }, + "id": "seatedReactionRaiseHandLoop", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 400, + "loopFlag": false, + "startFrame": 345, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_raisehand_all.fbx" + }, + "id": "seatedReactionRaiseHandOutro", + "type": "clip" + } ], "data": { - "endFrame": 0, - "loopFlag": true, - "startFrame": 0, - "timeScale": 1, - "url": "qrc:///avatar/animations/sitting_idle.fbx" + "currentState": "seatedReactionRaiseHandIntro", + "randomSwitchTimeMax": 10, + "randomSwitchTimeMin": 1, + "states": [ + { + "easingType": "easeInOutQuad", + "id": "seatedReactionRaiseHandIntro", + "interpDuration": 18, + "interpTarget": 18, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + { + "randomSwitchState": "seatedReactionRaiseHandLoop", + "var": "seatedReactionRaiseHandIntroOnDone" + } + ] + }, + { + "id": "seatedReactionRaiseHandLoop", + "interpDuration": 5, + "interpTarget": 5, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "seatedReactionRaiseHandOutro", + "var": "reactionRaiseHandDisabled" + } + ] + }, + { + "id": "seatedReactionRaiseHandOutro", + "interpDuration": 1, + "interpTarget": 1, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "seatedReactionRaiseHandLoop", + "var": "reactionRaiseHandEnabled" + } + ] + } + ], + "triggerRandomSwitch": "" }, "id": "seatedReactionRaiseHand", - "type": "clip" + "type": "randomSwitchStateMachine" }, { "children": [ + { + "children": [ + ], + "data": { + "endFrame": 12, + "loopFlag": false, + "startFrame": 0, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_clap_all.fbx" + }, + "id": "seatedReactionApplaudIntro", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 76, + "loopFlag": true, + "startFrame": 12, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_clap_all.fbx" + }, + "id": "seatedReactionApplaudLoop", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 99, + "loopFlag": false, + "startFrame": 76, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_clap_all.fbx" + }, + "id": "seatedReactionApplaudOutro", + "type": "clip" + } ], "data": { - "endFrame": 0, - "loopFlag": true, - "startFrame": 0, - "timeScale": 1, - "url": "qrc:///avatar/animations/sitting_idle.fbx" + "currentState": "seatedReactionApplaudIntro", + "randomSwitchTimeMax": 10, + "randomSwitchTimeMin": 1, + "states": [ + { + "easingType": "easeInOutQuad", + "id": "seatedReactionApplaudIntro", + "interpDuration": 18, + "interpTarget": 18, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + { + "randomSwitchState": "seatedReactionApplaudLoop", + "var": "seatedReactionApplaudIntroOnDone" + } + ] + }, + { + "id": "seatedReactionApplaudLoop", + "interpDuration": 5, + "interpTarget": 5, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "seatedReactionApplaudOutro", + "var": "reactionApplaudDisabled" + } + ] + }, + { + "id": "seatedReactionApplaudOutro", + "interpDuration": 1, + "interpTarget": 1, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "seatedReactionApplaudLoop", + "var": "reactionApplaudEnabled" + } + ] + } + ], + "triggerRandomSwitch": "" }, "id": "seatedReactionApplaud", - "type": "clip" + "type": "randomSwitchStateMachine" }, { "children": [ + { + "children": [ + ], + "data": { + "endFrame": 22, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_all.fbx" + }, + "id": "seatedReactionPointIntro", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 43, + "loopFlag": true, + "startFrame": 22, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_all.fbx" + }, + "id": "seatedReactionPointLoop", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 71, + "loopFlag": false, + "startFrame": 43, + "timeScale": 1, + "url": "qrc:///avatar/animations/sitting_emote_point_all.fbx" + }, + "id": "seatedReactionPointOutro", + "type": "clip" + } ], "data": { - "endFrame": 0, - "loopFlag": true, - "startFrame": 0, - "timeScale": 1, - "url": "qrc:///avatar/animations/sitting_idle.fbx" + "currentState": "seatedReactionPointIntro", + "randomSwitchTimeMax": 10, + "randomSwitchTimeMin": 1, + "states": [ + { + "easingType": "easeInOutQuad", + "id": "seatedReactionPointIntro", + "interpDuration": 18, + "interpTarget": 18, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + { + "randomSwitchState": "seatedReactionPointLoop", + "var": "seatedReactionPointIntroOnDone" + } + ] + }, + { + "id": "seatedReactionPointLoop", + "interpDuration": 5, + "interpTarget": 5, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "seatedReactionPointOutro", + "var": "reactionPointDisabled" + } + ] + }, + { + "id": "seatedReactionPointOutro", + "interpDuration": 1, + "interpTarget": 1, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "seatedReactionPointLoop", + "var": "reactionPointEnabled" + } + ] + } + ], + "triggerRandomSwitch": "" }, "id": "seatedReactionPoint", - "type": "clip" + "type": "randomSwitchStateMachine" } ], "data": { @@ -783,9 +1170,9 @@ { "easingType": "easeInOutQuad", "id": "seatedTalkOverlay", - "interpDuration": 18, - "interpTarget": 18, - "interpType": "snapshotPrev", + "interpDuration": 15, + "interpTarget": 15, + "interpType": "evaluateBoth", "transitions": [ { "state": "seatedReactionPositive", @@ -817,7 +1204,15 @@ "transitions": [ { "state": "seatedTalkOverlay", - "var": "seatedReactionPositiveOnDone" + "var": "seatedReactionPositiveHeadNodOnDone" + }, + { + "state": "seatedTalkOverlay", + "var": "seatedReactionPositiveHeadNodYesOnDone" + }, + { + "state": "seatedTalkOverlay", + "var": "seatedReactionPositiveLongHeadNodOnDone" }, { "state": "seatedReactionNegative", @@ -849,7 +1244,11 @@ }, { "state": "seatedTalkOverlay", - "var": "seatedReactionNegativeOnDone" + "var": "seatedReactionNegativeDisagreeHeadshakeOnDone" + }, + { + "state": "seatedTalkOverlay", + "var": "seatedReactionNegativeDisagreeDropHeadOnDone" }, { "state": "seatedReactionRaiseHand", @@ -1859,11 +2258,8 @@ ], "data": { "currentState": "negativeAnnoyedHeadshake", - "endFrame": 110, - "loopFlag": false, "randomSwitchTimeMax": 10, "randomSwitchTimeMin": 1, - "startFrame": 0, "states": [ { "id": "negativeAnnoyedHeadshake", @@ -1901,42 +2297,285 @@ "children": [ { "children": [ + { + "children": [ + ], + "data": { + "endFrame": 18, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_raisehand01_all.fbx" + }, + "id": "raiseHand01Intro", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 378, + "loopFlag": true, + "startFrame": 18, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_raisehand01_all.fbx" + }, + "id": "raiseHand01Loop", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 435, + "loopFlag": false, + "startFrame": 378, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_raisehand01_all.fbx" + }, + "id": "raiseHand01Outro", + "type": "clip" + } ], "data": { - "endFrame": 378, - "loopFlag": true, - "startFrame": 18, - "timeScale": 1, - "url": "qrc:///avatar/animations/emote_raisehand01_all.fbx" + "currentState": "raiseHand01Intro", + "randomSwitchTimeMax": 10, + "randomSwitchTimeMin": 1, + "states": [ + { + "easingType": "easeInOutQuad", + "id": "raiseHand01Intro", + "interpDuration": 18, + "interpTarget": 18, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + { + "randomSwitchState": "raiseHand01Loop", + "var": "raiseHand01IntroOnDone" + } + ] + }, + { + "id": "raiseHand01Loop", + "interpDuration": 5, + "interpTarget": 5, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "raiseHand01Outro", + "var": "reactionRaiseHandDisabled" + } + ] + }, + { + "id": "raiseHand01Outro", + "interpDuration": 1, + "interpTarget": 1, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "raiseHand01Loop", + "var": "reactionRaiseHandEnabled" + } + ] + } + ], + "triggerRandomSwitch": "" }, "id": "raiseHand01", - "type": "clip" + "type": "randomSwitchStateMachine" }, { "children": [ + { + "children": [ + ], + "data": { + "endFrame": 19, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_raisehand03_all.fbx" + }, + "id": "raiseHand03Intro", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 237, + "loopFlag": true, + "startFrame": 19, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_raisehand03_all.fbx" + }, + "id": "raiseHand03Loop", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 300, + "loopFlag": false, + "startFrame": 237, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_raisehand03_all.fbx" + }, + "id": "raiseHand03Outro", + "type": "clip" + } ], "data": { - "endFrame": 237, - "loopFlag": true, - "startFrame": 19, - "timeScale": 1, - "url": "qrc:///avatar/animations/emote_raisehand03_all.fbx" + "currentState": "raiseHand03Intro", + "randomSwitchTimeMax": 10, + "randomSwitchTimeMin": 1, + "states": [ + { + "easingType": "easeInOutQuad", + "id": "raiseHand03Intro", + "interpDuration": 18, + "interpTarget": 18, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + { + "randomSwitchState": "raiseHand03Loop", + "var": "raiseHand03IntroOnDone" + } + ] + }, + { + "id": "raiseHand03Loop", + "interpDuration": 5, + "interpTarget": 5, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "raiseHand03Outro", + "var": "reactionRaiseHandDisabled" + } + ] + }, + { + "id": "raiseHand03Outro", + "interpDuration": 1, + "interpTarget": 1, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "raiseHand03Loop", + "var": "reactionRaiseHandEnabled" + } + ] + } + ], + "triggerRandomSwitch": "" }, "id": "raiseHand03", - "type": "clip" + "type": "randomSwitchStateMachine" }, { "children": [ + { + "children": [ + ], + "data": { + "endFrame": 32, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_raisehand04_all.fbx" + }, + "id": "raiseHand04Intro", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 345, + "loopFlag": true, + "startFrame": 32, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_raisehand04_all.fbx" + }, + "id": "raiseHand04Loop", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 400, + "loopFlag": false, + "startFrame": 345, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_raisehand04_all.fbx" + }, + "id": "raiseHand04Outro", + "type": "clip" + } ], "data": { - "endFrame": 345, - "loopFlag": true, - "startFrame": 32, - "timeScale": 1, - "url": "qrc:///avatar/animations/emote_raisehand04_all.fbx" + "currentState": "raiseHand04Intro", + "randomSwitchTimeMax": 10, + "randomSwitchTimeMin": 1, + "states": [ + { + "easingType": "easeInOutQuad", + "id": "raiseHand04Intro", + "interpDuration": 18, + "interpTarget": 18, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + { + "randomSwitchState": "raiseHand04Loop", + "var": "raiseHand04IntroOnDone" + } + ] + }, + { + "id": "raiseHand04Loop", + "interpDuration": 5, + "interpTarget": 5, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "raiseHand04Outro", + "var": "reactionRaiseHandDisabled" + } + ] + }, + { + "id": "raiseHand04Outro", + "interpDuration": 1, + "interpTarget": 1, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "raiseHand04Loop", + "var": "reactionRaiseHandEnabled" + } + ] + } + ], + "triggerRandomSwitch": "" }, "id": "raiseHand04", - "type": "clip" + "type": "randomSwitchStateMachine" } ], "data": { @@ -1980,42 +2619,288 @@ "children": [ { "children": [ + { + "children": [ + ], + "data": { + "endFrame": 18, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_clap01_all.fbx" + }, + "id": "applaudClap01Intro", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 97, + "loopFlag": true, + "startFrame": 18, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_clap01_all.fbx" + }, + "id": "applaudClap01Loop", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 146, + "loopFlag": false, + "startFrame": 97, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_clap01_all.fbx" + }, + "id": "applaudClap01Outro", + "type": "clip" + } ], "data": { - "endFrame": 97, - "loopFlag": true, - "startFrame": 18, - "timeScale": 1, - "url": "qrc:///avatar/animations/emote_clap01_all.fbx" + "currentState": "applaudClap01Intro", + "randomSwitchTimeMax": 10, + "randomSwitchTimeMin": 1, + "states": [ + { + "easingType": "easeInOutQuad", + "id": "applaudClap01Intro", + "interpDuration": 18, + "interpTarget": 18, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + { + "randomSwitchState": "applaudClap01Loop", + "var": "applaudClap01IntroOnDone" + } + ] + }, + { + "id": "applaudClap01Loop", + "interpDuration": 5, + "interpTarget": 5, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "applaudClap01Outro", + "var": "reactionApplaudDisabled" + } + ] + }, + { + "id": "applaudClap01Outro", + "interpDuration": 5, + "interpTarget": 5, + "interpType": "evaluateBoth", + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "applaudClap01Loop", + "var": "reactionApplaudEnabled" + } + ] + } + ], + "triggerRandomSwitch": "" }, "id": "applaudClap01", - "type": "clip" + "type": "randomSwitchStateMachine" }, { "children": [ + { + "children": [ + ], + "data": { + "endFrame": 14, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_clap02_all.fbx" + }, + "id": "applaudClap02Intro", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 78, + "loopFlag": true, + "startFrame": 14, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_clap02_all.fbx" + }, + "id": "applaudClap02Loop", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 115, + "loopFlag": false, + "startFrame": 78, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_clap02_all.fbx" + }, + "id": "applaudClap02Outro", + "type": "clip" + } ], "data": { - "endFrame": 237, - "loopFlag": true, - "startFrame": 19, - "timeScale": 1, - "url": "qrc:///avatar/animations/emote_clap02_all.fbx" + "currentState": "applaudClap02Intro", + "randomSwitchTimeMax": 10, + "randomSwitchTimeMin": 1, + "states": [ + { + "easingType": "easeInOutQuad", + "id": "applaudClap02Intro", + "interpDuration": 18, + "interpTarget": 18, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + { + "randomSwitchState": "applaudClap02Loop", + "var": "applaudClap02IntroOnDone" + } + ] + }, + { + "id": "applaudClap02Loop", + "interpDuration": 5, + "interpTarget": 5, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "applaudClap02Outro", + "var": "reactionApplaudDisabled" + } + ] + }, + { + "id": "applaudClap02Outro", + "interpDuration": 5, + "interpTarget": 5, + "interpType": "evaluateBoth", + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "applaudClap02Loop", + "var": "reactionApplaudEnabled" + } + ] + } + ], + "triggerRandomSwitch": "" }, "id": "applaudClap02", - "type": "clip" + "type": "randomSwitchStateMachine" }, { "children": [ + { + "children": [ + ], + "data": { + "endFrame": 14, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_clap03_all.fbx" + }, + "id": "applaudClap03Intro", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 100, + "loopFlag": true, + "startFrame": 14, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_clap03_all.fbx" + }, + "id": "applaudClap03Loop", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 149, + "loopFlag": false, + "startFrame": 100, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_clap03_all.fbx" + }, + "id": "applaudClap03Outro", + "type": "clip" + } ], "data": { - "endFrame": 100, - "loopFlag": true, - "startFrame": 14, - "timeScale": 1, - "url": "qrc:///avatar/animations/emote_clap03_all.fbx" + "currentState": "applaudClap03Intro", + "randomSwitchTimeMax": 10, + "randomSwitchTimeMin": 1, + "states": [ + { + "easingType": "easeInOutQuad", + "id": "applaudClap03Intro", + "interpDuration": 18, + "interpTarget": 18, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + { + "randomSwitchState": "applaudClap03Loop", + "var": "applaudClap03IntroOnDone" + } + ] + }, + { + "id": "applaudClap03Loop", + "interpDuration": 5, + "interpTarget": 5, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "applaudClap03Outro", + "var": "reactionApplaudDisabled" + } + ] + }, + { + "id": "applaudClap03Outro", + "interpDuration": 5, + "interpTarget": 5, + "interpType": "evaluateBoth", + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "applaudClap03Loop", + "var": "reactionApplaudEnabled" + } + ] + } + ], + "triggerRandomSwitch": "" }, "id": "applaudClap03", - "type": "clip" + "type": "randomSwitchStateMachine" } ], "data": { @@ -2057,16 +2942,97 @@ }, { "children": [ + { + "children": [ + ], + "data": { + "endFrame": 22, + "loopFlag": false, + "startFrame": 1, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_all.fbx" + }, + "id": "reactionPointIntro", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 40, + "loopFlag": true, + "startFrame": 22, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_all.fbx" + }, + "id": "reactionPointLoop", + "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 78, + "loopFlag": false, + "startFrame": 40, + "timeScale": 1, + "url": "qrc:///avatar/animations/emote_point01_all.fbx" + }, + "id": "reactionPointOutro", + "type": "clip" + } ], "data": { - "endFrame": 44, - "loopFlag": true, - "startFrame": 22, - "timeScale": 1, - "url": "qrc:///avatar/animations/emote_point01_all.fbx" + "currentState": "reactionPointIntro", + "randomSwitchTimeMax": 10, + "randomSwitchTimeMin": 1, + "states": [ + { + "easingType": "easeInOutQuad", + "id": "reactionPointIntro", + "interpDuration": 18, + "interpTarget": 18, + "interpType": "evaluateBoth", + "priority": 1, + "resume": false, + "transitions": [ + { + "randomSwitchState": "reactionPointLoop", + "var": "reactionPointIntroOnDone" + } + ] + }, + { + "id": "reactionPointLoop", + "interpDuration": 5, + "interpTarget": 5, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "reactionPointOutro", + "var": "reactionPointDisabled" + } + ] + }, + { + "id": "reactionPointOutro", + "interpDuration": 1, + "interpTarget": 1, + "priority": 0, + "resume": false, + "transitions": [ + { + "randomSwitchState": "reactionPointLoop", + "var": "reactionPointEnabled" + } + ] + } + ], + "triggerRandomSwitch": "" }, "id": "reactionPoint", - "type": "clip" + "type": "randomSwitchStateMachine" } ], "data": { @@ -2075,9 +3041,9 @@ { "easingType": "easeInOutQuad", "id": "idleTalkOverlay", - "interpDuration": 18, - "interpTarget": 18, - "interpType": "snapshotPrev", + "interpDuration": 24, + "interpTarget": 24, + "interpType": "evaluateBoth", "transitions": [ { "state": "reactionPositive", diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8789fcde1c..caac8805b1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -292,7 +292,7 @@ static const uint32_t MAX_CONCURRENT_RESOURCE_DOWNLOADS = 4; // For processing on QThreadPool, we target a number of threads after reserving some // based on how many are being consumed by the application and the display plugin. However, // we will never drop below the 'min' value -static const int MIN_PROCESSING_THREAD_POOL_SIZE = 1; +static const int MIN_PROCESSING_THREAD_POOL_SIZE = 2; static const QString SNAPSHOT_EXTENSION = ".jpg"; static const QString JPG_EXTENSION = ".jpg"; diff --git a/interface/src/graphics/GraphicsEngine.cpp b/interface/src/graphics/GraphicsEngine.cpp index 284118a52a..53c8bd7c18 100644 --- a/interface/src/graphics/GraphicsEngine.cpp +++ b/interface/src/graphics/GraphicsEngine.cpp @@ -258,6 +258,7 @@ void GraphicsEngine::render_performFrame() { batch.setFramebuffer(finalFramebuffer); batch.enableSkybox(true); batch.enableStereo(isStereo); + batch.clearDepthStencilFramebuffer(1.0, 0); batch.setViewportTransform({ 0, 0, finalFramebuffer->getSize() }); _splashScreen->render(batch, viewFrustum, renderArgs._renderMethod == RenderArgs::RenderMethod::FORWARD); }); diff --git a/launchers/darwin/CMakeLists.txt b/launchers/darwin/CMakeLists.txt index fe7f4298ce..f71976960e 100644 --- a/launchers/darwin/CMakeLists.txt +++ b/launchers/darwin/CMakeLists.txt @@ -43,6 +43,8 @@ set(src_files src/LaunchInterface.h src/CustomUI.h src/CustomUI.m + src/NSTask+NSTaskExecveAdditions.h + src/NSTask+NSTaskExecveAdditions.m src/main.mm nib/Window.xib nib/SplashScreen.xib diff --git a/launchers/darwin/src/Launcher.m b/launchers/darwin/src/Launcher.m index 38027d6fd3..8fb501db55 100644 --- a/launchers/darwin/src/Launcher.m +++ b/launchers/darwin/src/Launcher.m @@ -7,6 +7,7 @@ #import "ProcessScreen.h" #import "ErrorViewController.h" #import "Settings.h" +#import "NSTask+NSTaskExecveAdditions.h" @interface Launcher () @@ -456,8 +457,6 @@ static BOOL const DELETE_ZIP_FILES = TRUE; NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; NSURL *url = [NSURL fileURLWithPath:[workspace fullPathForApplication:[[self getAppPath] stringByAppendingString:@"interface.app/Contents/MacOS/interface"]]]; - NSError *error = nil; - NSString* contentPath = [[self getDownloadPathForContentAndScripts] stringByAppendingString:@"content"]; NSString* displayName = [ self displayName]; NSString* scriptsPath = [[self getAppPath] stringByAppendingString:@"interface.app/Contents/Resources/scripts/simplifiedUIBootstrapper.js"]; @@ -484,13 +483,11 @@ static BOOL const DELETE_ZIP_FILES = TRUE; @"--no-updater", @"--no-launcher", nil]; } - [workspace launchApplicationAtURL:url options:NSWorkspaceLaunchNewInstance configuration:[NSDictionary dictionaryWithObject:arguments forKey:NSWorkspaceLaunchConfigurationArguments] error:&error]; - [NSTimer scheduledTimerWithTimeInterval: 3.0 - target: self - selector: @selector(exitLauncher:) - userInfo:nil - repeats: NO]; + NSTask *task = [[NSTask alloc] init]; + task.launchPath = [url path]; + task.arguments = arguments; + [task replaceThisProcess]; } - (ProcessState) currentProccessState @@ -500,15 +497,20 @@ static BOOL const DELETE_ZIP_FILES = TRUE; - (void) callLaunchInterface:(NSTimer*) timer { + NSWindow* mainWindow = [[[NSApplication sharedApplication] windows] objectAtIndex:0]; + ProcessScreen* processScreen = [[ProcessScreen alloc] initWithNibName:@"ProcessScreen" bundle:nil]; - [[[[NSApplication sharedApplication] windows] objectAtIndex:0] setContentViewController: processScreen]; - [self launchInterface]; -} - - -- (void) exitLauncher:(NSTimer*) timer -{ - [NSApp terminate:self]; + [mainWindow setContentViewController: processScreen]; + @try + { + [self launchInterface]; + } + @catch (NSException *exception) + { + NSLog(@"Caught exception: Name: %@, Reason: %@", exception.name, exception.reason); + ErrorViewController* errorViewController = [[ErrorViewController alloc] initWithNibName:@"ErrorScreen" bundle:nil]; + [mainWindow setContentViewController: errorViewController]; + } } @end diff --git a/launchers/darwin/src/NSTask+NSTaskExecveAdditions.h b/launchers/darwin/src/NSTask+NSTaskExecveAdditions.h new file mode 100644 index 0000000000..f26a4021de --- /dev/null +++ b/launchers/darwin/src/NSTask+NSTaskExecveAdditions.h @@ -0,0 +1,9 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSTask (NSTaskExecveAdditions) +- (void) replaceThisProcess; +@end + +NS_ASSUME_NONNULL_END diff --git a/launchers/darwin/src/NSTask+NSTaskExecveAdditions.m b/launchers/darwin/src/NSTask+NSTaskExecveAdditions.m new file mode 100644 index 0000000000..f204d065fa --- /dev/null +++ b/launchers/darwin/src/NSTask+NSTaskExecveAdditions.m @@ -0,0 +1,73 @@ +#import "NSTask+NSTaskExecveAdditions.h" + +#import + +char ** +toCArray(NSArray *array) +{ + // Add one to count to accommodate the NULL that terminates the array. + char **cArray = (char **) calloc([array count] + 1, sizeof(char *)); + if (cArray == NULL) { + NSException *exception = [NSException + exceptionWithName:@"MemoryException" + reason:@"malloc failed" + userInfo:nil]; + @throw exception; + } + char *str; + for (int i = 0; i < [array count]; i++) { + str = (char *) [array[i] UTF8String]; + if (str == NULL) { + NSException *exception = [NSException + exceptionWithName:@"NULLStringException" + reason:@"UTF8String was NULL" + userInfo:nil]; + @throw exception; + } + if (asprintf(&cArray[i], "%s", str) == -1) { + for (int j = 0; j < i; j++) { + free(cArray[j]); + } + free(cArray); + NSException *exception = [NSException + exceptionWithName:@"MemoryException" + reason:@"malloc failed" + userInfo:nil]; + @throw exception; + } + } + return cArray; +} + +@implementation NSTask (NSTaskExecveAdditions) + +- (void) replaceThisProcess { + char **args = toCArray([@[[self launchPath]] arrayByAddingObjectsFromArray:[self arguments]]); + + NSMutableArray *env = [[NSMutableArray alloc] init]; + NSDictionary* environvment = [[NSProcessInfo processInfo] environment]; + for (NSString* key in environvment) { + NSString* environmentVariable = [[key stringByAppendingString:@"="] stringByAppendingString:environvment[key]]; + [env addObject:environmentVariable]; + } + + char** envp = toCArray(env); + // `execve` replaces the current process with `path`. + // It will only return if it fails to replace the current process. + chdir(dirname(args[0])); + execve(args[0], (char * const *)args, envp); + + // If we're here `execve` failed. :( + for (int i = 0; i < [[self arguments] count]; i++) { + free((void *) args[i]); + } + free((void *) args); + + NSException *exception = [NSException + exceptionWithName:@"ExecveException" + reason:[NSString stringWithFormat:@"couldn't execve: %s", strerror(errno)] + userInfo:nil]; + @throw exception; +} + +@end diff --git a/libraries/animation/src/AnimRandomSwitch.cpp b/libraries/animation/src/AnimRandomSwitch.cpp index 3cf402cc14..68c7031de8 100644 --- a/libraries/animation/src/AnimRandomSwitch.cpp +++ b/libraries/animation/src/AnimRandomSwitch.cpp @@ -57,14 +57,12 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co lowerBound = upperBound; } if (abs(_randomSwitchEvaluationCount - context.getEvaluationCount()) > 1) { - _duringInterp = false; - switchRandomState(animVars, context, desiredState, _duringInterp); + switchRandomState(animVars, context, desiredState, false); } else { // firing a random switch, be sure that we aren't completing a previously triggered transition if (currentStateHasPriority) { if (desiredState->getID() != _currentState->getID()) { - _duringInterp = true; - switchRandomState(animVars, context, desiredState, _duringInterp); + switchRandomState(animVars, context, desiredState, true); } else { _duringInterp = false; } @@ -79,8 +77,7 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co // evaluate currentState transitions auto transitionState = evaluateTransitions(animVars); if (transitionState != _currentState) { - _duringInterp = true; - switchRandomState(animVars, context, transitionState, _duringInterp); + switchRandomState(animVars, context, transitionState, true); _triggerTime = randFloatInRange(_triggerTimeMin, _triggerTimeMax); _randomSwitchTime = randFloatInRange(_randomSwitchTimeMin, _randomSwitchTimeMax); } @@ -172,6 +169,9 @@ void AnimRandomSwitch::switchRandomState(const AnimVariantMap& animVars, const A _lastPlayedState = nextStateNode->getID(); if (shouldInterp) { + bool interpActive = _duringInterp; + _duringInterp = true; + const float FRAMES_PER_SECOND = 30.0f; auto prevStateNode = _children[_currentState->getChildIndex()]; @@ -195,13 +195,21 @@ void AnimRandomSwitch::switchRandomState(const AnimVariantMap& animVars, const A } _nextPoses = nextStateNode->evaluate(animVars, context, dt, triggers); } else if (_interpType == InterpType::SnapshotPrev) { - // snapshot previoius pose + // snapshot previous pose _prevPoses = _poses; // no need to evaluate _nextPoses we will do it dynamically during the interp, // however we need to set the current frame. if (!desiredState->getResume()) { nextStateNode->setCurrentFrame(desiredState->_interpTarget - duration); } + } else if (_interpType == InterpType::EvaluateBoth) { + // need to set current frame in destination branch. + nextStateNode->setCurrentFrame(desiredState->_interpTarget - duration); + if (interpActive) { + // snapshot previous pose + _prevPoses = _poses; + _interpType = InterpType::SnapshotPrev; + } } else { assert(false); } diff --git a/libraries/animation/src/AnimStateMachine.cpp b/libraries/animation/src/AnimStateMachine.cpp index b2d993abb8..658309ce71 100644 --- a/libraries/animation/src/AnimStateMachine.cpp +++ b/libraries/animation/src/AnimStateMachine.cpp @@ -128,6 +128,7 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, const AnimCon auto prevStateNode = _children[_currentState->getChildIndex()]; auto nextStateNode = _children[desiredState->getChildIndex()]; + bool interpActive = _duringInterp; _duringInterp = true; _alpha = 0.0f; float duration = std::max(0.001f, animVars.lookup(desiredState->_interpDurationVar, desiredState->_interpDuration)); @@ -146,11 +147,19 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, const AnimCon nextStateNode->setCurrentFrame(desiredState->_interpTarget); _nextPoses = nextStateNode->evaluate(animVars, context, dt, triggers); } else if (_interpType == InterpType::SnapshotPrev) { - // snapshot previoius pose + // snapshot previous pose _prevPoses = _poses; // no need to evaluate _nextPoses we will do it dynamically during the interp, // however we need to set the current frame. nextStateNode->setCurrentFrame(desiredState->_interpTarget - duration); + } else if (_interpType == InterpType::EvaluateBoth) { + // need to set current frame in destination branch. + nextStateNode->setCurrentFrame(desiredState->_interpTarget - duration); + if (interpActive) { + // snapshot previous pose + _prevPoses = _poses; + _interpType = InterpType::SnapshotPrev; + } } else { assert(false); } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index f885f1113f..d0204219ac 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -2112,8 +2112,10 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo } float easeOutInValue = _talkIdleInterpTime < 0.5f ? 4.0f * powf(_talkIdleInterpTime, 3.0f) : 4.0f * powf((_talkIdleInterpTime - 1.0f), 3.0f) + 1.0f; _animVars.set("talkOverlayAlpha", easeOutInValue); + _animVars.set("idleOverlayAlpha", easeOutInValue); // backward compatibility for older anim graphs. } else { _animVars.set("talkOverlayAlpha", 1.0f); + _animVars.set("idleOverlayAlpha", 1.0f); // backward compatibility for older anim graphs. } } else { if (_talkIdleInterpTime < 1.0f) { @@ -2124,8 +2126,10 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo float easeOutInValue = _talkIdleInterpTime < 0.5f ? 4.0f * powf(_talkIdleInterpTime, 3.0f) : 4.0f * powf((_talkIdleInterpTime - 1.0f), 3.0f) + 1.0f; float talkAlpha = 1.0f - easeOutInValue; _animVars.set("talkOverlayAlpha", talkAlpha); + _animVars.set("idleOverlayAlpha", talkAlpha); // backward compatibility for older anim graphs. } else { _animVars.set("talkOverlayAlpha", 0.0f); + _animVars.set("idleOverlayAlpha", 0.0f); // backward compatibility for older anim graphs. } } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 5eebd92fba..a8d7847c09 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -78,7 +78,8 @@ public: void setVsyncEnabled(bool vsyncEnabled) { _vsyncEnabled = vsyncEnabled; } bool isVsyncEnabled() const { return _vsyncEnabled; } // Three threads, one for rendering, one for texture transfers, one reserved for the GL driver - int getRequiredThreadCount() const override { return 3; } + // Drop to one reserved for better other-task performance in desktop + int getRequiredThreadCount() const override { return 1; } virtual std::function getHUDOperator() override; void copyTextureToQuickFramebuffer(NetworkTexturePointer source, diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h index 5317ec54da..36810681ad 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h @@ -53,6 +53,8 @@ public: void updateVisionSqueezeParameters(float visionSqueezeX, float visionSqueezeY, float visionSqueezeTransition, int visionSqueezePerEye, float visionSqueezeGroundPlaneY, float visionSqueezeSpotlightSize); + // Attempt to reserve two threads. + int getRequiredThreadCount() const override { return 2; } signals: void hmdMountedChanged(); diff --git a/libraries/script-engine/src/XMLHttpRequestClass.cpp b/libraries/script-engine/src/XMLHttpRequestClass.cpp index a74d185c6a..51e3ef0759 100644 --- a/libraries/script-engine/src/XMLHttpRequestClass.cpp +++ b/libraries/script-engine/src/XMLHttpRequestClass.cpp @@ -30,34 +30,18 @@ Q_DECLARE_METATYPE(QByteArray*) XMLHttpRequestClass::XMLHttpRequestClass(QScriptEngine* engine) : _engine(engine), - _async(true), - _url(), - _method(""), - _responseType(""), - _request(), - _reply(NULL), - _sendData(NULL), - _rawResponseData(), - _responseData(""), - _onTimeout(QScriptValue::NullValue), - _onReadyStateChange(QScriptValue::NullValue), - _readyState(XMLHttpRequestClass::UNSENT), - _errorCode(QNetworkReply::NoError), - _timeout(0), - _timer(this), - _numRedirects(0) { + _timer(this) { _request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); _timer.setSingleShot(true); } XMLHttpRequestClass::~XMLHttpRequestClass() { - if (_reply) { delete _reply; } - if (_sendData) { delete _sendData; } + if (_reply) { _reply->deleteLater(); } } QScriptValue XMLHttpRequestClass::constructor(QScriptContext* context, QScriptEngine* engine) { - return engine->newQObject(new XMLHttpRequestClass(engine)); + return engine->newQObject(new XMLHttpRequestClass(engine), QScriptEngine::ScriptOwnership); } QScriptValue XMLHttpRequestClass::getStatus() const { @@ -169,13 +153,12 @@ void XMLHttpRequestClass::send() { void XMLHttpRequestClass::send(const QScriptValue& data) { if (_readyState == OPENED && !_reply) { + if (!data.isNull()) { - _sendData = new QBuffer(this); if (data.isObject()) { - QByteArray ba = qscriptvalue_cast(data); - _sendData->setData(ba); + _sendData = qscriptvalue_cast(data); } else { - _sendData->setData(data.toString().toUtf8()); + _sendData = data.toString().toUtf8(); } } @@ -235,6 +218,10 @@ void XMLHttpRequestClass::requestFinished() { } } + disconnectFromReply(_reply); + _reply->deleteLater(); + _reply = nullptr; + setReadyState(DONE); emit requestComplete(); } @@ -246,7 +233,7 @@ void XMLHttpRequestClass::abortRequest() { disconnectFromReply(_reply); _reply->abort(); _reply->deleteLater(); - _reply = NULL; + _reply = nullptr; } } diff --git a/libraries/script-engine/src/XMLHttpRequestClass.h b/libraries/script-engine/src/XMLHttpRequestClass.h index c79859e895..d7f3c2e059 100644 --- a/libraries/script-engine/src/XMLHttpRequestClass.h +++ b/libraries/script-engine/src/XMLHttpRequestClass.h @@ -98,23 +98,23 @@ private: void disconnectFromReply(QNetworkReply* reply); void abortRequest(); - QScriptEngine* _engine; - bool _async; + QScriptEngine* _engine { nullptr }; + bool _async { true }; QUrl _url; QString _method; QString _responseType; QNetworkRequest _request; - QNetworkReply* _reply; - QBuffer* _sendData; + QNetworkReply* _reply { nullptr }; + QByteArray _sendData; QByteArray _rawResponseData; QScriptValue _responseData; - QScriptValue _onTimeout; - QScriptValue _onReadyStateChange; - ReadyState _readyState; - QNetworkReply::NetworkError _errorCode; - int _timeout; + QScriptValue _onTimeout { QScriptValue::NullValue }; + QScriptValue _onReadyStateChange { QScriptValue::NullValue }; + ReadyState _readyState { XMLHttpRequestClass::UNSENT }; + QNetworkReply::NetworkError _errorCode { QNetworkReply::NoError }; + int _timeout { 0 }; QTimer _timer; - int _numRedirects; + int _numRedirects { 0 }; private slots: void requestFinished(); diff --git a/scripts/modules/request.js b/scripts/modules/request.js index 37f3ac0d7b..48c9913bd6 100644 --- a/scripts/modules/request.js +++ b/scripts/modules/request.js @@ -39,6 +39,10 @@ module.exports = { if (error) { response = { statusCode: httpRequest.status }; } + + // Break circular reference to httpRequest so the engine can garbage collect it. + httpRequest.onreadystatechange = null; + callback(error, response, optionalCallbackParameter); } }; diff --git a/scripts/system/libraries/entityCameraTool.js b/scripts/system/libraries/entityCameraTool.js index 4410f19a5e..2968b8e903 100644 --- a/scripts/system/libraries/entityCameraTool.js +++ b/scripts/system/libraries/entityCameraTool.js @@ -355,7 +355,7 @@ CameraManager = function() { return; } - if (event.isRightButton || (event.isLeftButton && event.isControl && !event.isShifted)) { + if (event.isRightButton || (event.isLeftButton && event.isAlt && !event.isShifted)) { that.mode = MODE_ORBIT; } else if (event.isMiddleButton || (event.isLeftButton && event.isControl && event.isShifted)) { that.mode = MODE_PAN;