コード例 #1
0
        public void ConvertAvatarToObjFormat()
        {
            var    haircutRecoloring = GetComponent <HaircutRecoloring>();
            string haircutName       = string.Empty;

            if (avatarHaircuts != null && string.Compare(avatarHaircuts[currentHaircut], BALD_HAIRCUT_NAME) != 0)
            {
                haircutName = avatarHaircuts[currentHaircut];
            }

            var outputObjDir  = AvatarSdkMgr.Storage().GetAvatarSubdirectory(currentAvatarCode, AvatarSubdirectory.OBJ_EXPORT);
            var outputObjFile = Utils.CombinePaths(outputObjDir, "model.obj");

            CoreTools.AvatarPlyToObj(currentAvatarCode, AvatarFile.MESH_PLY, AvatarFile.TEXTURE, outputObjFile);

            if (!string.IsNullOrEmpty(haircutName))
            {
                var haircutObjFile = Path.Combine(Path.GetDirectoryName(outputObjFile), HaircutIdToFileName(haircutName, "obj"));
                CoreTools.HaircutPlyToObj(currentAvatarCode, haircutName, haircutObjFile, haircutRecoloring.CurrentColor, haircutRecoloring.CurrentTint);
            }

#if UNITY_EDITOR || UNITY_STANDALONE_WIN
            System.Diagnostics.Process.Start(outputObjDir);
#else
            progressText.text = string.Format("OBJ file was saved to avatar directory");
#endif
        }
コード例 #2
0
        public void ExportAvatarAsFbx()
        {
            var    haircutRecoloring = GetComponent <HaircutRecoloring>();
            string haircutName       = string.Empty;

            if (avatarHaircuts != null && string.Compare(avatarHaircuts[currentHaircut], BALD_HAIRCUT_NAME) != 0)
            {
                haircutName = avatarHaircuts[currentHaircut];
            }

            var exportDir     = AvatarSdkMgr.Storage().GetAvatarSubdirectory(currentAvatarCode, AvatarSubdirectory.FBX_EXPORT);
            var outputFbxFile = Utils.CombinePaths(exportDir, "model.fbx");

            CoreTools.ExportAvatarAsFbx(currentAvatarCode, outputFbxFile);

            if (!string.IsNullOrEmpty(haircutName))
            {
                var haircutFbxFile = Path.Combine(Path.GetDirectoryName(outputFbxFile), HaircutIdToFileName(haircutName, "fbx"));
                CoreTools.HaircutPlyToFbx(currentAvatarCode, haircutName, haircutFbxFile, haircutRecoloring.CurrentColor, haircutRecoloring.CurrentTint);
            }

#if UNITY_EDITOR || UNITY_STANDALONE_WIN
            System.Diagnostics.Process.Start(exportDir);
#else
            progressText.text = string.Format("FBX file was saved to avatar directory");
#endif
        }
コード例 #3
0
ファイル: AvatarMakerWindow.cs プロジェクト: Klanly/Jennicam
        /// <summary>
        /// Determinates state of the avatar. It simply checks existence of the mesh and texture files.
        /// </summary>
        private GalleryAvatarState GetAvatarState(string avatarCode)
        {
            OfflineAvatarProvider offlineAvatarProvider = avatarProvider as OfflineAvatarProvider;

            GalleryAvatarState avatarState = GalleryAvatarState.UNKNOWN;

            var session = offlineAvatarProvider.Session;

            if (session.IsAvatarCalculating(avatarCode))
            {
                avatarState = GalleryAvatarState.GENERATING;
            }
            else
            {
                string meshFilePath    = AvatarSdkMgr.Storage().GetAvatarFilename(avatarCode, AvatarFile.MESH_PLY);
                string textureFilePath = AvatarSdkMgr.Storage().GetAvatarFilename(avatarCode, AvatarFile.TEXTURE);
                if (File.Exists(meshFilePath) && File.Exists(textureFilePath))
                {
                    avatarState = GalleryAvatarState.COMPLETED;
                }
                else
                {
                    avatarState = GalleryAvatarState.FAILED;
                }
            }

            return(avatarState);
        }
