diff --git a/.gitignore b/.gitignore index 8d92fe770b..ef1a7b215e 100644 --- a/.gitignore +++ b/.gitignore @@ -94,3 +94,8 @@ interface/resources/GPUCache/* # package lock file for JSDoc tool tools/jsdoc/package-lock.json + +# ignore unneeded unity project files for avatar exporter +tools/unity-avatar-exporter/Library +tools/unity-avatar-exporter/Packages +tools/unity-avatar-exporter/ProjectSettings diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 15c5915c51..1559ece191 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -91,19 +91,73 @@ In a server, it does not make sense to compile interface ### Running the software +#### Domain server + Running domain server: ```bash ./domain-server/domain-server ``` +#### Assignment clients + Running assignment client: ```bash ./assignment-client/assignment-client -n 6 ``` +#### Interface + Running interface: ```bash ./interface/interface ``` Go to localhost in the running interface. + +##### Ubuntu 18.04 only + +In Ubuntu 18.04 there is a problem related with NVidia driver library version. + +It can be workarounded following these steps: + +Uninstall incompatible nvtt libraries: +```bash +sudo apt-get remove libnvtt2 libnvtt-dev +``` + +Install libssl1.0-dev: +```bash +sudo apt-get -y install libssl1.0-dev +``` + +Clone castano nvidia-texture-tools: +``` +git clone https://github.com/castano/nvidia-texture-tools +cd nvidia-texture-tools/ +``` + +Make these changes in repo: +* In file **VERSION** set `2.2.1` +* In file **configure**: + * set `build="release"` + * set `-DNVTT_SHARED=1` + +Configure, build and install: +``` +./configure +make +sudo make install +``` + +Link compiled files: +``` +sudo ln -s /usr/local/lib/libnvcore.so /usr/lib/libnvcore.so +sudo ln -s /usr/local/lib/libnvimage.so /usr/lib/libnvimage.so +sudo ln -s /usr/local/lib/libnvmath.so /usr/lib/libnvmath.so +sudo ln -s /usr/local/lib/libnvtt.so /usr/lib/libnvtt.so +``` + +After running this steps you can run interface: +``` +interface/interface +``` diff --git a/assignment-client/src/avatars/ScriptableAvatar.cpp b/assignment-client/src/avatars/ScriptableAvatar.cpp index 6188971e1c..a2e13a03be 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.cpp +++ b/assignment-client/src/avatars/ScriptableAvatar.cpp @@ -29,7 +29,7 @@ ScriptableAvatar::ScriptableAvatar() { QByteArray ScriptableAvatar::toByteArrayStateful(AvatarDataDetail dataDetail, bool dropFaceTracking) { _globalPosition = getWorldPosition(); - return AvatarData::toByteArrayStateful(dataDetail); + return AvatarData::toByteArrayStateful(dataDetail, dropFaceTracking); } diff --git a/interface/resources/qml/hifi/dialogs/security/Security.qml b/interface/resources/qml/hifi/dialogs/security/Security.qml index 5c52af1c05..a7a0d461a2 100644 --- a/interface/resources/qml/hifi/dialogs/security/Security.qml +++ b/interface/resources/qml/hifi/dialogs/security/Security.qml @@ -328,7 +328,7 @@ Rectangle { HifiStylesUit.RalewayRegular { text: "Your wallet is not set up.\n" + - "Open the ASSETS app to get started."; + "Open the INVENTORY app to get started."; // Anchors anchors.fill: parent; // Text size diff --git a/interface/src/graphics/RenderEventHandler.h b/interface/src/graphics/RenderEventHandler.h index 93f8b548d0..1c531adbad 100644 --- a/interface/src/graphics/RenderEventHandler.h +++ b/interface/src/graphics/RenderEventHandler.h @@ -10,6 +10,7 @@ #ifndef hifi_RenderEventHandler_h #define hifi_RenderEventHandler_h +#include #include #include #include "gl/OffscreenGLCanvas.h" @@ -49,4 +50,4 @@ private: bool event(QEvent* event) override; }; -#endif // #include hifi_RenderEventHandler_h \ No newline at end of file +#endif // #include hifi_RenderEventHandler_h diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js index e3da1c2577..f1931192e4 100644 --- a/scripts/system/html/js/marketplacesInject.js +++ b/scripts/system/html/js/marketplacesInject.js @@ -251,19 +251,39 @@ $(this).closest('.col-xs-3').attr("class", 'col-xs-6'); var priceElement = $(this).find('.price'); - priceElement.css({ - "padding": "3px 5px", - "height": "40px", - "background": "linear-gradient(#00b4ef, #0093C5)", - "color": "#FFF", - "font-weight": "600", - "line-height": "34px" - }); + var available = true; + + if (priceElement.text() === 'invalidated' || + priceElement.text() === 'sold out' || + priceElement.text() === 'not for sale') { + available = false; + priceElement.css({ + "padding": "3px 5px 10px 5px", + "height": "40px", + "background": "linear-gradient(#a2a2a2, #fefefe)", + "color": "#000", + "font-weight": "600", + "line-height": "34px" + }); + } else { + priceElement.css({ + "padding": "3px 5px", + "height": "40px", + "background": "linear-gradient(#00b4ef, #0093C5)", + "color": "#FFF", + "font-weight": "600", + "line-height": "34px" + }); + } if (parseInt(cost) > 0) { priceElement.css({ "width": "auto" }); - priceElement.html(' ' + cost); + + if (available) { + priceElement.html(' ' + cost); + } + priceElement.css({ "min-width": priceElement.width() + 30 }); } }); diff --git a/tools/unity-avatar-exporter/Assets/Editor.meta b/tools/unity-avatar-exporter/Assets/Editor.meta new file mode 100644 index 0000000000..aac82b4258 --- /dev/null +++ b/tools/unity-avatar-exporter/Assets/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 51b3237a2992bd449a58ade16e52d0e0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/tools/unity-avatar-exporter/Assets/Editor/AvatarExporter.cs b/tools/unity-avatar-exporter/Assets/Editor/AvatarExporter.cs new file mode 100644 index 0000000000..60b5e0e643 --- /dev/null +++ b/tools/unity-avatar-exporter/Assets/Editor/AvatarExporter.cs @@ -0,0 +1,207 @@ +// AvatarExporter.cs +// +// Created by David Back on 28 Nov 2018 +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + +using UnityEngine; +using UnityEditor; +using System; +using System.IO; +using System.Collections.Generic; + +public class AvatarExporter : MonoBehaviour { + public static Dictionary UNITY_TO_HIFI_JOINT_NAME = new Dictionary { + {"Chest", "Spine1"}, + {"Head", "Head"}, + {"Hips", "Hips"}, + {"Left Index Distal", "LeftHandIndex3"}, + {"Left Index Intermediate", "LeftHandIndex2"}, + {"Left Index Proximal", "LeftHandIndex1"}, + {"Left Little Distal", "LeftHandPinky3"}, + {"Left Little Intermediate", "LeftHandPinky2"}, + {"Left Little Proximal", "LeftHandPinky1"}, + {"Left Middle Distal", "LeftHandMiddle3"}, + {"Left Middle Intermediate", "LeftHandMiddle2"}, + {"Left Middle Proximal", "LeftHandMiddle1"}, + {"Left Ring Distal", "LeftHandRing3"}, + {"Left Ring Intermediate", "LeftHandRing2"}, + {"Left Ring Proximal", "LeftHandRing1"}, + {"Left Thumb Distal", "LeftHandThumb3"}, + {"Left Thumb Intermediate", "LeftHandThumb2"}, + {"Left Thumb Proximal", "LeftHandThumb1"}, + {"LeftEye", "LeftEye"}, + {"LeftFoot", "LeftFoot"}, + {"LeftHand", "LeftHand"}, + {"LeftLowerArm", "LeftForeArm"}, + {"LeftLowerLeg", "LeftLeg"}, + {"LeftShoulder", "LeftShoulder"}, + {"LeftToes", "LeftToeBase"}, + {"LeftUpperArm", "LeftArm"}, + {"LeftUpperLeg", "LeftUpLeg"}, + {"Neck", "Neck"}, + {"Right Index Distal", "RightHandIndex3"}, + {"Right Index Intermediate", "RightHandIndex2"}, + {"Right Index Proximal", "RightHandIndex1"}, + {"Right Little Distal", "RightHandPinky3"}, + {"Right Little Intermediate", "RightHandPinky2"}, + {"Right Little Proximal", "RightHandPinky1"}, + {"Right Middle Distal", "RightHandMiddle3"}, + {"Right Middle Intermediate", "RightHandMiddle2"}, + {"Right Middle Proximal", "RightHandMiddle1"}, + {"Right Ring Distal", "RightHandRing3"}, + {"Right Ring Intermediate", "RightHandRing2"}, + {"Right Ring Proximal", "RightHandRing1"}, + {"Right Thumb Distal", "RightHandThumb3"}, + {"Right Thumb Intermediate", "RightHandThumb2"}, + {"Right Thumb Proximal", "RightHandThumb1"}, + {"RightEye", "RightEye"}, + {"RightFoot", "RightFoot"}, + {"RightHand", "RightHand"}, + {"RightLowerArm", "RightForeArm"}, + {"RightLowerLeg", "RightLeg"}, + {"RightShoulder", "RightShoulder"}, + {"RightToes", "RightToeBase"}, + {"RightUpperArm", "RightArm"}, + {"RightUpperLeg", "RightUpLeg"}, + {"Spine", "Spine"}, + {"UpperChest", "Spine2"}, + }; + + public static string exportedPath = String.Empty; + + [MenuItem("High Fidelity/Export New Avatar")] + public static void ExportNewAvatar() { + ExportSelectedAvatar(false); + } + + [MenuItem("High Fidelity/Export New Avatar", true)] + private static bool ExportNewAvatarValidator() { + // only enable Export New Avatar option if we have an asset selected + string[] guids = Selection.assetGUIDs; + return guids.Length > 0; + } + + [MenuItem("High Fidelity/Update Avatar")] + public static void UpdateAvatar() { + ExportSelectedAvatar(true); + } + + [MenuItem("High Fidelity/Update Avatar", true)] + private static bool UpdateAvatarValidation() { + // only enable Update Avatar option if the selected avatar is the last one that was exported + if (exportedPath != String.Empty) { + string[] guids = Selection.assetGUIDs; + if (guids.Length > 0) { + string selectedAssetPath = AssetDatabase.GUIDToAssetPath(guids[0]); + string selectedAsset = Path.GetFileNameWithoutExtension(selectedAssetPath); + string exportedAsset = Path.GetFileNameWithoutExtension(exportedPath); + return exportedAsset == selectedAsset; + } + } + return false; + } + + public static void ExportSelectedAvatar(bool usePreviousPath) { + string assetPath = AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0]); + if (assetPath.LastIndexOf(".fbx") == -1) { + EditorUtility.DisplayDialog("Error", "Please select an fbx avatar to export", "Ok"); + return; + } + ModelImporter importer = ModelImporter.GetAtPath(assetPath) as ModelImporter; + if (importer == null) { + EditorUtility.DisplayDialog("Error", "Please select a model", "Ok"); + return; + } + if (importer.animationType != ModelImporterAnimationType.Human) { + EditorUtility.DisplayDialog("Error", "Please set model's Animation Type to Humanoid", "Ok"); + return; + } + + // store joint mappings only for joints that exist in hifi and verify missing joints + HumanDescription humanDescription = importer.humanDescription; + HumanBone[] boneMap = humanDescription.human; + Dictionary jointMappings = new Dictionary(); + foreach (HumanBone bone in boneMap) { + string humanBone = bone.humanName; + string hifiJointName; + if (UNITY_TO_HIFI_JOINT_NAME.TryGetValue(humanBone, out hifiJointName)) { + jointMappings.Add(hifiJointName, bone.boneName); + } + } + if (!jointMappings.ContainsKey("Hips")) { + EditorUtility.DisplayDialog("Error", "There is no Hips bone in selected avatar", "Ok"); + return; + } + if (!jointMappings.ContainsKey("Spine")) { + EditorUtility.DisplayDialog("Error", "There is no Spine bone in selected avatar", "Ok"); + return; + } + if (!jointMappings.ContainsKey("Spine1")) { + EditorUtility.DisplayDialog("Error", "There is no Chest bone in selected avatar", "Ok"); + return; + } + if (!jointMappings.ContainsKey("Spine2")) { + // if there is no UpperChest (Spine2) bone then we remap Chest (Spine1) to Spine2 in hifi and skip Spine1 + jointMappings["Spine2"] = jointMappings["Spine1"]; + jointMappings.Remove("Spine1"); + } + + // open folder explorer defaulting to user documents folder to select target path if exporting new avatar, + // otherwise use previously exported path if updating avatar + string directoryPath; + string assetName = Path.GetFileNameWithoutExtension(assetPath); + if (!usePreviousPath || exportedPath == String.Empty) { + string documentsFolder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments); + if (!SelectExportFolder(assetName, documentsFolder, out directoryPath)) { + return; + } + } else { + directoryPath = Path.GetDirectoryName(exportedPath) + "/"; + } + Directory.CreateDirectory(directoryPath); + + // delete any existing fst since we agreed to overwrite it + string fstPath = directoryPath + assetName + ".fst"; + if (File.Exists(fstPath)) { + File.Delete(fstPath); + } + + // write out core fields to top of fst file + File.WriteAllText(fstPath, "name = " + assetName + "\ntype = body+head\nscale = 1\nfilename = " + + assetName + ".fbx\n" + "texdir = textures\n"); + + // write out joint mappings to fst file + foreach (var jointMapping in jointMappings) { + File.AppendAllText(fstPath, "jointMap = " + jointMapping.Key + " = " + jointMapping.Value + "\n"); + } + + // delete any existing fbx since we agreed to overwrite it, and copy fbx over + string targetAssetPath = directoryPath + assetName + ".fbx"; + if (File.Exists(targetAssetPath)) { + File.Delete(targetAssetPath); + } + File.Copy(assetPath, targetAssetPath); + + exportedPath = targetAssetPath; + } + + public static bool SelectExportFolder(string assetName, string initialPath, out string directoryPath) { + string selectedPath = EditorUtility.OpenFolderPanel("Select export location", initialPath, ""); + if (selectedPath.Length == 0) { // folder selection cancelled + directoryPath = ""; + return false; + } + directoryPath = selectedPath + "/" + assetName + "/"; + if (Directory.Exists(directoryPath)) { + bool overwrite = EditorUtility.DisplayDialog("Error", "Directory " + assetName + + " already exists here, would you like to overwrite it?", "Yes", "No"); + if (!overwrite) { + SelectExportFolder(assetName, selectedPath, out directoryPath); + } + } + return true; + } +} diff --git a/tools/unity-avatar-exporter/Assets/Editor/AvatarExporter.cs.meta b/tools/unity-avatar-exporter/Assets/Editor/AvatarExporter.cs.meta new file mode 100644 index 0000000000..c71e4c396d --- /dev/null +++ b/tools/unity-avatar-exporter/Assets/Editor/AvatarExporter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c7a34be82b3ae554ea097963914b083f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/tools/unity-avatar-exporter/avatarExporter.unitypackage b/tools/unity-avatar-exporter/avatarExporter.unitypackage new file mode 100644 index 0000000000..bb25cb4072 Binary files /dev/null and b/tools/unity-avatar-exporter/avatarExporter.unitypackage differ diff --git a/tools/unity-avatar-exporter/packager.bat b/tools/unity-avatar-exporter/packager.bat new file mode 100644 index 0000000000..99932f1ead --- /dev/null +++ b/tools/unity-avatar-exporter/packager.bat @@ -0,0 +1 @@ +"C:\Program Files\Unity\Editor\Unity.exe" -quit -batchmode -projectPath %CD% -exportPackage "Assets/Editor" "avatarExporter.unitypackage"