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 }
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 }
/// <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); }
/// <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)); }
/// <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; }
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)); }
/// <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; }
public string ReadAvatarNameByCode(string sCode) { string avatarName = sCode; try { avatarName = File.ReadAllText(Path.Combine(AvatarSdkMgr.Storage().GetAvatarDirectory(sCode), "avatarName.txt")); } catch { } return(avatarName); }
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(); }
/// <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; }
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; }
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); }
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); }
/// <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; }
/// <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)); }
public void WriteAvatarNameByCode(string avatarCode, string avatarName) { File.WriteAllText(Path.Combine(AvatarSdkMgr.Storage().GetAvatarDirectory(avatarCode), "avatarName.txt"), avatarName); }