コード例 #4
0
ファイル: CloudTools.cs プロジェクト: hafewa/FaceToFace-Unity
        /// <summary>
        /// Process blendshapes slightly differently compared to other zips (for compatibility reasons).
        /// Blendshapes are unzipped not just in avatar directory, but in their own personal folder.
        /// </summary>
        /// <param name="blendshapesZip">Full path to blendshapes zip archive.</param>
        /// <param name="avatarId">Avatar identifier to determine the correct unzip location.</param>
        public static AsyncRequest <string> UnzipBlendshapes(string blendshapesZip, string avatarId)
        {
            Debug.LogWarning("This method is obsolete. Use CloudAvatarProvider instead.");
            var blendshapesDir = AvatarSdkMgr.Storage().GetAvatarSubdirectory(avatarId, AvatarSubdirectory.BLENDSHAPES);

            return(CoreTools.UnzipFileAsync(blendshapesZip, blendshapesDir));
        }
コード例 #5
0
        /// <summary>
        /// GetHaircutPreviewAsync implementation
        /// </summary>
        private IEnumerator GetHaircutPreviewFunc(string avatarCode, string haircutId, AsyncRequest <byte[]> request)
        {
            string haircutPreviewFilename = AvatarSdkMgr.Storage().GetHaircutFilename(haircutId, HaircutFile.HAIRCUT_PREVIEW);

            if (!File.Exists(haircutPreviewFilename))
            {
                var haircutDataRequest = GetHaircutDataAsync(avatarCode, haircutId);
                yield return(request.AwaitSubrequest(haircutDataRequest, 0.05f));

                if (request.IsError)
                {
                    yield break;
                }

                var downloadRequest = DownloadAndSaveHaircutPreviewAsync(haircutDataRequest.Result);

                yield return(request.AwaitSubrequest(downloadRequest, 0.9f));

                if (request.IsError)
                {
                    yield break;
                }
            }

            byte[] previewBytes = File.ReadAllBytes(haircutPreviewFilename);

            request.IsDone = true;
            request.Result = previewBytes;
        }
コード例 #6
0
ファイル: AvatarMakerWindow.cs プロジェクト: Klanly/Jennicam
        private Color GetAvatarPredictedColor(string avatarCode)
        {
            string    modelJsonPath = AvatarSdkMgr.Storage().GetAvatarFilename(avatarCode, AvatarFile.MODEL_JSON);
            ModelInfo modelInfo     = JsonUtility.FromJson <ModelInfo>(File.ReadAllText(modelJsonPath));

            return(new Color(modelInfo.hair_color.red / 255.0f, modelInfo.hair_color.green / 255.0f, modelInfo.hair_color.blue / 255.0f));
        }
コード例 #7
0
        /// <summary>
        /// GetHaircutMeshAsync implementation
        /// </summary>
        private IEnumerator GetHaircutMeshFunc(string avatarCode, string haircutId, AsyncRequest <TexturedMesh> request)
        {
            DateTime startTime = DateTime.Now;
            // In order to display the haircut in a scene correctly we need three things: mesh, texture, and coordinates of
            // vertices adjusted specifically for our avatar (this is called "haircut point cloud"). We need this because
            // algorithms automatically adjust haircuts for each model to provide better fitness.
            // Haircut texture and mesh (number of points and mesh topology) are equal for all avatars, but "point cloud"
            // should be downloaded separately for each model.
            // If mesh and texture are not cached yet, lets download and save them.
            string haircutMeshFilename       = AvatarSdkMgr.Storage().GetHaircutFilename(haircutId, HaircutFile.HAIRCUT_MESH_PLY);
            string haircutTextureFilename    = AvatarSdkMgr.Storage().GetHaircutFilename(haircutId, HaircutFile.HAIRCUT_TEXTURE);
            string haircutPointCloudFilename = AvatarSdkMgr.Storage().GetAvatarHaircutPointCloudFilename(avatarCode, haircutId);

            bool existMeshFiles  = File.Exists(haircutMeshFilename) && File.Exists(haircutTextureFilename);
            bool existPointcloud = File.Exists(haircutPointCloudFilename);

            if (!existMeshFiles || !existPointcloud)
            {
                var haircutDataRequest = GetHaircutDataAsync(avatarCode, haircutId);
                yield return(request.AwaitSubrequest(haircutDataRequest, 0.05f));

                if (request.IsError)
                {
                    yield break;
                }

                List <AsyncRequest> downloadRequests = new List <AsyncRequest>();
                if (!existMeshFiles)
                {
                    downloadRequests.Add(DownloadAndSaveHaircutMeshAsync(haircutDataRequest.Result));
                }
                if (!existPointcloud)
                {
                    downloadRequests.Add(DownloadAndSaveHaircutPointsAsync(avatarCode, haircutDataRequest.Result));
                }

                yield return(request.AwaitSubrequests(0.9f, downloadRequests.ToArray()));

                if (request.IsError)
                {
                    yield break;
                }
            }

            var loadHaircutRequest = CoreTools.LoadHaircutFromDiskAsync(avatarCode, haircutId);

            yield return(request.AwaitSubrequest(loadHaircutRequest, 1.0f));

            if (request.IsError)
            {
                yield break;
            }

            request.IsDone = true;
            request.Result = loadHaircutRequest.Result;
        }
コード例 #8
0
ファイル: AvatarMakerWindow.cs プロジェクト: Klanly/Jennicam
        public string ReadAvatarNameByCode(string sCode)
        {
            string avatarName = sCode;

            try
            {
                avatarName = File.ReadAllText(Path.Combine(AvatarSdkMgr.Storage().GetAvatarDirectory(sCode), "avatarName.txt"));
            }
            catch { }
            return(avatarName);
        }
コード例 #9
0
        public static IEnumerator ResetResourcesAsync()
        {
            InitAvatarSdkMgrIfNeeded();

            var resourcesPath = AvatarSdkMgr.Storage().GetResourcesDirectory();

            Debug.LogFormat("Resource directory: {0}", resourcesPath);
            Directory.Delete(resourcesPath, true);
            Directory.CreateDirectory(resourcesPath);
            yield return(OfflineSdkUtils.EnsureSdkResourcesUnpacked(resourcesPath));

            isProVersion = AvatarMakerPlugin.IsProVersion();
        }
コード例 #10
0
        /// <summary>
        /// AuthorizeAsync implementation.
        /// </summary>
        private IEnumerator Authorize(AsyncRequest request)
        {
            var accessCredentials = AuthUtils.LoadCredentials();

            if (accessCredentials == null || string.IsNullOrEmpty(accessCredentials.clientSecret))
            {
                request.SetError("Could not find API keys! Please provide valid credentials via Window->ItSeez3D Avatar SDK");
                yield break;
            }

            var authRequest = AuthorizeClientCredentialsGrantTypeAsync(accessCredentials);

            yield return(request.AwaitSubrequest(authRequest, 0.5f));

            if (request.IsError)
            {
                yield break;
            }

            tokenType   = authRequest.Result.token_type;
            accessToken = authRequest.Result.access_token;
            Debug.LogFormat("Successful authentication!");

            // guarantees we re-register a Player if clientId changes
            var playerIdentifier = string.Format("player_uid_{0}", accessCredentials.clientId.Substring(0, accessCredentials.clientId.Length / 3));

            if (string.IsNullOrEmpty(playerUID))
            {
                playerUID = AvatarSdkMgr.Storage().LoadPlayerUID(playerIdentifier);
            }

            if (string.IsNullOrEmpty(playerUID))
            {
                Debug.Log("Registering new player UID");
                var playerRequest = RegisterPlayerAsync();
                yield return(request.AwaitSubrequest(playerRequest, 1));

                if (request.IsError)
                {
                    yield break;
                }

                playerUID = playerRequest.Result.code;
                AvatarSdkMgr.Storage().StorePlayerUID(playerIdentifier, playerUID);
            }

            request.IsDone = true;
        }
コード例 #11
0
        private void SetAvatarScale(string avatarCode, Transform avatarTransform)
        {
            Vector3 scale            = faceAvatarScale;
            string  pipelineInfoFile = AvatarSdkMgr.Storage().GetAvatarFilename(avatarCode, AvatarFile.PIPELINE_INFO);

            if (File.Exists(pipelineInfoFile))
            {
                string fileContent = File.ReadAllText(pipelineInfoFile);

                if (fileContent == PipelineType.HEAD.GetPipelineTypeName())
                {
                    scale = headAvatarScale;
                }
            }
            avatarTransform.localScale = scale;
        }
コード例 #12
0
ファイル: AvatarMakerWindow.cs プロジェクト: Klanly/Jennicam
        public void ExportAvatarWithBlendshapesWeightsAsFbx()
        {
            var exportDir     = AvatarSdkMgr.Storage().GetAvatarSubdirectory(selectedAvatarInfo.code, AvatarSubdirectory.FBX_EXPORT);
            var outputFbxFile = Utils.CombinePaths(exportDir, "model.fbx");

            string haircutName = selectedAvatarInfo.SelectedHairstyleName;

            if (!string.IsNullOrEmpty(haircutName))
            {
                CoreTools.SaveAvatarMesh(selectedAvatarInfo.headMeshRenderer, selectedAvatarInfo.code, outputFbxFile, MeshFileFormat.FBX, true, false, haircutName,
                                         selectedAvatarInfo.HaircutColor, selectedAvatarInfo.HaircutColorTint);
            }
            else
            {
                CoreTools.SaveAvatarMesh(selectedAvatarInfo.headMeshRenderer, selectedAvatarInfo.code, outputFbxFile, MeshFileFormat.FBX, true, false);
            }

            System.Diagnostics.Process.Start(exportDir);
        }
コード例 #13
0
ファイル: AvatarMakerWindow.cs プロジェクト: Klanly/Jennicam
        public void ExportAvatarAsObj()
        {
            var outputObjDir  = AvatarSdkMgr.Storage().GetAvatarSubdirectory(selectedAvatarInfo.code, AvatarSubdirectory.OBJ_EXPORT);
            var outputObjFile = Utils.CombinePaths(outputObjDir, "model.obj");

            string haircutName = selectedAvatarInfo.SelectedHairstyleName;

            if (!string.IsNullOrEmpty(haircutName))
            {
                CoreTools.SaveAvatarMesh(selectedAvatarInfo.headMeshRenderer, selectedAvatarInfo.code, outputObjFile, MeshFileFormat.OBJ, true, false, haircutName,
                                         selectedAvatarInfo.HaircutColor, selectedAvatarInfo.HaircutColorTint);
            }
            else
            {
                CoreTools.SaveAvatarMesh(selectedAvatarInfo.headMeshRenderer, selectedAvatarInfo.code, outputObjFile, MeshFileFormat.OBJ, true, false);
            }

            System.Diagnostics.Process.Start(outputObjDir);
        }
コード例 #14
0
        /// <summary>
        /// GetHeadMeshAsync implementation
        /// </summary>
        private IEnumerator GetHeadMeshFunc(string avatarCode, bool withBlendshapes, int detailsLevel, AsyncRequest <TexturedMesh> request)
        {
            // Need to verify if this avatar supports Level Of Details
            if (detailsLevel > 0)
            {
                var avatarRequest = GetAvatarAsync(avatarCode);
                yield return(avatarRequest);

                if (avatarRequest.IsError)
                {
                    yield break;
                }
                if (string.Compare(avatarRequest.Result.pipeline, PipelineType.FACE.GetPipelineTypeName()) != 0)
                {
                    Debug.LogWarningFormat("Avatar created by {0} doesn't support Level Of Details. Will be used LOD 0.", avatarRequest.Result.pipeline);
                    detailsLevel = 0;
                }
            }

            string meshFilename    = AvatarSdkMgr.Storage().GetAvatarFilename(avatarCode, AvatarFile.MESH_PLY);
            string textureFilename = AvatarSdkMgr.Storage().GetAvatarFilename(avatarCode, AvatarFile.TEXTURE);

            //If there are no required files, will download them.
            if (!File.Exists(meshFilename) || !File.Exists(textureFilename))
            {
                var avatarRequest = connection.GetAvatarAsync(avatarCode);
                yield return(avatarRequest);

                if (avatarRequest.IsError)
                {
                    yield break;
                }

                var downloadRequest = DownloadAndSaveAvatarModelAsync(avatarRequest.Result, false, withBlendshapes);
                yield return(request.AwaitSubrequest(downloadRequest, 0.5f));

                if (request.IsError)
                {
                    yield break;
                }
            }

            //if there are no blendshapes, will download them
            var  blendshapesDir   = AvatarSdkMgr.Storage().GetAvatarSubdirectory(avatarCode, AvatarSubdirectory.BLENDSHAPES);
            bool blendshapesExist = Directory.GetFiles(blendshapesDir).Length > 0;

            if (withBlendshapes && !blendshapesExist)
            {
                var avatarRequest = connection.GetAvatarAsync(avatarCode);
                yield return(avatarRequest);

                if (avatarRequest.IsError)
                {
                    yield break;
                }

                var downloadBlendshapes = connection.DownloadBlendshapesZipAsync(avatarRequest.Result, BlendshapesFormat.BIN, detailsLevel);
                yield return(request.AwaitSubrequest(downloadBlendshapes, 0.8f));

                if (request.IsError)
                {
                    yield break;
                }

                byte[] blendshapesZipBytes = downloadBlendshapes.Result;
                if (blendshapesZipBytes != null && blendshapesZipBytes.Length > 0)
                {
                    var saveBlendshapesZip = CoreTools.SaveAvatarFileAsync(downloadBlendshapes.Result, avatarCode, AvatarFile.BLENDSHAPES_ZIP);
                    yield return(request.AwaitSubrequest(saveBlendshapesZip, 0.9f));

                    if (request.IsError)
                    {
                        yield break;
                    }

                    var unzipBlendshapes = UnzipBlendshapesAsync(saveBlendshapesZip.Result, avatarCode);
                    yield return(request.AwaitSubrequest(unzipBlendshapes, 0.95f));

                    if (request.IsError)
                    {
                        yield break;
                    }

                    CoreTools.DeleteAvatarFile(avatarCode, AvatarFile.BLENDSHAPES_ZIP);
                }
            }

            // At this point all avatar files are already saved to disk. Let's load the files to Unity.
            var loadAvatarHeadRequest = CoreTools.LoadAvatarHeadFromDiskAsync(avatarCode, withBlendshapes, detailsLevel);

            yield return(request.AwaitSubrequest(loadAvatarHeadRequest, 1.0f));

            if (request.IsError)
            {
                yield break;
            }

            request.Result = loadAvatarHeadRequest.Result;
            request.IsDone = true;
        }
コード例 #15
0
        /// <summary>
        /// Process blendshapes slightly differently compared to other zips (for compatibility reasons).
        /// Blendshapes are unzipped not just in avatar directory, but in their own personal folder.
        /// </summary>
        /// <param name="blendshapesZip">Full path to blendshapes zip archive.</param>
        /// <param name="avatarCode">Avatar identifier to determine the correct unzip location.</param>
        public AsyncRequest <string> UnzipBlendshapesAsync(string blendshapesZip, string avatarCode)
        {
            var blendshapesDir = AvatarSdkMgr.Storage().GetAvatarSubdirectory(avatarCode, AvatarSubdirectory.BLENDSHAPES);

            return(CoreTools.UnzipFileAsync(blendshapesZip, blendshapesDir));
        }
コード例 #16
0
ファイル: AvatarMakerWindow.cs プロジェクト: Klanly/Jennicam
 public void WriteAvatarNameByCode(string avatarCode, string avatarName)
 {
     File.WriteAllText(Path.Combine(AvatarSdkMgr.Storage().GetAvatarDirectory(avatarCode), "avatarName.txt"), avatarName);
 }